From 5269685ea256a6014463697f435c0b90f69ea04f Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 26 Apr 2023 09:28:14 -0700 Subject: [PATCH 01/63] Header only API for polygon-polygon distance (#1065) This PR contains 2 major additions: 1. Range casting methods. Developer can now cast a `multipolygon_range` to a `multilinestring_range` or a `multipoint_range`. This change is included in `multipolygon_range.cuh` and `multipolygon_range_test.cu`. 2. Pairwise polygon-polygon distance. This change is separated in two parts: 1. linestring-linestring compute kernel is refactored into algorithm/linetring_distance.cuh. 2. This kernel is then reused to compute polygon ring distances. Closes #1052 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1065 --- .../detail/algorithm/linestring_distance.cuh | 74 +++ .../cuspatial/detail/distance_utils.cuh | 1 + .../cuspatial/detail/linestring_distance.cuh | 46 +- .../cuspatial/detail/polygon_distance.cuh | 93 ++++ .../detail/range/multipolygon_range.cuh | 37 ++ cpp/include/cuspatial/polygon_distance.cuh | 47 ++ .../cuspatial/range/multipolygon_range.cuh | 13 +- cpp/include/cuspatial_test/base_fixture.hpp | 4 +- cpp/include/cuspatial_test/test_util.cuh | 9 +- .../cuspatial_test/vector_equality.hpp | 33 ++ .../cuspatial_test/vector_factories.cuh | 41 ++ cpp/tests/CMakeLists.txt | 3 + cpp/tests/range/multipolygon_range_test.cu | 207 ++++++++ .../spatial/distance/polygon_distance_test.cu | 482 ++++++++++++++++++ 14 files changed, 1045 insertions(+), 45 deletions(-) create mode 100644 cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh create mode 100644 cpp/include/cuspatial/detail/polygon_distance.cuh create mode 100644 cpp/include/cuspatial/polygon_distance.cuh create mode 100644 cpp/tests/spatial/distance/polygon_distance_test.cu diff --git a/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh b/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh new file mode 100644 index 000000000..31b984551 --- /dev/null +++ b/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include + +#include + +#include + +namespace cuspatial { +namespace detail { + +/** + * @internal + * @brief The kernel to compute linestring to linestring distance + * + * Each thread of the kernel computes the distance between a segment in a linestring in pair 1 to a + * linestring in pair 2. For a segment in pair 1, the linestring index is looked up from the offset + * array and mapped to the linestring in the pair 2. The segment is then computed with all segments + * in the corresponding linestring in pair 2. This forms a local minima of the shortest distance, + * which is then combined with other segment results via an atomic operation to form the global + * minimum distance between the linestrings. + * + * `intersects` is an optional pointer to a boolean range where the `i`th element indicates the + * `i`th output should be set to 0 and bypass distance computation. This argument is optional, if + * set to nullopt, no distance computation will be bypassed. + */ +template +__global__ void linestring_distance(MultiLinestringRange1 multilinestrings1, + MultiLinestringRange2 multilinestrings2, + thrust::optional intersects, + OutputIt distances_first) +{ + using T = typename MultiLinestringRange1::element_t; + + for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings1.num_points(); + idx += gridDim.x * blockDim.x) { + auto const part_idx = multilinestrings1.part_idx_from_point_idx(idx); + if (!multilinestrings1.is_valid_segment_id(idx, part_idx)) continue; + auto const geometry_idx = multilinestrings1.geometry_idx_from_part_idx(part_idx); + + if (intersects.has_value() && intersects.value()[geometry_idx]) { + distances_first[geometry_idx] = 0; + continue; + } + + auto [a, b] = multilinestrings1.segment(idx); + T min_distance_squared = std::numeric_limits::max(); + + for (auto const& linestring2 : multilinestrings2[geometry_idx]) { + for (auto [c, d] : linestring2) { + min_distance_squared = min(min_distance_squared, squared_segment_distance(a, b, c, d)); + } + } + atomicMin(&distances_first[geometry_idx], static_cast(sqrt(min_distance_squared))); + } +} + +} // namespace detail +} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/distance_utils.cuh b/cpp/include/cuspatial/detail/distance_utils.cuh index 5d1de5eca..87efb0212 100644 --- a/cpp/include/cuspatial/detail/distance_utils.cuh +++ b/cpp/include/cuspatial/detail/distance_utils.cuh @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include diff --git a/cpp/include/cuspatial/detail/linestring_distance.cuh b/cpp/include/cuspatial/detail/linestring_distance.cuh index 02eed59f0..09bb66cb3 100644 --- a/cpp/include/cuspatial/detail/linestring_distance.cuh +++ b/cpp/include/cuspatial/detail/linestring_distance.cuh @@ -16,8 +16,7 @@ #pragma once -#include -#include +#include #include #include #include @@ -26,49 +25,12 @@ #include #include +#include #include #include namespace cuspatial { -namespace detail { - -/** - * @internal - * @brief The kernel to compute linestring to linestring distance - * - * Each thread of the kernel computes the distance between a segment in a linestring in pair 1 to a - * linestring in pair 2. For a segment in pair 1, the linestring index is looked up from the offset - * array and mapped to the linestring in the pair 2. The segment is then computed with all segments - * in the corresponding linestring in pair 2. This forms a local minima of the shortest distance, - * which is then combined with other segment results via an atomic operation to form the globally - * minimum distance between the linestrings. - */ -template -__global__ void pairwise_linestring_distance_kernel(MultiLinestringRange1 multilinestrings1, - MultiLinestringRange2 multilinestrings2, - OutputIt distances_first) -{ - using T = typename MultiLinestringRange1::element_t; - - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings1.num_points(); - idx += gridDim.x * blockDim.x) { - auto const part_idx = multilinestrings1.part_idx_from_point_idx(idx); - if (!multilinestrings1.is_valid_segment_id(idx, part_idx)) continue; - auto const geometry_idx = multilinestrings1.geometry_idx_from_part_idx(part_idx); - auto [a, b] = multilinestrings1.segment(idx); - T min_distance_squared = std::numeric_limits::max(); - - for (auto const& linestring2 : multilinestrings2[geometry_idx]) { - for (auto [c, d] : linestring2) { - min_distance_squared = min(min_distance_squared, squared_segment_distance(a, b, c, d)); - } - } - atomicMin(&distances_first[geometry_idx], static_cast(sqrt(min_distance_squared))); - } -} - -} // namespace detail template OutputIt pairwise_linestring_distance(MultiLinestringRange1 multilinestrings1, @@ -98,8 +60,8 @@ OutputIt pairwise_linestring_distance(MultiLinestringRange1 multilinestrings1, std::size_t const num_blocks = (multilinestrings1.num_points() + threads_per_block - 1) / threads_per_block; - detail::pairwise_linestring_distance_kernel<<>>( - multilinestrings1, multilinestrings2, distances_first); + detail::linestring_distance<<>>( + multilinestrings1, multilinestrings2, thrust::nullopt, distances_first); CUSPATIAL_CUDA_TRY(cudaGetLastError()); return distances_first + multilinestrings1.size(); diff --git a/cpp/include/cuspatial/detail/polygon_distance.cuh b/cpp/include/cuspatial/detail/polygon_distance.cuh new file mode 100644 index 000000000..2da92a4a4 --- /dev/null +++ b/cpp/include/cuspatial/detail/polygon_distance.cuh @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include "distance_utils.cuh" +#include "linestring_distance.cuh" + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace cuspatial { + +/** + * @brief Implementation of pairwise distance between two multipolygon ranges. + * + * All points in lhs and rhs are tested for intersection its corresponding pair, + * and if any intersection is found, the distance between the two polygons is 0. + * Otherwise, the distance is the minimum distance between any two segments in the + * multipolygon pair. + */ +template +OutputIt pairwise_polygon_distance(MultipolygonRangeA lhs, + MultipolygonRangeB rhs, + OutputIt distances_first, + rmm::cuda_stream_view stream) +{ + using T = typename MultipolygonRangeA::element_t; + + CUSPATIAL_EXPECTS(lhs.size() == rhs.size(), "Must have the same number of input rows."); + + if (lhs.size() == 0) return distances_first; + + auto lhs_as_multipoints = lhs.as_multipoint_range(); + auto rhs_as_multipoints = rhs.as_multipoint_range(); + + auto intersects = [&]() { + auto lhs_in_rhs = point_polygon_intersects(lhs_as_multipoints, rhs, stream); + auto rhs_in_lhs = point_polygon_intersects(rhs_as_multipoints, lhs, stream); + + rmm::device_uvector intersects(lhs_in_rhs.size(), stream); + thrust::transform(rmm::exec_policy(stream), + lhs_in_rhs.begin(), + lhs_in_rhs.end(), + rhs_in_lhs.begin(), + intersects.begin(), + thrust::logical_or{}); + return intersects; + }(); + + auto lhs_as_multilinestrings = lhs.as_multilinestring_range(); + auto rhs_as_multilinestrings = rhs.as_multilinestring_range(); + + thrust::fill(rmm::exec_policy(stream), + distances_first, + distances_first + lhs.size(), + std::numeric_limits::max()); + + auto [threads_per_block, num_blocks] = grid_1d(lhs.num_points()); + + detail::linestring_distance<<>>( + lhs_as_multilinestrings, rhs_as_multilinestrings, intersects.begin(), distances_first); + + CUSPATIAL_CUDA_TRY(cudaGetLastError()); + return distances_first + lhs.size(); +} + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/range/multipolygon_range.cuh b/cpp/include/cuspatial/detail/range/multipolygon_range.cuh index ad276fee9..6f9cfcf2c 100644 --- a/cpp/include/cuspatial/detail/range/multipolygon_range.cuh +++ b/cpp/include/cuspatial/detail/range/multipolygon_range.cuh @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -441,4 +443,39 @@ multipolygon_range:: return point_idx == _ring_begin[_part_begin[_geometry_begin[geometry_idx]]]; } +template +CUSPATIAL_HOST_DEVICE auto +multipolygon_range::as_multipoint_range() +{ + auto multipoint_geometry_it = thrust::make_permutation_iterator( + _ring_begin, thrust::make_permutation_iterator(_part_begin, _geometry_begin)); + + return multipoint_range{multipoint_geometry_it, + multipoint_geometry_it + thrust::distance(_geometry_begin, _geometry_end), + _point_begin, + _point_end}; +} + +template +CUSPATIAL_HOST_DEVICE auto +multipolygon_range:: + as_multilinestring_range() +{ + auto multilinestring_geometry_it = + thrust::make_permutation_iterator(_part_begin, _geometry_begin); + return multilinestring_range{ + multilinestring_geometry_it, + multilinestring_geometry_it + thrust::distance(_geometry_begin, _geometry_end), + _ring_begin, + _ring_end, + _point_begin, + _point_end}; +} + } // namespace cuspatial diff --git a/cpp/include/cuspatial/polygon_distance.cuh b/cpp/include/cuspatial/polygon_distance.cuh new file mode 100644 index 000000000..55f80857d --- /dev/null +++ b/cpp/include/cuspatial/polygon_distance.cuh @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +namespace cuspatial { + +/** + * @ingroup distance + * @brief Computes pairwise multipolygon to multipolygon distance + * + * @tparam MultiPolygonRangeA An instance of template type `multipolygon_range` + * @tparam MultiPolygonRangeB An instance of template type `multipolygon_range` + * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). + * Must be an iterator to type convertible from floating points. + * + * @param lhs The first multipolygon range to compute distance from + * @param rhs The second multipolygon range to compute distance to + * @param stream The CUDA stream on which to perform computations + * @return Output Iterator past the last distance computed + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_polygon_distance(MultipolygonRangeA lhs, + MultipolygonRangeB rhs, + OutputIt distances_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); +} // namespace cuspatial + +#include diff --git a/cpp/include/cuspatial/range/multipolygon_range.cuh b/cpp/include/cuspatial/range/multipolygon_range.cuh index 4c0590c4b..8a5e99841 100644 --- a/cpp/include/cuspatial/range/multipolygon_range.cuh +++ b/cpp/include/cuspatial/range/multipolygon_range.cuh @@ -62,7 +62,9 @@ class multipolygon_range { using ring_it_t = RingIterator; using point_it_t = VecIterator; using point_t = iterator_value_type; - using element_t = iterator_vec_base_type; + + using index_t = iterator_value_type; + using element_t = iterator_vec_base_type; int64_t static constexpr INVALID_INDEX = -1; @@ -180,6 +182,15 @@ class multipolygon_range { /// Returns an iterator to the end of the segment CUSPATIAL_HOST_DEVICE auto segment_end(); + /// Range Casting + + /// Cast the range of multipolygons as a range of multipoints, ignoring all edge connections and + /// ring relationships. + CUSPATIAL_HOST_DEVICE auto as_multipoint_range(); + + /// Cast the range of multipolygons as a range of multilinestrings, ignoring ring relationships. + CUSPATIAL_HOST_DEVICE auto as_multilinestring_range(); + protected: GeometryIterator _geometry_begin; GeometryIterator _geometry_end; diff --git a/cpp/include/cuspatial_test/base_fixture.hpp b/cpp/include/cuspatial_test/base_fixture.hpp index 52635c34d..8f8344896 100644 --- a/cpp/include/cuspatial_test/base_fixture.hpp +++ b/cpp/include/cuspatial_test/base_fixture.hpp @@ -66,7 +66,9 @@ class BaseFixture : public RMMResourceMixin, public ::testing::Test {}; * class MyTest : public cuspatial::test::BaseFixtureWithParam {}; * * TEST_P(MyTest, TestParamterGet) { - * auto [a, b, c] = GetParam(); + * auto a = std::get<0>(GetParam()); + * auto b = std::get<1>(GetParam()); + * auto c = std::get<2>(GetParam()); * ... * } * diff --git a/cpp/include/cuspatial_test/test_util.cuh b/cpp/include/cuspatial_test/test_util.cuh index cb9e5cafe..2cc10bae9 100644 --- a/cpp/include/cuspatial_test/test_util.cuh +++ b/cpp/include/cuspatial_test/test_util.cuh @@ -100,7 +100,14 @@ void print_device_range(Iter begin, } /** - * @brief + * @brief Print a device vector. + * + * @note Copies the device vector to host before printing. + * + * @tparam Vector The device vector type + * @param vec The device vector to print + * @param pre String to print before the device vector + * @param post String to print after the device vector */ template void print_device_vector(Vector const& vec, std::string_view pre = "", std::string_view post = "\n") diff --git a/cpp/include/cuspatial_test/vector_equality.hpp b/cpp/include/cuspatial_test/vector_equality.hpp index 06ab03073..5d72f6228 100644 --- a/cpp/include/cuspatial_test/vector_equality.hpp +++ b/cpp/include/cuspatial_test/vector_equality.hpp @@ -238,6 +238,39 @@ void expect_vec_2d_pair_equivalent(PairVector1 const& expected, PairVector2 cons cuspatial::test::expect_vec_2d_pair_equivalent(lhs, rhs); \ } while (0) +template +void expect_multilinestring_array_equivalent(Array1& lhs, Array2& rhs) +{ + auto [lhs_geometry_offset, lhs_part_offset, lhs_coordinates] = lhs.release(); + auto [rhs_geometry_offset, rhs_part_offset, rhs_coordinates] = rhs.release(); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(lhs_geometry_offset, rhs_geometry_offset); + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(lhs_part_offset, rhs_part_offset); + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(lhs_coordinates, rhs_coordinates); +} + +#define CUSPATIAL_EXPECT_MULTILINESTRING_ARRAY_EQUIVALENT(lhs, rhs) \ + do { \ + SCOPED_TRACE(" <-- line of failure\n"); \ + cuspatial::test::expect_multilinestring_array_equivalent(lhs, rhs); \ + } while (0) + +template +void expect_multipoint_array_equivalent(Array1& lhs, Array2& rhs) +{ + auto [lhs_geometry_offset, lhs_coordinates] = lhs.release(); + auto [rhs_geometry_offset, rhs_coordinates] = rhs.release(); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(lhs_geometry_offset, rhs_geometry_offset); + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(lhs_coordinates, rhs_coordinates); +} + +#define CUSPATIAL_EXPECT_MULTIPOINT_ARRAY_EQUIVALENT(lhs, rhs) \ + do { \ + SCOPED_TRACE(" <-- line of failure\n"); \ + cuspatial::test::expect_multipoint_array_equivalent(lhs, rhs); \ + } while (0) + #define CUSPATIAL_RUN_TEST(FUNC, ...) \ do { \ SCOPED_TRACE(" <-- line of failure\n"); \ diff --git a/cpp/include/cuspatial_test/vector_factories.cuh b/cpp/include/cuspatial_test/vector_factories.cuh index 99a0fea80..d8730e230 100644 --- a/cpp/include/cuspatial_test/vector_factories.cuh +++ b/cpp/include/cuspatial_test/vector_factories.cuh @@ -240,12 +240,43 @@ class multilinestring_array { _coordinate_array.end()); } + auto release() + { + return std::tuple{std::move(_geometry_offset_array), + std::move(_part_offset_array), + std::move(_coordinate_array)}; + } + protected: GeometryArray _geometry_offset_array; PartArray _part_offset_array; CoordinateArray _coordinate_array; }; +/** + * @brief Construct an owning object of a multilinestring array from ranges + * + * @param geometry_inl Range of geometry offsets + * @param part_inl Range of part offsets + * @param coord_inl Ramge of coordinate + * @return multilinestring array object + */ +template +auto make_multilinestring_array(IndexRangeA geometry_inl, + IndexRangeB part_inl, + CoordRange coord_inl) +{ + using CoordType = typename CoordRange::value_type; + using DeviceIndexVector = thrust::device_vector; + using DeviceCoordVector = thrust::device_vector; + + return multilinestring_array( + make_device_vector(geometry_inl), make_device_vector(part_inl), make_device_vector(coord_inl)); +} + /** * @brief Construct an owning object of a multilinestring array from initializer lists * @@ -299,6 +330,16 @@ class multipoint_array { CoordinateArray _coordinates; }; +/** + * @brief Factory method to construct multipoint array from ranges of geometry offsets and + * coordinates + */ +template +auto make_multipoints_array(GeometryRange geometry_inl, CoordRange coordinates_inl) +{ + return multipoint_array{make_device_vector(geometry_inl), make_device_vector(coordinates_inl)}; +} + /** * @brief Factory method to construct multipoint array from initializer list of multipoints. * diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 8f2a26f34..c3201e373 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -204,6 +204,9 @@ ConfigureTest(LINESTRING_DISTANCE_TEST_EXP spatial/distance/linestring_distance_test.cu spatial/distance/linestring_distance_test_medium.cu) +ConfigureTest(POLYGON_DISTANCE_TEST_EXP + spatial/distance/polygon_distance_test.cu) + # intersection ConfigureTest(LINESTRING_INTERSECTION_TEST_EXP spatial/intersection/linestring_intersection_count_test.cu diff --git a/cpp/tests/range/multipolygon_range_test.cu b/cpp/tests/range/multipolygon_range_test.cu index 1caa92b2e..0f1b08809 100644 --- a/cpp/tests/range/multipolygon_range_test.cu +++ b/cpp/tests/range/multipolygon_range_test.cu @@ -99,6 +99,56 @@ struct MultipolygonRangeTest : public BaseFixture { CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(got, d_expected); } + + void test_multipolygon_as_multilinestring( + std::initializer_list multipolygon_geometry_offset, + std::initializer_list multipolygon_part_offset, + std::initializer_list ring_offset, + std::initializer_list> multipolygon_coordinates, + std::initializer_list multilinestring_geometry_offset, + std::initializer_list multilinestring_part_offset, + std::initializer_list> multilinestring_coordinates) + { + auto multipolygon_array = make_multipolygon_array(multipolygon_geometry_offset, + multipolygon_part_offset, + ring_offset, + multipolygon_coordinates); + auto rng = multipolygon_array.range().as_multilinestring_range(); + + auto got = + make_multilinestring_array(range(rng.geometry_offsets_begin(), rng.geometry_offsets_end()), + range(rng.part_offsets_begin(), rng.part_offsets_end()), + range(rng.point_begin(), rng.point_end())); + + auto expected = make_multilinestring_array( + multilinestring_geometry_offset, multilinestring_part_offset, multilinestring_coordinates); + + CUSPATIAL_EXPECT_MULTILINESTRING_ARRAY_EQUIVALENT(expected, got); + } + + void test_multipolygon_as_multipoint( + std::initializer_list multipolygon_geometry_offset, + std::initializer_list multipolygon_part_offset, + std::initializer_list ring_offset, + std::initializer_list> multipolygon_coordinates, + std::initializer_list multipoint_geometry_offset, + std::initializer_list> multipoint_coordinates) + { + auto multipolygon_array = make_multipolygon_array(multipolygon_geometry_offset, + multipolygon_part_offset, + ring_offset, + multipolygon_coordinates); + auto rng = multipolygon_array.range().as_multipoint_range(); + + auto got = make_multipoints_array(range(rng.offsets_begin(), rng.offsets_end()), + range(rng.point_begin(), rng.point_end())); + + auto expected = make_multipoints_array( + range(multipoint_geometry_offset.begin(), multipoint_geometry_offset.end()), + range(multipoint_coordinates.begin(), multipoint_coordinates.end())); + + CUSPATIAL_EXPECT_MULTIPOINT_ARRAY_EQUIVALENT(expected, got); + } }; TYPED_TEST_CASE(MultipolygonRangeTest, FloatingPointTypes); @@ -338,3 +388,160 @@ TYPED_TEST(MultipolygonRangeTest, DISABLED_MultipolygonSegmentCount_ConatainsEmp {0, 0}}, {6, 3}); } + +TYPED_TEST(MultipolygonRangeTest, MultipolygonAsMultilinestring1) +{ + CUSPATIAL_RUN_TEST(this->test_multipolygon_as_multilinestring, + {0, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {10, 10}, {11, 10}, {11, 11}, {10, 10}}, + {0, 1, 2}, + {0, 4, 8}, + {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {10, 10}, {11, 10}, {11, 11}, {10, 10}}); +} + +TYPED_TEST(MultipolygonRangeTest, MultipolygonAsMultilinestring2) +{ + CUSPATIAL_RUN_TEST(this->test_multipolygon_as_multilinestring, + {0, 1, 2}, + {0, 1, 3}, + {0, 4, 8, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}, + {0, 1, 3}, + {0, 4, 8, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}); +} + +TYPED_TEST(MultipolygonRangeTest, MultipolygonAsMultilinestring3) +{ + CUSPATIAL_RUN_TEST(this->test_multipolygon_as_multilinestring, + {0, 1, 2}, + {0, 2, 3}, + {0, 4, 8, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}, + {0, 2, 3}, + {0, 4, 8, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}); +} + +TYPED_TEST(MultipolygonRangeTest, MultipolygonAsMultiPoint1) +{ + CUSPATIAL_RUN_TEST(this->test_multipolygon_as_multipoint, + {0, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {10, 10}, {11, 10}, {11, 11}, {10, 10}}, + {0, 4, 8}, + {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {10, 10}, {11, 10}, {11, 11}, {10, 10}}); +} + +TYPED_TEST(MultipolygonRangeTest, MultipolygonAsMultiPoint2) +{ + CUSPATIAL_RUN_TEST(this->test_multipolygon_as_multipoint, + {0, 1, 2}, + {0, 1, 3}, + {0, 4, 8, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}, + {0, 4, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}); +} + +TYPED_TEST(MultipolygonRangeTest, MultipolygonAsMultiPoint3) +{ + CUSPATIAL_RUN_TEST(this->test_multipolygon_as_multipoint, + {0, 1, 2}, + {0, 2, 3}, + {0, 4, 8, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}, + {0, 8, 12}, + {{0, 0}, + {1, 0}, + {1, 1}, + {0, 0}, + {10, 10}, + {11, 10}, + {11, 11}, + {10, 10}, + {20, 20}, + {21, 20}, + {21, 21}, + {20, 20}}); +} diff --git a/cpp/tests/spatial/distance/polygon_distance_test.cu b/cpp/tests/spatial/distance/polygon_distance_test.cu new file mode 100644 index 000000000..6b0fc52c7 --- /dev/null +++ b/cpp/tests/spatial/distance/polygon_distance_test.cu @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +using namespace cuspatial; +using namespace cuspatial::test; + +template +struct PairwisePolygonDistanceTest : BaseFixture { + template + void run_test(MultipolygonRangeA lhs, + MultipolygonRangeB rhs, + rmm::device_uvector const& expected) + { + auto got = rmm::device_uvector(lhs.size(), stream()); + auto ret = pairwise_polygon_distance(lhs, rhs, got.begin(), stream()); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(expected, got); + EXPECT_EQ(thrust::distance(got.begin(), ret), expected.size()); + } + + void run(std::initializer_list lhs_multipolygon_geometry_offsets, + std::initializer_list lhs_multipolygon_part_offsets, + std::initializer_list lhs_multipolygon_ring_offsets, + std::initializer_list> lhs_multipolygon_coordinates, + std::initializer_list rhs_multipolygon_geometry_offsets, + std::initializer_list rhs_multipolygon_part_offsets, + std::initializer_list rhs_multipolygon_ring_offsets, + std::initializer_list> rhs_multipolygon_coordinates, + std::initializer_list expected) + { + auto lhs = make_multipolygon_array(lhs_multipolygon_geometry_offsets, + lhs_multipolygon_part_offsets, + lhs_multipolygon_ring_offsets, + lhs_multipolygon_coordinates); + + auto rhs = make_multipolygon_array(rhs_multipolygon_geometry_offsets, + rhs_multipolygon_part_offsets, + rhs_multipolygon_ring_offsets, + rhs_multipolygon_coordinates); + + auto lhs_range = lhs.range(); + auto rhs_range = rhs.range(); + + auto d_expected = make_device_uvector(expected, stream(), mr()); + + // Euclidean distance is symmetric + run_test(lhs_range, rhs_range, d_expected); + run_test(rhs_range, lhs_range, d_expected); + } +}; + +TYPED_TEST_CASE(PairwisePolygonDistanceTest, FloatingPointTypes); + +TYPED_TEST(PairwisePolygonDistanceTest, Empty) +{ + this->run({0}, {0}, {0}, {}, {0}, {0}, {0}, {}, {}); +} + +// Test Matrix +// One Pair: +// lhs-rhs Relationship: Disjoint, Touching, Overlapping, Contained, Within +// Holes: No, Yes +// Multipolygon: No, Yes + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonDisjointNoHole) +{ + this->run({0, 1}, + {0, 1}, + {0, 4}, + {{0, 0}, {0, 1}, {1, 1}, {1, 0}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{-1, 0}, {-1, 1}, {-2, 0}, {-1, 0}}, + {1}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonTouchingNoHole) +{ + this->run({0, 1}, + {0, 1}, + {0, 4}, + {{0, 0}, {0, 1}, {1, 1}, {1, 0}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{1, 0}, {2, 0}, {2, 1}, {1, 0}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonOverlappingNoHole) +{ + this->run({0, 1}, + {0, 1}, + {0, 4}, + {{0, 0}, {0, 1}, {1, 1}, {1, 0}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{0.5, 0}, {2, 0}, {2, 1}, {0.5, 0}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonContainedNoHole) +{ + this->run({0, 1}, + {0, 1}, + {0, 5}, + {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}, + {0, 1}, + {0, 1}, + {0, 5}, + {{0.25, 0.25}, {0.75, 0.25}, {0.75, 0.75}, {0.25, 0.75}, {0.25, 0.25}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonWithinNoHole) +{ + this->run({0, 1}, + {0, 1}, + {0, 5}, + {{0.25, 0.25}, {0.75, 0.25}, {0.75, 0.75}, {0.25, 0.75}, {0.25, 0.25}}, + {0, 1}, + {0, 1}, + {0, 5}, + {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonDisjointHasHole) +{ + this->run({0, 1}, + {0, 2}, + {0, 4, 8}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {1.0, 0.75}, + {1.5, 0.75}, + {1.25, 1.0}, + {1.0, 0.75}}, + {0, 1}, + {0, 2}, + {0, 4, 8}, + {{-1.0, 0.0}, + {-1.0, -1.0}, + {-2.0, 0.0}, + {-1.0, 0.0}, + {-1.25, -0.25}, + {-1.25, -0.5}, + {-1.5, -0.25}, + {-1.25, -0.25}}, + {1}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonDisjointHasHole2) +{ + this->run({0, 1}, + {0, 2}, + {0, 5, 10}, + {{0.0, 0.0}, + {10.0, 0.0}, + {10.0, 10.0}, + {0.0, 10.0}, + {0.0, 0.0}, + {2.0, 2.0}, + {2.0, 6.0}, + {6.0, 6.0}, + {6.0, 2.0}, + {2.0, 2.0}}, + {0, 1}, + {0, 1}, + {0, 5}, + {{3.0, 3.0}, {3.0, 4.0}, {4.0, 4.0}, {4.0, 3.0}, {3.0, 3.0}}, + {1}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonTouchingHasHole) +{ + this->run({0, 1}, + {0, 2}, + {0, 4, 8}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {1.0, 0.75}, + {1.5, 0.75}, + {1.25, 1.0}, + {1.0, 0.75}}, + {0, 1}, + {0, 2}, + {0, 4, 8}, + {{2.0, 0.0}, + {3.0, 0.0}, + {3.0, 1.0}, + {2.0, 0.0}, + {2.5, 0.25}, + {2.75, 0.25}, + {2.75, 0.5}, + {2.5, 0.25}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonOverlappingHasHole) +{ + this->run({0, 1}, + {0, 2}, + {0, 5, 10}, + {{0, 0}, {4, 0}, {4, 4}, {0, 4}, {0, 0}, {2, 2}, {2, 3}, {3, 3}, {3, 2}, {2, 2}}, + {0, 1}, + {0, 2}, + {0, 4, 8}, + {{2, -1}, {5, 4}, {5, -1}, {2, -1}, {3, -0.5}, {4, 0}, {4, -0.5}, {3, -0.5}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonContainedHasHole) +{ + this->run({0, 1}, + {0, 2}, + {0, 5, 10}, + {{0, 0}, {4, 0}, {4, 4}, {0, 4}, {0, 0}, {1, 3}, {1, 1}, {3, 1}, {1, 3}, {1, 1}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{1, 3}, {3, 1}, {3, 3}, {1, 3}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairSinglePolygonWithinHasHole) +{ + this->run({0, 1}, + {0, 1}, + {0, 4}, + {{1, 3}, {3, 1}, {3, 3}, {1, 3}}, + {0, 1}, + {0, 2}, + {0, 5, 9}, + {{0, 0}, {4, 0}, {4, 4}, {0, 4}, {0, 0}, {1, 1}, {3, 1}, {1, 3}, {1, 1}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairMultiPolygonDisjointNoHole) +{ + this->run({0, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {3.0, 3.0}, + {3.0, 4.0}, + {4.0, 4.0}, + {3.0, 3.0}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{-1.0, 0.0}, {-1.0, -1.0}, {-2.0, 0.0}, {-1.0, 0.0}}, + {1}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairMultiPolygonTouchingNoHole) +{ + this->run({0, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {3.0, 3.0}, + {3.0, 4.0}, + {4.0, 4.0}, + {3.0, 3.0}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{3.0, 3.0}, {2.0, 3.0}, {2.0, 2.0}, {3.0, 3.0}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairMultiPolygonOverlappingNoHole) +{ + this->run({0, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {3.0, 3.0}, + {3.0, 4.0}, + {4.0, 4.0}, + {3.0, 3.0}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{1.0, 1.0}, {3.0, 1.0}, {3.0, 3.0}, {1.0, 1.0}}, + {0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, OnePairMultiPolygonContainedNoHole) +{ + this->run({0, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {1.0, 1.0}, + {1.0, 2.0}, + {2.0, 2.0}, + {1.0, 1.0}}, + {0, 1}, + {0, 1}, + {0, 4}, + {{0.5, 0.25}, {1.5, 0.25}, {1.5, 1.25}, {0.5, 0.25}}, + {0}); +} + +// Two Pair Tests + +TYPED_TEST(PairwisePolygonDistanceTest, TwoPairSinglePolygonNoHole) +{ + this->run({0, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {3.0, 3.0}, + {3.0, 4.0}, + {4.0, 4.0}, + {3.0, 3.0}}, + {0, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{3.0, 0.0}, + {4.0, 0.0}, + {4.0, 1.0}, + {3.0, 0.0}, + {3.0, 3.0}, + {3.0, 2.0}, + {2.0, 2.0}, + {3.0, 3.0}}, + {1, 0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, TwoPairSinglePolygonHasHole) +{ + this->run({0, 1, 2}, + {0, 1, 3}, + {0, 4, 8, 12}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {3.0, 3.0}, + {3.0, 4.0}, + {4.0, 4.0}, + {3.0, 3.0}, + {3.25, 3.5}, + {3.5, 3.5}, + {3.5, 3.75}, + {3.25, 3.5}}, + {0, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{3.0, 0.0}, + {4.0, 0.0}, + {4.0, 1.0}, + {3.0, 0.0}, + {3.0, 3.0}, + {3.0, 2.0}, + {2.0, 2.0}, + {3.0, 3.0}}, + {1, 0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, TwoPairMultiPolygonNoHole) +{ + this->run({0, 1, 3}, + {0, 1, 2, 3}, + {0, 4, 8, 12}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + {3.0, 3.0}, + {3.0, 4.0}, + {4.0, 4.0}, + {3.0, 3.0}, + {3.0, 3.0}, + {5.0, 3.0}, + {4.0, 2.0}, + {3.0, 3.0}}, + {0, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{3.0, 0.0}, + {4.0, 0.0}, + {4.0, 1.0}, + {3.0, 0.0}, + {3.0, 3.0}, + {3.0, 2.0}, + {2.0, 2.0}, + {3.0, 3.0}}, + {1, 0}); +} + +TYPED_TEST(PairwisePolygonDistanceTest, TwoPairMultiPolygonHasHole) +{ + this->run({0, 1, 3}, + {0, 1, 2, 4}, + {0, 4, 8, 12, 16}, + {{0.0, 0.0}, + {2.0, 0.0}, + {2.0, 2.0}, + {0.0, 0.0}, + + {3.0, 3.0}, + {3.0, 4.0}, + {4.0, 4.0}, + {3.0, 3.0}, + + {3.0, 3.0}, + {5.0, 3.0}, + {4.0, 2.0}, + {3.0, 3.0}, + + {3.5, 2.9}, + {4.5, 2.9}, + {4, 2.4}, + {3.5, 2.9}}, + {0, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{3.0, 0.0}, + {4.0, 0.0}, + {4.0, 1.0}, + {3.0, 0.0}, + {3.0, 3.0}, + {3.0, 2.0}, + {2.0, 2.0}, + {3.0, 3.0}}, + {1, 0}); +} From 24d29bc3791f20293fe78ceb9166a4801dc91d44 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 26 Apr 2023 10:57:11 -0700 Subject: [PATCH 02/63] Python API for linestring polygon distance (#1031) closes #1029 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1031 --- python/cuspatial/cuspatial/__init__.py | 1 + .../distance/linestring_polygon_distance.pxd | 17 +++ python/cuspatial/cuspatial/_lib/distance.pyx | 30 +++++ python/cuspatial/cuspatial/core/geoseries.py | 4 + .../cuspatial/core/spatial/__init__.py | 2 + .../cuspatial/core/spatial/distance.py | 101 +++++++++++++-- ...st_pairwise_linestring_polygon_distance.py | 117 ++++++++++++++++++ .../test_pairwise_point_polygon_distance.py | 7 -- 8 files changed, 259 insertions(+), 20 deletions(-) create mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd create mode 100644 python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py diff --git a/python/cuspatial/cuspatial/__init__.py b/python/cuspatial/cuspatial/__init__.py index 2f3a27267..b281c80c4 100644 --- a/python/cuspatial/cuspatial/__init__.py +++ b/python/cuspatial/cuspatial/__init__.py @@ -7,6 +7,7 @@ join_quadtree_and_bounding_boxes, linestring_bounding_boxes, pairwise_linestring_distance, + pairwise_linestring_polygon_distance, pairwise_point_distance, pairwise_point_linestring_distance, pairwise_point_linestring_nearest_points, diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd new file mode 100644 index 000000000..82a4f1834 --- /dev/null +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd @@ -0,0 +1,17 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +from libcpp.memory cimport unique_ptr + +from cudf._lib.cpp.column.column cimport column + +from cuspatial._lib.cpp.column.geometry_column_view cimport ( + geometry_column_view, +) + + +cdef extern from "cuspatial/distance/linestring_polygon_distance.hpp" \ + namespace "cuspatial" nogil: + cdef unique_ptr[column] pairwise_linestring_polygon_distance( + const geometry_column_view & multilinestrings, + const geometry_column_view & multipolygons + ) except + diff --git a/python/cuspatial/cuspatial/_lib/distance.pyx b/python/cuspatial/cuspatial/_lib/distance.pyx index f3d68717e..972a112c8 100644 --- a/python/cuspatial/cuspatial/_lib/distance.pyx +++ b/python/cuspatial/cuspatial/_lib/distance.pyx @@ -13,6 +13,9 @@ from cuspatial._lib.cpp.column.geometry_column_view cimport ( from cuspatial._lib.cpp.distance.linestring_distance cimport ( pairwise_linestring_distance as c_pairwise_linestring_distance, ) +from cuspatial._lib.cpp.distance.linestring_polygon_distance cimport ( + pairwise_linestring_polygon_distance as c_pairwise_line_poly_dist, +) from cuspatial._lib.cpp.distance.point_distance cimport ( pairwise_point_distance as c_pairwise_point_distance, ) @@ -142,3 +145,30 @@ def pairwise_point_polygon_distance( )) return Column.from_unique_ptr(move(c_result)) + + +def pairwise_linestring_polygon_distance( + Column multilinestrings, + Column multipolygons +): + + cdef shared_ptr[geometry_column_view] c_multilinestrings = \ + make_shared[geometry_column_view]( + multilinestrings.view(), + collection_type_id.MULTI, + geometry_type_id.LINESTRING) + + cdef shared_ptr[geometry_column_view] c_multipolygons = \ + make_shared[geometry_column_view]( + multipolygons.view(), + collection_type_id.MULTI, + geometry_type_id.POLYGON) + + cdef unique_ptr[column] c_result + + with nogil: + c_result = move(c_pairwise_line_poly_dist( + c_multilinestrings.get()[0], c_multipolygons.get()[0] + )) + + return Column.from_unique_ptr(move(c_result)) diff --git a/python/cuspatial/cuspatial/core/geoseries.py b/python/cuspatial/cuspatial/core/geoseries.py index 9ff85a7dc..cfcd9051d 100644 --- a/python/cuspatial/cuspatial/core/geoseries.py +++ b/python/cuspatial/cuspatial/core/geoseries.py @@ -200,6 +200,10 @@ def point_indices(self): """ return self._meta.input_types.index[self._meta.input_types != -1] + def column(self): + """Return the ListColumn reordered by union offset.""" + return self._get_current_features(self._type) + class MultiPointGeoColumnAccessor(GeoColumnAccessor): def __init__(self, list_series, meta): super().__init__(list_series, meta) diff --git a/python/cuspatial/cuspatial/core/spatial/__init__.py b/python/cuspatial/cuspatial/core/spatial/__init__.py index ee07838f9..756e5ec88 100644 --- a/python/cuspatial/cuspatial/core/spatial/__init__.py +++ b/python/cuspatial/cuspatial/core/spatial/__init__.py @@ -5,6 +5,7 @@ directed_hausdorff_distance, haversine_distance, pairwise_linestring_distance, + pairwise_linestring_polygon_distance, pairwise_point_distance, pairwise_point_linestring_distance, pairwise_point_polygon_distance, @@ -27,6 +28,7 @@ "sinusoidal_projection", "pairwise_point_distance", "pairwise_linestring_distance", + "pairwise_linestring_polygon_distance", "pairwise_point_polygon_distance", "pairwise_point_linestring_distance", "pairwise_point_linestring_nearest_points", diff --git a/python/cuspatial/cuspatial/core/spatial/distance.py b/python/cuspatial/cuspatial/core/spatial/distance.py index f48f6a432..da71fc157 100644 --- a/python/cuspatial/cuspatial/core/spatial/distance.py +++ b/python/cuspatial/cuspatial/core/spatial/distance.py @@ -8,6 +8,7 @@ from cuspatial._lib.distance import ( pairwise_linestring_distance as cpp_pairwise_linestring_distance, + pairwise_linestring_polygon_distance as c_pairwise_line_poly_dist, pairwise_point_distance as cpp_pairwise_point_distance, pairwise_point_linestring_distance as c_pairwise_point_linestring_distance, pairwise_point_polygon_distance as c_pairwise_point_polygon_distance, @@ -443,7 +444,7 @@ def pairwise_point_polygon_distance(points: GeoSeries, polygons: GeoSeries): raise ValueError("`points` array must contain only points") if not contains_only_polygons(polygons): - raise ValueError("`linestrings` array must contain only linestrings") + raise ValueError("`polygons` array must contain only polygons") if len(points.points.xy) > 0 and len(points.multipoints.xy) > 0: raise NotImplementedError( @@ -457,19 +458,12 @@ def pairwise_point_polygon_distance(points: GeoSeries, polygons: GeoSeries): ) # Handle slicing in geoseries - points_column = ( - points._column.points._column - if point_collection_type == CollectionType.SINGLE - else points._column.mpoints._column - ) - points_column = points_column.take( - points._column._meta.union_offsets._column - ) + if point_collection_type == CollectionType.SINGLE: + points_column = points.points.column() + else: + points_column = points.multipoints.column() - polygon_column = polygons._column.polygons._column - polygon_column = polygon_column.take( - polygons._column._meta.union_offsets._column - ) + polygon_column = polygons.polygons.column() return Series._from_data( { @@ -480,6 +474,87 @@ def pairwise_point_polygon_distance(points: GeoSeries, polygons: GeoSeries): ) +def pairwise_linestring_polygon_distance( + linestrings: GeoSeries, polygons: GeoSeries +): + """Compute distance between pairs of (multi)linestrings and (multi)polygons + + The distance between a (multi)linestrings and a (multi)polygon + is defined as the shortest distance between every segment in the + multilinestring and every edge of the (multi)polygon. If the + multilinestring and multipolygon intersect, the distance is 0. + + This algorithm computes distance pairwise. The ith row in the result is + the distance between the ith (multi)linestring in `linestrings` and the ith + (multi)polygon in `polygons`. + + Parameters + ---------- + linestrings : GeoSeries + The (multi)linestrings to compute the distance from. + polygons : GeoSeries + The (multi)polygons to compute the distance from. + + Returns + ------- + distance : cudf.Series + + Notes + ----- + The input `GeoSeries` must contain a single type geometry. + For example, `linestrings` series cannot contain both linestrings and + polygons. + + Examples + -------- + Compute distance between a linestring and a polygon: + >>> from shapely.geometry import LineString, Polygon + >>> lines = cuspatial.GeoSeries([ + ... LineString([(0, 0), (1, 1)])]) + >>> polys = cuspatial.GeoSeries([ + ... Polygon([(-1, -1), (-1, 0), (-2, 0), (-1, -1)]) + ... ]) + >>> cuspatial.pairwise_linestring_polygon_distance(lines, polys) + 0 1.0 + dtype: float64 + + Compute distance between a multipoint and a multipolygon + >>> from shapely.geometry import MultiLineString, MultiPolygon + >>> lines = cuspatial.GeoSeries([ + ... MultiLineString([ + ... LineString([(0, 0), (1, 1)]), + ... LineString([(1, 1), (2, 2)])]) + ... ]) + >>> polys = cuspatial.GeoSeries([ + ... MultiPolygon([ + ... Polygon([(-1, -1), (-1, 0), (-2, 0), (-1, -1)]), + ... Polygon([(-2, 0), (-3, 0), (-3, -1), (-2, 0)])]) + ... ]) + >>> cuspatial.pairwise_linestring_polygon_distance(lines, polys) + 0 1.0 + dtype: float64 + """ + + if len(linestrings) != len(polygons): + raise ValueError("Unmatched input geoseries length.") + + if len(linestrings) == 0: + return cudf.Series(dtype=linestrings.lines.xy.dtype) + + if not contains_only_linestrings(linestrings): + raise ValueError("`linestrings` array must contain only linestrings") + + if not contains_only_polygons(polygons): + raise ValueError("`polygon` array must contain only polygons") + + linestrings_column = linestrings.lines.column() + polygon_column = polygons.polygons.column() + + return Series._from_data( + {None: c_pairwise_line_poly_dist(linestrings_column, polygon_column)} + ) + + def _flatten_point_series( points: GeoSeries, ) -> Tuple[ diff --git a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py new file mode 100644 index 000000000..f092b6023 --- /dev/null +++ b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py @@ -0,0 +1,117 @@ +import geopandas as gpd +import pytest +from shapely.geometry import LineString, MultiLineString, MultiPolygon, Polygon + +import cudf +from cudf.testing import assert_series_equal + +import cuspatial + + +def test_linestring_polygon_empty(): + lhs = cuspatial.GeoSeries.from_linestrings_xy([], [0], [0]) + rhs = cuspatial.GeoSeries.from_polygons_xy([], [0], [0], [0]) + + got = cuspatial.pairwise_linestring_polygon_distance(lhs, rhs) + + expect = cudf.Series([], dtype="f8") + + assert_series_equal(got, expect) + + +@pytest.mark.parametrize( + "linestrings", + [ + [LineString([(0, 0), (1, 1)])], + [MultiLineString([[(1, 1), (2, 2)], [(10, 10), (11, 11)]])], + ], +) +@pytest.mark.parametrize( + "polygons", + [ + [Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)])], + [ + MultiPolygon( + [ + Polygon([(-2, 0), (-1, 0), (-1, -1), (-2, 0)]), + Polygon([(1, 0), (2, 0), (1, -1), (1, 0)]), + ] + ) + ], + ], +) +def test_one_pair(linestrings, polygons): + lhs = gpd.GeoSeries(linestrings) + rhs = gpd.GeoSeries(polygons) + + dlhs = cuspatial.GeoSeries(linestrings) + drhs = cuspatial.GeoSeries(polygons) + + expect = lhs.distance(rhs) + got = cuspatial.pairwise_linestring_polygon_distance(dlhs, drhs) + + assert_series_equal(got, cudf.Series(expect)) + + +@pytest.mark.parametrize( + "linestrings", + [ + [LineString([(0, 0), (1, 1)]), LineString([(10, 10), (11, 11)])], + [ + MultiLineString([[(1, 1), (2, 2)], [(3, 3), (4, 4)]]), + MultiLineString([[(10, 10), (11, 11)], [(12, 12), (13, 13)]]), + ], + ], +) +@pytest.mark.parametrize( + "polygons", + [ + [ + Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)]), + Polygon([(-4, -4), (-4, -5), (-5, -5), (-5, -4), (-5, -5)]), + ], + [ + MultiPolygon( + [ + Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)]), + Polygon([(0, 1), (1, 0), (0, -1), (-1, 0), (0, 1)]), + ] + ), + MultiPolygon( + [ + Polygon( + [(-4, -4), (-4, -5), (-5, -5), (-5, -4), (-5, -5)] + ), + Polygon([(-2, 0), (-2, -2), (0, -2), (0, 0), (-2, 0)]), + ] + ), + ], + ], +) +def test_two_pair(linestrings, polygons): + lhs = gpd.GeoSeries(linestrings) + rhs = gpd.GeoSeries(polygons) + + dlhs = cuspatial.GeoSeries(linestrings) + drhs = cuspatial.GeoSeries(polygons) + + expect = lhs.distance(rhs) + got = cuspatial.pairwise_linestring_polygon_distance(dlhs, drhs) + + assert_series_equal(got, cudf.Series(expect)) + + +def test_linestring_polygon_large(linestring_generator, polygon_generator): + N = 100 + linestrings = gpd.GeoSeries(linestring_generator(N, 5)) + polygons = gpd.GeoSeries(polygon_generator(N, 10.0, 3.0)) + + dlinestrings = cuspatial.from_geopandas(linestrings) + dpolygons = cuspatial.from_geopandas(polygons) + + expect = linestrings.distance(polygons) + got = cuspatial.pairwise_linestring_polygon_distance( + dlinestrings, dpolygons + ) + + assert_series_equal(got, cudf.Series(expect)) diff --git a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py index 199c41208..49fabec39 100644 --- a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py +++ b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py @@ -124,13 +124,6 @@ def test_point_polygon_geocities(naturalearth_cities, naturalearth_lowres): gpu_cities = cuspatial.from_geopandas(naturalearth_cities.geometry) gpu_countries = cuspatial.from_geopandas(naturalearth_lowres.geometry) - print( - len(naturalearth_lowres), - len(naturalearth_lowres[: len(naturalearth_cities)]), - len(gpu_countries), - len(gpu_countries[: len(naturalearth_cities)]), - ) - expect = naturalearth_cities.geometry[:N].distance( naturalearth_lowres.geometry[:N] ) From 3935a84985984aea06ea1c66a01254d79932224e Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 26 Apr 2023 13:24:38 -0700 Subject: [PATCH 03/63] Add Hausdorff Clustering Notebooks (#922) This PR refreshes the hausdorff clustering example as a notebook. closes #1013 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) - Mark Harris (https://github.com/harrism) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/922 --- .../all_cuda-118_arch-x86_64.yaml | 3 + dependencies.yaml | 5 +- notebooks/target_intersection.png | Bin 0 -> 903245 bytes notebooks/trajectory_clustering.ipynb | 705 ++++++++++++++++++ 4 files changed, 712 insertions(+), 1 deletion(-) create mode 100644 notebooks/target_intersection.png create mode 100644 notebooks/trajectory_clustering.ipynb diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 17ee1fe25..71950145f 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -10,6 +10,7 @@ dependencies: - cmake>=3.23.1,!=3.25.0 - cudatoolkit=11.8 - cudf=23.06 +- cuml - cxx-compiler - cython>=0.29,<0.30 - doxygen @@ -18,6 +19,7 @@ dependencies: - gmock=1.10.0 - gtest=1.10.0 - ipython +- ipywidgets - libcudf=23.06 - librmm=23.06 - myst-parser @@ -35,6 +37,7 @@ dependencies: - python>=3.9,<3.11 - rmm=23.06 - scikit-build>=0.13.1 +- scikit-image - setuptools - shapely - sphinx<6 diff --git a/dependencies.yaml b/dependencies.yaml index 8da626ee0..6b79c0959 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -170,10 +170,13 @@ dependencies: common: - output_types: [conda, requirements] packages: + - cuml - ipython + - ipywidgets - notebook - - shapely - pydeck + - shapely + - scikit-image py_version: specific: - output_types: conda diff --git a/notebooks/target_intersection.png b/notebooks/target_intersection.png new file mode 100644 index 0000000000000000000000000000000000000000..0670a1968a02b9d7237aaf099de30d537690da17 GIT binary patch literal 903245 zcmXt*D1{r07%w z00BS`s%ajS7xu-f!RhfszPmXyHAsbuA+`P0_m5$kY{%@cDZgq7(2*~7an^t~#vWQO z&`7CwcXoL(Jka%u*ewyN*~xtm`ucVm^fHRv6q8uo`Zz=3Om$2xlsGk}G{6~Qd6qXS z4jPY1P$g{Mn||b*sMP|6+7xMD;Rs{V>-Ald)=Ut*Tj6$jhLA%Q-=O64x=0YS|5K0^8b`$tgFx zX!KjMp0I@@lmgP>wzawY3b~}(TLF%#m;eMD5wD(_J|OL(uq3yts);xmTPe8Lw#L2% zfu_M7*c?At_Iam|^?|Z-VU;-XAZb~FgO1-@&Ex7R7>RmUGzH{@Da)#K*}RGHc+8DT zUxLFTRKpK-tGa39tj32pyN<=f8mz0*bp3pso$3G+%jl(ZykBV6`tiNyJ z{ySI~jcHx44apGTg8iT`P{(f{!RWKiDVa1`XP&Ul7_?Wk9+vxT%#t%zmj}4x1A>m0 zwV*hsHtPikuD2U7_nxVMX6qk(a9EzJUW zNJt}BOoz4YK?^IJi?~2c;utHg$?Z1=qm7q(^7m{3i)Vw}3;%fMCZUSS)cwU%*t^Hg zxg|?1DZ9CLp&ym4czES2HvH8MB(V~O_i%sOeW5NlUFXX39?ZQ#TT9;X$x8D(`+G}0 zvZC|_2-0fV`*>jM)_84P`clbKxWaaTcEavq^_XJ0<%tQEmdy9^Hyi$z1-J8$`6D;1 zaGw~r@iSY;{wy8)7UR9lOiZRbQL#K}UXIw;tFo1E;if{eCI~T@!JLY+yd+6cCWW!q z=7){K=Gn!%!&=NIOY?$!48*5xk%`nH*)~#(W57@Yo7qDPXzGW;6ptJI#)>fxjh1&_ zI2SMe0(8|k4$LI&?YW&1E-(I@JKgY#{5PS)AMtNN zq4VU8vvFa^W!14)e!(ilxKOPzHG=e@^L)04hCIeqA$M!KbN9W1B(~$9FTVswyk~RU z7e(U0R>ZGrOw@b!>L~}M(y-655UDmf1OZLNf)M92Ax zWaP>C#pZOxA-}SP;K!);2vX}tYbz#c`k9v2tBykRsZrovZS~5>@Egxgi#9?7Heb@b zQgxDgT*na)o4md5oux0P`%7+WHLSD!H)D@nZY^U$7J4w42GsJjvF9d_63dO4-FzC3 z03NO9vx3D{dSF>?4Pi<^tk~yYYj(C(VZ2}nF;*9(WjV~dYUuN8En{v}8-N1vR z(N8+vs$1y*`*NpWWD2t<^F3j%-|6j<_Q)RdFG5f$sJ7hKbac-m9{M^P2fNdS7uBf6 zR5!VfW3kW)^UjOuxz5k)qg@8({yF8-b=a7W$3M;)BUdsnCcH?ep3Rp%k;el)wR1hY z@dV?D9TKr3!VaMU4PPgFcQm!6!x*`gc{yv*xr?8F_l~J${u%OkTTtH2RN72d`_(*X zcc)^cVMN;5-}?1umm6A;ufw4bRyMGynUwwFA`@A$5Bm^?`aYTx1fT~CoMo^6Pt{k_ zqF^$fT4!aQ$Lysl3*+u;5Q;=&grSeMrI=FC4WfR)Px1s-lZ&H+h*^CwY;1xpn!A zvFD74SF)Y6;?3^}J5kQqJMXJbhl{~r8f*q-gXuolKHy@4c>dd=CCoP>ww!~Idx*J7 zDU2*%DVCs%ziVsjncLLvyRjTJb@79sj%$j?xSIQO_m3!eValu4LmI6IOavXUlP4z| z_#=nlGcc;mo2NBDK}E+Tn21pRI$KyJxwd*hQP(kLdz2khK+=Wz3Tl4G{=w*-9BOq@T%p zXUl;M*vyN1&ACy|HCbw7Ta%O(+-{k$REgY2X24e|WDDP#$8jt2JJjgwi^;E)_VAoGF(5G~>KZc(#xwonEq6y@>?p{^C(p`6uGNP^Tn= zr-PvEZu4%|u;&9CibgFiB16mC3crTlJGIpeLGp zAlD!Id-UFsplCShIsM+E(aD6&Ie^$+GI=(F@AEtHk&!nQO70+P`w9ApDf=z?;El99 zNb@eAxvvdJsI!)Btt_iRmygD#lVcywh>RezJ1 z06i*tGTm1ki4=V|nD|4^@TSDQlBOsg08=t-Pfg*;| z1%pa1qjyCyY5bixFdsbm9Wxw*m;yq9EdAXCNbu;QwaPfVmhd7Bm*{AxUqE7lK#H@N znIYpXRA8C?VvnPjVZ>1W$n&0CoqJ`H;eQ|4oldHg(j+fu3d0XxONO0J7GlN13D4|8 z5BFB;E{7#Mk9WFNym@_6WZni$s0#H#c1S|+a38I7&6Z1OtuxlR3Cv^6;wpM{f;(F2W)Tps>MI0bqIh5eA znr_@!nF0USqM@tnUaXK3ku!WE;c?uv3$e9cozISC&yc;4j^Rl}_taUx!>fF641I&O~EE+MZYOh4n~2;f@L8XEDS4CDz_-!WuVi4Fz+WzGQ*fwLL1FCGwxT39d&0GwlkGSl z!JOiFtJq+lMeq0&^H|MaqDJ})4Y_#1Y1y0UR2 z*I6WBv)x$9Mu>}5elnG;>p5qIbuYlSDN=do_xf586)>sDcBek^=VO~G96mrF-k{8Z z4jPtOEsC3^Q11M?vAk!$r|a@U@rEF~6tbzgrAeQUNgN@o0g>qv)6}B$0Z=IQu)T!X zxzI4eOhW?~oE$)znSp&1V|OQd9`mb4DAMB^_6-ZgT3E2OHu83r=+qgWx)f3B<932% ztg9LWCiOd$qoLm~YI#Hk7w7rd)$y;PwRZ-p8?(nMmP~jH>J{LE&JTgz-|RlC}x zJ=&ow=rcn5e5XQvf2HpHY8*R1%%APJEIePWYY)1JyV%>1v}^a=kfOiGVq~^`R)pqM zq*yzh1-9qf%iu;v57BE(u`^1HXiSKAi_$$?*%;;ik|_wI&8=*LepHH}hlB*~Zqy^h z)MyQIFwuI_qplSn!F|d}DvoRHv{gWog@w0VHq=FYAx1kr4(8xd%9r5#(|Or4e*P3x z8|U3TcWe`Qc$%>)mx{=+yX}T#Hq96^3vVcmq9p@w+Piz0QDmWc>ZTEF*<9%2Xt|?= zPyDAu)srmnMk}o#QxRHZ3RzFSIFrH4&oAq{Q-s0bBRI4VW~<$%12>;>2muCt*x5Wi zc7$lLM}r0>KrRfuee?LGK%6*PS9-bFO{r^nAaLz_EFv$%9YFTKq=3RmBZcGbrh7!xJN-nl*lbDdUsYtOx9Az^hs2Vnf?`a7*&_|nVvDxfP;x}dN6We#SOfl0eEXv3tSo)X zy9PJkj`KJRLEMYnb!fr(h-IE_?V5&01ZPJtxATV#iI4=aZHK1&n?oYT$t+LV?sDI+ zc~Hd>(Z*}ThU;5&8^k?{vnX-iKAPOHXe-VVIV_j~lk3B^_7ZQz)F-m+RX5nM;XN~t z&Rkn+=9M+AYSvG0@wbOG&3xIWuQ9NXUY85C;+>E?a#|<;xtIS@cOpU^{erB#D2u$s z;qK3ZQc=n=a-~?`i$%A{jb%kj)y^EP1ntc1zssco1=9l$5cr7wn_0o**o9xWh?J~jDf;hfvbFf%N-(o|*c-csW; z;hDqqE!fBk!J>p5_h-ol#R{|S8o{PC#@OTCHXq=N(YCg>%->H%8O&l5VI%1eun=*D zL_V_colP4QKnGe@&3(?2TkMdWF9f!ihnP$~;lx#`U zlJ{(5?SVS8auxY!v3uN>f{R~GOVd;J_0YP@T`rt(#A{Akrh$3^ZoZE~n!+Lv#Rk=0 zi9D|GefR`b?zE{Me6fhJGSK@d3ZWwY9Qmmd_{A;duzPEXiM*Zy8lDU3I!oejvnwJ- zp6}*1>=VNYb(jB=E?t_59sl|yBld=FAr5A#h@>odip)zEWPzh1^O)v;_toj&`p#?} z3BD??0#Kk>lQ`fjS=xkw!@L|)dk}UVxMfN~VPd8u(L0})YjusH+MzMC-P$>gy1!R9 z$gJbOhCG$5oVJ;XSW8xp?`RCP$J2gX&|N8J7I*j@t3;2C?!^W}_OOSfZ~pgWb@&;q zqhiM%3od4j&c6R*6C{MF%fHN>h2pj2o-v|js@pl+5 zjptavJR|vs90#JIsdimFJ#`_cD98J6!c+6c(QH|W%D{afxZb*#^MM3S{8I)&Igba^ zTn+7M-^sM}%hI{{uc63IK%ZQyRho^v>~qSWaIO-YJkCV_P;BvZD+ZK3CFJz2_Y&?& zSMiv2dG&+wOYBEfGoZ*Q*%6ST`uKFI^-+$hhZ1qQZLclIqB#E-yxgn{IH|RvjrLI zLf??%HZcx)rYUO%9m#0%5M~5f6>uN;aH3~2#x&Liy-r)r3EEv={-rW^+`_+tn+w(h z!JuqB7L@KL`bJkrqpB$BCXmhBGk142RD_^9!(;EM%lX+>lCo!}rE3#cc0@GLI2Rh+ z2~lJfX3`X*GA^d=we4s*-KmJ&>pcHE-WhgEDLkik&q{&=dT@IFv8sA3Ak#Mhn=SKw z)S!oKNI)pXc~pr2p*~>Y|Dux|u}wT5y}UTEljN9+*Z_~o3JP(+#YQW8kq_gj3C6~W zWGI8X7MUYWvzvEe_WFCLo98a|_6!vpueI0OI%>5m-M~+f95xNs1%)=tkj&g`1e?iE zqel8%F@hXbnCE_-}Z7ceHeV@PW_seu$cH*?m9Esy#H8I*39UOq(>jKJ&$pD zB5dK8qygO+p(QN<8ZetY3Vwo|qIst^CyTF^pMF)gcE8kD79(Ep^-daL$mBMm2>O9~)__wkJ-fXdbCei}~R zr|^xUwKDgWSk`71M<%ZQ%%7^xYl`LGoD=k~#-4NE zHdnj(w@tN7x<4RCMn#K-azrT;{xhB>n=Y9=Cr58+R83Ke0`kXt+ee>~ui&Wd$ESMF z^KZ^lyaP4V==;#wrEd?|gi4GYJ##GMFs+z3P}ct*yu8H^q+W{((q&PkaWH}2`z{sd z=sT*`Y8{=1%ZS=Kwn2Dv4?J$3&g5vb7;l3M?l`t^u6jxaMlgmoa^dbWgnM?aFL7$)?<+9qnH-(T(U)5;mfWZY%8r5M!V-nijadyz?k0n16ncm!1_jB|&lX8f?S8!?bT4=DDV#q;;b7;GN#BYLt1S%8}9_^l?hM$A!F zdMjXJO;jcqlKL6T0i_m(JdYu+G&nSQ26u=R;)=H^RVk@-| zpyu+@hGs)tOxf94$tmau60=urhmG!!AIaYGSN*;)jFJJ<(sB;g@|$0M5n^Noy&9D< zz1@9~VICfDc5N0m1mdY%_{&!Yvb&qA(}49b6ohsWDPB~p!BGK<9541EkDw_w3F&e4 zJyJ%K;}NGX$B_Gy7xRo-JC}#*q>A{y#lp*m%iW8YG?#z9NI#d3=OT|b_1-e)Nz%EY z0EeUXy+zMue8BPIrh5xI^X%S9+~5znQy@CmCJCLpWunhzmMv?PHPZS{_WeAMtSk!S z78M4_g2cs()y~njP64@U{i$$;nN|mphr;q~V)nI|ut{o%0kyb*)O|r#6=Pkf!6?f7 zljvezf*x2(#rDozTSeqK$J|B?Es*?cfO>at_vNJe$(8&L3On0!FpT~=r?L-p8}%aj{Qc77HawEOnqSgFU}+Sy zlIN@%d{4Ua$-~>QgZrx$anK&Ad>eQ5-~e{V2HtYmB>U_662W{vetdiA2FW-wpx*X< z=6lA7iMw;8qvjats`b1Nd?FMZZ49G{7V(oMLBWl9>#gJO>3I`VFn@6>pm#LkXMCU3 zP4L*wl2xWZ0g?T^R_<+cH2gW-7+uKBsDYtyJUes`8xT3$Dopx-50xk~1 zr6&ojVhTqKXxZU5pKs08p7tVr2kV=QvpvQwoaO0^@#Xr{cOUA5Q-bdFLLiibj|>jq zJH+kS1d$YIz|3FsJVVCGQLh4ts{f>CX~E#30}Ul|lyBYx!6WR%sBc!0wQN64^egZ; zllS~FX@@C}%F4E#m;c%eFJBj)%@mTpcAh(5zVuZqOXv!_^X5NSVZetEjA~EUQpe_7 z*D+%s{r4{0Fx>g3GyVSCx0-nqgzLr*y3~;)dGs=uj||CdenKGS7?HWtZN|=j6UO*< ze|-Vzhj_)Uvjv|99ZJF%RwbOfXMP@b_?9e7$_vlgXP}&Ntyie(+6PN=UxIxb zA4!T6bAWCYAgdhSdn)bJ?l;R)pY0i_((;`qFbUzqJuqWJq1T8Z$>W}($a~+>RcdUV zuI(eZNP3+z1IRUBxNosu14r8dBDj-ul?oqeIc{T@M$^K zfsH^nz3K7CZ30~^DjC5NUvMR5rG0KdxD>3JS+ zvk3HnuP|renRi|sI-MNZ(1D_T05)Zlmu5-K@b)T>_LMvjuT_G*P7eB z)Wc8S6FY+<0{lC8sT4ClJ-WlkTeuw%%Hij$R<7w>6X zXudn=$dF6?4%rM5*zw12#e_^Gkc5@FhSp2D%U%B@_5L(`)TI5`ds0G+Ub0Y?R{F(T zrvHTJ0v|TJ_q&ebZGD=YMrKt$BOm1lVpYZ_8P#SvbI6z-qz9Fv1U0t<%9cMWKSB?G z^dC7~q~R}=POHkHm6c*i%@whfD6;y&;e{m=xT&eNT8SA2J<4$!OAKfe{1=CMVJ0s? zDQ(io`76}zxyU9;>g+P`0-U>I(wzwZ#zhnM(V;#T-Tdy zHWhk$jPqGDwqP%c3&TFj`$E`DjIBPhiRq8l*?Op-&8W0p1)_%|O*Xf`V&3~0*%T&= zGL0R1+Dl3vrJNl7E%xL&`~0Y`?;TQNP1we@$VwFeZ88DZ!L$xbpT-5;s4;KTDjg<+ zj`Z7zr7N@0!F+di;Ikzrr*Ewh5PYP` zpXZoU{?#2HK_9ig)~+2B6g-nzV{ZwYX3I|nP?azlyBKeSN?3Y8TM;G?ER&jba8_m0 zRQx=+qw{P&s8dq9*mqWinCG}UBmy?M!&%vVRFn5|{ucqWn0^ghs!5hjp%8BZBKz=E z3|e%UAn_XV((Nuskc96jRuO6p#YbTB0ux~}5F~;ylgu$v`O2Z3deq)Nlj97NIB9Nf zh|uR-twm9kc=Y!c%as0jQ?*BCU2w!D6`wJaJ8l6LM#wZgv%1DSQAA_>gH=n)r&2U$ zP`2)O8eR^?E{MVX28R-yb)aZu!W!ATy_OqrKTaFj@~8d2C#nzSPu5qEbw~{ckgd&j zZGZ~+x?pK~PWj1B52O0|PD$jk*X35{iNfXd9H~wHcwhbUSPPW+YhSa9+#a?}Q>Yqw zaysQ4xh{*VuH}yjpX<{&vu)}*+Qr8Ndfn6TX<3sJF_o5;D&t2KW;z(&a73fgy#`(s z<#BOYGjj!&c|Qtrp8x1|{S^p5Xf0)|+^lx!?dsOyA5M4*poZ%ArF`W8dve_}(aM?4 z9iI^22wRKo?kz_|csm!+K5B4xz{m8LK2%G`emq5+u(@+qsl}#ud+#v8iOdJAy)x^s-Xej*z-6ife=VBNb zggXtN)hZ0quOe>1s@-SMN!(fx?YdMRWQ0QG$s#!BJ7R{Ag9ud=RLY4lk z{`gJJwPaRN?IDaF;-h8#voEqb#eZkwr|qA6NBH}EfqsJPr~S@LV`K{*-;5`V>MHsd z^loH1I_%1sL)@tF>(NDv{}JHQ7S1!~m#vT+otT<`o;JvkcPqf(M%Guqs`9f51#dDz z(a1FfmnxSe-a5IIu{sKxlrxz8b*wEuWB$gEGlbHfV7z)?KzK@KS`&CzO0L_-(0(2I z$6UJXcEi_E4d{_}$1fx2voGo@##TS>0?GZGS;RcPfnk0xg(SYqUQ(!z;gY0nyF}Tt zwYl@XRx(bZDpBb-Bwe}l`M*;HwbK*BWA7;_t{@v*O^MQ2`|;1G8J4d66S0H#$5KGd z5iGp}uR0Zd?Isr=MF47R15CAI92Au1c~kyZ zd3vi1iqt{j2nfJ>_@l%qMeP%d5|fz$Ag4HXAqn)0bNSS~o99wr%>F(!^5E8G2j**< zvvK5EbA&&YT)A9=*>nQ# zt?rpCVZ-D}j49esetNt`4FAJOBFu&Ud((OGuV*}RXMS66s0^2QwR}sT5+evLq968~ ziFvA@LtD{aPsC+|iA`<10$4pNF1ZQ8MPx%@V(uiSQgIbF@9{9w%s`ffqDY&A2T*N| zBpm&f7K;5!tHJzGLKSEkr*B%5){7O*p5NoZWah!LZWwMITes zn>lwnmh<$*+_V%~te(2fp4{M)xXOFyLU#s{P5~h2y244#bbmzm&l({BLYv+*>_4C+P$4;y)-VMbwA? zPWmkoHnl!cZ^vIJp>Q_UYB*6|MZZ+p$CCzNI^G+9D{7?|(?*bqqS_DV%LQI*KlKqU z11N<(a}EP=W%bq7(J%R<{~mmL50N%&vnWR0IS8T_e zvF??Dd#v{$wX~K_clkv;!X%A!B>ppFzsT*eSTx8DvI;LeI_r49)Z~Jd^20kcrnfvJ z-`$)ESdU}V=sn4jRgtAgfw1P`TSKk&w@>8~WtQ&%?DE2t4TqT4$jElwvH#ZFYBvL| zQSmbV$q5XXj$X?rkHIwaYa>-PNxz-P1G)z&S)yc6+?AXvx-GrKD#TiBYe2TPA2O%m zUzfwma=>GGHt9UOfcQphPi0DJGvc|NQ8!KA2iK}Vxd2yRCFOt?U3S{;6>H?hla|E} zevaz5x)mMOU%yM|<-ftJO&OXfy_&Y967fly)_ET|kA897<~a|KHvgX94Tx52`O!3% z(K5YEvTnqN9{&X#XqF`x3?lf-8^Ru zn8Y3R2p1<<$;)}%PIJH8bL5tg(dLU2D*Yqc zPp|eWp3@sMGQJ^8pE9GvST!QUkewBP>u_DKA3@nWpafvQ+5${NiNcw3<+G;fnADao3sDaXy9R771+BBd=y91^B@$*tNN_{H)QNCe(5SBbf{ z{O7U$nDpYG!KYeKMIu!SMi4??#jeMde7l-z_@>Zee5Ti6i&rEu#=-*ET6;y8vTHc} zKIFBK|J*;lR??hG=%phA9YlKt$N%TDZJ?4)?p&m4RP6AM9+3SC>&?@VHKpQj-+yvJ zu4qxdneR*|Yr<;!v6;6maYm^lyfx%>{XAI;%yS1f^^vc_{c1>;J>ia7*j)UsV$qy9 zwDLXwwuRRn=AegP1U?>TO?f{0w9&fzw!3C@Ysal`Fk9)PV71^MKTXB)$>c<1Bh)$m zEC~^<;I%xf*QWO9#Tc94^Im|O(v|z3X2D1F<`D~Ux%0PrJmR21^0KhbyMsHo&7NFC zWBx<7-8ZR80kN_f?ri+wqw$-UJ*hnAa#jR`xClA6yDw!PbTaic`nXEi{L*A{3b;cr zE2DK#KxR)}EUxU_P0i`}8EJ3d?ykA)Rl?+1`%Lz&nj%#L#7o}Z|G-O0S=Mk;b4Lpl z4ULImW)tS=|2vgyA)TxkFe`+`3%~L*y^i&A8Z1T}bc4yHQYwF|5c#rX6`@jQP}ZwN zCwxs(Au}_RgM-7l@MN@NT^z#v0U(cxfdJ3bO1@h6rBeheUKPP=L;PUCT>Dw>o7S8M zHxgpu5&%;+w~w}XPj4TShO>*lBJY=13+Nr~p}$k29l z=gCHAPX8EVq) zaJlQjf8Msz62^}jJUKvUR9^0$3sTyrEurw@&)K+ouzVRgr5CoA{ymyWN=P@VWa;SK zA#~&C-nyGzoTARk<>f$#&YO1+o&adTg4ij~y^3yL@QDJXLRP3F6fJURWPJv{xr z*)Lb$olHLcZYVP(EL#vXp{p~aE6X}aMoTV0{eZ>AFVNqkrT2*4u7fza07F_RaEDY3 z4-NQ$?MC0Wh@d^9+5XF;X{Cx>i?+Uyg*@kLGE-{ z7vB^kuRA^qnF5=t_Z=d|90r%I(@LUS8D>wqQ0(ModD?vth{H|S#F;B|xkuV?A}?@L zQBh&qdn9bd0SVI3g%8W!H_P8u0_MpP8JWe2dO|00OWj(8p%hFU7jwuWQ(jz-psWQV zt2`aP9mry;Nxsv8iEVe((vo9lU=zuJh_RIe{Yp7j(*HpzDg7-h3;aZ74tu>lZ_s3ibB+2vMV~5rV5*ZYS6Z$wCTph|I)H-|Bxv zRnm%N#07~Md6{&v)+TA!aXQj@KC%^XJa>VMJZmS06TKpLUJ}L&FaN5OW&^Gi5pA7U z!05usNHq-yA;kCW-{M}b-P!5b)P77-p>=22!{L8+q@QF5@}|Cg2q=|{vdW2O@78%cshNZ}Sro;X>7S80cE^4VjQK3|0`nL|%zMW5+!N*Aa}~4z zdl5eGj+bX(BVlX?{^PC3bx;v4e?-_u_wQPHRC+^}war|B4T~cs%YWW+rj4vOzJzkV z;3t0SM1S5*th}%4#6VeICItb@$`q#+!wj|CJMp$&bxEXONhHomxudhKL;f$96=p`= zEx241s0;96l+h`_wDC$xkIg%O54^iZx+;@ zkFo3Ts$b4e6C?H?8+Y#JS6}Yy(CKnFFux;f*P|uZ5*C?|saF5fdGUHDJKJ3I@W;mK zxn%cf9QTW0lg%QN)n*d-6?i9rT29HL?SmTL6M|&qjdOt3<*tPKDB2PcvAtO( zo)Rmba;VK+PG6p?xgEm&E^uAYlB|u+X~J^Y4G>$&&CPW#yqnwLq&E@DA+El1-V!5? z8W-ALjkq9&9L;rru6HkcG6D7%3WCG5bbT1mt-&0@wY;6)j-%UR{!p8!RoXqk1K zwT)L{`xnwq34uVU&duGT;SURnXxje0y14hnEw^eOV}+MhRLlJa2cbBh=@2$x#LC@4 z(aD9iJawK#^m*OoxgC)~A*oRHgmgT6r;I+F-;sGrtlU-KxX?|XYggDls2!iC_YKSp zjJ{-G1}VlS>&Ss& z0^SwgmxJ!?CLTN8*Y2HGXj@V=tP)P+8JXHzIDM{)lk4p0aLo;wxl8f+NiyZ_mSoq* zp{NwgnH$WM1bx96ZXQE3P1|%=xhcs_PJ;$cs><#gasdDojIMuG5Y+!2NQeJ;&h0xb zfoTdo`1uG1jMOx{T1iSulq<^14|w|+Oe#L~W(Pe8S{?=8;oMd%S6nCVL$f-cK{glWL9{_hd4XID{q9J@c$ z`d=BRh8U-#3<8MLKA?XU5HY(QD9yo|y{q|(9zMU={aYz8yfKs%hLhOnNE$KBjOUBF znCQ`&p0-HhQ{NuwR9?=~0P5I+))X1o2abB2FvetrGh!;GSnE)R>S?yi#T z4}|8q@UV9N>Yr!jv%F@y@Y3|#SYMm7CF$^$>P*UzO~=V-a|r5Uouf1O_?cbs^Wcka z^)Jfmk30EfvjPpaKK?y^k+%^Yqj|byIsK%b4*hR2t!T~=v7t_K35}TPh=}lGOYx;& z)2$Ge#r^t~^Hbq{ zv+MURRyMSULQbB7&0JeGpkf)E*Hoq($$pw!L?HEn^1uq|BN5@iNUPu&{UJ|I;Rg;e5toIlEW5Q(pxSbBNs)m((Z+SPb{A)tC{Xo^11DVH zwZXO{X!rE|d~+|#IrX>t1-7~4BohBebm!_CnE%TJCf+l%Iy!o8(g0x|1Bq05jgx3n?Qr)ewI6c(yFw<4|etrHRn# zfNRodmK;r-9RA~t3c-FCB;q;NyG8rMLC;QZQlVfMSRnJG?VZsY{*pIC;H)gKu*sjz z(<(zB*SINz_IAkS*>)*G8q{!wshVB?z~Pc`u0=jFE^us@J!e1Hm*dl;BMbgW535#@72j)t~3+v4?#_ zby1E&xrUh7z+Z?0*ECG!p#@ahz7qERqgV?sxiMg#vcn5=O7aQ|59HAoE22Y8UaT$| zvm3$$#_ihS4ITW^+IISIs>y`D7^W1ZGC$SLvyQrr5ZjI3<#vm%`FzLU4k&1PS(#G39!2ynbEou!oE@H8KuQDC0!WG;JVrU@(=23 zPPlFAlQaH{t$O}jk=@*ebSMD-I%@xW+ng1U#k)vMD2VM+NkTU;4`td0)H(V;Vl1?Q z`E{gV#@g1x5M*cpJ>}|0^89_2w}qbby6em4UOphMWJL+EnKoK|JGqD*tw9USCp>q2 zCAqAPX2oEt)}ml%j6ImKF8_1lQu+&`^Z)4 z#D?2wdZHm|SP?}3P{a#wCgG5uadAHZ2+;3xsh zcchqanYy?y>0^5z<~L_t=ao2aODt%gMHDzlIEsy6i8rmfoZEWbQOub2sjb>749VL? z3&ckz@Z;61GTkYYO6xg7k7q*tzi%!gfT+^N(KqmK>-V4eeTlz-3hRfwZ$TRCJn?8Y z$9}cnGgf20qizC&kCcws(km01YguifO%E3y7fSG3q zk8HA%{2A}c6K#9iZ9q%5sjvB_T?EPm=2*m;R187iQ^VU)J$t`zHGSPlxwqGu<6k$kH9$rw6I z{j4}~(o&3Mn^U8u$@CqnIESo?d~{A+?%Oda-P9f4fTlJs*0qz7qC@XL!vCKIptUx5 zkyURrqiA03-|&Alo#kKC@7upJ5&-iMJpi)yDqIey!oa*7O-~U52&pD0Nzv zcwleyvR_>l8EE?j0iOA_4`sg$8Do;Z2eaPLcT-;gQKewPr2H`4b2sb(n@Vs-e zK-<~-E0e!Q=#tiA@F>;wfSk0@99sd6@aS}2H9ld4W%}=mGB}cCEhW4A{5w|xuMjZs z=D0mYCccR#qieKVQqn`DQ{yX#;>K^`tqSBDjeKHgQbmePTrmyug;f-yFTUOg<;(4u zYz@Z6(|e&m^LhbqYlbvnS>|tU!2Sy}^rKG7XL_1EuYlaVM6OXk;`NXjp(E7)yatIv zXRfsy0f~A{k@@dEP7xiLLn!L-;r=i?JDY1T*16WmL;h}d?4jl1KA53zrqUqx{F>r^ zWtv<~hkUVwVbY=w>)4o_3?1KDR&vd6IWV9HhDFk6YED<=$ONd9>7UE(pku$w)yezHM!HGG zkrE}fcwg$N7!$%VQWQrRbJREuERJEz+oB-j%}ZRN5ay90as>hpKVRLJiwEk-V)%+Ubnf=7Q7jV6{n5#xwYnQ#v~A6p-c+_L$a)l^;L{H!NGImksEd2g`cbn5b)Y7&EvBDxJgaXinit%$h#a@wj> zi|vPqsgyhQ$3sFHU{v9k97kycF=l#=o^2)qoA<8;Hrl)w4=x*{?hZ=i?{y}BU|)8W z)5Z&xudy`h#>kkh(7(6$7Z(?GA#xL*jYi^RBH7g~43iqM&rj{T8odSRML*x>sf~wn z0$ke{_sOxf92^J`3jJE5*Y>YY)sI}c4GO_wr%EcD|FCpl@^D)nWlBZ!tq8vPb@g8{ zo;~0V@OkkFzCHK59_VD}gqp!t+4`)=kUm)#>>ah%I^}DPC4D?PJ&=2kg*bYYEDvTt zx;HV>L-~7=)DOx7+3dstaEOvecVg?l9oLQ@MA-rP0dn1*n^(F&K8BU178I0xQd=VW zy)dYyrc44r{UZVD;}Rx9=bal}WKFz>Kf@3VP&JnZ5UDG-K6`URWfadh3A5V0SlJ4o z@j56^2dpc5aM^J`s&aSrEOWF^+S{;KA)P1ojY#eGsEjuFooQdoGkjbiTsb!yQY!=i zD3)!j^FBUm65S*_na@J67e;ac04OHLI{2s8Hn^2p)U>#I^_F}cH|HvB!8fbs_rnh- zJCmauz1L$w_X!+6ijOrK``rxAt_$YR7kYb8Es{g6kvJ8*bKODyGOQ>G3e*_uPfF0n z=8h-U!wPx9ZPqAx$1j4_y6)bb{L+6R{`(h7%KOCqYVYkN9ATw0GViGg_LVH2y8P~J z{?Di5X>yluGGLuC$w-%ZX*<7m4TD(-kIKaCww3v9WqWhci&1Ymns243^F-JX2o!IJ z+ab3AkEocX4{?E;PrCAIKU=Huyh{zcRQ?(zY`)4lqXd}&ECe$MjN4k z1rXhs$f5M(1AsPOmetET;99yz`pIO&!{{j{!F+ykuRkT0Hjf}c8I~v}@x`SXQukp$ zp}&D#(A-RrzWn;ViJ;}So|`OvblEumiVWVgAq)~PzDWU?8vW# z$NNjBEMDs+52B#i)IfJc>iC@Q9t4wvaweoeStRY z@H^hyKncqRxyxxbn^ye{Dw8!9w@9xfrQCEgpp<3pPf=SC*Q~p`T1z;jOQ0YN`*knm zWdgX;yU1GOnjSB}msK!_VS~a?)u!zLv%#Mfki}R#JVpvwT zyoo^SxuyKR_fvqVS*5Ce)1A<#Id0L)YU#1Y>1o;I)Ag-N`K^`JJz$?t+kSQ9+H{8> zW0tz(-MQQJJL4Z_&AJnW+`ZkxKn@{{VctTeepa${s^4HG zd0+R;D1Lu>y{eB(KWH7@^Dp94_kWR)_q+Sc@*4!j{P9|G%|fA=`Z<-oG3&C?bDLdH zKn<8~8?Lm$+jtmANB4wGzpJrQ{EKgpTxHvK&$9?g2Jsa ziU3z4n^JTqS*Z>=zd^zuzhb2TP4Vw8c%|FMcU90h!PVX->F6`#2)`XSX5lV(N}kWUZ| z8G1g*4vX+xI$CgNl@pX%v%QsFMYU_}Nn76t@2lA2)`06B!r;qG2erNV@YvWW3Ranb zGy67Qymj;WPfB3JeJk(nC`;x=g(?LNJTslyd`kD~#36 zWj&VJFv>V6oRZUT&$MtXdP@cJsCNcGM)B5?Xpi`w1PR!$?h(C?pVYEUf|aHdMsxLk z8dk>WLxaOcN2I+_93qPxQ|Yq6&8+IiTb|)U6^f4I#TIZW?^slj%$|!EX5ZO+hV7Q& z)Qv5-?Pukkr9ZQ>*pX%_a%E%q+;2bd3&3d_sKE2peevMJ6D{X^a(2)vip$;?tMZOn z3gGkaEPG*pH|pIIV;^>8yLMrsrWTbMl|~N$@ItizJQvXtq=3)@V{xS6*A@VPYOL*J zfCf8PZ6TxO^8(}$?CZv;g#>-sBij1i1sEt)t7}%Y_no|N^vEm?fX*o$zl7p0k0gEv zL2wn&-#Ap(Yu7~_Sd%um!xqggh=rTrW6J~H=%Rl%IMj|Ct18zZai|io$Uo~#HqddMPD=A+yxT04N{l$OSdJA4zI}&D3KO*kpllF6U5)rBjcwoD<>*7{b2rUP-dQ zyS9U;PN_VD=EdMA0fC;|-x&WTeViqG%62zz+z_Odj*@oo?ae*?Ru<)5pf#aGyyc<~ zTe{qTp;F8brhr%Kg`@JQhBR-o#{dAW4pkAJ0{6115P!V>w*C!=s10v{vQ}SqoT>{A zg5Gm~26uU6_jv)Hc9eGQE)G?v$StKtA}rbno$mRBsB{%(xygZpdgtfg;ypr7pP5!& zCGY>MNG|1X?(OQ@T)8ln*_)vQa_)Q^8Rf(nSfP@-IP1+O1grR5w2)lwAVW%DxJP8?YS@Ims82K9| z<>@ODm7%Pr8{gD=Z77xY>>ZnI@Wsu(H*4V8?mIvzEDK5?jzhf6mt9g6vEF*>grW46 zaayp4bo;P_;FbGu$WB6@BdPEPij>OErO^ide^$opQtNn7r<=Um^u4h2cu z3v)J_R%Md^;QXc-VKU*L_Dt$Ykt9_iTv!K82>O&}wlH^m;VNkZ9xo{23mXv5EK3?) znXbrx8{$Z_CaUDzaeKzUH6YETC!RN3P)B?oNFUFu$Y~A+gop^-4zE^FwnF0oAjxD` zyV{y}Ie|B;z2)-P$%l6*X&wJo5`tSzDw&V{m#z?}lieyVjH}syx3>VCBC8)6ph}^t z9Q5p0f5(DO`h%~&RDC=m^PF>lyQ5(CF&f)5{BxT^8ePW;K_?U>qgDM;E)TVcHJ@{J z^LiZ%Dt4`8)wgd*w5^z-D94sHp}rqR*BqCUocQA=RC$%JY^#3z7Nx{o%5=BC+v8Of zf(eh_b3~+kondM3NKv#<=G+LFPZ)J)WR~u?bJ7HfyyJ~M=!+l{$q$F+w)x#l$p0Jn z@;+MhHiI^NaGBa|cA&4vR2U|(edtSh*dde;YRet5(D(&%V~TZv_ci9o$?aW&OF<{$ zr?gLKliCwBCk+;t9{0jCh||kbiYmGYfBz99;}F0!my%~rP8_21gO2ysj65#tz7A^5 zv-Wp=Uj21Ls%`*ysRzi>Jw`>-9A*!_-SL)Vi!~a0R=mgS1J-O}UzOBEDvzpZ>@ECG zK&HCW)jT1ix{NBfz5Ma9WeA+C&clT_EuL8={r(f{f!8gZ0nl1brK3r7MC1Jkz>Z4^ zOQ+M}3@gx!aoJg6%2U1Hc~61l&8kdoZ1hi`^qcdlm8?dJf5VF)5dY63M@#Z zdr3m-VpxW7661(2njmB#f*fG?^s2c^8E=G$iga6lq)+>Ea}`zS_OM6>n$UB z(3uHM7O9CC*hN+dQA>leK5{^v%N1gtwPx`C&_pLZz3TlZ$NTog!wSD{pG3)rigukHxeRB&+C3SJkOag?9q}f zXt|_6jRSOEI(m^Pud}B7!#J+xG*$guSO^ffo=G4zG0bP0=`2dw->;VoR9Ca2AMizH z@=2*ftW@GOLMW}_R|i`bWxNl|UE%F)IPChZn0<-NbFUV={&TGf~F{yRC%|%;dKV&&GoGvtH=BYw>X7osN|H?ojN4RbVtk#2E(+ z$jHu|auO;oyY$&w6l0i;L%Cno2|JKRK_P*ZsNX@iZm!Y%r6Ne-ULf=u_~Qvx6i;7@ zzIxW`==p`~w*1X#?A`qp;bDiJ;|MD$WVF-FlD906z^h%3R(D}9@{aqD`yxwLHIZ=n zNCy(Bpenp^`{47e(8Uv6jG(M5#kP!^Z$awgv$AXY3HXUXqLBc&G51%i>BerCoP~fZ ztCqv3!YC6;J9CFi3`g2msAd1+sqhB44!c`SRxUj!rzli#{1wr+F7uybeovg$8x1b? zBpqT(RT|lrI)twjofv-^du>~&l4o2Gp5r3*@nE~}B3JaFyD?wp`L*AkcU0hEtKH_> zN;bb?pdaL~3l!7O|8Pds>^;g#r4VJ2 zO6dI|uTkD$ED*r6lfhoH;B~k&mDonu8DiA;cObrw^GLgeiS%RvPdJ<^%qW_X_%YEa z6Gt48K@;!$MYfXD*!Z{QF|twR<@;-DmpU`Y?rr+~nWvE~#ro-Yj+3TsOd!$`5GT1q zy@{qUlF<{44o&(TL-hq_9qmL&#h34{`$N7DQ3-vb_mmrgS8FtYuWB60(Z`@@IJT4)1k1VeWBfi- zvp+jKIqG(55zVP&U_M$%D3{0jIGo@a0p7Cd`w|{0ZK3R>>5;3W*JOBh^pmb}(}MY` zmgE|IIx1V%G(D?CYE*|cpoRTpo4+O$15W+9GMGtPyZmwY=~v|u<5s+xV5j0w0)~R- z`x09VLhI?)QQ1%R$GbTM>9b-8g5AR}a?D11YnsKZiat`r7<577W=EK% zXI6SDHI~yc+u%1+zJ-Dfcc9+GcZ8ANCRDj zbc-92xh1$-#<37*l4DiL6VkE`o?l`Oa&Q#(I|*p7q7S93YCedv9>EGMEnx-Zm27K4 zu&AKc8Bqy|{y=%4d1dA(By@Mm^TU5*DX_mk#)YY$pltV2wCcS;8evj)lX{PgMG!!q zZ>B{!u~N}$dQA-nMB|}g+RR!RgvwECRiV3w|((G4y8UQ5{a&xd6VWU;8j z@~d~F+pCsFcG5hd9~Z!`qw}R!#&2eW*$z@uO1?$|on?t^Hl9~9-AsJ_JtP#V#=}m9 z1HW1KWow;w_N~A?_qn~fzS#6^{=4htDO2>!MOHTgvp}T3(=cl~p_=l>JwAiQp7Bjt zxL|=4J!nK%u@sP(@@r)AcG+}jPBSLJFpAAI*Je(%|`S;Zk4x|L4vADQ_%+0_qfATL-Q;<6kpj2b= zGbQg~cZzkAV%@9$Kw?HJ9|AN3fLB{5-BK4c5J_PF20-d<+&w&!IP>RTQvICx4Yv*Zg;`HwAH*|05@(rZfep zy4^P1#K1sJi7TmY{KAUQ*Z8`H$hN^lhU-aj7V{hYnS-yJ%~!HUL(eKyZnDKX%1|JnylVr`toZP@QDVN`v{tnm{n2-}MPJ?XMch7pMG zuWVW*C62Z{n=ZzM@UP4LP6XjC-w&whi}s&I_%ORv^_beCPY76~$YI1gd)>=xdp+e6 zH+Y8%GXtY#Boj15dd`y9mYfKOqqmfsOLPq{O|B?pCSkrfi0;L)Ok8?jwB#8 z3zzJFuTSYQcUZ5S3)LfzCG@vV)W7+fKN1r&a{g~*d9D^Z!eGeA66E4xD`gUFWj(_Y zsa9gu=~680`e;l{lfPh1R8uO){tE=~dt%h9@pkAvh5XfW`0#10N&>5_-#sH>8J$r!^o6Gz8K}6KI0s{wpK z6vvZsA0*>~&0O%w$BW98Y~W9lm* zVMC)v=MgtRXWOfHP4kH&AS&@DGdGM+y zl<7=7R8)CQ3W(pH`6JOdAxL*ufY3**Z~&~-ecl`x==mPZ5ig9jy6~r+3-#RPOB8F1 zMeS?ROh2Xo#M%~+5V@>qz(;0NJe?k=cd!LR3nqSBJOxRa?C6I7KPy0;;Coljpk&Gw*mHkp2(q zgYE9Sbt1UWfyzH%>G>edK{XssIvqVFMKBjc#J2x*Y7lvP&7{b$``rfQA(DxyfblDx zA2?E%{6jfH4I1@$bw%;EWQ+A}s_d6URs-^+iF}8C8DU?AO1J?C@fT3)NsHu_1gaPj zUhdUY%aqb+7)Z6VQ0NZjK9mQ01_rVy`W*k;P{|FD(R9e_+jqXaxtXe0?=Qb)A)rch zO%(v^cqu%WN+ooO!rJ^W6aoTPFi3Lw1 z|HQ8qlo`f;w#zX@#i51jeP2N?`Q1qil+_2_M{MCIlD6EuUoZQK031TnXNzQd^DNvJ zOCDwzzC=~hzLac=rJJe7`?GfsDd~}xSoTQc!UuD6ECu?8UjE_w@?n$ErS059o)bF| zE48$@Rm2fVs;4+=axjL{27l@aZ`I1YAD8utLV{gX`ksBKZh;Y|I|3| zIM*^o-pf&5Ej<6~3w}L94PcIs;)s{pk|^8<`qnvSl(F?maR67f#XzK&=J+zSobQ$j zzkwMD&Q zW_op|8Zs2}&6^;#&PFFs&*qRpd6@K~MdYUtmIjS*6c`(ek1Dh-eIbuF47cWfStCdU zROi`C&xlEhq7Y}tKlkd={YeMrSJvDTK$(#~*?ie0dcJ5ViEaYGsAvw-9qQ!6qSJ>y zr2>RXWG`oT|5CpIJpUzYyO#1JeU-&_az{n@tRA))rtkQmA?>DT&+G^3;;T_XU75$5R< zCv4X=yD9OJ-)yg9M@|G6c3V(b{z4kMCI0Z?V<0(I{>00TaS1Y@U|1NwQ-kf!Cv}A; zPfc%+9~3IIpqx{dl4(a|Pi%IMaYpK}zXbU$rq;Y3*~|_R{<%NeH4+9bN4#~=idwmt zth@yaDk~M~pExrROO`ZClVZ;SU!%mDR|gyVYI&vi?_cbaJ@9JreHup}IvMRbEfeeu zm1GXuJ$zVL#!3hhAFxEz1T3rdwbnIZ@Qv}FL2WoDO+xr8OZ`mFXKMiV>xtrb8z}$% z1~^FT*(t(m>&pczo!fQ6fB&EdJ%zaNj0~2_`2(}z_6tSRpwCXz0Cwt@o+w|Li**R> zig4-nULyE!2Zv9;2s2_m6A|qO*Za?u&2hBXf6V1#5;+++!2Am6(Su^4)}!;YM@fzS z{lL-_pIKE|KZ3?8MoJi|3oXKzW!sL~B>kNt9kq^f;rzYmg>+@w4j{S=-{ z<^Y~_(<+|8LS-6nt8-czD59#{{ig69#-k1|%x*7QDCDn?+WOz+c$aUQYPnR;Ib_95 zex7l-@T0)#HZ6DK43l-)ht;lviWPExpc|< zQtMmkcL|%nQ~5?@Uxu3mM&+pe#~e`4O4_FUG(_JM=$hb^6*&_03*#E2S1}0&sxRYb z^(ms7cIVm;qm)uBPPH2wr6HD*$4*P0qH*hCDw~MMymWpFAV?$U7T_nPJ;TnhU1P*b zIE93HfL~^LyN~DdcX~_TPyb!qQe^9CpL?5-gA#eWg_=U_%*=Pd(BgQb+cT6 z8eegdv7uQbhJs+{R_FjZ;pkvm9pJO2`=m%p!bufs;$&i>s7QqqW|A^1DBG05$Ash^ zrVndRAfd#9NbpLV(lb)5|2-=GW=j9`gfh*TMJB+<00A!q%!LhVCja0UAQvJDA&^pU z{3{jVJMv~|eI~8JxL^E$A{@FW^Deo#B6j}?u&&S+si-mhTcAgB?62IispenFInpjd zfY7(BuSmPThV!0Q;(TQE_OFkueWZZ(R#jmg1w2JBRFqE#UGz4m8*KuDeWaScnrrL# zLS?@$zDBg^(aP}}mePFquP*o>=HbdP=-d!|&UR1nKpE{=)-4pUb=h&-aqseQD;i%u zc_T^lft7;@5=KthsmIu#^8F{}rc`pbVPo}(HZ9C(g!9`>gvm~8raG!K;QSOjO7E8C6@5Vj{zRfDpN(jF3p|o zLA+U~<7ymke6=u2ZBjNT`RD7uZxF)zDs-?dlV~Zt4x^X);eqvTrKghRFgp_Ogi_s) z0-kEV!Rh3BPeMlj4!ZLyFYm3&1YJ*d{96b<{vR4dR$d+p8tCedqL6s@414@SUe$+%cr>%3z8T^`K{fJm+7mL; z!-AG#1@Hj6r)RGqBh^<3@W@$dy51)!r~t_ZlMB32MvKbdoNWj`{JGxQ3#9K`I6sd~ zBNWN(-{n;Vm1K?zp$eAU*bqF^H%BW2vc+xL0Y==W!|Mk|!P_rwZ3)3-bidZ!UWLJk zA{b=*m!Zhy33%ON(n1n3@vMZs!ADsp{90Uq6+{L6IrL+tdb3)kXU9@WO8G>x=FeHU z-81lq*5(s({m(dR-?)E1P13F(`pQxP*`!SCDZ71IWL4})Ylb|)$8Az-YOhMxF}tj^ zehJ_{S(NTyx7SkECq8B!6T|I(>h$q19-RBb0_&V6v;{-Azz?o|rlJbGMC)64#hVdb zmZm&v|L{KDf$>wUQKkB$sNuI3I*S9-uQHT(-CaJ~4S!=VD8Q?BGNJ0q-|&}EdOS#(^#4MBb<_` zc{C;zE{@V`H}c*^x0CF7-QHP(dSZv8GSOd z|6zMQ+pu8Z)x~UY_`}8FeYU0A(!(0t-QV26i`}JrgQKpze>c^^r-btV*1ElnDqDi; zdHYZjdrIJ+3kgKcu)7i1k!Md$#-wA2YMi_+w5@1pM%d|EOuI?wQx_mFH1{J}xJ$c_ zl%cvpE5EpheBdsYl1)LL=a!RQg1PJJCsNTSYRCS%dODe}wDra|t3ME|*w-O&EvJ_swfqI+Z01C53`oj-dX-vR$Gy@L=5aS-F>u zEyU5|EwQnhgJ{u_ZhftHuWWLmZ;1z*?%0bR|C^0ku9NiQ8sq4MEQI25LaC_iy%{{p z^QJ^uPdax!)$~xOer@A1PSYO3n7f(1g)j_ zMy#@b;M6oG!I?pKS`0+;^J+;FET(P5YlQpsHwpIfJiU*4=D>HF0vHc*FViH=Q;3i% zsd7Z=c!VOCXx6K0ZQr8rkIPy2ldH7bD2Z=pj@tZ6H($kkX zf`>FB2u8~@-_Jd!KDhK{?r)ce2E~t;a8MUgpb)Q|OZLx0EF!d_Jm?>ZSH$P4Jeq`W8$2`5cd$}a zo=?^NDu+2~CR6|Al=L_`-E?YFW@M>&*mIi%jurrG-FUzt8__Zd$)0PH$)?md-BSSx zGf^=i$-O5)YK7^ZtgZchpKFT^T(DcM1985S^^r5YU$i7koyRlC3nQj!iqEcERv}@g zqeHv&`6WHQS<3dgCM9Q@H430qoH@9Z zzu!AOjg7?`Bp=Rl@6jEXm-ioruKky83zL(R(RFph!^2p&%GlaA#xsXon&1~ZmOTw? z&_1Dn@<175+x*0X);bFA^vaJ4&KgXEC%ts9@ts1eH2VmXDmD*~d(cx>54L^$y~NB!F3#FZyT6pygZ--aYgN{!b^L<6ZY z=jXQ3L_Gr)0Hkd?1vJCO#RY2tVu~8C9hOQs9RN{`VGYm$$44u@l3IYHMj zfi|yzlnjqxOaOrb?v_k1)_f@iVLtEFb^>iAYx06Ew|!cWxpKe}7d=1~@nvl}8yb*X zP?~4;M9HS#ktFtCWGanw1#+?mAflS{akropyF7?bwg%KVXjDSY)+Q^EsU`_YN9s4M z1^#IKVY>8dGCNa{f;(!VKHBT@834dEzvzsGqXjD1Hul^tJo}Zmz)x)DJukG%pj3I@ z5`5ObC(|DA8KfJNpmWe!dmHDgf+)D({kFQG#agY@Dws`7JTAN`Z89-N=484p0>~p! zPPMkUiBu!N79rm90PNRTpEA>+!dlIGtv&qW?PMm^A9A5SRShD0^!jLNDiET|J6QxL zN-yrF!EEjm?$&`-Q1E4xgq{7%cb?wT+Z$4H zd4L|v4eKmlLAdchrEoA+#TvX_Jw;mmu2&l$N`iahtuY%}C;`+ac8Kx)&~W#1F>qH% z>#n(@wbke5BsKeE^B06MlCO=B1NJ&j=kV+Ilr^imZZjy zv1LeDsMOYxq_-rTY3UXr)sJ$U=p@w}f?{9I>M69xPrvh>_Z=sL3Be~D=cAhR3m22; z!RO}p5VT(fegj6ox2e#dqf^$(4heh&Vph_SV!;;-Aux(5GKFs+bi`hwq#9=`_}xzB zqZCRWMU*Ox4E(SNsAjYW0JM?w2jpYbRk^J`Z&jv-yDRxxk|8t2vch=Bp>rbmmu_$ZbOUP2>XFk7R z&kpik<15Zn(=hLwH?gzlPVg;J#9ffdpLq2$?^OI(q;*NSGJc?m?>`h63R|QHR3eW-;sAY8RV2S-STN@Yz?L+L&0rW+7(& z9=dE6c`zDe(T}ICjuYZr;P7ONA-%d9%Jbdi8qOaMINERM>&$z_O77C;873)B%A4qZ zJX56KYDalWuIh?harJyIl`J8K1LVe=YX4&8%Amd!*|5elnu+G#csZv0^37O_aEFiI zZlMGxw~y=i;Rv~sz&FyGiPrSmP2E-~QC_Js$x{)$yw-vG*Ik4Po4yrtew>LUQD%-U z?7Z<(6+ZQ|DHXSwPFh}m?HN%OdwtoG%PT_dr}w@n#uP^}2x(|oHwM$ZRQwW_AT!EE z-~}U~%(S4J2%l(fTO_w;>gP$LQFIk(_wj0LVG-Zue&t-qb^+ztVKg+;DD(UEmA6!U z(fYF-$TRU{b|i)upN_F(o8C&>DnE}Q zrBToXi!~hI_%$~%29`Q~`q0|?g<~df6P%iwx)xkn z4AV!JhQ!&ZA0SlU;5%#;`1M=r~pN_$cX^?zz7zkb>8j-T;P+_sn z+}Qq>Cwdv)48}O4_a-zZe%x%AwiuUBAi3zd`DQ<(GL83)kY{(0V96rU^5+bR zjBh$9IY~REs(iD^3u*pNx1FqtlHbHgFp&z>1V?pO z?PfM`aMLSc)9E6Wgv-@`!RjU^v5psN_p2GE%3|#=v zW4Q{kxBL*rk@!c{VtZrOA|+2|LRY@_ira!k*7FdTjL=v%dVRnn_R@m-U!xb|^p4?# zfcol5oZ*-b4BNqUw;OzN84Ia;*xvVEyvts?&NkWg?l@hLzv@2JJZ(*XA<3rrDZu_< zH(?{tgSa={PVbv8(u8ND?NZKp?iNKtf17uU@7vhY*5q4{ab}aht^3vX?2BfHs;Bup z^M`rnnAHTfLz8UR5rzGySfkR}$BvWX;1fIfc2w_3PDe!h zN1SDwg{KPCxa_56>Cuj^D|>qy`0tkjP6qpLyN@;u&F?BZ?!51JJI)&yeYdczy~6~o zmG^!udRs;QMkj9N>}=gn+GoqXERO`HftPoQzbjgT!Q34Pk?9ejpVQJsZBM^b!Beo% zmKq|F6axHceN{;>Az`>%wLdp`e(w2A4W>DrWu7BwchOt-EQB0@CnM5vcf^4^VWMCw zvxjgCdD-sgDN-CDIf54LN4)OgNkibWHK#R-`K@|xw@_+-{0yX&`I*NS_#;Di%H$(I zstFDiaHum8^p}g%1jBsHG$Edv6%?4;+gLZ-kY)a^sB z%fHEIf*pPr>$5MdW)MGSv-&9Y#nSld1(xQd8}(;;NfTjL^_c1mBrrWZ#$L^}=jxEz zP?l3%>=?mH%AAa&=xU96q~6Y$_js^rTSu!WUP!6lDO&6 z-qwUoXEmk%XS$PelBHhuU0)fSyFnPj_3ifFseVYf1NZfa%#-xmr%Akh1Va|hc+VM2 zUkfN>BhbdFrgVw#bXQnhlz(nvm+qy;WyMop9n0$5Gk$q=@OQtIM4FP~WKte(Q1-I~ zJw5Dw_?)9J-x7^vCfsP4@ze*G*QX$X4Oc`@1)i&UIFFoCf!}16Pyy%y+rp+y=&jzX zua7XJ-@=AqU3!CBFM!!q{_KvJL}Yy+8jqmp)KecDCgZ&2X4+3cW**=v#&RN4EJg2# zTM74?G&9YTLNvtQy^5SkkG^~y;?iyT!6!x&`hDOeg|RdLBsb_LOXuOvyW@c^_`x5G zYP*lbkqL0UPRMu$kWM?qU`!qra#WiHl3DSqfxiz!7dm5OJ>7clV^? z&-MTc!CD*lx!=WHO#a{ir0o>sCqF$&q6iXZjrg2n`0^>87|;W>=hJkzLzw z!Q&@3li(|GGiAFpZ@3wu8D}UVEsWR6MY1DS5>E=qQd0Dc(D0M7AO&3Cf7~=}4{$#( z%ndm2MPqf3=zik$)z$~>Wz!h-cdr6NCX)2n?R<;*Ek1zl-)wl@`S5AS-5{Z1<1Hc| z9(&4+ah*x{pGxHZ?_UBy(Ej@+NhxVDYN`xxC50%W#n1jl>j&>S1Ox`T=uK>by%PvU zo-2D{uzD28!k2DRfO16oB;P3524?mc;w$jjnC&>{Gr6wQkSBcjboZ{rd_l&y_P;G` z)_~BDllyCB9x$@zsf}fajm1RrDYeLMGxwOXayE2P1VH%|$XfYq0P>$qWMmSt^3hnk z&#Z4+UFCG!<)Xh~IlI-7bE+EA?hNk?@?(F~a})ez-86FGGdB&@o`}Z^0qZm`KlkB= zJofYV#HGn>`1tCRzqdP`Mm;2hycmM-D!2Vpy&PM4kHF_&<CX^1#89VFPRKuE*n?v%9Nd! zhKxRA{md$zZc8L)*KOeqn{io#8PspQbhg}%@VVwESEjn{aY{Y1jGD#k_kM>;lDaV^ zDWG#3G(zUn)NA~{ujoW;*LnlTe=p+?4YsO3Fc1By#Ae`f4LIX`3ZOgW`C{yI97^=5U0n#}_)8QtKGeS6c{6_mowdo_>b;m| z+Ntn;qQJ|pG#Iq?<+2+T-^t?eq#)JZwnP=sxqh_%gCa@ksLTIRYujv{HRxw^JBcP< zXBJ(n%12%a=xdOzS59fWvv*FO zk8W&qXJ-BfBwsXJ_>_@o`ge{SJit}{cDjLQ<1Q%Vb7_dFW8lr%-|OpM^ZSd&;Hz#n zY_93a@ml}LzoonI;G>p~+m_&qXTeX}u!FC=n$gctVY~{kBCI?8!w07pfrCpuHD88g z7zH4fG}AB9zhJKbc|!F9GiD;tM&nT6OU>n%@{<4lS;ul_^vLA2Ktjli7aC3@d{-6 zqco(UxKHt;9wC7E#DQ^0crhKAohE#Aa87s%NYqKB0kHTvBV4-pG!=%Ynm5Gl4a#1N zeo>E|u%4dk2`LpU7|k^(9RP8|d?m@}N*)#b{P7&h0n`-3g($+IA0)~nnb~V;j0U1C zV4qAz9G{ppu59{sEP6ObMy%rvPNsCWtOzabe`O&yQZ*{KhSyP23D5rbAqf)6odD>lVhiqEKbD)VA?(u>db zZ8{iWRg%YTgIKHC#kQ`QOIJQ+41xlv?6t4o)BOOzxr%99Cd15Rw%}vnm4yY-uFuS& z7k0;MuF6cRHj?*)Qks^y-rYX6er1bw34h4XY-W18ku_avTA$y7AaBIO{kwRlsiRu) z)U+&rN0(VS_)pgF-y@wKD102fN?6T*2_9nok|pzRNUA7M)i<<2r^~3x8*GLwbo_1` zJqE_hPHsXjuacZ@nX+xRng_Tnwu&$Qb88ykICuhwl6Udfo<}e&ShXIbCw}J6$=$AA zciel+|68Px&(_Oek=#rHPYUGoy>k42EdW;ExzPS){7#DZL0SX=2tmi9UG6r_U;m<* zTnsu}ewG__er@+o{$Xzr+w&ApB_~e`2CQM@cosFbN=i;87yi7Ed35NqZIc>-hnq+O zQ{97BMeekTOj>H3Vr{VC{q?gEVQXF!5kP@8zV1^{nCS>#nwn#rR$^L0X#uADY|ruX zZ1P~kD;*J#_)5VxVL!UVqc#N?^_pzf8jW|59aHAOFD9OEE}{9~KtAkeXI|_)C5}Zp z`YoFT2Ol61^}Q`yE$Nvx0Vhba9<^4Gj!T;yw&0+Ib1MgA2t^gv6b7MFIOE&AY5r^I z-TtDAoc|^`;gL^QUSFk^bs03oL+g-YR(`5}{H5HODwMHn-jPhM!ExMsz0D+2_y1@* z&v-W9w-3iGY9wgQ7AY#IiczDj8A@u#-Xpf!MX6mSHEPAricy3b(Q1s^ReRQGC>ndU zX6^0C^Wy)?Tkd@1y6*4!J&z*-nAPG(duzXVP&RRu{pqWY>CVq)`JLTS$4*Co2~zLh zatAZfc?XXQv`gHlyxiQsUtx3u)j$qC$}9D;^g3Hh@`^3%mI(CFN;3vP2=9ZvsDuEC z@5ob%-J%mjh21{SO!W!-=k7F~{OwZKKGQA;bJ~ff4@Z{_X((+qU&4zXh{&1~z zBjwdwc6AyLZUE+$hHE=MH#OWnubRS0{m8!yb5eD&$SAKawQJjNkDb4TMopRJC1Y+@ zdo(H}?H3*YV3a9h`seMpF+EbV^@`nZctd*)(-iEp#IF1B+>=;hNTQGZotcnZo5BSr z(qWO*gRo-f&0)v6EH17{B@2ihIp6+JbR;s?k37`=r4K2VBfI(%~t(Y3Dr#6m3 zh0L6@H)~;UXO)fxgbm|`Ypf(U>!l|Xj0b){+Oo?&8B=|>(f zLWIkmv|0K%Za7i$L_BTmMm~7qK+*Y&gI&pgxNG8Z4@`WMB{OK}+u%3fev~O5C4?f2 z@Unt;MT~T+g>(C?>)$Ic@6_jKDLdYL+T%pKYmLb*cCexbddtZ6W5rb`JDD9`hwioq zZcuBb{PsZ!QBxcJwdZ4sey)xy*GxxOGQH=>_M`$l_#ip`qEX5Twws5v1pr6){KJFK z<#l--`wCFcw%ll-YnIsGpR5kli>U!8z+`W{HSTX!no`oL?r1*!jsbWexRyW&a-_KnR2e$r8 z^s=1$O%fYY0?w*LYI$vEPJy;q4`1vuhVDtY&*L8m*rQNUql#XsHH0t}ch1PMU8>{d z*~4$zEy43_2{5m@bOwXTrEg=`|^A5N54@SrbbljkR9KD@Y#>+4XUJ5anKH_~N zzN@`wVN~Ut+-30eRxcVKf^<~PUoIw$dqc}C*r)yvNN>o{(fILZ0KgX29Y)Np-rt-_ zQatk}baiP_&~mdp_EnI7wj||m_1M`1Y}3+cjce>6b@!audk~If1&xBmqG~l^#6m6* zGCEao&634(c#0)C5-I;!@lGkEw80e&Qheooy8JJLhtx;jwqP^)6hIvzT;J3oCD8N! z9sQk$FIB>}a_T8-+fID|Un&3o8uh-Q@q574)~-^4@ViBMASODgddnl5-TtHhwbOmS zkWgIh1jY~E*I8@`df;@rO)=rYmAi3XVpFe8Uvf0RFjemEp8iiJ zU|=mNzxByXW%%X8OJ|<&lifE-cOS$7a+tJf25W$X+g5W?=8x^wVT7gnyd9?a`$-gHzFWIPD-5`y@S*MSa~v5%ufdJbxK#}9AeTy)Hdj^Z~8;<{H5!ff^d}b z{@Umr(fibvd?HaTU&J_kH)XS#eds{U|*w`iuACLws~fTv6sy)9Nm16 zckH<`EE>@W?3aCMBZGv{ah!#{>|>iD12Hw(JHK$rqEZfS9}e61^>G5(24vsNDQOvi zcU-D{#O`aaH%1tg8I@3&+pYoUhp~}b^ziIE?U?nIcvUeu%1J40HYS(VUa{fthuUJo zj4BCL^X%O9cc^w^Tod?8_@haSo_?Wh9+iI^jO8Ccy~BunwBN31Dzp4cDU(BcF7(>r z{O=>!!@lW9+>HBQ=w_*aQVP3$eS-J@ahGchQ|YnU5P!+8H57x5bi|Csk^^D0#~Whr z%KMy%KZ6fo)}KrYgF{~nfjwqS2<(3tSTrSc)Z(ks;uw+=U%f> z+wcO=E_c+9MKi{Rj=$vlD&G(^E7{@AZlEc$ZogC-npYa+SNCT!G+iRe42GN!(&Cr( zTpKdG0g$`3_LTYSx7mF=MbAfE`u>B67wDH)E*(`8K9B+z*w0UoEeZ@55p<8G{%xcM zH02s{gF0jK+rEwMcQ%6VOhcMWxxG92bQ&(0~_GpLw1S@5SEl%c1J|{63ZStK?%GB<7+md(nX93 z^Fa;klv_jrUp7+Q{6ZmP(+8T)vgy_T!Sy>Ms1FF~1V-I|7Ee4m9JqWUU{C!`P4Z5Z z?h=CBo*>ZGMZYs-L9eeJPY5Y++(iagj{RgEid=Z&NV4Q+ zlHO1rs{i-j8h=45DJcnr{d{TnI+UiJOf<-p^Q=|_YSbmj{KMdAQ0-<@9$TH(Y4(-` z=yCCD8G>9!g9hlG_IRfd7~1K>y)}Fho3&h(AaeN2fN!j;Ys%}YyZ-v{n#7>X2;bAa znzpw(ELNW9)SzS_a#@$vET12-}>ipxL(ppi8g)>r4b_4Vh(juXJ3 zQp{V(E&-oIy3Joq5w`k-t+x=J)30RS@G8+S5ImhEc6>ljGkhOHJZo+PGP|E>VzUST zSa?}^t6rAVk{SBztbBBkrhZ%Evm{F~MyP;xCi_iS%I^f#GJYrvz3JF{zrxf5-j`xg zm}V27lv4t_)#)<6X-vFP(P{@H#E%aZ4eSe#`6trw_KR!D5$YI(_m=yX%r{8JLNAOY&PtlxpTk!6DGzZzo zav8e8u*)0l(l6!LVLmF{!ot%_H5-KF|mL9J)WX}JrY&{_{GQEB3 zjuLM~DV}cPrC#{;Q^J0!{qPunwdVK0PpADY`;446jRuUQI-r5CZ|gk#n8ioYEXSw^ zfT@ol)6>`j>XdH_*~j1Ur++fk6~q>0Q^}~Z+unfKSmdhyb0&97|DK8g75@DzuWs03 zRVUvf8bLZcKV>y|G{xihJ3d?e%E12o!J~Lh`idp>QqdKKA6>`KI>cXkyzadZZRBIh zn<`g$qG(ZDF-}l7x`Us(l#%zg$L=&|GaembYEDB zQAJkk7Vdjt{UdT9%+_)<$%B(cw2IHmI5zO8)yZ7V@V3ZpipPcX1C3?}>!VRLfr2L9 z%N_SXcHRnS-`@Xtl=C=TFuwg^ZD#&3*|j*7B7;H}pPja&oi3?m$6`+oQ1{l# zi+CKK-x=&1931d(KECuJgKcEfo%Zvc<_FY}wW^)%pL)9`0gPH1|DHa+4)!iEDi^K4 z%`$Q3SEC6Sky3s+B~1x~vX^4wo6Dvm9y^twiqUI9IuHUvOZ%4aBKc%)mGR(9QgG4w zRL<&?4C()0&aI^_WW!P`e6Q%oyIpbZkE!)jLDM@&H{Ztz#6N=Bym53Z(``NR_4BRc zuI{+fd+vdZM?oI}#3_f%#3*`XLJ25uyP4Kj(Q6je`$A*)%eOWm$82H$h+B3NFbVlh zQt_p3>w8kz#UJPVr@Ml40C+GWA%S?H`ShCdiE6IS8m$_R5cO-Pd5FVB5eN+_;q&`vcgaP(Ss##vx-OIiJ6S`&*TDD zGjTl?b=aC!Hff6vRU@~RyYDp5UXe*oDHwo;)s*{fa!aV_Nc?bQr(-576ouLWT&rr~ z+0nV0wE=ggwRvNQn-D`0WVh39_zaVg?<3YeXJ@-u*8hxle3B5c-nVKmq~zk{Lx3jI z2;Fi+#Btxd8#AcoXbe?$kiHX34nWurW<`{Q{%O=h^qGO$_2SEJj(GDLuSr!d1#rKt z8aH(KZ=?xPshT|=&D{8{z38#)tujt#gYib9r)6$ce%Mjr?G&vhRj_>kC%F9d^$y5) zy{}q4t9)Jd{pNomwx$Vwi1OZ_N7YWQ!8UM6s$6$!%}!GlgRq{k2UAe_uR6Otx3Qn& zjUG+ej@gvC`09huwwd?ZYt4b<$vvS%eg@8JU%t`}X!Mn{=-VGeauwPA3VMbz|Kd&K z9Ljzy_1^D*zah2A96nP!><8I@f_LMO#^Y-_mJNM}XANGo_-VYKZsj_96A4}n%lv{i zcYAX3OV$YnzO{Mo$(?rW0E-xT9g;F_UaueyjIb zvfUtZ)qdQ@06q7AWaFDE71gxGBtqe$p|Mf925$DXf!bn_D1t!W9H?PyA8=}k zbhU+2Cs2-(KGMC)V_Z%Uq-1$v5z#_{e=8SI-+z<2u)V8eoH!IobNfM04z;#l_Pci} zppO&RNmVkZ>HHQu9jyym(B)SY3}}0@Ew@d{!ON1RVXv$5i0X}_9weZ|2O&X z?J4Zjqb%Y5Hd)`;aW)IBaEKfmk^wAi?4=kc;(Vfbb@5Q)`eMJas*Pj^z0AKT-Z{4; zEft8J{HoOXxJ-JtsU;3O+d6(9 z_}9g?wy~c`3q@-3^~X28ob1sXaY2Lm1i^?wAI|4=fDr*AaXV_KD2~uiNX*^ZMuSC! zOHvVnD#isGauv^aT68ay%i(JXR_{32$G^7>XZqDy>|fHsg=Jz%Po!|8gCLt&vErtq zK)W^ZAc8=dtY)UM#&nle^W1ZcK4*xeS*oP5K+X~U!%ufeM1qU@>!Y@7w(G^*z`3VS zAMejzpNAjsWk`|>gbI*J%v_(C8cV0KAELvUE&X=V9pE&}o1Mve;X=ArZk z5zP3;$(HrUW%s08QD>!f1#A^v-ssw6bU>B@Eb|pxyJ-KRARF$j;<-D@h8pH9()f<{ zE1T)hDhK{B3yk#T86W1KMN0g6lOOVxG>rOvWFS}Jps#o1$l z=@apFYMsE#<u z0_?yoh@Cpzzu|g*eC=5G{ylv(WrCSzc1u#~rE;)zRkKt`KA6+dukWDP( zZnB1ns?lgD6>I#*k68UpP4-~!yd~7me9J_PNrs6>q513A_1LSe9_^$YYjV-6pApiZ{5QgN* zT29qRw-l#2tG?C^0*;x21)dn8~RCrif6iRZS9if(9nfYxVgF~-n`r_v4kFC8lR?8Sn%0r46%KG}ji zAvAm?mJw10DwGk9R?_KKb&0j+B8R&dgT_7orO=4x+6e+JtEMkKCYeZg_w^f!m-9;( zx85Rpdu*4uCji|0>gX|0dD zQB2FgiU1J+t)JP=9SUS*{rk^XtZTsM{ZKLI`)3%6;-dC4_L2QpiG15f zpNPVaIxDHfA-SPZJuSIX32oPw2^vE_@^AlTWu1rF7p@dad_?Gk3iGj*X42aCO}N2! z&AtQq*Vy-e1*Jp{%4Ec%0sKA5uujA2N1|W^%(ZJUs*}Dr^Hv51WoaY=SU(qHe&=*L zjm+0~#p1-|Zbm+895sjSNe$W0mPF~r_?UC1#qeo>95`bE^pvbDLWz9n0DXoxHu<7e zHUV~V8(2@S+*E#6tWbI(LomlzX_1D*`tro4pIh#u_w%a{Yz43vN>ZyYg*D3$Uc!BXFV8R z%N~T{yL%KHAM5<7KtMsA?BdYo`cUy~N%5>G>=$uM?2}mj)7M9n;g|K-3yN3LuDN70 zb$4SwlV21&u{TvV7%wm%_&PX~ez`g+q z&OJd-gITOsv`-xEkA8jiH{i7~LB40n(B5CN9Z zo2x$IpAm=l`n4W(AYbUT5SH|8Z>#hQ*lfw;IP_!Za~~Z-3sTSnGN%T6@(1)Vc;Na` zQ^(ep9rt~AkC};?G?G%qGcyK%=sM|-Tk6l^9uU{Ll{VgQE`4Y%Qu|^C17^9WM8Y1w z2bQ33qJto^vyUM_Atfq0TXK+KCd)sLiC#DheD`Wrzes#3V9GeX;%^-55B<(3P3edR zrIds8Vq=g}_GmG=%eDv0TJ8Pl5fV2}%6taw=S8Wab*>sd&O{63=fU#=y0WW<3L!D& zkHGf12rb02Q~0a3#RVyCDYk!bu!M#~%~-cqnzM@FSd4S>Q@|Gzr;kXy;ws^dUPRg& zi(81@$r=MIp@de_Q&7!tWWvNm_PF-tpZ%s$9vfNpiQ>>bzdaPK#kg^r>Z=!}XTSt(UXKT(%akWQF3%L5Z zu+x?OABv%8x?z|3A-fAd!q3`&sASe{tbDrMYa&(u?o=?Ck(L5vL$8)s=B}3UA9NLp z183zQrk3}gnxc|f!#heS+B}~yBZH4F_K1PAxi*g`#Ta?QmoHOzu(wPm&RT71(xtOM z@B&DG#N6gl&Q>E@;vuDgv*26ORMXc+9?roYNdr?N9xqux6PPw`jdMn@-0k9e zFXRsDlPks8CqPTsNkHP^5neukd96`GLv2611<4FDm4%y~kdCtjDX~URWWzU_h#y=x zN^s9payDjot`Ah54-XHkTrm^ntbD0H7)Dxzc zR?M4B! z;x}VTVXs;V{%KjhTFTJ>WI@ougs-3SF*_zCn1)T*MSN+g^IC;b6V}mjs4t+FgnQ46 zs?Q{|)jC;UEZiua>4*R%_=xrKm@qiw^o2`*2NIj3OmX^1t0td=G$u7T+-LO-NFT`w z<1W>N(F7g!!R2^Ifs3Bpo{e_9A5fnQt%IFbZL_s0l*s2R8KI?yQMy{Duu48$gKIha z_zK}c7kT-_ErI^q{!jZ^y&+Bt8W=uSS?Lr#SqSE< zdt=D|x&Uy}Z^O;Vf+mk5H>FGmBUyP*AT~C-&Prd(pHUIs+ zGvZG3+m8t!0_?o1ng}IT7+UB`CWp_Hga%d%S1fv>INb$TDXl<-lLjAM0t#RVorqpO zH1K<&F*!-^_T;X*TFHhw_Tx^lqv5VT6q_02X-KWgQ)xk*dGfB7E@3+WNieJ!+M7yy zEY!(gJu(PPXI29NgfWn2QyKY^lTAmHFKDoT5f!C==+P;Ih{9$mp{{B=?m=KvwUV82 z1b#GOJk5dp!oSmGi8xA`<|M(OmNV2OH4G9a!#Y%cZ9}3FHHd^gCbRl^`6vWcHj@v=UJ@ z>0|)%nr?ZMQc=~pAD7N=?QhX@Xt=`8PH!mAT@m`+TC6`!DqgJcT&;Rtl=uEyBDmo~X_|<3bN(H&>;@SUiB939mD$RS>A^D-f#|*lVXPUW z&Vp!V1~UjQrq#uSkYE*(3B-C>rknaj{8H~%yk1%uUT~E?ZFE|=E**fFF;plSA0H>(TAJ+E6;Dst z{8whf)^ZX3)$RWI-Q0ojuH@G4%;2Xwaz`crK!NLYS1^kT43Y6Lk79kwj{>9&>7)Z8 z;O2gPW^sebpAdWc3NCpZ*O|g1U^jP=5-qI;ja{v|+{Rr@i`~gW<=s_lzk=sf>k3}& zla!yVf}61*x3 z!j`mr!w>RJhPhT;CRD%s&F}%3HJm8@bxm_sJEo0zfl)H%Mc)eDD82Dk!%FW?qiPWv zgYcWS!*79j4R&<{qd~Yv5?>dB*BMK&{3T|F&`Fn0$43hYK&WVVu^~-6-4N%IsQ-#@ zkY)K8tKSo+Sw%a0AOO7ZnU%$rt)UXD0|Oy2IhAwED@vG9YANtThATa)IAI7<_Fa9W z4j0&DcegOB6dVO*0Sl|E&_hOY4nSML`sd>7Tp-}&y7hWASpRzc*&J85j!b-s8^#~*6S-K# zmU6?{f=UToz|cSq)N-sHBPGmxhca=fN*VV}(|x1=O|3>r#YlTXCY{96DKM7!U27R9^heVaB! z0?$`1?x!UUIC3Eo*)!b?ML#~(DlgZPaSP^e-+w4MnJzv2zC--}SoW)_M=~ap(VssW z*-YAHQ>N40Y2-UWbxNjM&IETa4V_ZVZj8R8vF|IRDU|Gal?hy1lc;#rw#Ow9%~}%l zl=pkXwj@O#fUjGYqOX|=>WC0@B;$2{X)#mhYwov%sZ~#Al>}lfg`L#^{V&wwjU`#~ zl2;qSFhwmj-vpl~^RUy+k}9j2uU&=q5*^}V(=jJG#5Bwogly?OxJWdAG#nbS9rGS# zeAsXPItj}RerbLW6yAb3J)?ETZ#Ik`z+deayKb||1n;fHLzY9?5Ml+kqnTTcPs2Y4 zy$ow~xnn0dqPLfF_Z}^6vL^6f9)qdLcH%RptBSeHQdF~9?S>=%#fDibBcR6Erx3id zRe$%bYdPbMjm8X_KnMNm;@@~D(}5B=6g=fkAk{sM|_KJXHyhddr8+&hJyx=*2x5( zH&(}bj%g_^Ccw)KIi90h^EEgCD887{3`?N+87x}vd7mDkMDYOD3pcr0>YkP=t{Rsm zjdub#EGO*00g=dF@P;J&rR6fgMFXrSCuKQ2~?0uO`|X@D$>ZLifu?t7Xyq&WTP5P~Eh)S2gdT5+5Yp+PFUDZJn!* zs1GG8*o#8=Aco0^5_N(h9~u)c(Vv8*3xe5J$lQOf>HE62>D5xr&KI82L#Kax!8S(O zK%me1rR>RJ9l?ABU8(H8{IaM~89qp>2cQkw{o^SkIt^dWqc-7P`(m0cwbFWwCkjKm zSTS|}j-*zEqrpa5zCDw_JDCF`x^i5g1hTxPd6Vt}{Q_G$n!!r?B=kP8Gtdk>nDO_? z85;Qq-k)77dkC119jiHe!z5{nXZ$UD{D!@ zYwjmxCqim&ZXC;X8?p_SiB1bB=|F`RxT(8-y^V-gw{VuF`utyt9+xDeLTP2KprA2E zMW3$cL$P79%N&nyuT%Ai4u}H$9JCz7)Y~m&VWzlR&D5Rj(D(1NDQ-KEKTCN8_Ayai z1*}rY3Z`>$ciMu3eYS6Tumf#JU2rLxB^qH`s*~=xTF2zUVz;7<#`1Jxo(xf3YuqLA z0c1%0DD{%{dqt>xCyk_#x$m$tM1)+xxitNE)3~d&g~w2V_MB^o75!O^kQB9}7(7s0X~Bc0Ib z#VsPy3295eZ3*FL40VhK|?-=vkimI>b_tr~Y1 z$%Jjxhiwo8=ZHLv*E4OWHYB3KlFYE!@706F<@RzbvA?T}2g`p~bs)7ffeO(+bO1di z)-?Y_M6v(jRjf_x^}=;naNX_5ST-IPT@;Ub)>3bJCobcASF5qrHZmJ6c$AdNyA3a`??mzo-c(qC=BmrEgq0P6-tQJiZ z`{8)Dsb7MXwxeQ=A3S-!aJrQnK@J%EFAMmFrdX?+(-=l+PUdGP>QQSg9p7C7R)YcG zms25pdmZDToxSXLD|K{qWdIm^6^Oq_m8a*KXUP7ROzW#X(PB%)`&km}`^jLGynu*k z>eJ_BKwHsc$wk5kQ@PUTsapX)U++%%SKI>K1hYG%Mka1S7)EVox9e*grw@^VUt6AX z2k+bztQ*`c?L!28wtf#0b+1K0?`p!4QA>j^Fmr5kxE;Q<(q_o9JU{x z;k(agFpGs&d6;PQ-r*3=p7Z`ER)SHjX-yeFukA9a^?}C^q3s8KhI?}T1~CRz*)b%b z>qkHv$$cGuF&Z21v{33A{_7bJ%4JGSHNkvC^oxQV6#(R2WmfqJkWU@~ZFJ2Z3NSJW z2%|_uKtlx_Nxf)#8&DQ+$<)=!$F{}t#$^e=Fd83fgJn!ER1KY!g*KQLfON<{GQLBa zZ2>e6(zB@+p>t?6v3d>WKCJ8(`%QAU?G`My}iFBJ7@9u zv~pjbu)Qu)f~_r2(f~fl0k%xgS$BM4*6&Xtq= zG_Xn_6(w~cFl{nBkf-gRcav#`X!m-5)?`~GWhDprXL^~4Nc;0L&wz99YbB$8tOi*m zm;>Zo#eQ2)gNl+)Ttb+Y5{aA0c82~o1r+dnr(a+%eaU_w*eLhXeEe`|-cRZQZrUxu zhgj#=E%)$kLxF*OHwMATCs*pM`_evp>>DR@@64QB&KWy0TkSwEPK8Epg?zO10~b!e z{RdX?!M7#g%=Fv&in?Kli*v-3aX0g7W_s34Os3yaI~#;Nx!6`mL+gdpe}4UMogB6j zG*Z3;z&^P_xul{DdcBXXl@i_O zdN3y`HL(U)VGrq(ROFcU>pfc>!z0`Tb%w#&L7ID=;k&FD?}HI$kh0Q$2s+lCj=nc< z(S=&s>T_ZK__segvoQ=46A>{y zm6JgsqA}WbeECc_e^zwDV>nZVHPRF%Az}y#j@WGC*O6jDBj_gL<4m!$GTKiMkt<(! zVzVxRM%|2BQ{`ukKz5XCi-%b?N(%Qt?$9dX%D3V7 zlh^=<HRAiWm?nFEIdEj-{za3_ZU9XAPd z>J~gJkY8RaZBFKnl+#YDatW8w4A1nbpma&#yX~}jl!m{BC(URSbX7&E5(AcG^IqsA zj&bbul@R91>EGlRM@Y<og9waO&oAu#k5I9D02N%aoaDXU5ezLMU$ zQIjtHtfEN5rb7@+^ucN*25|gCqh#yzuUov0EU) zgfet=Dy+inc-R!@7PD0dir9G~-`3E;)l>b&v({8`G^(RZpi6Tr7N#?;Z1A0nZB6&Q9L_*^XT{8Bu@ zV@7^$RpJq-^d)RbcS+VnNsaQuw~L1WK#lg{Np8=yth>j-pAp^3z^2Ukm#;aew4f!T zC?UCID}N3{2sAwtVU=Yz(jmu%kf&G8EMX;yJ^_H|mwg21oyxly(VUV;OX#CmWml{; zIl!+>#6Zr7pR7Y%2NqGBZrq^JHzkXA87lO_?}o}G28JFhUbMG`?D;;U8Qhe*8}siL z=nen@$IscvjdC`*5DUvds}ssDE< zDu!Jg;qU9(vm-U54b1|58c(j4Zt!(lu{D06_+}-eH7_=U#gf`w3<9VB{^jc2!jn`ej!D{o$9b(&cic{}KEIR9B z=P_MakoCp$yXp$zeTKmmh%DOah%_x`N90QGo$ zKW8RIXI**Qem4@J2R{WKgf2bjr$80{J|_oEOg&>;>&`^L#R`(`>C*j@?&ji*Z zFNOk>*~h;x91i88PUijKkOuVr)kqI}ZY^Z3L2gr3yr12XAMX@=7E*6nf455&!7&pI zefy#^i1bcqOBP{1s=XG9icmK>Q*J^dG`Q@CU;~HDu&~{VHcOdwu(=qQV~yl*DF(?N z*5?pih1d2t=!DpRH*rRBL8ynZVL(WH*JAsdt;ahGtu4f@<5)ZHnUb;W?2^#EE|#6A zLI84;sjlG5sig3b`lhC@UjdXJhU1S60&VSQL@Dk9KJ1)_ADxr>ofnE%y7$+dcbYF> zRp6XFYNjg7FBiQ3t%uxQMhiK9KvKX$5{h5pttrrQ>%Qq!y@LmThn`J9UV*b4fHZqk zY`T8K@G|m(1hIzA?QM7;KA}X~9D+@VgRr=QK*jSNvS-`zaZSQXB4c`_D}@`$+R z#qTSYO7{we1!n!6S_7gp&u4loDfM8@OiNN->|`T7Xs7q|!bM-pa>15TMk||I5M2mC z9b_jqRV^7~<|D_P|BHPn4kez!>^D3psAge?%LHx*+&~^EUe=Pjsn@$Qok2}y8U9Zb z6sW&c*@viEs|o7Ji9p<(ETL{gSQtP<&cZ!?qG1_rpzoJTWsm@e^4{I=3px(BYMHMU zECQfYf7~X4t5@3ptUhZyd$S+wJa}=Eh)+vfDfBn5t_{8_InCavi9mnKy^^jU>V|^J z!XB3jN9YYgTcB0JKK`mO0NPJoMOw!i&ez>Q92}IG$&Lg>7>feH$;t_Gsq@Z^nu;+M z8{3|W+l*n8K@POm-A@P;+l;f1LVR0CCZqupT) zN5SWdzm@x=(aM?WU#i?PM$c2#-$uznmBg4Y3lfw8rKWgJd@)+=A=7MW80Kp-f|BZ! z&2}tQOFO~aQ|eSPGXSz;4%7E&ud zGrlsw*0i8kmo(wW$`$%E=FM@S%w^xyV!$K^j7f$Xf5wb61*; z@vcUw`lwwdwc>3hB&$329-|dRpfrD*9X$TY8wrF;tc|+=arzi@vw+&RA}Zj0etd8D($;ZvSp_WPU>7-SjI`I#4AG!e;+^2^T*}T*3n2{M_PJS#Dt(iIh!HbP|92_twnDn~ubI)npwJ<9 zd;_^^^ko=1pMk4m8}$yK3QsCjxR}|1Z+_a%qsGW7x%u>j>+tv$D_IN`oWLvGACQiMl@l~`BBI5 zgfHbURyMCjtccs5OjoO`tEBC%@V)!tUra^M!eqG_J!T$x?0>pGY$M~R)PNSFo!|?D z=EiWWDXdt7niuyo7;pZ-#C*e!+qbufiR!2Q6uDix%4R>kamhLOQ<5BoS;bnefItJ0 z0jmU&Tia}Evf~z6qg-SP-`(~_YBLn+0=%yZ)F^qFCFu%kp)34)zQgCThK3NTx-acL zQx3%rS@mzw&r^Sv6aKs*kU)s1q(X60SR7=BG1ezLQ?0`6IUpuiUu={9yE1+dr;0C_RNFRD_=vBA$vjcC|9u zc2KQ;@$O?zH)dctl;+>w+0jUBfA6{C^`P!~&dg&KORq;(q6RiL6WVi^37W0@#2tn3 zv-s(~M%pdo}ludJCl ztf^kB9jt|tx}gk~y2+f8IToFnC0@#{Lehw?qFn;>Z1mvwC^IZ4R9-o^6YFZ*>#zE(Rc3mz@5vO6QRJSqtzqYKYaG_N)ai z!+)P{voxKvBza#XTC4BbYfYC8$K6pQ#^)+E5zHzz6M2}*TOBz`I{hsxI+{LB9#Q$e za0N;=DV?zOXFMv3XX~o{%t)2*t@~+7UU{E1avYISyT@(U!x_5yoX8R%hk<27v6WFS zrYulOq8;)9s9xJDLPw_#JpZ?!{SMMxbmlbOag`Mrr$Aa?PxccO9H`qlo0_^jxOmZE z3GZWpDap#YV#bXK;ynl;h@^8kc=_7*3twUW#mQyrO_AU(kr~fP-%kP^gWaZ-7_Wf4 z-FBSninG>M_r4wO55(TT&o=k^b(2|A2M~W7v!H=x6{AuWs*iQOdr?weKZC7(Pt(GK zOc>_qIygH3eiO~=)yR^Qlz6}Nf;OG3yu>wwBwSZ>@Z6Pi#^J}MIFPE%EFi(#eMQG! zE&C`v81rIf#%{VfHJP|m=iy+1f0tyfZT46Soe7%r{f;*1~yDZno(BQXZlkS^e(E!t`^ z1mZy9bf}yx;zlA>L^5BOr9CSM>rZ8Ki_yOQ+yMx4xP0J7LN@alr~B0&@?mUVY`Oow zGF)!0mmvFk%GzUaOIZaX>5J^f$Msf|3jx6RWzM19fyr?Fh?u@o^g9yIQOj-j9!lJ= z;{EMMl4}m?TV+K%qPOLR6<42F#FqQeg|6**o>vfeFPvV8JUugfa5zNNt2MX4CBA+; z3RW9*NgfCKi7lBb@phT1#a7xmvko&lfw#W%p?uE%`rZfQ@Ag_M=f0)6CHd9uuOvBD zKIj`ky%;Fs$O?6>piI6sBs427=*aH88l^F82CJ;4`IwmNk41v{dfx(k2UE?~&^e^B zkjW$;H4ps2m7DywCGPhE@NS+6Pyer2b~;{KRv{%=pv(=;F4Lz+NKCgG)QP)?eaUy~ z*R(Y5&ix(CMnE8T8SFs+U}B&tXM3~x@6k9R{toz^(s(u>Hno{&>PB^pldxJs;Iy#G zOly9oKSXn+m?kd0!o!NIf{&krsjTjo)Y*8F=e{_W^|`VWq@a}V9C(Arp2nXU+kfQ1 z@!T3`nT6OdAkFu3_HPVucdV?mnoF6Lq^6+QM<3)Kr=(;-PrjN>fMwt3Nvmnb_37Gi z3+||jxz?It_0Tbh?}UNJ&WVL7Qpd3$%slu8h*p!L!b=IYF({NWm!njvC1RK+Z&&tD?Q}eLp2DRX73Mz$((X9OKl^!QuyX6*j88Lf;iKtY8>p4{QzGwP{ij zI;nrLO)U!IT(>s^mblp1AgehQR-j=`N)_U-4>>?l5e`sg!~ePfjy2Os#4lq484Z@4 zW3ta_Vj zGtFn|M!ofxG45xdq>E_obe%{-LCMuI+;(KW5eWb?Py*=-vW5V;Z9isC#vVaSM(Z;{ zCfor0V%#{|9s91V8Smm=WTIm?977Nj^w|3Ir_7+Ab7&BvhMVHVNwGor)Jp~{vz+xF zL%JZP?5h1i#?g6J6skJhQDea|Lq7&=NqtaGEPAxDYNNxh_glVV%f&|9`3-wXEmg&Y z@UznJM$+ov#?aK1+4xVz^C{Ac>W}O1Q*cN+-V~?Kv+DZ_;&?=UpOwt67pBf{V>4&@ z=l`k7oI(ocvo%^^%d_aTcGD0e+pWyW* z_(UfBdg+Ja^~G`6&T;F>V*C%q^UeD3^ZI!74~5IFLXVur2~vyZW37L;P?v@l3})tQ zWTu?8VdK^2Q~j75(7$G5T}u#KlQ=op+d~wK>%Y&cRbQ>B*m%ZvzwO}pT=@Qw%;{|Y zRZdU+t_|FEO?am?hgfA^Pj181KyYt55N+Ujfi&86yQ6#mZwpyjOQd@{ss>G^UQqwizJi89{<0!(W2Pzr~)7+=!PYwgq;PDn`aZ*&Ynl2a|mRU~@rbK>F{n=);DKXV~q z(jdAtkd%%CtYL?PQO(da{hk6}lx6v(C!LNTT(st4--9zi1F-8e(@<1wpKn8^#EBaP zAUE;X!sLxHVfBdGgHhBi)jr9Iv8lB+e2M>FdrHFlVUo#aI2ANiQvAElTAV{bU;1W# z9h$C_HA|8?9Rf^!eSOKC_V5wzkoaG(U66Ps#gjMdE!8AwGY!Q%>H`r8DL4_xE%Xho&ja*O<;kHw@9_gYoP6?Tg z_p)xi={CLjm8v%1W=%aj=Ae}?;)VwGTM9CAK~+sC#9pn*K`&XW38&$Qu5p)NDe7J> zoF49P9j_MP4`;gt_rq3qoyc{&*KM3Va=ED*{o@^IP;Li*wY;L8fV(_Bt*YOt@QTlz za$tvf(kqOg>CN`ovB_G3gDy)|3CkjJibLMdcxkxMmG+!ZunS}fO z*R+%-Z3b6ck^k(MkNGiub$EDsc}PsXa3O@PxcU`Huj&K-bb98a>Xn2Fi)yikDV1lQ zwsNHilI9;gUhlO?{(;0@WkwsKB+S}6zqHwUZy&UCiH!?mKm$JZcX`dbbtM_mNax`z zNCi-XrqR<{3uX|b>-?|`NDwNBp;)`vxlPc^-I68;D5}0qH!G(%ff-8HRHXhQQa(M4 zPqJ_6Mp-1Z)QQHHvdY>i?!*e~8BE9%@+u@Tm`sh)6R7(NgD+HbqE4L(W(ci(L)C>O zKVRQoKlhiO%E-43Xre`D_8g39OA5H$&1qFye=T$7YFHs3Y0sN zMNyv}9DzaP3}k4j$astdWr5MPD3H+(-Vy3j>t}PXG#B+XcwblSR;}SEI~gwh%qVuF zKnCNBm5S~YBSe=1obsDC|IXGYXEQ(A{co;x8XRoeSCKjZrUNHwz@}P!K2kB!JYS-V z_|XEFKIp(RsM8=EAhL-RFETSrX;#UhR1sMsKBJf>LyYKm=bxu@@j6&YX<&S(=v&uV z9Tr`&jJg31#k!|_Jf%iywCsBq@_mzLVJaBq^5I-#b@*AyZIqIGeud-(UWb?TSgpa! zt_fj%u`s|~AQI_^wyZDhL;cOq$A`38-mN?L0$p%30DmY9LYdS-n1jlV3j=Q*+{-6U zjUEYA4ZFBVb{(=Pyg+9VZo@j@>C0&Ur>PKxj@If{a3zALwpG(Zl>O#PMU}uT;T}0? z2U}FH&f^|mzgQ`??vYmUdUMxJ9BQ}Z@o`Y1uPh_WI?n=bYT>}wzkj;5GFCCau8vu) z#g{fNu4N{aqz`|gjqt2uB{v}1DkI8K7a6q5KS7M zb*LyQ8BO)^oyuM=4`t{ZscM993 zSCV}(go3^>{m|DNLt7T&^*h7wz=e0mR~XV>bp@La=Oxb5=Q9i^Y~(|+lqI?kCx7!I z#D=T{w5?RhDpu}m)h@&Oa<)8REU5)_|5lrXFP_sGNko768f{kY_6YKVaiz{jpt5sm zFBG37Ssoiz6`P1kMPxyaM&o&@!KKa4Kg~9@=~aS>>A9)KO<0eo@s^tJm#cg#$2$Em ziW`M!{ivW8H*O_m0}X}AlT<`b9gKcc>mKJ}LxW(HmM#?yk zme837xt)b>I}siRhiUTIC?QB95ZRc8n^R5>pf|kSYY2B~wj};Z2|Fc`(oT9#FB7;B zrctDRHJ zmo~F(-S`&+vk)iBO|A}KAfpNV{=61iok$$i=jCuXUX%bZ7R-@g+*iA0;lvy29@}$s zSycBMHd2zO=Z}`-_$_C`n)6hY6c+;)Bxs@KjXWvN34se7?sR8y`>#SniIF^)e=1do zLmT78obKaTZW3Q2JTx@)h!hxG=&$t@)-LzMrzEqb^CwXYR5dnZ=Amf*4Op$nhQaXJ zx6`WL3OyE)ivFr8taT?ARM^dA5X!wuJrQscZWuk;K#%+`Pp&#K>5&sh zAh%r79jWlxzcG92K5sS}@u#x5=W=_@Z@8_V=%6s3XR15a$vVWJ@*yHBJ6{iAECtsp zccW$gX(quCs{xiU1=TD%t@EOmN6RPbp98)3Q$<|gD5VNGe5Gcg1puN{se&vpRj5W0 z)QSYwddd9gvsbtHJw_A4e-RU+-c8*2 zpndTOsIF68P#;qKwxr1jfw=3fs)v2M_>UwCb~JiUhI+!YG=U^-5|t5W$Dr54vwn~( z%tV#tP*^zb+`BeK6hF4wV!+>il6k~XTOARvsflJMbcCUCNg8cmI@t$Agdyp=sGayH zJx6$NtKKD&EV6sDfWuWIlXLZi71kfK06GtD{iqq7tm7>mhEHf_=f=qQQ47-0(DX7~ zh}}U{lEd*^^$P{MIJ)Y(yZ6w`NBHxFlPGophpFw*d4!kE~lf@s}PyZ5rfKmK4H?f6;ctsS}Hu{-68bY7%#IbyFhjyue9(zIPbZH$6N@|DC+if2NC@#RP~Vj=8w#KiJQuD2QTMR5F*q7+U2t?Nw8H*Kz2_l zO~eNpH?pO{!jsocrA1 zkft=pB46l7eOHT(I#hX1Tx#yyDr5zrOoq!LuPdlEW(`0y3ZibGhHBfXCp41&4#af#Bs`H7) z^cF||@D4EXjb+RMno-45rL9Bs2OX&vdSe7I1yZkUDJU&`wpTY@v6`eguj!$u*pi32 z_DC2{K>nk*LEcGCJ~=R7tb%)OBhfz*EQ2P=>B7`3twOlVsviC{S5NO#g_xC^P~X} zwP_->?z=dn+v|V-Ed5UIBVu4nvZMIRS#&^zXfQec3ewYkAXT;KlBIro&Vm&N^@Z0K zcii6r)j>B&qQqx2<6Z%N%DY+|jEKag#aDxqsm*mhuC1-a3A?}_gj+3>^!M&@@I6jt z+88hx>VFV|M4QMiC}XYlbRuRay}B02RTXOnel%p^^AkqU6SsO9U>KrSfL~Ylg4bf; zE3aA^R@QoFz5IFN{%g$5X^RdJ$)sB8!H$f}Uy#+(w?d98+^oeZ4BV{9FpVGG5Pfcc z*!x8Vct#8F$5gomA_M8F2JWMksxQD?h42Njl;*7#g$*5rwZxon#-@D1h}yCsOox|z z&<~|#CIovlBXz1ib)1Flnr3yxfB&|2`v+R{>>FJ@SA2^*JZZsWc|pHp)`rDd-*28` zgGW;Nv>UAGGE~*IG|)`=wV<~-Llh9f$UL9FPpeEhe)WB3Ao~lwU}QOrpe}`G-Y|Ld zCQhR7r)5UEzOaEi-a}@h6k7hE5320jlxx5gRPcA6YRHIINK64m&RH5+^)B(7GN$e1@vAcG@-fs&G6lTaw*EVWB!Pu6dB0|2v-x+%1_*k1CLrYN>4UdDl1 z;LskSKhcuVPY&SA1}FA{u=yEK)OQZ2mT4=*Zf&8#oxy5Df0A1KCz*8cMyBZ-4g~K6K-z#ykU#`7n)_Ob?Vy?fpPJ~s zkF#AbM-paIxa+az2i*kUU0A$1anIqUhaAFuWhhwEP(RcMEv9gz_M_&AQhsxaA$M}M zM6QLm*wyy+MGEO5Ny`6ps9f#v-1}LkopQBJqOY!`knC)c-aQwGh5enjpW)EI1tumf zB3jS$CYI-i23Mnu7$d0omkOZg0?*_Sv>c2H8FAn6)i1wI-QzkD{ z`cW8-#7nFUTn56N&Mm-i`h(1R1F-4YdK&gBDuODzH9tj}`1h|rCmGgx%y(V+>`c$^ z0!Sb2tYP+x3NHFl|1n$NQ0)WZr#C41ncwK9{vDj0pqHqTez=@q2LA}C+9+_qN*YA? z0(eCxg5FWlF@s4PpWa&DL=!ceHGv&CBQ-c)h)noxNwC`Ww{|EbHX~TW+Vn0JU>(K?qdz72!VT&Qr@u`LT|DldSRALgFsyvF z0Jay?4a9i`uz8CC4{OBj#$QOfqkZ&ooVRJHUZ0&qq9h9S7lZ9Ai1OHtvCgA;FGuw$@+x~O zoeBG*!>AsmH!S?$8QOn1+f--U6V7nH^pi0~|W1du32{}iVsAj~BVHlzPG zU2zYZ(G_)}2hZO)U9KL8kz#|D1xBoXitdHT7+V)AcQz#S);NxD$(&N_Yo_T?`*`ku z64tTR65CVwW4Errkg#^1fw7kGkg&emggiw2wDreU9wRssOXW%jebX!}x#U7&1LO75gm9f-82@Qgu3;C?`M=tIkm>wkz_z(URrvm%o~Px zSH+sM7yx}i(!}6+N}w*(bWTW`Jpt~COiM>nz36xX_w@E=0I2Ig=I{u3o5Z#lEus7R zD<~O^a-&TH2-23uGTCq5lQPIrl8xGApf>?2to7DqynK7bn*}5n)@8I%V0o%Lomss; z_fjs}3V$dONZ~HRn@j}VOF~G7Fc9d<7|_j$I&$;*2e_fB{HGKL=Og)~8{xBbjJ;j! z(T{;`SM!;pu%1>d-NNbm6#m>eV z$kUdcICjcJeFVC{?#}B9ByQv67TdZyl>=WoBqoqFM1zjK4~2#vD^hk9v!}Z zZ9dph=drCVw@~!XcgwN1!iMh*rXo5vpLNtGcZcXhi;*Ohcn!y$-Y<9CwJYzB=;))J zIAbhztv-v*Z=VPKw>Y}tXRELxzm|Bn$_<2w_^aysGhruRUcjzx4o$*3Dfrw;DtVBM z5x9xS?K!{P9%?l*r*}bkZx7qpE(Uq4e+6OM-F&mGb`pdlIP9XqM%j@k{-CH&5&fW)10SWIGZ0HhV@ISPm8PC;INB_MzIA4pV^2LsPL`315P{PO% zSY`Q0#`*r#v|>KYi}R_4IZNWo%=k>b)PQzPz*6{2;=1#$M%s(aD*W%}qb&7#LZa02>sHIrv$}|idKAnT z^q$(kgZT5eqK5F{;ZHZ7iC(7~)q`QOuaz@1=;1)SDL(_vdXx>^U~n+sKH^23YiEPx zok+u6D_1z53qM4)tct=LUG9QbsOJ3(V}*V!5LAq0LQaf!o6*m1Uze%u!6gBuze3Q-O}+`RmG7CAA2_U^hKJ92Ja z*lqA`wU7&r@_kVJzF;UdIZ|s>3%)wQL-aWCz9x@X3JSRjC)yk4Ee2l-y+7O>BB>)# zmC%rSsaF@N>bfOeK}S+|A{`b8E%QXnsb(1aW6H>{k3dz@vsO+Z7#2G><}aOmugZ{} zrn}zKL(G&x7-FJpWfrFjEC^`BGC!wdbSuKI?k{h7z(vC^dI^^6^@M5jfWmc;oZMK7 zm&zv{mfvUJEd?u)zC{ni|&VPwGLwd~gka+*0OW_-eOJ|GT zm+Q`5S3K8iJ->fHOIeAH)$h~C*Dl2Fa!bL%YfS17Yt;tgH$0mO z-}7gllIf5eIyKvjx}bZ;7^NQpkJzq*UW+151sbI!} z?)x*-&*fS>*w|(kK(*)uC!}8}=L*$v>cA~PT|=jne#b12gGLCvHR0n?l1oCpq({Z% zj93LV@b)f+>YB)DXn)j_bD`|67aQ-diMvTu1=&!_0MzYLI(^Pqn82M1&3a&4oOFQ+|h`5HU3%xW9hCzCD{k14(qlYox{EU zujvNYD|ht#{QQ&uNQ_Rii*sCt_M(D{du^Euy}2vdk4lHb=X>9`wq6Ex+K4%a|GN$Y zBCrZUA4HoS7Ic0&zA+miClmWT+?HaY8?)Y1a0r1Nxmc@wHQWCzjI>b}o$njtH2nZe$?42vCQJ}|~CK;WHm^leu z+5l1mag4o3K|2LcvD<4Q$q~~W4zBYRsM?y}z`5DU_wV?IMxUxgoAAAPZc=cQS6@Gh zw@nHonWB&aT{3cl%d9E&*>g#w_m0bY5-fB9Y;yB1gl?pdk3zoO2dAZ!O6}yAke$J< zY{$G&{V^UEI0cK0hu|VB$3R~!UzKToStjiVY!w)8W*lp>X!EQ)1bMV((Xbe}zl!TH zLJIq4I{^`&v+BTz+UDp~GnqA*uVzc^;gDTuQ=nhy!T$dF+FIaFbhdXg)_m#mKPwX= z|4?34EDiW>^U*h#*xLGG=s*q?99BV|TxmnGsi7}908Ibk+t$e*5RX!QXy6C@>}rUR zdoM9DJP%UAJ!9PJ&SFW+aZpLLyS!Zgb_R*=ESTx|p?A_!KULe51mnzG&!N%PVy{C8 z48s^Aa<_-)^qFhz;vG#0Nv0qT8VwOG^}&ys1(~@WwgP|UE4ZEqD&1GOx4m8N99<%( z!D9*(rJ;lk_A2v6)a7&zL2I@@H^3{}gdt5eFUfC`-eSk;eGd~HKLQ=B#Vi24G!z`B zan-!)q~|TjC0>1VUw*y1QyS|?=1e8o)JV@$#NlqbZFW!cVonOt%A*O6?o+LDO)L~= z)8Jt!@k&II2EU&y??4%nRVeK9Q3s_UZ%heq8iqCk1^IwYx7U^A?47n^s?HO@#HP-* zKaO%H{RO|nR*03O{A(0^yQ5y5>-fasWWa|Uk#~jm6>Gl~mjm&oFNdLrT1;6so%!#M z4B#`q{tLA1JXJ&4U}D65w|oEJavLIFUk- zmwsKLr>7Lgx@i*=Bx0fkEl9(+C>_`*`SENeVBLFh_jZ=gVCzh^=byvZl2MX}y&m>3 z9)X3*gQ#H1qG>rrGe$B>DUbC83LX{dUnoKesdFdJJb<>`mt+_*; zTDMgD&HYaDNAvpn^HL;P>QywkaASZRM8dVt%$R!Wj1 z-@@p|{f)W?j-A>;@F^GIa~0B~HqMF+O#_jd0E+8TflS5NbDUtzf`=(DN5cMRzw!TcpK?kx3qJK&$ z;J@vfY<5ku#m>&KlcAO3tHXo#7I5bEpRm7OaVGb@QwvrLq|+3x>4gFX#;y zWugUaXut~Y3@?P8a=wg^1FUH_pe2dIBPfu=Z;t>2zhM7M!0g-a&K<#|=4fBv^Xtoh zJQm$SCtWV#S1#el3xv><|5b5co!$z6on1pUu~M={AE3}pR_bL?&@q0_?*|sRMhQs z5XhNk44zKiI;c50@@-_AN=NFJ0C9xYjxm4qqH@rycv9QQ@l^Pw54;sTERO-*yE4GZ zh7sv5@whtxi9~xYb;jJWZBhde2gM@HP*f6JwW_?(`h3WGX42EiK<1O&SEJRn*mpmA4k_&?gKG zxsw4tI-gffM)`pcK_%B>gN_(I5o)oVeyINsp9o=2UFC%VaGV6#*dTU zv$7as7@;5z96$Ku2=(w)nJ{ljb4zB^(w>E2Lj63xeGFgW(t@x3=T}!sPztP^CuG<3 zlZpV_+i${*bDNJ|GXh`AB>PPO$u#rE*$`OCin+U}L!05SrMfIVfW$P|(DFYGEqskz zoAr7QVXJF;_RRNcyT$@WF-Df*lo)u9Ez598QCr>oa+5uNP9)~_4QHu|&~Z?TwOm-Y zYeT(k#LLj&4$D(-r9c9S{%=&=eevIN;KXNe<@L(-Wl#8d#yA|93DA0wz^85qjb`x0 zP6w-7i)53)aKij9nq;bo5V+)l!{X=W+mijM?e!|w53aYvuV&uAYtJK7g_cS=QQwcy zcS;nNx)0Vb%g;oxndoeJ{MqSd5nUxvrWD$bTgf}(k<)+ut_tG0S z_qa6xs=6P6Zygw9LuXHxxBagtQi^)oI>$;0q(R$1?7^-WA%-2QHw?4DDE6|7a+-*u z78qjxkwAAnmnS^^4PuoRucsj zfLC{X6r&FR3EDk-<}F@dj~g8NcR3S|mm9|#&g>lJvxyg0kD5hdxc=ike(v6h#x{vt z>&9s{*(-LrC6e&XddkWuwdNNdVpBo~^Nl;v_Ne{Viz2SOK6lF*m?R&LPossu4EK4m znm9K}k0(m9!a*8~UKnVZ%hJ1}3ZrU<{B%hzE+iw_dk?DFryGvD9YN*;ItNZ`-%{Uv zqPKPxc3a7r{g4cUkwvB7=0s*&J@(kVWALid(2zY1NCvc7a~{Dx_yv12JfEoxg~8&W zm0Xw-m-*fH*eVDWK+;8aRai;6$ihH6(dRe)bVry<(;J(=zHP#&j+y*3+}2*pNP^P) zPoX@*-iAEf=(VA0u4upjiYbYaS1Nk3a}NWKqiTczDOemd2dxZQJ(uWcNcAGoUR(o> zg<}|dfUz^{yMDJTT%}6*>1iTWo>nvNmEQ`S5?3a06aLtkcLX!5a5mF$F)`7yq{%ly zFPV5YhCg;}epyPCj|YGONRCM0dsylZxr)qE>+K4s8=4=z20t;nxf6~r$c8G+rdw@i z@On+td1LJsQJGATryHshpEzxIXb*yo#&1Ia62dPUF{gRQJFZlfF|MW^kba^1p%E?TJoU&|Y(%Po5?KvPwJC;KlEWd(a&m};yoRtvg$<)6 ztD+(??*>`?<>9g0T@1)nHj!FVTb~gjj0LNkQz8t8m^4V6H?DiDgGHH=S(+0Rma6Q( zj3sW|FCmv>RYNjp=CmF$?3dPUpdXf}It)R+ZvOxPQ>kn|rf<-VuNPHgNvVJeDG-IA z7!xy?Bic+Vo#iL2oX^HLMtoPw6IRMcf9Qa^v)IeZFeF>eIC z{rA3^3(;6_pyhoMDf2ku*p?u=0a6aXvM~$4J_*0(xhe~Pki6nj9D2TAlihQ45_TU$ zl9&%kHI~c8At!{ZxeJ2I&cN$XzejgUb~JRX%yO$yo{RLc%!GQKWE#LK&YXV$qb^3R zX4e@)V(ILVidHU)#%lMKqY_g^Ux-zyw}lu8vCsfw`;EU^H7|0+sOI@n0Cq&BI7U=? zKZLT?zR31;r%lKl3YtGse_-vx{?l^8tY!5(Ni<>SzAIjt^QVB`wxq>(0;E#$RW}{U zeuI&`s#&R6yc0Q33`5Ts7AkLILNJ96;BHCq~bbXh%!cSw2ij6)O z>5~P7tI@1Q@+QW{R^~|Me1N?i=&s&dMDmoen#q`k%GipYG*q46X7Vp#1^8lxzhkNd zqF}Jmj5D=NItzF+{ZH4MKky9jHw3?iRXdaw?Yxs3rr?@bi`82v)?GLK))v*jD60fvzo&jHe>CYh7zfu`+~j zr6@~8Awg0}RD({MvFmiZ=6bp3+CuVU*yeVH|KbsXcOA6iXs=GOfx>xQO}P{^HR=FX zU$o07-*RGPo-%k!^J?K`NRa%)nkl!|Ma-)z&)JvrlQVKNC`tmxAbN}h90>Lvr}1ms zoEZTjsG|UlsNWq%++K2_Tq|pMyEUgSz3sOhNi~#9-{XZj_3M6Ba#84 zwC+AcBz?fAQ>799c~vt0kL}kWtbz+J0Kw?$cD?y?t4v$a<7Ml@dzdcPo=QQ@*23>8 zbD64u>DWedvojZ_fC<9!n4h<_zt#%tVxrHO!Lnpi7gOJ=pS0qdc!0HP#kXSir|?Jn zUlv};jrVkt8Nm1iHlNwTv!2;)o<;VWTvgaOMbmY^x0F~G0KP|Fpf7BQ|%?y2SksfFf5Q(t*^4B+91q!=!Q}l1J z*7@?|?BSY``I>xu{tiB0ZYLqZz_yLPo9IQd+sKh`Irs&Iyu#sw=^{-YDIFBlu+uT^ z1MS{X(e#C=yuS@jByDdPOBxn_Hu)uw8?t%?a(>58dmRS@un>EZZyRf)1o_+BnR+Dv zN&N)hres`dgXl3M<9Vp@RDOOpa4Sas&JzmX;b}`~P6kTd2_O`H!wOM(& z1DC0>kc5e$yTuKiCt7Ni>#v61j&>hopYrKc>-VvXI@A_E7(>l@D%u5V(jrLkpd`si zby|fec>&ugZOORJSQ;v305xM@(^JuT=azHaxbnQ$Lm}qZQHg#CeQX}Clb>W&d&f#T zicII9HSNt@bf=)p=0Frf*t8l{I-rF2JKnQrsUI>N-Q+B5!%!027@cc8QhS8;(NWm2 zvA8;3cauHn_LUSCvaze%8TRt>$`73X9Ma2mChYd$9RJmX+k{X*EgBkBe zzxMC$BvxrpG9Z5@{?UwJPXHqHrQKodrc%(PqfxZ<+%26Kvs)fkDHl0XQl^GXrv8gl zN#RHz6ZqA+^Npw%BD+HGm^5&HD_%SWCj$d`uS9`dF1?#Bj>+qkR`|X@pdHl| zDz|#zE(|LLX_LF%ZTxs-ko>{GDTX17WGp2rYp!_e-1|T&k)g$;CQ549xIb7}Vfo!s zm`_~zW;R zN0*GXuD14wMT0js*&^RF9ND4rsIZRp$V%C-Ukc?%9(fpKDdH;2h5Fs zXtw;>ZhZx{!})KGkm<)@j7?tT4_h$wql1=BC_VpN()^qyzwu`}9mk}5?2n0 zpt1J76EGtGrz1pBQ?(oyqMScY_5;MLuBiik<2K`GPfI#@F7RdCHoc}3cDH)NkvD0t)EytWcW(GeCNhUk4Ff8Ox_>8@F*E2K*iELj4%>3(T~FQHf|}oMd>7hC1Vq!< z;R?_+9s%({FK+X>W~zgEqi|}wVFEkv!%br z(ra;@>2$D%AhbisX!pg~qKr{dLEwOeoE$+pbmRQox!GpFTqILbYFD$VLt2K>4GZ%% z`I))zKVQgo*Un~9-rZDJIG$pWv_Cd9%(9r7!OqQD-~)T33(&Efot}AfQWxIg^9%}v zBp$kHWa-_w(sm%N4Y0z;uM@-31`&n)7tH%fZ!-`9O z3$^AgHi0v;V+`shyc8x9(=jAVlXqONpRHd9Q9k)2&{#%4;Y_6B^E^IFQ2W;IG;W^mJXy70O1iLJib-nJL*ReVU;oE*S(x2G+8rBR6SpEWibF5A z2v>V2*Q=z`Y-(z)HwyNnV3+rCwb|0#i%%cXhQ>oTlqk1G+3;&)GF6ZWxw#bT)OIlM zvOI0Zx41g>$IcJU_DhMN35h)-ksztWk67fGA?%)1df`!~pGEQ`TRU}XtS{avp z(7GV~IhF%~xC-(B8nl%Fe$WwJ#Ou35LU&LYo<~Y5MQq3eQt4idi=bD0^vD}t9;NtP zdg}4VrdYOod~JQsphN(oy9*a`xRo6osqpa@y-`*IX*>P|*`67;t0iCFE;BuQ0SR~TBfuB>}q?2qS57yIu^DDXeKz}+-TR~r=(G$ibhDT4Et9FJn zdMyfncdRR)qc=t5RcRu<6{ z5?u;OQ`#R(x>fcN^}Zj)aRDq9R|sa?|KwBtM`OW^e`NNifZ^SuqIVnODPSRmd{Kk~ zLr%Ln{rujy$o{qbQ0bJ8{IDj$`@)E9Oc+xICxBN29_%b?j(M<~9Q;Yk@azkrDYKqu z8-)_i#uVK(FOmIPs@xX~=+l`L{(6=AbCit4F;A4rgi+9~8;}%P^60skil8&}efS=I z*+IP{vy4gZZvBO1VJ#b^MakB0K#g%ywT|}213LV%Ei@X?n4B=xIbWf)?vrUnyZb}+ zF6@aD-#(aW$DvL2>)76Z|NZ=1S={}sL4EB^*u}(s-6yy!V2FjZ%|9;X->|wH&{0Ad zSaXxjm)nh)&2b>LtxDhSrh(6TUKn>gWHF_B!!}|m#|3$q&HyP@^helQh!@#a-^`iQ zhUTOHgd*;k82I>gha9vciwckf2)UGMyzW$$gQ<2?e|F#1n#L#-)P(`>m8mcQ)iVR<^kzg=-Y(T9Faet)y_ zrY1z|YdT`z6v@rlW;tdA_?puD^0&eK({=B>U@bm2Nofip{z@2je0)OwYODAv4!L&~ zd2z9@7k*ZJT}kR(yWS%4~rU!k0LbHRk zOe92Qxo!gFpK66vJ_^kvo{R0+dTczZ*~&pOZed0vA=PilBR2UO0lnNq2Hn`}{s!WD z!cNTrF8zMdm`lbjoP46cwkr9ji1nJP=gDm-H#nuLX-)o@XT^uT|7Bk-40_=!%pEyzD=4St3qrlVH;ZEbRRiI^UnSvrSw-s`!C3IT%p+H#CZE>^f{U;uXuIPdo!1|Hto*$7*NM@LC9YNsyOZBrcZ9EhMf2Iglu%g z67i4w7PHtWjy8JPZ=}Lt!$gUqLecQU3~`uPkr2f#fTb_XjT}mXzSc`OTR7WW#`lVx zHvp=dG9w=~c_sy@FY64*cnvQsB0BK>4e^cz$Yk~hFSb&;c+aRoL8P;fB$FP#E%uF} zL94`=9<#syFCC*q838c`gOACX=_sj#A3QSIM?r5g4*P`!Ly@8X6?Xc`sA)o?C=@p2 z2A+;E0(kpC|2*x&55vND$Fp}HO;h|bpDH`(@4e_&udve$aaOc*_$F0#wHv`kG39Y| z)d6N~{-u9o*ejnBREF|IFhTv5vLWst)Z+<%+;FBzVNpHx-xF-l^9F9sSArp>{K4cKT$nElgmEl(R#IryA&R1cx%~|l+2B`Fp{W@lHz+ly@I;|9 zA>k;X`y#4v%D@ka4%}btRXLlv9=I?fxj+1lNcEkFANwTZ%XM7rF361GN8`8_z)X|= z0x{z^a>fNvr^R02y=sI3#xM?3VF(tD{GyPk;KIXs|D$8>xN|=Krz$cpT|6E0o4$Hy zB5a98QvJW=e3Z4=`qI@Yv87I|K^FYqXg?{ZzIQwTvKEM;O6*itU}5xMZs{t_&6)hn z`EcK?U-$9WaB95qP3fbO_ILLB0qO_f%8aw^G5hewXSz>PcvLRW;c|EG;bvV<1%B`X z-hkaFjIn2)63E?XId3oE^3l|uFS-LqC%CiHsuE%ozxn|4hw=4XzM&OkCnprJS-{-k z>Du!Y!T=ckRaqU4LeJ`X&az1fH$e|s-W({%05QwK zNhXMK<@3!&{|RE*(j|#^UQ;RF!2Me#{52t@EeAZiEFe4P5zrL?%N$a4=Ii{Zs6QkO z{Gvxym8Y{e;DaWdH>M&F&P4Rgo6&xuqrGDNc=?yFAl3>2v-AreY&i}}ZO1ujsS;7L z$^8r=_}H|Z&zTx3ynpgXMBfmC7d$b&B{e%iAPfU-#Me)#z&5veEj*X5ml=QPkt()ke4lRtoAQ*h$_X%nsByn=VGQvRwas3a>5zi(4`le?58TB!TIaQ zxp{nb-bqQFG{e}OwQ0E0F}elckz7cos=^2PEP@bo2BE6>_1>5~p1;Q!dWO60m~Vqe zilK#3s#utRjPOke$Ayg?`qznbyX919kI$-?tlU_w!d`MZofR9s&6D^|wwlM^xW&bk zFAmSPUtO)AiOGhI3h3$xW$bNP&G|t(27psJ>E$H9&8~BZN+mQU& zh*F0Ja$)K@H)__{RL(Dn-j5)eVLBB#G!bv;N&aGEPS;^vHJr@`Qdx^tfHS|(`mN)O zURde~Ks{{xI_%J#1CK_HXi-*d)~x*F7^JhR>Gx<=lwf{S!`ZXsALHdZ_hlgkHAjz_ zIB!RtD>vQ)jhs6Ml3XJ`zdViy&R_W_zStbuFK<8De1&YoCkKC*t!!GLBc^gIS*l#L z2XL>{*3IDtc)Ctjc*5fV7sNj{p!Q!_VMp$ZT43e3EscV)Kc5JNWe^ORo}t6`twgR0 zcC~NnYYRcS|i#@u9>0;HZ30@j5t zr0VMC+gc15-?}3yCCz+8eN7?i4_BlbW17vc9I{Et*en}eJsGCxcIrk$;y9jiSq$id z?dsYB^n9f}r9|cw2YU*ObRJCGZGJvmALx)+-=ow794->oJ-#OY1||U>8Zj@PS#ZA) zF+M)S85>*6C{EJ-we$)!H_JWJ0fDvgeJ97Xbh-CMMMw!tt8W9{ zthCub)RZyM(1`*;dG*~Co@ZWE9+dpKda3k^h;ODukpECTzF!(JX>LDlK1R#Ip~2XtCmXtpf;4%zva;a$s1t*H%E zP1N+bsfEsSn_l^+qXVY+pUMr>4H(cZs`x@6t}JzTE_&BL<4LhS#4^^eOOLJiD&%J# zPeg7!qSpwQ=Qf;U0mwU>jzH-{c~I7L1t;LB-V#NB+xZ88jGma|l~kmIrn>7k4TGs} zuY8p8!lPy~zG}w~xEq7y!^f2R-bV#g5H0xIjRUmIz3!mU=4TDhx`W`i+SktA@D+{~q?o(Edh5``!1< z`m<2gqlTdYHw;&d(YI~Jo*0cv8k1F@II1V&iQTFQyn~^Wf1NJjOSjK8HUzBKPk)7H&5? zQg$dZ#03QcvYw6k21{2Qtx^{G`sT>Q&PCDDMk$<@$f*GYTWm zmsfb=V{04kZn3fpCvoxmh@;4*%6egbxjxj4RN={e56FjwCFx{Hgqft6KG)3UER&?0 z+uiE5lTgZ#JXYk<->Ae;^7!ga5oy0}nW8Fy2I)gj$1;SPbigu1dPrMiCOoT~+ zmKu22JKLk!d;b(n)`Jy+bXPE;%kv(83*%-}wW~dQ_j#((wVj*wimO38@x%Gt)L=u^ z6_>>Qw4W)xM`6~6KTi&KhB6{=?7halJgX@)*p&W>ghAP%jk@UMk?cbh>ucGu{ z5xlshHhYqa3<&a4^eTDLEN+#5+GWb_wp#}>l8XU`w;hbQ;uzlCSJ(ToGHE;~IKrd0 zj8WQ-WREZEOCv~4tx^6WV~#!M{MbiI`+(&)aOJ$u!mH7+`2y*QtQb*2yDc@0*i% zUG0O=jV{?l&4Z@xKymV}*tKP+xvws1$>{He3J1pCCl%=9xhXCC6Kf07m`^BvynjtU zikjG8y{qlCz(t>S_mqL(s(0F?%7C66<V#`%y+4MAQ0V%1YP3eLyEtZBXM&|xvMakVlL_Z+vSc&@SD-*>z$Wl z#*N<4BE$xV60euz-LTb!0Evwol zvF|gy1JBN;#lM(J7;70fH(e~LWk~p-ShGkM=~>?bUuVIO1=d(Ta1*ycNo0*tIs*tb zV~MlMjtV@j@|Bz3qScoVVS=E;sBJ%xpi zpU}@w$eArCCO7H7>PEw#uxA2FdT-0IOXEdiwZQMsb783)UJFptGu8c!0c~FsL_Zhv z=x<~A_)l3#Et#1qiK*#E@RmE$aPo(11E#9IpZi!gQf}wuInet?*!$*x?;bG4N!OH= z0sP1Ky2IG>=D0|Zd{>u%`a4=Zn(JaXyuJ;;i={g)fQr>~t5hqSv*XJ$&k@oZ3I~1)n(4pT|8lnOC zt-m?V)65V}uFjIbwbs4^D3gIwA!Vmxw6nAQ0-s{2muCV<%xe{8}3$A^t;ptZ&Ko9ff z<;Z5@jY*YeqKp)zill^;Qv_I7E%}8v4z&eEftBXGn8_1-IDG3hLvU@Or^!xNI%Rck znEYerGCVB3rW+34xG68S7W7pgP~=vSR_KnOcPLo+R-2cH2IDyg%$8DQk^6IE^zXq5 z%41sNb)U@hD%lfL2~3b8{VDI9+~G+Nc*XXSKmjd204I!69bSoMc>`Zdlg;AEkkEwV zycDs?-MTRKGYy_P4C9&g}a?!8FJ z$%pitLpb$9iD~wwev$H(wI%Wx2U|b)kYUQsaI$T-r-Ye21Is(p#v~KM;P9f@6BlH* zW>CyCx#yQ7T|KTLSD)JXzn-cOZKw40W#W({W{H}RfH(i~1^hDNS+BINO7+@V=?c2p zzeFHK80$-31PQXtV1AW+>$X{oN(v?Qh(xnL(nty^*F1`oYn%-Ek z&$~JEPQxO>(Q%$d8oW$TlcdN1FqyxPYvj|VV`v48*Bd*#S9s%7ICgC!5fo~@ScjsA z>nv;hfNvmjy(B&n85tr=2oLTVWGMycCuf*An|E<*e7!i1xLX#Xuee?vKb5+fSmB6N zRZCDg=BBuqxLMOKaGsUFIL-ds?)tXa?3~BvuBN(vrMN_OvQke|zH8)4k{!Uj?k<^f z;sw_k3|cIrG@~8m5t1h?_?U5I>+@@V*Vtg+$Y8&OLgGm?balL+sg6YsfAUj%ryPp%x^24K88H zhpS)Ol}D45%6odN&4ZnZ1NlS7=aH779(nQf?UBvtSgG2@YOq0A`{EX>R|3uFUHH(v6ly=RO2?s z+@O!HyQvmLY~<04qeJO)QeqC=#j5Mj&@=pwq_&)=J%dE(O*B8cFzRZU+j^ev!b(W(aDSK4{Qn@QK?hO&~6oXt!h zkU3Vl2aEAD`_>Wwk}LkW{Ty3%etncEn^Dir^4oLEMHtmoEZZ@+U%)>`UNgI5JNqOV zDII}EHTT@-I{N(iB{&iu0cIb%u6tp2T%O7Q+p|hxg|-O0LtYt^5rE6fD++x2C~|FSgyGNmG32Da}O;v!zo1U@9l z!AC%Pp5ZIZQwrhM{Ubwu|B-4lM4Q4^}9=2w5U`QtcV z$#Zy?akFcDdvHhoc2>`FyM<+U7fW?@-kL3Q(|lFmd^zNEv0Li+ z$LM}gr>#f-M6ATVmDw#0soUfAbajs0OhAfUHUrJu_+W7^-+^{ z1YY%+nVmI@AjDhqhoFBz$>b?`k9@WS@kJOhWc!b9oZ zrt4+A^qe&-mLs}w-(}W;ew)69tJ7ZJ%h4D8J=jbo!r0ho$kgCMjvs72hHu3rSWfR(k^21CF^=T97Bx$VCro#^uYXxm+%)| zg5*|NW6FyKXA5HYdkJvC7NK<^^BrP6mNEK! zS;!LGnQ71Umt?2rA|h#gPYNL{`*jYJ6voDO9~KX>^$i~qg+IFn7*NF+MlwJh{J`qO z(G259?x0^|RkeUTUZ)P>b^>`hlBXk|pR_Bh5PW)`p)i$Sj_Zm$sebo?9DweD8Wkff zb}phw*m2#^jcwhHn0$b0yNtcRnT7y>DeaTP{NtM`H^|4lGL8wOe)pl-6tm}g@Z?UG z-(z&`%Dc3S33TC>?aa9a4+XfNy#_|e@_V`3$T&?ThN1gc8Ga0@*2@})Fq=Fjr7w4N zW*AbP$v19v;$CI@9CsBtxk5^T%iwcIFp|(|ew*)isw(JY>2Oc@69rqRRQ5!>m0}~h zysOIEyzx3vxiC084Bc{n-Yz02(+q)gt6$)UB6PX7Q+5W4jp6YuRW|i=479E9Bjvmj z^j_d6`7b0HySmGF>L2_2zGD>*6oh&2jp%IPVhwD*~DSc_R2!M(cD=Y(v z4)tQmh2|&yCco;TA^3E}W0QxgNduprKdCP>;!==s6x`%CHl*Np+n`HDiXTt&O1b@l zwe|I-RHx_iUs9$_++UwAP99P#tw}@TYn(kgDXjb_T@AI{N(rzyUsI<510gIZEM11S zt6V`h;|+{ikg)|LLNjd#t1NIFELyX+yBf>AK}dz&qkZtN?MyZK&AK6W7FF!lpPSxs zk%iS?e~%pS{2RG(rrPCQKriG>U+++B3q2Qf$+tM7oEug$oMiDWuoVvK>ub9-?TJV` zC@M^mZHz4a3UEFrQ=WhFa$Va@~6FF$O+ zpDIw6N00-QiTv^c4)!ehd-X6M#-k{Ek}xc2EY?NVy%NV$bF(w|IXQ*_62!kQKG7v9 zQf%rrJfUW6Ao&n}`8HPS%C&<{G~M)(TsfPaEqAHQB-5OS8_xU& z-*ah|x~*FHX6)Rs=lrH}H1?zmCw05MQ;Oe|aC}~#=Ht=9fBB7=Az|T^zM=usrujy1 z`2dO`?TA9P3wKxbVM+rqf7o<6m4^MG`EfaWCmzvhzZ-0?E!<_c@4;%G6{sgag3=KZ zTI7uzi-akXk=2Ijk#X{OEQTsty_#jLr&awv*!Ou)Lha&kj=P-0bbhbXfos0@18E0& z{fdYaRf@EN^+SZ^GF@1=tofhHH9P^nw_hucc1JgpkoAeF2KYOeoshJg#22CsH~cZV zQz$0f-W&7`AV1)7x448?9-u@4S`;Fpke?e!wZHYIcZOeLkq6(YGr}q{zcRNKP zn}LjRD8Oz`vHCvpLpM^$LK5rmRip^PRq6UMn~8KLDg}z%ctN@(^zN0|2FKyxu`5E` zT+Y`u#e81ETb}Ib5mPXL7sa^%4(cZ(0{CnRIR80wz1nHpU*9!nFZkfNDqRy1+u!}< z8QtTrGTf>&E*r#4%U_+R7B;iU=jGM-M2VDg!@x|D5`_G!gx;pw7MnXRR1>NoQjpAd zeZZ^Cq@J-=698$RXh&7-9F$O%2f7}N5k|%T5|ilp(c7ym*B}e%ww(@m7_A(u=pfgK zEpRt^>DWHKT4F&mKISBf7YP3RuoMA8%?}1o^NFRqw+w`&zTSyNQCH11A@L`Sjqnu# zoteFHZP=Xp>E8b7K;z{i}*B z{mpiUpBFYx?{|BU{{@n;C^x{!&+s|Fm0y?kOWjF&y|t&L_MsD)bI#Efh&BB%U!uYOdYs*$&?RMR z;@?=8*vkW(*Lt|)k6lKcQi#wA%-$pC&R^68#A0cWW&h~)3F{N^GHX=DqUO$OljO+-pDJ@4iQ({) zT8E}$#L*^0N&=;)y#mpkgO=vT1G0#&I2e@PiGK05UR?Ba^doU&!Tg;IZ;=oy_L|-H z;DT&Omb{95H%cdv$Yi%5X`qEmXWy`SG?hOD=*PMnSzAH}Fg*rribEsYwL*OD3ktB= z_I#CmpPw=WDN9E{^;+%r>uV|59=C_(7~&PkvG_2|(M@LlxAo`;GHX}1yW42x*^~k6 zM#^^pOqCF!o$aMTU=x$9Q$WafPy&o@G_dhimX!iur;8*{keOjuB9AbOBhdOIPmF2t zPYgBLu1Q!Y2Hq(VVOX8o*hNVQY(75>r~WiFSij?qxmJ9-I2A7Ed6ZR2if4j=+2aj< z7U*qt#r;W1$q7P&G#5CntIM3Y!BPEw zUqZ^xUb4>%ltl^P3-2}}1E>mqh|5cYn=+yC09`aQ{())6$>r75R~N{iEa2kOkaH2e}uicRjc zKfTS=CsRgj$)Fl`P)9xZwym+lrSZi=@!r2l)QpSU60UcKg8@+ zci~ND4yim406l&HeTlVA47#yLA^|N2828GRCYo``Auo1oGh4H~txWiyDgKTnTaP#TTg6;N2N{07Z<1Bs92ZijGP`y1&#LaNz2SreE z*h{mwmMQoxQ?qc!!h0)eW12m9F0OBCLzD^>T&VY#(RHN^Sy@TR013dOl7(iWfJ$m+ zMJfP3Gn5gFBpR*mBLm8Ptx>_MQzd8|a{7{xe(tZ7e=^1TEt&F*J#BWjI>Vc`#_7@` z#t=eQ5ga-=bbf8lHwv;LQJ)n^O41!Mi|R{P0)sgO%un%HkIU%|$%(rYpQ8nDoX0{R z^d{wQXQ5cT$j;|#Hf8TL^7bEv)Wrdw4Yzm`dxDMomIKU0AA1Q$_{S~FlJWgclU9PC zUg3r5;j+m*G=LUm$iqC#=3!cj+PJH;L9;MATJIj^_0tEJdC_zIwpIzahLyCclfg{HAk6_^Di(Mv?>{)Nsy}y&oAeIUv0!O$k;()-jJ5! z!UwID`*kC7m0fiIp9SbosGQKCq%74ADR_7RAxeHdsrfJ)O{i@0<-9XYO(yqX!!$7kko4)1A0AIxu*s|t(Q!Aj zFu9ny{jjHiR25&dgZWBiH#OEbAh&zn-pRFmzvp}*Yat&j$tR>~B1`C~ASuXUv2#VS;IW(PT6IQ$&jZ(xVG0QnG=vLicG1s! z6)Q_qcelNMlh{rjjZZuYXdKPwe%d8(+-}ba%(IcY7~zOyl5js?962TkomLLXsh4;r z5Dz22YP51lAK)d*sA&4pQ+C9s)ut;KJ_QD_{Fv;+&vPkjPm(mE%Xb>LF)u&x&Ob|E zi2g$L7ld0dZ4}~o!s6TX!nXSAro=U(NE85IaUMItu~q& zaZlvNtsHP-hw#5!6pDC~O-gg3wtN7C&9DS`?{6OeN3vyOF?+sbuUlvVzLc+gdX^l-y zDB&;`fNU!F*lg?P?*X*mq@a4c^>T8c1rzxw6ZMDR`*+i_A2cG~n4eE44q>E2R#}F$ z`|=7g80qh9NCKcdK>Zss#QM8+Y%7^)jwv0H_XRJn^onaQ>ysnR$7C!-tAfl}>L|hj zdAS(tg6F|mT^a%I!sE;-vCVqaRY9PPdDmdT{UO_u7E;(5gAU&Grvga>AV}L1(kM{>_(IQEFGjrIc$*ean zZAFrTRz@0YTL)~3w7$>s|4m6*x$yWRXO4S0@^i0;a%jTEqT!;U4_ik&<)V ze}EujM+kXbAz0` zCbD;QaQw@(aA)aIA$gP1e0f+ll>65dMqtwXVSfy+Lh2`Lq9OY;a|qfef{<^jn}H7c zK1Pu>mC!uqpC3$v;^Pjx z+sn!8i(Zuc_8i%L^PYEbS}T{DmEUDJ66IV$8I3Igo|!#2LtnMAXnQxm@QqHZTTE>O z!GxMDBaYmVsJ3)u?@i|YEG&Y_Qy_FMN{d4W^teQnvGXG9BUef})9`U$zD{Lt7sL(6 zc@F#cOA0Mgc6m6kG~VYW^r$Z=KP7Qi{N?H2>el;-u;eOdDsYy3<_;cwb^d`S>AeHF zvBbigr!1(l9BXXFG?}l7)-x3`YkUevA*HVoExK|4(nr^$@?~Gej`-Kd9yt6(5{WG? ze<6L3mtchV!GmXP5c(KSdCuz>Y{u_n1IHt;Qbsr?f1ZfT5AC8u(V-1qm8`$VtwiV%1M4jWcm=KS(xr75L47p| zK@W2Cd4j#;9|KXHAbamW9yB55ue8O2JX0r0Alj+(z=yuUG*#0E)Rc|+@{b<_N?cZs z5@&0KkBSAGn-7y)JaS)YOjF2z6&u_-arda(H*ToipS_$e629Bdm*N6(@e&=`PAZl=lH7^cO8)lw6ACkc2y`JQ_6j9Rjpi^fbX0<1Y9*) zUwua)wS-=DZLNjssAYJkb0q)qK(rzT52%O{zR`0@@L3YTBBA&p1@P%1TB* z*|+V#`6nZ`n)Yk)^3luf`fa>7k@u_GB;G`@gA)HfQ5)wx8u%O*;|<@lTNeL(&ygUn z7K5MB4bA%l2d(73VXYJ990*RJtFcc`$OlupG8$`7*RC{^@eiP9$OEDP!UrwIE(8Ed zlX1b$RQTim;nx@sqq5b0XTv8KT*u1;M>RV5i%yZx-tA4_!d2tK-poGk_S7!2?cV_h zlMnvvzw_|9!};7^lva@5=ZD?HJpI}IO^DDpH72gYiS02nP15>w`{m5*xM57l*`r~H@Jt&~>T-kN1l=3D(Wz9-GS z+{l;poGa`R2_(z)M_MU8$$JmCjnp{PFsniPqLb>Ma2&TqH0L2pL9fhjJ)^RpC<0rd zo@Ysi@-xI5Ck!kz{o?gGYp=rY#KIo4P{}+sSkTh!mk*m}1vNck8O!E*&kA~7E)wT-cZLyHgsR#*ERDc5DJLgJ_ zgWunQUUut>7!`gDkm_CnSU{uTI_pEDmJxk&mH?jOyULY|PQdSyjNwx<+o~C#5OOt)68GfCXc7*VN^6zL1On?&bZa8HuIZ3n`rG{`~R^01}>mK_+7JS zqN&ODeB+N$JO!LvadqFZ)o$J{qv<&WCms|h08;IdXlg#pygk8r&GKFE(hR|VR)3l1 z1AGly@*IzsnfD;B`X;|xFxul56#2Oe^3GU4l~Ubr_f0$e9)OVWT?!1s?lD#`$gzR) z8!80*3L4h$I@oC5P5R)3Rh%Q%vMG2*e&J@Eb?&u@Gu+X6&0HV7=~#FR@3~30~oZ({7iKgn3FR zcH$Qz%Psx%(_W0g91mLeN?at*JBDosdx)`VMXw@#BRn<7%XR1CL@rW^9+*)xeNA`l zT_){v8}kWZ6{1{+o^lMhkLJahDe~p_2F(`1fO;*Va@`TknMV-}PohIutpAOJ0%QVO z%h69Yb!uZ2a|eqpN8INyoX}p)p2G7*3~+iKyuk@hK=sdilogW{#Wt<-M9y|(F(rQGZJ$ONXQ;h`hi!zE|BD?{;Qa%T7+z>ToyvpF^Z>L>~#g{hw>wqpE1O50KwG;M>$#<#O}r*`(TqLc|Tv_ei?oZ6dL zxU{p@?n`W%DR~L%*gV#PWoCE2GcF`^t=1f{v9BE}2?mG&{L~nh(*n8~M8)Aj!KhWB5XP)&*XmeC$-2 zu9&)9Z_?p$AE0!KKmhLP6PQ%DHAp95YJ#6(q;bTK)dl)KYF0f zqn=6I#xV0F&F646dx^KPmW0ZlTd>Ic?9^uAOn&Wz=0ezK2E#5br z3?F65ZBPfAYs4_?+ly;H%rt=-Ugb>?Acwj-}#>iK*IPD3C4F|5Jtq$;?i0 z3t<_|mwenq-sz_32?gw5g2D(2ki4`k-_m8#9w>Mw7T-_sR zp(2;NO^1)pv zGqRSxI!NlSqiZ&04$o$<8xXBXNL5VL4AZM}8LU$A@Wy$jc3LH0HtCF3+c1hZ^w-Fd z;pTb}H+a(a^!(S9yuzJ2Ts0aIU7wLm|vd;KJM)=)+P}JWeK>01*aOXN zZco^da`>wvEyT`B^e=)SLh8nSe1J~{$(4m)Ga4G=2F&Z{A~o4SOrAX*{iK^yWcs2> zCQ2`!MM8PKcG~U(>>DFX7xppqn8FV_2OB)DWbApCjHyRvVJ$+0cxSc9U3eFT?=K3zohyK9RQ{nIFBl!m5)nGl@(~!4|ne3PV`I^XL`?qu?nOL2YaFX=a@PpeNH^* zw1YksV=}}=&GO_QkN|R49fsqotRMhsUyluruKh;B=YK`D2>{{^n@PZ*0Iy)IKUyiu zt>)L_>#xpq9%xQb$a|89EU1A)BR2c%Uu~(gy+D6fY^u*2Bc}C>)*dTkcu_TDzFQ>| z{YvW3J-3KByN+VT=$M>yPv!W2`r5olkNyr5B*8+GdI%in0$xo&(In-zn6=5~+;x2b zz(~Vb2=yl(5dt=~;m`DbajMcKd?pM|k|#UhET;cS=I}@F$UKGhX1y7L68(%x znTY=FZWtb9h2e13E{cO}n)i4>VuDF&8huCrXukNrfB!0Im zP$!n=>hN4cmJ7aOkW_HGfM0Ni>H1R#W{IRBz+pcbmWA5G>xm?(#iCF zOEB~)xifG5rbNMSW|BP-WA(eNMfl(a&tWt?=KFtMxb{pkve$KF{IL@(7NX1(d|1gd8>CqeF9~yPx~q-7-$Ay zW7JphJ?2by|ZLm19-LyRp2xZ=fS%l3+G=RrSgOVvRqrQe9=&j z(QHRP0Pn$cPe_!ha#54d_3F~VxoOBsz0jp@=Qz77GoWkCjkhBf&Ix63nN;vZ;j)hg zvLhLdHn!{qauzr3krJJM1?TW%D~=SGL86yM1KZP;iIQbtyZyATC3T==L$iZX$}pp; z=asbrjM32Or?W)AmDJaImpPrCx!ak{RY7gTJ@HF@(kj*xLI=rOS0f1q6Z*bvk5}NO zk&8yIceuS9`G?={`LfAigAM=y2YPvaKpiWwK|k@yB4%CW$q1ggj!%%CHJ#y=3BVD0 zR$vz`elez4i>vGKd<<+jlOMy>HBmj)P$~a@L@(oA+C>b&@<*6aTYkx}`RmX`yxc|m zN==PX>R|VoFOlcPuNMi{S=z@+n@%P&=lmDvce8%R7iT*hS37f|`9pRkC5nTQxJg3F zZxmfu)xM>s=@uS4f<|Fz;T7&d45Dc+UV$lkop!PkFjN~~!J z3o7(YSq+i}mG~>oxwlk<9z{_6Hl@J2)4v!b5J2T0k=49yn0sRmpqbz&Y^nGs<^q0M z{DoLkc7>8Sgc_kE_xNkiwCRUOt(|;DjHNDbAMnuL#8tQ&OlI0)!HHI?vp2uyn2e0~ zV5)sN3bg@?A>ESGRA*tD+WvJ96uuWAQ&U8_0{qq-W9UaQcp&)uTmsD>c8^hMNL1nD zd;A9s9|lpSIJtewU}@(<$9te;-e^o(>hV!(Dl4v_paaS;U>dK8y6hMimUQDZg<9Zl z1Z~vnAqYJAHxHB?0L>3T6YEI%++OY;7Z>fcoo>%>P2ZjR+_nzkLsp|hlJCp##~B)o z!Uc1>O^y+$Z(zvH41R1^lRF#M*wly4;>p6#p5W#hJuDOwlnw?_I73njMseDFz75#q z@K2SR-k>(dXMc(RY;ED)?_S>TzrAlCcdsI&XfN$2?}4&V0=VWw!5_dA+K;H7n*K4+ z8tH@)3J|8-sFL|oE*OO4mF3$fk3m$L3srVTO++TY49BM(6xS(Tg(sV@*Ekk#PhAP5 z;Y{M*PF|JBOe(*8HDffj1?=TN=NB8a7zsz^3+ww44qF+)O-S^|m$7shNK=Y&O(pqA z#3Ij2?F|FN3oN<9Dt%~Nlbulm>PEl$G$q69c9%DDb8&CL*6LZfX29&a1?k(4P3>nG zN&+jrQp$({cEI1gpcCwq=(zjBG`;a3$Mm7dVmxXO@mXL)ktuP2BrM-N(KwaHqO24J0~oG+m<`G+Wvl@_^J3-LP$0MV8Z}t3E6fM z3E2T?IahTbw@wzIYi#Pwyet2fcWjiUNp*;+>oYj&0^@=J=Pc>OOt1ez;-i zTE+0jkRdfi^O?FSI{2B&ANh!|r5)uDUkX)3nj7n;i#?cRRAXY?@NYIdB~<0q@o&Xt z6XdtYi{fYN?o(<2h3)|#&j(vZ%P979$)_S~*}Ald7hFF%J_2eWd*`n{vwswIQ(&`3 z4VWX)Dzb7?XZIcmj6PMfqG=BA;M@s1SYTq`q z5dS8e);z5?=wJvBikl&kwI3Xvt+CVgQbWIXPIjQr^N7@j*x#JK9JE5#m0yw4*Tsui+_qv-hc)r|?&c*K4^FtBVsFhv$kl zB~3>+0^?(X^ByxsOfr*X9-r(=^H|;mYm71HQgu1HxW{mO;4>2c<#v0x-BF~IpKoE2 zxfG~0SU*=be+*v(TK!d1_*E|oP}I)JYDIeearUwa8w7$L2fdAfMb_8U=h?kE`z5X;oI3;!u`~GghzQiYB4&Udl*+sj%~`4pN^@o` zqeJEAfR(tZdv!9(0BL2aju7trkH4s;+y4_;y&1WRq4aZ9^p%6gOI@rEsjT7$o|h|3 z*Xz?;N!XDei=*X~x!9VY3~)W>Zj$vzkL%6W4Ic6~1JnNbXtVsRM{y5;vk+bl8tcPx z7h!&l$ua!Y%&Y(j{a#uwk(PITK4Qgvcs_!6LVcpei+_8O-JU8 zHN!fZNo=Z*Cs3*uUiG$hQkN7N*K^GmDK=4`2)jk|C; zqUf|r8Vl;KQk;8+)px(V$}O&spnv`ygb7ZrSTQyIhVI5baxzk(`T3wyNAHrufQXs> zQ&J~5fOqI97XL!JBz66Mu(k%i=IoI(y-(D-CHPdv(mSLWYbvZM@dhJd-Yk zMO`D_^`Z^PY;+qt9hS|L&s}4ojO(5z{iQ4ooVF>=xH%j(_CDMyN-Xu>dB0#Nd}51M z9uyl=1}A=E#E3Aj!tgQIiX%BPQrFprIQ|YR%;?eNQDxC_e#T8h;Z1hm_0oOyCvSFv z_n9C9<8Q?tsu&9RCYV+W3jb3DP6zR-KJknvHV2uSJc{yfY+L-WTJi$9@w~p_6;sA< zn4I%;Ag^FiZuKv9GjtRU>xjP1pX`|+J#dVj=4YVBc(oNkS*s3fyS+%S$qnuk?1J%w znwp@@%eJeW>=yC?ZB2p_=oxAyF42zPo8LAP57s@atY1+e;?F{VKmc(DiV!UB7hJw# z4&)sX{e+N!j;s1D&fSbO6!6I31D8kVj!Uk){C6P1<-+o_5IER)xH8AE#3{Da;C zD05d)=}X{2uXN)bi^W17z}rqy>c0pl=rH zWplQ7Jv>tNK6SNC(}}4m)uLoT0-u9}qrCm5lclzly#e0%1IX_@7)>}To7P{Rlh7h3s4hv&AFB_XbL^RH%+RBhFTuuZ@U2GW}*wwgl1%760xP!Vj zJb6MOSwf=ZKi1#k%OD^C805>yIOQ{9#bn)&`u{8d;0eD112#1FL}Xz8U^e9@E(Z-* z{1j$m*yxU|+`4MAvnx5{%Y!d8;tNT4OT?gWddfW>7VUjHg>)?6g6X~!6huE?1jb`Q zePwTio@jjgZ{u{gBgKMe-t&6;2oE{Ik;gtTAIDcM&Sw`;G64#kMS+f{8!O`2LNxb7 zJ7dD>c|x(oxIj|O(%jKN@Cq3qp*iHNUaT>8nG%SX;*~~Q0Ayox0cLdX3K;|3LD3=C5U)Z)M!m!xt zY%6~*L^r_1F^)=j1f}R@{GVj;11&P?q=!fhIamwPJ1dgNw%aQ>2;Zv{{puhXyXTggtxzxl;rm=<_ft)d44XKRp!_4O9BUXc|^D@SL*C zLHCFCdsVoa>J@D&VAnMpEod_^s8>CXz%vyouC`Wl=mO7I{VN?Xqx9o!x%_H{Ycnlc zN`^>y&2G?*iv{A0X+c(DV~Jz=Id=8otPYiS4OI zL`@hPRFf$0$!@*^zhV5d^+885sq=y5(`+agBsunH(MuYKi2OE6Y^T@@^2)cwAV<&WK@ z*U5h!TV2E(CJfH23_Zdkt=B{Cuvpu_<0rnPOg`5=HImnPSOyp9&+*hhz~(RF9ngii zrXrmkEcMwNnt5{Ovvp>A#Fp(2!?>#GCQ4Zp2j< z_zf1u?RHZR4FA`A@=8aD9N@VqJhTDwUF_&*(H8phW&`E59pPyV(A21eMbs*4);@5ib;cBYUyd6B~rEmUq?K2qK0@oVb+(bBId0thA6oCC((wlghFXXi{I0!E@I5bx7$C!}tw68&l1PqB zo^;8*sV;f`tEy_`EB+J(F#D{H-X(X-2WX**;)pVCPVDZ0VvdHV)XpU+rgva}k%2z% z-Z!H6&IJHwnl#t!w=q;T^lGuoE_I%1ZoRfL$e zTH$bvrqk_gUPa^l?MU-Y;&h1X{=kV*J7aq3-KLtii^GHpQc_QtG>NteiMq||+;PBS z-6eF2^6rku`*0Esr6Ek|X}r;B%9*n!6hC#7&qQ{Ax_UV$=i;AHfuK#hfnEP2=~XX= zZP6|ia6^6_FZx3M8}tZ5-*w?%@hkJyc(}RoNHaB6Rmt;zZOw-}&GXK4QWqC@0f26i z0i^2Z9_mDfFWmpVrh7f#RcH<_1o)Op0Jx-0HT<~-KmBw1Kbp=noXz)dmB0S?g-f;qrg624US0+X(q2}iEQAfd;<( zqq0Ofcu{Y?eZCgHq)K)55(IJ`@UR>O4?Z67z!toPQn=q!T>BYS`*R=Vs91_*m1qu~ zDbU$$4t(9Yuv2>O>}DtRWUyW`FOzBNf$ut)bQ0av|C`JW)_Q3MWKEz4 zfJ;R?-?B$^%`%d9i;qbDyQh&%5sGqhdt2XSNZNj>IHSF5F6bBXtn>QxXl!cp=(M+2 z+@NA8USo*Ea~1}-%u4l@wKHD}1QlD zoL;VIXg?z7MfyCiS9|NiJ*;@ybp@Y(;`C=QX7R~-u#It5=U#XAIp}{>+>8F}6_UYr zRFaYZ&Fc!DO4qHQ2U#`EST4Zz&h^=F!|2A*q)23K_&j6G@6kyzSqcDx91xVK&s6Ak zub&~Mof?2|Ek0?((memy1d{(H^LX}&U&wTGr-rgg{CurLt6a1 zd~jc5S@HdFavl4%ud?iRk`m-)Lh3y|k(oP6o?7499K8HsvTKG8wgxPP5A~i$HvYO` z=kHG62aUK2L~eEP9Dkt6M4@iBsKyYg1#yxn_pg94_NDT zV?at`!eDZADXt;GL|my~Xf5J^5AaR0|FX$1Z~E5*bFlxrxe^mJaAM(1=T1b8tEZWw z?sy!-Ia&55#-F6szKClL7ZNIIgv)T+&0^xFntt4(P_o3@=BP#^=8_o4xuio%$rzc~A$!sg_@D^Q}k~3QzocM>}FF#uNfQTvw8Tvb@Q;FqQh^ z=8lB|>-@!^TR+@$hCKsl7J`VFUwR@Uv3|hkk27!T5L9Tmez|f5Z!2qYMQA3x=*PLg ziZ@^Plq)t_0*dlfk|GXVPO=0^BJna56&*sJnE#6NK&#r6~uz1>3!j+ zZF>r@b!i7{q#oHxz-;i~B-~cVZ9|Zus*@5xzZHiR$6~&bN~~B;CQ@@H(m)zF-sChy z4k@?hhSzqbVldxdvX?i6TFMrI1>9_yAy!u4)d9Za{M^14o!32)GNr8=$|^5kZ*gHk z{HqVtpS(C)V1_W?!GScs+F|(bG~i@DLhk+gU8~Vui(z4PXlXQOJ`za;?XL($kefx% z8%o}pe@qsTP*<_xlD{u0dL#JL5=tEAd^fnZM2g78#AW-K#sLjs8;dM<8p^*l@U=R6 zyCW@#*Y0JJ(2wScOzOZueJ%sQGzH`V|ZlbUB%$jEmPrIGY?%|z1iu=#Cv#eo2iE0P^AiWYM#2&D6aMf22ip!#2&ko^e{qhnxnt@LWv= zbTxRYB$Tl3vDHk?qrDo|U+mt3MXl#8W2{va^!bVfBAYP?!HTKKU$23W(T#=;-Ic8W zMYUw^7AE)s4d@J9QliXH87e2>Tv#j~oey$Xs<_nF#YO-Kc{Lh_AwvNjh3#lwzAx1z@hBC0eIN9cNj8v>SINd>8JZ*47dK1 zz2mvvk=5nKe1k$_RR1RPV~ux4FiBOYzUf(v*6l5$CGFUAeSWj0w<3%Dzsnc@H_5}V)gliw6&sg3!a@{EM6%p%0h=)p3Xho9Id&| z*uCy!4EuX{V4YV`b&Vyd)Ed6RCA@WH6dE+|xrRL+-e#`AxNfd-N!}Se73&4UENX2L zGI|q|x}mFNg&uAIKpOV9h4iFTgMohFn2wPSnc%9uw?+C^M<+A^`<3h#TVeUPQ?%TJ z;Afoq7M^HX#jCYTk}V4S%a$aa>@X^v#w#w|I=5iqMQ}`bH-l0FJh4e$)d7Aqc<+&h zg9kY<5gkins)}WXNdno=??Kb76Bw_GU%SV`|K8D&Dj^G5!6hpoZPMA|dfy5T*Rkxi z@X8pJ^PNPuIf&_7vC zbL@~kUIdMb8}Y4PmG z!k*#IAM!kFz3BTKRMBfslims{!c-4nkvj3D`K~CJG?oI?hl~gS-yyL;X+N=sybUx6 zveNuw9eSIITdqhQc~(@w=a}LyVBz@$ZD=P9aiRu*iKN-b&O5pG*14R3u3*28*~%Z4 ztbcMbh-Mu>gfGNf8)~AFQV6M`V|fy^YWFf0m}LJz#Xq<|Sv4Y1c$v?rO1ddfa~T+8 z>*OSMB-oqyKAn&3F@w>|I95piNMh!X)Q?p_@)2)#IGgefeRIjb%-Kk$udJw21D}aQ z19tVe`b95hCX?`RGPSA)va(*}lieCng2ITsi0R>@HxB`T0X27B*(j|uc)6yiu|Y?F$bJbJM;8O8j+7tpL<3z*0j@b|^f4paoA3}o zrK@$l<~ZiKrt_^Df|QclRkYZxZkfDnm}vNTQ2ElcnSxw?Why~csaBsKbb@}GG=a9{ zJHYibmf~K|B>J(TsCP3R$7pD2q24W`rCHm#xvDKzAMH6yO{lDmCwu?=*{OZRZ`9LC zx3H(vUcONXlX|k79Sf)GW;%Eyh|8Zn56W_bYk}=ka_83{37NJjpyqwezL0=Vv%9{p z<+qM0*HB!?IGG3jB(49%)oCEcGQG%enUwNee^$ad^|%Do)1Lh25f1`Fba%o-#BcBb zY=Rn$Coes3e3v$h9Z(KJezr&LIf z7Fd%%KUZw{Cpw$gz@pD8+KH{!eh*78Q&-$;PNJ6{^(R&c6_z8!(irJ`aD37k)Q0rH z2xoOiJlZ1et-5#H0Y=Zm9DCRBv6|`8KW=`;p4W4ahfbsDhZ9D@`m2wwtAD7x>bB*I z$c`F%(&S|UAcG&^nI}NiU6IN+cYnTxtXaGhFOFvs`&$3;mg>(WZ{&dtl;U2g{6l>o z8#>7|ORm?ypL=I*o6AjZ|18FsQz5DsjSUy*DEJ{&vKEZcu4qaa1NMhStF#miUfQhE` zv*gO}*f?M7UTrPDoDh}CIJ`{awm=%q~KYn*Iuitto%M78UN`ig@{B z17pzSjSw2L!D9(1jf79>;@Y3fG*beHBFo-6ur1At`<`>o5NC7@FnT>8cY; zI7RT;Qk$n))amNvzkm9F@h2fC4T{%)(ipF`toM3Xvz@uKY+c%rsVw0q3vw-T^nSgt zglZWjhVJfhEeh1~DCV66&yHD*tG|C+YEd^99Y}P(Zi2395n!3=z;5G|DQ81)JQF+qC_tVAs}dnHiC|XGx@N83lQc~5wIa6Q&Lg? z>d}kY$lD}Hp(PW1HD{@bTx3PQ!WhIqf9!n<=*&(`pyu^2QZq-`@z_-WFUY@J7Rv8~ z&N1-8r{o}44K{>?FT`x9F?4YnXfsWAw#lXTu7=Vdl_w&2(gZ0E@J&5wtRkoD=%4$< z6VhCJeZ1s_io;6pn#h?F!vM8;+pEakA*E>oPVaij`0w@pk(FYm<81b#IDs=jXGSt( zHOEzTnv+3RmFfORC&@?vZSpDg5%s!q_#tn{OD1Y^=jXgKTQ_E_F*%k39u8kfT^pW{ zpP}w$!&hwZup8p{LA$NQosMI(#glV@s&>h`n6BkA^WK_gSldRv#Z?+7?h+|tv}jt9 z!bHZ;qxN>!XwANP7iV$A~>bUzLAR7Yw0F8hmwZItiDR2DhTQk8NgBu!VlnB$`T$#xT z%J*!TJ`N}2K%^G4hQo`7bOR@i6vU4z3MG3Pbh?U=Aatd&36CMkCOqhun%U8V)1iTD zWP%U%_06*_dQ3q-`X81~9GMrL1gGx)G=dt&@^!jN35E*+^)!%L{&=9O!O$oH+n=QS zohc^tX;AyzJeP$d<^5bKRWVJxPv-vF=;Y_&gI-Ki=bTr=7W&iT>70jD?&T-vW*y5a zBZaJ=jSI<`Gm@D!*n2)tIP+0WIN0g2{sW0UpGl?+u~-)KOt6jRxMVLb^bP(d66a~> z#&|yScz#gr4ou-^zf2S`E>4r#xUNiS@4uwJ|NhMSG`Z5l@ZjF9iXJ%0a)u8YlW34* z_>`V**Er=rj6OadT%IJfb3~Lus>SPyht4tHW`<|A9RzC&)WW=1?%bUe@W)}eWj$vz zj@o(K7I+rAVU`PfFI*HyXF&I=ynQ#I)ojj`;rAnJK+O5MEe*|Ee!cPzSdn$KJ%lA9W&DgSU zTBv}2rQ5xzU*szO?=_-CknaPcVNDGB1nqL+V|g0^k&KFsovI>a+9fEG+i(Gps*r3jljpp#(pj`Tr!fbu3MteFm!c zX>3MJ;?{(t#|>Wrh5GH6J~3+iWTfSmltRpqN*^7N26zbjK+{Tn2V+weZ;HfAJ6cm_ zcub>(3@@L&s{!%C(&0ID^NVMt?Y^Bdaj5{cCnSFGIRWBLhkx2g6TUmdb857>v*8rv zhwYmG2yy&zzXg_(^x?G%fZxFF1+gI4Q30%T={fa@yv(Z|;@+Vni=ET?{kOJ+jKwtt z#ovdbd8|6GbnETWyYux~7G_QT;pa~Z@+5t)-JKfJ#S5#O&!1_4%UQb@gD>~@FC_bV zG!jo=IYS3X1=~(}2AY9gJj%a!{1^R>KJ6;ANEj|uvR{d5YYWDaW@PR{eX=K~#$I7W zoO*ob3E}tV@3rl1g*Bg$Tqy!!+jE2c=&+^SBg7cnkk)`atG2uvYm}`K?yDC_c(J(RA0z36!)cTak%dKi1dkpoG`jV zIgBp&r&Kz!B`DVP%3Q6m6a&o{5aw(HOZ@2rkcTMI!r>eU(RfWg{)1P889$ha*K#`^qTUXCirvB#Ex7E<(+T>>qO(`pL7h zjpNT|C)D9b1u}yd6n9OSvk66XX57uzs>oHv03;X`k`SqZ$OJO~>CQaU9mw>Z+ij__ zR_to+Jo|-9LML0#yN4d)b}z3;vE#hmXCEPP8p5UzDvE?kS=qenWR#@<2n--QMQxEW zKB37p{v5AVW)ZWWS7SmS=SD`=PA zVCtH~ZRhp8f7b)o`LeG}HAVWw!-bZDFQhV)(iUf7)ZxCnGR|)FeBdUJ%xA2Xa3UiG#8b1L?Wr(D5&e^-LQY3d9Jp{uBNaap zSN|rK>wMdNP=lx?oD_uq`?u8?7}TKr{ivP}{6y!L!!$8z!#~A9VJiUWziXCxkW2xH zBd24H%EfN$gfoC_ejR zH0n7aYNVs6t&!SLl;c7p#6hHYzXPVT8A4r~@qmvWfqa1t{1)O%XC^9ncvg)X zV@u<#12cT4Oc1+=7}m@eUhG_;c)$0i^J#0R!U{0pJ)zg9Yqw%3(D|dSmvFeh&IC`h zhj~YElMZZsZmpJ(U%821I?vTt!lffuFC0=PLVv1@BYoIcY!xLvnoJ~>(!aA(m@eNk z1YtujOv&I3}o=H6F<68J%E;w3T8`+1y@P4LUMB- z`1U<}VdH+TC|@B!PW;M)j3^HA-|f9~9M1tV*meJtj)P{`pPWyv0=2Xo7H$Y)zK!l2 zUu*>jgtaJ41zlEtI*NxlfD8=4azc?p~1F!in#2T|1jk@H6SO&`VJf~}do`@Auk zII&C++SOdKbUxO%T7wqM3O1!twFu`&<7j7xt7ta4*=72k#J zI`5XRxpQP$-Z9vU;p>|@Sq@!HTDHJeNeyesO3;fQHd3#t@ zM<|(m^6$N$LQ3kCXlx4wIYe9%t5No+)J0%`jGdAGRZ6fNv7N9TeYtad{9G&B&+*}A zlP}&FPH2YqOablf=#7m@Hr#)6X1-w|zF}Qp5KqYdxK~*4o)W|T2>IzA{0vgdfZslu z10X+gx5fgn|KZGx4Q+e2kvnaVNYlPKVWMtn{33M-=ra|l$Y>I)Gyl|hGHNsR-ACHw z@PWIVd1~^QZ;5Z5nC+UUDC{)B@l1F;kC1^1eZNsz5zPqjEL-x`+vYzbQrx3~3^iiD zk;M_(bt5oQ6<(-)6&=k0s{k`wN^-eGpgNIqGC9qiC4(cX)7W;xZ;AGXfYCt z=xCYR6I(+aSS*@vLLph-piKw;Dq$kROi)QZNC^s-qpqqJ7l5x-o}8EjQDvLIg)cWz zTAv!%oZ!SbiVhAYFGtaCa!|n``q%+>+6mSUMRXX0^6Yz3);R9qDD>+Ulhny2W7v7u zj3RFGS)H%)^S89?FmFlgDc07kRCAfCaQ3}B^6HyMEa4LkJ?^R{Y_}!G`%72XHKE{Y^eFdE*x&Q6lZvr0?uZ^i#7hIA z)H;@J-ijW-Qg`2x#c7T0EtgI?3C8dZgD?rlR3n-7)Qtab`V&T zT{GfNNH-&=&}rqRT3W^o0V7ltFnA}ia;L|A;<>wDXZ!i47R0{`o4yP2JGfZQ zE#*--H@;@OB#=6wZ->_z`Z$pLh@jJbrJ~h-h^-n_+Om-uKFCQTn>tO8z~Db-pk0WI zYBX7QN)@lTLV^Ru6P5{^1nFrn<}Fgjtr)v_l%=Pz!+7ouOuyAZ-KnhY&AkFr4nubS z+h45-y&SEmz@n5X{bRxrpNg3#mWL-Au165H#$pAEb-sBcP#EHc{Dl=D24au8Y;N@F4$47wR^J0zq@ zwX^$t({@&tU%|n&vD$^xSW<^CwokY(=i)H}vtG&fQiYXDUlPIl^!9opHXFEe>`c7fTzuPWz8{EVXt;U!aL4HnWnuYny$ zLLklDkS>Dqw2{)=fW?Bd=ohGyOXchw&_FmSiX$W{qo37&LZmO*Fuuk^sKnf;h$>c% zES`x8oM8V{c5mS`Z&mnE~2uq2@~ky0*P(ZoAyM|-;eF~j(;o-66{zezqoi(>Sis< zzUHY7tLNUS*@gEYs<~@s{+)gnKO~?YICh2x#wUCvPJWC1{-bnqPR>5AFZp{YkZr)o zkX5(=A>^ItqVZ=ut>Kes;lN581H}b-U%@cAT`X` zot72Hx}0931h#v8+Xh(#c(0hXQ!#mxg2}BA?YeZ3eE~uzUtqV= z51sB_^|*W`y#j-m)f%^@8R_)63y|4*PQ?L}Vkhf1@xk{nrS<$4L?fbVDsP(Dr)@(sTADX(tdT;lm!muMROjof@D>So86qf^j`4q)Uxt@ z0IbhQF07`QjLZ2y@sw8GHqm6Ka#UKHm&_A>^jY|Wg3AEtA9unAdDwAcvH$V@+6PCq{1+uptsTQy7%?DHJ@iRcd09P_n!b{EHg2M(5y z3N+#wPH1Ft^!XUpvU3||i5&nFS?u`8?aLfEjz1&nZIz@X;%@wUz0N#te#b*HdQD2K zl?ITRS8{fzAmrGbCuCs6V_R=}j0Vz&v^(yTu~T)YQ5%+t0;4a*5>$bz!2Z`h^>1um zi3)Z<%{Q3q+-6jLv#@2Q*ICCC{AD4M32nfUMirx^`k!OVOD3f%OZDfhQMcxDD%JSK zA{WlmBeH~?dDG8F&6j_kC|(wN2x-+SYRleap7*+;l+KBD?ASdQwH`dl&yQOdi>?y{ zRo@krbph+)*&D>xu0o{^ug24Q+i#8$GYwfJ#s=LE*nCls@aYD4**m(ceAHq(m|oc= z-bA)rxRzfzzA>+)ig^J-2oli!FlKwFIUTAYtE%hB{V%BB9@WPbhlohz>$k8QN)j27 z)Pags0CcRPa*K z0E!)!gW>QHAmXcxSTs@pA)mAd*YbLZ#I81JBe05!E7O0>&u0TC)u1>TQh`t&e3&?m zzBbf>Drzxd_ZteP&3J82MKzkE+@0F=Dw`wLK!3PzYSi6Bz@9dRHUkK#A3${qVWL}k z7$Bu$RN$zOv9hB}Z5Bhqfyp2&_IzU4SJEBPaRBL8gH6MyrScm5G;lJ#!l!GYNt9r9 zkPk^w{UMSm?bQ-3{75Q;!omNi)Y0I(Ix7*8>3JMv?eaXStdO7mH`A;bXon#N&zY4Wa>mT<)~J?= zBK<6UN|rKp_7k%KQiX=un>&5*zugM7|3b@xe5;I0#hP>1nWiDPbtNh0fmLnq>PY2O z^2Xj%2yM2ieyZ{&VLAO{lhD({m`PVMl80tD&OzzlpT$sb|K?y{KSc)H@h9L-JN=N$ z+?p}`*qsVC$hOoyC6;lFiwO5`$wbw#vRrn6(5Ck4$0qIcCCSpyys2ekO96?Hrv#VR z`7hsN8vJL^DspqBy=vIEU4iy3e@USz(Prss_xUd!6G#@_O}~&JxgMI|uK{0Ehkr0G z{rgz}lrkNfBvhTO{g(u)H>*+o60mT+sd#Qo3Mqz!9c}E#k12E!cA$eKm&<4JAKObj zVST^3F3FSsQwZjsl`GJ)63GN-c+=rb+8Ye$V(})0m(^Vztu-M}aQBE_!GPJn^0ajW ztu(oI|3&xkKh!A1K=h)2VhL{!i=PGSNM`NGWbM8^>>VpG@Zq*Y11+{e*eg~r!MC0ieTb51CZpdL{b+AV7KYw6frE9|IU=jLsl_v%SY8YMK-bPn& z2}Ptf(8n#96GtZco$nAg(bf6ST4fRfXMs?ZY`_8Nz;cQMyb z*7XRi2Z=uFeNpQmEbAt9Vm~jtJOhmGQmp19tr?7wG61)i&|4`@?PhHtsO;F?jKG82 z*`;4{;@^VYWcxr8?5$;0!YuWCPAH1!K6sCbbQU-(O{Fvrm<+}Mn}xn@*$L|V-K8{y zC9l?ZJ1z^s0v~|_0?tW}U`x*%9f);dF@>EzD%P)ZyoT`67n#IIlRfk}FzCO+AAUt9P5=DF0t;z$%g{J8X zzWDR5rQ^BsV@{S^BryGUTi;Xi$E2O$6Hn|m)-#)QtJ<*~#RIPMRk|SwcfV7}7F$5apGx31qZPi;o#B2oW~ju1PtiIqf-n5f`69K;I`n>D*q(=mFASA_wM^Sk|AnTFB06(PCl+tDxLF?Ff1mNLWlvFF=1Ic8Mi zWteyBJp+`RejSS+rM*I2qm}U^n0sP0y2+Y{yR_J+qN>JkN2G zoX?>u;&d;iJ6C3z%)=Z1aIWjek#j3m)H2O*>?cEVsQDcES$FS94vZ zqlzhoG&N4nz4d3|=2dqKpdHegw*YTzOPdcC!UfZ^ohRbd$=vig4ru5zE1wvxyyu82 z#4Jmiz#Lx;2=d?WyvgSP&%=FUHPmN&skQ{L2j( zDupLhOs4+TfDD!tr?ZvtP*Z_Z->+=!9M8`7_71+AZwdiIei=^2guZg8y#2 zSWqCWLchR4K7V{aTs+6mx#KfVM$nE-1QO^R4{G?+P79V^APa|};#N4vPXpBNFhdqI zW|>m>K7=pJtfAbNfxPJ!#VeeEuX9uq6y{VgR?}<^qISQ`$6cE*yhCEkjXt_$-p%)3 ztj=<1CFt)bqfJ2MPufu((!PQ`z^YG*g?Qs)xX%C^mL=ip^AVksmdgo~Aw4x@zYkltcbaOE5as*#yd7*VD?GYtjFWTnWx` znse!(*Zesr7829B)QrLCvV!#t?OG`_yXwj~BexW{X?ssg5 zTBfCwM5c3bSD_6A_fqGAV9|s>yP;>Zqw{=v6Q7cjuKi3 z>0yBZVblOXSS(|BkXvAr>-BoU6}L!Q`h9tJ!*4Sa=eno#cH;q?6wEPV@s>$rA8o}W zBZC9m%kUp(gtnbvbkY*Xnf}#3!gM7uXY6m9oyPt)amQQjhp;vjQJp+imX={hN5j|u zYi#fOmld{e9Cj%UA+=C03vn5HK|}u0(j@zMM|a(9H4=deB^r6 z9iyi!${lh#DXn;YDjMuDy{Tr&OcwfgYx!tUT$M(a?)UcP6g%8IuFo6gMWy)aK5PiQ z>Sbls;&<>c?C(I(qwqq~)uF3+Eb}FG@?e1>9g3%isAL-O*oV;*Y7RDLyLW~D?-ig% z+_nJ5cqxgVu(VRNG zJ}5hmvzZgVXbULp#-NQ5o6=)flJ@Itn?pLC6}cev6gq&6E;BJG%@J=AJ>*NZJ6ft5 z^WXkust%+oDG@~&0hzMGRRfjAVpHkKPKAUEC4|zTILxSo)hP~=VF+La^1dhMy)Wi; z%U7bhheg$Z*~!1jSjFMN_sVQU&Qwx}A(fL@w9nIgI%f@5z<@qyNM)@BJc_Sz^rzxf za~1TkHrqhB^65uDp?X{PGNgSfQxtv0#^;9*FF#r5HQFjRS$?L&eG15^+1Oa?RJR4# z6iSPpr=>}xgE$k|qy*K-*p#8SB6QPuzrO*(`dG-)@ncilnAx3X+#5jeWaGuz*${87 z^9{F0FZiOsY{}j^__4MJr#_SI9h;UOJG)EoS}WTvthdh<6hhk!n!{)O6`r3i#e4Os z3e;Elg#;*`4G9|^d0qb9BUC)g-oMxkK^RD1?WIkwg$7@&^cXFOOD^mlzSN|TDaTaU za(DDxaybxSMRy-kQ)5 zQs|!*qyeeXed@O7;Ns~S;Nk0vx(TbH6Z)EeYxylu-CD*J}}ro2S@o0H4b@a>_%z#!D#5k0#lnZE?q* zy>MT|=O33L1=-7+g@`3itso2R%BwGsEw~!jR)9J5)g0YTGNM`w0LoUMV3NYB&;OXe zWP}fmocSx6;b=b1*2|>UNYmt&Wx#u1{m6ZpNz9rgo#m3^kPv)mUI3R&{8an&g?j+* z_kaImqoGM`hFCDOKB9cL6n&ga(z`kk(Lg1ayQTeEL{Teug}`848uxC{qr!@93-_i` zRJCPlx}&KW`{O~`ux7Jw*pZiYNEAYm?Q|uL zhgpJ!&_=>aVa)w^9Q+InQc(t)2fFR^JJJM8?Y;5U)vT`5GsUZwU8|1J1}nd=gAaOo zQ}L*YejbaSKb~C$XeKWyQ3m@ntaZrM^~GvfS*7okfBf0O*!5Lf5|44>gX8Oo>%WT^ zTh0Zf7pn&m!4yV}={j1myWAOpYWU5Qh4aC_8%praD)d#_&?=?7G;{Dqu&j{ZV7BgP z%~v_Z%l7xZ#Mf)t11SKvVk}8u&F zInY|h8fhOMr%=2-lD8C4RtNmNMiZzZI|iHYgXjMxdOfgj5jGA8m7e z1Me)~FN#d|H3GRIA8+CUKWo&1Gzi*_Lo2b0F|mJK#f#Tol;*ZXb9{r%uaH~?V8eMW}3 z7H+8Th#PQ7AgLy89;n|WL!1}UAlf^}?qL5^db6SMvJ-t36!wqe`Mbk^`p6}J?BY+W zRUq$n=$WzgRQyE2#YKF75>Lo=5YOddmLeI-%z3jd^tk);#Kh|A=LXWJSkKW?FmNeG zZ!E9ZGUS3(v~OVpzmq(Xu;*?^;y`p;&oEMJ3}dCKRF#QWHk~BkQDvKM+7ZnDP>3PnC%mkzmpvZ}!RYKcYP_0_&*ua3 zKgPgJMK}PoGLEg;XH!!LsWXhr6QxPX$tgsaTtwmoA~Mo2PV9LE3xz9tv25lncWELW zqX-?c3q{ScI4i@Zq{Qr#DW*GOnD=AKl=2=f;mp8(*N5+}!VOKoY1ktN2 zX}{^im^$;e)Ak&@H&dfzlNgXDV`gq^6EYeScDg^Qrx^6P>uq;9ADj6sXn$*V**Zl3 zC}uB>F)RG83g`m|Ie>S3daUccL4x;d`qEDvPM4k@b^hFZIYZMpWIuSa=?;~Yh0}xVD&_N!R#Sq|E^ze48ZM9DM_x&BT@RJ>jA#gbeh|fAhb&{E-XR-tod-!(Ce> z0l}{|*f4UF_1C&Gsvx=u>;zSkRJfBjgW z0QeUaf)VBE-U;Eq=#Bhv+I?-?Yt{8HGgwl+{mcPYiedH@=#8h~=bG}ed)`B-sx3Bv z;4_DDKO^X7bk%A_i@iD4tFtv$R_;*fRmbIcQrMUIc7=|&J^@_>4~CQ6d7nDg441oX zpLz^^yff{|lx*w^*KG&-2&si0^P9%ldCxChi}{u8mYZn(eb{)fu@V|4A$3Y zIs~`}F`;`qzy*tsa|g-nR6qcbOdpM3a>ahLkKO;Yc*g!JDpK z_FEKeUkw~kKYrXWGVU)~aJvC!UbD)PvhLtw^>+QFC-ZQUZr{{LQp z!kBHu4bq<;l@}0QCC%3}di2S1YN{5|*mOs5;jNSj2lDKttQXUO@v?2)3ntmp_Kt-Q z;T?^IkW`xl*6akf3FG%$t4JdsVK+)`Km5bs!`sp0;Sw=NC!ogY31AJym(`Hw*?}SZ3I@~gici$%28uEO zrsCJ;S$Gawe1wTdVs{|>)!*~+BSg$p+pr2hy&5K z_ot3bTWm_Gf?p1K$A)!%0FfmtOEd8GI?!jP-kDF$ZnbmDj|N8;s-*}k8Idt-z`Xkc zO}umayzf$1-E*X{_{<7=&c-EOGJ!{aHm8jWUz~_UYQTv?e>a@255}x7&I>NKoEmga zBGw{bWF~~@~d>E zu;;k{DD-K{H!~yOh4|_iCTQ_Np?PRlyZX!oUtBu7RzN^k(4~KT-|oX&LA-&bEbhnK z+psyV==ez$!vL6!dCmTZmh*Xbah=};l{IoIX8VN2(2_`vYCrUIT1|9%rDkR_kEZfi1!*+hk+o^X` z4ktYU>NJ~*NA$frU zl|L1Fz^j*@AL#nTmg&zLrshHuKylFMx2+~`wnH`Vv+Vd&@czJiF{mm7ej&v{tU)QB zEj0`6|E|>a6t2pSWqVOr5`KR+SiFU6q=hv=c9rw~2;D~ODOjC7;t9Hp^&ehNA?P8C zzLQNXfETm{RD$98dINQMpB`VXysx8|i2TT*kVnKzrY9Tb9+ zEr?h^cQTp1QesponSFu_wi>e;lUYmh1tXy=hx_A0t>!L_HrbxbTmx?iJZ4< z*dMuROFTh1R7vzS=rWSo-JYqh>oe106s`Spmw6n7ze}?AoPyr@zl+njQ*k`OD55k8 zgt3+#o7p*zOAW(~6?NH*`fV?+P88jRlGOeevZ`QI43#A9z3L4ns}D-n zD}$6rqX*@zr!#y-Rt*ehbS{0GZiHuB9w&(onrf24-=Av8pOX*N2T9*}z~uFYlL4ZR zlV_kt!|X{yJNnJZEV1kCAqf*3c6H}^7k4k-#<`X41E%FTJPqLl4gvZOYOf^xVeF{E zc%v{w1$ii=1qpq^RE+maDwS;^s!3AvH9Gx!y}j}2QJWjK_wz7gGq&qsL3?6PZFFVv zBg2#RRNstrC zUpzZFzj+HF7E$#A>gl!1T~Kg)!l!pavX3d7gQ>=Ary=xo@iJHOa`^i1wWUQqi3TL) z#yseVuNZ7~5HO08ec{%{GdDCS-)MWB(IpdPc$hma{i$9u8hd`e-N48rH@xlIizfHc z<1Xj{HlUea=R`z)?OX6_=CR6uoO1&Zx34P9NG_&ybb1|QANV_Rg7M~RsL7pJpkRodll$QW}1~(!cSc-n3-99@Li{q zBs|<7;&hFd4qbgOEq!PH@r~yv3F~v&wxVK5>zRpy?ewx(GZ8!f@4RWG6l>43@Kc0{M?m1ml~+kc~$ zraPki)iWFyHk;Wc0+W%+@^AZ4efX_d-8~MAIAfue@8m!4 zu>Ke|6e*@kqy#6kvh^VgxZj9#R2LZQ9S)h8)fa^|vtj_}kRucF2_x_E#0qz(4+g|8 z8qTDI*(K}hY+BLs>#qf#WR~9cx0s!KC;+q(=1G%75bV@pU<%OwmxajTDkti(-Q zN@G}_7zdvCQQ^)P*uMP{)VG}u6YJ0Mgc5c*5E)?@yc)WMBO2+d+>7p4GJ0MYMRXmo zV>kb$6Ovga-NANXFRE6!o~i zh>?%*Ns#zi%I%-v#R&|vWE8dc=5G6J&D=!LAO|T383{65rHL%wf0yi-kKvI)2xsPb z8vlSZIU0dqBp)v%)aTP(+sVU412{go=Ko+um3MF>q73xtW}W8uI65fLeoE}+b2)Tb z+Yf*YAPTQ18|PY<1>5~W_&qCwi{__l$H(V3Cf);xEuw&kJ91FOZgO@``tPCMSde!6oUkh@k-1f)l8C1Ruqm$_GdbNZDq$+ zw-&UlCr`G-|gVz4af_H;DlFFrpGAU8aozW*h& zI&(Vz-aR()Kg(WCu~#<6ZG2nv^YsgzNsIB-C#6agr31%NG@tXcjJl2hCCuK0j54Ng z-eHB)LVTq3m>C+M7Ga>L!A*2hSbgc!1O$MJ(fiQ5ezeHr-;-E)?6%I31jH(CM;`4V zA=qd%nrmze)lrV2X1q;mrW2C-5&Y*^wEPyM&t-OPlf^+hxth@LNC9bjQ*aDR!*1ye zjp+ZggrhU-7rV`0Wn?+YNzwa;{R!w9ub(%M>(PJNsR+l(`RS;o*p(u($Y!q213KAA z|L~)N2jqP73I9acz2%53=tre)CIhGQ3i?-NH6WOQ#)v z31o3g18bU!=|b+SiMjD17P+&Vq8R1aHzkefik&TH`kQ+th?NcgY1K+<2zf041}IPQ zPKnf>E)RC(nI12QFt0^%14V!dhq1Thfc$AQGc$T>uP5QRn^?qzcLnW>c^iv8A=a-% z(1@^G=|{~5vmWg5$BWdS2c*b4Wr;$bGd;rOnfiY*%vYr8{~aBD0I-RW(FVrK#4!y2MY3TGShAjJa2PxxpAYJ9GS%nvqkaTZk3k$3ys@$a;FNi9n3 ziK!tfQAXuQ*etJpmT}x>0FOqpSH{WtOXznxZeplSw>5!6Y&W>-+VgB%#(ryj1VI*x z_&ix@am;nz%s3mm4j+%(EC_+oOM;97x%&I7r8e&kRf}@&=5LpTyUsu5SNfU&-o#)q zI)tp>DYmN@{;Sh}Iwc6e-Tyf_xU2c&tEZM`TO?AJ@YreB5$pyN&;_@@FRE>_c0prAZk|BU=DS)sIkdp0AgdkX>0PWvCjp3 z!3d$>d!+B~8^Q?4V!0*5{2q`6=&*<89O8FsgNX2Pc?Ds+mrvPJ;wLsmOoE*9Sfp`)iw{c=b(dBH+`cuc3 z9!ANs&^1ji9eBg}f!>vA^xpI5&yrm~s@E_>+j76{3WuytN$3A2t!CA&^WIMg%<;_H zfMH_fHL&`&5+#KgiLsxb+1c!L1jumqf*FQ7#*M(ly(*RYgv5mi<8m8q#f?`v$GP$^ zhKXKbBKoMzdzdK*8dGB=!lR?g$psiUDm9nz{5C$XS20@JkHWQhPa%&l@yTBs5S@^F zIz+aVX|$Wnq#2inS)J4)o;gB+&mT}jhp`zxEk8m-j3qc0A zhO>pE$!1kl*K%E#Kby`seWem4^rRD}^LawPv!}qU+su7|saJ=3{~~_u#g?b}4X~!s z5)Ti%bf=4q_7s`!+u^DpRl!bE5<4 zb=>?*v!xl=ctP<@q?g#zLCeo~9SqJ0Mr zwR+w}pkUQu;K|M|H`z<24)jND|&8lV7c$*a70e=-T!tF-+k`d*{Yh(SB$>tJqE|Oa%5ZOmsZ3tAjaSZ+Ktl)-o7%RToLJEjp!J zFKVYlRi~hkJunC?F4v?HdV*jZTVbQe@x%%MtJ4>J!HNXJdH*@aWF8$EG)Nq1hTYxJ zgk7*Rf2Y0<-iezm6t#=fpj#|ZuXDwKiFGI{5)uxu>qD>aE^htLPEXyv^C1=EZogaD zSb*xF%k37U)|H6`J#4s@UQ&7{Q_c#*$nKh)8%LRt7<@~l4+weRhFJU-$=!f(Z zi`EL%CzuYnxX``KAF{LQA(8Q7fMDPK%KwFPs`X5tO~vi4eAv?E@ULp=1x%E zbQXx3Wi+b?Rw#Va0DDb7`5Q+~ptwUur;SCs0bY`CnPq=?!|;n}ITc?iy7IX^F{|i4 zls%TKscWK4g^C=YR}(`R6U`8;rF|ZkXix1Ox5-X}U9>g9U0iTEpesfW_x_}SFe3g9 zeru=|HWO$(RI(8e=TLobk?Q0^lNB=l4Er^16jWG!r?zKF=Hbnkr=IfA1|wM}YczE6TQXQVB`(W1 zwq@PzP`LfMzoN{(P8Om3a^(NHtiXTAaR^b76S3}q zZa3zJlYT*A>57=`dL>RcPb;O3-SaVTTZtM~;I_ok>i!K#SPznkdmepndI}IAQhMuP z)jIs}5a7>T@d{8Kp?6XWUvk+Cl#)(Fc5?450VBlhn7>bQ-Uv51Y5e|vwgTZ$#Ky$B zb*N10Ys#Vf!C^U_u1{eGd~HMLS05N}EW=2>d32@x3bJ!+hxyB!rtUo-cMbTarY3(u z&AU7Au2!7)?C1q(%UfuvX+@vUKu7;-dDj5Q%DfLmUg&4BEvz$()CQm)K1#8ltzN?W zo5!y93dgc4CCoY}L@C!c3PfV-QU3mnss;N(IgBf({ zsGb?D9HhlLSZW5Ifi8U1wi}saF@}>7J}S0F9+<9lh& zK4udtzZ$0ua*|X3h-Ni6`{k#oQI=+i)n?lP>z2R7tFH*p^1posl^D0*N1Dtig1_m3 zA+$9sV7x?EhtA=m9C@?XWLkWr&Hpv;e>fu}hQ567@WRg_c|R^qk5M#KVww82Kh79u zaguBva=%kk34;b#sfUke~;a|*I8sq1ieK(yIs^$lV7 zE9>HEZnMeUK<(l^8v74tmaUx}_F%)>o#&^gxTdc)PR~+&wG+9l{1UI%1Pxl`xG1dF zQ^DVh@y}a$=31b3PR98ctKbKI(Kpo8Su8l!ek$>mplA1jsoeXePuK{t!=I!^w%tBBa82KmKhc`k$>alZLqD8#}wu<6(b|Dc&tqB24M5-`#c? z2RKAmUS3>m^`FFsGHd`HIXKwy=V4nW6he9ueYxuMJLOdb=hu{bz_L~fW?VUV3XsJ6 z@y-j4$>PAAOVL}aY$Tzb45*(7!-wDTUT?o_EMa^;4XJ0mylp9ttZ^FNm@y>;wRsg< z^q${$jkN^w;jfFn=?dv*`oFU+%O=FJw+9Vg+{4GFhFd{+QJK%ajQ%pj!uuG8(sG8h zDjfLb?`=53og&M0gmxt+hyZ)3(@mU`Z(A2mIx#>xC?Fk>w0ymEASkR}ra4K4KR{{C zpQWP!@#2Q*sH7XC`@h5uykSe3##`rN)gyG_nft@iMDg={Xg8%Rv;u;1pA-_JU49#n zl_rVQ80^j1c|B~`tq|SjSeBaf6PI=1dhYJMHVfDO_iA1XemfF+r#jV~CsHMJ!JRMw z%T!>|=bBGsKVOb^eH&QesT3~XoNeWR&A`c4FD|DrQ?sPn_H68zk~fL_9J*-3>O!AL zX*VVT)zo_U@h~1u)RlM2$!e-C|OL!5dZ)v%x)~6&}j6()fIK7DF{p z*=GPt_}bm?;;t@u&x^{@BpUdnT5M*6`_=wFJT~^>XuT)s(Na1E#g@7WSg3VtHWL>X z^b9K}0!{o9W+KeV=oe4q4!)j0B0DuVadmemHJ~XdVWzS5=J1|mpZOS)y$^CG%sfGL zhs!*9nx&l%;RMJiV=L7{+TYN;bOOAB#L8Cvz_|SrxgnC~pr%OyHvBU`(_8)|Il`n| zPA~x>{`*M;ead}6{zqPGGXRy6UG@=eDz|~+p0(&o8%#JQP=8mL;r2(l6(qmayskTM zNQratL9}iG7$BDhp?G68dU;%$*Q2S?m5`-JHUsw7=F>{ZE{)ruRmJiOx8o9KusdVK zxLxH4E3-Mp!HANtXdzJU{OK41Q$n z0|cIIA7#|e(RXRi1~;yZb0cWI&Sx8Yx>n7kq)|z+A$1kP$+be7&3s0`av^$ji zd@_xJjzt@O=v1>t#by2TtY-}!A`I}W_tY9ByS_Mnw|nRD2>3bC_OV_6wcQL*Zw5j$ zS?p@MeIc39fTok>&wcGy)IemMl3WB@eFt2sQ;{dn z5Uc(68Db5O$e%MN9QHhl!;*#7cltSE?PogIKn`^-;sALp=|z zt@d;62iG~T)KU;QcAM1|N%nO2tQQu8rqK7MBfZ0=n8IXONO3({@$=yo0@=wPz5tpc zGgp9FDEjH!U<^X2%tSL3ddDEtVpYnZIE?lQC z^3^veM?jQ0rO@t2K2lQBoPv_=JuixRVqz~|cd6i4TWjl#4QB{45dMQln8SzX)xC!+ zd+By%Y`YxYmr5=ia{R;G@uQ#Pu&c59J_kBe6aXhW!X1U7a+Dlu(d@KFb)0X%K1FXX z08@2;go(b&fZ?A}H9GghF4utAEIQ=kBov@?66{fz9Wtg<_t1M%3~)?Z4Mi+dwVNHIdjTqRs-Eh;bbW=a`KBq7!wlCgsg5Utc34_Zef>f-@gJb&f66=qGYNJ;IkFpWJ` zi!XlOV@#|8ul91U;lC@->>=JMQPwo8P&*vBgf#qz(FE$7XnDs1=!^k%lrvSpCABKO zdWMeOme(kYFf}phn2z3gn3#p581Cx)t>-N+`Lhp86w5H@LT@nm z72w-{zIOUf+PdJs$MGX-o_~D4RG`@Y8Lg3MHZuVQqHRs0s*G3v{_(6Wq7_PH%0?ZS z9$Uf9+{q`ju>p9ouTt{j$ES~hwF-ax*f-b^on0$G-+qNqGb|#`tb0>d>iY(#xoc|P z>P2LLnc@R0i)WrrSk%9Am?_4ttqz41#6AW8n+?CjeJG!uv%s1gI?xn1syo!V?dADt zD(xy~cqchw6S(#A6Sp=;aK5=xI>m|XT-gcsgq3bFb}@I0ZAD~<>Me|tE`O3BwmKOHGJbUi0Yf0VL3477Z zOgEX67As#DaL?iEJ%RUI7YK8V%PJPl({!4T2`$iImcRm7y=3=xMfN?$A)V(cb*?DS zFYR~Jki{P#{nq%)Gx>PiVnXZh1*fF%mo=@AgpXX4ScU6S8_WN2e767u=$PS0rW#5K zwd&2&O=B=${_CL*D?@?%QY(Xmed0bX2}r92T}p$(DTRhxqBsU1>qkEDQd_cXFNo=e z1J*ictMwY6ZCW%phIs8Yp}3V#%`pGo7|IQU`ib4n+&^X%*vwREKh&$BwnFTi8oJ*v z^XAH?%P}<+1zt@cCp?Eia>KgyHSa9z4++(&ySA2Z%&N$Wb{6fRbY(samkq8 zsQWn)^%qd@6h`=(Q%;VYF zME*_-_Te%Lu+iv(yFRvAVITx~d%3#rIcyRcf@Sun@tDi(hx*l}PnyFgb+hooNLB?) z77iDHf32R}r-|67Ka1M7$*(*vMNOvOXEOS`M#*@#imjQ)(&is9q{}M4AO4!bC%gix zYF_dIvS~x;ysgac#&RwoWa@OaZ#@$8G4*$eqil2Ag#>uIAHXBjFxn77ocG{2Izypx ztYUtZ=c2`Txl8ep5YC5a?mtSxE3FgXkZR3;y{{?tEsM#zg%jpXApD-ulol zZ>;g1&M&Twgo182udeWmepctj=OGZ*rmYKjkj-g(mUXrk06-?q!7Le7Zs5{h8r*j6fL3JkrmFAPZf202s zyNg2Pz!Nj~5>M*&yU$W@A85;h{93W*>~jq6MTL@6Jrx)#b*NRPWCo03q1nILv7gUh zD4UqJFfhr=C@r;}Wa3FoY(p!fqrn?_;V!c`nNP7Rp_u!%b&W0UEUWE%o#vt2G1C`> zV9H#OaN|)IS`~)`EA4ynubx}~$C3{Xm4Wq)7of9o%-%#Uj+A|+fr>^b) zkzuE=Od(KB^&p`?YBspT0G85zQITgk#$+?%nsFppNtEEkY@OV^{7(dUeSdzj8I=x~ zMUGg*z)r6SO%%32C;y7)^dI$Ar=oEqqM!xPd22Pd5k<(J_#}36W%IDT3}6e9i#OE2 zi46X*8anUu2PF$8VYXe!R*6Z%a$!Asn{lIQnEQzs=_+1hmFhX4mi|31!T2xk`CkDn zfKxqjakUyf?b7Gydh9pfUg7YA@r>s(sQ=CBrmeM^HQ7M8zRm=j-p;8Bw8Gd*)uOAz45Ryx5m;D&BzHE|^16wJMPXbYqPg{0Ps3FtX-@mjw zvj}nZp8sLm+GfUPq1~_HA=y4Zoq%J!;I+k=_v7~CUD(5X*e%V<<*0aAVBkY&n8Bz? zg)I%^;k$o!fFa%Pjqck&NBfWWVdyc8#BkJe)7)^%M546XHbdF&nj531^T7OY$+zq& zt;S~#b#Fg1#*|q-0?1U6`$`^Qi9UV#~ON??<^00ab&yVMum!boUMjEYg$pN_Kv&?mo4;)0K z<4PnQ2~K}m->0TZ2>~#@GGE~*DzFO2&YlTn>NHlYUO`pekV$$ut?;%#tmnx7?}tAn zsywUZ^FusJJhASfV|M*NA})<;jr?f-Y<;bJ!hEVY6&L4; zjJ2U6DmDVdj?ki3<+Eg1=U)_DzCopcI|N{kbh+ ziKEr*8x&e$`={D+dQD!FljmeanuDyLZu*9Cc^0~EbKC|%R-je8qo?%=U?u_Y!bFQm znioD^A8!R5n?D}d9xK^<42KlMGEc6J_nQ72cz^QXhmDJ%%2(G&tm;UA-hZc855hypW&?xU+s&JgN>Q}5-xSUynw6v^GMmTd;b)}W z@y0*yE+hmki42eY?vX2)HOtD-qE0Gl6gtLcWx^Pup0z}gR$XZXK0jIM?=+n^PMvMU z?5Z}&#^osf^OeV1ubcj5N$sxAB}Eln@kza!Bz5tl=*bHp(g_Yx$!v%=h28;tb% z)%uLOc2=|H8FYOz)Uuj2cEM7le3)YCcD3m4=vz2KaE z)4J03Tayw!(@N~CMk|o=JNko{w#4CYhw#c_9S(3?`8?EkXg7E+mEa|78bQr5@i>%S zXw0Y}2E#N~tx?_ouBMZax%{16I2J$yuT_UfAoLGs7es{Yk_H-z3d8=~-A$~J#`z>X zkApplD`ITs3*-$Xaf=8X2dshebsx6oy*IEnj(-P9wKnOf6kPfh?dcsNH&0Ju3sz#~ z-!4n4tagQS?E;m6z{hW?v+XS zDs!L6$n=uceCJ~_h9U(3<$-o7t_ajCz!JKZ`SL`(d&z~@&sCZ!#tGxcf9ULRGf3`% zqX>0*C+G{ZbSsKOd~JD>(WdQdZoDf?yns-PsotG%*yzhxhW|=&N{TBe?7n;<#GLxg z_JGsRDW^+>`xU5WPJE5ICJPoa;=nu1ppXTFI57*^^Qx6 zGXhfX{~aHGvZtIi=7HbhW1!U9OOiajSO4s~jdzXJlY83=PMo^e3eNzUaX3K;;_*p%Vtw)qdw71f&cOHV z(rP22oTMkMly)SIo@*3rtXKDz42XS$oKy)4!Di@dwgsN~8JP2<2cMOCd#96RL@I16 zSEX*u$9;4D4dq>xs`@er*P^u2l`fg6_ss+mVV6JnIM`x;Wbokc)v1}@o}ealvC&no zf1D~1gx=32Ys^;gQ_ZfCWzp~378UFZ^0%7eOOmpKjlE`$(EJ-e_=JTPi&hj(M6oZ3 zX<(*GWz7CW*hdH`GNq#1>k}wuRBx@KYb{U5pZ+m`3y z2yIRYVa0J`O5!h0z-Hre=MOYcjD}RoVo~Js8^-dfwD?3yAVjCzoQzIMdOWfywEaJ; zDW?jU{KrfeTtM72mL-W7rJy0iHEN$96s?I~oZTf{h>ozJW)JsoZ!hhAx%JQ9oW))i zU@f^KWXn(xXI7`jX_NM3Oiq#s;duNXZ`IdQIC5E#SH&tkyr2IMdm{m6=xTiSO_RDJ zBx94@(nDjJtgnL%`_o3-5pT>@EsX)`Ek_Xb zT8zt;ya@-ezXUQH61U?r(#s0`T?KHGedUnYOotOL1G4-@w(R-o2>@gtwF5m$jb(cd zaNqkKb|><9cmgj7yXOmQU3S3`Lt+Vl6R5eb+1oliECPJ<)9fF(Fx-={KV^JH=Ig5t zBd)|>Fe_?1_(xCA4x_rz7U@cpQ75W;cjkI`CZ-ge-1yU4Pc^AwfKw_ArY{aQEEI7~H}OHax@pQS-I6lVxI< zK4zg=!HLM;V1|pb|A^%O9AnU-<`Owj@F1{oCtOViFQana?ebqh`1F6mJ7qh1-Ok`f zqMgFpR+!OwiK|IXr;!1G(@S4K>dBk@<;>^FT7%$c7$K&iQ?xSJZ-%vUWd#=x-1-q& zs9@9e{o(+3T7=PN%zmoanXupUD@1j#g(Q_k7{53}Sgy7Hfy1$ggyGLVhDi|XP+{)ltxS?kH`-u~QL^!A(%gyg zBC}g%jbb@+*{SVn;iRZgjXYxcVTk-vOUNzksDKD9Lw6!d3AVA z0*EQ+q>>>hjVFW7=I`s}2?z+zj2t_2^Hg(n#Bz0hn(9l*7pB&>pn9dtGwu=Ec!333 z%y6Q3Q6|@0tM2`Q%Z3R7Qv|Tc=zMZC6K!Mp!WiqQw&FSsEgA0L{D$FU=;+qLie@O) zec@}FI>g~bv6gFRL5n`D|L!;MJB@^j`x`J+T{+SCp?3m&hEKr&k7F`ztvR1`cfaE$ zYRxo-|MYspC8b$wvOnjhGdk3%D!$+Ju9DR@)Dxp-ZQ4MxUmR2B_}Ah;V@`?63#MpKscnR5YQ;|1~^ZlS0_wgtf~r8M!>IQ9i8url(UMt%vJ%`@o6vD((Q zmg2RDq36eO$ZU)Y8^W#zQz0_Xqz8*zRLN7`$P6W|87SBg3~0W32k~W%gq)e4JJ)%u ze41vD%-hW%u|8ZVz~h_=evVRoJ1ck@vYsk0JtcBW>W$sZgFmJX{Twc_yJqAO^B$BYyk#D`R5{d;03c$MyK39sLanhML|4wlW*dL!7I4o4XPE)WL?`_5;Xy?0B*>+s+`okWMLXQp9gF@T#K3{GR%pf-W z3+4?sE)Kt*-Rd-XyBR&EAeCQb=jAz)58|^}AY3Y2yzI1`v)abE$9DGgxJ9o#m!-y& zlwdXtWA`PbtXJ6UYYgD%yp_u2;be0uvIAx9T*B-J%3m4c|FQp= z9#@%Ui#(m%kzTCC2iO0!i5+sAur@pkR zNxA~L9r)LPkxVt~H%meGAufY_EeRCe39DPEZ%ULO=@j=HcR zNXT~5Ilr%t=q0>9W_YWRR{Hi`>e#0^a7%TC_PqpNi>+NGCWLS{<6@LuLG-q9kla9W zlSjhmy}s6bt`G#dfd9;}pNxw*4|pg|IE0Ingk`5CGh>=CIyyeA#l&0Od05?zHcss8 zIO|ZfDU81j@>}mlL+i5t;nK1^pH|l23Wb%}1RmIZW|x89U{0j+ zgCP0-p*VQqv40|Ts~DyJk&{KF>ot9;nT~Qjy@SCbGt+RK$>)k8>3fNiie79P4}_)6 zv_vHV{y)t08=0!G$RKmQUeo}K$UJc^;QE@I^zDI*dL!kqf>%iy5$%bE zB#<+L6xW&x{C9WDt?mzp_q#PW|qZPBk7f0N`fD%0yLVLB0{ zE-kv(e`UMW6lzD3p3g{f9~v~>20BjV-i1(!)G9y}Os2=$k%`4_Yo_a$*03Ydl-VX% zsoQ@eVSkqw??u_9$`t?rtzWBt1Yj8g!ir4jbAiMq1M~ZvZ_=fkB0Z0Gquc8bm+L0$ zW>LGE#ik}M50LE_ug;>f&&<274@NqWB3gF0m4W0PWV!5bowR(L#j|s>pz|%TQYY5j zx5a$~r#h*_KtWh9u`*zpfCeC=QPA{7IsZ8T_MAoF3)=9FeLC67@>>U}mnlf5)@h%y z^=S{%EB~FiS%VWl>jmJui2^^~u>UQ|Pbt0m=@+Gq+w*}QlX;r~63;W%q(yQ0`7y(L zYp3C4g@C|kZp~P?yczuqmNsA|~FE#ECL6B-VDeyG-alyz1#QeWP>cr3?~o+Om5}uU!BN3)-Rx64zuex>k}+WkAwYZ+ z`#^#iQ5*iPXf9QcG3?$LBE%NqCkw=G?kQ{6(9x@Ubcz?2;28GWZJ@VsS>{-2-4(*J z!%5EvzS4eDX5=6{cl}>GWC<;7!})WUhXK7CK&zVFfBNs=@58FIO6bL)7rXJO9xqet ztVKcd%`U0G!m~a;z8nal12x0GAS1e4-H~BvdSDc8*de&*sWhgb3$bjh_P>3&Jlf9G z!-XBl?Tp#mD>*nJ`U!0yjO5|8F`*9B$%nqJh7765j(y_23B5!ckhJ;t;d?ia6uIVa zfj% z<;Hmd(6F_tRDf%>R9;w1v*}Dau=x8&!H{ddP9(iJ{Ne9_k=S1O3BYJEsI*bU@C3Y& zdgL?HRavTGYemnCuEhg#4x$@a9U+;T{YgTbY3}I9MxB|qglLDC@&**2X(iT~jX9~v z3Mpt2yx+CTS=csLPjY|99d|X;74wXuCDo{OwfVOm$bMobLK8HufP$hp%6o@ak&I8 z0qT_O$V1`^l&VA@)$sZZ^C|ZsWWY+;G0i=eX&W~sEB0|t!5`k5{#6jDnepE%jL@P_}qG?ORyw>8b1D_shbg#=k zli{rReRy@~6l8D6@QEjTBSb}v6Hg%hXUg~&&A`>Y9|gb0xU)KbsG@%Ow07UlBZ@=A z?#ry5^ykfk|6IF=p|Huz!%-v=hcPfQ26Q)N@*k^Kr`&b2?2_VyI650v_epVuUXewF zrnFnW*ui@YHcFRaTcWm_J@;Zqpv|{%bgrfK=PRWWkpKKo7yb3NV$QdffFU)Q^owC) zEdUsoJnmb)CjZUX5%R{TR0iId-Gy6ZFZ)mn4mc&C6{Fz~RNLs4pQF1ICH zWw_G8-ZWTUPhpf_-Iq9rrr`1;=;(Y03Mx9SrgWqy1sh=jtmb22rAC!ExVT^CFmTX&-E5>!cWn7|Sgg9;~kXbHQnUU0Z$!_6t zd)&;Us6Y%h>b2Zb$Fe1QC9z0J_ju9pfVsysJdDu={mxwx%Xb{*q_IUf!Fc*gvXy&P zFk-L@T`VgvwbM&tUAcOww^X^{+9^K9aWX`Dh_=J$U05?<4Ucm%ew=-vCR5dr{t?<} z(grXFFR{`SW76hTB(R|bQNJ|;{xQerpUE^&Iq?NZvE9(fS=7XB+``m$t2LC$Lza78`e>XzJ_}bgx z4D4x%2*-5DX@Y=kS$TL~A2*56Re7LOcC4#KX2Yv(49N zob9iGIeZkoa-#kDP92n^oS1Mv&QtS$FM!G|c2%A5AEhxuZ zw)tcNc?qwjt$h=y0@}5*15=j0tkg+BvF^%6tAWvi92{U7h0mbVj?^MX@0Eo_g%9)d z&=%5Ijn>z4l@66-wn3t505a=K4@1mWgbFfmf^Z7?@zLM+vhTB)5a9Dp3A2K2qXY3c z!Ft;>Ajr>g^sgqCfjz%>i012z;=XUP3b#MPP**pHdwYL&m*Ge4VHdRxKOSy0^=n(b z*J24VrD8g496sP^wzNdv|LoN02pLP+t@i!kNdNWjRW~$YK%?10j->eOH8aa zbEIOar&>y2V|C7$U#kmNpIT_V@jG$Opn5K)K2OGNlxC4_LfHM;!@4DHLw&tpZ2y=+ zgI+YFWY9xAOIJ6@tezflzO%n_ckuf%)M6#M(15`6IP68GL{O!X_JvLdds;mRN!Q~q0+^f7y;ZDmO3RKVeqD7(tk>4l`cmJ6XRn7 z+nlA1fI5R)Ha3F47&>=X|I$+t_8~bF&*OM=9a84uhMQ=_eaOa``g;U*c}U#eet+}z z)NdQ99wwm%Ql6|*7Cu_wFGFoC)rkN(t@la_h;cIy{sO4da$)bdT)mWcXSf)M^fG9p z4_-&Q9k$wV++s*m*JU@yrHAkk3TKQty*TFX>V%rSfQzBMkf+U;nB-KPQ z>haV)3~sgv&`OBQsy~A6Z?uSC(c~l+e1OhWH@_>-Q|3(y2aM}CF~QSwnIz2~J(il$ zhQTu;iswPhW7&{`nva*QxU>=#S(Zu?yQ-nOD9g5QU`Fa*%S-enp72@vUi_;a(J%8U+q zo-Q0yi{y=WIn-+MiJc+OmmRTEI_MX)5uDUL^1{HA~=&7m%9IZF`c?|&u<6O zp3(8)vfg1UK-sErF97o_^v~o>Z~HBO(Mcsg5iTj=EKq&iiIZfL`|7};0pVdK^fsk!3n_{Y%w05mX zbM*B&&OTeklIULj)E8p~X<~Vw8H46*qWbJH&Ein)gqjiJ5FkL8Ra7=YQ=2e@UUc81 zUb?WWa~U{g6GgF#ceVO#Y#%~pOJ6dR-P2|8;( z<)j^O*(3nA881!aWa(F{6Mp@K6iZ)u_wefDd|PZk|87_J=fS2QAK|`}Itd}tZ>cY5 zHHBSw&3gU|azF03@AgskV9&%W&^P3TJi`!%ZqI)l z8?of--%WZcN|Ho)5FFQ7U&*apBue(gP*^CruQiK6nU{B#pDYr68qpyG_LW>z>kvN; zA@+OzMi(HXh-LKYi6w7f5d5>wo?2xBa9i6L>Q$LpL_e@M?C#| ziaDMj@8jFurWz;X7AgTqQMP(3EI3<7oatrt^1N^BYwY12#&@jpRJD*5GRt(G1T|0; z7Mlh)g|12kCEX2&PMlV;%lV7{Gm$>4w$@KlYiG?+C_IVh1149><#DiMZkb z97Lx+u#$h4U!0hu1X$3-6Vgs30d$*SR=s(`mgw?m&_C9KTfykFr_;i(-&$?o>wy)( zNwf;(nb_zR?9Fbc-uv~5F9)%VNl7l*%IxevH%ehyCQ>e*xrG-aYJ-0{CL@xVn8h?$ zu;Y5io4M6}1TLAzGW+H(s!f+&xwDaH}8FOIMO&Y*2txPu-pMr^0l z5q0?aUp_UJ$%CEW2Hjp4NXrGgonP!URy|{jA~SB>3JYj-R*L!EW3|Z73vXRGlVng- z%)&DW@bljs68KgCNE#&o>(7Zo8K~YpRb#gxQ|auJeK9e2y136r<;j?QbTc!h7xI#st(UJINW`1*GyRsWFHy;55D?D!mF`I5d4brT4uDhlkw-|C7^&8}Ks= zM#Hx+?b_|zy}@aiLMRW&9eI5e5l#7>k^_de2fLe4TqN6L;0@i(2U1MP2I&t5uGxHrNiE_+DiLUMz_gz#5O;I8I zF@T-KiUu|XA^JV(cRue~F5K+vKDwK7qN^SK0)A=f7FRTDoS{HcIA;{zr54@c5(v_D zf{RW>(Q*hCa|-K;Zr#83hvmfQrgJjT({~$EJf|lb5P7{2Uhu|dYfry3C<#s5B|;DQ zo9j~58lUTOAt#XL+F;k{-Mi@s8NSt@VEB?I;EWW}00Xrs6Gh7406>prbwprKMYlAu zjaFC6_r23=zsWHcY49mQU&x*v+`?06m(<>D??C3a#&5bn6d&hyiGNk2F3O0m5l@e1+%izpkoixh~@*seDZD@>Yj@CJF7g+`6Qo0Tk_O`Z*uP4?mGH| z=H9LoZGPALs|Tb2zfea<>Yw>23-GE;v1?Kx*6?rJj1U#!ujp4d=Kroq$@oOc&F${^ zBF;V4TxC!el?iZW%_}p~@MZQh)u~8e$}rIpP~`;|?*)}-SkUjxzt__HOAoRD@34FU z^(n{Ae*f`D5EEdbK-`sr1bzM!wp9Fp?QCj@9s>2~LtdDRl95lW7++0hczi7sYwgKt zk;)}kr*za4^`zP21OR9)>fBUhX~n)QSK##Vr}EESGrFIj-iGYlJUJ#V9F-YgG_QCT zqoCZkD|@-EL}{m%&)DX&^LKY>Zhw{muCPs`!~`AHg?4AJ*#nKJ!5h`VCph)RbW{$& zS>!3DFk|=SnV_wx!w#XZC3|dB-XP8NNkL}@biYj>vz=q7J=}T+NDQeQ%epHW?x z`>oE8=TF<3+p!UdK3!$Zq6N5?qFh*t_0(odlR5&2Mw`MLXkN^}U)+nx?jNL(_-L+L zYK_fsrw>Uf)c4jezliy$E8@32V8F@nrZosKQo9O{Qr@>2fl z@8MZ>!~%|O0qP$Z2<7o^eFCDktSYR=i50gwn)6`n+bNx_g`Sw>FD><(M)xnwwnGvS zYTf>(ZuV<#BX-lPf3Z2w2?_a-St2Fo=u)ZNVpWm5)%GYos41!UtaspYb*efU(NASK zH0KCZ$Sa`}#Ae@%;3Y;qRi8fBk^31YI%)UA-6|U`A?`0m0g`Uq&OvNue{$DJk{Z}H zHXG0)>KV!7)DjR6{_9KLE6K%;)Ci<06p!=Ed_Fb{b-b@XnNh|cB_LaIOMX8d3`ljMn;qYVF*pfhkO97 ze!=4hgJ**zL0z{Q(S|Rrt#f@^mt+ZnD?k+U6^m{-*-|>W_7uP|^Vg?eYwe$?0Sc;8 zaZ0L(OYs7EGR;0W1kTyzS@42L^!3U&L%#MkB6Dk5D^Z#obq;AOtO+4i#%`!KDf5%(tNXJl%^>Uy8apt@9qPb`bdM9C58gOGZnAWV+ZVcxM7NnW$@Te?X+$`g;84N`Luwr8pE0XCDw^ zs$u-b+cmt_h&VAZs#4^43u;_^+_DX#HI_5#^lRUX*P)clWQkjv>vv<;(Oz0&)z8|X zS#I+=9TFCHkF%U~bh&UHv7YxN?^aNTM}{D}>QSLlUJ<|w<9E59gEuw!9hCLG-UPYx z?LxNuAwrWDz^W=_|9odF)>LoUH$M8yqss~37*YM$XNJgkGQz&L?e1|yUzMC5s%xB| z?l6Y7ek)DOnwPA4D}S8K9B_4Y&?Mhx^@{61T0VvXd`WB8K6*T_Ey!Cu7Q8h=RK6YI ziYO;7|Br+AK2a$$NN`*&T;;<}z0*!j>pp6J@P{yL$f!Rd`B=%iXSAicwL`kqn5}8B z*EI&NCCEKucEL;TTn!gH1`F zV6yMqKF&G%)()ObAS&pJd@Y|RS3;3fdbBG`WHvNE1)qsu6X_RR=x68EIhKrl^~Zve zUqaa{H~T5ucLw4R?tia_M;)_1k=!+^M=%PPk3J;96Wwo40TCOppuOcT6#ij}yn?;} zLeJi_Fly9t2Pv41a+M^h0@<#}|Ed=u!J6*hQguM95gTHr{Zn004*>@JtD|x4Yv91& z(MW)`l|^Z|qe`d5d}PcJf+xJjxbJtHZHgc}hkwVQ7;Q-A4ruDK>QxV8_T(>orL+f4 z+`G7)AeP%t0>S;f#*3Rn_NvKb;f%J{7a)KF!n`B8S=Zri+SaiA`C*3lqKG!ex$z!c zNs)dp0^$?o<~#kE@Nh};mPr15bI`OL*ZcEYF3n;@cSerk!^qgBT{^93F|d2K8Pg)v zo9)y&Jp5jk`ks=Y_8nXcVWp%wOEBU=)pVgsAMAcyw(`dsT6uOD%3p&jX84ki=BEQr zdl&GDG|=dHz?5$=)|&w?T&afXf=sC*9=#Ua_VE{%X*b~8 zp#Xl0Z}tEPZUTX-Ntn8_&@81KNqk>~$X!6U+8b5h%=?hB+{ZwT^HR&)jZX53#Mb7Z z641E3-+c?8i;0qP0z-aSp!1g@pMuC1Au-~;eATr zXG>nE(E(;EI&M_qnL4~$*+a^4P>A6|>oaXvK`JcV?l=xg4~!e^_Q%UEmxvUlX6HQ! z-W{|Md>~*x{X7qLh$Y3#z~oL*Rv|M@-thwC?i$5bR{&gpoTSe`!%Ui|gLE?eL{QFR zk=XV#XT5w@9sN7g!`wc>ECao++a;^z0}#_?$7uV2+*?co=X7aJhIRG0o8b z2*SKyB9Cbv6Gavs4Zo_Tm`q6s33-zd7jZ45(7{J8101p~Z9YebCCdSqm1V&1u0Nt%h=_Uaw9F$yvQuTe*4o~D``tzN*9N+( zGZpt?8A#-IRj^Z=2PKTG)Zhnqa^>#leh1>2v~8a%vZ*zv6A{-$A01m-Cx-U9zYg3V zk|Fs;VY_a9Ap{s%B|@-MAo96ybsydVu-`@T{AP9IpUKYR!pxy=0%HM*$iiZP#R~<| zDZ^i0sa#oKX?>ATkFchIt&?~X`QXnEhpQt1`TgpWUv&QKrv3dv=4K^g zrh8(k19!RNEPr)#DNduvW-4Ra&zO7hg{Jm!#q<_;`^|}gu-NLaF{*6aibi|F`@L!} z4*E55qjPK>*ZYHPrXxtH@jN-<&nb00Wq+1$_LhxvT{_P9?``>5*Kus8Q{4Y#{x~wH zy6{P#NBpR;utI=}rN&yJHQADcsJem>tro`c{3U?keLlwE#5-A%3@3k*ykN_58qhYj zgx-*MFPx+7#naqE|C>x11PPvry?D<{L(}M74&6us&$9FOCz-8c#xN{tOZUkamZ0I@&yX&@ILsCBUyaPa~&V<0a3*#Dvfb$jyrc$b z(B2(HkOEuH=L63UH*n>hkZ&Cew@tSvoz4%x*vE$)1q?`%4nF8%St`2~9^Z;MymSA4 zZqY@`WAs*%s*XN)q2EQ;hLD#I)0^Cayk;IkWc5ALyD8%1%PlRqlHf@dbnsHwYS+ACsPAM6=8!OWMK5#4Wp{25>FgfEaFuh+;o-Fh^ z7Z@@kb5ol|N13Qdugn?#`?1eGg5i8JWvk9!M?Xx%F11gZ!-iB1T_Y{}agd*CiSF5} zI5OAW$t5Qnv(|+I&N9NWT}x3A`9(l^d-m5<^LK>ghVEh5I*NM{yQ^Mj^_+`CA3z$Z zds2ftZEZzX4y<|HSk)TK2=T?aN>JM{;Pxf#Sqa{NtfSQSGpt=IvZ`^RAWzjXV1aOJ zJHx?SZE+%h4kXkpElS*%kFE}S^hZc8Tb(evy|ck5HhIzW{TrJfWIFzxda=CmW*Hrk z)FN_sltJkF>^#R2bl$B?L5D;A_U&32*Yv7t=SXq|=!XVW&K(d6wR50zmKFT1rOjYW z;^0Q&>fc`U7Mr}3v}q}r%znaIC2r`5QlP>ky9FY9VSBU>7nn1~5t#1Bxt1R2&Xeea z%1lH`OC-1$LW+13nZg==xM|R5kCqM;+YEtBc)$TyA$snjtEb#3R4EdKZ-z z7^x6}SO?cF-*ZMI-9~l;5g!e8GOYuXLb}F?)-agA`zI^CmcKcVH~@D;0i_g1b-vkmKMrD_j&j`PbQEwPsq;|P2rc0bv*<6#_P_=TDGiMfzk}%fOq?o72km0t+^f30?WveG9 zFOjRNf)O70S@y;Xqbe;-K)zP$h$*41<9 z!sE&G7TBSo`}yXc*hM;qda~wSBh9B-LIP^SgHlcq-T4&sFr)GrcKn~Q>W>G~yk=tu zELeJQcn5-!U?(XoCtza2lcd2?>UBo-6A>*p8HU}r*J-zdCnpUVV?Oseg-$-&@iKL# zMsFnCgL4w&MW=}G7colxm8*NA++;Al@w21j4P^B1(=eMe8#|`rJx=E*o$e${yq$d>BH+0r@qQLc1SH zVQcnuj!)X_S}+dqn?;gaQKjs^zN~&G0=_1)w5r^Ia0^`%*#J%P?@UsV3TIEMT1qR-aB|4|K2%bP5w{nn_@Y-8gwC*`K7{{)$bD`H@swVnX z@Ay6f1lg)+bhL%x3l-xLu8XG2^>$xW54sBgq35(XWZ?0(;mlqRfJcwtjE<8snsCFS zy6y_&(hMW4YUEktB3yY1Qi#J&*`Px!)(fUkM#AiX=M#cFl>Jjjyv`^cUYJSv4Oi@B zDN4=iE=VeQ;jw>P+J>x?&RwG@BB2M6Q7?h3cXhtlfb_^oN*&>ZdnN?jgMu<=m<2Y6 zefyM%i4=fc7+y4`k&h$}U1ckim)%tgPT9yV>RIW)NSe!rcR(HB8__{VL9O818gV;U27Ss@57}I^% zv7m<){Sxff9EZI=&kNejwnQ4-16AN!?9vKQ3rH>oiwZ@uj~s$BWGLVP1EH7N8_h;w zS_dSE8`MYd&(eR9i{~J@`>nlw&QZ(-YutJ{C8C*3WvMzRUfx0x&sI4pv9yTv4Wv&5 z>B#{+I6%TwYhk3+5nnBBQFkZGa({*gXAk^Vd-22#rbrf;2VKWT-h6s-dCoREiB>Uu zo>^uENPsDC^fC}oVw$fs6-v}xo%t2&CJjiuWb-qySm)bgO}Wmcefitt^FcQGYa0UY z{$i=sH2B7FVJi4GE13NObPQ}~@`M=>^LnQXo9v!|&LB!Mt(>=sXFKu!bmx8_?X`sZ zQi5LedSt-*-1c2Sw*R)sYWl1zhoFLD6%mrgIc0^l&-SjGGs`cu&DLvVYp*Rzg>EN7 z2M8x&9Oy$3l3Ce{uk&|{D3!nWJ@sHJTq%R|6k75wB|IJ>#`eWjpoq(=o`HD5kGg-x zH`s9W0g^dc6926~DYu3y|0nXLpK*sfZV7OAxY&Kf{^Hd0Y$A<;U#o?8O)I=NpSK*{ z_%2MV*~T3{z(3$UWa zKc1#D1}!p~j!=@1U2}s!I21hP@Y%BMlxBBD+lJC8f0L(dy)HmKInW-}HNV?R3?Nd8 zq!f%`v*R7!C`5&-64khl^a{!b1z>5CK9eQmR@84 z$Uj$R82@g5RIPMe5|3`S4x}1iwJ(OVuQhz~>@s;yZ)4Rc#u9lZ><(Tg~A*V>H(t^S|IN$$#U}AG=o7 z{n9g24eoL2N4xwSq+J}%l4)*)3rN}{s#uu^u40ogWoU>NE$x)9?(Df=ElG$-oP7ek zTY-~^M43_!kdKh?!z)sed|cW!r51KaQsl|Y<1WCFRjIY|wK2JHG=x+0>*xy0#}woTn!u7L*z}2Djq}WdZ#9 z1vf(O@+VPk2Lz@A|S;wTfK3T1G6W| zWzT&7*22(9P$J-CgL5s6I_6hOhO3N4gMypN?||dJ!}Yby40XqbcjqC7gn2SKW$M<6 ztGJ!Ehp?W(Bm5m@?VH}F<$#OhiB{ZOV$%rKf|$UdK+nsop?;o_?fI5Oq3J{zw)sBF zmW+oNt^ARq4PP>eT<@Rp{6n;;9rILz+ zEJ~B-CY=V~Y~8K~-UH5WIj?%&0eJ&J;wD8v!fOF3_dlB}o<`GEym#&d*K zP+myLC`J@5ER!)i@{PPL-j($xBUu-!l~~KBs!gomg*~A3e$xw~r|%lIcCrSS$3r$k z%_P1m<3DLDktkccpg>UNwzDHixud(vx_yA}3RCM6lyOX24AFkIrEDe@QQvQV()50l z_ZX9eXDst<>}C%)tLeO+k%l|~!;0*Tv?gKcb`8zn7WPlCCpaq7qRl&7n>$YT&VQb4 z+1L!DkGk3ns;idUPOxl)fhIF!+6!WYP-+4Ga$N4xzM(X7@n|r<8sEr8FXV*FMJ z`VcL-rX1tb=7!|{zcEp*!Dr1oiMpa;g0~W%z_dVJbqy0&i;<@f^XFp1b^bdcul8j5 zC4aNxugDz1S$G+E?{1)c+0Kd&OUVmN+>&#xpGPgln0`nCy_gN|{oCs4=s9CVMj`^C ztqE1MZ~o&?t~KB3{3s>^PQ#0|_F6hB%OSR{%7D6WW^dLDdm z{$wq{zs=u!fo)(d`{jLww&11>)b-L?_3iEqoBo&4oM-FJ&lTACrG$A3uM;jgXmq>) z`P{rl>~|E=6>*n0R}-5)+p7F)>EBs^=i8diay^cB1m$gY_zHbhIWD}k({y#6ems;> zO)SehU9dt-@*J7_&w5?E$^^H4$JGVYm%6vNN>UG|`1{wdEKK>odV@s2%IfG81#nw& zD@g3umF-mzI_Ck{ry=j(zZ&T3;)SWc=t5E#y89ETx)U7ip~6~9>>%Oq%_9c+zh!;y zC|h7Gpi$t>IrW`)hG>(iHHl&?6LH8WF}IdD_Ff$Q1DxLjBqXuqx9`r=w^L&g@ZOJ3 z&$}Eoa~rbM{bx0$?<9-Fu3vE$146i({hRVAbm4x7KCksUgD^QJ6+4Xk`*qQ-!9EL$ z2GtA8xBKwYt5FOqX-|e_eCj=hY4290vASiNW`w2US0t7A%)-8)x+S(E4L-S9Sc|-N zeT#|qm3>TY$6Q&pGy+i&(NTF#~IqjPte`lcjV zTUi`5bmp)c)_U-d8LCx)VGF}n)dBuN1AKfhW}$Vh03R{*IYbShCH@5!cWs~_ApOie z>b#3XYD?m!x3{}YtF7CZb)C`7WqYh_RBCpE6;!iobAvZLN@gwn@B<_6J^kB30+~v8 z52wi{S;uCIO#wr6hUNyhS-zAhR6;IVR3%GhN${mbB>5&YSx3dCyhZN>XMbvrX*==? z%6bj9*zX`!VLu&R8;Lceyk<_Mz%>jR`Yrt}yzgO3TWiL&9${t|7aOj@Gh0^5>m11J zhLOJb2hE2{2^HYTP|K7G6>NTu&FMPgHn;=3JCn56Mspc1I#p95d>nA^keZV#F~+LD z=1!kVLWF`?=s$s)uY>GFEL$9!uWzydK_Z8=cOsuWsijng(LJMszWde2a)I4n2)u~# zN1;RmOX_3oaQ`*95H)aE=Zal$jl%w#!(as=YadC< zNNLF?gbX4&YL5)1an}}`mt#zu5KjDP#kfc=bq%zLV!^4K#q+2b7r!NJV~ZJYc}f6r zMo5tF=w~@t`fg^qbl#2<;>OYod&hI}!51sy%P!2OMS}ZE+Ipe(NjXIhSl*VN0CuOT8O;p{V1UKYlhcs^LNA zJt@xGM)~#xxk};QXR*q%1$LYkaVyfNUsQwKUG{dP$~9**#K**|pKb9VEi~b{|GJ zx>5lmXvMPBzc6;JIjBz(q_>nSH}I0eOFIP;ZKq45C(_B6*?r+{JvCnln(L`Hsfuor z`;7+_+K>~;X>Oh9=GorfF=yyd*?^T68yP8f4KqWKMb6bUOdm?T+){&+5c`z3YT>S3 z^i4~r{!WRA(Z3l{(0yWR9qNrc@-E6oeR~E~{uMCIBV{x4;ulMo6gu0}n~k@4q`mx* zZ(}+NNS=^@VnNq#h&_DTmr|$l0>s^sW`i=H6dh$m!l*~0j8%u2UMviVV>LO55$`D{ zMfwq8j*jq??+~Enk3Xx27KDe0toL={0akiOOm0JM2cJQvX&KE;N*`7xaN0O_*x0F%cpLmwHIV7LAi`>QUED6&n_N7UzpEBfdbxx> zhi(*3)o9|gZ2)a(?}#S#SI{3h;BqiT(4)_CV#{BSbZKBLZe9O%kzSucn7*wu) zGU|M`IeKp09u#=tKoBd$p?g{9@XXE$!Lp1du<@)fyRquL<~fI z^1im3WHboUXF^+np9mED<1&ZE?j=P>Ayt!GG=cqZyH?uAr{edNMxfacR>3Hi$9&I^ zdIw69-US@2uKbw@m>#$0`+D;y?-~r?NmwLif>FlG+g6k-{0Mbvc&bp`c8gupXOpQ- z4LToYSTukWec5xy$2c+5@Ul-ZU5du%XAftc#F6W|FZ|0oxyTyVxTyN*;ocOF0F;*f z_*-gNjD#SxHV$dc=wMl&W@mWq98Ha^{&s8D$$0A6;A2obR~i5ux)Gp zaL1fJ9xRSdn@*8fIYy_Wt(h7;wso_PsB#V;Xa;{dpKx>+c9d(akDc4&#+xjQXYHvx zx?|YAp8V=*7LMwp@6qb$#E`|T<{Nx!`P}f9OK#x553NiIwONwvVvF%>+kB&&qsca} zl8*Y%|Nee)Cq!TWlQ1P&Z^8f=Qh-LT*GpyYiTi{54K9DL+)<3tW|hmlT|L(?-{_HQ zUEtPcD*0KDHnxz)MeOA^XM`I6??;gwQT`R<*RBqJ3;n18&OU=W zcA~;DhNZdk;eM3q^T4Rfa}?XX%C2TR=0+T&5-+JLn47cnL)p65=EK-WC4y8slcL~z zd?Bx^1-yo#Xrq&@>S}sN@T%_f~OpmMKe|H^IojQ?&%!$YRn z;%s3ufmE7J+0#aXx`2#4f#P*&OnCTc-*=P*)z_58(XSldwu2pEm4DhP-1# z{d?+y9!iowg%#lNarixL5n67~#Pg`?ixDjyaf6>Aj9s~qxG5A#nAK;43(JID0MGAO zJY@Ro1*IdUH|Hj?S~a>y8j_M+$K1%ls;CK892rT0jWx4}HazbsY%}`js+KkrLKbFA zDT&Y7=s4-9eRbp|=};l;E%DC~M>fG^EuQjQNo_jg-qLQ-p3R?^Snz=hg8X8Xs_RKy$N+-t$r?8%Sro10;gjqFf_N^{^Ayq_3Sve~)3a18 zJN?eB(F?n$(g20i*NM86u2C=OVmaW@!l*~UA%ukiyx_1M-kl!)^W$jH^l{E7#bT8P zJwOPf`xvbyv6(|=1*Z@^3LR?Dd-lbpP5f!eb#KYh*RSU%C(}~Q;VbLib+~!+CNJ!M zqj~19ns_o5Ea8++112K*ya&?<5_1Idmv8^QeR^~vU>amMwHI-)V|_j0Pearveq_QN zp|x4%BW>B3Q!NKoHUN;IZsYAohM0zxp+$f`f=Lv#>ersvLk4gFjOLSenZN$bCvB4! z9R$It@(*NUEN*@ucX!^%-=35#U(6bwm2a6|t+3s!#0OoiG4`DI`+hcAiYq0~SEF-h zMo#$o`$^sTnS|aH+C9Y_bze4aQj-a0jkC%5DECRG(e^ltFILQe>4A&`39zz#szAct zMK17g+o~aZ&;X`ds5O*~&A6}!0G0-x1mYuO5E2el?%L_j*CJE1O%$qOC(Dm70r+cD z61ckSyi*hJ=VomTczZEKbknLi(=$R1>7{S)paTCXq41n{OyXsc^yWQ)kj~JT5DLKb zY-<7ofUchV4S2(qVvIvq764anm^N?#z8R~t9c{Fo5&1qKwzOl*k1(eIZ+1A8XL==a zCJ~j*i=T{USDN=dYMygB8pz1L*+kGCOXG#96sTen(Hw5{n6nrOx3K&hi{3aVuiTEvM-rHIL z07T4@qQ1S2X||IEq=1$K@GCSy$47?l3o4KZM?PeQEt`yiY~bnoW#`cz;b>{M8K*tq zvwQ^j+l9GXRK4^ww&UhuGPPH)0MUD+@r&O9kWy>?-7eSH0@ z^Wy4Fh<(h!2xSQ5CE&d^@yYZzuV%IZ+SQe8y6tx!*Zf4(RHAO>-F&3FB0Y^AtN$eHm ziQdi}&+81jux)sUZxk0Nd^j&du9Z zW2Zd%VD)6Dt@`Cy$uBTE@|emvpPJ=9J5Qv|MQ>)Cbqe2dESFU`yR1zv2)ztgkAUw_+}5(+xh``8g(-s!v(|LCK967mB{(R zd_2~RZD;%e2uK`0D&9`9RAEZc&|nb95os~`in)|$>AY@s$=X2qU;XReg0%nJ7(M7sHb;bgZd$+x zoqf%dYV&Eo*_PH^&UTrv%JI6)9;k8%oQ$#5oe+0vEGaShac=u3Pfj}4uqn&!$L3Ce ze_->%-Y+jk#)5;kg~4lD4YphvsRP`JSJTpXz-4de#fC+LZHw1z++>R4*x;*52a}lE zA`jO_NvWWDuca(;8>^|(6YQOQ_c*GC_RfyQ_2(QZ=ZknTOGce9D$O0=9N$jEO66W# zZ`QxVTdEN5tg11^A$0}j@&oT3m@`H%2WHL1m1!scjc&yKx2d}+EZ=WX|2)pR`5QXT z#x5p2L`vSV(F7kWx{%d=6!~z;`SHbh07O`aj7=u+gKN9L&oA0iA~TZbV#So{Zg!za zV~WI6;pD9A$e~@hBR$7KZStGpLImxw9*kE~f2rg`xmiWyk65fWX$V0Q%RD?F z_|~Xmajj(dyn-A;pIENHa4&vyBs`KFu3WisEf=HX_((GyHX%X5^VX#&f!>5tk|sbb zSCi%T?^!T@^!(8v;YXUIzOYnbmpR6#y46O`RcSO?FH(H}LDO$U;KTN#mpq2yG8k2@ zAHMS8Kj!ZNte?R0%`hh~LnJ<9PtYBKhyOmlSJc*~p9;Pizuh{D&bk(Ch;40qm&fwB zJ;?p$-ty&A@Y!VEge-iq_d8Tk87IMAn;LG;3(_GIme~grWq1GT&Hpb2(;OXAVfSp5>(Mq*(mO`1`j* zH#n)~7f>6QBRuQZI8CcP**wOqP!CuQ9OLREv>KJU?r~d(7$3^1;oEOl=5Xlipy9hY z;)v7jZ=>cZpi-&W-h&A@M(;HJ8J(0Fn=RDe;M?C%Ir_3j=WAZS2Ku6Nyp)1GYYoS; z#NCCnvcMy`G7@9={1k!B{Rdl!fd|^l$CdTqVpx>9JANPA9?v7X$lX&Iz@Go7AV=>~ zu&;?|-Q+t7<}HvYr@g^3E$Iz4_#rsNHoIKw&~({e(wMr6G2-~;et5UE|FoCHeT$ry zeYS}7AG-g3N4VpUmE$(|XzxG4d@Kfi$);)=dIVU{j`jWTx>6)*q4>|=x9}mu2=K^5 zSq=&Om_U=a9p$1J73~xw%mk5Y#}XG8r=h7CeBFcNONJrM<<-|jC<(+pmg?$i)v?a2 z!)S);vC}n1C1d_n)chG5bBG|jG-R`Q8G>|OSW0&%;kr90 zrDxc`Zmw>eyx@%#YW%RvSILj49}A1fF}Qz(_$#XN`7Hun|lr>B%OA>vrUwIJ~u49(4jz|G-u(D}|6x^wAZ z+}SNQ_^&tZgntR)(1nmJm6}_sIaU1G*dPU7@194OXI)35#e3PIv;acicC4jDleJO( z2)D(OWQUqS-&zqO*ZzkgOl+*<@o^9Foo7W3*Vj4AuLJQfmcSrm$Qjf~iiR6e7Wb7S#q*8(4ipHB{{_@JP zptW%HizZu>+bmSal|bf9IOn57UQqKI<_r6{LuyI2xC-fth%6ruY9VMzK&7wrxP-XX zhJ3MvmkQQ=g{V1cXQKs=I5M~}F!a|_fL5If5N}-kV&>EVOz`X`ydaI)NIA5g6^4{D zZ}w{Gn1$z3x$A`)AFuR&ZfNV6duQsDTFxZQDsQVS8fKsj<6jfutH?sKDDsl7ro_~S z2<}^eVX!itEC&fLQTuQwzmC>_JN(oW;uLy=+I#~0m3gJ8YxB;7 zrll;At{2mI8PVzNJf{S>dwLHKv@5LRPrSYmm6H1+zWVG{`PYGePRz7+4ZDipoou31 zmj%P_Tl$>7xZT+(e&5nYC|xqs3_~9c>{gsrOww5rTYWRa2hLdW;Rq`ViSS>3^3;}- z|58>DOFd)dCG9DCLqHSpK@k~I+h5Pv{ypR;d=KIaOpV|_g=ZYf`fk*c_+dfy4kx<$RDUQ5 zt%>Cum6CWpicG~3usBs-(4iw^$x=|dz^2n=Sry|JipV(od{`F8zq89OnPj%h4o^4X{eDQLcOFsYbg6U7TC=jGV& zCpLG?2Z-=(?SAFzvV@VZ=P1;Yl~v7H$l0|ho6uFbU9f{4y@e?47lNe*6OkGkB_IKW^P_K z@UVX%9_5>;zemCop}4n@fM9foSq?GY=N)jH`4^uncfGS(h^wTVbLxG21>^he0GpuD zD82WmrE$GSZ7d^bj$h9@Q1}Z8?9iF;PC}I z>hrK0lK>^&@3elVJI6K=L>4ZrY@>t_-~6;olk~C#J3(~r%GhgP%Trh@(hBKKcm@+G zHdco5>Zp9@1pRsE5Iw{wM4`y;_}$+o{RM`3a=I(wBh?+CWyYu)|2}38xVS?$%Z-p8Qh zwY*eEugkJ^84ZYynW7EY1`G-Za~JRJpUf4zEYdm8BjKcBtCUclVosY3Cef|6wYmPe z_xw`*jPAJ)Fsxu8^JYpkad`SZ2(B!XvamlR;{4S>S>dN0i^7_C?&IL&-EZDv4+&29 z8I?H5ZtArv5xSc={Y{y?P3+n9wC7&xcx)jB*Bh|+Nf4*o7&4o>*b0M^GI$|GpR5=A zo~}!pp{JYl``fk013n?ee5ud2TGL_gkui=HXZaz#aYN~!0Q|s#Z(`g@>Xclsu}*|X za~Pq{x`%$1gVNA3v*zY_i6c1V)zSp`$3oN)P*Ng_5YmtYx2@3><$Kz*eAa=>7h#lz zJ!by_LQ+Wp^YY;yFO;#J4|tb47n~M~Q_5E~-@9%-=LtP-v z&~al8A2Ld|xY(%99TXWz-$I|VCz0nvhi8<_f!HKn2UZPR${8`gm}cfbFm2FZ?7D7U z*W4VgKOo3AD6!6dAk~<0;N;|Dy?Y{vj4)uR2s%|zyBvL|d~sf9L7|KH#09D2&U5yb zrj*_M2EXp+ME|RN`+%;gxYCz(ReN0O-U0>=1i}*qffj5fDlJYh&Im1`eNg#S|fhz1_!>I!y<6I&sM*D zzWt~Fgm9y*TtT{qQ#Yc$X>i#09q6fO#s0_Z#)>15jk${Vo7FZ#1B?#p3*VCF%B=G& zGB@{RBB-7{DMS$RcPbD}O~s!~m^j^3g`ZS=^^!O<$Vc}zhqgT@?rgOa9C&2w>^IY==1HXClRW{)5 z2S5$VNjltg;PanxstCV+nc@cu5m03Oe$F&SZ zw6~il7{~p~IbrL@FdgcJtU4(vP)}O*vIzDp=X_&)X8B_5t1BarN7*&C^B@*uP=sHs z3eoUo`PJrpc-pxYe_A_#M>Ul}$ebQx_A< z8DBz_@$JmuaP%-i)hhE?zHkF|uejd=65H+n6greXy&^IZJznjWdYz#9@w|{qCn{M@ zNwLdSzPT}vFD($?OSgcG1pgO$@-T@pS|3*@A%?PT9%hc56H}X^`_Hi|;_D=K^wN&8 zS0a~%ZP~Fgm64^4Sh$@4XF2#o$U|&i(`fXh$f!hqCXY)MrgO^BN58Av{lyMVaK%(L z&Rp(!T6tV@7z_?%25GDEkLg4~;a<2ht5I;;r=wb6cP8^9=0yfZtlr?*u~`N5b&sRxdzAbI4^<|_3x1~iTiGW5Fn7wl3qaC( zSxVT3s0=mN50uh*Es7xLnRqRRBui2(&BTZmLPQCsYlrjTgtQjB=Vgdte?c!m zsxZ)jXOj&`5sIA8T9PYD(GgLbl&D+TlK=qnDf071Cq*pcpjasehFZTjR^q$Rf`gry zbMJ9e9|uGY?(u!<%M^EQZLy*Rw=u3xr31FXGF;%0QJujs$-We3iYG|edC+WmV-hW_0U!?-J0qMa(H|GrFM7Ev!$XcA*g3s3f0U$x& zz6>Es5jJd;e(~ki$FEyLMo70@Q?%8B)qlk#gG=;@{?tF9i6>N;nqM(Mz-S2(?D1k-l zyh*JO#&m7pwRzZ&rIdn&jQ`&6eV2$z$*0FBFV8N{Z#E&7%c~nh1_39zo8At&-j{D~ z9zC2RK!`d9>1S<5CwXTGQcY$gs}@Ag*h_0CMKzTc%S2Y4aEZQ}&)9ro_S zcw5gn9K#r=xGP$;=q(uss5ankfr|IH8voRiwA@}!J@b3lRXbc#LuH>v zuDD8-O*Ej2ni}R9;s7%u|j$;U6KAShz zqiXB?YPmAjBBF7YjWyO8Ypr$cT-S9K`&YNmKKtzR&p-FpFwtf+GLd15BBBQ+>Bc!S zh7BWP2*DUz1vx-rw;$(S3!o|Gl(TD^Qlw;QJ7+9gHX=aO#-xWwjg%F*$TYF;nBsqHiCa9)I`SAARujQP=ukA9(-!zxm;R{I@?nJzC8AWr)!l)6IPv_w|2^ zFjKi(7vR?#GE+iPFsuL=rs$ljjbejLTHE>vrw&tBj>jy{h1Rv3ZOH&7Y2$1jg@D&@qVYJ5i4CG+ zm~sd}geghmb+K&bD?QB|#p*`c>&Kr>Fn| zR7x3#Y21%QWGoxw>uNe{`YBJAEh4rJk2@@yiBOUr@U5VL5EB5Xw*(5Q6cn_Urg3T- zvWDJ!TVrlLS(EEt2&K3op_Fzi!0 zkYY&~6u>pDlu}Z(o@oz@#q9k2`n@M7UGI(MH?J?*(v!yz+tz;e*~^bUeJ>Rwx%}+2 z&p-V5!*=d3FVDNKowuC`o}L~*dT`Ruu4BkI*E{dcPk;P+vE;@4bPU-w>|B5S{60Eex7f}6FicOMp0029H#hrn9~AKF zW;i-&yf<-}jDddUcGqJm`QfuJOJ+7X2>|q6lTr$iy3U0Rswsr{=KT8c<44D*ix843 zT)f((Sipd77yuqTT3SnIuczl(MfwFcDTN7d`S%`2P6GEEzi&wAKClBnmKKe*mW;33qX}jAw>z4CIR9b6F$*3A* zG-#Z<2Y%5negE(EKY#JMwe2tl-@x{Aqk?;YX-d{o2&py$0ctXgmHAMKCjij2CdULy zC6y5KZ0`DnpUu0)Y8j?5jUlIU`FgW_WSiM6O#>(pQBL{tVte{%2>>2Br0m%mqLM)Y zNDmOHBKGQf^X&1wl3Em@>UjY`O352mM7F%$4u;4xS4+E^mPpZ3HET+>bpk|6xe%e{ zDp<+Z+WL{4Gavu~5gI~7MZC2sxXm{z&yd+53aK!&f>xGo*HjrNNGZ3*AV4Su5&Onk zW)V#}Pa#hsHq1aIqA68y=ApKvwTGgLKy+{VLxqw{%*h&)M6!Z4d`tOJz$V4$yd$FR zcDEl!-!=9A6j21Mnm?-Gj3EGKTNF%z$rHn9ml@e6bmZ6mv{r-ZksZdb8Wb z62}k$K!AyftyfeifPx|lz@k7*Ro@0V6CpG0_aiF2xte@~)0EoY>n_4=u@6xIkeJH5 zzCXi05aIl&E4fS)UR@1M%f?E{YK>t-&bcY5!twd*ZHeyj!-p)+$lSNReqB`>q$zj0%$G8E11(##!sSzH7X%s&ToLTqGkvDGgZ> z9mfF?ym!``oXa>)3ZMv0 ziBX-kDd%r|NGavlXP1voR@a;TZo8Y$x^WmKmChS5JnqXlBu&F`4FJ$}&8+u%oZ_^1 zh6F7lE*493OQOgnrxdrln??V4*)T{1HgF(UqW}?<`|MtTLl_`Zieymj+tySh2@x44 zV_J5GO@%WldH~2p1(20l`?d)-vJ&hbZ?%v5+XlSnK8WH+K~OyE8yUV~nx3 z+Mid;OHj!r#~4M5wcc7^mD~Y<5L!zD$oMw%0e~!^0!%6gx;cqj=Pi-VsjTt}5kbWo z&qSN;X1Cv0$vEfiFoc855F#_WTQ`YeOht-eXW3k@H>;!5DNH$})yx7wVi0s5l_dSf z2oaHD76BmQahj%SGS0_RhG9BBUckE!FrX?@?#G>6TZ&8yu-@#fBW7xw*04cAW)5Kz zky0QZnEG%VQrtb>Te3C4pebN$_(hFC@2z0%Zd)@?Ss&bLj|Gcp;sS>J4@-MF9L zd-~vKpZ_AMG;K3}^;MWgYi;G393LIGZD)*e&bLj=#yIDVwQP+s<`!FtMc(bP0K7hX zz22;+X`FSl-EOSXln9`rDJCL9z#>9bx{a_DscDS0lv41Ps|aK+#acFoOO|O$i0GUF z07kZ!au!v{0ty&a8DKX|H`i+-B4p+&Q3%%BzF(vq5vl8ZN|}h|R+r_LS$TJp-%3Q> z->Rw{0FtqU1X^+~MUt07^jePDUz5u#7Ioma4rIn=WUZp5m6E_ z*7S=W5SUmMyth>Wg8&%8AO>dwCt?Kf1w-4DCM2yTF{)_q9F&aaT%6++0TGZZ7?iyC zD8L5x>sXS;3339|$~>+Hjs*a$BV#QaB1UV74?=?Fz*Lq4^rAXVwXNT5cB;UJ`@U6? zDa6J*5Zn)A<4w*55SWd#Br#QSZw0_xv#FG|?`oX}ytg?=CSQ<^HMPv)y`LcDoJxp~ z9-O{9doztnmR!>e;aFl;cQd z=?IS=%$@Vh_~vYFnMA=lzaKY8$Ez_-fDi%@Lr4jX&oME!g+wW#@}h6nH=8F9Pg4*8 zo3j#YotrkBsqK3RwApMfUSBO1OI7W9KkNe{u5b2)%*GI)?~HSnm_(qI0;FJ|pPLX$ z+ne=zIy&x3DLEHHRh4N-MRG~}>iM2}&+SBu3qAM&~$12|=wBVm8hx z(e?G{oLe3B%-D72)r&PTfC3vrKx5o~H$HoIG@m&EB-9Wlh*RtQ@uTJLdLW{b@^0F< zt{e8_@@TfbUXNo~EjnXSajt0(1Q{Tua(1>IhkSZ88+MoTdFQMd$1!TjDWVp(+&c4Y z-d*hv!ra?%V@=}<9@6`FDZ*L z^TzdTjWz4*44_UYN3PBYyqI%d-fYf}7p_jO(=?S*a?V6F>w5t}h0Zy{T)hRVw;%wN zgI@+3+tmC(E714WB>2vS5D|%~3MMkWg=?#72%(n!>hG;Fbul0!W}~3F&0}ah8jj>0LUq;9NMX(8e?i255y@$OxacA zc1^R{!@9h$H@mB=>-QJ$*E5$~+oY0nu}p?7=d6;MZJpT<2#|Y0LECyJ`sO#EogU2* z^~az6WHIx8-CS*U!C57#FU&{28 z&$gxL@^}K8g)yln(HwKS+6Kd1-O3eX45MH0ZnqK1sHH{^bqOIrRYkJy0a^4kQ&(6xSF~h%vouI`93k+lOHy zBqW;mUEem#`E0w}j?)+y?S9v;n`X1$*X}_kT+na&uY0?%x7WPA!AA9dJ_km zj^>NTH$~D%AAb1s@gu{WQnU>7*_>pgEJAyrHHCAh7KfuAS7cdGg)#e zIVaLW=-@V?Yb;_GCB((N+3i9u z*%(ETDspIy-)#4ro6X7b;>(v;4^HNW%@p>V^+>4R(ipNK(303T-a8@&&=iMd2p8vP z<1maF=axaqSj?p!mhQ{%BB)5ZZBvmo2YUS!QYvZOO?}(*f{_pos)h&vbdUl&pvVps z6a}bs5q&ELaNx`wOoZOaIaCkMCkj;`|GrM4PScq3+oDF%3<7t+`dW;+9WuWG`BaT% zn5dGeMfL!|T;Z>oaJV{-R~zh=4P`wzqq=-xd0;P z-0I}?JD+|+M1~C!9kdn@0SyoVRI5Ol#=%&ZVqj)f(EI8o03xznE}O<59Utv?`;v-t z4vFeQ2B2{|$ds|_cDJkIT8P;9tznEY4P#jJeJK)SYFk^Cjhe>PN0GB`hw%8M?|U~* z!ue3OSJkWSK1{>$@k)!t7;7d^28vGBT4#Muy4!D4iXswAtfaTM62FN2PHpYpGZj%4 zB12>lp%kq~Zxy+HE0F-GS`h$D42W8a>Ot>PZiO!qv1^<8Y<|7n{p!ot-}?Cd)uMg& z;d?)S{?*lX|1ba5pC?sz{@K$h<&IU;dZ>)qnlRfBeT?*Zs+#{K^0LKm7Oq z=pX+VpM3i1fBR4W>A(En{@4HPkN(qdeDJ|`m=1uZ6pgXY*}ij6AFr<0<9faA`__B= ztxw)x&O2wgYh2^3Ve=aaVKo4VB_aaf>h4&FB||B9t7ri@O#b&W@$V-&pC^=)X!Y`{}_AIUt6;5PG}8#h=?=X`Azw9sLU$cWxL9D8F~;> zgVn7@LV$3!`HJ8h@E;)fFWTLbKO)2jB)TQk0vQWhEjPGnEF0AAE?3!Em6eq*-*l%l zM#LW0T6~Ce@4J~cf>7!`<-6y^jT2|b-h2JlZ>Tm=6xgwd9C$1SP$g&aj*EaH?T6%< zj@wShy$9GOC4`b{$+ecm(}BknaTsb9(WJb0K7`qfO~oM+;jC+i z-C&Y$u2-#JjDB~!-j-ToOXD^pVo?*F%r$F_?QG$@MKg@qAk0qMGLAm*e%%KbL(?Lv zh=8ip>>MFd+r`wE#=D!_?b*db4FXdwbv~c{_|Ly++pcZf{l2_@`{wLo5koWPwBPKz zS@ZhM<#xMWt+#Cx``xZ-y7TizKU5;jslI-(IzL~o*ZI-K(dC=fEIRg1i@JuJrZvd1 z32hsPA;suZCbdjvzF{Nz;%C>--@owQm7>ff#jakh5$X9ij<=hh*_~c25Mj3)$@y^@ zkB{b%Q@fY}x-?YNtdo4Y)>O1@gH!_}5qa~))uTseZRc(;$H@z%-}g-n^M%`NdLoX& z5$bH&Y%fbMP{y)6o*7uG)zpncdGCWKHRs2V&!ncDD-otz9XkZdRZ7)(?H@n@-D{5nS`Sxbkx+)YnUo7M6^%hCD+bm{7 zwpt}6$c01+LD32TBk05{yDwv!Wbe=cQGc@D$C&Mjxnpt{Ur$B^c$I3REcr2>7={14*-->Chsz4cJV;)n0|WiDP(2Zi?{?dZvt^7f z##n0&u|aaqcWs=lcIk4pOGV5qTjsEkyeG28fr^-;l1Wvia?Z8io7733i;Jf1p{N;7 zDG`9C2uKD58goftiUEV?$XrEBvOJd1crCiy=jGC$K3*`Bh^fMMJ&Z$X&t}bh+a3sPxfH4U{eVQJl*PPTt@c`RKI`V)jEFAIoB{aY8TrxK z$?a+-qRaX0_-J7OszP9ACr7)@?e%I~ioE~c*=+W~YTbw6_CxyQ!>5zUFEekp{mtzr z1TP|0Y`xpJO+doi&2G%{_UihZAAeZta6d-8bL0NTT^udvNBf}%)B zx%R_&_VhU*m=De~TUAjYQq_ue%%d>VWG6WB4?P1;IdP7dCIsQmCeiLU3JBmF4Z~;; zouiRcDYeR1HqwVCtxTO*u*uW_oO3ZY-i0a^;2kGK^}v|Q#Rv@v?~N`HpjI?>4=t4( zLqnC3OBEaUrIeI&N_oBBu_FQT-Vr-R)>=%oA9ATlFpUKO03ZNKL_t)wl&WSamD|-` z#1L0RZ=!GBUao49?Jm9d_+&riFE6k5{eTF4KN=X5Mdy!>j@Y?21OUV^kL`TB&%g0E z{(4nm<|>j>s->U-6V?e2rGq-fOaau)soJDB7>81;_G#CIX1WPgYpqqJA|e5Jcc?uk z!>+GsxF@v?Oz8VpBGMluk=*_LwP2I`-HZ3wfK4-y$AgEj0Ei0aoK>x9;%2k|7k~0+x2p{Rc<*zOu5HI$Zr7VfXUE%q z$$5pyYEusl9Dl~PM{XYzpnvo^-oIrq-LP0gfA>v^{wPEQ`CoV>@W z9XFNkX}@{$^wIk2dN=r-GqM3p6!A2*%I@`JW>&Sr0|z;p#1DVjad^u?S%6?hNJJCo z6Y0)wd&)h}7-_%Hvf?|tuk|M`FRpZ>Ey_=Dg4cmJKg^6S5b zE?A%7&KaVVj7Ciir^icXzFqYx<>yb&+mn@zJ#Pc>_2p)ws;4olXw&)- zc(bizQpRAe)Cy|q9BVaXFf?}L0s(-D0^-E2&q=rIp%%G*v%R_84MSByFq-h-JeC-p ziiE&Lw2DH8S?8L_(L2`#F&c{~sMYEnpUm3bPzp&C~fz{&KZE>1r_|*j&key9>b=tNnglEShn@kHN!TU|hRm1jrXF%r{ z?7dH8j*;884Z)B7xZRBa&@G}FK7Mwls#-NP{=E+#-(0O2+rIBlFODUpaX&2PP3?e? zn>I>urIyX>>t-Ik`q{i?#_e`&8jlVDhX100B1 zjMR!}w2W=rAsK)n(e=I$fuEl*`u&bTpFKJuwwiYRKF8p9+kCwmQmSK?Qngge!{j#)sh9aYg7ZL1fas_rO*T&3 zg}&s&T=V}$&-J|6?pIBOdzTwk)qH5_7AZ8PLo-j9*7WD0s(CoGsFqS#DWx^q46LB~N`b`;jj1RU-)4`0)dek*ZQkuC)+S6T{Te zkXpEj2w3mJWbUR{D5WCEv~M%ywp%Qm*J_I{JwDg7^)`#VzP!C%ZOUL276_GLFj7Kj z8z)Lgvc9YwTppB&0kPlLluL+#JOOy6(Ii^U2yCFp9zhW)X-ZlHFgazkXh52>=t1Le=`QC(yjXyTXLZ>zmittJQYG@11iY1VqX?O*n0-rD>WN;%q+4 zIS>1Neb65W!83C%(lnv(;dpsGd2oTklSgN{l*y?@Re_)hp<2zQDvFAhGPUSX73psL zZ??PH>_`;eUax=pvsZ}V8NtjE#OMfg-i7scRE2KVsKR1?u&fo;QgYjdXWf(A?fCfO z91$5II=H&N{pN?ytHD3}!#{p~dHwj&8CWr^0B~}&usd-*n1EHpX4r=ks%jTKKVRm}s)W0#u-b zi@N3hK$p>KJR?(2LM_P zMD9$n@vF)ez+8kxy<-(+a#IqWs!Y7uDmB&I_~?VH22)@1FQ1nWKb{HV28k(w!R4_=T zTz>xf(D&mw?E8LwyS}=)zP`Cx-LCqfUvJll=-7SplW*Q$uiEC24pM6!b^`!7?*LJx zlq84W0AMO2MWqY^(YsP>+eB;|(OPn4rYUh40Ucqf`F5L*PX&Mg?9MmLqzWcx0P7m_E*zBHI^`JYawUUFc4nk0o zTIxiQ?z(Qf?{99`pZ)aZ#~(b6VfLM0{)IpIzy8&J994A~$L($}s)7BleCIp=S$Up8v_8{@4KC ze|G-2f8$?2JzBJF6Px99{X{?kAdCEkOr=r}%9m774#KdB36dutQ4vYG;v}zN4jI{475&A$wpTKOf=r^0Js#n*W=wk@ZJKn6v zU;fVfpMCx|r9D@QO-Q5M%|Q?Y8mJGE+=08sj4!{ue)Q<%{ORfKzq(n>JMZ0o)h|vi zm`lwic;AEo$8)W6d((Gwe{p`%kDC`S-(FlCGvf1aJne`5{-!bzAa$K*4*o=sFLK-H>Bj(_rlFFySEJpjwYIG?pKxU1{c ze%J4|N!4Yq+onP05W=J5qpk@>^!eFIspawM@gM%+N3)ZKBtV7jP+ot2 zyhz&6fd)oU^nq^Vz&M za{V^Ppaj%-Uo>e2Ktq$0wTr`aw%r!T=-hB6#F)-q2}ehnS9A`vh<%a zbP?1v_%O|u_Z7%H8a645`9O9L1_)K^w6&UI4JO*a)Zw{r_fN-NZ|YFqAkmat ztVLJb(KF8?BfVP*?&#%q2jd+`>J!u=qB#pWBtQeGU!4=p3=K`8R-saea3WPBxe(_~ z*E;6`d9~i=RAzG=`T-DfttAa*;u0{YT-qiQlc{LcqFU;^9k!}&x0~&LYk+14PHTuw z6^X$&Z3B)UJvrO%`qndpBJ9Sj%wfz95Cnj2lSTtmQCP3?$q^9;VlHOvTP2zXmK7&e z05}BBIfD@&T#Xn^{G6D$=3-T?VsPGhUvtf4$yr=*#5DHV-DL_HK#UH|t}b^WPzWw( zF`X(;6wwF{212d7F~8cq4Z&^q!^z2VyX_Z?j+jnPPZqQJ%gf>Czxj&*$iR-`!Iy8M z+aEUWhzL^iZa3s~uP;9^a75I(gL{&yI_E+RyWOtud(+7ci2-0fYiG0WcD2o^#1PL; z&eU{@DL@29o0M6H;X!PmLr(j#F9P6Qh-}8DSgMpe)|2-!HZishyE^uR)Ox!aMD*n3 z#28;)-bfY4cycrk&du5wJtJZp{nV60VliT*)y?hXmlK!Gw?29f0Jod{zx_9V=fD@X9Hp5Ri~W#c@Pr zHL420A+{YcJ9fnAm=VCh4q@J=a0ly7!R{sJ2T%9(EV540b^tgK8pQNnoMP~fT{DbB z48hEhIQTGyL?MCz*P5Hih&0hf%nTF&(K#-;s*#FeDwa|P zvdwPS=iagJ+Bj_05xKS*QdOJomJR9tF%&`uz}-0Z`xFTFNhIxp$6Qi7i|n|GF<|rh zYL{*jKtizK*+M>ljO_fpYvzl23^9iI-qZKKeD%d)(m~*ZnA`4d9ZwU{lpTEF@v=vp zvdkxh%3=tBK+J4_RpG09&}kxjc=HJe!44JycZ%A81n4m}xFmYLSvnwPAn) zMv7lGHrwa42m!uwJnXj79gK_sNPec3&41D47N99pV&Cw+js-VQO%7mKT# z+ba6$XD@%@=RSD;EIxhz{o|i}esgoRoB;gA07|K`8_ zm0$VQzyJ4s`+MK}^}qJl{(9TC-Unvh?RLNOJHPWU{^U=7ebEu?bYh#o9owaZ*Fe4`+oS@>#M~qfawoE{o>#FtKSL1 zw@o{pYD{SgOEr7fkSX=hcO24`NoBPvu>uI7Q$>}UvWRLa<>0F>o_1P;!J>`8sHQ3B zQtR~mI-;sVQ$lbXR0YXIrCqRyfrc1DtuV=y0IcnT2@=tSEUh!$SvA%z1{#o z*Ts|5#WU|)5F#v>ix9mP&130TJ7zUAt&=?^G^x-sox(TH<)QM%xyZSwccE=orm)$i|eZ`f*olDBOrYA=0>)8x)Xpo)%Tal!jY5mC%Sw{SDwZr2Kvwy~kYZ)$Q$=k_*vH zZ`K=hF0jA3>94N(?XHw+lOyg|{9jBD8p=BpbQJ+pA~SQ2QK})4s2M@s*X0qWn2~3Q&XJf+%?CKZX4M}^S*!w5lbTH`UITSR zK7?8+7wy{M9n(WHG$JCFT<+o9hx78(-=JyIy*tDN5gD282xIrt_aqUX%?=&syP^p7 z&aG?uM*<6u0Gyf4A(|+nO$46%po1!sYcW92?AV1sh*+zZq9STwVy1#j6M{_lGq0H` zXe|{Hr!po4Zvw9AklgX{aXmN+Bo6JErQB|EDQaetCyd-Xe=saYL?q{&<&x}OWi{Cz zsE8rndjSzq6d*ukM(-Hl?DS|hYtGJ=FJ8SJ$Fkb=!&t^FL#m?7rb()$a~kGcvowt> zf`kkJrQ}lTA#NPe%mOUt$EC^`njG!}Lgn-Cgr zYGyi)Ige$%9=a~X$YvJ8BoN1v>nw(f;+<=vZFhEceJiRdrR8GbT`++4F1@+D{Kap5 zJH|-Fh>KGPAoPigvr*ZnvA*Xhg`|&gbo7KD%A* zcDn%)rAmn5VT;cIo%>pxAkSi3r2?`D>ZI-B!~RS}t4Q0;rjtxxA2Xev9mNox4^{O1 z{ge>R>;TDox9FPEP|Df+uvjdrzQfKDA)`Y?a-Lnt zd7o4E98fB{cUS`&;DgSLnT6Qy_W3xM5WK^8G_Xn5JYoOA1pv@P(BPrTNr&Nz3XrS7 zA%Ft#0Y;xvuH_w39f=4@9^@9?O=DI~004RNWd;NX=!ii9nH?h9Aq)zd$tLd3&FQ`e z#e{)5>G&XC)+Fy!zpGWJ%L6kU`yyIIt6?sAOrxr@Cjsn&n8y8(2_4*N!;5BpM|@R6 zBIGU-u&=voLYyrYJ}~=06vTMnzv~hhprPMv_bzGObwBTfh}Jn?gM;9 zz`fn>4|Pk^Os}k30fCtA=ePSFINqHN@lZDcqN&lHoujGLTKt`DZg7N5rHH5!p{SKU z)hhikB3Mde7d%YcHN!G)tCI5^n|FR+&iRK>)By*&Kga_B>AM#Y1yh;41a$J%b8JWk zNFdWn7DAXV{qe=Aid{8@7;t!mD@#<#vSuahCu5 z$6r*Dv*RPjF6aCQ|NM_{R^#=0-;W2zons@^Hqw~!|NfIt|JL95^^|j|#XEnzd_1OA zDYZ`7jQ~Vg#Zndk5Ct$RV!_kI!2>J%-B848H6ThU*$a;=-~?s~PBM5?KM|`%=bdv)dii?S zE{MR|7(_LCcRX)BB@r>`jrpi+Yn7qWE)`}DY@!Y!>}nvZX-ohx^aC^d;QM`#z!T6? zMWl)|=mKK&~n*nl`49AcC2-X4fMB3iar1E=*ypNUcKI! zYr5!bQBez?d~nP-`KZc}j+R}`<<*PZruAnRr_AJBz@?>qKYw%v0F`LB+sxbUEDpImC!_bdMN1@-3M@QYzk42OK=d;GS@H4z2c1YmZ z=CgLH^%o1TTDq>=ZU<%`Vkouj`;nPLjJ1kG*Up-uucsIDVV6=Ws&;WPANsN13^i*} z%avm1yBW>8xF5>156-)JB*a>w-}Mq)8iv_?7EhPMAZg5Iz=pTm)HZDuYY1BBbr1Wz z*Q%u?=eX8f70?UeDTDpgHOQE+v)8IFz`By;3)&bQaM-s5_msyfVxaPG;~ zf+d3#8?>TP5o2~~lq@A6FI`g#?)$N88f4lJL#=rp<06LLZYXJVo_!OqR@*^^yf@R^ z_5Sv@-|tcyiyXWq5D(!^2a2PoRnw@ii2uKP*ptD&h71( zITxVj+BS1ytF@e;9Obb*o;TZ}DsnR+d4!;5i1#}nVvaGkZCgq)Rp(4pQz-!8n4%-^ z2@%`StVcPHf&W52!6Y+NRmaYgAM$X|11`1Pt;z&oRconb@}*(q;Db#Ka}h+GCL4`DT;ImBC|V{Enon9 z7yUlP;nq@V@)7Xf>VY5QeQ-?Phm>o#n2X4MzrR_nIMDH838rvxYXEjkjApi&&2GyY zYXv)O#idHg*-Y<*wbM#@*fc)es_X47wX`?pt{^=4a&mg0z9HE%FF zhIOyb5fggm#yN2{S3$%nqg1N$J^fk$fCyUOkclQ42%xa7x4rkc=$q4vnH7Eh@v;_U z2UR4e5}QB(CNNE^YwZh1{Kk+ZJc+D&^|pmS%hY4d8M4ETdUSq# zbTp=XyW6vCFR!mZeEuPG1b{2iq ziOpT?mjR*yUf!&8I#66x^*+vgdX*ru-D?>RhZ;DJNGOW^a2OAc*)ccKc{b-?%$^#kckf+ zEhJ(*teBGk=PNeoh@uMaewLsq+!gLzeGyU3Ds1g0wAd&s#O64F1bwZe9pNikIuD}$0uhm zUR`~8xgL_-pXdH~cN^K2oKKGDV?Q9M^D`gj-ueA*JERA6d<0<`stp)E-Xs}o; z<;CY|Oe)IE6XR>>hjADYv1yFi(G)|6Y0~`$=e-a28sPgJMj|qR=-u>_0}?cuND=}- z$s!YxhR}JhQ&(Zq5UN#`&9-0Nu5!sGmth`h zl-wQv$N%|b$I>u z>RtU3u)w{=&5Q4*T?7O)9xsRXz z{3q`>F{o+I2~DJAP)NCsNkr^m-+%XcRjrCSM_m_&G1VefWEe&TR5dXuwE_U4IRw&D zEciA?K}E#AjuTR5s=*TxRjGN*VHth!IVCd?vFPVuECSx&hXH}kD7z~)5a||FVrD@yA7(m330LZ%N zPZqK3e9rmvm#^6&5d}xoxmvB(db?h|%pSpAu17}Kc+WUd6Vo;&VlKHdGZ>a4%ViT{ z82Yh_AOIH3sn((f<{SZ-i?m!WOw=#{03ZNKL_t(~BnO7E@yq3Gx7(Njv%9?7Ig&T8 zZ@_xSI;BmWJ!%lyx9!cPRH^e20Zc$c+r)s;2Q5+h|S1{Obi-IkV!`nBzZqW?e!8?2M>==PVaQ!f}v)M3=6ORHw8T|F- zrkTaIK^Hs&u5Wu&J3j5I)L8v)w@bMy_*v(=maEFyqow!mi_b4Z@M+9V6UMQ$Z6pNm z+@=i7uAR00u2-r3ejnq^MDv(L00kC{wyx4{*Ux7D^t5~VV%_ic26n&r%TGn@>dkG= zvR#iN>KGPBX8;ys9QuAX@4oo_C*B8yvu@tiTyL*;NC-fs7A>jc}7hh zrB*Qmgd78yXcl<0?Qe${@uy$D_vqx=@odqyRV#ZgRrg!zx25mvwERzP@u`-W;sfd( zNC^Z8f7i7r9K&uBKj7A%^{E{A^>BA8XS8jLY&2L+{TU>0a?(2 z01X7@Hn)8tFYri8#%3fwK;UfD+0Py(u0sP zkPLtbymK)u=dc=U7u#K^ihYS{76C+1v20q$%tTcrhR`$B(+}n`e)nj=9WdOPW~UW(LMc zj$IYi2Rcpyx*tAzr=ljJ*v6@1adKewTQMMbmyAK2OVtN*XJquzOBI{eKc-3YYk25_ z0)VKMIz0jC9C_!amCt(@!xVS~wbYc7sd0#LdDO{u_^7&;r zq*CgBxATr2fu&@3De?eNq~wxS6*wZ1nUyL4CR1nTZZGA%!#mxusNw@(K}Hr4148yp zY+4OW?G7D%aF`k1agy+E4=1Y5Ip+frnI4SGTsRo28emmaWV|b8)D#V+R-AG<5F7(e z&^F?ja@(Fd@6Dib3}$1l2d)uP@L|@@KKjl=&tKdylU4fXPe*?&w1gJNJ{H zFi!0xM$dDt>O8ltH?-|;NIAWH`SRxG_RZVZA+(PlT`ZT!ufDiEIXebJ7sB$yt#4Lf zxLt2z6Q_x{?czks9QQlo$<7X)_kXdHK`Dj|0BCY=NI*0_dG9F12-vpK2R{|tYT9+p zV%Ba~+rA%jDa_Q(yNj-^X0QL{pEXUaBFCr4@6Db!Z5LzHHXS+_L;M=&`Tyr3BER_U zZ@+r^k`UOr5d3<(B}4-dQRm&)_iNm? z#g|v>?e=KVddwex@^gRtZ>Hb-U;pv9zy0m+fB*Y`=eK@qu~>Zelb`&(-~PM*;2-?= zmv7%bd;0V@|NVcj)|yN9&M{3bZ)u`K1a|D4Ynx`%=gaF=&ZXZEpZ@sstIeo3t?EW( zp32Gc=)I>O{=(0F{P9Q69U1_5A}M3l!x*Sl5TI18Vod1xa04A9A~?^rO0Cilsg$Y) zsnjCkh@y9*ifYbO4JbqxqC-RlB{-a24FJIhuUQLP-6k_r1?MP@(nhDMB03D!OjJ~= z9g?$En5l{J;_M{lQj658CDr9(p2u>u=yv;lv)v;>O+pS!u4A9bQ4CJh##Eh9Ey9j} z?t{lBcDo&JH+!?njEh-p+b|4eKKCgV5v{eV%P>YvIkst z&W&U3tE8b$lvfq=(GgKeb;^v>q9Hg99?TL`PPJAsFg2@+%cEwojEh-F6eA!-*$=mi zlfcxjZxaw1=yuyL7L7q#9-VDB>Gpc`A%vzJoy1xTK$5Bif-258O=!}PsEt4U>?#I& zwJWD*`i+mz)okd8mtPKM+BzW1wU`NjQLQz$jgF%MIPa@jAoK0)cD0Yunc4EFTO7Of zYCoI1aez|w_ylflODO^ht_j;s8v3;F6M2&X_M1Fgxb3RC_!+w{6P<2SFa zuivgjYvRiS1Z`tj+rXGFBwjAkTNORdkIKDv6le)INih~9hGH16_h zGYs|V`^WoTat_z)aU9BipL3B9KRkK)v+G)6981&sqvO-n&GnmCF96{5;?ZZH?q;)i zv$}29EH_a^VpGpx+m%qGrJ{us7Ao#S0A0>TM1!d(q07$ifF5_$S1kaF_m2}sSNk2IZiRFnVz{zrESNY?}vM7lvh z7=m<4H_|nbPRWtd-AZkwdyj5pNP`FngVCULcl`GGo%8*FJ7?$KcHgh(^SZ9bmEHqZ z>0I>CsPM-t|H~w5$$4qJEXsndN$xbQAp04iXN(Qd@W%L5Ew|2-^+aCdNNy9AD+-o`VBb-H{w-@I#V`KO6 z8G1URp^g%^75Jl=WB=7fpn1ZE85yq_R`^`Lf!rC-TJTYn#!ALCt_n4E-V_@Q1T z3A;aChl@fAPjfR$?5CHkY3;49vnm&toJZfS)0vVL$hO~oYWQxroUV_ zy!?~CR1jW$$sslsYcz0S+l;E%-k#u>>kK*nH*@+W*#o^O8z@v98^Ch)E$Hsw#6$4B z?808t7rr*J(J#r0>ut*0gWDs*qM1P8FLpdO1w!?A>gty~bcKFNSh4|U961~*-l4!1 zEcrK9?T52=R3E>+PhnQX1#GhjvMdPM5xz8dzLSBT3VO~(3Seh_(ghh({-U1uin-&Q zT$9!w8wyE*WkD~GzN0taQR^HX_)9uOLGiIVFQG`jAJ3%*@%7*8X_R5(3ckZ;yww4v zP*S1l3Vno?HT7de0O6PDpk-e-RFg^$GL+eS43%&iP}@Ir{DeJQW=jTgsQsNsi8lT!T(uBdqaLh<@zSjCnR7RUn-XX9_g(=?h{|jj4U<(1Ta$49R}_&P=uHO zfE|YUSf2sFH<144y0FXN&p_Hbr#0sdu+u#d;&&uh&s#Euzl$6Ar5x(IycB-z$RLqG z9(vNBltUZICLi@2C}=!y+LV4tKpkD53C8|)F#r{aE{dXq*jz-W>zo|i=)O8AzfeAf z`k)8)Wm(4ZCoIheDRp&pauDE7Ca54_)E=G|!}Bazk#JGzy8?GYt_DwaQxeA&ecYtG zArtMth1R9?NGjj{qni`4a+n!t#;e*g`1re9zE;@Hrn~sVf?wFGsoY%X(G))i-sIig zJw@na@!f%4*Y+PRMZrv&O{FY-uObC*^4NF{Jwf0`9^I*A36=FHl_f)-q_3ND^;6)K2@t$252_EH+r5|-=_Jv=|L_t(c60o0m zeS!8DfC=<=2Ay>dS-ckYK9LQ7TYIv#KQ_sxP0Oij;7u!dcXSOu z_jOr8W8lmQ2?;BaRkQ&wWBtY7N+|1<#{z&--$W9Ls9=tKGXPaS*bFpYrMCQc`tWa~rk&1Z?UQ<&_UE~oUPZwo?@ z(lfO>=CvPOdeR8286x|!>i<}s;>+X_0#~$ptV}87DJ7VnGk2^iW5+gVM7c4mJhj)3 z-F*Aq#C%EAN5fBIy-4VkY1Tw0__iPj_M7~qJZ8~hdwkTxsNX|AUAPL!xQ>k;BN^f% zKAf@97beW+&H3deh;o~~-jy<4b|vo$RYf#NEJVJcl?S0_4`Tkk2)!cLe|PKN9pA9{ zOg`zYfwcj)qm;DV-((63d5%hE+tKn2vx*D_>I!{_||m}%te$EBJ_MDb&;<<KBI~A8=1f)bqqhaja}5VE%v2dd!bD^spE`yn!>@c__>A`IXprvo<6*%+dvs|radU0) zrL`alfBh`lb`*?=)4jTCm>9+P9)89E1kw_f3L-^HIren<(DXhR7lG|d&%Yy6-cz?* zDXvq#S}`Jqe^iX=@WxLPFm*^6;JFo&-XlT?XpYj&iD&ck7n~+sm*pdJSJz-;y`|G> zH9l_QVHaKi6KHTJ_w!K6ZQ~q$zS4vvcO@fSoBD0W@`R!*K^NBp zCs!qh)rU*Io#~@6RIRs|(gg>*P2%<4>gxW?!OpG!nDI{N5@e*ET~XHSeQNkJjDxp-LQFmXdZ|Zvb>7@@-&z0T~{Zo7_9c( z>)~jn#?Ohzfr31?ky6J|fqNk3&|xNYaGc_1gwEx|E16Wm5+%%!TdQ4Wzvqt~BdLa! z2H&3wG61jADW|z&JTY)sDBo{4e+l?s}2fkZT&k_!K*gq_#G zk5YTe-d1Dv&7OVU+FI2cGu9eE#px^5Ok2JvBxS@dN+I0+KwdJ57+;=)K9ArLdF&;c z_#P__*3m#^_@Q(XtHuW)e9fV?<(FbFqlbsYpc!S|0I)V;8MdX2AdsslDks% znI=X$DY#Uk2M{JA$n{~RSDhSRd34WH-ok8X5>(xW2$#4SmmGKztQR|ZWvv@ffBV|n zRaaH+?GC>;iZoODIjzut`C<~8LZs3lQVm1tZhTsKm_HS}(8vfZUz|+_AE5IcACi%q zGfA8h`u8;g%Uq;X6 zF9pvo)iv{)8Oa7*cm=hO^BVmtCj>pk;zi81HtpusX(>(9*QVx9CrC%^O@!SRc3)mT z4ouH;```302e1LqQgW|H-KKM-A=#b%eYAY&YY`=Fny2>eHy91^5cRhW$6+P;YcycE z4-lh512V8UeX2i0KP{oo{ag`AaM&sC$9Ga?l|oF{s^=o$2pae$n}ik4^RbzNoOpY* zZ>?5z_P1RO38rXF>1|izv%aF=xX?917Hg(Ex(WWPZ3fS2VNJM#`impnon1)cq#EqCu&66gg zjLcEe)x#B3KtoL8L&N8T>b(4)VD{#Siq&BDv<=BL}V=jl?#SWLD7R^*OD(kH$ddb{wG4BoP4NZ0C-I{>Twezkq`};Q-y4{K=pNSHUzzfYd zl99sEMHh-gzVu@>wK1Ekqr%X~=K0NnAxg$I;C-+xdAk&emyVJXFVYB-c$sDV8c-D& z)#akUc`mI32)vJ{6{*q&fqJB&)9+j^2^t$*{ivv5)8$b8`%U9z>0O&d$?YbWLBR_B z17?N8ttUVzHVhEiESk*4X`ATNw2@{eG;W_Ma*c_aPx*D9KCH)5u)gvCzBC|_oOJr1 z-<&?+>O!mYmf~?r?t$&$#`1A#`JTmPALY>vH{*Nkv%J!JSS)^|c=#1|O&7L57rMXH zj1E27NE&m;Ap~vI_{;)rc(h-?X}^wO6tqj~MV$wBE-lH2zNSrW;>jl+C>%{1g{ z!3Yt_IDq`0T_VHP zbwK(D8%QeoARWAum`Tb!^Y~dRTzWs-Lrf4>=z%hv z|JuPk(Y=SS)Sti$0xL(d6>6%P++KpbWX^zS4RuOa^NSCce0Xi z)^#Zbw0=$8j0H}g7ox~xV}B^!7{i94&WTq@%mM;CvM=bc=>9_Pw(8LIb;DAPgo9dz z(|$vGG4`J1^mvW3ianmt z(z5oa5%%=uhJq)(Z~q4gtOdSL;_XhW(t=1HU*WKjfJhswh=J7ZJ7*t%k$m5e@wq?A z6tNYx|Fu@UR2d(Iz5`E1PfFURWVZ9wh@;Ze6>Uf933gv%l1Blt-!#=|Fl-B!ar+l= z+2?%mT_7C0t+B8w;@O z%66mMBF{aVY$h7isGrWk+vl^dF4>q7kF1|rhOVv`L^}Uh)-yWZI_y;~iOKCZ`qqP- zRjgt73^w=Hh-lqMnQiEEZ2T$HCsV{P34RQBRWXXs%ywS*#t-ktJrzz3FvzB+j8WL3 z8fsfHlP2$X4gGJ)eHJ#8uT@+lE^TmL=PcV9y5}}f>IIo65;rk z0S(Sl(XmzndO--~h;+fe!TzDakoX|Yb#%R2v8nci_+o?_y>ePT9nI58W?f>l2UGvE-SBi z()8j54bH~j@LDKk80e=$c)_cA0*itJhY9yaU%l;hdb}L8F{D8Nr7Dl)c1ETCbC*KV zdSoz*oLxisla~xwoBItuSvK+G(rQf}`K#lI=i7;daQCf(Na@pSVIXp<-ddyK6;8LUWr~P22z!cOi zNG8waKs7_z*Olu_@LJLK!!Cl$rSLH?m^vH-x14&T1sE_PiK#gqC(!zy<0tw}&j7T~ zh+{%dH<)0|uWRp?Amt`L^@Q;UGF5PekWN_6BSMfczMVez+*C`mA}v-BCnCrbP?9Yk zS-DaZ;@gO%yTvk9{-C-p&~sA4k3oV;9vbr;w>eLMp5lWjBUQ$qlu|w2WiCV4#f}MJ zY_ukxSh%_k=mD^E9}CZu9*G19;-~rB_dp?yY4|oBa;5&U`0;RRYE|p;thwOS9Cfa7 zy9YG3^+p?5rdk(($~{mRCocG>n=~~;-t!udIOC>v!FLuOO}u@?WqGO$eyC9J@3@1Q zeWfOk&U*ops5&_b8U5An`{qXs5a)h$;(l?pcW;>{xD@F=Wqyq_}gz) zLiD=U*bd=PJ-czUmI!)08V^Ghf0ut(aa{Ct2EDo}7tE=BYij;lq&$N-my{6knBDrD zg?)?Jma!>6V@)J+8bes-)auW`T^SgIhVK9SH#D<<0CSkwO$a)yZ7vk;=R1fw-tt}Y z8KXIs*bE6cU~(b_M9v=I!;RENW%godguRDaaoNQ3YlT;jQQJ!*d|FyDGh-s;;O4@L zsnQQv4EFXt^5H5JE$66)W#+Kguzwgx%n3ZzC*Xc*9vj zX#3JEm4T7o77x9nB`UGO9#o<|^V|qUx${9Si~P2K$z5E7n!RQ=pF;NTZ((!MxWkf{ zV36RuLsuTxLcdwYvL?B^>BrgPo7&}@+Qa|Fil&$E@_{G41Z;ORj}P6q=*zB4%SZ9Y z{rX3w$K9;lb>(vCqiN+xeQR8^pKI1l`J@a z6Cvb)>(t?q2Y?0}&X1OF5dRu4Py8AqU@yN;7@a~DPHU{eU41fhsY*onNg2E5y(qSk z&X{owM}>ZY_b{W0!)u~hT0EK=N^I-sIJc(nOPX+Fy?B2IJ$3Wt62Xw=XE&OpJgwt`}tVN_EC+*<89-bMI+fn7#LqZK-Q{P@7m zrQGxV{oY@u%I1f!#`iZIS((Y&-)Bs{jOaSuI!T|f*n3wbY7b{wnB{(HtjOx1(O;Hz z*Ssu;CY$d4+}>%!=VclLPNz(SbMThzI(8BAnt5pshP1iWExv#H39t-*iMH}b#P~Ah#$Qzy@=|+wi4a3Lc~tg-rRJXkd#BMsFlTG!kodd ziLR(=GKeq1BoYXE(48CO2Jn6>RR3lS($eCGL9B>=2Z{U^QQC_%t~>#J^n1=BUJ0A}dGrzJ7OoA)0dH#lS zp~4L{8`N!4&ouYlhnU#Enc&Xusf&5>Wf>l!_IC(zfL_MF%REJ@q?}a2jqk(I3$0|f zu=6!w6gyP*D$=-{0cpIfO33O9j6`0nUOSD+Bw=bm@BmQ! z`@)(84%@_dGqi=|_Eb)%FwudN5f|O37|&v4@F^>#pxMsparWY2Qw35p3^fR30z@gr z)9C3(k-(}N%HA$tsY(mlfudo95a*9{+GMswme~X~AL+Pxd68R2??e_wERP*e(;+B}o%V4WOO}c-&?^FQjA)vs^k&K!Y z8S`mnZT@;%m(iE1LG9d$4@m5-2sr-{B@Cdf_UL2#QO?fr5nqw`XP!aSv>o$MS7WT8 zcYnEkhMn8~kiZDbK=DNeNw9%LS3Z!~YSQZb2|qVAFq?BUYjlYl)4%i`fqSHS^Y5XG zlc9CJfoi_5eDB{wCh{2%ULx&myX(_LXiBvQLt-`AOP5;6v4#sL&{#lUDNMXy1i4i9 z4CfTAnl)-K9DK7$B9z6o-IowB@iGY>`$E}cY(bUSE1BoTDy6h!N?HQ+N$y}}EHWoM z``<`HrXc1aHj`pa^}5AGW7kJU=5OIw49c_tz}V8&ih)V;+#ngD@W>6;x zy$WY#WtCJr?Rp!vA4pi}Jxf(e!LiND+nRB{KQ;oJnK{2XIXOAq#^k2A_M3}eS|u;~ zE(K{VzYYH)dwX`WGt%le;V#~NuN8Vr7kbdn7Iv4*Va}(u9Q0VL{AK*}-V3%63sVM- zhWzvW1c!RrV@9?8NeM`|<9!`}{Fj z3kz~b5q8u+J)Is3_H2;x;t0M9>TYMUU5DX1;@N(18)}OzA*B3eVN-+$P$GTF%*=-l z+;-yr2uG{i;{MptBO;!ItmMeVsBt z!2&J?T+`>~)Df5HfJbyNmEN(eUGLyFyg&3qa~w~HDY1vRA|K}2a!g)MlXCHFAcI^#d0R9I*z5W%a zQcy7?(bduB)Xr)#Vh5GCHE5}N920X$NpS1Lg*&O$;lG2N0Rmbfg-~6<6qhV!&0) zb0V)xIfPP6J^$Iux-RBW1L$oFxPV^~hMM~Edoe?lzk6Uv14xT<*Yo#j%3Dkf;=ABR z36tgIZ~@l}WPX|`vgRc>R-TN8-g5M&mv3lj3LIVc;=AW$6aM|!SdXM!cjrQFd?O&H z8CLkLK!Y+^UWj|ssaaZL2Vm!`(mW@*pC&3a01gmwF&TaD;Zb4DBzHAsV1F@gnqW1y z>IDusUcALKmU;8$?kt@y3()YNci?SpY`3>}qX|Wf5v;xg`^A!1=#`_fs&Ty`v`3}X z&1M|<>s-Tn-fi%@>|c;LhSoU!sVF=~&`o^(q-E@VUM@?sQ%E}UwJ=gkE(AT%CsF~X zr-RFq=aOO`vuAe+`RS)IHDZM!$F6gJZg~|I6vI_ObGl$#@%*v$K?gtyKyrJsX(aLi z#?Qygu^v8Rf<5NVa zJ6xV2z8p4rcCr2NbN&4MWm>g(Jhm81`svr&&J1JWNEp40q65C*0tlquLe4khL`s+@Jc?l z;`;LLQ@w5iVf6Kuz0dW@cLDxwf|=K!@+#=RQV=w%qs5_pKt1(Zih5J#MYiRXtmeJcLraI=a6jAQQ@@|_E&EZ#*ye{L;l;KmzQeXn~1Q>e7 z>20)2MZoz)dQGGUs-Iig#qmZzr=&kroI&_6o$c4vaRVBdDz3}?+_j`a5Ck#rlG4q5 z^D{*uc05k>WDK0dMz>jZn8ruDLI^U$*`Y^!Km7ycA65%%N+OL}!+pZ21zwFlrRXHG zS*h(pXa=X9k$z>T!@=AjPlUJo;nrJ_9a$bvvw>0pRik@eyu^SmPWZwCPtE&_CQ*c!w7cYC&>CG-4X z>^|uQF_68?K>PF0|9VRW5kcFL6=?t>?Vq3F06g4J1;hYm=9`K_@Q`+|f^3Fvg;CHa z;;IrOxQCj)#+}iC$uH^9VD z%`SA};=7M){0|?Or-VLXCRuavEVjJ*@fwD-WKStNXW4Po^}gSou?cp*<@YdfC~AKD zfSJX!C%SI_V#)|^@0;uD4CC2>9^JRKs+q$zc0bq;-k4i?XguqK0N%Yec?(dA)Q{z4 z2s~Q(Z^O$gP(-8g;;*~muI}*IRyqa(5PDOImNfe`2lMhqbhWkNX3f`#kF)UEWA?#+ z9pC}W_rLh>_FT~fhqdLA#(sx(l-^3(Fdmtpiy4t}uqv_#GjZmltn+;J2xYg-a@QIr z8h2G2>8{d%=-h%6-}Z6t_@BqCKw4Q@vkhHdV=4%@)b8zMz!_|JeEvet`Q`MX(!12OmHH4ZPO!1=2GI~cUA-wE{?3s$ah1-Xq zSvH&T>qqgVYUSiyy&=h0uOxMKcHM@`lVdT{^Of{r*zV2N#ocN@U2(|wcy2oPf_gj< z6?k^s9{xr4=4JWW-aP#A*yAqgab5gjN*dE(k7V*NvoL4n-FiG-zOm%5<1dz#xy`hE zSU1T`b(yWW86Fx+@w@1a#2AH~g)RKdsXG*h#OJaN4Hu#?u$a+OKvf!-EyT>x%cR6TDL6S0u56oh^TC)yFRi1oq- zLRZ%_^mx`&3ca0%H9QF^^`1^4P1VK&)v~-+QK>nO&i(6L8lC0e8smk zVT$(m2HY*_@LYIO#*A$GJe$GbMl!;-r0bl=59DOC`FQ5g^yB z;Mmsm%1k#Nb`Eu0NMF};Sn^e`-WYf*oP2#$^_q^i#2h8zlGLk9KZ(sw7biG&V>Og4 zg!Y?uKBoT+iog7f>i{2+ATKj!$eZ>0;ALV2X*gsO<*Ljh&nyUFCSf3c{W+>&cxNC- zR~2IxL%tn0`kp3OCgA#2@M>)!u<0*^Fz!juT?q-=ueQ4t4YipYlQ(YC%^G5elAxqt@Co^(G7xm&A3VQFPh&PbPI+k$&>7x-!A&@Fqk_-*0X3Ugksd^WWuYB0TthjJrjjMH( z77;rLU4-7ZvCY)i$6Y#_)gYX{$({ik5~RPVWRYsG?ikc=iN1Nd=`8o{GOfOzOY+vP z;yeFvA->BdGDDZgv2stTd@2uf&0s?99&YH|fWAIK4_~+mmt2&GeSfNZ5 z4Z0$=N&2K}4anSS)L*5xT+UbH%9<-rDP|d*!%|Cl@jEqvVrU~E8&pn*V=XY_cS*g94MRzFK{H0slPTaTQ5q%{Z2hRvj=7Z(?^ zLM*XC-+!{w*g;D6#yCJT0ma5Qx$RfST);HMrSBVf7t>&=;nf}n`17})E$r-H_U`$@ z9)H^xtT(;B?fdNqFn)`I;x`;ayE8Z0p~u-pArI?*VO!geM{M_-`#TqFHz%iBazPiH z*&Z?>Z89>J^>WYprl)Obh-8^rSqlmZu2zb}&hO?8CorT3J#_$PRnb2k*>qgq02i~T z{i$KQ9DEZcABq`WSuy0fFIq{du!L-@Lg8zyf>y^#3E81#k z_>|}|VZu}PGA(ofF@VQ}_^V)X2&T*?oBsoh$)dj2K&|P**=)MMFiU-$+c~4poEi|` zI@tlkoxkbRoq zQ~wa9x7xHCdf4IdfmHxQHBM;S2xc;-SZ^_Y#sFusU9B&bROMa{JY4F=XhR2V*U!Sv z*zOJ=wGHSJ2GU=6+?7A>@IO3UhIusRgk2qfSq{Ox@^SZZZaz|cIpFs746c<@cUJ7G zg+B{<76HFSn?8L8RVs<)5*q)|ubl&T*>^t@K1ezX6(ns!$8v-x#<-RM8@hs59S8*9 zt^6=kjThw77MW#;1pM*;4jR|3o*~22K|oZIr5t=pWDv(W+_yN`;EkKov=-26pBr@z zLPArL4nUbT%xbNpK?=p6A~1~mWETH57oR17Q-PKtHqLlKOhBGb2I*gnq{r3A$}~|_ zRGS4bvX?z?u}&;KjwL8Wdt(+Y42=F}eIPW>SYt|3;Y4U93xx zmhjS(2n>d9d8h45vGTTCXU8QXej~`LkY*L!A9%YsT=O*zCh4^)bwt>K;UCIwW@`;i z0fc;nE~9v)>eT7!`@|Ja5;D&t8&L0nc}SHFMbGjccTtP(#Vc0bT$Lb!_$m!gz29Sj zGC>j!V?c?T%BIG@d;b-wE7o!CE^VF@)7QXdB|a8Rkc5BJCnsO1BWs2+0rnjBeZLaY z51!pm$ORw${coQcu#urRx=qo}cK`R6L|W>lb}`ZKp92Xq^O2FesHKwz;7fKczFaM> zZT_w{OilfO4MU~fP#jMQl6&GNS9QLovVsh13W6Iuy!XAX;*L|(;p}XiXXbP0aw;|t zp1OJ316T_bjkX$R8#A117u3WEUqF?um4?o)1^1?QuQv@@&v9)NPh%SG#;xR)7Gi?` zwi{E&Ix(O43RBMSJCkBfQo?1zd_^rkiCb3C`;|HO_>yTpdxFI<&6|b4*Me#ij(v_O zRC?wV^@f1_6Z86se-SWJbL68iDL7Q>8OB9yzU+r&bOEOu0#wC1&ONW^;oBNaHvzUk zOLjyCz!1WN3$MB6`&DrBlKN5^IC&OU>W0mTr37$7t#le_Z>xZG095v;?oLAtqo`l` z+6^LEGP#0V{jyaNZ~wD9z@0;QMumt)+#)EG7Be+S0jd9PFT8$P=K6m9ZasJxZ!_du3I_2;glD<7oWkt6M+=DO^pGpNul`e1A6DwkyMbk-)^aKE z7Jyn3Tk{waj+{HY+L((T`qF0twKCMW0l9>T zO#qYS#hsx8ZrA`L-*9}g&J*tjJ5_GK3^M@WBlo5#?8iMt#i_D#Umq`6RZso<{D;I} z_YOvgjK02E6Tn#O?@!T6tspA2s~4d!Tn}DM${4G_XZ#&0A)hwakG-o6(!-5PBf)N4 zA%%ENg^W;Tkmy%*sg}oQnt}J24~-rO|GG8UDbeV_c9WfzY-Z(ChD;3pkR2CEG0ukdw^Jck#Wc1}HIj)V6@e&I58~!f9V4Cyl9&ljbkaaJDQ#T-o^c z!mrYF%9Xx z=bHcKE9LGUDC9ujCoss4tK-49hvH{avS{6YmYOZpw=I zI;u*Zt*ngn`NCFESX_i*Kxm+N7(ZwOgnq|p4t4VNJf4^Tbur)J$^XFAK=?P<`;(W< zKpgLRNF`9x;c$O{Oe%Y?u(Q=7c4d}}T4(ukTz7oY$9)!m`+_rQH+b5Y@Q=utJ^alZ zbH*s^_{I&R6Z-{YAvfx+QpNH}B{}u4sh>{ouIHyKWpVj5#&H;h>A;mX^~U;^(z->GJekiYm-DQ`={P7On^F_j@_U)k=DCLZSH zZu2o~=k6QBhZDIgg0ST$EX4(P!}WK=^Yho;kJ}G--Izth@0s%%X^-w`+8;W0&8Fw~ zYX>p387@@2wUt`2;6=CQavB#RDy3C>1b)dh^(%)a0h+CqMEE<9@%z-ARsovSNuO3b z?RWat+}zcKRb?d{wl!{;^K`Yo!e(fW5svrPloT$$E;s3Pj@ddEyAu9Kd%S2GVPFih z8ANO)z<@Jryj$qwYsvb`^{2l_K5|ad?EV{>4oYlytS#f4eE6iF#`^IEPj^K&c1+?H zG;9r1@JN_MmpSIkDOB=De3EG_MUFt~tdGurg*9mprxC%isUW3(ZZWnt@Ik(<M}XB>nXSN9Do_8zsDPO4|={%mP=e~JyjJ8RiL(xf!Cd^md<=4G7i)8m5dN{e%IIqdGxktcr zgu56ypj-j7U&-OWn>qiPsS0%ta*a49_a2T_4q+a=wsv{FxofW3VN6j;k*urVgZsWi z`Oq8{Gp51E0Ik6X7RX7(>p7dYyEmak`MvHNaPVg4(5_V9(X(=JZd%0Fzl=4uV(3?~v^!>4Gb9*Iom zQ}^`Xb+e<{5qsf_)9aH4Wf99@pZOU3<|MlkPS%)JyU>o-1<&z6zj{aM@N_<5y~ToH zY%mgZY87tg(;~)c2w&z3uy|9*EAC1gq)y7GjwKE5&w_v!i|szIP7}*cvu9F=JyOz| z)WDA813~zf87rS=Vrl1w7LVDthHu>BwXlH1VT(IvY_!YinuxGjN%k z4h*oNtZfcAG5@G~ede5VeeMSPZlkMOPq(MUSq}Pq zK_d#RRctM-tR#<(gXr022vWbApEJ_P8yUhdaR+M^JvwiQOZlnmLr|{+ zxwL3`F6{UdYoS2+!#vdR^T850`|lqA>);lNDhFLYD=M<_F|Cq8fIRm=5PzQ^#Zy(y z;qoV1I}S#i$g{xbk&s#ANSeT6Tl=S@t-lztT!=b8h#645@)@SDk?34`54`{RS z0A=QOdTXqk^-Sun=cCzT@PF=zuc>j8{IHULOZ_65^yhdQVwUib1jh`QN-2?qCr_8B zx+>s&l85Le-ABH@n%j852OF*Eeo>AU^vAmy3i%(CxK!MBc`LQ0H-BKTn}-pDB-J6O z_AZvezn%N8dO5Jatfkbh|K|mW5=0uuLb7=0wR3D2whcjcaW#l6Qgo@?PWwkbd`e8X zL|+I}rmY%!E=3wc$Go-&0+nDGnd1aP#)R$ z8Rxe5bAOKVojCmiHY<@__}xx}=O3ypA{l@faYKI-Wtr)x<~G=OC`{E_n_|B!-V8EG1W>tnW{?VV=1C~7f-g#T{z zDQ9?f6)#ubiECC*_3 z=VN1`-us1ed(B$ikM~QfB^BYM8zCs!unQs~bIVP4#H1Oe%eOI>kJpWI?`YLwhL|9U zE$bk-)o2{5I30R)kWL{N+9jtB`O8ARYD4d9D86oex5aj+2yL5BI_$n=rJ}`C!~|og zsBtf!MMpL-E;!|3%4OoY$HB~lOYW6rvHdNm!%8P0Xi$?`ja#E1;2YWq@+J*zG&>k{ z5+z0T(?=|SnYQ_NQ)f=9@%}wXfx3fYw2P;mZ+yFpPhh9 z%L%}=J57K4>`{FBgReWp!t!BrT}N+4HZ0(Jb@~g26#e3`+q==?bz6Z~>L=Cik9~Dc zT{oGRVfS-k_m+3#hj$p8tlRby|HB&peRTKH;oUF($6sSxTlEh!-6umYiv17UpD!j8 z+xV6ywf_FcB~dr`7Pt3y<=(kbCh^vZm98IqQj{z{hcS-+bbk_ChkD>;jZ(Y{)sV4` z`sm9v?{N>22CL*$LVeu0gDgS73h6Tr4vxl=Day||%+`XoJx*yEWl%AVT@<@g@DUnL z6gj`7^93R+!CAt{_$~ZHEr5k8XPFHBMj{_KH=Gcu3{`K~(b8&Vq!ZkDzDq*z6{ z>CB>=mY@IWOi7f+KqI_8x-g>v+f*~Qg)`u z?!^VIF1By&LSq&&vkpr;uJqrenJaR8EWrM07>e) zzXQ@JgY)3$rPvQza$UiXOQ%ii{qAyKJP%i|t;LhqB^(wll&M=E9R(*8G!^Mb7avj- zs;FZB_#`>wPg@^3Lm-md7029JU2ZmM`R0MIUn(il zXwbnzy+ylk?v6Ghvskt>Vn4F!A)|^UUd)e8!$$J`y1nGMj*GA)-6;Bv1%$|dux>kb z&AS@Z+6fMfx%)NlP$gz*O#g?1nHN11^dvJJvo9gEnt!k{XQa0WMs=p?7t+ zpSzgLSBxK${5JU{-({gOL&-B_8|hX+{_!$Uig{Q-L}MFMRR0?=pU5I*1;ne$6u!>l zw#{`j^7kSH@KFNIEHzI#ZsaxA3l(jtqapyw6+i$xEkZ&tWqGhB}raFFjg zJcO+l`w?dZiR0Mi^4WOvI?AV#E3iObNvmyO{VcGI^)z+os}clO-MIwCQ`h+ZTedFl z>8o(Gq;eFr(vB!nS3eWbQM#p@Q}r%-u`PGWMhG!oUE#AGotWIIGL!}@{K#`HFqq-e zau4S50+4z{&=WO+M-z#GW#g@7Pt=I_c0}oh##<$k7#`HroDnJ8!eowz>9P+_H3ROi z;aNCPagHGe(e#%IFNtgXl#}P@2Byn6mDdC!BixPo0`1`;CmU}^+m^oQtmrITRf?E)2_+tn3FAI{1*NPF5c_CBpZX{g)Q|0*b^=*PvHD)`NBMdJPUToZmq3$1( zG)&vj=Nb3=^#O}I_kA=lw};e=&zaG?wWFgg*oW2@KYX)HGBF@zYi{IY>aQ3pD{hA= z9sR5plj|94O~@ZH|CcvpyKi+3kUW!{q%me(UR!h6zP#jQ}TH@I;K;fF{k&~2bV47r?lalYbbIB zL?1+=*uSIgcL!T&br4mG0A^L>rlkB7)SC8hwyX8=N~)+<;T6crF{sJX$`jsH%)I(` z784mr=cojtveiqmE!?Chaa3?_C3Chf)Bl|T(R~60PVt;)0_(-Z0oPgcJ~EKhVAKWO zB`dF?1GXW9(!}={q(SP*!_$x)%O>gtVKr`Ps|CR)u&USnLZX+ZH5WD2w?i2wJJCl3pbmBW* z^*k)}JCqB(JG+&;`g^No*%j;)+O&w?!@Rp8-}l4ptzw4}1<#jZ8F4qb52=+Kbz4_Z zh)<^pUytbgR?ZI*%vm0mKL&%1*-X`E-Aik+8hFmubWC-2-v6Ou0no(RW7}8>jKOWQ zy#p?;UmcoZKCLbvafVw|S*cTHKwiZ^*r8m&X@kpdl0deNF;8n_MdL!FkM(VTj@o$H zL~)p`<~rt~v9rT7$O#0;I|m*gp%b$CW&ICv>^h_su-kP%jRT#T89%T9415q~P-nuT zoRkJKHZ>;10Z{y$b`t3UJ^CuXc;8g{W zWw0{<@?(zyH>VYHxn2HqYLPyDwZY(cs7Z&5`WK+s6y7ha|ZRwg1_!5K9LTX(D!bcj0J)3cH$Q z`{Yb{0^xk@N5{Ew9PM+}kG>Tq#`L4~)T6mxsX5WGOLIQx)4X@Qo04>yD9KcwU)uXy zcxR4WCXY{9=+h$q9{?jk+`f`aIpyhU(uV1*dTkj<(K*gd({^182qMz90ReJMbOba6 z5fF~HkM#ut11QvVxtMa*aXRO^E)ZdgDaHsM0W36bp0X-9qPmS~yU@0d9ObOz6zdCP zrkrI$0EGRV9$lPY-t1H?7rA$DX{y_sy_(K3H?2R!xIXW?KIB-YLmnqNjLEyej!kQ~ z$x_OTr8k4aUYtY6Ohm=x6_3E%#hASS4 zKnghT0r~o7QZ?@>rTp;mnwj_ev0t>N7J}d0>_xO>i@E&KU-As~?$AYj zNwRLOZI{zD?{21PPEBBS)HH6M#XCM6q7PJr`?dosIi~SYX&TyhIPRzAY8Ve`<(jS! zH=7B-_S-lN&9fhFaw_B@j%7ZSu4@ig^I{c*wd=y_qJQ!H=EaNsdtbTO-Atxfia6r+ zqkele8BG1qOk*~%X`YeJQ!3+rZhN1jIp(Scc7&3AJAfACz!mjmA*NnSyyPbgWX1g87RI;QjVs`(cYZ{-jsUav7WC7`V-tWeeOWU>tc(WOu zqZHK#*RER5=o|tV8u-@Ng<*ZZ*u2_TM=L}mLSi7s-L>p?hX)tS&^SOWsCt*oO)6F+ zea#6w7Z9-uQoQrboC|$Vh~g-kybX7S)<7a%96-An5KC z4JUn*O1xCQ_4lLFuH)L11D;?7Hr@o&f+l#$6uIX{xy- zH503Sf8Eb>z7?$B?IQxXyBAv9$yoC-*Z^WFjKmZGT@xAr-H+35w_6P76@zWN{=$W( z34lmiS~lm{F}I!^%aMOU(6kE*d~>)#0wQwLH14KTXhS06_uuQPhXbN+R zrO19NpFRJ~Q!#jORMLN8MLNyhbtOv2pfqFzLS(q}R_{O!w_rgPG>GApln@%mqK0Tv zikWK3W{SiB1&QmkJr*!x3i{?^u!0jOS`oTkjD$FJUELWYKsq{BA)J(iU&rhWpnwRO9U<0}Gkfp-VNOIe zr&!%%PoFS=qN(yp9T%EFj#M2n?RWdoHd6=;7`HQ)L3_ z+O9})&O1;~E|6OgH%M01zp5gI7(KJ9fF3VjRQa|a-~h^LkRz!{-*soJWoUeGSi}H~ zketI1oB;zM`09XEHCsio_VZwvDN<;m|K1KY6!r zn|I%PcUTOMAKpXJwrL+cxOaYW7UvXWTA#0)#=UrUxmvD6m!5w5Q7R<#`n~tw6Tqj> zUS7X?l}dha|IGPFQHjVmO=vqqclGk>Fde$45fSgotE=nB`{|>PK1Id0YeMVyhiN*@ zIp!_ynyz{9;ND`fIO~6ehu)Wu`h9!v=NJbOG#uLY-Nz3O(y%} z`^?;R-PvNuxtL}I^UkG|wa8AA-Jx6|Qs1^_P{qB-B?K3|tFvy-Vg_PINehADQE^Jg zJkZmjr0t@OIiaZ`wBBD|Z5*S##m#+l)DohWNX*on{0|vG!QwPhzXS*DLU+-dN=`Ay zS#nk_xAIZM6KNa(0Dlx`8=%H>+MDHD4E0p&AmT7ARW+sj^y5#T{_rdBJ$cB^Nlta! zKy-8uM#PKt8q9wF=YIaL{k8w(AO3@X@HhYF-~7$r{LQ8bKlgJ#_ZR=-zx$v4t-sZ_ zEpb4aPhnHw9p`eCB&h))HX)P};gpLNngNOG>m_D(uIsv7%6>d7`o(tZkX6m5Y05cC zDb*34h(sl&QZYAGF#tw%&M{GyQ%*_R&@#DNuEv8JwF=kbD zp3@v97Z*G;(~-EsU_eYc<~%3w*#{=q67$ib9uXLJ<3U8d%6GZ&Cxl{2NzR1OwtB!+jdM@%%(YAEEY_#ST1gMyLgjapkf)6 zfURk~q1mX*!H)>j8ndNeC~n^f!d~Ro2JCPJIq5zudk+$J~}KGA*H_S z1G}IG!J5Ogmt4p+M?>HkrCqk;IKO;(jnFinwB@$-QtZb*_}cfr_YpfTSsgoKvSi(= zE22Z+T*A&dAI{pdiw?0z5Cj~@nLTzxqoOyPvG2o!hpRlo_4T$J0y{q}`o3?jH(T#` zSaj?t&iTn#?{BZhILUq=r&0F1x$m39J}#DBO0nWONPKoa#B_7EUcP*}DW#+|UEIGQ zW-Ye89&^gxQP=t=1OR&QV0p7kfVjUI7prb{=KBV(#k|5a7st##SjnooKg{hA=EL^< zY#2Juf=cf4^`YiWc8lISYr6od!&#r_$fn%7lx=@KPO;2WHdQg`7EMlc@v!v@h}1Me zN&PPk=gAY=eSIZG9GPA*}3C>h1uZECRbJGI0HcI+p6a#A~cW!P4i}}&%_8+ zN3WT>vUihlmZJUR#l303xMw^JB?+`qT)qdNs+9z!K_73BcGP9px96wZd80_e1br zCC3=weRLMQkGc2|hDARN10j@of-(o^`o8P?mH zBW9&Y4FYMquI)MiSOcnoh~!cjNmWg)ZCd(*BIM3<)@oCC`pcR!d0cc)RgL>m@W|cc zSeNKAGqD0P0ANy7?3iANaLZP>%cTK0?p)NY>H8`pRw{weXo8<+h2tQ%BBo}Z$-qic04t&bR-|_8EBFJ!`@V0G zPz4dedm_h1zVAX2H4w9e*rDS;^tJcD^S!5<^ADeXG^!4L?|joVp%O7`klQ?uB^AH& zK6tBZJYj9;mt2sLT1sP-+TlWsphqzQfRrp!h?pqYF#>{`JA91#QIKKl+bPWeK*)Cz z8UO&8E7AHm08*T~Ce%zJJ7J|rXa-ePa+~#nV4%XxHA?*GyHGc0aKxP|6$}9?U6T;? z^v#G0$fyut04_L2Kw@&v zdlypS(>PZ%ECy;)^=r$1FfbxElil_zxVv2x0D$1#`fPEwTJ+scbkgE~`CtDfANu?E z&fk0Qy?^|h|M=DG%{vb+Ytyqb>IA{uRHIT%VkA@`o4=X-do@MKmOTo zeg6l)H^-R}eA7((L&*iWxw~-PHVBx&2ojN17pJ5iHey7 z6ad5&0h-X5;q^@>cB+bqL`+0oGvtzr77&^>N545jmxDy%|r=B)D9))0BK0Qi|Pj zNHMZ=%s@mXmy*jg&B1f<_01uB4@i=dNFgF}SVVI%?}BJyKH7Z(f;TKtjx-Y0wrN7+ zh@fQko}1RILdp^vFQU^Jo6fPvLrh&07H6x^Uu~FR8uP^(9$u`Tef|ot?6-N`=f%>i zsq@U4Lg3vdO)+^6u5r(vAErb3`cK^Z*6+Ni*#^P0sEkwU)w-@R(oi$rREoz~DS1Afld~1ugR6$$cpzIi(bv zzT3Rsno+-8#Z(@4!*(;?f4Exqy{aSNP2*I7 znS*zW$HRWNEoD0_7VRdUt%g#dNOnXq&WGI;eDmV->wf4Fjh$~>7vq5$Qz~cc&Us(v zSW>?C@LWZ~fJ~&|aM4westNv+r?0l#u^+md>uqS-rt$sI$HTl_ z^i2z|UZyASFRm{4{i0=WCFj?#4>@bfwpcWW!{me8Z1zpxp5I%P6u5U6W>waP$5QCqJD74wbr!FA53<1}eG${bVU*%6J0+;-0U z(6(+)IRr9-eB8GkCjwE`J65gioRm_FnVeFcSRHba;@GuK3jhSjNY#3)+CY`!(b5sh7 zigUhLxm6M)9Z?1Vs04CEyww)hiCI;ShK48ZLDrITsX$gm6A+<#)ZQs(Zkw(E0Nw@X z&^brMo*W?+O^zDpT-&tM97W-Ly=XkQO=xlvWI`mOw(%~&VzF2*7EKe(w3KXMZP#{P zYvjy8RL1>SQtp~&wH&f&it`t@1c>#7mB0q_cKLEw-FoDDoq!pHFE41dsv$zGVw*a} zs2bWWElsjiDbA$iuwo;iwYE_NBRf9y|Jwrz@QZA+x>VklF;JDGhzLU9Y6rBM%p8M3 z5zM5Br1Tc6XSM2=%f4o=0vrRRRjr6-IljlDs%qsZm{BAvxx|=C&H&)uu@XSg5Za<( zB5c@q)yTm_Rf{c`{jzVEnLzj3?fx)<_s?Elk#k@rcvstJ!~lj}7h>7pzkjdyYde`5 z1DuFhdeo`soIU$eOAACK3SE$~90OIW3 z32b1*bR=&nEQd}+kI@ze0G6|qqSckrv8%)A76DdO5wUD`YxRCI$E$Eqt!Ax&nmFI& zT$-*4&Sio9=GrsfTQ9%*{zCw|+8jy|C_w=d00J!9K9+HPw)BpgrcJtCx4nq~on%!i zNUU``qejeD>3oPO9ZlzMkD>x5AQ{+$8auwZ*(?_KYq5qk@8WKhyP6bH1p{OvCh`HX zri+?G!(;FK?eC>+o7J-GTfV*#@7-sgezLyzXfd?k{?@lwtL4K7_pyx2hmS9xKMPHJ zh_9w;iVEJl?G(E(z317>7ky$Vi+oA*JM+aCLR<9504$xm-*!-fXV6+fCQ?O=x^@4IuiBOwwy{rx&S2mne1-uu4q z35k#nheI8Y^_;2*r^)pAGXMZUaEcYjKj1^~|tV8y`wKKEU(!MO$? zJ^kd_%gfDA{ZuGpB(|>xJrr-Ll z-}?1m|Mg$})nENL|J0xQwZHwhzw@1c`BOjj)3=oj5i%Y@5;MzM$=%@T%{>1FZt7;U z0RTc`cBUp$-socuYR^S)Qwp$2W!HqIN2*q+wR@RGnOsb%Y696g0&<8@vZ{)da{C3| z>U5ps<*H>zrsmkqyPYA3a197Mk)jol*s*sGz>fJFW|9kfCdQ_5DuzJH$;X!f03ZNK zL_t)j=$$7b5hcB5`66qpUA_?+X%(Sd68b&`Z{?5A3lNF*8y7{PHyrMoFRZ zm9>IIfH03`b4qFTjAGf4&9Ld72%AB1i!=L<45@p4dAe zkSxrkWSa5tOr>})U`ce{BQy2a4nY{t#yP1`mbnvlQ+-?=`t zo}idQin`g3yKSDMwXKVz1Hhd2!E?U|h@2zL(;UmVxtf~b9J7>iwqA6tD@BP5A{EgP zyh>&w-}s#4db$4m<&_x{QP*+Fg%G#9aaeROUv8NA{=;QAv?=9roY(8sJf&QUV`>{W z^h3^hxfoQH$%V$nIX9g@?53}O^~tv`w@eHU;v5~@y$7r9^=`RZ4uki>U%%QjrC}K^ zUu?%IE|;B%UcR_IJ3pJJ*bU2R%=a&r?A>U z#?*Db9m4W#VI|IoJWkoT*>1*Un2Ys8D=`u~AD9SzXdL9CN=)9n^;xHeP;8pVoUC6o z=%8!EVa{FW89B{)62V+@W+Om0QzfI43wtKOp$}l#H4TvYz85Xd8NX}Y9KkaAg+7k^o?yp>2FsrbNlXwTH-z zks;f$eUbpcQ(y+PlEvg!#fZSnc>C)NDpm_FR~-vf!-NFsBs+ ziIQb^3MmHw#~i$K>>T@(XMi+~8-~89j&od{tsmSwUktsPc8!~h#iFW8h`#9;!(!;W z;C(ESJ*g_7A_9j7iBn21KYzJeEQ5Ee&d(`dtCUpi=+{(DMOE<8wxbR@x= z8Za8; z6dZtvZ3yL#6_}{9bK#h=TCIOQfD#EC6hf`CL&>)T7!l9bi%0KVjJvUvGS4&CbP*<1 zEvGVunavalBrB33Y4wn-M6b5-ZSV-F#o8W&>j5xlsg!|SWYsl}`D`%+@7Uqy>U!Ld zhr^Ugv78HfnUk8$$=D(Kun5?A_P(FydC{F2pm+Y{7ktDhDlfYFebF5)1e!4t8cNPu z3L!OJ+xLw~A;On0FW2j{>JnRD0G_=6)YRm7COje-$E}p8h?b(5qj6S7an7BhCoSa^ znjpq-iVU}t%>X0arT&Ww6BX6tc?|%80)ax7TyLZ@VU~-4&ByNwq*dv*d=F!#sccdmoB{h;DWV zP{|41S;lHY%FZFtj3yfH4&TP&q-DUo0@(nLZlA4h zQw^J9HZ$iN1DM%~6tfETD1cRut1ln5O1ylvKbB2DnojWle3(HNK>nh|r5T)ZbTI_q zwe99+^WjHNzw+MuPu{t&SC`}%zzD0EJD35Ob#2qN&5wWm>%aDQ{?2dw#&3N5^l8_1 zhr{7N{p)}Izxum>_qV_G?LYX z2q7NV4aCYTdn2So0t%m9UVi2AJGW0Li`E`l-CzhHHw*yIswK1hXjCz!vb~x5p_%41 zEZWx7IOjQ~wr>G}kWxv`Ga#@d?|o6#QjpmIrfJlDIa{BxV>6BO-1cpq_;Sigq(fvz z;!{^i%nyNm3y_&GXT8~sbIi=>z3ckmJtIQO%^Xw8*$1z&Fd-4X+Ux>*Gz5Yi#Rs0| zvfroR(Xn$%p=+mITnwRq5JKP-<=Lk5x+@MWu*HR>XO|>Y1=@ zLW+gas0}Gb=bac{AI9~f^UPwhS~dG!+VAGWJ|bF9z}~u^ZXFxdB&QM_$2n?F-f`Q7 zc^-iSf;FvE1wuMox34d^`+LjKT0b;u#d`(|!!TUExK1&tVku+ag(vSmdiLqFl(Gwc zwd|UJ!4sH%=U;yE_?@#j=ZB9jx_*%At&(6^3^~3Yr)e0voJ*Y3auJrx<}k*T({kCL zpZA;1VVqOnvy`~qZMrV_5ZaDJq=?M1AmBWgd-vC-Vx~+uPjOiEH8rB|1E4Jy-C-O{ zE+K?*A43D{ivY zrcB_2mm>K3<-xE`Ngltm9_PYY0QCC$rj$Zt%kx!9rHpg*!FgAki^C8?aNBK~rqqnC zUv%vItIMffg>gHNvxLrh&lmSsn^!kA7!b6W>1My_+Rig;U=g~xo*rB*$Z-=w9253j ziXubK#Z&?DdJ~(*kwYuy8Z%K4OR@OIHv#8E^xlnA92TveR>zq2=JkzZFKR^u5rc20 zl8{`I7&@1VOi9cjz|o=DYVi4S&w-8|2uPJn-kAjz6clsLwO8ucRgQN(2$2gEP=Fbr zg(J=*hE<+ikPdI8If|)ip*4{^3k8VCZhue zbO_)bH^F=M%x^7AA$Z4pv)`-P#r^ZXJGye&QD={4P!RAG;U|*O1hC3l(1lR@=kqv= zs`q?;wu0Krkpe(9L%?5=|^@L-&(`!x(IZ;Ulgc$gIHNJrfO0I5s3MXC70c@ zvq4YvgW7sD#SG~1mIaO#UZ7he?K=k&5*)L}>hM@BhZ;!byg#n?Z~v?9Zuj8)oVbE( zSUXB)C~8quPIp%%AHy7(nkIP92GI6xno}Lv$K*{r@}<15_FGs)isqwt7D6srMZs** zwJDbnT*<16%b`6#Tkj7eA$sSUHXvZmWf4)OB6gH4L*O@DytSW@wg6Rev$F+8fgk5p#~KX~sCGFVjy=fr(6onNo}dprTA{ zPKdNr&)4VY{jl6zzb=-XM^SDp&B@`b3`OLnrdwrF=H{%>d|?GaF3|*6h~DNk;~Vc?>_ysYuhQNsuwdg zmAq*EyHDQ8>-r@!*Sk1dz0rfKWq^8fqz_~Vc7UEF*4=-y9!?Q4ha=IZrKh~(V$ zv?b@D25RbYR#k#K6Qm&^oRVRg+0{f>)7yLc!cj-pkGu>sJyF+Ck5%l^7NzdU?F5!8 z2>-q(v2lE(8^j};dL;CI;aa}%Z>z&kPBS99J8H?>e;z(%%AzQe|DOt7~}fvoY0!) zSjhlbb$e%HX3kk+{E;Bimp(eMm|{#3(M$`R`j3DpBBE07mx$VSeR1*5eAwRJU4`q5 zl;Fd%U&1N1+0_*7yJo3hIJP&l2y}}8016NskNYH)TpNffG`?g*s>Vb))RSg&dkmq>6K|NIVW({&<1ZSu#}RTvU7{okOa~^BT^|+1e(r^2vWs5X|)_;%%#Zv z^C89r(4|xkQ&hDO*py6h++_sB#0ct;UF+A5kC2?_Ds{TK*^>|RRMzW21c#mGR6M(y zfe`1ir+K~V&(4>srUuS=Gc83N03zh9DJD~Sd3p2BI~SLiTLb93W}YLGi51VJ25Qm; z=Nz_O6AvkPpK_97kKcVK#ZvT`wQNlDEcfo8nZfHv)wlRaD z=f%Rmc=2qxYQOXCn>5S%UO)8yX0tsz>mNTlANp=}Mk%HBeSP&@ZmwsA{Lv3yraZs< z{yiz>{-gEgYHx=7!wiP1+IL|X-1Ut)N1UoFWolzP##(9+8^1dGv5~eZ9+3Zf-V*{j|N3>PUF+-WeFohZsCB zSM7S$-8<_(`smeu%tIfBHVl22i@n|)z@YD&erQ#N9G_h*;xvVJxO%l+UG&3h0J9SF z=a(CST@xBIOj$}1Ga!PtYf6!6jMJF9vwrh>tWv*9L^>R%(6v4wsF|3Qd1x1=f&|DQ z1wzYRACzd(^Jw5b{(2jo<9Ui&WG<0><60M|GW31QvOH%ZU{6gOOf;q9MH?Ty zV=$iPX`biBvSmlh-~b?}LI64IYSoGrsM!&3H#6?;JCE{*YQA&|yEHS$top^x@$DJR zj1Zl7rluOr8a2&DY8&28g#J1g1H#=1Eh4X~s=!Vp0W&)?s1isp)ohvxz|`!tUDpt_ z6etGdP-j4@W^06;iV`Z63}BRxnP@p{oQtZBkh(TB-XUNqMugrUx7|$Cw@vNbn5ih& zsmo3Rk}Oh0fI-2ENg(#FGC|(<;YIAa);YJi*}T5GdH=m9bh1g9rj!++N_P;Am>Jd7 znRu{b3Tj2|*lGr->S`kFx()y~+iejAWcGI#n7VsD_M*X6K7*co58hnW-T&Tho9Kk< zARq`+&jGjs?%-jv_xEY^6fA#$H*Hg6|a3OFg zhWTVgDk_I@5-lolw(1C(eAtgObN}SscL}L!8ba7^Z??Og6gi9s0NCw!l@0Rf!NVUs z{n&DR^zM_KGKe*e@7mxU5g}6;r?F`p05I{nh+uKx&HU;8zTucv1+oE%T29r)2)dR4 zYP;ds_^jkohfO&FL?Hxb4j~*}%kBVyYH)XNbjnjXrrR-dF1c-5RaFr%C1YQS`0n^y zr>^aBFxQ2cDkcM@vY)%`HVxO?&0`#<@U1n5kZ zeJLeNHnm09w81~TSOH-!Y5*5NqTB~_=n#x>Q43(lE*2F*G>|Mz$b_OMqUZ>b**VRb z>FqYXp{jv`q5|mIa+yC5tR|d|hab`9#0${&dJwjZr&-eTNr_Y}i zDGX|+jdO2ILx*OjdH%W9~AbYdX*(IRf#mIxFVr9DVh@2bY`IFR!NC z2UT)991hb&@Qzk#W=ru zy+MQ*m#_ERErG1p%cg0vl+c7Z6-2%rr2uc$C#0ZRODZ$YbyQb4Ma%D7$^5@5x`?;} z#Q@-#2ua?$g8vUk+k|0gLI|&~Zc=^=JVZnyr&{2&lq`o~dvgUQMEoT`9)OzA_(na3 z%)H%=`@_rceDC}B*Nfe5zBnJ=fFGy({o0Rx@NfUQKl4BQ!~fa2|BJFW`>`ZT@58?3 zED>?HT&t_Pd!~C9HZ6)n5~c-sEW?&WQnV?{&-RP|1o1^QAiv4hoBUuH<{uy!kY8j& zgiP3g1sJd-lkg&PL{Z#kdS-g5Ju~kf5$Bxm`}}a?W@YvCjNns1Rc0YG?!6Ib`Ig_} z|N4LY*Z;#``?YU<>sy=k`Zs^`H*?M(e)s_(#^Ai;N~tnaM5d_`%qhJk=u%4@(cxI$ zx*=u;s6*PHvOywbLKKtxkOL9DWADgRoB3+kuK_@zrrXZUqK|5m8l-_av4Ri%B>(_G z0g6C4J;&o=6p^;`*7!c>Sr^p6N-^LVy-Ef&X0F{iRUL<69EK1)1jo$dFjlS)5{inU zHeKV`-K=l=KB<@s?%sVYk9m8y15oF^Da_`rb6BhZg7>Z;MoB`5^I2h z&znHbJ0cY&;->Y8m{V@MCImn9LmKVw^}M;q_SFegFLR?d$97W%NN(Nn=KKi&gjO_g^s>N9R2v zV07_#%vaa*7f*LNWp?zl|K?YmXZxe{>TWx0Vp0A4`@2%`_U1750|ICkK5Sv-k z#70eqG>Rl3Sg(&nrXs;N-qXwH>$b(kq8Y|Kj-Y@cG&ZAB*8T9$o*j0j@hYO;JLf};f!WsUeK(6DrRn0; zqt(srp=4QHx80*~I1HaW&BLK@VrM2P$@l*3GgZ4dpI@J^_zcKk*zRKVOd%lOyjVYZ z?@>Dsvqd}{5*T!CzPmXz(e2mAVaPpW8VV5;kc`RCn^_x+lu`gmfy4xXNlQ+KNhGV8 z!qaEB-K+_Yp`)BeCV2X6-ObupFSdu>5F&S7Sf0$&PwM?&C#JpqC zQi{%I3!=b``^_#yH-dTZ+|+r%#yJG2z7RwxB9){Ir=Gluk}5IRVrorMj2RJAH4Fhb z!KmtXg(9LN#1xt!Swt0p@+jFR$CZjpMx0hL0yNDVhjJvyHa1hMq#{zlI~cQyq>45+ z11$oMYh@QonTRY>fSc2HVxEzZvO?3LSzlq>+?9ec;bSPbw~>9|h;>Zn}1BH|pV zYNd@DfSKK6lK`NYw&KP?`Zp`6A(B7r_W%$BhA>H! z%L#npoMU#1T=AtjXCjJCQyXzOdCA=OdEQ1aA_0JuT&HF?>$cmi^9})X&UF*0{s-Q1 z1^qCSs?;zP2@s9Qre3A00uZrkg~d-;kvc>LPbz1oMns^BL3mb zs%j>TOw2=>z(rlx4QW^|mk3CX!60~7M2Oz#%hmj?3i=T{4|;iVW?6Dk?mG>${cIj0aCm;|`nw;puOdQ|~Xq`*Y$#ja_f zs+=QToGp;+6nyA~>cJ37s+;B{OUT|K5-~H~&!^*XeERam{x}i=0*Hc^T*lrrn%ZtR zJi0uWWEYp`Z{;v`o{yu|j)oL12{c!>Qz=D6Q<2Y}z4*=_{PD3LOzpeh|Adf;pdXWH zd3<$|$Fc1iAAA{fOc_r2*3%@1FYItCnp5`d)0onjDqx#{thOEB9u+M)ee)xTB?IfF zS5;zCz*Hn3kJXlrYpL(S1?6q36+O^XM&?u5Dd$`+&L8KJhha=9zqR=zA^DTrtX!Ne zQp#4DOYjCw_Y+2pex>cxSGP}Jy#DU@fB3V1{-eX@&ZgE!HEA(KP(UUMA^ewr=kI*` z+u#2F#~=UKfA{bHk2AAR$iMU=pz_hk|etxa16GX$N@jL0OjDwLvG zs)FU)paVjfTx+M3k(ro$D&sH?<-T|~^_no{F<`Sgzh2+IQbos(iHJD((2spR9SqD( z?*#BZWFZ0q2nh`>xf`dWoz=HWOv z=ORaT-1mJc#dH7yMKdtbayFl#^W%_)emK86N5YbeDlS(u;_A{?`hLu%5D_585FB&c z#N#jwLr%HWXU~qo(9C@B44M=qI$u~asTCkBSyc4qWj~o-H=J`BvRD?)AX(a3WWvyR zB9u~1GYnZ(bR5SJLZDDNYFCf0zx$`3Jb7{+o0!MawDJ1g%Q20+{;=QnOuRauA;9r? zjH|X?cp{bR--=qwu$*-?gMJid&UqxF`LcQb?B>xstLM*O--h5gd+&<$L%*Ld zI_ui5(u30=K;RlGSyc72@4slf(9GIZQIS0FS~EpZCVcOMb1CKZO9;XF;F!oey1U)= z;~1kyR3h^};Fu8=$Wkso@-XBW@#U*S*L8$d8atFCM1X*+^F>aj?}wZvHeO0`zRG1{ zj6R0IE_U-Mh{JB!Z;m;YVa#m|F){+Au`HIWQp)joJiF+SAp}15B{pF;Z`#HgsB`Q+ zHNo|J^$rlpg+>jx+hf-?rAqq+|Mc0-H@^06?t9J3&L4LD<>kB-X*y_{kj4-jCt~ZH z!)`M+F__^{)CB{BDn;zbb<3DjHUU6I> z<92<}Tn$F5v^l7ns-|HKO<>0vW^PEmWNDmpwXCa(25l3Nc+~{}7?O!jzoiEBBb&904Y#aPtRyX2&5B@PR}};i zp`o{IHBP4oI^gJIY$6!+`(3wOdB=Ho2R>%>DP>>}z*T7``pKJzrh*}!vIYcz5d1pl zA&ohwKl%R0O^7dEz4E>dp;I+tG|_s(P6wG*UAVUjz4tJNQ^Y^DUw#63+6+|0Dh><* zCt#LL49B8RsN>UmX%@@_GkAVw7wE4nYkB zKuxTONKq-JD1i6g`H;sU&le4NuC4oFOr;b=h@O3LvqhIT_vBGi)vj%4i*86G05HNR zDq6-oMDR>>zB(UL4(;3#ru~)-&S(6CXE%TLy=PCK-`=eE20?;u?3pMy zS49g%%65BHBQskqS65e8U&1Cr0&;`|K#ZtTKKS4(X148z_f||kj5#YSf##ex+hVGv zq?A+0fqe%ClBH5O*iYhf(}Dj$?pRILbR0&;6x_57t6I)5fcHLxa8d-mU$9hFB~BHO zO4=v;5wJ?la&oF-Ym~+$A~D2LN~ug91VB)m1SBfMyrCli03ZNKL_t(18BTE`AplfI z2(DFiQ$@y#J**WJRRcrkJUi!{XLdD@K20zHvtc-T=P%D5tyW8zbS$v?(mCgY^8k=@ z_JjaRE?lgdoO97qq|BPxG_gghm1jk=)ek!CkA&DZK?x_wA|fMB?&$&oQmRcb0ugIT zsUMI1*v;qcJtH2+0RfPzv(rgCgdF?E0h!8vyLso))$(kXQ^}5oaV#o<$;?tp0N|Vl zEjA9dBX&5ZoKqSz0HBg5fBRy?xK-d|4~Ii<=FDI=7N-u%?pzp7;* zD^Q!RC;d1rQpO~?n3;-{+?!@F)zY`IL4&*X{^hINkALvl-Q5}xbI#0cV5y|Q{Q2k4 zF3y(DF$LEU&X@DUVbnKW;0X`+;7&}kC_1SI-?PjS?2FMh05JP66c`>Bp&nep%s|ah z#YDgWzRXzW;drnX?Lku=y>quW8v`4MA2r#mzcVEs+x`B{TQkTtBl(GaAOtL`G5F^% zUcGv9_4?-K(fPbcsrVECph^I9?t>5B$A1dH^$-8y|M2(!{_p>!>nx7TOOtMl{!XMN`p%rN-qm@5l6hES7EcmMgdrtSvLApnY+XGE;Q znWZ7S$dBJWd--hBAJVMx-7+Ww)h>5%fLIflQUJ`lS?5mWTSPn_k3Ra?#t?kI$tfjO zNQ31;v;cczgzH6IBOD!zNE4dcqA}B18*(Y8zK9Z048D|-a*n|RSd5_`i>VRQ@i+!^ zZ4(hOmy(&Z=&;-R`6{|71rk4H3~WMSJu7ZocTe=McOKZ8rO^jTL!Mgu|HT ztBxI$V+!uD9dgpKx3+UcW?(6owhIW_bH+x_`! zrl7m+usmxwn_g8-V6<}V)12t*Uw?OVH!!gRf}^$#{c*&?n`1x!N}El)vvzy4U7dIP zLmGx$OXaDM_s+89tcDfQss*}Mrc==#w2BcL3PLui5z;jrK5 zB%ZPFOJp9$QY}Y^eqdrk$RZdhI*RPVENr)f^HdB=5jDtT&PlB@wT~Jbzq{+*!p&k_ z&6~w6N|r;PyRJnAD{5*AN<>J23bo8>X1SE$-J8G^v1>ii1bt59c<-)Kw17@qUKY(o zbLl7L7MLg^B2p_JW>yRRV@hU)PEj&3)gHH~mQ*V7qi!J&>b?jHwa^Y#{?*JR0~l7D zF#{qCJ|dxa!Lb9dQnFLHJ7_zfl`fqIz9}d= zoXUndjU`p0g5YFn1l}V%HnSo{?je#VN*E)0?}l-N>T2(OjoFX;$(_v+09v1pG0nsv zgs|K12#IIQBsLUyb$j=xKYZ~=AAcrU4WJk)HA#SSVJ0xiS-_!^AwelZM60t^*Ugeb zjPbz@G=xd?4ZxI~8CJV7B67YN#^Ix{JUSHHy!^BYj=f(k8c7MgSApHWS1HTo#QpW2 z%{Vp<*7gPv0t&t*c44M{-%HBDS2wC@RNWwEZenA^TBd2>oTEyVVZO&b)~EM2vJ3zK z3Ds;I$DA`El~NF}+9VhlO#M`a6S3MQekw{tU<(D?MDXU zYX5gXGw1WLKgP4`Yv&w#4*-N%iV%Y88~4@8rc=#w_Kpfrm5-|}BSdu04K~2Z^Q|_l z`$K;`_Oq^QnqX$*n0EbmdrTEh_HcOTf+uD-U(92OK12WzGf(WC3(mcvw$++15|WGF z!)o>3lXsl+NVwUKhr_lXhIV%T^6rkwY0j@Vd&pvDdAt9ofB0wL{tLhGJOB6ZPxl|u zdmn=LuKsZ!eE1=PE$QsTuYG7{U;WDa0BELP{pweUsJhz`QEkTNXQPUwlBfGQwXr4- z@j9l4JXmeogD418II4gcPX8~eL@c63lu(Ghoz}QM=o_o5_x{bSGI;2a`;8Aic<=FJ zLvFja_B_Y2%xA5t9(Kp;tCeGB$e;Y#p9UXPvg9~wN z3VN)dquQZT(?iJ-pw_U*VVtk#ss$TianJn%9uBovKBZUk*RgGynj0jZJO- z2djo1+GI5N;KBxW(lwNQj|oba6weu{_>{m}RQPpDqqzhWs;-LC49qWWXh z5gzUWgn%Y0PhY%#d9!}{^!YFR!Y_aR!;j6ZruX-SvnIwr_t7{1*+2Ow=VxdC(XamM zU--pe1cFlX|M|PW`+xnv|GbDWGCTS!|K4Bx>2H36ehdI_f{P(~rZJb41z6SJGgrXLO}YKGp$K9|pLUU*M|NCkp-0Gvw>Cm(G9aB$kAR6zy6 zzsF9>gH{faZ?S`Hc6fG~GzqovSe%K!_-dVkR@#?+zuRs3o)A!$hwB8QR zJ3xp{JM;(NFfq>BAgZYpQ(dguexq4!-gKemn`fK-T>*gEtlMqu!=JkN{D(KDu(|2Y zV782gP^7fMXUWShF6Qm)m-+U#-|r7sSF8DwRa?>0&D!-WaregeZ+xQrK*F{y>Y=_~dzr8)0>h9YOyQXOwqY~#&VBgxM@97ftPJC@-5z}K>urC2u{b;HZeARk z^LbexF;C*8Vr4#SwMa7$DNFDHfSZPU6;L2gp32$oEBxk|B;)d00*RXrYiQ&{*8eBABRW<9jg^?iE(`W%3XFsGs>Kq}rs%buBt zRRAAB;J!^240Q6eKtr8cwq_tI%#4NxlO{4F)k7$kS{R!)P3A1(PhVHFLOCXpJTh0v z_{4Iq(Wa=C%Er-2!jh%awG+6W`&yS}o95?G(^Ujypcc0#qXwEXK7E!r6 zzc#ZmO*#-VCieWW6?1yu2q2DUvo;1#g!Nn%)i(;f1mF=&rR1z93^WrshhyJ+KLzP( zYGBnXJC~xWj=7|KPoW_q1SqOa*F4~qh^qK7Cql-!+3wnArUt4qj$i0C+0;n~4ZJa^$92aZ*Kd&e2r-KTQB)$LyH0OuI)duJ@T@+qBG%IRR9) z;~ER5oGNdJh*D1ewE0wA*_cNLR#np}9PhfWNMU9$WkOSi<$N)p4Z~;#{V?{q2w~es z@87Hx1eiBIdIkU=eBU2K46$kJ#~gC1hE7%W-cB+7RF7b1D!cu@UAHNz2>CF3{d${H zG=nkshy87EVY55FyxIT!w|@FR{ZD?Ooh|LKiDx75B-q{?@RwBmvU0BsJjXR*66D)90OxuJb}lGO^GW^OV7qEi0Bvr z5)g|`5QCa1P89|fAcxhX79ba8f_v^<6C*P>F|HO1AvDC}p>G|N>O8jXqEX3@ADz|D zq*(!AIEnezF^jXY3?9H#(^$5B)y1pVum7k2`5%4q+2>bh=bt`%`YXTk z%fI$(e@#UG$A9n-{`ddmpE<`Lee)Y{y)%OeD~$jM4vDZD)S5wc51xR0Sp*S?*pTXJ zMSu!MNX+bg5S4KpNwIB%8iL}ii+AhYS=Rw%7ud(v4KB+h;_M#24=`YdE_f;$BIhJE zMp<2Si)F)vn_XXXGGZs%duY2T5Mel^KIPCf5Z z^-{8`TGNFXLleSb$oqcGMdr)dVSn(!bu$Mj^;9FG?e5UFvAVyPBAIGWSyT~#nyz6Y zQ%j|^A>6KaIU$kkVK-}A0vU(>Va)5zs0NOmNkK$*q-tqQQlx3f47*u~UEFT_L!XX^ z@#=cXM3Mx+O3o=K$z`|KqU#XC*FJm~iHNZ4=0iWK>Sfz4mb0_-+2Un$d%HHHwrff* z!||w^FhmAav6A)re4ex9LD}&vhOa!i{@$lgD}B=dUOe5H!K-ImGBOlZK!OlG5*!bG z$#Q8gX?51zy*@P20f4CNH)CvE$+1W7EXh zqN}R&o9)(Q7F*Ab56ATU`L4>|BZ6w#?}wY4{nh1MvbL>fruF)8JY*Gfp0r5eNydtu z`}7AlUDvK}j|zJIWbOlR_s8*&S7$T1)y;l5yYLrRtG>_eOj1sLKRQQJtYqi&}r^fW7KK$Mb(KzWq)W;B+j^KsS;w}U1NOpC6)>$8sp3NPn zmw$pSAz~^@#C)rDOu}AyiXZwt*mwGO1UQLr@a+ z?BIm8HRlSQvN*1_Mt-BdS~tpjv8k@>mdoY-u-mLR{n*c!b40q^9aoPQ5< zRu7W5+6xFECSaCNK*y%>v)1RLAx04)ARA*%4&2}LF-!F9yc01Ih+TKTB}&TP`;jsc5>zMn zQ-J`0temY@xfEt<8aIrxj6Uc5o$ve$Fe^ps3$$JPGGi`C`%`Pn;} z-aHEcFw%-*`;x_lU+4-z^s(!@5L*i@n24xpoBK4Tj#4rb5)cAr%|#0t zV|^|Ob!4X!b8`mI@y>R5lklHoSK1_R7{=v+Vep~qFgc{IPV3qZJWb-6Pz=J z(tOW=Ny+)QNxo508qVr=aCO_9Lr41 zd5@SLvo}QrX1)rQBEr9HJJf2Q+?B!F%?4s zu5BJhX3+fLM85CF*GGyE3sQ*mmR>oY?lw8Fduz<8Zt~`GlLWjXehKLMe$=B10jgdi zngQx@NKaqnKlzi7zxL?SH-G9w=Saj<)G;wxP2G{mHF2}s{GJ{^)Q1#(#c$bMx%kv%m4{zy4qS?Z5r||KeZ%)Hl9Bu~2#QeP>GRfhFoJh% zRq<9tPiO*BK&I+<302ibDfrOE*0c~B7^&KD9HnT8KKS6g`}Eb#SKqmwujb8cHXMeV z*Ec#U6Sz~U6^OulG=QdcZR4TX>vSj}(YbNVP4S~@KV%U-Tlp$;$xK5cGgzFjoV!2m zS~WHamaT!2j{6C)oGBD6#$*DQg}F~BsrUkW4OKB%;qyJx>(K}do`^9 zz9xDw^^Vmn=Q8fIa|kMC#*UFObioIv0DyLOy}$w@z<>_f5#=JsV<9vmn$H{WT@_Jf zLS_QflF^5dv&@(bQN)-@0hl<3IE+K!&`Y0lb}kguaZIR(* zR+37V5P8gr3C3cr>2bgP=11@EkGru?yW8Hm#>M8HCoU%oA>91%rrXV&BVs5i$0joQ zlI3vhOVZGgbG+zg=kapB=*Dr|bpH0P3gQD8be$(}P3yk);e`+Jok!OYl7NC^WM!LGX9*cBMeDQLP1oL@&@y^A5 zcMOe>!QH;vFVEW$XNc-J{R50)PFo;7CK}o29gtWOk5K+o{ zx6NR1*dNqj$*UNlp>{j$edMn7`<*);Q_2WA=P@4-<1l1EAac)N@6RviszwZtu2yEI z>bINYSYX%ayXUSy7d>SN?`gv@Fcg*~3b1Z4}r@Cg{8SgDbE2%)i6pR49_p8;aZM&P>*L~_k z2(`)c&Xe~x{b1D?1Q8G!(K~ii=l*0rZwLmAmWDnTDLEk;V6MeKVmMo#y>*@-JPb$P zK6So`2ZK{@hne+38ur%j)WD8Fs;M#({J2c!!H6*o1w_pePIWPx0>K*D5wV(Ft}gFi zr3ntyG3mPBE<-i`gNG?iy^d$drS#+IosZF1mX29@m|ROysLnG)F@z>Y=a?NA5i8)M z2Lg|ZS{RjrH-i{_N?Ao2P+*cM7{{?c4u|~_0J3HSW9N_?&x}lWyG=tOr*z!!z>Go+ zf!}>{?W14cu1)RbdMBa?1lf*=r9g1Fs*f)TBr}+&7=&e zG;Q#Xfdq8ACLxG|<f7q6aZ20aXU3a z2LN;krdh;vQhLuKDVHi|Uvg2?aU6pWK7=8cJf;j_W^MB(Ma;!Sa7A$+&9!fcW!P1n;p~LOwuw2ZKhkiC|ODcpQZ>Fj}_+cV~zVB<2 zU|>j)as~t+gEyIwvXv-a7iPW4>5C8p0I1>p)U1%a)7@bJxHmE}k%xuFn%=y59B*4Q zK_yb2`t#(xneFxm7n_+0+X8M|F2;N;5i(09L99>a{a?+uipRgD~oPX z#yhV05VMFSGgTY<;~#zZ<7dxb{*7P%^`HB>pZmSv`@JVm-tGJTzxZ2!YrS6o&ENQq zU;5=={_p?Z-@CnCUtON7!Rce6Wrb5FqbD%9s38J_mO9B0Yi|}1m?pykHK+ncr5sgC zDFuwoD5d11&$&!iW!@2UY}@U2Yice!K$AS4Agy2kAYvhq6^+h;v&F2LFW`6>SLYpo z^+Qgn#NeFsX27l?4r3b4EYPWNVi2R40uf~qO*)Q31nn%GU(QqwkyI@gDcO8FkR5@k4{Tu7)!0iRgfxyXpRI>H<^(xGJM%=Q#gJjw z51`I5HEo;o(6&B_x`2R=5S!LrKVGbFk2#4CZgaPbE%(QKI1IH$8>91qn;6f}R)g>N z`~3XH%{ZpM&*LE7ydkz2nmpt}yiJFpPlg~#Z*GS3^O(ov9BYB`SYAB4ee#v7%ZvGo zr#GQ%n#RBX-i3k2;9op_v6wXgs0K~zn>M)UEbA~F5m8D`$<)kyM?~$iWAA5O2(z$V zA8%f4uW(FY{VZ<8qx{m}Q|m>U&i27pnd zf?<3;T>y~ZxSNRyq6&AO4qCN2dX+yl2wO>*fjUJc}H$4DjJB&B$@#Lh|WE%E5DV%sY;P@akexA z=QxJo9XscWf|wFhOQ2?+ETSBh9J~5xOpSmHl$m$?{cdwu->yZZ65^4F9UJkiTMQ{T ze)iq(f8544jpO4d?{sbW#z+6gfA;VEC35b+`)~i7?|kPE>N`S0llrir@y?{JrFv6T z1@dhd>1@#{p#cppgp$xjauER3FYiB}fijaF4}i$dsi=@Q02f`?H2dwY76_5hITqFX zB>+|37y%woegOc1Jn^Y>XlYCWgpNglswDbJ(YO{P)J)WBy8yvXG@07=!v{Ct0QAk% z5O74JDxHE?ru3vAqB9c>i|Iwl&$mt*$0j1iu5|N_Tpa)JSuzI}B~(fV3u|08m6l)qtJ%gfxz$W3KCTv%VuFW^zoUS^XWSN{F>M zuBykrABPdm+Abc}MNPWa_q~ZctU>7F@@h!sz2$<)sY%h%Q9RY@5dc+7zu)e+H-_k% zSxR{vdPXQI<#9~on8yJSQ!c7H=3*jn3W;FiBNbrl=8l<&35oAFnvw^D3={wW2pl*y zt;T|OntqixVn+I=#4#DSPspFsrlhLXmI~^&p^!myDOC?XhKPtc<)~oD>_f>(RZAY5 zQ++1@fp@8y(~d~wuIRK?2gear|e`EB~8d|D`24UK;?j~;-?;g8?a|Fy&9 z0cN#&BAcS*A7}6g0EEs^Ma2Es#{ZAJ3K#;6B^eqsYbnDhfBeTEUtFC1)nEOkJRFDP z09J{MWX3s5DdqL+o8@x(Ge7e)zx7+c_438bZ~g4Iz^v+Zeg669AAR(Zn7n%R`s(r= z>4Ci48_F)6kQk?Q8i9%HIa14%s&(>U#d;{_=)#b*h=8F1AVv{A?vKb=w2XOZV-Qnf z_TC@%2O?6C-C^Sp5s{d&6jPft9#bkll5_a_?%MjvFoYTB6k5nU6Tpeh_<9>sf0i}`Lpv|XrVP!Sz- z(L%GfIqv&c&tyJtoHu|H0uB2#Qa&CAK%CDO>{9UTm=F6t`tbc9yeLJzr`0MTA{ee# zvr=*%2Jge8>&5ezw!Yin-mDQLAuJZH3YcntO#A()rNkIQ(^$3R00f1c<>Gw#^2P0Y z?_NKBwt4+}%bw|&&MxL6;ys&EDg9@2a2+W{%Zyq)!qVxYB zZEw~qTaulJts#azh((LWs-^1|r7ns{h;lgf6E2YTdNWtJg1YcejV(;41b7 za7npNxb^cQCZ#Z#ltP3?#|yW*fS)#I8pat}&8ogr?Lxt^1I713%qQT_!|m%oRY=?M zRR6L}1|Ecoh;QgL^_Nw}?yXGb>eY+)-g&>)FHS_7dMq%5;L4J!#}at&Oq!aR)B^mQ zlRQE7qZ~x*qU++tkr|s%*oO%ag`Gesm!wc^;9mbp);f2yhGtj?YX~QdRv! z1b_zdd*A={Kl0(M3e*$W8)uL_n$v2r))Fk)8FFE2bhqq^CDz-M6(G zSc<;$X#3gAD?eEQ55dfREYuZ&QOSjrC z(;=tDHT^K9v@EEFRBE#1n0C`rrHVzB2w#2iWwTz39!a5w#RWkiBqnr3_|VVsYbehe zyPw9`spqEUB*u^`U;UK8z=P<&exTOwiI2KqqUs1t^lCSpZC9brc|IC401Q*w9}bt> z9tmL_%m9gNBlr61rFXR7@8=~E(Wjq($xQqG*v9Z@Kl|b^PRwcsK6K}2{%o@qwYF*7 zz9RxKY+?h9O&g%d7tfz>y1v>>A?93!?q%A3ZZk9Q+}D{U_l*`%4M)yMH8Ww-qhoY= zdq;@uf|UIB@Bcq+riw_+!T2vxKLY^oTsgn=Xhky8h|n(KahJFm-Ok&SKk|# z-EQBs%{YO0MFd%}6eD&3r)ytBI)|++HHb3~m5B}}H{WHhBTCa*|2xNR} z%iNDWgnK|BoG_i9EfuVlnENv>B9(9CLm1~pOEECd9#j>x8UaC;yev!8_(vCK`(b?k z>8FU4v!rESmN6}}Ln0}Konr>izDQ<7WOI(s&;63h&E1r5r1GX5lc}uNeGyycg_!}g z>p~2emXcCl<1wx2S543|rL1a9oRS2OCF?xrD(UDQOHng(j-^N~MTI6h$03G{ncWdT zhe*Sm5OkUs?>NS|q_kak&NDFq0ulMxs3NipG4_ilVwEGrvzlPmTF~w7VZCa-XB8!) zQmo_*03pVdlR7}coHC*I5vK$SBx+Z;x6Iu24SR08mR*pX*6k+c(K%EV1KaP0&1yw# z%Q%;mce`+1Klya$3HjJo_sq6jWcA3W9^|2J)ZbQk%IchpG zz+y=>F#}Qg;`#pSYMAE&&~&})I^Q)hCmDuip3~#U+j+@9`O#;)yP@lv^YayXMs)1y zi_flxG0%&hKiYbSch`rKa+%Zia+8W7!HbtS)h?`UfGdNij;oc5uvHYCNLopuTfqs{E*%MAUKTO+>{Z0MW}cT^bhC&?1pn*FkfC?KlYk`lRyU=6)oQRnpocNod}Id zNkHHrt__{K79ic;9lG{wIVu3CSxQ;ehH)w)G5BRkrIZR7Lo;@@qE}NtS_LTVo2D^? zzHMr(9EgdWh*pveAvyNWJ0k0RSkjP0N|{R0;jn!2*^iMhv_by|t<|N~YC}Mv5QFR6 z@Z`PshGDvT^=cePW;o$EAeC}^bGskM=sC{|kUK?02>=j|?tzMhm|EXW(-C{-oC_hQ z0*7HNS`Ndas-Ox0^Elny4#B(7MlhJC?7cg`*Z`q{2`D~LIy&L~)Jy^NBu@l6mw8GR z_h_bIDgZ^^cqa*AXqvW-p84y~wrY~T84`G6&sVj{N|LGhKrRJ|*?BWlO+=M|El9+S z)k3h8Qc7vsa4eCSAz@V#Yok*Y!y5i79Hl%Y3(H)Vue;_kp_Qd`vWkpW5bOk7MaM4Z z1qmHH5kbI|m+0et8d*#{@;$xbVH!`4+Sr&uZE=@mudcX?!~^izsJ> zoHh8yvG1CwWf_Ozlb?P3^zlU#xNZAso|lxJ$Gd4UrJNTj1?u7f0F}0`>WmQS+u!=u zlV|US5MuNne(fX z20zZr?O}el!p2i7qH17z`+EP;cfRrB)g5RNm0G>_Ze5@5n}6Th5Ni9qRwb&~R*}NQ zNBu6d%22uo zwq?h|FohUHhz9T{|N3A5(I5UxW)hKUo^namTgd?M&ARmV{V-F&+7>{>`}QG-ga>yE zs(K@_1FWWJZ{1I2V1)col9JfzshVS^B8CV=?(LoY+-9nZg}5fn|4!SffcbXn zMnvTv4hNvBM80cU6u*_~HNl!)MQ)iRxj0Xxo;V{^@W3)3)ngyt=x)xL_A+LiL6ZbgZx8sf>aE z2uOx_G*YhX;}NE)A%wPV4Zws9Olnp{q-IG{q<{)$Hjc~l{Hg{OMP#@>Ae6KW#Ndt< zDFo+S&U1`T5lU9qVG~{7$K7F;a)i+YPpUG{^Ln#B>}8(k4!C6Y>n1I^o^3r$jBdZ5 zLle5LK{XH+k(=vbcQ=j00tklnr84Ka6q#oOv}30`gpvy(sc035+@7D^-QFOw)h0<* zNv`$XCHvsbz@Q4xst_Z1GpQJx`iLbhudfen3}!%tX(<(IJWUx1opauMK~+O3k{mCJ z2AH!fOZJ|Zl-bdG-Jd-=8;8Y*_QmHnv2mznSyXrXr|(=|y}J3}qj!ee0|9Q=t52W5 zc>dW}K+vwj`f;1*g$Ws$9KU{X8yjD;p#xLvVjQLvf(1uD`ZSuFIrAdpFwLoC71*A2 zYMM*N91(e$hOUb~;N8u#TD1V+f_L7t<9R9D=zsZF-rEmlx3{}JPE(FeENUe~+cd*? z)1xOs=VS2Bc{dGnDoZZ<>ecL=U0lT1*Eg4E>ynFiE(W{{>|*Fv9uVhgS;qP5#mzT9 zdar4`SefTEjSE2e^2<9B>AKB&6-52hXWkU{yLq*WT^GhNl`NZ8xOzRGojV_y9i5%6 zOfy0R=>gDY`CpGxs(Ydzq;&Kaw22vIo#&mYR&N+>f z{^aAAO$^I;=vogVP1l6rr+HL`Z-4upVNBOogPMVAhzpY#64>(giI7(F36OLDkI4+1YxWmJmZu`i&1aFTUCh^Kt3X3Q4GOV znf98KJp8U=b(%E8V>&~G-dBoV7Rk%9m{|>X?vV-gyG+jeSRFX;cgReLpr=zL1VR(U ziej$H94cmNIhE>7PF$6j3;;q1fuf3mnWUv#wfo&vnb82OCQHh@VSMuRz01c>uU>t5 zySu9^ci;6j%bMntvoJF<6}7c@t5x5$4G|znk%FoM9?Wve8H@-^(Zetu4nxWI=*hZi z{af6Y#2pJI;vc?}JU+ew@6i-K6MgWM>Uu;&xu+yCTzN@@>L}bS%VsZr4 z4P&0CX@7f&ZETt*G$F*Gs^fl~#>tGjCIG;?Z=ODVGA(79lYwDcM66^hMb6jVlcyJ( zt|?lMd~18C%8<;=$Qi1c5n|gOT}`;;Km9lV<|jY?vy^l6j>v5`eaWSFxD5N>`JLZw zqTg;e!z{PE>2Ln}U;Xf-cPl^XVV|d_n*bmp^Rg&t2*;HUDl_}EyfUHpF(rA^Zy^fN zcQJ;*$Zrjahp2rtFjXt1s0b3NsdGnLxr(%`gAkc(c{P{nB2a4w$BG8w(W%DF5UCn+ zXl-;@sSVTG86a|qB%+eu(7Vyp@{;FawT{8Dnl5>%Pv1dClX;qn2^$oZqk7mWo|arx zM3I`JF#^<&|Ae1FsAyvG36|xhub}% zH-MCMPAO%brbS9g%Pdlwh=2QU{q_Iz$6th|`R;fB`o;OC?fbLs+5o%NTFnq$?G-a( z2%*aR#}JU{s2)uW4|EaC%z5s+Gg%JPJTo1g+5fyd@U<=Fkq|>bA|}M;G%B?U$O8iS z2cSqh!K47ys_m-*0-zyQu>O6J`S30xGJvR79vKqwTYpA&h-_LaDGE#x8Scd;-rk+n zF5~@=i1N^{^XDsNP1DTf4Ix$_gHR0dFici8fl~hJ#p|Da^86bgyw8qBq;je1?Q0wV z!Mo3*bN|yn|L6bNKllef_>JG#Znr=D;SWFi{PS;o;~PKu$xphjZJPK8fAqgSx;%gP z*}K&&zzo{HFEWYLR1WV^2Gv~+0CHZ~c@ZJ!%oK^b7^^P7nN_zgCNLxbBC{^U3i+-* zQZ+NM;6u;OEqZhJN=lLf4w0B?DGAELOsiGnysN52-ZLK6>xzg~1M{=6o+f7;$IR@a^w`nd?BxjpD9}v}MDY7i74#X^A0_?GA z9T?b69l#4FK2#Oev z<8*eh8OND}JL}qU93Nd?co**OcIt+^jaz+&PQE@=VeZbm}s8oZq=#ki>sTik4V(7qUW%EXFZK`*9T(CNrt<{2WHPp%F{Tj z7E@y6X^{QxfB@0o1XuASBq~I{?V=RTsiY-4??S@@_~gmOrgyUeQeKKw!VxuI}z`FV6bi?r?oGAo1<(`0VLM!F*rmO%p(yn zKmv1;=Ma7H?Anl*yt~^Iakq-YVL<@TBx24HkwY*aJX>~-b4iB4k($QmB38sX8mH8* z;xf#l;vD-xWnR{OLk2fr-J)kO^4=|}I7hy3mVH8k?xJZfqgl@Sl`_)P1ohQbfLW)CL==NxbiAxJ_vgr zmpNj%y1wq7`A%CoDjk}rR7P@eoO3?K$9O-jETuS>;Esi;Tx>ci$&BOD_YD9RJ=Pw- zPToL8yhpPM2m&@PFrSR)9#nxVz^TShObmcb)W!}GE0qyzf&X}N2Bv_7W?YN3l~-Dn zNUB^{76HUs(h-qb!@{Fz2S7alqUO9kUuiM#eJ;g}$PFK$*?m{&z5ri?kl-C0C z^=*SUbcKpa1jL+^lmck?Dz_)$K^4*99kFklc0cd$!yYE`Rc;?106YM|s^=T#EMVq6 z0v!oyq8iv0DOG&AzD?}-7`dKOn&Vqv(_`XP5+Q;D6SXnwoE}C|YMSz~>Vc|+04|sm zneGh8%7V_fjy%A0H$~@|JR;wZUT2v>0MQ3u9fnLT7eT;W6alQ13ZqcK+A6G3PLZOZ zNJvPj@d-s@}sj2lsPg$nbWwaYQqlrK|A{NE*|0Q z000o17U>O!RYaGRWAq5V#BmQdqioAO9k|`(!(#gP>FazAN6O;Ycg4&I z5PVpc3`8QDME>w!{mI$(>{ov2BS^2_I_!Gg|Bb))z2Ett|JVQgAO6F?_xJwZPe1Qf8rZlHqtop+O z0DxA#7s94#r*TpQI@K{tDc%PFC^<6``Tz#C|6GYQb?C(q>cuj%bACx_L0CV2v<$;C z4z7;OBE?5q_5Im-PxCwL001BWNklKoOaz>B~=F6e%Hw)ppgiJlv&z)gm6;cH1pe649=A zDZxDC^Rv!ON>=nVPiY#&u{*zP4|f6zMc}iKUtT^rd%d5QrGQD(1RrR%?tII4SNo=o zQuHi#29!z$D1;cI-)=Xnj&^s4^;w@wE+Q!<(E_Sfhml#M17nt)L-cq1>l#0Y=qRu` zIy>*%HWhUkNo>tP~|(xX%8>2tbI=ECWD&x#|Q>MwRME#6?Px5|}Gb4*)7l zPpu$;G1jc1hys8Jh#h4qs~C)ya-u&A2&f=?SBtN8PBSg+10o}%<_v&mXXlR|J>DPo z<2ZX4x9bgnU0z&vT{jG4DT-KyXvlkXjGj?cnXvZmnUDcfK9x}ch%o02P-A@*F>>UN zkUTImx(5!KnJUuP2n=9Wx$DQ)No989X~y|?-X1ny9{&DeJFb$PJk42~+6k#&M0&H@ zHJdHmQ#AkpKvbHhxhLCb1vl3vl}t)O*9OPT$GFSPKt$94xT3`nOtdheN=DPFPe6!m zp)D70C8DL z^-HZ-L=Zzn=YwN(dY)kAM7=aV~%R*S`P!`RC``HGy{+6>?hAVVu~JM^eC7uU<{_{$Y&q zrY(a8AS#lU!;;5`p>0JXK&s9Gj(t?aY9?Ag;MjR~^dOD$;KK+4JcZHU2i0RZ+5q!~_(7ax38eE{K=7MO2CiDiY$n%+)ruXhFc>oTz{l$}{*_0M5GTT=V++wMnVO8#5y&DY8G@Za1sj z+W{&V2>_1?00LkL{`&eBkC+-%(5&W9Z%;)A#s`AP$b=^*8zNy9M*xs2Bp`3P*0o$x zKMPO|$4k8xrb^zE)Fq3IOjUsy^geQZyFb9kFq)2O%_#`J9~%e{8$31e#(VDnk#2`r z$E)?~+56x8)nEN?=(ca{6h&Z}!5R2) zYE#RJg=ke>M)G3FpmtAp6xF-iyCtQMzWJ@!FaH=!N?DlMGtFkzt^IU?r&>}?8S3aq z=)3Ks^NZWt>)m13I36a9p(#>Ct4g?5KH#z1W5CXroB-g_qqAT88{hr%i>r@6`4axJ z4H54VWfh8MrYB^!nHB|OAFKD%U!W|2h;?eH8xvO|sFD(LMGT(Uu=o0A49@DC+B#Y(lTce>sEb5p~NxkfH0ldd^Y`uvuMl7^yxmCMN3FJ&;M!^Rq5QMg#(kt)C`w z>{r|7)$^O2W!^7{tJkj&&PPD$dt5S&BMxI$m}AotsG9rcH{bi@CqHZ6dn~FY%Q((W z8@=ZkL)V01IPCX_^}6@Kpap?mz8YV=9xpZ_&*D67&coeqTx;{_@|=*ttY4j-ZO&rv z%@hfXmQ)DX5phZipxaH?cg;A>DWwqk_GVNoMX6o2<2a>Ukc`Nth5C&%v-P$a595pH zub;eoSyY{8LYwFE)r;#7-hb5hEitcFQKUF#Dd4?7J8zbG-tBfK@$6y~+W?EPqKM`s zIU5+TlNh6DVy3=t0HE>lc3Hglv0-$sm}tqK!Z0Q*#)!)ycaK}k_W7T_YTCHJ8_aZB z#Cax%h!~o%q~cpPQ>beI*+J2F?@$)c=D6wOp>;3LKAAPXf zPpeHEJqzUBJdVRcRQrLc?|TkDgWg<^F}T>c)B3~CqZC-R0RWZ>hiSMExJwoTaE@yb zsi*J=5lk_O5@87J7;8I6O|(dG&dgMcsVISSYzAudCiG>fiatorOedKlH-uc&91;;S z2X^cnBH=w5_f*uYS&$h(R+VIYw5T^R6EhT0rP>fd#7b?|hx0O_A>l*Azv{e2V4~>I zc?Y0~mP8F8#JFjiv$M0qu$Pp4Y!d#j#zKk1vji30%M zu$vGq-ur$ELjgF74xDO}gwY={Jf>e?8PR+QS*mB{Lx%DFhmJvWDkV!HB9GE_jvX;m zU?#$NztSU?6I6;2eQ1bqNwW6h9RZ+eV=58ga@&vZK1Nh_UO`eWgoar;V?skXKEdIoh6W%nU)_d+*YDyuAU~%P6y%Iq&=JcAVzVKKtsU58n&UJMX3B znm+)c;X_snL`SJ8BHi8Yb&>a;JzF>4z4PqsY%Pj_BM1TA&7}{3<#pi%=g@GL@1I^bknNN zi~t}-MUN_ZRbyjGODUyDxyKNlu#P7&sM8ZIr7#gQGBcPJEnu#O;8}`u%t%XKYJwL% z4g3A`PoDoDKm1cp>02MZYe>9m2_fga?pEFhb`gzSXxKL{^sioi-g$t5(7VO4oJcvM|%hvem3^|FcY{lYJN2mI)Wtf*Ew4mf7 zI?nlaKQQylm#^j}?RNXSyWQ??zl?h@VeSQ$S-@~kg~*r)5daxM=Duq$YgtO)$DFcr z+%(S2XPIIzXOAwbVdP7>+{ zKe@iX{=2{RTf5!vSAO}g{Ei?8K=9TttJ9-g}W_4u8Li2(zY~>KLAZW)0DCr7z;JgmsFaDODWyT=OpZ~TX{wwyeG10S_}}#Z7x@-Si<6~axqaVVrs*F z7^e&fMyBO>Pr(2P%q+x^=Cmxiu3$cJi~)&a6Nkfqh~9fdaE?L@KCl$kVj#ethQqWU zmqOe`mSRj0VyG3PI>F^s5HU8*kW-qL*g7zXUCTsfz)Vb3kz1ygH6egz@WCaqoCOi5 zIdy$(V=&W{MT#s-4#C&{`^y)1>s1@P6Scd$L$~tpy!(h9rNxRnVcSCS)dmdE*Ovf>k10r@VbX~J7%ZJ~5U!+XKa(jDt^5lG( zGlGE9-RnE09D-j`1_Q@_nGe%k&?IG9ts@6?&b1x)tGH^LYR~=;n|?wQ20^yw5qGJz9Z@s_piNW!7Q06s6T_Wi~sHb1LIJZXRtn=V$Y9 zNJ~aUwJOT1KmPF-tG=D5;v6--cP?r%B5E3UarXG;cE2q7_U3?$Z5K<1B^MP~Z+j`a z%rj!~!CgE)6M=C^w}9D4w4X&}o(IR=x6zU9rgFYnJC8YKP;kM4sfju7$hmBgQ*j0q<9V|& zhPH89r29Y9CUramEYV9a{!>VdVW_E0|)c=q~4NbKaGgAaJR6C*(j#|S2K&&F7rOrM{ zmgrhEtoS{4rl1vmbCO3RAYgP=xT%`Yh^hgqqJmZWoL1d_0Weepv3r2agK5^Fs4!S9 zC!dVX0nC&X34;q2rZ2J(M=-cJzqq`(T;}P;^>wW59pJuSuU7qj7;^#Vn22kh$yj5x zQ*E!d_6-P(k%5k9v`q7|EC4`+j-3Ifl7lC94vvtFqp%Dh*hyge7+2ykv2l*63boyb z9DiXp!^ro~5#LlF|D2lM{V(PEI~dl>>S_`uU~- zJS(D?=W=s5eNDA9uujb363W zefj*0XHOoRT*sj|W;_7Tu9|j>Dvq1bBIf{sL&h|hV z$<#G@^LAmYBj|^zDj1I>YS^}4&HOq#KY~OoU9J{s6__lsDkw-?C#p`>iX(_ z%p98-rBt!n`%EUKluL<6TdrzWh@wZG_^RMg$A(w|fCTM}tGk;QS2U%*j|gDH!b!AI zG*mFIa`5bt1Cm36C1o&+j!o?ZizVjjsAJROqAz9|d_coe3KS3(lxl|pA`&<#s+Ll9 zp=*n&npaeg`@J0v})<|Jm~|(^9I^ z^4-m0nHFGP=JMf3AN-YH`1ThshW9^w|GVG)j&r`Y$cTXl$^4vy?FWR$3OjKn9}w2 zZ7Jo&%d2@#A_)Kp?EGxI-K;yurWRr(9t}_`m>U2AQc8Eb;cmAlq7Ym&`_-yFk3ADM zA*jYjPu{<~{b4Qu2-O)DNfC=G5LDG3SmqG`i0SHj_wgrRH8G6y;+Rym>e_#;C2nwZ zH?ME5nSrV*k*gY_$Hp0ARn0|2_5qI!$*&{hj>7$bK!Dz{Yuh%uP($2Vs`km7en<_j zMa@8LvD04x5D2(V#%iSQA^s}yUA3o|THT}p20x;GkEr((F-miXd zzu)~Q|IvT^*=L`fpKVeq|KuP4<9D7t{pDZ!B}8!EjnhDYZPzwkHy`GEe$GQ4AQ3B| zNMUwavLhxU?_3jt0f_0*6xGZsc@M0VEI%hmEh0C!w?(CiQO$yPUwrYEQ`2qdoev1W zY=qRd!8vXle|>uwymt(t@i~bPT(x@G@!7gP@0$H#yx9$e4l^J?UWAwg2whmx+%&#z zd=p(Yp#9ppC=g;PGEPfXZ3Z|7F46H^?X?M!lpGNgI|2a592$=i@9y^d!=Pq9_-*fx z?Eg8Dz4U#`8Uu50_QElaw&nNSU?-nJ+LIY%N=vH?O9JrOVS zVrt8rZmtjOO>=P`4~M0cGR^7o@#gyF0YRo2HtW_0my7Opi*x++S*WJ(yZtcD(=tz8 z+phcW#mgIVxZe23Pamo1&DH+(^{_1Y;-ZhSF#Brq-A3H)q3@dzsOU@gEJiOMt{CBRdTfLeV&$*37F7f6GJixjhhb3us`Iyv`rAO zCYnP!^Q!@;ahepu)yw_)w(0t?yPM7Ib~pTsKlo!HX2*(j`KSc|Q*5g z>?_#D9R+s83Lr!m``Dk-Gu%zXqeqXo+ieq@VZSeFso-7quIpE^X>ay3hdz)v=Gx2k zj)HT1GM0I8WJE&LW5iaa;m5ReT^l?qxcZ9K81ZyXZx|5|mMA-QZ?F)=-7EVwP4=b z9))&~cL@CTeV=NL^}5BRG7Ku?uqGF7{fdj0B}sACSXnUkIq+J6P%AI)oWTBr|&%p z&(6=7cueM?q-pu)JKNpi&_`vQ$K3(|`x|7UuRi_h-EJ6$bhDeDJ-%F@U0h#ZJ$vW< ze%0h2aknFY8`Q_bWuBfs`S!ZsGGSmif=%9f)Mj9q zOIhYz>6Gw*?q35+c0Qe0ZIx-$1n;V&Zq48gEK7k*C#j(0@IuU`h=_`wjB9|1s^4YJ zUGIB__C}@SxFi99h)@XiV_8J)$jh=*^;aHtN&(Gmo|bt(tN`cR;pt}MvgX5BeNqq& zOjJNs>agyb*v2r76X;QyEfw*`%t*vbhItX^-W>5BOUa_v(@?8dD8~R&N=+? zkABj``0~rw`?~{}?GO9i-N8938J+h;{IidL+I8K2w}1Tj!h3$STKm|>*!`V<@892U z*5sS>?Z$iGuGTg1T(9~%Q4*1=9fq+yGz7{yjl&nupI2%=BK~=Gj5m+KJ#2&E2^CYB z83u?)TBFF3pk1q62xw@v-K3-l2nv93^alfCFoOS!t@mn@CCSdjj&KnXsY+bY-P2+K z3^cJA0E^|WEtdqAYc%6O;9ul3UuZ_sXdn$(fTS6Wy9r@KBErQvhYy}v zRrgNkLtEYI%E(A}5BDQJVWNQSzWVA@B)Yszpa0YA7cbUG?#F-dn?O{i z``eq>h6J#Ys)50wrIhZs+fu6c?r=Qr_xmOmEF!te;V>4_SKqz)i~s$v0iY_>^U7iX zCNP5g?RFTv0Y7_oInNU!b{*D=B260ut5kprV5*SjoD+fFw_z!-k-@Kf+Z_ATj6M_x>@a*d9um18chkkhV>bw8)U;nHB;$QvCo7>xY zPM`naa{yEWLK+WK2!3;Uaq;~6+wCvC^Mv%^h<(1=39dj4jSU@;0PsYUCMTNP&0{ko zszpRj9H1v>Oci;5cT2>JVR-rM*)PBS?(MrfXQrFWuJ5B%Iqc`fdT4f#C6|lMa5!ei zba_3z{&p7wp+O8Tctpa>m3Kjjfjl1$GnyR_sU|4F`M^WxK?;C6N2_HtgK5kqJ??Qi z)!2nnsz0}%M6{HerbI+$b5TomjuD-xFhs=(x~#?B?eF%P+50E3+RK5wwEV+qcITpDu?5m*Pbw_$ajyQksj2f^&E8cR7`Q zh@<26)nb3BX-+BCyPL@~BGBG{?&od2f6)Rp%HH=eY!j z{m@P09HJAkQlM5CmeGX(067%}0fU@t2tGuAILz;F-fu28%>u!DM$+vrfAdfG!!pcM zaZBHz3TB|iYPP$Z-Db1sB9&C7QRLGcyN*4F0Lf!)(xS|IYzG~ z$4w-p=~(le*g0~{#8V!--Y-_&<<&CHIj5ZGLJmt#7oR@+`RmtR@26v34o*eizTMX> zC09fs=6Mz$fgN04bSbG1VLu=0zN{}-X)5ck-%V-V$F^;>-fKIVA~OI;uGJACHg*Xi zn?cu|HoH>QREZrm(NYiy9pt$hr~!RgDpE60U_wDcV#$RV5UFTJ#8b$Mj)|*QGb^>6 z&>&)|BtmlJPOMM*yG^Y}%e^L@m?>1hLux^udKQ#vFI! zaTr#MVL?b$sv(qG05Qhc_kE1uV&Am ztwZOgxiu4kmH+@C07*naR6M(0<)Q{UrkZDMQ%4Boa23O|O}_}#2katmmKMEJg$i9NQn#KjtI;B6vlu)mmR!{uXavp7Ic_UW4N}hIn5r7)+F)Z< zgpg{fAp~M3_O%`#9!4he%rW?&E$opTLv zZ(vP3{j}WA4Zx-Z&?v<*hLmdKPy<-Yft6GreIaR{#_e{uXUJN+K3-g`)~lsA9LKq; ztd@%hnwI35*%AAp3&EKMGI=|>H4H*#wW39zr5;+#ps&e!G z?iauK`u=V=j^oYyTkrAa=I+_^XQk#Zzxv_r&D*Ps7ys3N{cr!xzx(smdbwF&ELTfa z_3RYP`{2AcRV#%7@T_|L(IcO8j-I(nRj6vEm@~d}u?@IX)(|Fu06{Dj*!nJx-Y+Yc^u~|;2o!2 zzx?v0W4_xS)~mQ#b|JpJ-QUmqw>sYwlH_Cn+RE*wmuj_^$CgDkgF4IcJ;3K*d}0`! z^Uq&?Hg508-QK*v_1-rpF3+xt6lrIsI}eUk5hD7ip9zly6+R7O!)94ksQ`xb@ti(P z4gge9&wK{-J-(Wanx2bP?G|#$qQXqU`&^2uHT2WzHX2m$@ve;M<3ps8J{(bfazOmz z>+kOGcFuR{BfV*}#W4KwKl{)A$N%Mj{pmma!w)|F0ov0rGyTkr!a}mx%*+ASy#SF~E)aH~+$*l|RT2M<=P2Sz# zzIy*&t6pz5g!Jjl7eD`}Z=IP;lP%YDoaTl<3EmN*>pONDBhRT$W5H8u*kqd>Gw#Zf zJb^RwG;I2u1rdF4ITf_voI8wVP9?@>y9wUo&D-g5h}7=h?uyjV`I^f5VmThB@i3bj z0xTDS9XHwX)4ZYsKvSz(0E`Hi!FMsNT!ao;j67Z}hm=K9osODPskt_+eXS)#QUTZO zDVW&flrj+veL$jVt~nJlcRbANO^+0b5D81JDwgKj#3Drv0a|IN7F#U)?d>=W;qGo+ zExP^guv#w;yMt+MAlPBOKoCT@yuKiEW;V}rsrl1qi@*Q&;E7yENLEUTJ!%DlKEzCp zNb#vJf0ut6D&a(-l$?-UE*1@?D zdpG5IeX&4tlIG1i5?JVi03ad9KK6r2?xJVM(_Feu=Ysd8npv$SB@NN5A`vZC9p6ID z6%k6Rv_@5%rc$zu#{*-@8PvM*Fm1Q_a7Y61$;+!@*#lb2d3Srvlawr77Z&U8{@tNu z^?{Kn#3)*046zF;H3UCR6^MfeGs(FG@4Fa+^E)vYc-ohnxA()MbA;=Q<^B7^{rjC( z`{eWMz*LJYmYzrvRI4)4ba$w=?n_1E-F7lDCd!hAl{;)tJ=UDcF-sA>xLV%d?M*cV zucFR}?eVzse$j<4bg86TYc3fLSA8VJ7Nrq0AZX*&8`LV^6C%`V%^O-(YR&*)%?Z+l zrW0zv(kM8oA%Y?Twxry0r3nyC&r)r6YE5{@YStj{-Z{_g9m$vh8k|xPDTe;>$U@}c z&v}X=wS>>KinXft>H5&jYU~tL<3|d{H&iDHkTwZ!HjapETv_r(vMw}Yfg zjou7S3EKlS=y8i~SEf@1@%&3OH9Jd!ddEbMx&|M$gG5b5$*AO#OCiT*a6HbzyIRFD zYczzDqeJUud5pDSnkOa?0EEzDYv-r~r`C$lkc(6~!6$|;EQVkJb1K`zBm%kQDOCWR z(m1CX5IXO#R{eU2tD#eJop0jc*7}e>aGF&_nW^jC#isY(H5-7Eivs3aOO+{=IptjS zZnp=3<23iZFCwNgjv`W1x-DY0%FqQV>1LdFyWPcdxI5mO*8=)d;jf6n;53v?GjPw35&eIrua7@G`BFnB@E*HTEb{>fv5v$EHA$sScbMz#WA)*FwY;Is} z%^)E(A0$=he9lQ#my6|DTbYO`=gj<(z2+&WZA2O(WakJ`O|c2YnE`?euFOTwL^6>Y zV|RIV@yl<%E1ts;k=X^WU`H!eq^gRjJIRG>&2#8oOX*{DrHHDJ@FcX-vg*Z*9lNKc z6%j2}OOaAE1SUE?p$ORQco6tOKB1OcQB)a`mP6MP8$&>c|2rr;uC2p`4ShM)+I5c9YIPSvjy&$$g67#O;z;qr3P#}IssF~o-I{J|&B zn&d&6kKS?3W6dJ~IE<=>2<#};gwCaLG}D(aF1s!Qz;?XLY5a$O{KdC#-p^_7qQ?*C zq*g#QRY_$MT?FsboSK>2sg@_Dk8!bB&T|5Q$91Hdrs>U_o44<8RznO!|J85&Xt)1c zAAHG$h`jfr*n~5yh#ACwk)~rQRn^>wPZ^x|yru_u?x-Mu5i$@MXfrK6O~?0%?2GED z8`_|z0FK!aJ@vFTvnn;$+}iT3J#K(t?&;q=ML#|5#h#f|(5iSt47=%36@7o4UcbG0 z^X~0x^=$j@8}}&np)rO(`NKbW`Qo_`@khV@Ls846K6HLePW}Ol)zVD6p_`@|>7lFp z0Vdhh#6%bx+2NJUM!cNM-WD&s9@Scl-U#?frVW_~zB? zpMUeF?}nTA`?hfyJ1$Zyz|wcb24pGKQeoZurE`aImLleb}vAIs4P&&(;+ZiOa3c#fT$=b{Eg zz>ZWv)o$M(UVgeELg!$2Jj~NfM2qDz#7?EwT;?eg20&zD1v~8Kw)=+Il~Shhuvl%< zJ^@1Lc$(6_sz@dD0C<15?N^jFg8&$9F1qQEo_}(sBJ)&hwpypycU@2Y5Qrdpbe_{V z`RF#6!*bo-Z;v^b*vEOA(wL6N96|`d+q-NA_cs%mn!sWeOjSf;=)9xDZu;cY|hqZd$Gu$Znjog5@eC;<|3!CPFb4QLW9osWu(0hbk5k z5;dZVC^$xY5?QzYJ0O8S>A}N^6@up<%*>eBvri?-Sy_dUievy510n=$hVIo=!3a;5 zn*ac6)#Sw81XP1lh4@@5HUOwPLwx)AuxGbVss6;4eQKq6}@ylS;pV(tU>T@bbUSdE5{igsouRZhUO z2NPsOa%^hykR^VgK4c%IF%K_M6|DdeDE#XGML>Y&gLwuBeR!Fo1ppdw>7j-4JuRSf zzo>DCPQPeEGz0*UbGceC?A#i9fb)Iut>**=QfkW8v_^-jrmRFrL~Z#oVU?4n6VRy+ z{Fnx}@k9*%v44n&-Z2qYQBTwYh;DGJE>5Wy(Nd(;Qc5&{=sA}Xf^(kD)S;;eF+Ef; z&#{O(*N~a0qM-{FYUqMgL2w*GH}tAHr?Orx=9K3-0npuUH%`+K3%d>guU3mU_lI0c z&hs?q!{HE6|GR(vC*S?#r@eVx1YGxh=Q=M5X-owG1Qdx(VS5-IdsDr;-=|zeEL))% zTPK9MDZdc2Z`HKZAcHZH_b!|*P#?y>RynsOPN=@7z1wP~4TcQ{&bfwD0)TP?rdM{I zhyn;0!MV#nxkzK0QW1PSfq(j@TU>t-Efy9K>T{n|3+X41hV; z2X!y0rB-?JbbvI~@JEd!Pyok|jf*M@XK0nG^?f6|ApyGJ9dpSg=iEYxHaMmRWo@P5!PO@}_~5B(G7Kn$L_kohHgKiLoDu?VcRNI!rs>_gcYyHj?Yn6jZ*Fe# zoL{~9u60IK_4Cg^|Mc_Eu=UhFe#D=A9Do5dVSon&VB5{l%SR3HEJ|{I3jx3f9w-m! zvXiR!`PG(FdrmzQnAVh9GuEjRNX{+3wubs{el^vOCa5aVq+7rYgqV(FtqN1hknle1;o*;Ths#ZkLJsA-xdd6)MQZ5C~eb=XR^q>ii0Bu)vC*=>2bHS|BAb;`TQeCQpUgBJ538Z; zy8Z5e2rao)eZ*87nl;BrdIU{Z(=Q<=_B^L_x7+Xbhr?kc zrgt~Dsya@RrZ=~{*_nz|xw|=lF_1VigB*_X<(I1+ z$apNw;ypWV2>|W3BN0wh8OPG{!e=iAFdP0KZx6@qN<_e|79ce@|ozTasEAKhXYTDdBCj3LI( zBm3al%$TWx{#C8(TuyQvCnnaas^)@ojxj(3j)dqCZ9L3E-7` zKWz5fdqfm-%c0Au=9Hy~XJ4y`m}9NAIBq?9-jCBXClid(?e4d#3`SKXdbqso)T#^I z_x||pVShiWG&5(Lb5f&RV7Yeh|LKOzU0rN$-|vyoGXkIilsxUXF3ov7mdj`B+jo1j zIt<*rVX&0Q5ubCRl|?-oPv9HcqVDFepayBWb&LqMVs z!+4y&{NblllDDt!yT0?0MQTZTyFJ#bH@D+B3m}Kktu_(S_PZ(Ps;Y~1x9Hteao!z) z0FW;}S*d8A%k$5!=fnK$lQk0&<1}UGs2FuI9FEiT=a;n#5;(6@sjZ?$LkH_hkzxeL*a#gF=QcA@T<228)^L4M@6EDMm{O;R<{ae@#oXBLlUN@cc_SdEvHAv++8- z^C%~H6%nIYV-q_(*>@s>p`q!AZFU1xRWel7R^Y%QMjyubYDj>HCl&!Q#Tau@FzCAe z^768a-SN1O(T~S{cl|v04y=GyGemOU0cs;8Xc>}@Z!2>VpU+~-F~0*i~we^-|w!juUCu3dcBd8 zGo1eEzxcyArXT(IcjGaK&9Ync$P}3o5SL9b5CPc0BA}`s#<7cm2)}*xcC%Wpm)6A) z9MpOe79;272{pyc9J6l$%?Djm6_Kj)wDizIk@lMANmae`A%tm~02_>xOD<;B$0*|g zpum${x7NyM=J%Lp5ixRh7CkJvm_5cWh_oE~7cZXgcKa`{uR|Ze@f5?PW3F0iWp<^? zoJtoxkO$WZx(KmAQD_;_2VviNLAD@C$Em2Pa}=ZF&?KXg3AHK`o&WmuUPf-}K8VPk zRi)(YLm+0LAQ0<(%UyVYlByx28K9gQ%c?-CO3u5WsvrOis``KYpa0>M#$uA=k5s<4H3zG&z=K_VAz~?v^hXLMSvQ#g7Nnv zpj1zVg~yg}>xmOQ7*fHxT;kn>;+*Dr)b=D>Q9C)CHN@;=zElj{`GNohu;_xS9mkqV zky`KXcVB<^rl@uRj8ZB%@9Go&w<${Du3MU6E~SeRni3c~K!=F6N(jF1yYW~+8W9u( zI3VPlrIwN=AC_I$bzNv8&b8K@Gk`tadZd>2bez9#g9MiI*VprY)v9~!n4uNs0GfT* zY4_9mL{1q13>w`99hedlp8d;IO{AJWO1?8OpHoXh1~_}?JbC?U55HaQqZcs^!OeuH zq60D@=Op)spdPHbVsTI+C*Z2KA zClvwHlbC@SF$k#Q>0xx}^a+n{dpPE_T`U$kl^35p2ZY##-R{0^Y(&&`z2K>v_RXue z-+cF4L|YD%OOXO>yxkuw1V_Xngf!QF5lc?avvVw>h}bz|$3@ID)QZmgX)37{QR}?F zxQImzkQ!6U%)nb|6q4+Ll|Nn zCm;Q(?K^8ZmNcb41n%Rjx9@}ZeHUCnsa4hd0)vaY!;A>aF3zj|&8wX$PRH%$atI!~ zNHH=In#r8iJI9PMxW4m!=X28CF70-uW)0ql=xUKP7XV|zVHt=~MblK9+Cfe!r;La~ z;(gd$uBw#PqBDZ8U%z|y>9fUR@%2x?UR|u%@nXF&H9}I=v%m^ECdXJ5nc@C^Tjpwt zT_0+$Rix(X1JB2bM5zdXd5`QcL?E_YruEgP6hK199b(Wrc~6JKv{-h#-58_0-yU!7 zEJXL>(`7Andw)yh45>=pZbz-UT=cKLxeczneBLjYJt5BXT&t`vHru;xnzDD~E_z9I zzdI~f%iTU-T=a&8$V{*cZoTTiDcj9uIButY9s7kBgT7|~c>U^NX3t&>``w`%==yqD z%JA;pal0Fh`jpGfo1?1kwqq^Qcinokyu4T(r}Tce3(=)KMIVTul+qwKwE$@8gR3f1 zj0hPO4bwPxeI%q|=-$7*Q=@ObzVR_?6%`Wmpi+yyzd3}?ANDh#u|ox!=ERPNAsWES z5eHC*P_0OH#M4-g`|09paq)bE>|7U^@wgkAc(v-^zPn=zOw_OXDW%0CxIh@9xg{7N z;<4mlFdp-9pX#jdzC8i~0uDoP0lI#$ROe%M&dnu}(R9e=s!oRlOac9yxA%P)r!ft_ z8*g(Y3X!j`B0=dpcXKmdU9SLa7o`;=5nIU9N}yeZ52kVev>ttE*=+ zzca&9s&j$iYmEfK^XIzlcCs!x^`BijeJB(ZWD%$R=lQYZWVEjNl0X!Bp{toH>c* z6Owlxz{Y78?4Nzo`(K9uo$duCAf>7I$+3C_vb4num z?CQeIR4XZrle950GjiTeh2fKrJrlK6_jEE_8dK%5T<_R9=jM5CP}MfD&btu8Zok75 zTUA=X=bX2b7RU)&#>~xUh6tT=2xy3n@qfatJt<4K*(c_Ui{;DbSBqLL1d5@GhQ)fS z?}$7TRk4)oW)TS$Y@93*P=JuFNG;l0q0I;v@Bw+HqA4Y*S`F|VkV)0xS&OP@waUa6 zOinve>nmb&=>>pVv#K>`9_|)%)fi*7`mlx#K!6{<4xW3yVt^v2r%$Z!;_v+458u4L z*=-N~BJOs_7(Jn_hPd62D*D6EpZ)yr|DSJv_S632`kR0Fi655JG#`)0<90Wd436*b zw~KzEMIAd8xxT(Ovmbo^Y2WoBIOm;1`rY6EeKc6C76dp9LkIzgy4c;`-%WYGzkQDY zhCoQ@&S~cf@QVO|IW=+A#x{WFc&mnl#MEjituFA9azNuk5Pi5!v@Q>Q^p{p@MFhvq zFFiXzBci6tM_{Jg?Hpt098c4@SqwmoX6#8s&@2ET7($(s0%AL4=5f*~ZLT0CRih&6 z0@Zvvo-QtWL>Q-O=vQ+p0ES531wfXQ^%xSecO5$u6)=emi=k7~)xwuF?YB3})e-@} z`103wyWMVgJkR)tofA9_>C>pVIIA+f_U!|4_tA;Eego;@roI3K;LB1iz| zQ=>>L06m;L08dlRC&eQ|{D|}a(W`v~)49U}KgPn3z=?!t z_^?Z7Dc`((?ZCgddVbuGfBt9xX1Cw}e?R%j?d`3ZIv$g)%rxmEc z5Dv#NmkNXqk>9-DKL2!6vjCy0E&6Vp6EJxq?^s0VoJ}Q7rJw?UBNDOQI2o~=0Ts1~ z6zTea09l%T2ryI1weNilJ{KF7vFn|wU0e@uULWhes8#@|+47vEXbf~LweQ0F*SpJ$ zA*ZTlwW{+Jf^&|Y<1RWCOH%=Z5Sa;ifWG>an{SlWVuTW+tF;1p=T6Ua2)MrTZ{8In zT*eqP-rbCcITsUb4K|{ZigUbL58J!_JSN|TNWN7hj{9j?c2aZbf`WFT8~T{$LaM@1f)}9@5ZvDc3JPTkXc| z0@tGJO+SvgiXnnyhY0=P-n_aG#34`!{PNTFyLX3v;i{-sL7+V6&^hmYSOnF6P9^6O z!|L7r;re=U{cL&Ijm}YsJdU|v1_hW?nKHiqZZ{rMBNpD@jUv^#a5$vhZZ;q44*&ol z07*naR2G50i`!j_f$r``Kv1*QDt__R^YJ)|i1+mJ^OY%VHrHr++)v|SJ|3rjv8+`T zad$rwn2QW%>(z<~y<_kF{#byh8+uE-h1p8 zK6qkg#BjSCJ8(eYJ%%pae0z^XE@14UNp%j9K&y1o9}ZKD9sr$#*!A-`_lr(Sfn57# z?-G|>yT0?FtfHt0z>G}6OxZE9BSPv-i-j15RX^7}r|e>gU3WJfjBuW2GE2uqhPkE? z`LoYIt18o&Vo+6j@q7^@mLm7}bFK2rpTBwj+1iS{Jq*Se^+|u-W+dHRI=0wL;JZqYLK$rp0=1unGRiz?(Y+(ZcfS%HXr@f#v4&~#P zNXt0SnT$KN=L|tbL7$Sn0RW&2(fWRzrv^3-J%{KX#CcAjZalTTPKS84htRqGO|xPo zdL;X_$W>KZ8a$OD%)~}Sgx>o)Cq!gE(YijGFSAx;1XX2X7ed!{(>RLCgRIc0 z4^zs+fD<9Jb3PC<;wkKC%^VS-7>URSf2y(?Ad*UL(d|=#zV_34wfwcOelTyAHfQt< z2uQ9}sZ|`i_7pvYdVRfb^M*pE2&SR}>{=5+O+5Pt(4%KGdF&kGX%zxCmr2l^bBLk! zPMenF;p=ApJCYR(}VdUo!-zd3M#kW~?xh;x>17+NfD zhNkEr0J{JLHXRSIUf-muciY2sm==rSupONXX5bKf4A_zP4iWpIi_SZbQm1L2FD@^; zxu!V*fFXzhGsQk2Vaio%ZEcxpo)<$u9`iIOVy7jk#IJwxkL%3_;Oi$Ob%dsS0r=6j z_V8*C(ZgZ-xCtW?IR$|a$)!ZBA8_)qmCqiCH*H63R4722d?&#AfM@gp%tn)h^KCFe9O%h3MI_h;`Ac>2XX5 z6x!h@AZA~_eE#kIzT{Jz8v)2sDOHMCqoN{JvBe_Hb0xxDA@*IGlJ9*=RYivdi8N_* zWUyN5@i0#NdC#N<({U1mp%067@1tw+!+JS5rdq8eQMF;|5y8m9fM9NWoNu?|)w3Zb z>6bo4W>z&IVlx1=oTUr4j7-^2wQS!W1G(druP*yiBm_T>3BYQVe(2IX)m$Zu^Q};a z<6-U>K6F7%nX&I}r!`@wQL&i$f0j=2?I2#H;#yyMt0F^-e&x09-c=zVne?{`vbf}ESneKkS_usFD9pR8g)QDNs^ zeEQbn4fqH^3H5vlLHT43{{ zzg+jn_CQcO?N(AVoN(4B zlLBIoz=kdJ$&OA!Giqnr13N%~<_}~F3V_rMH0)GLV`_-A(?M&wN)xO+SHHlT9_YCY z<{dNR&<$Pe<}{1S)#b$}FJHcX^LlrG3+LkfZhODJyzW=)5aWKkt51T1W?S)yox_s? z5}dV#vB4J%R3YUOoa_6(FbDaGVX6)%vho|1kgEO6~8PUhA zo9{W=%-T`}4%1NJxhN5M*Sa^S8&=Y6KLgPJiS z5uCw3AKv|w)UKPKFSwii9akE&?WmprT5re8~WPh@tBNVLa>;kIhIC(a@yS zT53hWBKiQJ5vi)is6*Gc!+uIN(kY@4h5BLW5gmwFEmiW=^+WISwk96Y8iAa%xh^3TTt7CV5l)!nfB4;)lv@19C zY|}1d;#^N5&Uq#cv7ta!YDHpZb

Uv*%auQc5ZqJVswi&bb`N*)dmfp5yl{Xn^Q^ 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 x6UO&r0~o1}+)hBo4j86yvzYO+fR*nUtjMMQySS z`e&H#zUb7zb=KJ@b ziA$9!a&#vMr->BbM@I(I?|3gLz1egah$n6QtOKgfZGnIS zh`FXJr3`*5?WHP)wn`A1#JwJq+gn>_bD~LTfkO9s{;s+yDZSYj!0T1kSpJdbyzik{ zg`1f-9zEy3V%WCx`)+Y;itFX|UMTj6?G}d*7P$Xy+kHOwMgVDhbGGVxeXNtKvT2HcOf9?9>Pj2plb+6y&5=Y+` zKEb4Zf0JDN*WwSp&ONkaNlVuMPGh)$WbG3C_!h8`zXJJ!UUip1XF%7IuRrt|NM%|X z>x(fQq|7{t%bkUn?TIGxZg=}4G4B#?JwNyp0ZR6)#z}uMs;p~Zf*E9<#R&-qdaXqJ za|7unTp0s=Uy!J^m^p7!0)%n!f4C&Z7+Dg~{d$z@!3+RSQTf_%76hT=YuQfABYcVe z0t7G694$yabM>W_!VOe6X1Yhkjpw)NSC~a$FH%f$XY+Ny4(jgcreS)#FqsB-s&Ez# z`%EsIG0NNU(uW+9$|f!OE_r0F)w8mnOz2{>U1P)*>Rv{nzI7Aaisj5V$1+tSZ&G5^{<-aGI+9~S7nxQwYU zSd-=$$xny=9k|9d1iv)yciMW-=LCYw_OCy{b;o7(*Nh|i;z6b+na=R#M?bIyar&nd zL%{PM-}T!88HGTv)ZF8{Ls~XvbCYg)Iy{T( zW)DhlQ5V_0$K#>L*`cR5mzU3rY~b+Ib|!neC()i5Dr+TU?uVM2s@+UbP$sHsPHtx8z_NX|C2MQ~ z&+o=&;3|(z!3@_&@oGmaQnlX1VZLjZcZW@Z=4b<<8st=c$Uh_rZoG?oaHNRjNf)la zG)IctU;O?J*@wp)iR0(8r*!2vf@(fk?T#t#qEUzUyByWU}tlPP=@AeA!c0q(bV7)!PMx z7)aGj%xZ}8e;Kqntq10S_O)NRtBFg?69-qUf+}4X3;&4DdY)!)FnupI+xz?Z*X#cx zDCcK{fFf1Cg{d=uw>_`Rc-%&1ks{O~|9;IrHxTGO`BVRINAK`*7H!_;MoSH<1r|OIzQ25|?XzF!Eukh=tM@i9G2{M=T$jK~|Y-#Ygv5_>Yyc z-*0bQ@8wlZkMO>K!Q6vA@=e9nc{%R*adb0k>H2iM=NZ6Mav6n(E8&fGOn2nN?@UY77-< z!$wg)cRs^tCnP$m_Eudxn%|D+H)l1(^b?3;(qu6;ccgb*>UmRp+{N<$YXQ;RAI`$tzavNAxQO?tQPatbcg7+ zB?9lOP+)zFX!|Tt1%l^~v##BOE}pfgydW(KI4h5SmX}BcuhKOZFU@!8VNFWvhLu05 z|8{%of+)_i zoMhr+)J@Foq$)RI;mi?FXZrDdZ(+|w$8(_Z&CmPERyO*vufFnsOw?RIgeR0eR*X`q z9-IKV45of-O55ITA{LHHvNmRxwmDEZHXP#UeZ2g~s+)46vK*|Ju$8ZTh`*SS6EfUH2EvbH3`F17|aK! ze;nyiEK;}745>CFvUqv2^P#k!8kp-x!3ku6^bcAJd?;4!%KevSe~(2L%61OFS(yg( z2Nvl(;un1potyoWMO7oAJ%6N?B5)f-!zrBl4!wYMN|SBwd2Ek z)>><_IvbYY_aq|hnskaHf@-Hp%MNoN@=dh)pzxkk9z6~_1y}n7)f!;$es{9!tC0h0 z6Vm4GrSm(m*0YwcP}O3T7jn{1J<$V_rCs>qOi@1m0bw`@mBZsBG_sLX3Z0kn9}n}0 z1yS%35`x{!TzKAVi|qU!Ta%93pNfPwaSwtguU_3|M%$3^#- zMKO%)f%muLI2Ioi8T)N_Y)s*5>VL_lmvlV-eXH*J`T(nSDL_ueBDrn;RO8e6{Y>9N znAso%9t#WBEZ_Tv@sV+uKX~}hbM?HqX$`|KGX;Z=O$d z@+3IJ)@awIzxT9N_NT8C|=8G>}74e5Rv&jPJ8jkjBtZW)5i2$-~)~ag*%F`vqQn03s z&la&Cc(&!v(szISyu#N*k0)mQG{al}>HuOgJI}g;YqHuG&~Mr>O}=FgqrFw3_5A!8 zdB49myT*$Dc4jmT(eL~46oINfNZ-}sxau{6JWV<+XC!eGZxsi%*gF-Y;r;zbVNqt3 zC-Exvzj`XP-F!Sx-^X0EUj}TBAB1JsX92%5`aj|AS&@NP44eQz9{Sb-a+0|1X?s0mb#zWM4x7qOZ`cEg7%hF zue784$qb=>dqKSLm8&lPVDtQH@iN{k@{3;4v8lx?oZzi7oDEma2PE(=-Srtx4|1sK z6-ZSHpK*TgU<8P;;5&w;L~yE~CPk1r?G?Q2u(3XjHuc3K51$(pu1Px2FEJKJdQi~{ zB=M3gkL(wjo4zS=s=M{GVcol;01Bo;k2*g!{P;%*1_SLE+DRWNJ;a#6`~LywL0W zwG^92lEL6<^*K{>c_7xqL)-=Ix-;r6vZ?HOU`PhxtNps@YL>Ln_-=T7{HqP+X~sM9 zuIffJR~^~kKPWlabO97h^UBnkN+wzf0KP~u(A=ccON%-^etbIeFkw2JXR4pjJ_SVd zB@NfTI*g_Fm)M)^Es%&efxfWWulph_)x2=&D6EFf2vk~P!Dg60V*ecm|Lv#o@edXn ziv9RW)PjwJjMi{Ri)mtYR}leG<0^qzCC|YkF;xlj zE7a|8W2Kb3*!yQyUS6H>@)gQ8CSyD!Rb|o_Lql6Hyi5S-oCaNE{tnJA>2axwn+r9)B!Nehq-4EV(y zUkT-C=bv08sRs@r{R=OM5nOL~@{{$o)q!Yht>MQrvrPu|?yCw%F$;4t)G5GVj6I=P z;u?w8yWYnYR9A|ADflr3ZwB4ec*6rS%0+iAU{? zQ{lWl1MkUmA;0DxXivkdB?>HQ!L#S$A)s%jCT0fS2Nz z@>I{QoSc-n43LO+PvNGi>C0gmH0h#<5ag-H7KF@9Wq`=o#pGIaYKDZH8;q8{enb^P ziM#~q1mcEhk+>Ro@_RVm(V+acZa+E=T01;Z?(EelBe%*P@=O|I!VKkpi~NUk$~<~00CC5shFD*F^2Uiap9{{U%8=ik?G zF5|p)X7@XvSYv%M&sk-=Mg&io6u3MIrn)Q^w0Oa8!NY~CUGB&-Gp=>1c??>22k*5> zHl5ASpC;E+)-mvEkcNG!l9r;>^i!G1nJ2a$L z;w6Ks@-q~qq~j+qlht4TC@L=`I9j)OyaHJA$7firv*EEQ7}=5a6H)vzjYTvXC$ z|D9YWAz{rdXQ}79@=>4`xxzIO>U9$UzMW?ROf7?&#aKi$(5pA_Z1=Pxn+%^Mig@Ip zbH^;W+ZTONT_1AP5<_Xe@4cyLZS5BN7prh}w|=+Ec83l9H{8~{@M@fKW?M_Aa67>| zC?w=9pmx{|tD+KP*;IiLLr>Rxcyyu}y3)NRZR)9xAr*?m0CaZOX6f4|`OYk!3@JUR z|DS>CzKi|70PF$s8qn03ce}rySFh4JlokVxW>xknEA&u((0l2nb+%=N0hAHUiZj?Hv>^A z(3wEoS`S-*y}PJi4>>uzTwNaRD1W1|Z;n~(xW1gi%qGB)jd+@D4LBMfVDpaWBa7a`k(kV@>V}^g;Dem-<-r#cQDTQ6P!ro7N%@GM-8*Mf)wos1 zgVqT?ekQQGQ~gSx82M^Dn=x{EJpOh;nD*_V73|KbDFCgZaJ^k0dRgs}FCThwwwqp2 zzDF7z2IC;3H)ZQ4b@hFBc6_m@#aTITsm%j>+(Tel($4r9BV#m4Vo4H4-L-A-jl8@S zES_1S><389_9mhzj>DmHWGnK?MC#3g|E`IY@aAap%^sbU8sPTajFB?Zd+wIbw!Xq{ zNLY*m7vVE*85q#y5qUe9;KPeCTYl2<;f{{$VnhiCdoiEc;^8Aq$#XW!Qi-O{$TEq+ zNGC#{E?l(L{aE&z-)&pyHCvm|lN=>eixN)FGNX_KZbmoo#ShF6)gfvEDRBb6Vq#`M z7)*R0B}mw~lvAx12V<>`+1#A`OfRe$siK-D@+p5$md=Ou=XY06`-5-SNFF!wrBC06 ztmprjYztM1I;bs50bIEoHnM2e8-D#49S6!}#(Qfl0PAh8b zd+td8C@Gm&Pb4-=YgSX8h8O{LJN(!l%mgAA`y1jAPpH*2_{4jjjcHMZ%Xa&alX*NB2shly=_9!*m*rOc6(dp0Y$CyjdFFSQ$S@aN4e6R4<^*GJlwrxqcwwv6op=rCK;FcADLfb;Ro<*Y+zZhSVBfa7jde*ES>IYl61h zY;@$HncB1WICZK0bUp~r$OUy?eyTS6b!H-VAm3>xu-3?Z?B`-h>?q}x^K`2l(kv3| zO6=#H+k7%sJ%h)K(B>nec>(X1oMv^z{bX&l8i^pVNSU) zg;ev0kcC8*6Q_eJ-4aMk*EUP!1I}s=yHC~&lh5gS2HJC_*KIuN^OMou9h~pxiE0eT zZa+8hN<+S>(>{G}HEYt}Pi3MPPrhk_5uH;eXw+0vQ+-vYJ8Pm{rR$5i&3GWu-lw{Aj~4&LligkdTN z<+-ZutSiJ+oz9zLZUnp{vPs=96wfP30!ZqJ%N=nBZpRscM?nSHBr6I<`spu)Jy6yM zUULvBMZ{>kwMkMg9xMXSa#mE=goG%mpz=jdmC28KP7;s_T|d=}-A67eQK}8T-BA74 zlgy29pk3AhFKO}%^vXz9JWxHGAQaau1gRSnbJ^RI zz=RV48^O#mzkc61$lHEgb@h!|s3lfy2*}glHQG$ig>^%9KcO7vua+*q6qjr<8_UV# z1A+7Z@Kibf^Ix9KPQEJL6wR{IPMrjIt-3>b1_kwbaI4O8(Jd_yF9!-UsLb@|3`x&3`uE5$WVdN4FUs1LOKLVL0Y;SWpsB* z4HzXL-O@E)I64MO3~8kMyZ85Y`}_g>FM|lwXP^w8U0K3`3nSgXIdgXn7#bdSsC^z zeCQqH>%MKipI!CCHf;zOS~+?mCWhxjlTiEeJk5n=1%DSXeVfF6f5t zzOJw-L|iOi=R;1sAlI6 zE`V{z?VFer6x@!CjJyn7EpvZr*;%vcL78JDx;xb6&_2pa+)HsXV1Kq2kUc@RcqM<= z;lB7t4aJRUFuFOqbnI;XCVhw&*HpAEvxPJnon>M2{dZT$7Y{~LuY0Zn1ck|DF1Lqb zuJ-Q852amq!9_<$K8?97-^niyf^PR3_=3G2P?HC;0Y_^aDU#$Yxr{ENITQbmwzrSg zcH)9>SMS$p&3usK8c6-a?uXy{V=0=e_XB2^a74gmZ+p?l_7(0HFg1bfpEp`pv$c1l zk}ll?in}Kb>nZD-zo%lF3zS}r$CKPZoUSJ}-4-2%X#op$Ti)2I0uUR!E?#*PZK5w% zTFx`$V5{m&r)=Yl3(+Aif#$AK{0fh`9j3LvySCh_{cs@CnP~4SdF)oI?-F!* zoHvIR71vCxSolvT_>OYgl1!Pkx}G)4UhzH^!M3>#L(PD1`NoQ0Y~bLrzNy2qWYyiakk~fX+>1&tqHO6$769)|fGFuJB`n zk%0K|_V(W(h;4+KqtBhW!j*Yq+rU!yHau7EBH4>|cmQsaw+Zoyz!_rJ!Nt)~pu#8l zky02V^SFk_r07zeD^l_>HwC0euB--qorE7iSW^Eb z(oR)=DhIItLfsI8XQxIn40!WTM1Pw%G41e2x4vjMVg(8wX1sW~WExf?I~y6MLuCOh2P+R0!NgBW4c4y!Zm{ z>hrlSG?4MF{KQ{gR6l{Ac-{eLD+O6PPU>RMk1Xk~&yGi$V5Xh3Y{@4`!KBx70~Ttu zm4(I=VdRKKPqePvQ?hM_wA^o88&pCRhg0M74OYQ33;~~Rd()sJoIYPu>AxZ}Dnp0f zJ%0-@6=k@2BA7AKZiMMLp_iOgo|IZhxVze7WOTflRvd~wfit~bC_bVhbz2Zmi_7zI z?Reb(N}H$i_7*o?kTB%?+hV*F(^`qLW%5oKK1-_58{9D6Uk8`@CFfGnX@Bcf2WA>L z%qhUFtS6}gvS>|#&%?c~;I~QF(Sjf`E(*viJ+4X{@eJ*fEw=d@<5>=Hi`K%5vqU&_+f;ebhN>EiVBr ziGgKC^}a0CEdhkVIH+;P?6hZ6l`IS*N#gI0eIGU&*%y3mgZ_AI`C|CNAS4cZB{yaJ zHe)+t(G?vkKf+mhx`EQ<%^0(zi$4tPkdP$mq06?*wx@f{D&eImeK-AkN{a?>1Ct+k z{=b*s!~ZJ7D$VY8Mn*<ce114l@8yNEZcmi?5!`h1y@U}x1~m?@{zxP!za8b zfqII1+WCWa(Mc3o!)oK2IL5elG3b{%Al9%^2uiK)l(DCiI6Mvvw`K~S4n=U*YaCONQW5)#uGcKJ6%VCIqutu?W(rj{^vFC+`Jn!za>-(-b`-FQP+9}y@rg`fC5k7%~)*D?Z&w7RenT?8@vrO zyV|PdzJil9G<9}VAMEGot6uFL*peU0cAQO9?x)1r+S-%~^km_DGeu5MEB5k>R7Y>v zjia`$91wQ{(Yj0!gxaM+<8-t)wL@sHKS+NDv{U|zse17;Nk#ocs5F(%$@99$x5Ml1zpL%sTEeG< z6XK~~gcT<-ic4^2@gOvNKb$QBtPZ17V1(n~IM{t} z5M{*;-B{Mdqas#6>W$=rJE9Uv~_Av#Qi<-e_w!vF^fOici6ITo_ z9VgcpLENp3OpHOtrI=clmpA~5!`sW^8}b7_vIOU4KR3F_^R>0O!%if!LXH|R*)IN6 zVhesOUS`pdr)|eR*$!tJw40ANC*%geH}^I+c4mr!OMNd4aERrmB2Q56nDss)@`8Y! z5hqnqmlY}LXM@_;0=)FY1UYc>gHf$F`$@DZQTchjC5M^Jh`%=6S?!L zOP@dbd$n`5q{+hk>LB109hYN3+u*y@zkdy)^}$RuJFm2e7fdd+C!hlluV~F|;$fFZ zml2H@8wUZ`Bks)w-lomsvXWhN^K3#Zf409n8K=5E3hf%$jReTk|K zK2(;yoRTEhMCJ!ykGi3su7#(}q|Buk`PCiVI9iQFkR{?OAiqS!CSTwrm8gsmM8%Z0 z-wibgbPM=zZGUbxd>IsQ(Ur;wlctbdCC|7@bNs4j5)1pG%xXwuW52W}9l55OR1+u6 zX6}t5E!?dsNnP58_Kxo~j%3VJvu^jLip;1|OFgDkKdxj*!v!962AJ^$lQQkhA2B4j7(=a%+W|=}Dr9fdY^|ZsHrb(GJf_%7#P6R1^e&IErPr~1G+ppeRLk<}8Z z;KTxwkJCIR%jy9`*ab`8l)2J>&23=SIvl%T_s(1Lc2D8;)A2Ev!Ci1{KtNzeD zO6L+mAin8Aw-zdQQsKRX!URez;mObFaV2W7B@q2&+(6M@Nv>+wH`M-ERyHg07B)eQ zP>t~Xre*&weWBF#ZSOnkORZ0SNl&@=0@{f4rJqKP)KrEKD?%0Z8rvScC)S^KXjX(6 z(Jm@~6U3j7Nh_qE<;!@Xl^3Y9Si1kTKC4v9=!=v-jXcObu`U&2ov>t7wRbT<{ytxUB#(KIZ(BOQlp*%PVAjrBP!s zPF-oTO-*v)sgXeqrnNI3dy%=Q)WIE>ikt5C2=pC{*H*JD?+C4C8QKoFwTa;P*$+`V z#2S97mc127*fhTY1Bek48VcQ=+s(AZavM0Yon=h^fbj6bjbv}HmbFT*kU}Jqn6JA! zYs+r2mQ+!W3)btTlU~Fb2VeyeiZ~CZCa1}y#j5PFQ#?WGt5S^M_tV9`8v_6&m7BA8 zU~=GA*mxUnDMwNFZJY~i7;EKdUJY1}ELgdT&D?dM$TmVQNQ#7{p1e$?%7Pb?Xhf^6 z8;(jT$$?mk3g8mHFN}e&r(tWOjkdFx3ww)4Ff`<8WKE-8qb3j}?9)OYbi1&F?(Sa#H#_Cc4SSVozyZeG7$WFZGsW!C!%Cj({Pnu@1oAA)v9atu1w zMbTFqao&gK8=tu0MOoiXTHSsuewtXq6CBAR(cJ{M;NqKO1>n3rce+5Zk8FPf-pZ?`nkDCEalPMt2RCzfv{%pbq-+4pi9l*VRIBxZC^vK73q@->KVeA2 zW-llr9oFCT=r_9nBVCB0YoKg$y7wy=s4uGEO@vBs@8tRn+ z3oB-vg#hKD2)(F^6H=H$fhDO;;@bn!9J+9Kq_S*IBO4(|%`RDc(N`y0&B`luMVE_T z@bktKi*^l!M70tt401`6tI+Th4New+T&K`4l~&_k5a1&q3(IlJ=c7Mg7V65|&wZZ5 z#=<;tT{ti1TYKllKah%#!9whl%SZ>lzG~se0`Q;0y6d;o^8B7N|3&!Pivnpl4DC}w8UyjKYaQc_pz zhaFxQXuKikTzHPCbH~45Z#9=&uCB?05&`!k50{$x!S`SGy>74s|J{A}Lno%d|NQTB zm-D5VeVa6RXiJgL<1oRMXGZ|JJRCVw-Hc#6qu(7of zee=(rRe9L}ve(t@ViDUfL_1UgRiaXM?7!M#&MY|&9ReAQPrz3&*TX~_w z-9G?FLwaugh9f+1HK9*zODjg;BvofFA~^-2zn_AGVEg=5P5k*JF@SBHj*{Z3CDMpR z+*Le+TOJVB4~vM+uZYh?bbmRI`T#Rj6@ggR;E@WxD1t?NGG(azH3`Y`Rj52LAGH5g zXE6@wiEsB6eeZ#s655C?E8~;CFd^;*2xV~mH%Rkef4|;I$^i<8WL_}w*|trCjWRJ! zn9I_(6oc_h9)sLm#KeFh1Af}cJCaLDN8Pm1!@EZyW46y3nkp+VrajtM=-r5?)aFpC zGuPS9IBP&0$o09U#AF7WDUw|>rG7V-pPiV$b^d9qH#+b_H26gHVd3F?(s{M(?xy?U zX7}v+t(ouH0w({ampqt%w=J)W@aPver}o#NcGNtjC z10`8|H*j(P4|~Ldr3tz(8fydoE;gDn5Ac&>X?F64zZ379w_+rU*epdtCS^Kre!k%2 zBTH{+GOguR{I(Aw_Q6;ZKd;=kQG=!}G+dy*vw=S9H!f5yIX0=UUz`)r%1cSgJW;=` zoV)*b>*(1wLASM@s`f8anC(1zYE+U%R*dBV_uu(e97Cm(~Jaz{AoEGrzx^8MPnU>$+N47gx*% zUH5L{K6Glk#n<74%>OW7^b&OIir;GLOOHZjj*2leF{^6W4h>nY%3ge-b&)!w0;RJ# zHNVFpRB78slc704sZuiu{k^I7^=&C3QfA`AuuyhiRII&uxnuV3t3( z=Hd<=urxpX#)l5wt6lt>hwg+S|8#8*zvkS=xda+- z^wiK@!|U-Ps47J`{h%I3(8jpce^^eX+!6MsXR7pyN)`OZTk(u;eKSt!HAS@Q3c>3_ zx=cI(r4F982N`uLDK)E-GR#P~Ut1sV=vC#sP>HKb19U9k%1Y(Cp*C-__VFvKr2p#J z|AkW2Q9%X3mWD+xq_K(P;*e)$Rfu?B9>gOQw-b8^$0I_7{kM`wptdf$X5k+hAt62G z9DkcRBkY-VZS?XwF602j+3JsCQYWx?^&5ha2~q|Sfbr`OsZX63a$lzsmk{Y=DIYo| zB*ph{^fVPS)bv2HaSHuH)I;OF{t4zlTndYBb@8zgdj?!=$GJo9Ck>t=-gk~BX~C=@ z@qeK>M%9nk9N=}ar4tGvG%&d^6&o6f0$4O;0T z5o@N7I~A3Ap2?+b+*$d4_kQ%xEmaq$S=C!nhD-)X_pvJOJw`}|KpH}QF|s?|QU*xR zFX&SYedno|3JpAMG*Lrkla5&IO8_l-<=-*Ndr;w4F8Z-s&hxhQDRedM#cv4;P&Te@ zyVDxLAcL9OPtz>MGejCwpB@#z)zZ^JDpCbH%BKvP@Ios?SZQuQT7=khL8DVG38Lm9 zbUx=s0s!-~T(MjP$@U!i54C(c)<@xk@d?Cl@9fYI4#8?4^0YbXqLSY zhS$1>l_Zmg9jAwrdF?p<{vH?-A6V!HRs&T*#7ZRu^jM5iqPRt>({TU(19UQoI#A5t z$&l_O%YBv%gFps>x6HN+{ahH*h`CxbvzIhun*tfP3oDaNOHS)6y}zk3fg`Pi!F=hF zb2YMcViIk^0sjsk3S@Kn$nVP@u7X?7`YA6CR&F|1Z#r4-w&ce-IvJ! z<#mFN?ujlAS09d*SB}7V6M3mS66a9aj)0iUgrnji|uBHB!MS=y;Cz+mLms{WsZYAqDR>T z=VlH!@B500C}jMGKF&R%aE*+6n z88HKHv*I9~k3)JS>29OogmrFCOs?KXe1#HiRUUy@b_#})u2qE5+(h09#0SGJUs0>F z0?*95h+7A2kyh~#mPyS_eR0?5JlMCL$#&pWKT~R763qnI&(}XqveFjhLS*pciTY1M zQa&g>s&`jkVqJux0BKRd3WSFR^@llk8LIBdgv4F zx>#WmnPOpn`N8kFbPV!yh$Z-T(V2|@hNbx8_gEvD7+ z=_{wx`{c5h-}l2V4)&YTJgpsPgYSc}P5WyG4+pi8m!CxWQLc1fyK1uo0Nk7tZAK$k z0+jF~0aPZody8;{O)lSFHKJl7V{GyO{demGSX2SRVeN-kd+_Q=%82h5EuC{fOJKyh zVS1y!xnG^p0p~}1gJ*r=;RK*`&^RJs`2Q{J#(A5;^>x6~^~V%aWD(K61dcm0I=jeke1Tp|W3M zlQdz(XE*NKCmbjRjEyR3pcfbC#_3_c44jM;5^^&cLsmcX9~(rK5DfS{PoVYj=Y&m9 zj!#fs(81pf^xZa@09$yJDnxO47v_llulFf3B%Ue=hTWCxoId3=VsMP@62R;{r%jQp zB+*0ZKkaE+(%(z;u5nsA^Sf)g*U<}6iKeQC(b_hhY(!I+2Yyig!B7w!|K>F)0Z2WdSD^i2c*evFRI5`z*v?$W*_4#r5e~nmsY7eHFw4$|th@BK$4+TMX zotc@&71pC9X?2j6mV|2a_-0AY8IL`(;RBBGDq!`%ouz|18AU8ETv3>=D_kn%4F67y zl-!~VXQvv94H2J9SoZE$qk(iNjuSK|U*;dOr_v#x`CE z#h+AdSvBlrFnWQPURw{Y3t&^XtJ}6b1ti9lX!nd8=rFLlaog+A$RFKs2)vS08Cdh! z#&a(~fxZrpE5=IEc#_V*^ob;O9SCtj2ov^&t46Ql=kF>kbGU@gK96j`f4r(sL0{d8 zx96*dlQ)J`yszG4cnec&aqwWbbToc8G`1zm7DCU)qp!x!-a?N%D`a{UN& z(`tm3jFsz;w* zeV!7YVtMtRtE2o8C%+y9N3R-ZK38(F$2m4 zhau``W6e1+>atICj1vYz$S}K526^KCJ>nd=E85eP=#@#kms2*^VJ9M9!Ax<`6*%RZ z+Z4!Gq_;1rvChvi17FoRF*2uxbAY&t;vrx2Ue|p1XEWGu)6{n?o$sV-h9#Wo@j&37jHMbDnqnX&`{t{%F#p)FRql3&vli<`%7_ zqQg$`TzC66uWW5pze%+F7a+yy_P4tMv+Ko?q+PPY zVob@IQ9tie8WwtAKV~wV`3bBGzFx3B4EFL)6CJ8NVKAVLjEvDdEa*P&EqIeYal~DN z^7YEMLgnV>eVH%c;U|^!W22y_34ypc0*-qYs)&7Q6}BTGn~pZTV&DXqWRV1C&^(#% zgQLU5BEkhH41vV#Pt~uS>!2dEle0b$zQGB}T3f$CKoYTPK1K6GMS^i$lpTExm0Zk} zS-02ci+cq;;l5nnyFJ#T_`eWXPY_YC<8#}@NB&W4x0ekuO=svNss-n=fey}~+op&w zj0n^Ej>tmBf;>C`XaH`p<;s`>12SYna1v=M(9wRo0&?Gnmck6He|oygw1uoaXU1N@ zRv!;ms-#rv&zjS60Ps(wDvjs~nxYWouA!?99?(vQ(gvD?;g(2LUwdVr!^uFA;P>2r z{AzW_D4(m*1)+}^G5ltSa0;NdlO|p!H!EEoJ8&YIz|*!;WG*DeJe(y`_d$`RoaHG_ zJ*LT>?X&2*#bZX_y|>x*?x|d+%IRU36)v#!i-cweP1+38W zJ&e`1@EX|z5Q%O58n0m`fIUa~IK=ZaUjDR?UtMRkV#B0l*pb;`O$ilYHy*JeMfu0R z{YkH=lVbn8o9M;Fa>H{>M{6mEmh+`S(l!>zs6{F#hab-$1F}Rl zsl_T1a~B!vxqs&6~f9PLt5 z)JY9N2sRC)3XLwm9##McYQV}7P--0d8b7B`fC1}d$LPl(JO(IN8i&Z%ufwu8f%$D~ zTU}XS1}QeRizb3Hhs2)P&zc!?2v(BSI|nE4z;1=GT4Ko1es&5l<*w@ngZy z-W8d(sLM+$jwAD^FF-1>vW8nZq^B?rZIE2$jwWKsng5~w;v=xvzL-98iURvsk8imj zuJDtg#MDt7AoNuWF<{n36s(SJcMvVu-Wp?BZG9kmI8K-}pj{U-?e^WZ4L-o!Z+73x zisVd82H)-KsIChIe)jvEylmpl&tV>I^Jd}7rqCOM|V zTzgIwsodaP=Qh9J_Zpbg19%Mh^d)F-SJP&LY58w$sNjQoCwSS{8-SCP6moG!5c;>~ zL7yqrX2z!{1Wq^;q~Iv&*utl_r+_kCc7giXAQyp=L!6U{fsT z64fKB&mZj*$_vLIe6;-jCC$mgvN&e`YE6L{B(KJcFA}4U>gU>=zK{mKNQBYUOd;iZ_@PC-ABOBDJn2Pz3OTmFjSRSJPT3e3WJsK*cd-PS!3Go`K|)x(it&& zlO=v_NN&-4xM*?q@3oK|Onp6&wJ7FnpgyZn{c!|nrgS%P1o3pz07Az~kHEo&yaC%* zHk@6xM&a9};D)?Y(|Wx1pHM$iF>+sD_1F||ymTX1`;$CnfOSyB>0+&sj@~OtCJGQh zmBMnAGX_S^OaYC3wrf;9OCHYz(Ni$X9!z#eH4(pa2YLrmR&YjQNnorkY^(Wx$_0Bn zuz*=Q}qqJ>0C`wWCldjLT}5>weUl0+{prQ`ToVa^0&o1Cu` z!z&wRc2@(L61QRoW_aY;Er<5zC4*gEy~JF0z7@{?2*GBKN6XoN_VqzyaeCl((fewu z7XAJO%f9DdmST#FU#qw(?`RT)D}&((f}aZ_rdfYWW(DB6+3s#Wv-DpCabEV`xt4;Ba}IWja(9gs zSGHaXYHxT5mH9AE_igduz|_ce`!4m7q$zT#i9|W_B>8NGT!w-|>ty-eN8&?XmP(?h ztk)*4@1FQX5DzcRlX9gk6yX5~tRhdu4-;(KhYVeC5E*3BTGG;z*mkK-eY-8a(qw^t zWkx3gPAj~edZBzZb!$xxK|EZ=ux=cUZ}#FD#v*Wz@lRO)5dYq=T(6*RT2-`qIIvXe zv5r|sSs^VZN=j2lT+Cjia>N(GT%zsaIxjxCx8NJY1Wz4&JwH{voMyU8+s14B#ft)D ziTt>&jE#Ter|?vMPQCf_Gidh9nsoR;t_s1yYIlpTdy@NKV-|KvW%ThBj)wTfl*sP# z#e2P#^Le3O2zznrhF8-0DDpkdUGQH&l;NBDUA4WJ7idF))ep4@KOL9U79p^7A^Qc)c=e}!A+&Ng^jD&lp z{M{-1E76Eb#A^0i#pTW1br#VRJE^=v%H1Tr-Hgt7`BSx3`SwWfr)}jXANi`?h zYh*K%d*24I5}6ceT&*t5tFJa3(Vv>UVF(Oi$j8=OPD$COagc@5^(YX(Oc9GjH@D0g zK`7F6|72o=YE(tqqe7{7fo9s4n4WJ4G}O9zH#!3X)yp{)jl8QmJNR}8OiaWhP!d5U zM=%mhqCFWld*Ev|B(Vq{V}bPg-y#)sE%cufOMid@Wh;H>0aWt9nH?flkpBt%xF*>) zT_7v8yx#kfadgYtr}xRu7664olczk78bSbaV}(}BcGpOMdAD(>hcr}Ay%d;qGSiB* z992JZTB1lIVmDx7XH6IAAEBU3Vyl7Lpe6t4<=3Ycs*&9$lH}&arsy5v!;*l7hG z4MWzLMl_}NOG_St*beqTnK6BpgyAXNxLex5q?N%hol5;1$)u+{&1iJ;g+b(EA3jSa z6UCs1tVIL*tKL?)if^MDrvcEruNfad{AsDA(Kkdwa9&>cYy3 zq~gz$l=hgI20BWYSIF_b8Buh=)!AGv6Vu(^WWX%rU1j&}wP@Gf3cLWD^0*z~yBp(+ zTmKvoa2u5nY?%wkN)_Mo-L8F^3_5REy`L2|3-~)Q8F*bxbRsgy=>DNPy)5Qq>_=NP zkRt3uT_cv)p#TINDN>ags=6X)NMGaWyfyz5=wjoEt5Xq+6t^iqVVv4g^)7Xc9Bj{a z&}yF@O<|@PlTz<m=1C%ASA2jDBw#=gv{YFh22l%vmnvmR&M? zad6tJsOk00fX@x8`Z%~#S7d_^pn%7&C@9P>sPi#=Vr^i$rfBw?#PglOpJQ?s#oco9 zLI7&EKN2xZ`A&G0itIHv$1BJjC1P)IaR3t}xh#9-SNM4-lK z>B&~7o_qdvq;BNL(ubF7)__uOebZ_q=``r{^nd>qDntTiBfe&-f;~?S1aybK%;RE1S%`I zn8Qk83YnIFm-O{qmOFwl)uJvY-B~E_sUEa>%0rtfkh63VGd)*v!~V9o4(4+6y@BySu?JGkmI7dp?YFXnz!` zc`_H^Q&>!e-_n0bjphavL4wog=EHoxbOj32m(jZ(hH<@LGF&=+Z;*DBx5eb9?Oq)Z zp%*e;$2S7poJ`Ctf>-cW-``)}qrUSzA{e(E)wX%1A#Q-86@09oaC;L-{Rr28JNI!vE2pSN0I_7da^zh6wb8?{0(tPo&7_M9BYMSQRi-__T=d7N zATHn-2z=(6TZHrOrCl`GcK(mpp>cVX$_tE6ZMp|Q(aXdQZ1k1}P*s=()0mhqjGE@W zuzxF{XRTDFg9EfO&*9><#DrNX^kg=a`!(CC9^-hZ%}kH)2GZpA-UWV*B96k*twyH2 zs46C;9(=VVwnxl>5(-!oePuK`$!oQYFC>Xkq#FOj|95b@d-MebiK60nDxw?^W0OCf z(>L+zOcuuuNfb}k;tQ8$2A!bWq)0a;N({CW(AB)DWWVYyUb@de?Py!;TFocNNs{t9 zEBZSkewVRKAf5&nc!T{=G<;GzOab_U)SFl8FDa*5d6&>X{>_fbue@E_`F}jFz&G5~ zDzufxuL&jqf7r8R?FpC3;=}V zh#D9~&owpX@N9-i2@8)ATnOzF__JAsX^ylmPo(6zTEwuTB9Fe6!jjQ&>jo&@+^}D} zM1{o3uvYt1Acftv(oj<8(mP!Imz;v;HVUdnjI#^$FEjd5>)8o^bv@~FkY88iNGmc| z+h8y&0sMeB6@KGJWDQE}By2(Us?KfBFY{d9>n0qW%Eu7mkEqM?a4wIXAZe9GY9$cBuhQ6BMGM?k(h(rqt z{zr{FMc7QIWK(ncrHFveQgz0lU)*_-3(dl4Kp;XUo^&Ed#Yp=-^SPjc+$3)f7h+jr zxF~RaxcsAmZVC+{RRdJb-W)}hE2zT?A(DQVpdk`8DyO2hH>@|9k@e;cpof=LyV~9| z7Bavy4X;+bM5tA|x}g0Pd9-y!p`Vu;D>k~E_zW_{IVrRn9Md`5;lu73V>_<=M* z>iB=JD$%a9JdDgut7gznO2PGXS%Kfb3bThZvj_A=*F~Le!ClSM2z}3`)T?6@^TL`Z4d;&oWQH8^BP`)d`Ar<4M^qk? z`Pz!>fIV^-Mi!=hOlo?@n1wW>tVdpR%WKcyt2HD5xIUF`1<89IcAXah8*S36{Wk4U zM-hki^sHXi!RZ%3N&79BlYWE{P6$?FJ3^mct>aT?!X&oZ8W5}B*ci*fqKTSQ$}pwCHuSJE(JKFo&ty~hMDHz zOng~GFALExhr)#&l`I}50vJQuy_@{@t544Ugo?oPiIm~z|HZ8rTrEugoOwyLR+`~* zH)9rfw|9G6@tpZ?TQhKD@z~XA;BZCqYH_an3S)M)8;n`KU-DP>FMM+5i0%LFy8Ja( zhQTy&Wg30@xkYFrR6lUFFmUzPd6mu(`K9o@(mbs-VGBT-IPbsexgYQCj243VOf{i0 zoyonuedoRql9Y+nJq}H6q$}i3HzDC*4GEVohkbWp^gr|u^YHuUMI0outNTMjfsy%O z64TzQc-YBKwt?63(WzoY_Utsp>}F>!K7sru?*oAN+o28MKcOd1XDHLvC%b3&7OX{0 zPFY6KNDJ=PX^la^l9xyo?H>Jn`QIPA*L2S@0l6SRiQSiP5x;!89vMR#!tYiNI%R|o z&O|k7E7@$p?5^u?(@`@}@sX1*LG_r;Fyb0BS&6nL7aQ2J5VKr%)6IOtWXJjS`-Qy; z1D9^U<3XM%9GVef$_3J|5c+wsD!8l3ll8`RD?sLiP0Wn7Dz+%I!tj_(67#y%gP z9dab80f4A?(Lk*U>UIeO#8#ed$-)P#@4uPnHak*_czRpcAjN#Hasv|FHIktS0)y_f zCnaBcNZDHG8W8{R80424-xJj8;b|8dW%&E3!uN0>u)!Jzr89XB5+fpYhbDyBczF zNQoT)l8B{4vzlsRz@mabxx`k%__}~n`XQ3V5WJ22vkFnOP^lCAVS9DwB z5vC}9E1KhR0Pr~&Jd~ST4EKx-lq+h}j4_OEwNnsukY|7aV|V6X>)A?9Yz~y`&ppv? z_`#dOzqhxG49ZEd)*4w5&1c$tDZ>rAUK<1(@%HN$Y%)>vTT({x%zL?WI7%w@yQ=7@ z$+X}O&^z7Oh`7jy#Kma`N}M>(0^3~kW_}ot>pDkHOW?)LTT&3MNoBgnzw(&&a zN2zV#kO8-|pK{l0ii2E)MzuI(KT^;TH|zXnRR*u%5Uw_s7JR1%WQD^?6s-}ZM(+a#!q$U9|mIAb>73DrCMSB=j2zR@si+&7#wqnSVxH zUS1Ai$Kx^7A1T_+r6@d`7B^5ccuJ87@b0kPGX7$6mF7aD2o7E5q192xmi=0rqi-HH zQCN;s;5aaI<3>lTYKZF*5$FZ(9S>zxZca6>A8%TurKmsztADMi{({n^ci_xg zma@J3eV*&S?k_8ayTLfzzc8SyarN?6?uvHsCQ2)K>)7JrN8Zg}_O7FmXI&?6g0F?; zZZrO!=G}Y=KBW5h3oG{zNWca*l8uRXUdGi=P1ym>;7M?_!^1f&wzSt#D2vEjQe~`v z@sc3f4Fs*M4UBJT{E5Qv>!Xl&f>{=;BMEDJT389vi<}dpp(Yxt6r+{Xu|^@LwsmYq zy@a4hDdylu1dNgS?SV#WE$+9(LbQo+oX?vjmEULez0NUs;YMLBA>MmMekacXha&lF@-{vh|obD0p8`wfqTjBtHpUKUBL-$07b4y-d@yRa# zyRO`U^52=&e>r_bz0jed$JM7*=d#Tc-!*76sXyWZfiOE?#ruV1W%}XA{fuyQ$%A#m zkSRKY#{7TrDqg5C(M6>}IuTNo(0w_=R2l9z9y->1`2q~Um_V#UChq=c-iw$xY>%YRh> znS4cLf!9qZSmNO)l=JEIw4rN5-qSV|sn|(0dHsMBZ1@sj+|J$ztoj}O9Squn%iVUKca4+C#p=aR{rU4J?QX_G z`uOg=s`Rg-RzPj1s*dmesd(q{3eF#^%X6&~*>FMEQ3Xe$b;%yxM99W`@=hGIUeE((ehcn)Z_;6}ij0r1cqp zIQsd6G$6R<>17ysN?lqGV>NyQ`g@|fAz{5uhSwsj=>duWyRLRiN z5^1^LJBZ4JOXqoM$po!$yJ0cIn?SDiCP4JDzLEYt@gQ|ymdKf8TyE9b`FYUZAY0G@ zEqgV^Fr(3wh|sa3c+G1by;%Rj$eK=X>}*Aih8|x*;G9l_e{`{XqiI~l%+=!GI+X0` zy4)S$5b+Z=-nG-QaXl{D95}csk4(6qdlSU~$iHrJK>~3x;ui0;+@)m~6{kLs_(xQe zp+PJ%_RO(^k!`Md7T?I7gFH&}BtG#n+R z#Du|B(pqj zjAd0yTlWh}FuW&W=bg))=gY%kMND+Bcgq@)ORck#adV$K6lEnJ>F{$W80 zJgEp7ub)9aqE=!U{gG2LTC%*Hfcu9#A(RlpP)6ob;ADy66i$5$9ke&woqAM>7fw9{2GFc~G4+W#8L#GuXy23<=>~kw7Gbajvuv2 zz3M222t`Ln@P7~7Wv)>oYM_g&Q#GWm2p9J(VuFwICe3b2*DQ7ZfpLoDc2J>ro*1dU z3dyFYP>&TADtFqssCnke@{jV7qG57?Jje$FZNS(Z_K1vp*rc_g=Hy^QU?_|wGDXEAxBLJ z=WxDQ>1;a5r=%OJE(%Tjc&xOJaj7>4C;AMAhwt^+n)a>82xO4`brZAe-W7LEwS5p$ zGnA7h;VUfo)ROx#1J6f;mOFG9GDD``HLDY*PzSevJ4IGByJ;iRU5%@5em!G&N-iKI zN;vd->lg$IXG~WTO&LiRXaM_BQ$1099zwiPw!@)RM5Gmtk;3`Ril$Z6RTJe(5*n$Z zcs_>G(}RX|4X4tf}YQX#$-WGbV^Mc!03?b= zqk-L4&>c4T*C+P&!w+3ot8&+SgBh3o3>G&SL~ig_2kvt18dGmBFuS{1Yu@hwq$nSQ zBpM?)wCI^DoYY$!ZFauho5|K_P#&y@!-$(GkuK3E{aZkbWl{^9mOmp(ZkIJFkbLIkdQ1=_#-9VeB8S41M$LISErP+DR{O&sQj zy)C|zWTSWmZ@TM4hRy2cr|Ceu^Ms&p_9L0POg6a%sRjO0vf&jnUQ=iIJp+AX*`cCC zmfFJW8X}t_l)G;GS1H0Je`fD(=eTWcVR?QB zdL$|&Aj@!uv^0x<1IJC~f%|oXY*&Bte6Dts_!-iIZ)a*&TTgjGEPFU2Ec;<#1n?<} zx)~!UV!7pxt3C>&#yK_ObKV;fhADqF>@%Oy5m+%A`p;Es^_r-0!=4R)X}I42;zW_9 z3)P?B*N=KS_{gy@`x}k5p%W9I@q08jNvXk^*?V*YN{DBtQQ^p2ypO0c%ab|HEoJ?E zY28xamXXZ=fT5Vqniy)J7_K|wQP=Ff&N)xG8%npZx*}fX{V7CsO5}2)3||;UMnjJ$ z&sJh3CG$Yp79VyLZ^JK{hWh)cs3RxHZg!=)vFU9*;=pVfh`;#NeWxkS4mqrnnZgUL| z>|3{(Kj(Mtx`f$hrmICeh(ZnVJdB?xwEKHV_MgP$U1T(M9X05Nh)6xXmJ#Js5og0J z<-AFBSCvdlo-(-3Cx=d7aZE|jchls5()UnXz_gfWp?JR`!o#66W?N!DK@ye1}G3z{P&y+Gyn+MfuQjO_Ec=);( zw#eSY_^uW~RB`0ihWL7*rPgUvsm{O8Rzr2y(p-K7-x0Rk-GAOqc=((A?(g%99I3-+ zuHC_ZTbMNtuchiCt)^6SHDheSCs#d~0GasR&ENhO{~XuFU5NR=OUEsMem}K)@)JOd ze*AoIZqesJ1NOTAX0lP~(9zT;faU!33Noy%}TtM@&%^y+M zC0^4U;!0UJ@#E`jv!$y6(XWjU zZHDndyeJrTqJN0XAeyhm2+RQU7^4^l`2cPw1 z`>WNDDqJ{ib$Piv=l_8OaO=9_ z{Yl7=5c-@rNj&-0vj%w*kji~Jx+;A7naQVVzjO3v;&|HaS0jX6ZbtCiBFsj=O|qt! zJJRG#hf9M9iG?&E>Q4*yK%oT+G(;7)Y}#QE<%qF?TRLf@r*BA^bl{rtE&3&t5H5oB z^cP8r4;s>wQYrO~$?EL2`)`##a4X+}O*MwcD5y&uXy{=FZJi^E8qWus&1;N$N7^p> zXtkcFrP&V{pj1V6VaN$lN(doNaa&$+yYQwhecUPuLF#e>$x4J%I96XbeE z8L-%{(|28`C;k`!P+jQ)c$@WqXL+}{u9mJQENk#a#(D4!*Z7GuJjmN4$QvI79a4uf zKU3DHPEmXEV2aUZ_(%Dy38%urFMysVrw}K`{Ysf9ucU z**b#U*4>)u7QVt-|FC7#^NI17i15wj|G73^!i6_daW+#^>(uh=PNBwM(@RsX)y<}<;8@^Yu zUz5R$&(&a-r$^&aB`&X@vJ-cvSOZ#Ws=L*QQf|lr9KyGib}(E!pt_G%8*Nc#isZy* z>(P~eGJeftP=j1d)z1qOgj$XVJ$yo7^V_NewzYG$8Aeh&5k3(?of$2anc=E{UB0^u zT57DAaqKW{GP@TtC31iF6;$3JT3wH@;Z&jwFQcL7Q{$i35}d-SX#AgpqaWS(6R09j zA5z%0!Rz^kI9eP`2>DQsM)Tqu`bDXWuEcDmh;| zCenJKxZUBp_<$+hSR=}DZOhP}h@(I^oKy|XV}tdZUrS;hW!#Oej7UK7r@jFgm;oXZ zLP){alE$_!qu=^AyJvmxwXAxQ1TiXU{E2)vjnGAnC4Ea!euDO&c zXr*CK!BN0dICEe%WSX~Pshp8GobUmX~#^xj^nrYUy`WCoEjB3K9t*n%G`v0k8ve*mx$%H zZ1VDcW3&freKsh5^o(g5AI$NnLEqC3Q(wW(QiQLu#JUHRNu8e|z^~)lscJd{-WVtz zraY6aG?K4vlk;EIy6FRcz0VEJ<_v~A&owm5adr*YL?C)f4Q&JYB#nHx)xJ?)))G?c zjqLQS*7VqQiPenK?2hvkCr=_PLKPurG9z^mF$y|Q7#y&HK(uBJUL!D_0jFn62+eVI zuLj1FO;vT#xes-wohKs|c^BJ}xjr|)s9TcUH0z;p;Wle;bjj!G4`Sdv#fe1B{+1YX1j8 zWQNOe480>I@q~9A6-E+qYrhIClh^6eDjIBP6cmPvIT8_fJGWdQR|6VQ2sBZ~q%y8$S8=YED_zY~UIT}qYIVp_616Lj$W#vBD-nue zLft*VXQUs<>EZ_;llQ zP__j>oX1gtG(KZE`Yr!w^_`&Q2v8aDLo2X)*p6^ag;SbubY?}aDcL?$S@cWGKsn=i zE%3hNEwQKCz6hhj1cajApA!MsWTmhA8PTip_QUzddrZcv3oQ=;`7r9Cqb7AeQd1}m zVx6j{(_r$eM8ErM@;6-}5D^_{L9-wo84^vWtSD^A1=T%Koq4W3?V$sH=D75nhNX~; zj}%t?&E)fh@Ds2Coe&4hBepAFGnEq45V4Zjp2)?4BHbKy_>y<^!Xq!50y-g`dERH% z(LE&46X2CR(jon~zJ`KLrl#hqA(+sz?>6VQ(V?wclr~WT*>mZ;I!;A3x9i3KJL>Gr zyRABF3>GN&Q&J!`hE6Y<2fLR;;$|SQ8<0LA3OU$k-?wO+J-dB(jtRQEmb=(ikvp5p zyUmDX^V_z#o(ullpJsklD0kDF5PY+4ar2wue?o#L9!-dcr{~Ehfq-AZcX@Y%34s@i z>^?ZHWnfC>aNFVUdVg2c$?ljmBpmj2GblTrZdizkNqVi?pe^|!*3mH{y@qBr@l}O% zCiMi;!KUCmo&Yz6Cl-m=YYMM*Jl)O-(}*Tj-*tb>Zx|C(k|Vmp_uYA^vD0}{eEWy@ zO{jgdPChjcr)$}eyu5n&8Z_8v!iwVKyTnncoA(pjtg~A0GQ~`CtjnzU4N<{-KOA#x z3f7WY{k72Ut3sUSW3(6DUr#5GD<#$z1AyeB9Rhow;$-EWzbq( zF|B7^T7n;;9CuDBFPBw8m&jMlD31mG z4R|48@|m~;4i6%hZ20RjU-4akDD>+ZK^?@tfhM!0NY|Q$A3Z)jGCbUo?4kBr9a+A+ zn5Cj(ED|obx>Uu|P5z}Gew>q2r4S!ApWVR~{U*AIPR~W!pxE_xG-F78&_P{tJj6GG$}M+iq#*-#H3lY zdU<=BvoD+E^@E0|lf}paYfY~sIpSi(^x|C)wzxW7LR#M1ns^)^*X$}imP7D5f7AF%~)weqz3f>SNowq#La=|9Rxfiy&AYtk8}ULYs3{_>oKdnD78fmfz=OKl5s0-F<;7oaLA=;M znW{Arc;LD$b37Wd#dwen=x2Q*N$Y3*2O4)f?`B-TxiZA`RI;#-ARAZ;1pD!#Q_ z^{xpBDWrymb%zsi`dH}vj;3)*zrjf(TmH1#mu#2^@9veyz%?d)!`aDQ4C^63Mnf*D zb!L`(de}SG-;W31-OUkCG-$}Ydtztj?=M5^W%kbZ@ekeCFVRiyov{m(e^zD=It5y& zO&;jbGIUFN^u#F=LKF#{3ZDDZ4p_soV29PrpR*qN1V-_u6q1J&*~3G=Y3zk zTxMYGB^m&yS3V+R-AXUz`DP<%6XGzEhAsR^laH7daY2+4i9`wtg~%IP4IbZ$*~xU( zqfj)$VRalIkwV7@=3l;TWb+p55}De>okJid*@ed9Tu?kxH9Y2on*qNCPmSnerO_{- zZaQJc7a}35@fuZhIs`iQec%2#f-Bw>mK7AHjAS!X3<*)=>G8?;<@d}`6R8h_|M~aWA(2uzQhDLuS&f~ckX7b2bE&# zbIm^Ks)45xkr6ywy6GXL)@q8eHnA#gkwQv?rd(Vguk?YH%K$quJz-qS{kI2&X&6o? z{B|W#Yyqx)W3-YV!Wr&dG*FV6Y~9kw?PT*3Aa*6FU(9X{B!z<$o2~V|3Q@5!6>|)A zNqXSt5HA)&QBG27kSsUY(U+akIKECH#RG^C3+JLe??tCln!_M{xk4RHD_8S>X37~9Ql-162?6O!L%fKP=Zc7m448{!8$tf z@&ku*} zZkVRV#8|Ni2&7?rvDxLZ?lM`pHg44s(DXP0cy7+`*LVRD{dJ4L^(CdX)$8+rVN0%^ zmkD>1!Iyvp9@}-%AACLsl$PA}v)}Xx-2D~^y5M5Z82F3MX+mpi$sHx;dF;Ug&-)T& zxE&-UTm0RFB9La{w6DV>!s%mLP3-j4V5!!+ji`49GZmbe5-%$e17&IgsP&mPH!iS) zxAH%46wiFy>7`faDHk!L*OnenGV*PHgYFB+R<`x<_Y%jq`&sCwoC<#2o_zi{GU~|} z5+#narjb9wFM6TY;Up^JIJOAs&kbZJU;Bj>=B|2W6o1ToR!>Bxb39=lP&Y;L`0OmT zzyp*J9MHB^YCN+^dk`pn)I+UgQDjV6we?hfiUiH-(wkhJ`xIqXU!h8*Dw2We!b?N~ z=D2WP?DnXWY*q#-lh0N%4Wt?f4JPSowrnKFB)=>hYT-+b$?>geK_+*uq*y;rQ!^qU zxVsS~%-i%=#nV!D% zo29VVFF{z!TfJ!OpcF|EGDFrJq5_%LD7e3&+h-X)IXxsfSZ)4q#=L;CN2tpSYYUh& z@d!lSF|7Ne+VoKw5_UYw#JK2mDpyzUjV} zooF!oWZve>46EWqzWShM$zvBGqS5Qu(e52UFw7)09o^y=6l2e$TE+*;(j*4!Ep$@? z|EOOsf5>t>9CE)tyYy^CGW?{2YuJ9Diirt63%>0+xA2jCJjv4;uzTwNq!hr(^?;8r zMtPHt9d{!}cRQQ!YGh95*MW2N7Oq zZ7b7yIWI>djHmeR;|IR&G-4bab>akg+V!3Ln0B};0#RB;9YOY#Mo72WIt$%8D&_~p3%@#2 zXWAiUB5(^FdnP;{uF zHwZ8mv$y#kH-A{-t!aJPq$P7XUnLHln9KYYZO=0e*XgD_y+c9U=}Ob}1VdWV9-eMK z8v#mikiTwl11`j-a`9n-ff!S*FCz}=Z^$s|+(JXa>PA&1} zeeRM9%@X{t&3~Z_pvrJtpDxE5dTD1k$FH176oiu|^X)_N)Rqf$WL@t{n9Q@6!p2mE zc*}m9r|F+Mj6?~kLm}Fdu!h0v4x6YZGid^?6Z^Nn$H+%_*5EP3(2P~)Yy${Y7_3jPgy_nyZQ7SWxX zQ^?6gBl+*2&RMlq>U*P{dB43uNh~HSBgHsjZwFEF&K2*WG)H*&Du@3JfT&j91KNPOC>ouO+a1 z9djmkwc}$W2g=?T0Xyhc-(%Uc1^=qmD;d+&O8fQnQA^nm71X>>+(yx_5>2D~2lAW_ znr0*77x_2zp$)PBQ5AA8RSv>e_U?RW3UP~qS)vijl=toC8K7${%#8kN@D|_QAmqDy zFQB#~D1JBoSfnDas=YD`(=e=lhyE2QNQo#Mc~J5g@-X9G_+)7DysxNP&40Gm@89S#Z&FHX$JyPhB zXbwJ3MLmDO>GR^dPz-0R4cTNJm#~eBC~H9UsNN8dxbs`87Khy}e_o!5FYjGT3ZjNj zd&?Zr?&y*GNJr{QMJj)WEm)%@6FGzz>P=Mi*X2%o*}u+fZXySoeRzpT1Jz!~k|k;z=snqqDA|xxj^lm3&pA)E^2*f|$UPKBxpdxOSHE zNO}6hLK{MY^!?`%$q8wLLg7Hg1Hj?*j*{wK348>*JGH@N;TXxHh(NW=gO0)=M*VyF z2m2x@ZJnzHCkA8y(thH(_m+Q~Ak7Jb#JrG{0$+R>qB?2W zQRtOOD!IR*n&soix%2}803Ux+Q@WiVYPXz0GzbM{nJc(q$Gt#am1%Egqo1}lO<+bF zZA%^ANOmA|;(5Zmfu=>HQabSS0@u0sc`Zo$(P!}_ppYSA*I5~kj~es*b3G(rX9E&Z z)lTO{2yr+M15|e=TbGBYR3z_Hva)w#l*eo~5m^qr;b;iZFoHnF`rje(69W@slpLdW zaM1Q*^^eaDuMFyium*Ws^#{vnYdcwzTA{Qc9}Yiqv^(kOMh@aj*VTp+5eOs2?X=|f z46EDM@{)?%R_$?u10lhqO3LSuViCp%ZWSJM8#qiyKN{`PvbL>2(bb-C9LP9}!1e*|`dJ zHRn}hUUs_M!S~O28I**dM^LQZ9NgnL`w>$ETDwEw-@^`uYfXJ-gNM~DYX>PJt& zJgQ4M8L9sxXf45GVHY@;QYlkPre=A^|1zG3k}ALjBqT^wy}?X3a|`T6JA5a+L=q*Z zU+aL$_&G$q>@(m8*~c#A^oMNs+5JdCy0e?Gc^#TV(C7b}5eLh#`Rv~jdS;#de;kEm zDHLUXAdy3h)l7qQ9eTsX$s#2=m+`|Q&lE#~o|+wlF!lw{h)>Zk2y}XRpN-M5fbr8C zG<|mu!iLRqm zKYj9BzOAI};t8iD)*wI19lyOqTpxOx?1?2PEwV;cGQ9xxiOp)3V19hnu1t3cJteWg zh26EIbVu2wVK2W-J1P$mrgtd8^prSrHU4f~Kt*aIX>EZvBj}nZ9Mc%!1!R?Y5=t@? zrz63y=0w&dX#T5QGILFhpOB1?fiX@A%4(BOdPjR?mRz0fUhQ*<`p=EE$z9xzQ=Gfv zsmYxMY+33OFsWcoDZ_o=Jb`W z+!3#1k=@Brqq~CfN+SWK@NP@XcjX}P3t@jFg8NZm(0rY*lySAqN$=;SMu#PPVhw_L zGF4r4kuJg+yIk%zJ?ep;jMR8t!L{#uSohin|7%Cs1Bo=gVp2|tN5l{X_H=ys#-=-e zV36&3_CtIjse`Rh);L8W4HcCvca~vAWd0vhWT)Ycb*e{V0qFN|I4@(QAVqCp$5@dJ4`rK#h?j+IVKGo*&3}QW)!J z!}~@!dJwT+L_Q%kpSSR~b2vVZ$?(?jjE``){hib=gw<6Ywo&S=bC3qNRtep6iBU4B zdVoKZQ+vNNT|%U%PEQb|$P1etK!#84k%2%3@LXd9I(36WI|Ax&5EI1-cikoH85?~} ze0nNA-eqNqFqb4`kOCRxM@i3|1(U!?a5Qo9ZH=W52o*mJOo?&w7%@S~D=5kL`Fq3< zwY6$L%NG0fDWumjK9O|67YATj=?Eb2-$SG_>FR9G;9R+CiPTu~%y%$yc&sS<(!6>$ zOXx9<<%=`P2iW5k<6_^X{XTnQEI*r=^ZCG-RNnPe@cGUMBlf_XI*9k}040HbN+i3l zPyHXD52Qc%Ix_eo51^Lh&X?iAha|y=zuyQ1{HD#jnIDwZg#KH11*}ZQ2%ld+a^B5N zNeKQ8Xaqs)N8^V^={|So1O4Kfl8PFm!16p2)FU@E8iBfy`@nt7tz`oOftdyxsNzbj zVTAUo23-XZJW@wyD{kHba<-?R5uM4pl$}3|`XRQ;#}UZ}O)eM?T{ZMe3Yg(kMrKKr z#+yE$)sm&R^t&*v0SC`#`DswuUrBgRVbPR+EKjHAFN8<7h> zXxr$>L*$ZD%FoOx{T|m&Yb0^*7-v&=K;MyBTjQGI(robGi@Uk(a4?u{+|V?!ae~L!z|fN~&$Y(qN)Lz|O8tzQ9Y)NBoqf zR9m4T-cVG}-4>)!`s6VPRFwRmpooS_A1^)#{Wmsq0H3xZ5 zHYr=`py`-=y=9kqZsmUx4{0!R2TRpi<2HmMQ`tW!5(;Rn*K=&PApcP*cKzA?0Q^BT z;a0l5kG(wub}_>_>tD{>cUg1C;9S+VqAI5P)0PcPx&8-$o8XD;-+Pgfkw88ZBQn-= z8TRiG8+5Q?d)Y5=^QjEPTMK(#pl6@M89!K&Gbr$Bf>GYk@@P^x{d4HUj}ZK6D0{lD z8c)hcB8t+g`R}QmCan3x6QI_T{mA76?{Av#-_c8A`)NQI+izC$mR7FYg0W%jmqQ7; zL3cG49aq@kzn{hf502%|3fb>M*)O^SWS3m)R@%Ka;Esx>B9x4#K^MR3eenFT z>3~v0t>whVkbat^eDm~$FxEFqSL9ZEW`0t032n0-xfjJquMM9ph<7N6^1~HkhdF3- z5C?Z1*Y(EtV6d0CR=CtXYlU9jjib%pW=i&0XWEYzY^+hqrY}I@-9lGF?-M`n_3$Z@ z2u4isZAqC)5fE^nU=jf0%Rq^|o(ohhoU#AT106}NKIT7{zywP7wX5S&;;wr9wa z*Hf4wDnxC~oQ;pSrkzYlU5U4{HUu3_hDT|DLhg~Y)${M|e>Ylf_Bq{I$?^_>RwV24 zyl*h+$~^k(2>1N9ytEH&Kqnc)92OQF@Hi5}Y_?lr>g$4;W#2-}w}eu%S;1u;XCur% zPn+ld_IwJ&;lKFqoTmFyy8V$70^vRQok?u4+cY{kduqs;M2Hv{G1Wm1R(k-GT}tv{ zP$guIW+0G?qpYGwobD|i=y;MR86ui9t<3%k7>L$R^~9I|GVa>o{ng~)77_qsf0QWz z+jzmrc{njQ8Y1qT023Wg1!>TuN}0YIdL2k4Zyp(<-^*rwTJwh0N22#vTpgwTeUFdT zonu46H_ufl0C|>a_4Qme#&1=Moij`|78D&p+jX5x=)#NILU;aW5K1L`FZc}CV?`iN ze6elxYnT0FleryfOthN(De?)iH{(ZmV@^0~;qPstedSg7+O2gd-sj40r(3@v9^&*Y7Jc<~U|aI!)G?m*wZ`-!n!bEW3q~82 z2YpCF@{zucVQP3HU&Ih+1dx;4f*)v2GObRy0eM&ow2;~~WpU6@xjlcsBn(6M=S^yL zhSn4@VPthiznKuj)6y4|ITRCLAEtKwT?Cep&$pa67GtOa@r&~152hrzJp{8_`j=0+ z#u(zLWaE^+Ew{A&fobf0G-eXFVf(K{i=-{atfcH{`_plZ@jJE0u&3}ipYf8XnHBtF zB(B7ewRAW@%@I0s!@R}txW(!m9&+Z2TM!;h&e zH~jrMuf6`Ot}*%Smh(FpxIAN{Kq*EQ-S4lG(m!ZRj0S_FMjT#Fr;<5WoSH;`<;3^F zg;DKESQ8RL9x7QA3etk{E$d>n>(cpnVu~QfDfDC$($f)sY)jX@#Gpg<`KXVSDC-v{ zBM?V5)%YP{64>}&dSTDkkKwt)b9GL5gB#MqQ|Zx6#5g=F06R+_C>nAtzl@mo?cta_i14m?=L9vO#E z?fb|Zs8I#n*^)S}HhHM5$WSaYyxSJKw$S^XVfwp8-;TPVXtxMYFes#Zl)B>6L$RvW zn)@swIU>1CnpoYXlo4dV)Ai>+FAdHiUx6$2?L$p1W>hNisPv|H){oiHW^a~K(xQy= z9F~>yp8msiAz-$z&!ah%&|H#*}?%Gm!ZMdV{nMtVkO^vSM4 zmvIYqgSxG+{@*@HI|B-Ln7oZ4$dj|y)$&>=hOQf_3NsAk65I6x%b5RUZW@rKS8ffS z9%ryw5*4&!Z`=`I7aZ`(bT3~|*Gzr$=%~SFd6&WTFCzPd!c)KN<3!Ky8|=^s-NTe`t?{M|L3L7!ia6sm zkmSlm6sBCisLs3(SX^C55UAJu!?iyIP}p;-PTVc-c3$gdzW5EpjvQ6*VXkX_(}UTxSw)`J#d856oR__R>l_}fF`1uKBnHo zp10c!Ru=bFP0`WFd0reIpqKqE5?8Ya^*3gj=LDqB>~p?sK%5yOlRpbm7IGTlLi?@j z%&Qbg4PJzTX1?JLj|x#E6iC7N^~$Uq{KKAWcNVRcIzZj~`3)wsFa$4_r^_8aBYLom zDRB9T@yD9-npAE;py4q0nD`9T#%Q?ZgyeaABzw^I+JC(a2X|u#i_1mvJOrA-Eljto z(?TRGHR_83FeD{((;E5E3+K!f=J(}MVS_bmq} zeLK1y)6uab69#mac{#VuuiP8RyBxK<&%YF~#X^wj&bc5&qkCrH! zh%(U}#x?z7!>)6^$fVb9qB=T_hcqG66S->A{>P749Al*4Gkx&+B6dG>AgiU0kGZS< zabm}2T4`QpJ|psD=I3dGNwq}xQAa<4V#Y!nr?%~|E(DIS;>Xzu(|GNAA0gNwYth$F zk{f$*HP%+s>1TuSRT*0HO?vnUPpb?>3hM^pZQ~IX08{B(w|NkVMeOj;dGEiUPrEeh zKM2!G(;B~Lduen{O~dLedA33778@h68Ye}fF*lH8+pu_&1qSPjh~@A9KC-3Ou@(G5 zEu$$m|GP1-0aaxb*u_M-w%nq0dQA{gLWDhnae+STx#ymrk3X}8VNN<+3qd|1A#@X; z)~5CKHRHu$Yg`fAIlbJ1G(}0$;-K0Cl{w$M@B0sR1o1$7*CMeQmE+~z`ms@;>Jtf+O_!u7Z?tJzh2qd-^O(CJW>kr{2Ze)rsACqcoTguL^L?B+P zg{8+IFbuc+iXe+xfbIXXw)+KnNVuUiCuwc_R5Fa|3nx;QI7BTc@9agrn$DOKw81+q zWV;EUaS-jV1w}nhAvrsH%3ZLY4(HVkCzu%^cA`On6XBnAHS+7GG`{k;jKK;~W>eFs z@`&A;hIqn|FM-#8GAlc|Qj(vdiXT;&_Bbmub8&q%3_E-H;p@O?Vd|sTWMK$LVkK&N zyd+e<0sqQpC4DYoMo=i|fr1FDScU$#G9jJ!InfR)jBqb1?H-=i=~22wvbuZVsBaEp z@4Jc3phiqQ7~#qAWP*YM{Ex`YP{mTajyFzz>!k!w|ApkyQio3} z5R3xu+Ss#kqknZl^?$@~CrS%{nPZ%&>lW>3r3S0Hzj8?t`Q2?ktLY4i`y5s0080~K z4Z>bB1plH1RJ+%!|D?K(rGVhVzXiFwL4SY$uG^)q+wH=HyDitdt%eVCx@!M`ro}v< zLZ%JpKQ1-47GrS%=N=@LyVaA!NyZt>1=Umf z?Z~IY+oB59-~CSASe+L1a;46Ll$~#KpW6j>vZWYL%Ip!+(9$qG;CcN8Vt_udJ)!h5r6DD27g0+neHT^lPRn&BakV^|63hbPKi3ocCTJv&|Cv<2f?= zX=%;g!tPCKxS7oqlXslg`%>+q#Z3uZv;@cB{n#?Eltd<;wC{HnhEIxTC zQ1N$bi>27&Q4hCksMNEL%~w^Naz*?Fs->!DcY(J6v6#Cb zcXz+~k6nZD$WOQE{ddRN5C3RZ)GemBR&9LG^1@bVA<)2+S3PettUJhs_Q!^WM$zp$+p+^#R?@nVQqDd=)W{I~@ixOe-oif~j7BG)I%WXZOw59F=B4D3 zm9VYHo&v#%WvWl>`OH6ho`(F6tAVP*&5Ns38~lK|sf6#&_E{rqzmlVqUu^At*b$I# zh*ab8Pl&_{n6-JW-%Sc}Vp{#b2fNjF)gyvx-hb5Bwa2G5il+sg2G;N<$ee8hZDTU$ z%LvRZ+75GDjga~GJI3O2B<+7kq~FFbmCm5!4}hPsZ{@fiA?^8V60yJ7K`+ipP~@+o z8mpE|kaWIeU}MO$JJ&h&Kn(Mem3i%jzR zjQj>QQ#6;{cjphJKWDb02H7NY2H9BIEm}M_uTGg0Ol1S++Vb+BdsxAY%zgJq-U!5` z-y8e;*ALSdlg8iZtk($0*#!H~F?rQIgv_LPAS5Z)GLGnE~~tVJ)oVvrABPgH%v zOMe}KZy1eNp2*eW`8OnyZb<*}xpvYCSru=)KaLR`WiR$2&_1igA?z7wJ$-S3Z{Tgw zo<+OQznQe?KYV>~?0vCaDOFZ*j?1;pNX6;V;nAjU^to)YzKs^I=RMjsimiIz;ms3D zAeM^T-;Z;6*}T+f<~l1SRmy4dR;>krv&USOINQX8egNt$OUk>U52w7JysG&0pYd^P zb)1&mW$p2@*WXV@m}Yl`WTmp3e-{4bSrxbUc;Gp?YAZ0r=AvRpx4DVLOQvm`Eiai> z83wKr6e#p-bPE}@V9Yn(P|38E##il49SV#~cNyDD@{w!^OKVaRET#7M-GC-_AfP+;<|a%Q@Bj znn@{3J)=pB%5isQYaniE^*p!qO1f_?QmA6VPZcvrai3WrDR2t^vOfP~7lI(@O!_9K zV(Q-=3HH~yOZKh5*RVS7Qoq2#estsZ1V6icCc~>oEk{@Ia}WzD+9DUM3e!La zHS8(z#i1PEYtK>pi3r2+yPee=%G2q1iqR3yEV|+!sCxk92QuIk;+Q)16d4~9ksL60 zu@;qs7cz7Z)aGkL+fgIcD^YZ6k~nY)d0{hkksOZjX<-|+WTEl*yx&Hx)@b!q9#*2n z2~7Y{$ku2t;cr~97oSeK$6)!+C0WuHkC;lhnW@Q!6Z3toab_|ii4>#MqamZz)SsV< z$@Xn?aT(VsOg)M2i;Yk%#-Bq?h5V3IQ0CGHiN?gS4g@rKDIDe=KfV3Do6It?!_oGenm+c=VCUk8WK(DZF-WS!X$$F_bxI6s zhy#{WUox{h(q<}?lRWNYLJ`{K*(m{!_1=q7Do%CxdCAPJYv}LL{gjNxR9K@LjKC1+ zBO=P4auf99@XS(UP`4xv(0AplR$5BF>~}V;BX?hKMJv6SuHGq0<3n#RC>Ai^|BNR3 zb?a`hiqwyI_7RVcP?S(GaTM}eEiM^?FK>`>@J30$a;q^_iA9LxMPeC@M|ckEN!~3V z`oyrq2E|kfQ8GaCgl#~O^MoWz>HB|#^?w3c04A0~&elK8KdLEvq^v#mK!R7zlslm% z&enU2#!YQaF-X;BQ??wIRopdOTziaRG^%>;!y~7x*`_u^x~HK3e$KhvY&KcEJzpOT zI$FmC;`|NvcP;*1u?L>jYb*sFhOxH;F3!B$g)XW2Rb1;q-pxqO9^g-yb-kU{3cOjr zCb2h z>ZP*b4%>b9uIqYT>5+dcEfl2aXIA?0h%CH{bFY*^ zn!S75jqUYs2RGc@=jEioX^_WO=`4i4*!-j2nCl#3YYo~L_c9`uHkGp$Nzji=!~lKu z>dZNU+pX3|^9x(;OY2`-XWdCKI_uPQ_*YK-0;Uu{Vhh{6VPz-cdAEeg0J_fTylAhe z=JGgDXgU2$R9>0 z;gIzS?1C1;ADS9-d*LjLB~D5wG;_<$2vh3?{r{?}!WQ`7=rpZ36g$M;>7 z2eQf^UcNxh%gKar8Moby*66yd8Wr`pvPD!J@#@Gh>N-A1lAOC zec=AVbF6$X2$R|y4J~agWQEiKdM55R-@j_7P`d9zt5MdO(kH57i(;AYFqRP`b#rKbnX$UsKED78HB^^ zzboR=w%y%+!hnVDULEB}XBUa3hRRzTObxqkBluelzvNlZs-c5Yi4T+Weu1T^1I=g< z4F@7bZ2Ins`7?2Uu%xYDre-vetj2qRL4g6a$5;S~81&u;tCxDtg_G=PeW~phwQ~mM zV#>@s1(8AO+(rvODvrMTu1V=|zHW-S&1ytxEu`%MWvrM|(ChB5RSPI47+jmo| z?vzptmVDp%HkPJw@Ol1ODwoelXtu6^#vHk~7=2Z()8j3ukwlTWgS;i|1xSsRGhX|4 zOw?ULpYJCDI4`Ar56@(ImM{A4oAv7iUHm3pT0XGEp(zyAwtbgt5OQ$wQ~ zK)-jHJ%{Cmk7|fhBGuvqu-V8bl2Y?2t_Z#FB;I)MU=~ba+u~Yd_A?6|WiZ8+*raJ{##OU-5N`!P7wGjVu1JI#w?cfOg}LMavgGLD7ZI{jpYcA>A2#vT4J53vF*|l zchowH_vQ1W20o_#0>j0#;Jn0PfEY7gxC&VULw1bHPx3DtFhpgf#oDPaGQY0w?TinQ z$O}6kqc@%ZkqJRE64mUkw1F&>>_q zPDwdlQVl&J3HwW9r;i^)HHgsMav}GBM~HoRPRZVC@s0B)$pHT<23|#0W0ihUBTHW? zjNgTw9TT?Ol{}dr+XzYk{SBfnkZctuw~!f_i6jL5`L}{x36wAyBM1E=eDrT>_qs=X zo!=~A4zArCHa2oYCbDV!7rsFG6Le6nTl9F>S`>JftNPH#0<4%!0)f$mobw^O=dR|& zcSuy?aZi;i`zOn%KzG6X*bKm`!Sz3O!PD}I|J?tGK_PqbCfrT>bAb;-l4p;r*WH7G zoTc&3-uH-ci#NLUhV%1_a)cIX6;AuQd=+8}BtOJ9^ihfn|FzXHu5+|dM*g6Y;RH@c zviQI5U9*lwD~KA{>so7ZWI)1&o)q^6YQoqN9{kEZz4aif0lP*Yml~r z6Oa7y@O@~Y)Ut$Fb8~0*t%#zdR|rj0wIqc! zi;Y&_XkrtudIvv+7?lEoygBmt!H|D7&oh&gj~zb8cpEnlK1KJRCxUgfLjc45%~?O; z^TFz)iOY(p|L*D695Qt@{^?)}pjx_gpH96-wk;P9POC~77dg$g5K4N=_pb3bNPPCX zq2+SsRR`((9kCv9T&&}j0=hC{bFz^NLV5aT#?pOZ^zAM_b&TA<6KT1ze;7<>0~=ah|kyOhN6d&dB>~$ zntG&769pr^AP+o)+q!OnFf?)27t~5Qi(SVm%2DYm)~J*=knqCSdgnVyb)jUHGSLrf z5VwPYn%f~>0@&gd;M0~wbA1YU-0s@Qyz0NXJ6gd*&<@S)|7?A_tMB=@RQa?P(&*#* z^!(8Cv^i4w>27I9qG;%1lQ_Biei?`;StLz2KnpzouZO?HqlfyLrC5IC%Udqp`D4@YH@`@9;vQa*Rw8fvxkAAQV7 zyUBz#-_8;n+7~)G@>^R!4H?8KUU`ebHy>lKT{-%<2$BA>BbErg`G%RdN0x0OBF40z zR{hRSmkI-}bq{(|;#r9j2Wfi(zZzcx?nINrL%`u-9*S%ej4DvVq_-w`tHcJZvk18a zusRwN`dfQ0$9JLpi9VgcQF-p5;$XIB99XeR$5dx%3`|%92;PeWs^sc(#OnsES8Uql zqrJ_q6ofu}$!=<~IMY7Xa0u6El=xG;E_b6)~1cGb~30eoqPe@QZo%@ z$+SdD)rsQZd$0&vdO<5VKOHjD?Qn02OP}eE7n0vNI2H;7#`eFsZ_ChP%4{^OTWt|? zR{4eGmv0G*GJj{Q%@J7v1tP-_W)^)`IEdWWhHuBX3V9J^) z%#i`{Q3U)K)u>Mxli|L<5Q@aE@^@89kP$FLhrL!*JQxrCJ2Wl@Ge{`VoxE(U$MAHN zPB5Frw8m^szvM0&8Z@r4x8vw%Cd{8Ap15k)ctukkA($ua$-`kvqezgHYx7At@;~5N zP>AOR<-a@Qn;g{BLiv&av?PMzR@h@!S0s>Z zzVGQ@4iMKUT-0H!0_BBDLO^TrszZU)9zkU)9;~bgj+-~B2 z9g8y=?fhl_`Gsd)>=dC9SKDc36wz+VHJ9w!Vc5H0Iqj_NEe`W`Tb)$jWsY}>an!PSVs1SB^CU(@mfiY+0 zv>7ly5%y~fQn9)9Y>=VXPPIuL<9i6Z0Wjq@ZE(0RjA$jfu~pv@SHbI7imVBGC((O! zW!12e(AH%vT1TuBI|mb^M?G+FfKU+^;1yq}(4PFz>b%oEVSASJ_$T>Nm;6Yoa^zv`Lz~uKJhgFldFffXd-0$YHTxsNF?oK>Dup)2zK_O4!&B`syu6g+?4b^yC8! zRSAxP<1v!?s4eF~>L|Jlz$@MzlbC`iJnA^hgQ$q`@P2>I$h)#x;eleoaDTvhMJJMC z;7{&(q{S#G6uzFBrJ!NBxAy~)G)KOnSC$v{--irMYxpacAA5B~M4?l#)rjrGR4J)f z*^4!cF|6!J3@PjqyFAVaW`FW98}p$UwPf};i;^Vf#9?|2Qm2Ptyw|Pe?Ugf%vf7Hw z&a~LZ&(9_m{?EI+CDELcPd6JTPg6}H=i@HjJ3%M+(a*ct&OlQ6VUx+jWOCp|U*wDD z#meXGlkPxS5M9tkYFA<5rGF%BBKWAj=O(jW{9$)v+3{(=xn`p4)P07&Sp^`=b)Ex^ zuzs6M^;7YDj#}J`FL0fTPt#)+Y6|Y0Io0wFqqYkYZ}=L|k#qIg*f`3u3WG5tzhl13 zyTNe%8x2=FgEww&${H;n9Z~Oz8e*LmIRV;_4EBaFyXm1wsZ#>_dy)(h?t+Q!jXy(w zYO`3db2Qq6c33fkhlr!G?&Fy?B(GuyfR;o0%E~+p#3Ex#^`s)vGUVFTQ{raco+FD)mQ4tS$UyD>!Dcc4cE?3(F zYZI4PkW|UKTy9MGHO$v8L|;+3&jJ}pY!zh`gz>uIe7wg{gT?J z`zd=>SgiBrarOCWh&JdOb9VmxjKf^_LwP;zfB)tCHAKh{SW-Cn5`pmgE9^x0z6YG= z6}3425(~@v`x;lQ+^g`@81h~%NWPT|PbM?U`Y zobEeSF{a}R%OAH1>Ule$vU+lS92Y|vEK&3&i{-<^yds-C!8|Du_u}dY;T`zyk`xfF z{3V^`qTlzauY6R8#&VrJfK6x2^#bc$Vu`#kK(uw%k>G$@L>R(wi3bed<4v;4&7cwG$3M<_V zU33T{SV5sx|8Ygv*~v^-qY%H*t+}^ALj0)P`WftzuWZykIBW0LeEnMKGQn|G44yn- zQTOA)Y?Ipt!VuTz2U(%*nRb>h%2s;y(ZOSO9Qnkj5fNaq6Qlu%m0lRQBp8jdDIo!@ zX1|D0_X9Uy^segrq###|QR0?>3QhH2rP47;F{YwHOc;z`HHZ3|UWxMZq17lJQi1g9 zg=Xv~e}htE#XT$xzypo|R?vMsyQrIzzj@y_ER?_c3Tdcvu>zG=){o-3?7tBoPi=kl z4pOxdnkt3cCt&J~)zTq0HfCxIm-Xw-FCO!(d05q7LG_QCl~E2SB%a$s?uaFCSD$WV zLhen_zXu;J>^yIJSd5M(fHwE#(5tXD$y%Id`zz>-gErtw`ZWuFi#8}cI+Br>3I+u~ z|0Z2Rd$fMjnw_CSCphcmJdGj~JU7Oatqk zHKW1IiU*zg1QOif&=NAWO2%Xj4oYbr+~Jr$;Qa;jsBt$NHaeoe&i(WYqq?EbHVQVJ zj@mDZRaKs0h>PmK1IND=-d5fg#s!hQDK9Gk)|$Km|7p)4yo{GmWT>^iYyvoK` zzjfp5^xvv-dVD$#Y&9~}JAAXf{6UA14ZQ;FJ7&Q-|63Y6lpZ3hn5N~@Qd*wJ?6xt( ze*>bi0@fMw&}i_5W0r|N?@K6SC`I6$;B`{=%(iMASb91_6aQaULcBdUnZ6SOLIuBO zmCDl4EIo*ZCT--%O*pq1i=Nb+G1SCW`4rqw5z4}TNxgMf-|5q*K#%Pt95@`F3C!Gw zn43!Y3Xo(%Fy5m0(hLbkoEwoFVwfKO&InJ%BkJS>y=I0CPuG<}F1tuDCcHR4B(nAP zvK>VKS0Yo>;0>QOukuZV>+IVbZ8nE;y;3c{8PL1oSDZ@ZD-Mnx7`+{^oea z&qqh?jZ{_mkIG_ke7nh+)|_VA*V9w0Y^lTNWJ}lh)5NyZbkv{R+&r=oTw(Yvk#vHS zkYuYQqj%G-GhdM?IdFxleBS@CdW$f5oM9;nzFTU0{2)|R*m`vGymBJ`m{b{ZWfO8W z7xFmwJpTN2Uv#q>@~}o2@@K63>RIioq9@C0F6fVegX&I!XxFuUopYnUVR{tLesEQIDW)&D4K)yORWerSQ|eq z7j)!1ri#zrM2UVfJL#GojSf1lfmomqzb)x#znks227cQdd?55N1Ef0M^kJ<&Uof5o z%IBC-+))TE8qMvrINf)@UbPa*7bQVc7JmKtq3#5vpoOT;`wB@RGp$d#3q_H#jH%u= zY_hdRkurVjxgr#BR-ag{M5FyyUHdn<| z6b=w6WlAE=(M%7SQRoijCmYSr24T&2T04$*Xcg(Tmitb7dGYLxG;qs=6Wm0t8PcrAYU`+P#u=XNx6vDNw2cD8ZQV>yu8S#qFD*0fg`z!Kqm zzcPXqyxafW8*&5WbDk$kKKGG-3OR1;Iali8&mZr;nyC-oqUL%WrwbPJy`Fl#>UVzh z;b5HEH)L;pQk1s)3F%`_L4i+e-H}D@rl}H;#Bk^F`=~Rq@)PHVR=bP2a4EaG4 zfL>w|$5Vl$v!ZXI(sSHi=isyK-6bIkJ-Dx1;*Oq{1uoT=iG?aVAmIVqpsx~4-GpBZ z9Ikdr-I1&J$39wRx$i5|fppErxRhecKKt;Cc#IE;Q{Cvxhv1ufOH9gWwN z+c;W+$dd_d^fy=L?WUEzom^`5$HHEHci;Nk1?(m^4-dy%S0p6FNs)b0F~z8`J`L48 z@20lEJ<~aSIsbphBjduSgG%I4fF==8f(uu;(D2n}<&U@j7iHOL#3cmX@t(U5vR@32 zA$nWL*A(j#J?r;Dn?Wm4^>%#?1@v{8d*GJDyayv~ZdF1Mmc0BuEuCviWzw8f1)HHg zXdf-yK#CG43pJAV^3fuFommeHzpqgdO-m)>a=aAg(?803vsr|;?SoVzH97-u$ zfCl_-(TDlmzai&aheUZoar<17;;k$0!OT8@+t6jW85Jc}$%Wda)M6Jgc+!XQ^im7H~jQw*JZVaBNt_w0=y-E@43!L6E92GlhW- z7;KvJAJyB{=KuHzssZ}KkNH6R-jbqk6L8PxSL^QL{s!fEu!Cr z1u(VS@Vt@9myMz#IUdH8+y&+6KYmK={zn8=IOI#M&P!9bEe}Kkfm~Pq;?1!<_HI=G z00`IC13j2}v;<=*`+KtHIMlb=Gq@V)#baU@0IkQ51p=F;BK-9qjZTNQYA8Szz#K@s zZx>sn3b%Eg{atGRW!^i8%>;pmt1WeSuSH4igIATtPhdCa{Rr0oL)Ec(lthr6&}=zU zrN_ijRig%79r{hfU+{hTTLEAg@sAHhLJypJj%t2H4x5TW9a3DI_Z2axJT*ST8$@#7 zES2;sV|j_=Wcmz}jkFkr1o!>S(bsZEg18G+VyhfFUY7WpIG5vMqlygRfspK|dOO7@ zYtKQfdUEmemR(2Yqijw@#kk$IQI$1`E>1=mki)x=visnDc0KpO)MZN4&;qCuyKiVh z);I0_Y zeo1L!SOO-JBQr!oaTrSkGUBkBa6vI~z3S`(Vj@J12~T6JSr7lxoXNiBjEH{Fk##ngCX#xhVLw-))`?U~$Wn%p9Ux*HsP7_Ufh!8s-oVR?% zGX3ynFp)}w-WY`E6>r_23K^bW`Wn3IgR5{1QUMtfbj@)p^|j$3W@#{38mE_3xH*Bw zV&R-xc67OKOol3<0V(s3=xwN)UiJNaBoD%1QOm4(*^0K8NQ1$YbpFWu(y|m6shjE% zSIYjf!>MCQR~^IR^@0OEhC8BNJ?5h+wxePk_A5Pn)6Gr_erXN#);7Hc9yC*$KlCr- z8*(g_bx@?Fs0-wHk+%Sr1rb0V$UUofFr3ze)Nh^Btd65{xV$fx*utVgb?xkZ{tpY1 zBkt(u-_ri{OJ?Q1=x(nl_^<&W8FXZ6_^;JJjZy~uTL;L*zGl3+!DlBA_dwAee7@&; z3KS_6yBxa*GD(BhrnZW1MvBbWp3kR?j5)I<&pu1uo%fu!J|C_IR+yp~Nd`WaXZPG} zk?&iJn9$VT-yr6UgSTc*g8t^R;3&ZAP1+t#Wps)7n+n1c%B=#p57WSUIVoZF39l`A z;&Edr!k#~#{M5)ZW5f*w0K7sqmq&}Ov9=w?C*BtB@&Zt`(410$WN1CDudQ7xkBESy z{>VAUZe^4Jla=8vT%&n#y4d3jcmWAw6=zsjPK=VpNNU{>#vQ@A(B-zE zAqo#yPq!A}2@?$6Jg9y#<0-g&w~QrudU4%-e|HZ6PiK$PKfj13t`zwO;>HUn40mC7 zz;_5dYHsbm{o+zLcL4M--N5q~!?O(p)^l~9_RY`lHPPMunpW+qhr{bmEZD2-K*g~h zW7RQb_rba|N%FAriE#Gx&EVZ|La3E=PE<-{yyqkZ`yK#!|7=f*O7`b{gqE4XM8P@S z6c6g~Wzq~B&W!N9ln&}NKx1Wyksj(>{Eu}g$JwywYArc%cfa`{l$kfC&%H}rLi}if z0HoZ1X&S9DfkS5`442j$+o^F_#=<{mwo)uCto)-ZWTEKLP;1KO zRC)ggpJQ?HGg5j!bywBLfJoa*PNj zbO^#Pym)k$N*bK1L{8Q_ztyf%dlEFqD3!)Lr*ht$ZR~%Tda%shc~O}C$@egJZq*k} zD%RHEwjHi?QW!Pdr^{v38FYXo4A~vgx7de&8kaG9B2~)Kijs78cW+O8_}+@2&6^E+VT|n8RPhj~@mT6OHdAg53KC9j#-NPnHYly22y*R!vfr znoHEiQU;c;6{zM$rWi8@A~Ocnax)o0U%yr*@c5(C_d$0uSiF3nr<0p&j=r=y8$&xi zuW!EpG8EzYXh`7g-Ha<4eEMa+qCAz@Lw578Nc`$S?)Fm4dM3{JIVd{Y_-kS$$Z)lOU% zcDnBxQG)KTjwm+3KC_hh>3Y&UFk-cjwF#gVby7#i^af6XLj|qovJd(WU-%%^pU}xs zrwp`n&ws!7`KrX`G;5^3rlpc;{w{n|o>a?o*L)Q}h%R4^y75(+G-aq$+{=Abwgcz+ zxhD0*>*0P~laLK&Tm5+j3~hl*JkZL0fj$h0e-FjMsI}jD2x_SI;?KQzPOqs(duOuY zOx^mE!A1d%TB-Z2jZ7(uxM|yCzp^2ct1gs&KrY&>)L{ddm34m zXa*LX#GgMHsp-mc;;CiOe`#?Nj^*ac%62%bfic)Gz5pNiAB^DjEMrorw{VGll;ND-Hbw&&-;wUyj$)x#grY zp3O_fGL`+tX>qQXoHxN5mRU_`>6q|H|96KF%mW5`8r8~@9dyBu?*jB9V29EcYBnYGxFt?6Z&&9Mhn zx@|Fio@uH(nVJ+x2~3GC=f?`tqY+QXH#<_XNbv7v@lCYjhp&znV0)Biu|^78q3t{wn53!1ZpZQe(qouttl8YoG z{Pi2(WBU&omM~ey5~G-HndIG3(m`k=1ICYx$l*;6c`Kb72zzN%V+;xi#VRxGrIKBm z;*TG&GE$m(_hcL%4y&-b7?VV9^G{blY;06z>Dw5wp~q2M=RBW&@_nKc}w+xgoCCo3Pw(4@4Tq;pjBMYLdAXNLRj zJV-r@uIpZ`or1jpi!TnMJ7M+V9t0%rinDF^y89>rrRU+u1CPi{>vZ?_;K!0>XQ7M! z4OOw*Ub?%#%c4HUH#Iw4hTnhvz61;@z}j-+X=$SCcAI*3UT*dLPsmx()8p#>^6KLc zEXkV^Ldgz;FSG#<|26`yC9eLdQk3o#g&fb0=g-v{@3lX16+MrptM)uw(A~o%FQRrY zE-qG|=6h~8CIVOdY!bVCJx|jmuOpI1l555^r|; zxY|pyci%9s|76989DpXF9TFeD2w8{)wh&uz#Dk@=QBZ&i%+Q$4_BwL_hXTL(#D~{n z9{0OYg&^ja@-1s2J9dXL=Z+d?mAN6Vr!9|~86Efi`x2MM`M@xAs0{#TU7MQunVnMW z<)zKIJ_Cf0yFISmenZ*lEC)Mg=}}#3JW^P6cwg&sb$*?9lDv&C3cQ-PQ95(1f)_nh z7u|)cK0Y0NXcg)>((Z(?H?rK)n-_U3dO@a6ysOOR^AtcC8UCm?yo{!9+a#fu1N3=3 z{AypCWhb-D+21W*XN#3pz?D8mfH({vTrAe}hw>L$^3UWk(Tr%%SD9>1#-}I5{5BAx z(ldvWj7x#{N9pOr-^|5oa2uo&%0Re_M%mEp{Rt|nH(jA1-)4hPpJ)Pi%&m| zv<(FM?yWlmvc86)L?+W?Km;Fh>;VDS5-E5Uzlc`h%Z>iK6OVwNuX~tagmu{b9HI>v z>bmrf@oQQjd+Uy3wtWs|fl5fc@cK0-2^@5uCg~o`Xr{QC$k@dEv{`X$U;fRt7jVO*#n_`bAsfUqUtmP4>kdZg8 z=h1iCID^e?!&)mGo%|?1J+Ghp#YlNxZ*raoBf_Q7F-PbL#@e(0u7rfeScuSJf>FY- zQ7CAJpjP)Z9pq}Dz+!sz<>Xqg0>rLge_3f<21b(Vti;mo53H3A!domkuGQW9RlxOM11X3ZwO_^tP6?$vfP&EoR5E05n(q{}!nJ}P6{SG|)rHW>6$ z%1}`Y;h&x&vI#L65Y@tEC(Y^a&M|!>P<#$A3nOe8iG6gawh@#Zw_fXG1ZAi&pP+Nc zA$c})al27-5S`{|RszEYwF5^g!$~Zjg3ibSI;xbItztrpB@}98(&lOBcRfx)OhjOW zssXBn1BW$U)-n<&CLHUQDvPn%pdy|Y_;%ECS&KU z^Kht**_ygf3UTYqlf_gA!t_=u>SPk;V+54!fy&jCd+Z}#Vn^O zdV}y>1_XNX_yAaa`DUIUv_3d^(dX&@Sa@D>#kRGv^0b5V2gyE(F4zpyfMWfj{ z+_JC8A<@#J4aFQ{tiZ!YQfXOPi#pd;94)*gvRxMDwz8J4VGkYNNhblhd})r-$5T+& zhjn_~r?!@c@gNOY*ni}bM84I=$jtR%49UR8Dn*A?Z`;A$HlK}P#71{uK%B|@a;?#`K&E4=kJ3fcJ5lcbQPTyWMPp6JW=d7CP zap!bd6gv$S=4rdzy%i{A;kbo?Ut3#OTfA^A-+#YWDecSk%6%;*OzWd;JHzo^Vf_(M z9LC6d9=24UC+Qx?fWQ%8?tL!rd6?pQngZPQe&>lmm%O@>{5YoiJn)N9|J)M@+wL;p zTs+dTaLf~bYv@H2h@z(v`ptO`DdNDvz~hm?L%=gQ&=-@30n;KuHzym!L&qUPNo2Lu z(YA(RT5WgJf#_|ZTrY-Hq^)cjUlJWJkC}RM)4F3uW|Sl^c|C&frO&ll$@~nyB|QF8 zCyPki(imeAF6XCmXuRM-4Q@q`I4@peO|ua-VzbhJ z1}wkoA%}@V9ap@^&^93)Egkm!)UUVq7jBkGC|FKLUTwYywf+bHv-0jD0`{= zD9&>qO~bL9?l#ue)>Q4hp4FoZoaRSRpneeYQrG#dZ6x5;uq(w2w}L=XU3X;OYf4L@ z$ZoCt!yz*22tN8EwE6&?J^^Udi&mG_yG@pme+$hA@q=M_%iTfueUb4DS^%}85g~B} zWPJn7TVOsN6B?U%?puAjo9mwSTJ{tSm`kKi-@Axq`P2yrg?i1s+r=zCCI=mENZbJ7 zrmJ0nx1-6=H>!c_Ho?asw?)sDL!W$C%ayVv?`?|w_7+1PcN3|#u?_o@G8I0WlF(6W z+7n1eOpW}-4nYHf6V{{&5Nr`~alPldF)^VcCoxqA9U7D=MW}q(;q72)%{gRyg)`<` zbPjip&!&n6&TIdIR;_iAtF&zvm&kGEnKkp^+x2zC=M&R!`A2tvT&me=QQ;``;hP;C zK2m#qyv&2(-I;fEely0LC@^dAS*+_xs3_=YTsdaS;)X$hw~(dJX`H>>wu>y%YY3+KhdE z8&nQbG18sM@hH-8UVJ(=^?t^H^C0}hB_-3zlL+!e^epy8zJ7i8u}eHTjDW*wvq^AS zWPU|-@l$~ls93r3+5@x0?N4Ts=1l;_m>nPCSkH6aO)hH&KJJVuWk|q-VS6Kn~<3Hk}RWy(qHxr73lN)Ua z_a6go55=D|`y~$12jeZtPNzU#vFKqVYsUBNk%7WDt$EpU@NxN1_XUo#Q^STY9^@)4~eW9 zsSXoAL8_L2Gg8>bWBu37?`UMr;ngb$FB8vY5PwuB z-N7SR*$wX6%YZ_EKu|8xW5=JYk(n@ixX=y8!kG-Gpu@`_du6U}p95XFDlL}2TsL}agK>@#zt#3crYJIl=)2+kLEmxQj4E2 zno6sAlQct}!Nz+<-@#)7X{J3Biix6$Q%I!#(M+B(@|{3ahKD-#_gS?D6jJ1%_l{wb zj<8k9S(JP#<~teofRhl&*$N|3yydo^QIoua1Eoejg5CS%9~Yz#I|h3thsk24)T0iU z6!Mbz5HV+izjpAo|H(;-m3GMKygUk`^iG}K*_`lEEqsbD)w#L)c1%X-dOG8;H z(SOy>>%RycbfVM(*=~{~W~I;-|`l{J6KLAbC-Z?GvbYtqA{kb(AtDvpKiq zuUCp4Z?TEUv75eunp9V41^SH!(`z^nx98GRs;RhvNfih6lHqD44WK?YVv-jetS}Z* zOeWAr^;o$_Fn%h7C5HOfSr9wrXUM^fpcVtViAFerLXj3jjGq@5{4t@)s|s(SYxO0o zeQXyN$XbPsy!3BX0grdHJ}@>5<$I^+#?}hx=s~i--AUZgmj()bgnO-sP)pk~Pq$a+ z!*RSKE#H=ih3;GxBdAcB!lQPN|KUK4y8Mr}vQ7N&zqA6L|NGs56+ROVPLuAywLV#k zvE>dQx{!x|Elw`W?Km-WbtV&RJ^${g;lHkz$pJ+R0N@1}fhMtTzQ;dT@20Y!+;`jK z$$=DVPviu7eEP8n75oe*BaC7%)2zpg&%RJa)~k0w_}PlVBm! zx2Z(3MCx+y(Llv)2Elj1OgkS>JF$cdYF`JDR+QQ&GVmdp@b!vmGnD$j=3qK-2Hoskw>+xpI@?YN zE*_5yITvxX%FMY4x$f-`PH&y{t%d#A;#fSgZ`EJ+zfV+)o_7??AKQncgl^5psx!>k zX~vg)GkPuc--G4LtPeVoM|Cyu{Yg2xpslTJ$>-Y%lb$;@fq$zH+d@M5Q=0ksZsx#WTq(3Cd_nTCiDIEb|kEjItc z11nuGc&qt>0>m`g#k%)Y4t|4P3H%|>=6=^}$Jc{MrI%@_>wyM6_y2&t=HXv^-Nf^{ zbJJ1u(~M|6&7aS>1=b2|h=d5(;FwdZ5)Y}L6y-?Fuyd$F%P(}-g5{0m`8TG@c zo6ox=BTtX2q!qV4bH@oaNIcj*l-MTZVD_=xl!rqDi@g!$m{Wa7~Qs(Nn-L_cEa z!OaGr9^Ga1f>*2LzdPU2`sL0M_>r?5$Vl?yC@=_2 zZ0x@1Uxedc*l{D2D=&#v#h;!k=>UjUJsOGelwUB8FTWJ#$N&eR_mYlpOvX}zCRb-* z%e(rn+42ZX@AV$IEUTv?@-4Xs4UIMYN!#fj%-_X-!Aibo)U#5ckNstdV&%8HUp{V4 zT^q}jmMY<{a}lvKthL7e>&d(tm4x0}8Hzr+cE4)pSc(f6Y;m|>H&O8xt08`G)J4C$ z=5LrR1buvGOqt=sg~v?4t0`ja+bf>zA@(A&vp&$jn`M6}*SLceaM-Or}*!y;iUsk;`vb<22d-uQv_{`PDkr%+6e zhBSz`;*(BapFWA2{#_l{hl={cuNwvK4UJa7*KR5|!KBDRIGus_+Zab0^V1a(O%+u3 zm+HC6y1j=jdl%np?6E?p{jhr>RMf-%ly?c(h%^Si3k5kHZ?_bmSu<>8fD(*D8M8IN zB=;sb^G%-pI%zYVJGQq-J(ydoZsnqH%1a?Lk=%NnNezW{^J9l#3y^+QgV2ACof1_L zz4=85K`~eXA3&Q-A)eS#Sww(qo0%1znP<4myr)wIpv)Fda|DXKc-8i(l$H$g9Ho|H zmKtav21<(&3Z|_B6!o{m#bvgr@3Ks*Pe-Gcf5eVxkg4zxm&CaztbgHoCwrhkI<2$Q71~w! zxe@aL$>ZO_V>>`^8(#4#g-5~6%e`GhoU+~9%U{tmM1Y}GL7a`uPoS7?Xjh&;56kks zahFFXPm8ME;*QzwJ%e`;EF$d%S)eJ|&NAV1qRsP7vgCQsv&-{=>$M}m<`vR0A6@iapFuL># z)4}m{#a}Bkt~PeQy*-6RHYZ`E0OeOew3_mOSy4Y6BKA%O5*t_blF01uR5;3JLFxcy zHOF^TIAUVESL0al3-@P%*<6NZw#tkqQ=yA8+!EaQ&!2DCi|bfqlx+{sHjNi6nFPI1 zmxI2(*~!pYFW6U8KsH&gzt$D<0I7ZTb>1&e)1)$|iu%5I1Y(Oo+@}h!)mZa3fl}P_ zCX6IKkyzhPO0e{qt_w9Yexpe3w@O(nUEQpR!`vmb(h(HY@CrM2CXcw5pic%iH+)QT^L- z$YTcq1op9@oK9o3(V-(l^DU&4ZwJ5ZE&L!#%_xT;m%*kH9RY7BHdx}2YM}mpG!acd0HGFl zyS)g|=RbWNHWv}i(}~wN66zIsEqjcX;|{R^nRXfbIO%H7$PgNR;LLXEdAzc3Zk#2< zJPWThr_sx#6wUU*lbLH>O!P2Y_+1voQ_!&}1y!KRS`PF5j_s1yQy7 zaidx4tmtMT+Hy*pv%aDS*sf!P>{{QEf_!&o24{X^9aJq!)axGD`~SM!oBf9in(gpz zHhBCQav7p`5bCNib1;54HOPqO9(ZywI^#gi5?$5fK6W z_q#VMPBu$}O4*|#d>3fN(B!zniETs<)^xf>f|pT|iG=piy@VFSp#aX<(r*FOoS^*C zT$}SrZV)b6QF_XFZX$yeiFG^-!JY!I_^5vBxaf4xpQ|-9JEv{+rOn6v3QaXdqKbCD zDdZ;#YM=QV{9?vCy3bW-Ixqozg=i8Bb{@1ojGGzZmz=h8ZX&r~ORI=@yhvyBmot^* zoaT(g3Z92Tu6LStLmrc#&O^?ULzZ*63o${*cMJ%LcRHvvEL-yOxEKzsbb5%PmvU^w zlfCNXw}BSTu)hh|nXVS8_rcbsYWp0eU7rUD>jY6jGOIha=eHb)3n7WqftvcRt|iBx z8yxWP(6=?Ep^YqBCli)_-$t%WI+V-ot)!VCEtN(IWIcz7wU!i-TqKcb9P*7sE?=xgE zaKDhlJhIJK37tsAM0yrDPL@7osi7~Ph^X_=Li9Fjo9$`BW(2Jc-drd&#lZ=?Qy8Nq z?nEx;Q@=GF1Zh)FmoW@Vl$QRh_{I~-^`YgwGzXtyfC07ioIom`CzkJXg(58KW3+^* zTzMb=yIM_T8Zoh%_Iv@#8+UV z6hy?FPR~)Z^*%Ft3GE{v3fLSep$87d8(Z&m5=w0f}SDaN4ot(aMV%MwF4(X^oH z_TIjOA}E?_3hKK)N)Pcu!r;8}6VPLg89j1S!NRhFePzP`N7H$~v;Dq(I7U&mH>E~x zT6@HZ)`(Tq-nEISkH&0JD>YNpUQfP1JbyrrBRP(D-uHc7 zuj@KbJ7w#AS`AWou106C$Oy+A(_*T&hI6wgdSyiYk!!cEGF1xN-+e-jzWdx}wHVW! zVMSMNSxxsmAxthXPxyKwhi?aO}L zH$<%a{q8CKNsF=m3*ux$M_okTB~Ttv73l`wJ)U_RJ%6`T8g*EDf8KYu{zybNUis3A zJ!)Q_9qHZGi$ai5&j+4xWa8!wo`QPIx%>;?i`OkktAx>d_{U-i`yAWM(yyM zFn`i?+k@29ibXYv6-#TB)o+16#$gHNiNG086Xt-m!!%SJbQ$k)4>YU|X~oWB*x346 zD_iF!H^&1!aekLbSG|I^Tpu&_;*;`S7@xSHacm?Y>x9HJ!I~!VE0dnRfLdL%;P>xy zve=pmpJPr}r2n4)ecm$on?D1pm9uZ*?!4&&wx{YT^v$v`tl7D&CIiFs#|dz{Br^!I zhUqbTXK7h(|{p;{58t`p-ibAEqRxy0H;M}GwprF8n)iI@jrxGX7y)Zz7w(u>8*$TI|v?sZ_^tEX;W zZ;fv0iU`5l_C(_8R;kJYm7*`oJe99xl$sU~Y%g|kXG+gCjtgCl8#>O!b$IVS^_`#F zM*e=Qd^4yVdWyp0wnxqFqE5eju(d*f8AVtf2ei(Q=VmH?-y0B|tPQ|#MZMa(4uY3Y z)pUX6x5LBSE*S(6v%P(1r2?rS6LVx(Toq|K{`Vw8o(0W7nawTUfH|teJ*IPh+m6Z+ zF6^4U9N9S2e>rvq0lH*L{QVxyCc@FyWhIU|tho}pG36Vz_qrkSdMkIfd0Od}`s7xCTyY6wFXa<;3z;df z1zs#QQIN!aWxlX;4!nKmH?K5S-Et7j1?Ke^mQ zXId-6p5@n|!SjbWVb{*@n!K7_cbfvbYa2e{iOa{USKGA(H+H3$|E7xCl5$Cm>GWAG zv%je`AS+A^4^7y;{D{o>LJ0lB!hKsPxzrNQtqY>A+p*2I9no9%jSF5854;Mm4!TB@ zH(F{a!{j3mABot?TESpGI2`3d`@1x~wA%2?@0(Newl$RyCk#=LZBZ)mlyi7H+6$tO zquEpkclF%-$=fr>5k@kGf7E~4oQ}SG6g4+t&{M}^_r5H*Y%fH~0wC&K=>9(O=tx(M z<;tPQ8XJ5tesuIUUTxzU!B#GN_(hpx0?4+*vQCv=e;PS)Yxi|*Dmdcsa08}B4-Trw zO_w?z&4m5PHw<{0s!ic|Ga+P_U3j>ZQknMaQR#R&~a9lng z=uqOpYA^l_dYWSME0#r_L)G)ql|uCA^~g&COxVBTM4GtQB!A%mmnTs^!X5W!{|j0# zr%lZ?n3_FDi2@VejJ}v&+_^%_tb_%03Re`uofMG#wp3ysFWZ>77bgLu7b1ijy0B|j znIdm`U8HWmm`kGj{P62@eM9%I4)A$-ytlR`-)(+ZDT(Qh`ANM{D8B<6=Y zQ_q}}W@R7K;2M>^9%u!OcB)2#>s+cdl$`;=k|f*{@}x78z7Ir;F6T=^+}VaNazKgb*F zz5YgXuRcb&JCVHm#Yn76@UrQv+wKD4`Vh<|s+HQPtE|&M$uE$uutJdXzTTVukl_7i z*t%aZ1BBPr29@A5&-j$uNiW3<73^&%BgJ{Www^`ZA7RJxKy$@PSL}7F_D{Jaf%AfN zT)R&Nw->W~L@nhE6ZmeG?hkm22LDw($N~(QGf~&9%`YFWJ2)MTZAxn;{H)~M&JAdt z3&#Rpx&-RFTVyE6xC*E25|pfK%#o3fFcH>9g2X3Br=5xgMs7&(tpdQ?sBZ2tpOEEN zZwNAv9E_MX9Hgf(%Y!fp`sRzz|Mr@^gDLYx23(|0g1tElgxu95S0h_SJ zG{xnyjipE0_JImci>`)w+H$zfyZNAj2EKgxFq6nM0bzC6cFe@( zcA1c{nO@hOS)egaQP@MM)OTSUQT3ylKfW( zf)}ihC}@guRA(#Hv*$az*SFX@eKTE`BKk}~buGtbXG)dVIn1__EX3(bnEl(saC21n zoP_Lo1P&ajrW}1SkQuXsZi_j`-kb$=EO@tlz+iAkfzDIhT=U+RM~~HKNsoMowm}{@ z!8(E|Z5w-g!S5BY0J9)<6WzDx!~4(|g)alN6fZ%<(v+=lA0w;wZ0s{xm9^MRyZOr1x>kd zTk>2q09P@IM*|_~XAhs8iRl3+S6(+E`l+ia@+vkd#0>WpAM}}OY@jx5vR16|AAT3 zeIrlgS1WNx`A+A)v(`*>J7$RmEIo3U!Sl27zEHI zmYOd??^nsmaDR^q_h00LlIbU`DB;nE8v16>Vuzu|X86G?Y{jfndRuBP3F-<{5>&KJ zpZ8e{7FkaNBrwjY&xJc*N573*d~){yK$RCZ2Jl-jAb$}>B7<8LN)fD8K!}dM|8PO`jtjfXiF)8Jj znWrONwtEK2fVnqf_ID2xHGUzS?v{)e-318<2>6Aq*xOUuBKx=@JEBmk+i*zKwFe26ZI-a78q|3-?a8yWYJnUkLUzTJWmyX>?PV3u@_+ z^;N8(Q~OKt#gS? zKupN}C%{lf$<#+nLS9MU#?Jc+SP^}pAzc{@qTjv@?nY#2&`_^<9d;^5U`Meob)SXl zx|0gIV#^B}Ly#zMbZ{|cNkP=#psMAsRPkt^@Qdxi);)#Y);fe&VI>-Tg6zUZo?Q%s zn+4b#lQ^twP(e1AMc~;S9&9#bQ)l_BNu|i#iSmQJEzRhR> z&_ti6(!y^#OkZ6?+04u72e6*#RmnT(dMjT5fJ(K|*--6)NnR)w`&8e@*u`E1vx-B8 zN_BLwEb3Qpz;}_$!h@JM1!#_?296oxQ+J(9SLN%QhWkMSeeBBZ#5J}=IYL#JCzFKq zmW2*5T&uo(P{acO6*$r5eGqy6E_y%Fp=1A@164K<92gv?c(&aB=a)j|iQX^0f-xW? zzXp!)V;u1xHI3jH|AtR6{q;o0#1?Vc6!8*-~4Cw#@Wbd zI%7fMHQs%4yO#U8`yZlMQ9ir}82+j6gkM9f2nkal4B4zM9Uh8_pJ@bTro@I-@A23p z(WWZas2B7BIdl-qt4XOEtCS9`D|S(kCOgMcUeC!ULR7KbMK?K??HW4da$0i2J>*5? zkA%w^h)#z^nPz@st+RWGJa+n1<>7Q5%O10&uPW-%#oGDSJSlB$qP(iV+QqcXmr z_xiJv$fsN-N5u}TXUEXN7junIgGsGeeQ`OhT9SZo+iL)cl5p39r(BLU#Ohv!aBmL@ zA(UV!7CmjGfd}B&D)Q$>K$M(i8RqYo@3&zRLr4AhKZU=Jn!P}+=fbIu@w8T6(W#35 zSSt=;bt-Z4D5QctuH;WN6#%wxr6f6-C$b2*8c7M&a!O(zi6vL>cY_UqAGBYjrRn{U z=TgV=7bW9y=n9MqSM(FAU-vzDR&!hy$2|nBG&V`9@?4g$tO?Wq;zKp#*hrKxK{YPV zNM!_3{ZUarUvt_M5mF3^>N_wwOhijkXblb3pq3IvGil#=eqh6IT7G4^IM1}y>YZXb z!p1c@G0Q#ngnuj2X>cpPnP8aNp@FL^Qr4<&PE!Z~Kn=sM2bC|-Q^6QE+I7ZEb~`&e z$_-KE(~tC{bylDNLh`bDIGhx8x_+bZB_Y;(mW2wR<>Luxf;5S=)B2~&&gI%9G?j#$ zt`Xl5%%wUSS*nf7Klm;wzb$CW%A%PeOE)rxH%%~uKyJZ`8z_IOJ^&Dk$3h+5C(oPI zg_|`AB-A-R0(n6MLdzqjB>667;$2NO7;(|YD93T32~w3L^-ZjD@Xo`NNZ~| z`hGjFlS~|UCFFt%w1qmDH3i|;%OdAgy$yizi&H8hUnGa2T-mRYCi>dP-LAL~ul2}} z(Q|Ki{7Px{q4F=>h6T{SAuw(KQjt^$d0xTqp>8bwZp*_+hF&c?EZT=i&%`qWwDk_n zdwSb-p0U2zNEx)qykImdd9I&P(xVX5(S`nE3M;HXDe07wG zdl%;805o;xdzk4`I~Z=9`r7vcHy`)a7rVRN`QE#h(x{swV)jVC@L*hIa1;}O3k3ZA zXIjw1!fsr(PO zYdBTD*SY1`QCnC6_r%or7b1QDiM0d7c>!z6RL4t*3MY95IHe8&shfj4TF*2<&kyhy~>E=R8``j7R4_0=HQU z_a3GD-t3g#?%e;wP2l1n-o8;dPL_haJlp6F`~AlKoWd8aj3ZG2*19u| zT5r`8iqIU|BkrO8y?O#?U2Obb9hR*=%bDQ#N2uV!=Q5A6(@wgsqam%gepqBd!5#Mg zYWk<}#gFS>KhrBZY6|_KiT*jYv#W?w<#1~d%J=5V7pLkR-We>7WW^kX+?}mn?Z2Pi zmJLadx%+pCJK3>p(SP4lmXzA90Ojj;x5sgjHhXltMJprYyqG@aYNW(SJK87F-)m`( zJx6iURYm>w$Nbd#Us-z-Vyx^)uH#AuZQa?+6QkIqi6fDzaj`u8m*nMdSP1^?> zcm>;DsQC3QXt^bk+0-GT%YA|oQzU}&R+dIZhlO2EHNdWyI3sw!-28jmNkPV2x1+wH?c*8BE*!hVnAvx+xgmJ5HmC`RjI}CHJ=l{U%g5CACvJn27VZGvE~D$386ZrAjD9fZ7C|&|0&c zzc*36_#CXxt%@z!1G8wFrh-p$ccpWm?l|zo6+CC~*41vt`8)8Xx2{#BTmYZj-+HU^Hc1f}a&up}V@4z0|A3e>rCq79 zzwYeQmA2@dey*E7005qcs*LRf=k6uu*}`k1Ae%fy;KOG=fC|2&xP&waC9O%4M-m zY1f(Eo6>K%*2-(5w&;zwtnGc>5MD&qO0ONk#7SGe35pNQsiZWs$Ts7BhjWwIAo;AA z?}lpM*D32yPCKgEd{mgLJ*Cl*aEdyu%Zscd2K|@uwOgy?99tH`+Zwbg;(&-Rq+qeg zx9Tro8Y$A6c5VQ}6fku`VG5!nD3=aNo4MW+-FHMn^jG}Z@bL>R_*DwwO{J3n)_yX_ z|1?XZsCPZ)DGxm8ci%zdU^NSYX|qXMW+;+xJxfE91f8`Dtu|&=JrJDACF}C;HsTz+ zT7+vp*B#<`k^X4{8s+XKM*nsB_FdwnZd6pOp%+rQ^q?AuOWuvqTr z6yzAyLjN{vqJWOHBjIrC(P&L4T#=ou3#t{skPJHL_iCUFLvME04~~x?6io&CM&S-!m1 zGlLQZZ!=91c4e*yMyH4pEj_1+2Nl%Rv+HIVC$isydb&cz(% zU_v(ZnPe+uDfO0vQZ-CKqmu!#N)LvB0$-P{ec$=(i=B2Av{-mC)Dr-CiD1DX_lAoqjz|O;Lg=NQxvuim{|^Ag?uaE;mZ=(iRWVJ8W$-6$6=Cc)QTKV3Uf3uS21M;J@-J_mjU@EjrwJOJU>vx5T zhWn+4NbKq@sM-Qfq@ol!EKZ~X*m_rc>|txR$jn6TY~UN(GnZHYSLLE}$2G-x=XCF# zc`!uJB=Tl+2elPs1DZs^*~7VORY6%K^yx?@2ybzCGRrgT2@ytmRzp2?0UGxQV5B>CZ&r#C8QYnOhK%N_3_{UBK3 zpPCIwH-QzQtJ?&|WIbG#rgG5VWt&fbEgW^}x4Q%yz+2ny9EGMT^wg_9bkP@}SN)y1ot%WQCaMQCC`Mc6QJ}@; z>v#JRX{>K*1kLB83&9f5imC_^8x_X~4DsJn1U_xR91&EI<9%ocIiCFlmvg>J6O67P z(yfLRpx)vsy6yZR$H1%xpMxW`V&p`Yry$1+5nA<~M0bsv72x5&5id*wlQ1#CSASsp zth0hb&qh-8kF`B!Dwf0p)7k1?D2^ogb1N)*c8i+in>QD!3^PT|Zpi0AmNKES1vY<` zOnHQ~^OBQ_3AlqBUi9UNM-UNG3uvajCYBy8f0>otUJn=iDaI#(yPFTo29=CNw=Mg$ z-TJgGpU#`lzuoFSr-^LAhtoLDKga9;39UNtVCSbY&l4G%=@Fy`P~)7b^@66j@qfZ# zB>num+dEE6?qmkJo_$(-5|v5?Dx-B)i2@y6BOIdSCvOjg>Er9c+F4qV@ZJsyC zx&%yZTB}pUhCgkLDozI6Y}MgYpO;AzCD{*uEsY)a5ey9r1&&5e?hvRXbhCfAFVkB& z6ApaDMBn{@`XMQopW9qg_cL3yw(XdNW~} z>I2s}KB@Efy@ULRW;S1Fa-6BfL`AJzdV}xWqSAUVH)lS{>i6AE`LfncKX171^oha9 z_g(VckM`YR?|v)aT+R1IM+V;9>@?&2^uEy-A7U3yrcOKl82a3z+ zSeBc&VUDx=nn)&yY`>D_u~vqa%qk#prnFC%%I6MTs%HGvKl(oQ34U$m59OHYbzm16#R z4ABB&A97u;(brn|84QXdidqkhbrVeIPoHVInxXV)Y#Pj6Lj<{r^aQqqwVU)$ya0k8 zIcI~W*)S;=>Xy_=JsMomcfJw^-S+oFN69Uo-rhEUYIQI;3`Bp0gkWJ&gB_J3A|>4l zF?)AWxPfDg&9tOT4|M1O5nwuS=`Ehg<259{!LmH$KYlR09$@bX?e@IZ&rMRUyYW5mCa`K^YyYqKVYDbn|B`{t4s?2wH zq-*^!3%vp--ZPXblb(eQM|gC-h1X`v<3ErvN*ACU4D@e&h*XRU7n?FtA21w_^{I9N zzf2HY$&%I8n0z8eZjus4a@(}G)ah8h-wwx}CGNlW>+Lr0hWqaCwuc!rE669^r z&-r0n?`@srq0+@sW@5Dc=K8qg=)Yr+h?c!kAo+$u+IyBQ;qX60R1diy?vHMB6>dWz zLrtqi+$h&+Vz6<nQU>^>3a+)o&o$0lb2MZXs?}0ultAquktlKFCH!PffRsLd*Il6)%=ej#m|7 zSw2*;7pcL=H+l<3K%P^O1=%pa{E?GaW*MhwWAksG(PUoAd)^SCQ_e&ANToSLER|CX zG23l{8tNZ24O3xwA6CLRnE~baLPu+;!hvDs+J>6YaM6v=GJ(8N4^o}lZ1e67K_DF+ z=}Ad0s}wGAjZt@`UDQQym5qVoXF{;R4l3C1n=5k7!7nq(B}R}uHkXYqF1ZMvGrT_1 zTPuuG9a0|x@=Ew+#GiZH;92NMPhaOMQUe1S%y62YE`GWEra6>k#TepkZjP}|82iBo zoCpBt->Cg%8YxX|9KgpJiWvtDd^oHL;7MhJQnATDm1QM;`1pXJ>Qsjj^kTI%#gyX0(0?Gmzt!N zkU*R9Y4a?YjgpC^W?7}+t={&k1j}iPxooc&g`QGTzg_dBkdhybc&3gA?j{cSTKw*< zCsH4&v;C2?5mHvYTT$QjP8`RFSBz;~^tp;I8hHXBsnWf{&7?hi9*VO@+tDROy6H_riMkZs%c%a+E3ZIq(Z^j^gNe7`27+ z>FVn3Y>J{a6wJ;o4{sJOj&JoT94XkUa4)VQ!&9j-d}^{q;7_eakPTr4^mhONV}|`i z)RQi{uB7(mEX~dxi~s!_xtz}yDvAq9`}o%N?dHSAf9uyr$M=I88Ywn~Ke(UBBmHyNFJ_R^$0lr(0^jTKb{*`c(tc zRO5HP)ys=i=Awqk(Yq}%#z!^rSB{i^|Dom2v&Ph&bf)N_9mjQr1xe-jD%$^U9BXk(yF%=MY(;DLR_-T^GA z@T5to$%}R>&4F?~66m-+`QiLfPBWdyH;UkO|Hvj`3%~v+wG8$*q}@Ob%d% z7Qlq^nJnqZOkQS(28AtR>${t0H;QJ<0J7O>7WzT;q`h!e26vCX4#9o}0@)sirr}(Z z=j36WG)01iT#cM~_OH!*-QR^}2;^a0cSTmC_Fm`$c?%K+csgRj5y;EV!jZAmv)hoB zi}x{?eLeSg=8&PK*If#oaxv1HJm2Kjek0vDC&d;d&mM*`=!&^$dx%e+1a!dP`0j?c zEyJ~{3W1{)HgDm^wBYWLNNN4|c$>l-qEyh3wwot-G=m{4ViI(DxhIko8@cuMNS^fh zqAB=kNTxxmk7d8dC|05SeA2hap+Vse1nLRGaNF9sEu|VPwMLx$M$26s1iN+4$y2O^ zq}F?S@;YLu5BS()@-Y!OD0G(k@AkfJF-eqSI#|F=_kLWQ8VG>;DLEg+=#?(^nW?x*-yc)FRQ5S8y*WB zXs#OUhixrSPEk;giH<+((mu`q_qlEN0o9B@(-a_MuDDvTx4YBgn_gyMuvOG~SIk}C zUFwu$;~$2aSx}qRvpA`gIX!8H^pyXf1wc{G^X;J;y6;Ppl)BpO1F*f0t*JB2QlY%)K_uu8Lxr2n=godZ5sxa-GMuB|+MGchd~_k`vBkgzxLWDqgHoA#YoQO)n2 z_d;BRdLJX+F-tt{M}bybgO*W{G!O}ml#XzO~=?$(4fz6sL2xb@@aRbUcrMvb;J^ ziy18aRUD`B9uzdys)Eld6j;&=8a-6{XVQ>3i3mUrgGuq4{>V-ZM1-tCFpf_$V`DR_ zH)Sv|YCH-$P;_zDwxNOvJ$wSl{p~SFTtBD$wyH70(j*6(Lsv*^p~F*V*7GSgqku6; zu|_|?GTIaD{b#MeRUD+5kd(pP_{TLXIRHuc(T^Z2-jyN9?Q6g$D|tD6=lVxwWZS#L zB$W)-CfE7ape-051@eOzyQ-rmr!05i5DAlsGbWOxmjXxk*VuzCd$$(tO$9d}Tt^r3 z0czau?d7mhRWM2tL+9H+so{p_3Q&5 zq67*Gs8XP@hV^xahTZ)epJkl3+izX|Pf5zgL`vpKcz;HuJ^KQX6d8uEj+@Oub^0t- z*vMg;!4gSMq-8GwEwF%GZe|+%3fM&D>ox3m0zqAR!YP&$Jm{72LuBD_0`-97R?V6a zA-}-B{fO2kXmsvBXmxh`fZ6~cZ6W^_+8(- zcGnxBg%#CR^~RgX?<=JwHNQ~ejId1|5mDhDO_|w zpaW1DMtnoaQ5%`^B!gdw*2m!u0EM#MBDg8Bin4lq=#?|zYns>WE&ll?!@@bkInaVe zjkO8RiysLU1hHYi@+4TPrMzvpnxQ~fAkdP|Qx;76BsEW;lk%yf$y?P&upzpj4%_y6 zi2s>8B4^ZL3_LK?<@+nfuXE+>HdiviuiLg}jF>(8-$m-QlMc4`a-_?*r{};mp=Z?- zNw)x?CU1)6PeK;DlvExBZ}jx_u59KyrOeNND4H5UtVCYxQP>*iSl_?`hFh|I83#<& zNGdw5*q?o<5zq@VX@C8m75W!DD_=buK28Z#?xUZO$^K>a z75lHLUw62%j7RhL@7rdFHgw`wOdtUhXhmL$kb$|oGe!5&7irqA(&(FJ%DX|k8jm&$ z;SV*Z;X&O>N^)}Ug)Dc{=GR;sTjTtJ6_nw){TIsg-?d4$K&1`1z9tFNCfH2u8p%}u$ zolOFW1Ql4))cv3{gut%T3HEr3g{UF)H=(!qcuAqJ?GieJRv`4;ua*OWdTBrAIHw8T z^o12UzZu(v;f4DJfj|_~8OMt$^&v;dqwEkSmtY71RC8Vi!LP4ETCeICr?e zS^K&!(fwttdtp(lewR|EGXl(;bGT}$2)zGJ2ZIQLwNxTDe&e`Cl=CHQfDv~ZT>cW? z@^{7e+O|m>iJT!93xHLWM&5+(-)|Sou(LMIch!{n?AqOqm|vrroZ#pu{?po7#{NHt z%%9}}mMV5fFaJ58ZthHehw==XQ*MI&+{kh!?$&B57`w6&_+27OSNvZeZ~V!s40GmH z^(q3lSmiW;7gG7t+a@jPlP|wcQi=uJn7jqV&KJco zJsORr>Iv!c5C6CMB}q6RR8v=-q1LA)mrXk*;48Bs@)L94XYpz%jbM5G(Hp~| zQWwi7V{;mY_+K@{ZI3v^wgg2sE0u4VscsnWFWHqNg75w`iy$O<>O56qZIlCm*34AR ze3}SVX5$!enJ0g zyy68yYY1wyEX70UffKE!kbVpg%atbq+zULm|(FDfA#n%Yv_NOobZF3LXO= zSEnY3xIkMbG%AzhBb+H#NA&iigb5U4n}%Tzcq*#7C0KVq6@-lf3Ip^7Bu;#mN9o2t zH7wxN*2%`%C@cLqmNQ-sUbBEJR$8MfIMsIr3Yz!T+O5$=dZGS0$N@<(*7|X1%RkG{ ztK>9O5vl;JHVTR^{zNaH@~8NdlkvQ%!c_Igs|VW8(874t9?UMeG{Rs39$k$nXE995 zS4qyia{*TgAx&b@zsNlMgzxM^G3t3qDG{Fv=!qqyG#2>2a+Ph|655Xd8L{5#u~DWc zC9Lk!!=axn#Z~01_TwQ*966Mgf@53GMEL}IEQ+! z<`4wo0UrUR1B@D6V54Puafn~NDyFz5yBGr6D(dtAQe`i9F|YtaamyfS`#+PN8UHsm zXVC!g|C3mmS!!)#dwzTPayLDRI5KIk(;w-HMC?bAfV|U!=->IveN{Ps+9E7EDm#oo zO6jFHNT!fnt39VCnhpX*yvv2S<97K9-@#5&M>9*Kj`ndTz4_%S*-U#g*&iU<-HEqL z^Ps9C7MmHA+m;YkK|K68X`3~bRKC()pdzf0+OlHYtMp+JcRXqAN9K?5rH|<3p$&xi z97DCl9>GU$Z)iTamk6}4Me%cw2){|t^#Z$@A@d&mgmA{PS)aXP&Ld3AP-C{=-;hN4 zFv+$nJ2LD_C%`|?+_FACKz(@~P0Y&6)$qBK)_?1b3rJmKNz*1}%(mfM3@G$sWiSr8 zhU=VnW)DKU6(a3M<`F8#p3?Gw{?8oc*Jb1&P!Pd%B`Y4?LpSzJBJbBuZN6rD13JeN z_6+IT+qoEA(h{JbpQ%!QQb!qt^e=QB7e&%EQ#U6`)EFaET@KV9RKzYkvr?rMh|a9{ zJ`-bnFc}&Qte?}w{)+k9(~ArFwsz2$$3W()7ZbY#A|Fyep&UyvQ{a<-vzg5cwD8bDIPJS$ynR1iKy#`_p1}rK6XwHh>s)_AR60C}=ogPAaGkH!@re-Lj|3 zb}!V;vvK`muB?mlTV2F|?^Gc$b1u9s=3o;6G?8#TAHb zew6X%#L?m-(F0oQ0R18&Q*w0;oj@V{CMSR!W8Jo{u7AeXLR3&t$vP{1B5V|yXc%F~ zSw&5tvfOIMt1f^$y%JmZeBjK#Kbv7{>9bOFO}bb1ks|fp8Q>q!m!_4kzl$k``k50h zovjg>!44Au2%zTQr9fDceg*^ZRd=4;#(_^nl@pkVqjTCz;M7=AOfK|%3MU8Y(~8nz zsC0M66jtat&UZE1WFR2QwVm}+5_*fk34dH&*DknA!X+WW!96|1?4>0Ez(F*MWTnBx z`}!FMFi2{>4Q{WgwR6SGY#v=%s))xuqk#2M(IpTy5}+b2kHdQ^(O5;&?^BpvRm#Kn zVhCRVr_|ZGoO}iD{PoZB-=EJlyM9qYVZp(e!_H`TcUEs_sPXstA+SszC}u`wTdHYs z&znq;Y2n!_8Fk&ocQk-K_T8Ahv)x?~Ad8%7ZLyirxBKXCrSkQ^^y|v$(w?-F74z!S z5um>1a3eu(fCoK_>-oZcm;qBiJ;@`8r)oDG?sghC4tC^~ zl;Zw(oh5f%f~(k6lD`&Vm_8L&Pe46*3yDWgjE#d=DQKhLWQxdE&mQ(N@)dIvpCB>OGDA&YTWq+=OpxJ_T zn6@tSc2PShN>P6tzsuIyEYz>l^ev-#kzLgN0c;aF6HwCZWFe!J!okE69*mD~zaQyf zRrnouU!6`EsHJieM;X3tqI&cMTl`vbiq$0UU$+ylxCt);tU*o*z&(@e(C(0}T7_Y4 z^_1fmdM3KwXofg2+wPm^`ww!#GBfV@S=5P4lTX$b^L_*NpXCggo<&g{lm9KRm}T|V zYK*nxwXE&RNN&=qc7H3zD`?LvK)?k^(V7Tj(iA;eQ6r@A;stQS!*T}Fk|Q}j;*?zR zH51Q-<15OQNxpqxfLi8yISOoXlUb@1CQf#%FufRH^A-i)>ufz>;50>=(8C@LB*w<#=vGhFO}mmS)3nv4Y;7$*UycYi^eJKeMV=iwaewSiMXlnw8-)Pe$p?0!9rq& zGm9TjNwk`|7-)SkvKsVp#)sa0%+U|2BnYH<7L<9eDYj8QBWIlW*U|f@6p3e=O@ow9 zgn;oGQyz@)&d5>*$wJ7m{Ks#KE5v6o9(hU3jmPg~k}P$}nxwdbFSUa{DPy7<%5Q+_ zx3PtI);6UHoewbM9fGo_Wu!iqpy3;q8K{r%@uHZ`^g~@ch0FDeedJ<%$g#)m@zLnL zj05)S>8l)cVzIfpGZ++f9);NVbN$fuD%;99_L-`*%VVOOxYD}&g0IRC-;h(kQBUy= z0LnK*O3^l;0%mFqYmBTVDhivi$!h;2q{3HG{HZ={6zia#^wDF~YKrb5JqgdebYEnL zZ`4bRSNDDj>`QWd4&0`ogW`TF7&N5pJ)V8V=!T}c5KrR|oB^Th6dld@pxz9$mRnKu z{X1jXey-EF_PEnxt^>#c64YYYI8dkPN<<=Xa==NTqNAnjG;YB1$7j;G#T@iyI`YX{ zqL8zR24Tw+=(_Q{xn<*dq2AI@j+6#9?449cN1+PS80Fhp(EEv0u4T3kvYhzljCrk zU+K~!@hyjw>fF5X>NVJ2BHoUgID!8$c(UQvS{SGHltvm)04Rfkhf9!eAA%_%RO*I74+emQ>3#Lhasf90;>Hv?V98-i&%n_@qs$*{SQ%q?3;D4DAsB3 z6?xe8N`ZYmhZWYFi3p&~#y;;NhGLI8rCpcc3ea&c{1!xWSa;fz^4S4q{6xhZP&(qy z!Urn)@WkVek}{KhCB|*iDj{?9ec|oCt1=o}5w`PX(_c9Jfq?A471Qhja#)FfhcS)H zf0ZRP2}W@{v+FS)fUvPORM{d)?(rf>msT(R~(SHt`_8#iw9*e4kfnu6&^TqUnq68C#<$Jy_H$6TD; ze-k!%%7oM90QynI{mj`(_~=2dE`P~$8Q;}P;mpb}kE!sX>;@7vRf`5OH&!%FKROYB zyX|Xi^s&4he!naQHEr}s(e-plAb&nE8X1725bV$w@@Bji#Aj@e^A({Hx%j90u8L$+ zW!kn&zKVbVF?sxZ1NUH^gxp`*-LBO5u0~(i_-^dA&1H#lo_ZI4|6}@E0}x|oxFcZ` z9P(#(Zz%&)Kr4z7-~7X^Gr=t$c#u@pkBZ0%IA8a(-Ie6=X3O3+&OSDXi9Ej${qO<_ z2|Ax03{yG}IuMBo^dsio^_=xty}i0S)EEcWxSIn)AdI-MyOXw&i} zEuZblrstEYggIZwRMKEH?YPz763UQSQE!Gfl;@)kA6f+P&)`dO()wX)XSq(Ptk+C$hc)t9Tso8k$%1U6h2J-5%cm zakT^ds43b3-)Ptf(H1zoLL)pHwv!k?b3JmcfVBlj*Pz20v-_u;wUA|VyGecrTs6#` z87@CoS+u#Zql7thO~EeC{FKL3jy33)N@Uw zW&HSt>Qj=?|Gw1*S;lt`a={3p;wM(G&An}?jTUGP=WSoR{2xtc{nh0E{_)X6Y6BHS zatshfTDpXRG)OlRA|V~48B*g7N{Do)Gzz0egCf!*&1gq&2-5Z4`JVH+&;1A7=lgmld35Z6zjdi;8nCr}Y6(!iEGb79Hu05pSKof)i zUYLq}>Zpz8S^fWg`u5Nx?B)7(W~TRZ?BUMwzr!g_C8lyOCf@s$gZNaYZuC2%sEzpS ztmsI44-{$|Sy4l^*$-LSn79|K&870_w`?u~$pj*{q<(4LQp(Tgg};N;B6>tfBEMhs zd0)GRL9Z?Kks4B`@%`@}V5R?WnxiWB6%a^xja2cwV~3yH-rdQeA6&s`0BW^(5-1M#(km=V=dYU2Z0AM=DYhv_Wrg#wY~h1AH7P2*mNp~ zRZLjM<~df#cgpc1+onsU+pk7K&>g`N2mRyBJkHMs1qj(E`(FQC&Sf{y2*0JfJvf|7 z{EiVwm+k7%jazHq*PcNM?205rlIUx2K}0CA#&2MIo2MVh`+o4>`Kl=-SmW0beC}~ZF@fJ4(J)y&DbABuE-VDAXL=wYLl>f?W; zaM_@6Nw}lB&en!zY}&()ccuix&xaJwKPqIF@sXb1Uew)Ogh=0R9jAk%+fLHq60w-P z%(TE(e^bCL=Bt=O)!hjCzApgqc0= zPOu{j&4M(ArH~7E4ZnIab?7exbCnn-j&4DH$Du7UM%t< z0iY8-xd8ugS*_-MzS>*Q2PEm%JDc2eE$h>y3wpmyEaCmaq(?P*!hnu~p~dT&<*?Jq z{IF|JbL)=w>l2e@)e#nJBdaOG-$p*{>315xrY}37e8k52lyaF3whqUS}U?5PRaX_uDgPr8RmG2(v0(#^`&a#swx3Zg|Sc; zQ6A2nQ+8ealI-H*#-vM%@Vo7{fA}t`CREY7G#vh{d8zTP2xZ;ZCK@l@ zQd$HyCEsx=q`~?rzcixO-6TuIVcOCtB@ zPDYtfDD`^f&-i@Of=H$RMyI@bduVyM{?`=sK9Iv!sk){-W%w=gQ0zHW2}p_?7W%Z> zUJWTRqLGc`*7N3l*K}g+x5&uJuVU=cv6~vm45cFOZq!r=J^xSY`rlOI+N?a=n9^*c zU#R{ARRE0nkb#bq#lNS=aKT)YFXdZk=lUNOF}F&n9@ zh-g#jXBli>6ne*5-iAn||F^l%K|g^uVvRQm#h$)ot|(O7xkGMF&43oR20Du zOLeNaX&VtmAk*ikWJ@;yL*|j}e{fOIAC60HxKnhB_rLb^qc6v`E_`u9oGCyCdLOZo zJduz6^sf`p;RGg1LZ8rn85+$9`*$*u?J;fB6?%!4%^!K2r6E8DP)gR5ESIHz%`#v+ z&#EUv&*!z60@X?Y)QbnV+qmp|IiawByM1&n`)GcaV&WB{{k_9dr8zL7%8S?SNm-Wz zvFq9R8y!C~Q=GMr0xS z_g2^2^+YdVSWW4rc#?!3+paa*%B=j?JSiEy1$A zg>t0T>lGBm+0%J%lXl=+qluH)CkfPlC-YtRAZElY~WZqN!3sU)%6f zxv&J8>H>aaNRX~B{Ga!3BZsh0)hBhJ5DOJ0O%M3Xv~kKFE&OGEteuxdB47DH?Bvwc zn|KA-s;x9_G4m!A*1t9UD;O@?Yy8}Q(o?#w{Ai9Sqw%yiVVL;UtGD%l8aL;TOCj3T zYBC@vi2#IOoiMKh4R**RW$u>#JRW+X^xai9VVY+xCcW4dL-`7anqJqPps)C!7vS%g z=}&?EL&v_m`7dGefspiq#*Uspn?lL3`6S+cwX00`9e?oJ3<2fRbv4*^z1ww82>c+t z@wbQRu2#Ys*L;bSXNP}=>N+oW)&~e@s6yEFRAM@cme91t*aC-h%vS>Hwt*BfK=1&j z*6%p3^VZXbPkTi$>`F6tSuX5qbXWKU>7uEg!RPg8hF~CC_(y0%GZ~F&>gSHlC_0jo zOifLr9BN$arSma)LeI!ac|A$TYyQB7vndKHAAgQSA48M$U0j-x7)vD~(IjcC`{Q?N zpRwhruRvjjqRL=682Ak7vQkLX&0=5VroZuc3*Cz{YM{9nD4Kxl{OyM!W`)MwTRrn+ zr%TUdH<3rJ$7erGOC`jd`!IQb;uL^6fED?ro*wm*=Ck0DYEkY9)ZGrFnGzTk#H3}i zDGHqC+-|h*XO(_lvXpF_L+*JbUMJdiGWjagiuM?Lx;f z@?Cn?Sn>S(@FDKw(x+ws(}&C%Pk_jAJ%8uCncnJ#_St#y z96$9A&l~GK@zNcs!UoH!_miWWc>a_2%@+AUNy3;bdj0RD_D8+oWuO^nh%H*&EuZW) zOzZIXFDEyvna91h(q>FaLZyZ?ZMFB3;_4kJ@7h#nO`{ullZDeKMHa{i0)#mk#~u&F zs)|sT(s%LkPfF&d`=FSAngA4GJwL=6jzR`?D9K zgxs1yCqDcGwvP4sZ`F~7xBu=j9Z|xg|5g~UaMRf)RYP+@pDbe{3{t#)tXh5R@5$Z1 z_NHctj;=>8E-vn!USix$EUs~AkM!5Aw*g(#E@cGrYbtA2Yg*w(ios6=pE}!sa~6+| z8DET55;3($XRTaT^6vb?yugEd!uCG{CEoLuf=V=`N;DagL92TI36T}e0I-vk6Tx*_ z$0vG*f2J_Gfs!Xsu-9=drtRr2eSnO_*8SwksV4X9*ydAw*mYS&o~~%N$rNk1qM<(n zZ`zDtF)Jk_qZKSwtre89`s?bZUEw{sR-<|>CsFc_hN=-7%|K-ik9C(Te@px7&deUD z&~;{Ik^!6&&1MQTmGO7VK88Y6l!qSlUzTn7J-xRz$&B6pS_A*{Dh4={ z{E`FXN@f=x!$K|wLuhhu3b(aWza7WecQUU7M7?)IKNdk?hWlO+GwNJBK1Jvo6Eor# zLln@Wlgjb!;BaA;4Y`bePlcDSZkUrQ0EfL3W(EK#Le*H+&0TB6pB+)*)uJe`v5x;O z7L=^HbJH|dlmQSG^Ya&1xPC3TAg=AwRAbK#>~$)V+UD-io{?9YnsMeU-Fg`Ycj_Qk z)cA&(`C~aXA{)o=x^HD+qIfsW&w5JQUAyNpqYhy(Y6kNjRZl4yX6e+p3va2)f-6-w z5wORie4M8=lhN%{@d-fW2Lb5wN*-01|9)9+=5}w$f~-^BlL4`<@EL6)!1b@+w%A%# zHAlzvBIY>z-WeJs(iE8`r#v=5nE+dtyg9VF>6uYD53({*+OlG2V_$9$KE1iVq+^#S z^r|OaH{WcUreg}J?Y;Gq#b_dda3ir@Tb+NuuU-R)C16Zta-2Ko?J|4*ml#PczEVGN zD_!m(6@CPh`j5!qw)dF=N2Sg=1cC}pTABMOk#0J=c?tP>gMRA6Jl3Fx(K&PIl#BwJ zRxfeuyXub71qj9s83oy`OP^0mI}jsk%W4=Dc^r&*#q2~4NqAZkI?coxte?XScIUy5 z44p}g-%qFiVN3e%-QZhO3DYG`02Da#{vjaNs>{zwahrk9OJRhqd0XZIFP4D_b#I*% z21q%Sk5^q^LqlrdelwE9YuaP`AJ#=EK{-UmKzF@1;r#0C)lKhkR^@RSW>^eDL(kdU z7u!4(qQgfwS-7%Mi&&Y(2A-ct(EUYNcgeQ5EOcGpNR$r@cyxtIP@m)6J(z`wxc|IT zQ2j7)825QhD0QX|S5_#SH@eC6Pj6h3i454~@ty{`f4=#=Fk6`mc>qy*#_dP|tJAU?jWu?Lj-%CqN(gZ+X9Izi1# zm~8Q9n8mt#fC-xEQq|z0MY3key|JH65(y0Nk&9*{!MCKo6!lZ0v>;(5Njv};_C@#d z-^KIf*Rf+m8Mo7a7){>wi_tjC`2n^tx2yQu^Zc&!5%%ke5d!k_$`dIX_$Ecy4%L`A3kd}_qhh;r7@rzpq39;9#N>@u~^^ zKAPb8fz)-XP!ZWv%3tYLFAF`c>O%Fo$%j~O`ne%r{Ws4NfiiP7uSzs9)lDJ-&;J#( ziI6annol*z@kEI;e!JKu+f1h(bF9X?v?&f8fpP zeuWt!st3>N$IJs0Xx&Hw3vc#oDdlz(DQ3h#YARiFf)qzO7iokXjksWtGfXyPY>4O& zf$7i2k+7N7m{*3M3OoXsG(ILuLR(jA9M7V&P{vm1y?6b zIa;N9ErXF5dc9R@0Px2TVHI3uWyf@oHe^7S((`y{g*zSBjf=|Wdf~+D_YC%^RH#7> z(raE78SDcvS@@7tYW!^B?gwyoW)Yeh0iQ&|BVG;0p^O}98(1OwQ+gLlci2fRrV*-U zNpf~$$&nCJ&B`YER9ks=lo3!(Yj8cuM@LJm8*43o8wHqnX==Jecv#%aoLy={0FtEs^3KO~YWX zoHAP`BmiWfgZQC^d<5ZUv~?_N%34ffHx&6Lj>-@^J-%P&P~|ET|+8<@lTxA<$SqiYQ2P7*+a57+sS2R43s%dtc_ zCQ)_6?-aQ;tuDWwFmc4_p@ifF!bJ5`ll^KO?>9<3!|>#%Uowv!>jJ-VoXUH;g5FiT42>Z z3QG^F8d&G!j&KKxt5y4}se_Uh`Gzdt_`CrM?eS9aRNnQ`HVfKS%vNQw3!pRSml75A zRx-5+#iGc_^Vx~nNILZt!k5Us@ikxy9%drMB*WTWiQjVna4V{_%I1@~Bf!N-%Zn=v zC@vY3|I7KdP=q`$w?;RgZ1L|$5SV*|4p&l>&G`IuZnxU?y4;2^Lg_6I;u0w(K)iF_49iiWs(XwPpKYE)bD16K1+%-(blk@7#1*?_IShzhnGy1TgVb)Au=HPA6*P z`U0Y^rqzi`^|cCqpwXR#M4Aaa^UY6mWlL$Jvo{tsGV1eluDm($vQ8JE#)K@E%Br1? zyztJUr;i&yZ`ZiLe;p#vWot7tjS{RPVWI778MDe|C~k>#h6D09xxbXhzxpZpU*%ID z6CYwHS5|nb@hsi>H`~ORSZ^i=QpEHV;?xjZnX^BcO5Ji(5eRYF6g0jJLwE=&GXCgX zi|~LDc!;d^e>rZ-Frob#)KZ4hopAenu##KHbX%>FKGtw$PUpkMQV^APMj`dOkjR%z z*0C3&3~A#uvUwkdzV_m`NdBM%gfnXk;z(;&k@mbSL zQGNHBiQ219hlDLt0B=O8^fJw6>!bit(XCnXd5jb}|Kd1AHCODMdtDY_hxa%v)9 zYDv4dg(Dl$L9u`)N`pZ=HM?wl;b}O0d zZA`=OU7s|v3XESdm z*+?CUVrz2|dk`B3+xvVE(af8*mE|ex%p#pl{?~i1|5y&m*AZ98xN8$?Yv0()8+((kC^@Uv#YKxH( z?U_6uRW5k`^3{Ls6-;cM6jUNWOP{0%cn?VjZUj8|YvUSqkeZz3JCPBTC)eY&`OU@jt(Mf!rP**)7tL zDmrZWKPB0b9{P?+B`dW6ld$cZXa7*RJ87JW6$GV<*L<;41Nwf zXYXafr`kq$FA7{rf27;ApAF*Maia>?+ljZ|@V8g%vBCdt!mpQaSLwp=yUveXP6A}h z`Q6OAJ5ps6xc>1R{%3bTsC9xc^eg^yFmSn^ErC~9V!yq~@4UvMPXRNCa=?N2Pj<#9 zQZ&7qyDkD!ylLhOBevnU1l963!fgEg1VVDczn~-V5{JdT2Aj__$3<%$U z(#OmvPWUISo_31*(FdDUBTzek_*WoVFT!!GjdB4Uy;mq56+cHuGANJEqjOlBVFiRU zWuN#OXI}obJZiW-9)Ww@ZWA<+*siONuJeWP_VBYL9|0*ksjA8AivJFrYlnU%4w&I} zg(p;w#?2)rr)3~FTgN!8r-7@DOYrsD3Fh*J@{y_tb)Z$@6sne-_EJtAqWB|jW@S-Q ztTvJi;^hn8)1<{fL2a_qob2gK#hQoCs{7+oHhoE#0gCX4z!%6VWI$NjghnjoFD zKV6dry$YOo%WcMhJ{yFi$ z{4Vb<9jGrNE{D4{D_B(2fj*h)XTE{P(ASa_n~tE;`NVR%-L~F4j%hwx-tA3y0FKka z>Cd6+9=iB@oum9I-nQxwyGaXB)~>r9?;aBCEoq4}lplrAcC3G9LZ1}8a$m0=lDFl& z|9yI0%lmW-Vjsfv%#E-yP#7H`2ChNrek%p?EOJCAxEDBb0`9)?+0q!0r2teKD-lx| z7)+JT2j#nB96O)vmH+i;!7gQ0pd}g}*{?m!3_h)`tQD|*rxS(bdjo$_Vm^id?4>Fq z)%87oS?pHs=}ip_;bXiWDa&&x*?CJ4({ZTn-pSE-kzyoxdQM`q`!E<*qP($90xf7} zUOwz<+=7CFleRIz1;2DiIJ?z<60F2NKh^a|zdc2f1Nsez|M^OzgLm^;Y9~^UX(XdA zuiaS&5MypNxYV&t3fsFeBH;B!=4upbez>+KOk$yAt3CF)RNKPo zCN-%@y!GE`vq%aslPNAwLx4h^UW%RbP7x;vB1#-^_c4G?*}Pkq=O#fCNYvdLw48O3 z{+#*z?S>^2e{>aCwEFQo_9O*(5(TU~&n# zKUg8r5IFqzseIS(>Qgt#`oc-AIJGF<%_H}Aa57>Jjcz+#Iz=bPEw*vBBtwE+d)|pp zx_iQdv!S6!BN7B@TN^kOLdq6w1KrFi&UPpR0U(NE$AGGAbj9fs(X%_K&3o_09h2jF zD0zr}61l~X^eUAtO=(4tUGlCSu*nSp@I;DEZPzC>L;%QR^_Y~nM^62{lz?eJqkTl& z0pE*LDz@7>86x?o4-4v5yZCQ3GriRplR@@mcKt3s3vI0Am4L5uS`Y_Fd$sX1nK8c_ z8nDKF@Pl6*kj=?;+b;Vu)O=etDs?HiUSQ;(l+ITd62M>rq|Uli%*erZ^v*6k{Cac4 zSYsNBzc_C=bM06frll2zFG7|XMm8NV8osvN^hfr1yMcfovy01h7UWE*R| zrRxX*=GEbGW-IFF+TZB>)rJB=TXsLiY2lX<-i5nzQaAtGYsUW0Xn-!{ozP1jWP6BD zshzTuo0;o-4#m40u)_GaR@pPl0`|3d#!#kbZ+Z!J-cU{imZx>Za`WKB~ zZaW%6FVv2NUQeWV-Qoyw#U9H8C27d_6&p~<^uOx?inO~h*FmzL4ii}7KWwb%>Clp| z#0&g<-B9&0d1HK6w!S{VYWJffmLbGEv&Djt)qwvGuu?V_Pi9hnIqEkF2i=HvN~E=^bgkr&q1d5*oLJ57{`y=K3< z8C&kWrr}E~-20v@!7T`#^rp9~&^qkmUUmwf<`!yGC*vI`qPywx=o27}al(1a45uvu0%Ha73k@}oga zx$O@=tNd6r3Eu`aE#DDmDNg*p)KdOp=p$#V>`Gw+ft08RWu-NKZl`oFAk5_xZboGvnqJIq&^JB!1MYg;o418kStR6*-y2DKzh+gSmV)uX(JfCR{!Xh)UHd$$!@2x+I+*>I?}Yvve#j=}x=N_vKO?}7lP(=l3Xl{)q3 z?!T9w6V=!}n<2peo92flN|Lx7z%*=)GN9b~N}NxXD}Dus9cKm4EWw=iL${~88UBtR z$#3$ryxl)N#W$ZD@iwLqu&0Yg6;HkNG~>s`v?ooiJ6bR__Gu%H4pwRNm96Coia8p5 z+;}*}U|hyhd!SE92mxcB(RWQ_%ko{AuA|AX2G+Q&-Amsjg!an%&R6~xHzZx>SLkF% ztXNNOF@9eH9=#<}`Isa5uHzEE{L4lT1wElL-WKNl-AOwKAfh(6*et8r`T83ret@X- zN3l&lQGE9Y*tqgJ15llPV)+fD~39@k0vRbuXuoZqc=0*gCSk` zcU0yjFIVEY@N&-NVnj}Ir00WC1qCMM2NIwpE0;7=g%K@Q-~_9<@=FRwEn+|cIpOC% zI-(~#;O+kw_G3I?U0SC04sAx1GSi44M>9t}g0GE1np1>R((t(K1CS+D+W|_g%GfqA zt~P>3%SDRQ#SJ%)aA>V4QWon8DH{k0L^VYeC9nPxS`Z3nVh!^;=oIH!`cVb!{hB+H ze%wIjdFpg%GgV}nOWz}k#Gp)rZ(aa6N>b}eIzPvuE4?zhMapt$FGC%Y9E5}DZ9imD z*h%A5Qz0e4X$g1q`rp6Uld{wvt(m~UfHSpzm)yJ#8R3^qpFnLDm*OSf%FoED+2~ud zq}!yxrToM1vX6npa-XDW3wFvP{?ZD9CUx&GrLFWBo3xK^u2#W#DV3o;>CM?rzNDeXnKDwI*3agb zXX2&4ErDLQCuqOSOsUt&{bFibUd@xwi5AbLkK0(DX}S&z>2T3&q)SrF_`UC&U;J$Z z0!iV*S;}Uz@wgQiZSarOHrr8Qi6iaW7;z?Dfd>F=Ddjl|_NFYhZHanJy)rigD*Ify zAiSpLnURVRm)<@f9Y4L6?0!wnkooTXU6vsHFf>J9AG}&|{aW#VUI6Xry=@XWU{}tt zrhu5^gNds*BE=w(Xa8OcI(|`!AE;%b%?O;tyQOXbuq?Chmx2UJcY}f!VXJNQ9Kzr) zsa_mqnANl-ak>ZZQVc#nkNVxyG#AIm4QEV7rwe)z^78iJZr1z%R{yTvoCS;l!;j!y z7m+q0*C+b~JtNrU(hHu^dA3ufaI+pRL%n`^>JffCqR>wt-sxsazZNq4UgA>tLx%ZN z;ZG^%V*R$ks+U$b>0MXf{(7CqhF^TrQ|h<5+S?_-fv=tb&c<%fyGA$v_{v8YG{uKRJ7Sm-D4c;$AJ!g@&6EMHsq4s{Y z^5)JAxKBdmy@~t{Y0!lB)84PGk(^x2)}Hx{8KxFvUhIto|5j_}ao{by;E-bzjC zkFZR);%WH@qqlQf#c?B&lK~%N)eoVIgM;ZljP!P5B(TH+QLJ5UopqOG`tjeh&-3#FX$#g6dN20IsfMl( zLG=0TpO@KeP;n%eXySSjOvBNQ6@#p3^_x1{ZVdK%=yibO!T&cFf8stoiu=*?cWFYscS{;u zOqT-R+ZO^NI3U7+)Ew~kpba&`EKlf#8sIZ_>7f!8VEe1Fk0!)SJdzP!S2KD$`c2>E^N-?Oxk8Qo;UicRU8R(XZFs81_?sq%ZK zjITsJGvZQ=iI2M{$*oU7`~%hK->km<)fUtGhCVacWb*zAhl^uVa_>VDeF{;h;*G8U zRvcwrD(}!{#s`Z9zXxIcRQpq?z%=p%GVJBGZFo{W&vSq$I0X|%@d&c+e!KQZ6C%C1 z=z{MGJj#|>?g~7`S-~I><^kaof1Q-fSp5uVmRJnVG0VSCXd~6NYV!}Z#lk(bAkLRY z*{fzZ%LmtCL&CtIV?U3lRZbfi2p0XM#kVR3Kur710Yqr${j4t9nvxI>M7!9f9vY-Q z2azE_KzN*pPY1n~L2;i2ob;d@l}!&4CgI5N`7K4dkx;v$i}J)Xs#?NP-PV+ z(ofZ8a>-a5PUH`ayDF-ZDiiI-6+8f}C7Cf1=~)70=R4G9`k%D*x<|PB>-+e=TKjC% zM1+pudKazQMN*JSBFS+dVZZ6Q{8n508P)40LwMW#r;W)Tq6n5DxpF8Z8TgPud44U9*NE_o0l*D?4xD!+e+GmXI+vEMV>Ph!k5I*G; zYwrl%4@y9t`oKlkJBzHGe*1(m$r@qE;j#GKXxjkP>}P{L_PD{Z-(KGyZ6ZB`eOl1y zR&>Yt1Y=$J;m5k3_bC8KK(z!EpyW4cK1Gdqok5$w7^OI9MU21K9L-3|X68*+tC}; zRO_#x4xAC>&TlY=e5*t=PxWA%3OHV11K%2s^WdB zJ%yAXXrv`0d;1nEjbvo*gC;CTK;rg0z(PTa}{xnIs6x*6dHF_wMi_6kRKK zngaggf%F#~j2okz^BepOs-4{@7eQmA#2`#Bv@Kj<$kJla`CRFBVO5Wt`;<+{`vuH4 zmN`9?5$ZS8DcKco=q+#0fX%&(WgYaNBO!M_}Po^Dl84wU&A@Z21H+^md2(h0zoHi)Wh z)%Z$Nd`4Rx5FAQC`n1}apsUQ-@Xh7(-P@I}YxWDOT3p*~A3}wch+OOlmjP!)C<6)( z5C^r6-lgQ@1+c&Q=Mcl=#X;uqgrcc3Hx71!j~r#R%fx@yBN zKzP)7!VA;>rzy9$%N16POmW zPDhK5DN~1om27MSyJqxL6%adSgU2D#!=ZLVTI=pk&J@8*rwOsqD#gbU8QvUIqE<)N@|8woAcJ@ zvQXBT>XHttmy=ULsKvm^c^BTWe_abGzdIt}V1&W%KyrYQ91Crf6HeRWzBOH|!Rz5% zQ&@^CRkNWtJR;I!_@LbaL=|VTtJ_%|SgECby}0ehZFObjgW^+3>S zGUzL6Npt=(YaarEu)ANN>fofPFcur1!)#q z_K<@ff3(&6CoTKRxb|~`C*qe-t+z%x-ICrB*+-dhGL*4VLxDxf63K70&D>&krp3sv ze}gUg!AHKOg_n8(&A4u%NpaWaWUp9bzpUe?D6w3dI$k1ZqUMM{TR8`(C|6;A=?9ss1tpR%%UyT7e{HMGN@Pk;}BD1dV01 zU`GEB2`~LmT(T_ES#3@xa<(GdUP+HX*N>liWvj6kXPmINXLUAl89f>p=c8|WtCC`| zIZiaJi?S7I0M?UF7Z;7u(WK1*l@Pm6RoULKUvoP>%Xpf`lG56QM0i?i*$1x&4C#9+ z_3N}!q|M}+ms|SpM)-gX>fVC%kRxiWy%(&i;fd1R^)Hl{*I41{N-!vKk0J{9W&z)6 zz-(ya{SahxK?T1Alt5F6LB#xbi!O;z%|X$UrG-sd-ia=82Tm?iEFh()=@6|Szs+|W zq64!=i#trxG!^$wV-+rz^4ZExrs_iXCw1imPlK12mo4#4*&ZSLn#*SwCWIVoQ4AxH zNT^7G1!8B|>p5N_(6Cu+ubVTyyMNx(X;`@^@7m=T0|X)q+;`>;C=1s=Txai$O&V?n zW|eQFVpssUjit`Jg8?vCxA3gYIewtDKk2p8-m+#mUo;uOH9Om75N@{n%F!oRhVK*? z{pOeBm^O@@2V4dX$@y^UOb0+ueMlxLsC2|W=+>$`ow+Zbz{Pc(^i*k>G5ttPF0@G@ zcgN+EfZ(*cu6-e!Q2xMFq=Y;JjsOE5EmrWQyHBr5Qa8l!ZtKDG&wpSBNt3{+z{AtY zdLboC~O_*ka%%KSYDYREDw9A8%yOAl)$ucW< z(xoL)1Z=TR6lcu@RV5O_Hm4g~Wi%<1tIEfE-;ZUhenGa}GM#_&Z#||u z+Ue1*w6?lx_t(b{>098p@&HTg#oL48)74{Da)5A6Q+1GZ*zYW!RkIN}+R3#)-BNgQ zLJTNbs(?Q_)uHyW6HKgDT=B3NF2Cp|0cW)VM}Ul#nPZ9J(4O33yGkU;(ZC2IoujiF z_T>q?Y^V#?eh}HtJQJCqNF7*^%I*&2D>clDc#aSXNa`}YT&Le@Lr{fkc3m2@Mf$h5 zP4*1~zcdR2UJ;G-DSLSpH*L`fPUtJoJ{T=2%^b{}S@+B_ubF=%q!~Y2@}8NWZ-?My zaG&eov&sH`RYm8p!s{pkAVAUMPnT|29x9x^PNoLDp=*;@p>@#F0w*hwl)vQg8`t;IWJ;~oO|2X4*L&gs^O~_dd9D&;3(ft2 zl@e8zHk&$&jpt?dT;D6Eo*(rMRGls>(2~IE3-Yl1mQAHc5@i+Im&LE8FgY0&38mE< zx@68qT#$GqFroxj9vL*)-yeqwMO&fIo&CXf-&38QK}0_(d3dn9#fmwM=Frmsf0?@m zX}L$=e|_s#Xz$n$Q>}mHSy=YQpm>2Hm?-EnA5xUU&^z8Z`0k`o4Ps3lU1P-EhN=;g zFk(=@_JEdfZiZNoNB!HH2nBww*{2&gVR*B&*7-{_&0Sp!s-D$|Uaz+Nny=1Fd#!oQggl*Oqmb8 z@7}Ql=oQnxH29R-9v#fW8+>AiNM3fSuMXL%zJQ1hXtzA5&cmkBK zSoY@t|4{4(#;cwlJ6{$Fwe1VrWOn4=J_9&xEwjW#!>5Vvm>z94D%#?+{r?TRZ*urK zqhzwU?2?$q_nC~L6h--HOY9y2nPEz?^5ieqn~#+^`l%iX4!l9k7Eb+LoXsT>fVlqO zBNT448Nt%ts6NZ3HKk}z`C^xZqCbod(i}-lDbD4H7-i$Zr1E_akX=?d{*jl z!+X0OesVP@Y7~07F&Ta`7It(Rb_x%>!clbHc-+>!@Q@`{bo&(a{f<95Er2}A0)mZ(Yd&SY?J(?HYh?6M&8;rulA%b2<#eFW zD=!Q)LeJl&g*#t)-}UP(9`fu(Q^p2LNAA%b3&|5%my{Y;V8N&Gba8quoY( z)hxe{tV=9I%66-&%4z~|RaIlR!(;0zq_Dfhh|^ z%870@XBWn%#u2#Z)RWtBXknieLybEjuPZX<&)vT~d^#*0>`jS~0lj>n0e|RH)9PZX z9A%Db!qWQH#`bxI`}pB+IxyedQP!I|Oo4LMz-?cb-XC!mZXO-yvlw={HuxfY_`&uO z;jk^Juw~ZQ$sS=Q-Z5jn8~RbzNjvU-C2xwQ<({_&Z#DOzSThpfxK$#51Qd`$O*f&R zD*bjuBrzDHUeMuhzs%Dcg>243l_s11y|w;Gtvm{zFyyQ*@lKqRWrAZzk*9)ioT)`T zfMNqSd{k+ozCCCjQ6FzO(+*$od1PDU3RSEdbdI~%l=4^j)FE?Ce zL~B6cWX~Vf88X#O)!p`nd$k5`6Oca_TWk+_{Jw`VTg1pZ?4mOYY%XHFTUTGXrrGy! zFIQ_hR{CZNzf;~MtRR&XF|+ytfZW~9#)siAyZ&k3UIx{M*>FKf`Xcr+|Uf3Zp1b3ClkdJ*JYcdBBQoRC)|A zJsnbu`>G3HUGDNF1~UC}8CD$seIYM5a`f$+BZ}FP2asXGW&QXLv05<_3dFPVhO>vdyEKag?I#_mbTaQWF@a*K%T3dlU!a98P?ptTPY^?!(Jm`EnTkWZ5FRFR;JNA zUJu}aQ<>EbrhvFJSfl^2+I7nLQZ_BzW1yyVo!p!mXypUEg+K98VC6A#TV?!HWG3^B z#hVrgo~stWR#WMIe&{9t4FB+^cYjrd4^S+`<)mmgn8K7y$;B@%!%;LXol2Z*6P1x+ zvaaWC{b@BV4HJJKU#zu&(^*fOr0D|yooAJO;(5W zeq8Qk#c((UR`O|2!uo%BXSvexU8=%TI>+Rbtx%02!m?4POs z8uxR0gyc{L!445l$`EFYz#IeIZE4w2oa2nTq+YbfO{95m&gcz@5iuB9G!S^JO(T+3E4QX%~k zK&}MpN#O$4gN#UtIQH)Cjj%?gI~E0#`+NT%00=?%zV&(ip~p-9J;LJAv^dY)-M0cF zoJfGBPmcO;>;JLUrcF~3W{T(sv8%Pdn=Ph45zHNzDL04xgE#IQmAO{ISZ_A{ukIsL zqSBLBOm*p35sy>-!WX_+a{h<^@W0z^c3=6*mw)}&|L&K*^yR<*U;kIX`}=?VYyZ~Y zi~#DdK_6J1*?U?P%{irEwIq-x5$JgTUAfM=nt9nO#@*^R%w776 z+4-^Rapt?5s+x7Hm{+Gs%Z;6;d4HVdxgDl?910Omt#-hrND&cJg9Lc?6}Y{Fd77EI zl!2LKy<6@-$!a~SV>|8v!2Ojhc3>IC)thg9R)}A`co81w?i@|MH6y~R-8q9cg9rwI z6A?Nfv71A9N~HyoPFXk!A~Cqu26x0EE(DUfnS|rHA%s=~NhDhL`XK zB$3;Nv=}WWj-DcH*-p*RX7}8X0TjeA3pow9!NfFtLHq! z=g+TB(=^R9o{tO=34oN61)Z8dzPMLPxw+X7V|o7Ulu|-TL#8COTCdJ2&;5BpVtRNn z0NLUWk36vV6b*oc(Exl70rM~)hXMR7I|N+c?5}V3-Su&QsKT5Q5r(#g z5$nV(6vS1-1Jv9+gxOsCojBs$&eq#!EmKcoAZCY`NjR^*v#Jhb$;@PWrrTHqfOWV0?r zobr;5!NS_+tEa@GR8aCO~nxdIO5R!}~kWpk2nRG0~%_AU{ z+}bRKBcfFscgVunT$>7`BWZ2xRRT!IV@2ls+c719fO)R1Iv}{=X^ywv-2Cw4>ot{4 z9v^Pji5Y>=)-@7F7MgFzBi;3)-@uFKFSJJ_pB?f0)vOI=i+4Jk4jnQx6AmelIXBf7 ziinbnNbVYsruEh-QtOP85lKy(Hh0rD13=293@bngUtT0;GPB!s&XN;^&voucpmY&! zzm4-{W~P=>>Pnc-E}J#VdQ3Ta?YjJ!Yn^M$DGgc9Q51}bCFhh<&xgSPCdi3bh|f=L zZrW;7Gc#YWhM|<}{jpbgr)%0~cyNC+ovcV=NvaFUz9)4CL?RJ{gg(0k0E1$0Q~)Ak z5E&@3v086-yGzx! zzqz@7@#M*;A3b~e6amL^Oq{`;@>0+BFS=(l=UhaV=^S%^I2M4dwd3K`R2O~28ShXx zHSInP{ZHl0IZ-Z12xA%&3nF=V)%i5FaI@%Cz38mVzKpuUVQ#To=X2^J001Fo;Rt79 zK!h+xhc0wGPXz)2i6IQ!%zH*rH-V1+(;3I@lI?2f9y&pYOx(563zl@o$%Gi9E03|m zk_e?cP@yTh1$t-CoSy|!05DVyCg>g;=bd+9Q6WG{8}No0>OBxoh?m&GjyJuIBL(8! zChxVK8bJsPM`ln5LLeF>4TPxH6x1>5R3YLp@8_uvLn-}$#3dtqAuI&|oC1&u1flz2 zxa+ajSk9GYn{fAD8}$;$9GXT%_YUr0Fc2<+lx{y|4(3#nFoC%TAR|UELCww~2Z0!f zw){C@F^@pKW+Oym zHr2V-GNzma!c|*@Pp1AHC!#x%_(As~j?^B2$iD{#AbV=*|4?j{0& zZ@vBYlP6F9@89~Z&pdwgo4@%_zxmB?{^$S2fBE$3)BpW{`^SIv>GQYWdOV%tlTSVs zp*J5sc)1erJsQq%>DmGk`z< zYkJrph9Qq7Au#5 zfAmH-i#QA*001BWNklm&k)TABiFrB>35st(_^a^H=K)870x;wb_C2poE7v@4p zIVF+qRPXA56oja%u13VfEU9R#T~?>6VLq%kDJ3F8SA!sCL^0JfKW@3zS0ZcA>ypo| zDt)7~GubR9?l_6NcOOo`G~~s;f|xrWn~+2V2_3})Zk^eP=}b-v1PTlcAVvU~YQxNl z2mqTcDG1!@pp3%M=HrsvuJ+=|v;FmP{rttfhYyBv?Icc#h&JQ+v!8u@+E4qNgGH2_ zYn_lG3a^ioMmf=GHfkuI$3LNd0aN z-*0uMce|9kpvNui?6rS>`5QU|8+qxx`>z37T3WIF7xN zBqDH7GejUD03fDeJ$z;u0+vijcy$^{lGd5m!yxPJ;I;%X2*KP=+7z&-1o&>ZU694Z ztMw)&GKF>`X6$3HKp?TQqW!EX)Bf4%?aw@lZtWO>h}skh-7M!EZUAWYkOUb+n-PcV zv251ItK;@^oQ^(@sY~}DVjObG^5XgRX178{Ra>poJXN>IN!+#be~7&vPt$2~4`!Cc z0EA6zH8W2_tB0G_ZfI4tISUI(&xb`oFgQE?BO;i(_Ym7=9b7?15n4>50kt{;Ab4g3 zfO*#Au`%Jj`&(~_)lY{Bk(r|;X>K~lFMs8;_cojLSdtJp)CvHOpbY4S5uk_(AtxcC z*4oqOPv?0qr3}MBL~3gDvJ?m?wB?e8Nqg>_2e=}@IE+9R9IJ5^$Ea<_NQqdN+EUG} z=Vc+H0Y-o@(@@M4!Xon+1dydEsMd2PSLBqNwg_vrQG^gm$tf2%>uUqLj#;e>*87@v zfIwtPt!Xn&-g8$1Aj}mp05zo?&;SL%S(3XmcNbR@5phF=ZhNp!U_eTkljJ1hkVJT{ zjR|ue-g>;=tOwP2v7g`AZQP9zh}jlk7zv4q!(*Lzjk%gm+U$-soFHWsA!J5mF3i{N ze(vZJ%UJTNl*FlT5ZFT!k&rm2#4M7^Fs>z~aTxF2zrWsI9QHR)KKbzK#k1=d&$Klr zT90dhU?xE*g2Liv)vAcBH=A)BOD;L*S}Q>GK*L&fo@aHK8qBqx3w;hCH9yU5u2arw zsx@W2+-)u{N=|$?3cQP~RBLOqYKsUk00z@DI~ReOG~oGFs|uGp$|*6^X|mI7hkbi= zkH&$|-74LZde0g`2yYg(bN+jd&7A}c0$?`;_RfTah;C5J#C$Fgd+<|FJ0*<7$jBbx z77);Fhma6F0D~}M@iPrGU*_o;L4k-lz3K~mD+cLz6KpoCK|E{lUi?t7it?5G9^Nk9;VVG zNIbe@4WgU-)BwPkOoW872h#W5(0Ud%01*T*(o4<;3IPPBY%WW{`ohTRs`_wmt*L4y zf-$F?TA46q?(8yEOG&gTz&W@80RRN4mE`Qqm~qoZH7wvRt~vf1wb!~f_%{`R+j=YRcQ{?YL;ZP#nJ z=$(GY$-`Ro?mK`mgsE$f01V@x>e?(~0z~2>BoUCghbM!F$GWh{_TuujY5d(_Ru6~X zwk_*Q zqqP>a?2Q4|+RVZ|rsBoBe+~eE6sFd3m#JE91^`V>C|2W&Xt8B?J&}x?&4pP7&II%4 z9`9O+gChhkDz~48D)(1g*j=>FrZWH(fH9Y*ZXQG;Nm^a>rF0&KxLKmdQOX>QFcoOuVtj7TY$+i#P*R!69}loSCFSu()Oxxww8QyYv)2+_hEd>OVd z)!J0e&6p7aJ1}qH?m^OSa}@!cDIuaqbOUJQ(&KJ=mrIL4G$JA~H+A(sTF1>QCx(GT z7>%jWx+f^KrcD8{psRDYHAFy|PSbRnuCJ~x?mf78@F;IHgQ@8-j5!TV^!^8*eEQ^h zN%G*{YQ0MDeE<8V`u@A`T-?7HQ^r<1l53%TwF?3;n6rVmw!Gkp0SvljpLz6oed>(} zg(Nv1PsGFoiI)heyQOf4%2q`V(@SkI5CsMjGI9ikE?nK5rT_8%3FelVGlGYqzcMW8 zs7ewd!knD}60ew0RqI@dxHX+mGa$yvUFMXBluMQz5u7+Dy@8wckaP&ts8KRX4U?Rk z`82h7Io-!<+T0|_-4DmPsSy$*#d((ifCzYYbx^aC)4hw;W*kHqp--@}_q5R4-}A%i zDID!~=DV!JSN<0P5P{~;TZ++{R{*V9j{~E{fHrXm( zF8bvnrbG<*GB|Ph;t&u(7E^u~5T@{srq5MdGo-MvTv$Z7Z--0~(3R7zd8>0NLX2*a zOU}gBlqIfS+$2iZFAl3!G3`Df7y#N75l`(#gxzK)ASPnm?uL0bH=X90Fb>xzW||Hs z7R*`PG>IVMy?eWWaMf@)Ocguzn2}TRa0?}uI?rm&OmpE}c=5IYFmt1|*(&2E^nFBx$av)Vd5l0x=BS;KL91_cjk1@xkTl zbW<-MmixQ)b~OySw-7JC9_$4f1Oy0WjYauHM5}Q%P1D&u6B)_DZfO`qN+7*fWn}XR zV*nU315;2ms}5#vvxB)4VPZiPf$n3m);bR(=bSt&dgy}MzBLaw zwQx&_eP%wCVV;gXior~+nY$xlq67eHR@;&*4@hOqi<1U3xpihsPLdL11T&>1J!4pP z0(3w}TBi<2xw|_PL&R7zQ@2#*s@7#Qt1*l4I0yiIfw!j0B8;f5LPR%+6p~(GF%c1F zE@Mj7w7OaZAr?vC01+(AOll^GHKL@n8cL6^7UJ_*9}tMSq&$eo<;6XK$fc||o85MM zvD?*JpFjEJ+0##NuCItlTWea=YBjFLKETPjtk+xjXch%==&9i;1CTkWhlosS^)%0Q zuFcHsF!dK4&3&4VS2xGQar*Sx)n=7aqMTwF*rw~l&9K?6FL%2%3f>U1x0d$%zD5V5bm0DqLs^(RFnsr)hS581mG+^7ZHze zLpbxY+z`OJD6tEXmjDexW`qDUFb4_@a5Dh*Ui}eux)eh1RUDbqa*&)mRVNP&MqZk$ zms~q0r2bx???2EC5F!+8Uc@aB?hD`SwK69$LjV!ps*h3!@XkmT6U+(?=&IpKvASCH z$ukU_ zQj&DYnGqq813)GOz&>57<|A+7F_s6e({Tu)0FaL5*`JH!u{O#ZQ?SJ%-|H`qo0`NHSYACBQ1B7Z*wJula^#`Wqt}fsH+EnZH zr$5B;@uR$*suH(clFrAR@X;=9H^a@LUGL}T*Hg-?jG=0MX(d8J7*?C1wkIEd><}!O zB)hw|8$S4-1QIY|=b`>oK8%PU zg0|M}PnZxH0t46)mvk==M|)|A67J@1?sJ=kd$a*1W>_Swop;Q_=pJgGL^x$6jy{Zw zh;T`HcI{Y-SnuMZ#QGNOFCag zcs8z+B08Q22SkfcUTZ4MCCldW-oN~le|dd#Y_*k=5Yf$;a|C#t0VG^z{4Z5)07*EB zXg~*L;>_P9qC%KNnsbNh)D;nXDkX-Yol44qRMi1rQY3^i2;DqT9D);VE<~&L;a)^= z5+tnkFrD_fjFh{FP$Wvt8ixMN=RbdWv71lVZ8|;OPqpM}D{CfQU^!0*DYI z9Gr-{#Rvcp;gC~p3-W>3$1k0Tu!Q?{wb*NKL_+WYgU;TD9*TzNaUcSMqc8=BcIep` zviEC&&dY@e5%0b8{%7BQ>u>yxZ~fu#|ADzf4>30*qUc3qEcOD6$5KaTUmoHwN0XTe z%n(o<*tL3Kr^ubn_K}kivt$`^&O>sK*7S6k=cyqgF=pbPRK49L6TH3w7D^FKeV&z> zO7ZSX2Nx>0=4x84SD$?RqD}LBf<}xS#SsxR13?fvq19??w%(L! zuBiwSwu($v3cGqpoTf=tktj*ZnF7MSVvj-#jgS@riIEN2Q(#VF%_(7EsJb-=fPn5= zvk*p^iG?J+e35ztjU*0_;PuU^ZpJc>d4HJp`{M}fU;O+d00^La>tWvdnA2)3w|-Nm z+9TMAh+a}w`g?-a>S3Dit+!<;tJSJAxSBQsNWvWw=zGudY3}Zklk|N&rxe7^>{L&u z`DA9>VPkGda>=O=Hv-)3^{$zThMcbVht|~0Q!ZK3P=@e0O{ddz>VC~clwZ}mv!u?< z>4qnBRX>jm`WAib$Lin!kkS$ZEFyi1ihwzfIj58|A_fvMw^nPNm}ON~MASirEO{;I zq^E8@spj*%$aUQP)`}#;dJH#&5kj~RMAc1IyXwW%9e5EGuO`z(n9 zMQF21OW*?lIOJT`>rEGBIUpeRS;3*leSUm@ zZK|1hyWRY?U;X8G-+9jg?qA+}$8on`$u$U?(MW% zFriR{gQ_E7CKO!6>UZ8pKp~*sc_-?5EQkQW%n<<$5FjWEr+k547hX635H71IdKm)X zDVJVJgawkjLI44KfCUxFgAjtt5?T{|fO-BdLVLQ4hgo=pBLc>YS(>v)>tu%j2u#E@ zJ6R+F1GnQHomvu<=$wsyobZBJxx#tV_6{+|GA!v_sas#;h`zhO5`5N04r* z8>0KQn8C4Wz^ul`NQ5~t6AeQa=EW_vx7pkS8Y2m%^S%M@T}ZYXSFP1924X}9@4h|V zYm!9zji|QgSJ#{EZWveZz5hXCxqt88(2LquVQ&BAx4ymGU3~RxU$1Tc(GPz3*`N8WhM0Sd*C~gjOe}eB zc09EgFHXBn5=3M&ckn2gIOjBOhF#rXUr)!Awrkb4V3&x((prm*ENp5>RGS0Dc1%Rb z%w6Mtm=6&GfZpKRhYP8uZg%24E@dl21Wt41mri#Jbbv%cSyFCwZgmF4luJaP4a1_p z2l6m*L+VGytv3mp8(5d2#d^pQF-J6YURbgy%)$uXz;*F8AzD<4wVOA@602$L_KOyl zlu~DF3oMu@A~LavEVg^N2xFQzfXG?Q!WIxGvZSiZ2fjwGg9rdS>)z1xJm(9jglcEN zi=a03fT=11bVvC9LBia_p#o*d6cN*DBEnQeRV5`!)avoYr|;dnyiA$Wumb=|>E8Xz zuYT@7iN)1ufdYH z6|*x|;v+yE?IvYRADNF(=`i zcpPq>KbCz$&BA*;z)!h)AK|#nXL_#^0n7l77?@K|MVhv0nydR?*v6c%>zkV&{rH`a zKKar&f9V%nYv1|K_aeZ|a!wIO7>od|LIg<`$w2gy?slG1^vgZS01!k?xg#2ceeyQn z%tSB@3C{`O{Q-3%hkFo#n=|K5E}AB5wI$(_lUanvT-*JJDlb7`_@{w>y?`)mi;_2 z$xzbva(z6^rR1Ydty!xEhy$Vla1p@PCL>I(SrGwz#lj+bw?{~fEXdNG_38GhxphuC zM1Z8cpW3RV(SsU1ez^ML^Sy;bdSls|4kdL78WC0V)>_jB0m714m}$s)$T`5()dPEXK}d177zkozCRoWa~5XiTHEn-j0h$k%JAB9Ou0maw(6#4cABc1_0ePpPyvAuQ{jexepSX(vgCY7`v);VQ&zq+|vmkl!on1?Tbxchp& zK_mxUZFd)!_r`Hma%r`F^wEbeo)X?0B8ZoC^=8lF(qlL>-B0FRz!k` zb8GX|#XLQ7)Ti2-YHb~-Ff(t}_c!y0A3yu((@(CiZ;q$^dLyOqNa(AO?3EbV1sy!;b@h}`|hJE+$0cxeZagBU%k(0~ALN?lh1 ztDFEJ6L(SU^V8LO90Fo)G1ZuL38jnx3$&o<8YZ(hb}=hW+I5o*5X`O(0-anVqV?b# zTU0xTW~GzSJ0{kxC*TYdxZe5ckvT2M3Is_e7B>rP5uy51&Wm^6|L6zreqahYB~`!P zACjcQak_u8DMP;4tvBoPvp@TpByy_{59nIf*FWpki4EKx{q+CTeR)e=_lNz>_5RJb-!jwvVc&K62n+ZPp~57DwYICPn=gL(>j3c4haYUW8- z%{S-To<4o@r7wN?-~SK(-tYX*|ML(2KhEAX=Cb5G4||uYI?LU@rT6YxIiyHYBu!DI zWJ;D~YauDaaS~g!gdh$O$4HQP17bk3rT9k>1PGD{whZ})Aj@!qM22HpqNF4i?I^Yu zYN5CcNr|+m8O{u+dwP2NmV576s_K2;{HSxk@9W_tKXQKbblOW0H5h`;Yy#zy3GOETudQ{VT7$632M|{=H#L|M-9T z*u&#v=Yy$%f{Dbn8mOUU5d%biJS;7Rg(;H(03_Uvv0V(U zE{=5BQ2Onr@3yMyLsNySsw(GQ?$f&KR`a>v72^!RvH+k?^}Z>n=zB}!kYhUPqZz5$ zW;?V^AV=Q0l(Q!!H82Z~_Lt#alH=3p9WCb-J3_|>2F?LuyP$Tq8pr#v<2A3O1- zaY4*uA0?-{YE(>BQ_2sIPOe?O3>=uuJ6BcJm_{NLO~`D*OHvhLMrI}|qG!1K=E?|2 zR1BDqn8=si70kR3>>R)(Z6Yb3MN))V&*sHxnb{Xej;KmfL_{~y_H>f-F6|2hfYJrM zFbD>dX!c}jQec4wXuCxK5vx#{8R4Xide&?qBxB<@%&b!B%h`KYEhz`sdeepB=2fDL>L@Z!5QG*;o;4jH$MA&pCLpaJTWO47eLg71+ENLRe1#SjtaO} zRb9onTrg2LLjX^NK76MTVr@>XLo{2S6Yc zz@%ARF;M~l;0Y3jP@Duzac_UMesKHp{%YF~IZ2;JQ4y1_i%kYs9O&O@9sRU!c0}2 z=bY3uS2fj*+pGsL90&29bIRU@I{2n>b?ZaLG3Mp6K5l%9Vn}hs81rhs-8*RW*q@&C zRqcY;wyi?t!Em$g9~})ogua)d-{vv3^ESrB=u$e8s_L9`juFW_XJ%teF=tcr z>^=MP=F0ovJ;EeESpsDMK=yVnhr+l-j&!SGnMv2S5X>s}=xe%_638 zijQ~7R{#(w#1u`;RLQi$3;>?%h60%b07PRK2ufRfI=uJAn7s(t#+Xd4U;sp|baD}~ z_BAqP$)%T>Qw}avz74(>$!0V_So*ol*{rV%tuV?rHPkkyNEC@&wF|1CAME z8qGjei7|qj0eebgvdLhz+;1xxdN(H61)7L>h5;yqh4OE;-6f~oVKTQxL?A9~j5iF5 znH}se#pL6k_$|;WLqf!>hkH*wdF5o?ciq5DO#MsM}$j6z2$moEkdDoMGFI^R_-7hu~Pv zX7hHnzYNs`Ic0>D3o8Rso|H0u@ILsaY1Zqt_aUX!w)3$+vs|#K0;&kWNHM3)w!eAv zW{T(-;A zqfdS6cmMUT{_4#qp8UPfJYSlFU-;sehjC!%XKnlTZ+PyVZ+~u9b0K*-U%mXwonQU6 zPiCkmuBJzvZY5BKV}-fWJCA*8L3IRY3RI)-wvGZ+9)c`VNI6XZ@#Bms_P)UyDIH|^=4^5cO!|`!807XOv$2e=l zUex3D2<&{_uww%dEqcUSe1V;JL==3r*_@8UP#)tDLfjrN_6|Ukq?A&c&*vco=ZF!R zAxVOXO{B;I03oz6`DSECnZ=SMWUo8M3_FjAHo-N|0;ZjWSox1yY5(r_FMwT!b8aB6O!^Cd*I6l+AzKe#*2zn+?H`(e|MaZJOQx*?{N)v)06%gLL{Rh6%U zuRK?doab#nI_8|=-a1{~^J0W&R`qHrj_Z?kRWCv_D;T#$8;Iccy`#_l-sivi%4?^a z-VCa$CRZI^zJBTO0081wx276g5O4sPb5s*GAy(PZ{Q-cP6_6b_buB6R5LCg;iV9pZ zWkivkgdY)@l>1X)>LTL3hXQ9EldG7Bz=LHn0f{4+4KXsaX9Cp5GcjbfJ{o{c8Lz6E z7KNHX$ONN8R`sq@RY5r$M*vVDa*a`Gnq&a93poawF}S*|4h|2Sl?MYzL(b9--RY(~ z*{=8IaB@1<4G`BcSrqY(bH#|b4=@`xs`;o(&ecgK_(b)X^aYsN81opjBa$ozKt>m_ zd~Y}iq4Hb@ACvTB1T8@8LJb60P}7`KQ9OUMwv6qbu+4gN_uhkH7+0(16SuCv^0hl6 z1u4y@`7HTY6;c6yT>J4trkv5-u+2t{(=w-hFMF3c(8L5vQ8Wo6I>OCq ztXt>6og8&$;5`9hU5B=<>pD2c2AWc;YLBGbb-zB@nnBw(&AgI4c3n4bRz=jB2t#m9 z6WUqTcNu`kKC4kxc@=4A)yZ*}lPs4_XsRmsd-spKE`dtQg9;K-u62F9aa9Nc>^W49 z(E%elni@C8Y1GrBA*(cXRnmt6av+8&mU`?^(UdZKVnzhj9a7m`Ftr>-vjGA*Vu$2N z&8{5G(F&W^R6&Z1C7UNURY0570id|fF#yFF&8$cxENCs5pjm7BB09TRjqEk zn@CEzs(ckf`KOwtl*bs0&YR;9{G=jEh`|;2l@c?7fu@vCw>UP0SM5hPXHiB z&Nbx|>-B(02dl%)c8EEmBQs_{^(C{)db1wJA?1`(QnMIwHk*~sEU1k!0>DUQ#n1*x z)yDDM`mGMZGc~?m)^iaV(s1U{7D83KDp@KW7~09ac0*Ta52jjsKPFXGcVTZR#>v6c zBtxfKbgCUeN?BAHdEU;lNbBe2A}r>$A_E!%tX9jzgVmEy-e~ITnP;A8 z>gwR|FpjZl>JZN7{PFQ4P|$PoJvhfP8x|ZZXnE!8rP-x@i^)<-C!3g3jwAWz|5dPS zw}L$OPj*NINI)fMFD8=$YyhPgi&iSeYUirGC9HkJnWsWB6I?_yUSKY&p#gG{6`LHp z%ae=(SUM*P$h&>r%!o-!DZ^nFE69W-uu0MoGvN^RBySa!qaB$W3``6N)HWj3MOnhLILR}K85R-D zoX^u0L`>su7etr@3eL5R%1MS8UwZZKb5GqQWM<;1>=H@Bqn7DcI@*DyHP2UL1|)}s-=twKxch{5r&*Lj+n5-fB-;Z`9_yL9+3fAu%M^1@f&`_13-*0;XxV;}pc-iI4E zZry$D&R1W0@jE~G{wHqT{QU2K<^KJ9A^0m-E`P(@zwy$gOMmb0{=}tA-oE?V z>-XRB_HTUOx4d5@f9|uN{oPM}_Tj@v-}_zPhQwsL*=#@k{1+Ch{U80&zjfux)fZoU zk%+(d`@ZjYe&@G;=BI!9U;XP}f9~0*pZ~%iIM3hkwzs_J-S1p37GR3gEk!PXD#z%& zBL@XjX9ko&*3MZ7Trd=-P^t*KN9=q=C8zCXbB0$e{68~DDG%d#S;FuP#UAC#1vGl$_os{ zN)*b<+>cYEV=NRH&w}W}4AKUXvIu}MmBk5n-IEDE%~F~*de%vurX=D{qzRbG?MN2| zL;(OzUDZ{P9Uta#>EvnVW;r)~E(aB{2r#p>-8@_@mqnPUeq1X*mp*`qWI5w@mnEXm zR(X;|xrjQkVHlmG;N5OQU!3B*)JSCAjSr5u_a2^t+0kh?j8RlYwDgin{irOhDpFNm zBvzFJi)~vw#=XP#mS13oqO0kgGZiySDV`obTp`qTgTzQwdymWlbh_z94G}M2+7BW4 zYL*ndWdz767XuyvPXHo`nLWE%h3heur6y+yj+t0goB7NP#(q!{?_AT=^ZA@44sl?b zTv?%D;|*fAvxZ3#5+KM~hJu4e$ONFOgir`k1yXb_Eo-P4fLw7jjVTuipwjv<)FF+A z)>bv3FEVuHT00LI2jF%9)C-3w0OTa9S{E(1x;C{i^Rs1pIqx|}M2In~T0dkF*mh&g zy50`k?P%>HO6Kw8baNV041w9XGy)g_Sd3CNE{l#aH+AriHMkgy;3OG9@wy?Rlrxkp zQ566@({eFiZwE(Iz8g$dNK!U#$%>`(iD$p)EPpwF=C|AK^my~===kZUpLqS={W6gO zk(|q8y7&PVAuHFK^=8-PQzLZN2wQZ}fN9k;a`x|lj~6&rvQEKU|@W&m}? zo~i3%sKe&88%OhwLgkjrxmm6otm=>@^j+*WW7Aga(~byzU`b=jF~-~vbyJ6Nz(PAI zY(6tG#miUPu`}lsfK;KXeBJni!#OZ_UAlB>cDp+z!uib2W|bMv7OjX5{lJaSlB>!& zPa@VfbsS{7?O(h7pq+=!>4`dZ#S7Wvr0Vln-ehJ&$&?;Xrx4LOl1u=w zw_G(zof_mU%sj?~j)oY`tRE8- zEf>q;9cgA+vZ-lO1FP!F%^V=K?W~>8z2kZLb1@H9*lsruAKve}ejJ8z=uNU^8zq*9 zhnRw|2$7INsOO8-{{F#oxvacLM8nDFH08YB^nJ`xbcksj z+o2Dvv)13ZHWyV-c>Vg-!%O=&Zd|>5`O=e5-n@GCaJ9Fpo4V^dFpDvU5YCheQ%WjU zx3v$x@P>Wm%Zl$9)qormJ3u5r$A*?XW95UG@Z-1i{Ao~?Gh94@FYzxHB`h#C%Wzg4 zD0;z#i~rb3zzlY+m^W+t7_vD+6VL=u`2IWNMV%gM1!7dN30z@d$docN7e_p-JQmQI zDHPRTA}~WR3l){-Nj4#bF(m|2RY8Es&OQ?WfMdrM6BwuoC*FO1AT}ZZG(=aWrYbD2 z-S-zs3Je8|k17IahD?SN)mTLtd_pWLKgB5HtYcnY*};M@0zu5|JS0&=nIsDEY!)Em z;oj<KKRm9UoG0AhVQ&%o%W|f+=U4#0RX!d=|aMafN-J9ue)T$ z;aT4dvs%t)W@iAqPV(dwi06>nevo^QHZQ*Xnrhx|I~8dv|KL#~7S^$;a@)*_i3%FX z009^wtECJGMog1pXTMAA0M5* zeES36_QAjS7yqM|zWTz?{oK!a=R)v+m|{et(@nS8^p~$(O)+&{|CVQ;?fdRaU;6#0 zp18SMElyv#OGI~W-*(Qw=RNOv=GkZe(a-+FfBA`ju~^Jrc;SV={bTKJbBW`@jCxCw}qc|NO~YH{S8KXGC<}b*HD@5B~@M;ofTRfB5hJ zyDxp|-?F23z3bgS^g}<)?0)uVe%gC~<@$|-gM;7y((l)G_1^cq3jicV%b6z?ZWJ&i z^e&VPWRk%vXmIbU%2&ZpPm+}~0;oaVv@uDH>FCi(jvW)V^L93CRW-&0NW(B@5d=VD zP$Blpv9L+chZV>ynb{C?5p%7*uiIHOo4@+v3vYkwN>geuhi%*J?d?rzjFBRPCrDc~ z2|g4}Tal3o9ebu~F<%@V-+yeIGmB$imW3h|Ax1K6nE9fM=%j{>z%Z>gV780WFve0P zQ@F4hl{RXzBSS>DOF59pF#|$Ti6|#3a^b`ii5~&jdoYKS*CD{y(c#JjRS^S7F_pY! zDr1YLG-+FznTqACnlq7iY$frMY#0Cln5mfE?)pt6l2lZ3-fp|s@1NX#aNLh?bi_8Z zp&yJZm8b?pN?Y*WkK@qRo(Yw0(+#hmJi2jkwXo_O;S~Ou%GkxBMoo3QAm`9g6@v2t zkO0JxPfoXL+RpabDaO-s#hi1ff@j#S69KCTfU6t;zGt zD-|u^@}k6n1kO39 z>OcrtvMLxj1E1A4+u`oLquZ}P0E5$ROF%M!K#q`saMPuJOb4s^a@OoOjj4c{qJ^19 zW&*34Iwe&B0@`%lFviP=drWk?*$!ju`mtznMan5<$&zATpL9MrGmAr-ri`%x>ZB?M zr4ok4oeKZ}|L_lA_{tx>0gYx|TR;RBy7(o}@k8OV6(#0Ag0n^;w0f6*XXk)61)w@f+TxV(2|f3BhhyQLF1 zc}ivq?k-Etk|l~{Vb7(_mB({Hyhwtm-U9_DqNZ+!aey5|1^_}>h~%bzTmcOVj@Eh4 z00>54q@qa^B9xxYV>9#d)%JWg#>tAi4Dp#NfEkQqo{U6xY87TS#GxPhg4@ZGRW*dB zaupJnG{!q0Q%otPltg6chMWWdLLI1hUGI*5?5W6!>`H5A$7E8g>e;JVQmiK5KluLu zbe8e}01$g*#{^@_DT`<(q?Gd*lYuo=)z(c@*Uo!jF4Dm{<+Ds+Z?Ol6?QGu8XRH1F zx~|wHj^l&Z@2*czW3gf}P>~q>7}Hsn*v@C|a@mH^Hg(&yv)Oz;Tb%u}Zp<-jjCsA@ z9-VBCH{Hp4b9A~sJ>I;2@8QFHM~2u0p3U6#%dMIa;mun&mdp8#8`qzH>WM2?FWh z0I;a$3(63V&i-zWj0uBB20>F(SIW3*ij0N1nlt1KhM*{Kick|J#QgQ$7y}ff;?zc< zXgX0*35YmnAOv!#YTlD01T!~@ZB26cMCTE>T4^a5C@Mf<=bM=&6SGlaNXV8L4Z#Bd zFo5QXng*a~llm@#0r2@sY6d2dzyK72cK}-4JOIGJh>b4%>>~JXs^o~6O+<1;WB?MR z$%za|RY51tkAPFvl*ABBr-bLt3Jv9^P1VG+S1uhaQ_clLame$Dat70yH13>jnHbLT zEN^z^Hx%&SP;J@0Vo>UQ(}(m;3Mg7C)qWQp=A1WO|L|z@;QrCWqZ3uRa=2`kOGG!0 zhLSC(ZmtLdh{0iTAtZt>;mLZPvbAP?*E{D*#RL!>B$LrQ1VHC7I4IPkez26H_q<## zFI~F)V?X}ms=AmjMdiz1`qDr8*`MjR+xGC_l~=y@P49fyYVY9x{x_d&+oqYd?|tuk z|LBE3+HSYY)pEUFA3c2Z?31@P+dhP9wc7ig-}&wNeEzO?y=%Qb{f*!FwI`pr9)f@P z=)o}bckjN&?B4zE_k8F>AO6LU|HA+AfBx@H(|rH;edt3U{>Z04{plCK`pP@s@zx5V z?+0S{#I0M8j*dR_=}+Idc5S(s{lOQ%_~kEu`MvM`=J{fEy4n7@kNm*ZtJgmJ*-t-s zcyxSvy0=`iW8BHV6y%d;1&bO@E(o3yVR9iwAA%2+50fSe6$H8`hbU?2g3G)J^Z8=F zn5o)>hbQAW#;IwIuF`p8%8oOA2|j2X|W`vshJx;}k$vIc;hHPmfgHLmgtj_-K- zT24vTRJ7Z4^Vz(uTvY`ClylEr+&wXhL|CNOi3|K^x0)Iu>>pfiXUp};aUA<$dvbdJ z_ViqtvJ12M42e|=C<`(*K&Ya1aN0c(6)+7B#BjA-J?yrXjwV(r&E7eYXlMQ2a*rlA z$%GUDx#GuUWTB+=h(&raC*4FrFa+RTBd1I@J#%T<9YqYbG)#C`k2C|vtY%qF)pppU z^U*YzwB`}ta6U+JYDX|L5*FmSXi2N4MQDm31lcer4Z$O-cMiZ}!er(MQdTi>o@!<_0LVyFPRM9^91)S? z5U7nx&ap6o0f}eE5wQifX zuAFl@rBDUu7%%j!h^Uy8<}|i#%S2T(k49(b49>$ODnpD6f&kGBvOyKR5|d3N#U$lz z9DFb{K(6W~!sOAE!Ln*og_P5}6A@6;e(agJz}lzTiu49q4g@4}DhUAd_Bg2Z1Js_q z<81M42oRxYAYGtKsbmf4wi~{FxJ1pM`EuzW&FR}AP!XX;xEc>g)(@$Iv!T;eOy~0EWK!lYGMYTJ{oO2dY=>R4{*}mf&LO2BK z`|O=>s<3;-&Xn}b?B!SPESBx1OP5X_oou)3oRb*^ff^(q;4y9~34nrLJgG;NX@@dSO6p@k8 zIaF0d+&@?#qN(PT5x_*VWi3Xu2&daoAO-K6nY;1S!aJ4>r3{J)-q-V46Lap9ZC)F* zq~)p}h8#x-6(gA%5K$IYfYsiD83-VFIC*q>d@OD2;%I2qj%@`dfJA^A)0i@d2(vDh zHBmzdqGo6Wuvpc77s*>3Bu1%l!VZ4(Gf(C*T|eA2u(6L%Uq0y5*hv|Nlb#;m-2$7rz@DERp4p+@%j|*ZQJOact zd6}CT0@gkNLd;oIQp_=@F&1J8?}|4fIgKfeNiV$qSoq=`ofTro6pQusBJ6UJ@mS3iz6a2HKE#D%x86N1~KKL^ekDJxNX|f|Mhjf zTH6e&+-_pu=akbp4ryc;xK!8jWC6*{K7`eBb>-^S)pA*f3K3IEMG0EX zhB0mWvG3E+$CH!oYxf@9dwBHv!$%K~Pu835vaQ<&mW$dsZkn*STHd&E{pQUZSFT*T zasAqrYnNB6#cVcfnwt0x6gY6sk6HT7rt7v{w;jir(-?>T=3A*-SY zO=v_o>q=(P67-*)y!J)D0YpKvfeIxt2*fp!Q`0P&FC>=4P>>j3Kc)tx7Sz}wBUsr) z%Y&pqf<(-yh6tV;ld+VDoI~%}%yxNwsXBv7sb-?>z*!=tnrm4si$T%SP%ZB)dqvTn zEFqbqV@LqeDD0}KVWP$YDCn6SA6#&wwcY*kJh^U*N~ypyLopmQ116M7h+L7d(BsTf z`OyG6>7N6DX^|KqBzDY1j#1RI)Ws}xV#k$)duQdB6;z-Y#Jr*1de*j8(~GGE0wUu$ zj+3AU;2D!2riANFM(zC5|Gy41vz^lQHOTgVuZLjjYZ0mck-~Bs3{$rOe zT{=8GT^EZC&d%ov;{)@lz*M8|2f1$4HKl5k) z?Ee1#KlrJi0o*j9elG%ESdo!j5_ z-GB1^-}-I8{mD;ORj8`!w|?uBFTU`?6HnawcmKVA|Cwi=A>yZ>dG?RK`f}4W-~F9` zyi_!&AQ;RSl)9O!j;0q?n$CXo8VmF zELr!P9A&xiRmdizj4BGM5ToP-Ss>I+2$g_2CNWqp=T)d3Y7J{J7F4wi2;{wJ?)$!~ zLYTENjR0si)g8)j5LHh+sn#-zs)_ElAygB`-iI(-ESwL`Y#Eq_ek(bd*_e$p?XPAw z41L%4T?d$%0TCTmu9{7^!T><;zW%BwcCL1&U9V<_CQNWvcQ7zX=dBN>#H1=yZeY8d z!Q(lC_sr}H0F!|OAdrcphiGtKctpa%3r$*0$)H%nmFBV`n6WQRy&`nTS=4jktb(XoQlvs7owN{$7!aaZO!C^j ziXS+Nhq@fcqG`MoGUxlj6Q%sKlV9G=}C&{^K=VbXapML)C zoqHlmh{5|asy|Y3pK#;Q51N(>hr~n-$`>+;sc?%#2n%g)f7=+x1AyS>@AL8m*AM48CZ)R0L! zzM-x?J-19X*>WB)_uS2#+M&GSS@GEMFR#oi-BdyLyW_ijv`Rq zjufJxNA`w8cU-y9Z|{HZ`TOPMH?BWB#5il3;Cb7}n7pZV{hTi|VgLXj07*naRFJbw zUiQ0OT*O4AsVYJ~t5e%!n+U%2((T2f{jNX$?ne*zHtXY*QlZJcF(xbzFk(vS`1rW4 z>g{GbU(AadMK$w;=zw7Ca^wQog?d>r1K>CelC^0n z5$XFFw`p~$RfRw(Sn4dmOwKU^Cc+eR@k^;|U(Xu$%qr{COoX9g$&fOT$9C?9aR9Ko z1_3!bj@>pnN3(_74&(ln002W*^sP}9s=DgCu^)0%Q@yB-2#D)C_uFKiOhW0^Ny@~; z?13YIIVzB2?7OtT7rn1gjXg4u4}7>+;UwBd4f`h#E)fz5KY8mi7ZbWAb$!>xFM9~S@20ZO&c&CiFj0D$4NOdiF&coVlw9a+O!ro;fE}N7 zi$y4FKC@FJ0LXdFyFv~jj^b5wiZK@xQxSF{go>FoM^n`-Ic3WhCPc823K9{WC%e^@ zBNg@j$;<(u2&^D8SD^}3V5Tz&kcf`s5XT+>T&U{0&a)A5r;^DijN=g1N;+$_Gp|O( zGPg?yyr?FtDgvaK2}<9~m|PWDRD%yGi2~}2!=u;k9N)WldjH|c(dj9m z?XBvkZtXYTRX)sTvuoEb-?(}8@Zj)mZ-4gk;pNq08A6yXXK(CTspgc%VHk&D9Q(2F zhOQrmA*ED;*EEiziim0=F`4CJ!d;R{yTA}LfV7JNO9Bua75)RWF#;875h-C5F?+=7 z?3+ZD645)xT(ItM%!mO1)tp$_pA0bo=8_;GvylVB#&a=}a^7iHF$Tndd6&;qaiuRj z&SK>R0BWdeaxOz(knGdt8BupmXohfs!9M+PMP|#W5jc=L|50daf_eccb>XK>Wz0#A zVmFHcG7&OyQH@ozJnBw#uv|}N+S0IOJ84qa1wtqgeY0XLT>LHx>0;@rXu+bHf?>(o zBv0Mog0@#JohYXQS+!WapMggv0XNX|yO7VIu!x9;XW|5KhF3YiSCgVlA-cfy%^xdv z;@LXDM7p~!Ktb}vvv)3L?Ulp*mtT6-?~rwf~m-Pa$UoUC8?w|Dz7E*G=53E%!L z-}sGhdv-o+uN|U~w%`2t$AA8d zU;N^OhYyMQ@Zj*|LRKmYR|+iW(@yRuMDi!cCRSQ6-Qm+mrprg<1u zRoza1OjXvW{dPMLQwX7`YH#~t7-HMjhX;E|bbP$oY&$cRaV!=@Oo*V)Wg-g3KtoQC z>YAAvL|X0bNft|+{-h^nRmnLKvG)}cZcf)*79XlmdC7Uq8eE{AMSYdh~D*+9bkl+MCte_4?8ABj>2DLvSwhWAQf; zR%h1nP{=k~YM{h)*5MyvEcbR&;3d1*^DGalkT6=&81#=xke2o>796e^Zp1kPN9GBN z&zh+geg!k1O}g@!<4(~BO$n%&H>jCp(W1p^W}a~u{;I0Rs25^`%DWU}PNQQ-K4gJh zmPJug0>sMKU~$6l0j6|rYRAkjRLBfq&W9PhgM(^4nbpvoIEsI z##mTQz&II_rj)bfr*B>VgRi^{21#;?rCw>lIaN45I=XxJ-fA`zNp)QZ?^PsinD<&T|;v2EYwhRfX*PQWycNxQcf2uK}g;^PZ-T|H;%Qh zf=9O_e-^Y(G5%K5m@^=nniR(&ha%#=+gr3}O6LMR6mB9wa9sP^1Wwm!xp=g&NOsqe@8N9&kN`bIhH(2oEx3~{~fhd!Fw-eUfS z+j?@eHq%#b-hK8&)l2xq>6?^ZxxM2r~ zxeger5(JYOWKqfX4c9J#(Nl+eW@rK_M*%Af&=`k4#?sL$9%O{%y)U;vs*p`a7Kl^r z69AAVmifgI4I!NELw(=(aU8~&Ql8H-i}-Ww8xR^G?5)}|y;B?+sZ2mskzJKS5&Jlb zNRDHXjwWXB-K4OQb174o23{Z}MgSl%ql*$QQwE)~q?8eju)uAQ$$6skLkuiS(rk!S za4;zjX&jKy`9Q=~U?w-|;#Xme-Db=-iNX;w6H#fbmw7HK<%@}F7R^}@an|~REq2U| z=)E`Z#~4$VvvN7HC(NK0Y8PY7Ijfm-9K83Ts;a6AfdDjX7Lh?>%4#;oLC8fZp|#vx55s*B}d(9*0cisfTYXefrIFHAsO3|k5-h8$uL zrP{N1q-J$sw9F_#M9ztsp_y8WQB`70#f{z}B_>cPtvfyUg_$xIL?py%!!9WX;YI4C zoN1^aB9Rp_{OJW?Bql~NGcnCb=V08kV1D=U^Ls^;*e@}mbBINWPQ}y+k(mpxH%hK5 zUxZ!}5damC#eq$^kAXQP&Eu|r3u=%{GZRS>&7_ctN|G_*s@sie?cJ%UMKBM6;@76*b8vQk$Z*H}8w?AhP8zN^pi#J4;l}KyxgThD_`@z|PT< zLm;*DDvX(FH{C#@z8@YvJZ?i(jD2Qp8+O<;BWF|{Z>CCQ6&w?ZNQWPPZIxJ>wU~22< zx~}`=r@rvt{x|>iVlj8lJ$iJEmcR2`-;=X^{`t@T`mg<)|KuEfoU1)fo51ezZX{ksivm+hHu(#?P z?l+t5$rd03RV70h`q5Rs@7ByKFq16N%sGDsNq7SU3(;u-ZHR8R-D~$A-no14;8Lfe zV~oN3d4Og}NOfVNuKT2_1~#A7!w|deXqEDXJ5vhbc7>CKoZLB?7+q#ayV0-)&KODV77GMuZ}YplX9Buam^HnHe&jZ7V5` zNSWCM9}K{`aJV;rxHlih)D0s%cI+xM!2wtnuAH3{>=4VHUiaO4*k0RZGEB%k0q_JZ ziGt>w#n#8m#q!dngG*~U*k9gzv|)C`7`K~8NO?@j^J5u%PGgKQOAf&Sz~)So$*k+6 zid?;ZqnR%sKDhtdox9tVmyT35#oW$aU}~D`=JhMDz4m$r2TbgIl1xM}70B#O_2sx#j!`OCK@pY| zHA4~6oB+Xv#&$SfMDxzd%{*PFc{^uf!|rT++NL@1I~fS@Y3@d&fr)1*t%>i1^as!7xT!wQ>a?YlNri4HM&g65?fBD&G zp1OSHaywrf9j}LB3{`N>mHV>o$MvQ|;%z^qELmh2$9_n|5CKnDv%0DqXOc$e%+xV< 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%0A^%C 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%0AenLGzvz=>)lTb44zmk41l&a!Yj=PLU16Y?4 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%0A{>zk@x-5spqInAqJDk5+mF+;7gzI?r>O{2soKX- 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�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 z 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 w0tHb|4u6aW#Oh)guL%o<~wPDT-m!X3C8 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�Zgq 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 num_min]\n", + " lengths = [len(traj) for traj in long_trajectories]\n", + " max_length = max(len(traj) for traj in trajectories)\n", + " min_length = min(lengths)\n", + "\n", + " print(\"the longest traj length is: \", max_length)\n", + " print(\"the shortest traj length is: \", min_length)\n", + " print(\"the average traj length is: \", int(np.mean(lengths)))\n", + " return long_trajectories\n", + "\n", + "\n", + "def pick_traj_with_label(pick, labels, trajectories):\n", + " \"\"\"Filter trajectory by labels\"\"\"\n", + " selected_trajectories = [\n", + " traj for traj_label, traj in zip(labels, trajectories) if traj_label == pick\n", + " ]\n", + " return selected_trajectories\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Filter and transform trajectories" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Filtering based on number of points ...\n", + "the longest traj length is: 961\n", + "the shortest traj length is: 30\n", + "the average traj length is: 87\n", + "10070 left after filtering based on number of points\n" + ] + } + ], + "source": [ + "print('Filtering based on number of points ...')\n", + "trajectories = traj_filter_num_points(trajectories, num_min=30)\n", + "print(f'{len(trajectories)} left after filtering based on number of points')\n", + "\n", + "trajectories = [traj_coord_to_image_coord(\n", + " trajectory) for trajectory in trajectories]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Visualize the filtered trajectories" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABMIAAAJJCAYAAABI0JuBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOz9SZBtWXaeiX27Pefce715fXSZkS1AgABINFUQxAKrBmU0sYpmJCdFTjinQRMaRqTRNCAnGGlKmtHKVCrTiIPSjJxARZmKRohlBgokQQAEMpFNZHSv9ed+m3PObjVY+1z3FxEAKMmqUiDuSot8Ef7cr59m77XX+te//qVqrZWTnexkJzvZyU52spOd7GQnO9nJTnayk53sP3LTP+wLONnJTnayk53sZCc72clOdrKTnexkJzvZyf7XsBMQdrKTnexkJzvZyU52spOd7GQnO9nJTnayPxF2AsJOdrKTnexkJzvZyU52spOd7GQnO9nJTvYnwk5A2MlOdrKTnexkJzvZyU52spOd7GQnO9nJ/kTYCQg72clOdrKTnexkJzvZyU52spOd7GQnO9mfCDsBYSc72clOdrKTnexkJzvZyU52spOd7GQn+xNhJyDsZCc72clOdrKTnexkJzvZyU52spOd7GR/IuwEhJ3sZCc72clOdrKTnexkJzvZyU52spOd7E+EnYCwk53sZCc72clOdrKTnexkJzvZyU52spP9ibATEHayk53sZCc72clOdrKTnexkJzvZyU52sj8R9kMFwv7BP/gHfPWrX6Xve372Z3+Wf/7P//kP83JOdrKTnexkJzvZyU52spOd7GQnO9nJTvYfsf3QgLB//I//MX/rb/0t/u7f/bv8xm/8Br/4i7/IX/yLf5EPPvjgh3VJJzvZyU52spOd7GQnO9nJTnayk53sZCf7j9hUrbX+MH7xz//8z/MzP/Mz/MN/+A+PX/uxH/sx/spf+Sv8yq/8yh/6s6UUPv74Y87OzlBK/S99qSc72clOdrKTnexkJzvZyU52spOd7GQn+/9jq7Wy3W5555130PoP5n3Z/xWv6WghBP7Vv/pX/O2//bff+Ppf+At/gV/7tV/73PfP88w8z8f//uijj/jxH//x/8Wv82QnO9nJTnayk53sZCc72clOdrKTnexkf3zsBz/4Ae+9994f+Pc/FCDsxYsX5Jx58uTJG19/8uQJn3766ee+/1d+5Vf4e3/v733u63/nf//f0HeOUgqlFLx3eOtAKUpOjPNITpHzs3N63+OdxihN1w9479Basdvv+d73voM1Tn7eOzbDwKrv8d5jjME5h3eeOc5463FOfudhPKBsh9K3j3F385ppHCm5UHIFpfDeIsQ1DUqjlCLnSEWhlDDcoJJiYo6RUjLeWDprQUHVQtpbyHupaPZjAWA7ztyEme9+/wW/+71Peb09EHImp0qlUKnEVDHGYZ1DaeS6Uibkic/yASuQqwIqGlAKFs6dUgrfezb3OqY5kmKkFPkArTXr9cDZZsBohTEQw0xIgaEfcJ1ntzugtcb3nnE38vEPnjOseu49XNN3jtVmACCESAwRlKLrO4zRpOlA1zvWqzUlZz799IAzjhdX12itmdPMeujwnWXoPZtNj9KaOUaoBdfedwiJME5Yo1if92irUBoUhpvrHTlnUip0wxm2G8hF3letlVoyJQWefvKMwax4/WomxUwtlVoqucAUI1pVVp3m8mLF+qzDGFBo5pxJofDRh1cAZDRD75lDotQKJDabjgdPNtSSqbmgtAYUWleGXrNaFUrOON8zTZr9dma19oyHwKtXkZvXEzlXeY+yRDBGoTUYrSgloWriwZML+vXAfj/x9rsrLu9doHTl7KLj4x9c8dF3X7HfTfTrjifvnPP4yRprFDFnduOBJ48ecHW9JUyBkgvnmw3jnBjHTNc7Nmcd4z5y/XpifxO5uQqM+xmDQhnF5X3P5rwjxoLtPKvBE1Nit91zftbTeU+YItevR7b7QMqQY8U6jTYarRROa5xSvP+V+5yvHV1niVrz6mbkMCYO48xhP2Os4fJijTbyHnOFWioxZp5/csPNq4OsdwW1gtaKbjCcn/f0KwNknIb1+YpcKp0zjIeJm11ivw0crgK2swybDj8YOqdZ9Z5+cMwx8+rljsN+Ylh1nF94Ls43aK149mrHs6db4iGxPuu4uOjQRrE+W6GU4tkn11xdjaRUUVrhOsP5ecew9pRSSCmhleZ8bdmsNtxsJ0IqpJQJc2K/m5nHIOtAG6y3GGupzddszj3WWu4/GphS4uxi4PXHW5x1WOtQSmGsYb+L3LzeU2pCmcpqvUIrjbEKKpyfd4RcyaVChTAl5nFiHgMxRbRSrFcD2hrGMXFxvoIKmcTzF6/pOs967Qkh0vcd++1MroWcK2iFVgpvLd45Yi7UmlFak3MmTAmjNEorcirEkCm5kkIhl0znDcYq3GBZb3q0NRhtMFqzObfi46xBowkpMU+FGDOH/Z4QIrVWtNZ03tN1Pc5aNLKOrm92HA6BmjVGdaSSgYgbNBcXG7qVwxjxnjEmSi5473FWzo9cstzDHHHWonTFGNnvRoM2GmcNX75/xpOLFVY7jHFUpckpM08zJWXGHEglsxnW4i+KAuVQynF5tkLrSggzKUVSSdRSKaVymCd633Hv7Ix33nqbh48eMsXI1etrwhx568lDdvvMv/2tf8+Lq2v+zE//ND/zMz/D7/zO7/Ab/69/BcB/89f+Om+/9RY5Zz766CP++//zf8e7Tx7y5//cLzAMPYVKWxaM08ynHz/lw48+oe89qMqnnz5ju9vReegHQy6RoR+IKXL/4h4PLx9Qimp7XjPOM3EOpJTEV5ck5w8ZqwpGG6z19F1H51Q7iwz6yBxXKK3lXGtf896S1UCme/MkrAmlNSVNkGZqSaQk57NSGq01tSjmOdF1jmGQ2GOeM1BRVKCQc6bWilIKrQ3aGKxxWOuJcaTW3M6XyjxHPnm15TsfP6f3HTlVUi5UFNYY+t6z6jq8d5yterR1PLp/jncOrS3YjmrkOoy1dL7DWcPr16/56OOPefbsOTc3W262O65urkm58CPf/CYffvghzmj+s1/439Kt1swxEkLg6uqK8TDivefi7Iz16vaMPuwnnLM4b5nGQCkVaw3ee/reo5QipMjhMFIVGGcopRLnCKVirGa1WrFeDThvqArCHKlA5z0pZq6uriXOUor1es3mbIN1lhgjpRSMMaz6FYfpwGE8kEte3jJGG+IcSTEd32rOmZQTSimGrsf3XmKwlBkPgdruwVmDUoqYEjFm5ER9M06q2qCsPcZlpcjZbMokfsMY/vSPvM+X33tCrYVPP3nG977/AS+ev8L3nh/55tf4xje+hjNWoq1qMc5hrbm93lK5bdqoGAVGy/3lnNlur3n68VNeb1+zHlagoNSC1uJzD/sZpTTUSsyReQ7EGEAb+mGg7zcoLTFuv1q1uERRityxMwaUwjmL0UbilOV6lMJaS+csKUVevXxNzKmt5cI8z4SUWnwr12yNxTqDtVb2X82UErm+uuK73/oOh8N4vPeu71mdrbj/4D5PnrzFenOGNZYC5ApliUwr5FL4/gef8J3vfMT2MBNKQSJXhTGaH/+Rr/Ff/Vf/BV95/0uEEPj040/57ne+y7NPnzEfZmqthHRA1RGrYZ5Hwjziu4HV+hxXAkZVKrJPlVJyPhojTINaZc+XSK6VkDKxFLRSWO9QyDXe7Ef2+5mSFc51GOuZ54i2HqMNq7MNq2FN1Qbj5Rn5bqDr+nY2FG6ud/zgo6d88vQVc5L1LnFNZh4nXrx4yXjYcX428PM/+5P89E/+CId94LsfXfHJTWWaE/vtDc+ffsqrpx9xGA9UnXDWU2pCK4u3ivffe8Lbbz0mjAfOz+4xhZFcIrVUOf+NwxiPUppSC6Vk8WV39olC4a1qz0u+FkMkpURpvtg6z9l6hTWWcZowSvKOlBO55Lb+FRhHVXI2qlqpOVNK4XNNTS1nyXM4rlOUBuugxdOLacBQoZbbjf2HmdGyBqr8TK2VlCRm+Kwt93u3aUlpzX4fePriNVfX18QQJD7aDHztS+/wYz/6DfbTNU8ePyGl+PnPBKwxVCX7P7ezPKXM65stv/N73+OjZ9fkkvBAACj6eMcpif+rKVFLIedCqYgft477Dx7gjOXs7IyvfvXLGKN48exjvvfBx0yTvONCopLQRuO7gb5bobWR865UKAlzx4d9kS3vrCpNRklMkiWP10qx8gbVrnp5JYqKOubAhWWlaQXe3D7niqJoT1Xm+MzeeAmApqDbfg4xMk0zpUAKAaM0/8nP/gR/7n/zZ1mvel5++gm1RO5fnLPZbHDOsttPjPPENM3EVPCdx/uOUps/UBK/GQNOKZTSVK25unrNb//et/nN3/l9DnPgS2+/xXvvvMM7777DT/2Zn+Jf/PNf47vf/5BnT5/J+RMm0IoYEtubLXOIpFIpwPtfeoevfvkdHj68L/kbUHNiv9+yHjqu91vAE2Lh5dVr1n3HxdmGi82a3jv6znJ2tub88pz1+TndsJaYplb22z0f/+Ajus4BGeMsQ7/CGEPJhRBmYkwoLfiGNQZjNIaKU7c+CeDqZs+/+73v83//F/+W9997wtOXN8xz4v69Dfcu1tw7X/HowQX3LjZ01jFPEi/cvHjF9c0NKUSUgc2mp+/8ETOJqaBxWO2otUpuawqlZmrbm9Mc+D/8H/8RZ2dnf+h6/KEAYYt9tq1xCRY/a3/n7/wdfvmXf/n43zc3N3zpS1/i4f17DH1PbU5Mawl+lFKUkpmnnmk6YK0mxpFxlADs3ffexVoJhldDx2ojiV3vJdHpu471qmcYBklcnJPAauKYyAAMvSehqVWcUowBZzWq83JQaAmWjZaDImXxEygIsR4DBG2WDSsHA7XijMJbSfDu+G1qhVgVZxc917sbXoXKq93ELgaSKmgLulaqLfKzgDKKkgs5RapSeFPJ2kDWn/UPR/BEKc1tMA9KqwbgVQ67hO001lpyKZRSW5AjAU4lE2NEGY3XHblU1t0A2wOH/YEYMtrIczBGkWOlu/Rszge00cQQKUUcYCmVnDKm66jaor3DYXn4luPl82vuP7rk+mbLuhvQLTlx3pBypqYkoZA21Cog2DwFyXGKxlhLypJkx1gIqTLPM1o7vJJ79kajKNRSSFUC4vPNJSUUlJlRWVEq5JLR2mCNbkGwJqXM9vWIc5rN2Yo4F5y39EPHNMm1hVioaJSqaC1JRcka7yzGFQHEKjjvQFWMdfSDRhuDtpUcwQ09cyi4TmNcJGYJEbVqAWOR1ZVLwWiFtYZu5UEl7j0a0FYTU6LrDIrCvXsb9tuJaQ7ElDmMgZud4fFbZ5hisJ3mnXee8OEnn9DZjmFYsT0EjHW4QdP14rD6rqdky/76mlwLRVdqAVs1+33k7HwghoQ1ifVqRcGzGhwpZnG2MTPOmXnOch8VKIqzwfGVty8YD5GYCgZF3xkKmbPVin0qVGvxvef8fH3raxSgQWc5AE2nWW0c49aQUiGjUNQGhsnXpkPBukp/5lmvOrTRXF8dmA6ZvvOkBON1ohs8KWdcNWAM1jts76hG9kmpmlwLqQiopbzl/Lxnt515uZP7VcowDI6uFxBqc7ZinAr7Q6DWijWa9aaj1CrJZmfx1qFUIpMZNh3hem4AuJakzjl659HOAhI0lVrRnQWl6QZH5z12LT6roplDYp4TShmsdZRcBUDLFePAd+IDBXzKaNPhtaIeYDYTRmmoAl44rPw3Cq3k+mPJKKuhas7ON+x2I2qM+E6SnH4lQHslQ/M7ymqUUVit0MqDVpRscb7DKEWtis5YrrcHxsOMygJ2ojW+s3hnUEq3BFICrhA0ZxeS2MeYmUNGGc3Q9ZSaKVUCRWutvM/OYp3DYEgx4bseMJSscXrFYZyoClxn8INrQYWsPWsd2IoxBqUVne+piG9TeiLFREmZXArWSVDhOovRGt91rId1SzgkS9BKUVKmWoPXnfwOY9FagTJY3aOUpfPiW4yGEEEnSeS0tgy9/Nx6teZic0bf9xSlWa3W9F2m6/sGLhQu713y5MkTPv74Y/7pP/knrNcr/uu/9Jd48vgx/9f/4X/g8ZPH/OKf//N85atf5cWzTzDWsFqtiFUKBAIJaarR7MOEHRy77Y6r7ZZhsOzGET90GKtxztB5J/4DhbZW3lsFpQxVUH0JvKqEMIaERYCroe/puw5nQKva4gJ7S41XEnjXWrHOChCmBzKe28O2Yqyi5Mx4EL/pVCYl24pY7SCvlr7zDKsOYy3GeabDSEkC6FBb0qRo55NBadPAOI2xlRIDOWVyyQze8ejeJbEofvPff8z19kBuibexHmM9q6Hj4mxgN77iq+8+4Ovvv8vlxQUoTaqaQ5Ize5omXr2+ggpGab70zrt87f0vU1Hc7Hb81m//e15vt/z1v/7X+Sf/9J/w6Ucf0XU969UKpomcMkM/4K2AWl3npTCltcRAVUnxsHNQFLEl5dZa+r6Xa05WEoySMU5TaoOUKvSdFLbWmzUhRkpOWNe1eMNgrPhOa60AXqsVq9UKpRVaa1JKpJJQRgpmtDNbKwFNU0zMaiaaSMlFYjGjjmejbWsIIGtDTuIzjNF03rV9a9E6fS7ZrnKjYAwxSmIP0A8DJt2urfPzFWfrNdM8obSAJb7zPHrwgCePH3G+2Rz9RM4a3/U4546/Jy0BGceli1GyrmPKpBRZrQYgo525832qrcdInCXpTSkSo4DIvtP0nWe9WeFch3MOYx0pJUKW+EVrRd91UhDWcn4soO5yLc7J+p+nmWEYscm2OFV8nY2RnG9BgqWw3HUdzllqiYT5wDx2rNfrI2iptKYfei7Oz7l//z4XFxd0XS/PCiVg3WeAsPOzM0o1GOdw5fa5db5jvR642Kw536zY76EbPOuzNevtGl0lZnPFcm9zyX5/Q8kzWnU8vHcPo2RNeW+hIiBOey/iz+Xna4VSDDVFvDGYUlANRFRaM04z8xx5/uKawxhBW2KuLYFWOOtR5hX3Ly95+Og+7z78CuuzM842K3znGfqeq5cv2e8mlJazqChDrVCp6JqkCBYT2ljuX5zz+MGGUjIhJZJegy5oX9A+U7UhKy1gvzJo5Tlfr5hCbCtc0VmNGXpKmXBOo4tnmiZiinilsU7hrCWXRK2KWhS5AVhKyd/5tpeW3K7rOinULsUzpdpalnUi623JmRYwDDAOlMYahapSCKzl8wDUsv50hlozqRb2u2su7j2kGwZyrccCvqoVXctRLLtWWeM5Z7z3x2tWSvxGVpVSC9SKUrbF+gUJOD5/HUq9icForYm+4r3FWUstAlp779HOsVqvuPfgAq15AxA//rySInChHkFyAeMy2/2E71Z4f2COYABVoVTZM4oKGkytYJFnpxQ1S9xx1vf0Xc/l5SXvvfcOP/uzP82P/+kf5f/y3/23fPL0ihhn8cs40AmUfCqtWKi1EaCqOii5xSKfz/OP7wgBwnR7+ksxiFpwRr/xnarWu2kwuhZSO0u0Am3EL8orMBTjQH0xGKcoaCW5b6kFU0BbKQ6jFFVJTv7p8yv+9J/6Bu+/9y6aRNf1pFIY58AYIiFVjPU4Jz+TSuH8bAMIeUJy94KzBmM6FGCM40u7Ay+utmht2Kw3oKQgRI48fvSAeTpwuXLsx4ntbs/+MKLQGGuwtUKBUiuHw8j+MHE2B15fvYBaSDGjFPSDlSJdmHnxYstq3XO+XnNvM3B+vsG2ONQ6j/Od+LCSQWs5a9cDuWR2h8STh+egkHeiJK73g0NveozzxzN0ec2OjG4RUqkauzrja1lh/cBmJaDp7jBjtOZs03O26tj0jlXvsc4AlWmaeYaQN26ub1AGVkNP37kjMSXERE5SsKQklC4459Ba3nu5cwb8URJaPxQg7OHDhxhjPsf+evbs2edYYiCOs+u6z3191Q943wmjR+kjaAMt59VG2A8pElPkcNjz+MEjSl6qCBJQnW3OMNrQ+Q5vLc5IkLo4mZySbNpaSSkJ6NOCs/EwMs+BlLNUqaMcIrpVixb0cgGMBJgQ1sZttUNelFZaXqQSpxVKIsUojrIhrto5xv2B589f8e0PnvLxixteXB+YYmWcJ1xvuXiwlk1RJLjc7xJxLi25k2tI5YtLH3K9stFaTiUOqDaEVxXiFMhRYb3GeUuKmRyLBHOl4JxlnkdySFgjDJTDYSSlQr/esD9E7p8NfP1H3yOngjXyHpSSxBqULHggzIFoNFp7Uir4oSNOEVSmqMTFvXOmGAiHmaoLc6rUQ6DzhqHv6IaenBK762uMMdSccM6jtWUcoesVtRrCnBj3mWkubDZaEG4FkI/PxbbqX5orH390TSpLOqSOa4Na0WTinLmZA9Zozi9XoAqrweL7gRhfYfSSjGW0FhBXa0POQJGDMqcgQY1S6KQxVp5DpR6rqcO6x1jDeAgYY9FKY7W8iyL517GA66zBWoNSCaXh4uFZS2zkmR+mwKtX1xhtSDlx+UhYdcOqY3O2ZpwjXWdJqfDt736PrvOsViumXeDBkzMKApJq4PXVJCDRPgEK5wwxmsb0KaSoeflyx3vv3WPcj0zTxGoYWK19C6YyOReMkUDNKtX2q6LUws1+xqJ4cG9FPziM86x7j9IGrzXFKkIJDQXURy9dlSS4tEBaGfCDpYyRmhfmJeRUCEGQM6luSTAbgjAHUix0Xqoj3WCZQ8F6RUyFtZF9QVXEORPmBnTR3k9L0J13OO8ZVvlYlasVNAqKAMvOCWK8MIjmKeKcpvcOZ8Eqzc3NSEmyEp3RpCjXIQwtOZCdMyijiCGiSiVXxX4/0Q8WtMK2wHMaI845alGMh0DfVyqGEArWaZzVUtW39lg9yhlhyVhNr3qu85aaIc1F/ImWIKPWIqCI0hhv6AeLbodoDLkl2BarLcm2amWuaKNaBdpAbodaA4e1VoyHSGcM3ltqleAu1wY4aoPvnAQGWkkiXoVVkUthezPiO8c8J2GgkcmpUJKwi4yxWGObL5frSDkzxcgckzwrk0hjRqlMJoufKQVtDbqdJQJCSmJ0W+FULYBszzEVigJj5bqrLuQs39e7AWMcUxKGa1aKbugwSgt7b/kspagYtHJt3xVyDlRV6J3FmQWwMJKsW4vverTreHEjoFdWBqzm+jDzerdnngPD5gxjNNM045zjG9/4Jl/72tf59V//df7ZP/u/8ZM/+VP81E/9GQFAKhgtVWjV2MWlFLa7PZ88fc7NbsuTtx5zdbVlNx7YT2B15TBm9mHP2/ox9y8eYYwj5Upq52up5egzVfPJ8n8VVSWx6r2TpEJrlG5BsuKIb9XGBpVE6A8r/yvOOqk2hs4Sw0ScD1JNF68qH6YKxnUUpVEYvO1wPjOnJPFISwAXAGwJtAUMKlSlSKlAueUcqZLZ7nZA4cHlGVop9lNkTpXBW87XvcQSpRIL5FqxfmHCV0iVcZr41re/zSefPqVkYU55Z+m6jmEYUMDNdsvZ+TnWOWKIdF2HQjFP8ciyd9ZhjYSJ2giT0jsBJqcpkHKhjAFtJZCupRJSZHs4UBFWR4yJQhW2PpW8sC+0RhmNMZY8Tkzj3BhaSmKpJIUno00rLEqAG2M8JsglS7Lsncc73+KsQkmZaZ4ppWKMZZpHrFP0zmO1PPtlWUgBVop+S5y37EsU2Ma4kO+TZFYbAWRDFhZYyYUYovzdnZhOKWG6pZyYRqmi61ZFX8DCxSqFwhJ73SbgtyCcErYDlUwl1EIs4qt4Ey+TRCEEnr94RYqZ/X7EGo1z+siiiatITgnve4xzGGNJFVTNt9d1XL9KmIlvAIJK4oxchKlwB7Qr9Xbtt5s7giHyeVIgjrksvA7qnWehjAVj0Uaek20s2pgiKIMyrm3sdq9zkGJC/TxDyDvD+WaFVYqak8RV80wIgWmeCSkKYK2yJPtKoY3lbL2RwnoDPrQ2LR6Rc7SWxj6pSIGCilKG3kOISxFWoyrUUpjmxM0u8HI78ep6ZErCalCCJZBiwRrDo/uX/JQ3XO73vPXOV3jy+JLVyjMf9rwqmZgSKQlLVKnFFwlIUkoBJXvEmMDTl3u+/iMPOYQrbFdRaqTm0Api5Y11WqpiNx6oNdN5LzGD8uQcyLng/IAzFj14apXYzFqN1sJ+zLlIsUIrjFIoVUBpKq6tFdlndwiFmPYO9Z31Vtu1CetKobGUBiJTM7UsYLYicwsEyueU47/XCuOUGOeJ1ApAD84HDmPgereX3aY+yzuC2lphAglVFVbdAWUqx4A6F2FT5VqpqrZCs6a5DWGOGcddCKcAyhjJM51tMYHIBZUi4Ns07fHeHd+N7DTZg5LnthhRFXJb/5UqbK2SKHeA51ru+Jc7e1D8jFx7aUXWUjM5R6y3bM7XKKP45JOPhQW0+DQUpWZUKc1fZkpOwmRVknAUKkVLOXb5GXXnGRyfhZLymBQcDJ1zlFoZx/H4OiR+uC1P3f7ZgD0F1oC3cHvbRRh+XwCESdR/541UiU1yTuQs+VsF/vW//R2+9fvf4/nLl/znf+5n2GhDKoVpDuwPE/txQqHwzgo41LoG2gKR/2Xp9Iq1YkwHSgDPJ48f82MxEULkZjcSUiDOB16+eMaqM7zz5B714T1248h+v6eg+eDDj5jmkXfffszT51dcXGx4560HnG3W5Dizm1NLceRZfvD9p8RUUdpwfr7myaN7nA0Wo5Xk9a2Yaox0VtzcbOV8b/9QKp2Vhbzdjhir6S5k32ul6W1j8t1ZowsrNldF0UoKnw0IfufJIy7PBWdpZEphYyowumKXgrcW/7F0gimtOOwPLR4oRCO5ai6FlBqDsJ2KurX0GGMbaeeLQfIvsh8KEOa952d/9mf51V/9Vf7qX/2rx6//6q/+Kn/5L//l/+DPKbXcHq5wRPJLC5SXqlRudG3d2hKXyrBS4J3n8cPHAnRocU6xtVRK65Ei61vEOjWqd2hVwN1uzzRPd8A10MpQLUfnsQTeVQmdO6XUqMQSxCkENDPWSNKlNdvDzMubAzFFVr3DWc0hzIRYmGNkipFPX12TjOVmnhgnSaC6leLi0uG9YQ6Bw2FGKUt0lRAzcwikXNuiMce2zMWW3KIUYROhFM4iHrxCzhJ0lVY9rdUcWQ61FGotKO2wtiOEzDyNKFWxxqO0JuXK2XlP31us0Vhr2G53KKOYRqmYUWH1aKDrPDklQgzEWFtrY2QcZ0oFYw0pZij52DZH1YJqW4O2WtqPUpLn6xzWe6itlSpnCoY8JcbDjNUGjaFmoaKaVo2upR7Pv92riWkfSXMWQkBzqVpLYkkp5CKHftc1hletjFMkZQhZsQDVrWOB9cpx/8GaECLOGTZnHmM1OclRk0qlxszaWUKowhwYLDFkXC8Ml35wvHo1o5XBmDsAWwPEtBJAoZQqTBNjmA4RrTR4SWKWqlwxBd8bBudRyoCyzCnjdGK3T8fD1lpLzhmjLQ6L7QtpLoQxs70Jcq1La48C6ww5lcZUMngvTnhY92ggzROdG3DOsJsD8yzV4c5balUtCVEtgKjoznBxscb71jbkPVNImFKoMZNjbPRy1Vh3Cmv9cS+rKpUk1xlh0xktraWpHNu5cqmAplbNq5cj6MochKm0tLthFBebDih0g7RT7/YTWimmMRFCukOhl39XJQKWftURpsxuNzMeIr4zXF5ojBLQUhuNdRJwOqsFDHaGoffEaUZ7wzhG+lrZnJ3Ra0OIB7ku3Sq0RYIkaw2+k/dprAZ6XGcBRYmFm+1BgBWt6NYO5xUxVuKUGsNA45zFe2mpXFqTci7t0MmootBVk1KlZAS8V4acZQ/kXFid92glgb+zHuciGknonHO4zpO2Wdo6G8BuTD4GzQtTo+s9MYnPn1JlmmdpL7SK9cZDFQBQGGyaUhNTzsRQ0EYS+a7zuFFak5cqf2ltNV3fSQsPkuzlEBlTIcyREAulFkISgM+6CCqhi7BkTHt32uiGmajGuKvSnUGkVAnUjDbHM6lW2SfWa2pWbLqei2GNtp6pVMYkSfL50JNSIYSMd479KG3nve8wygLC6DCqUKjHap1CQMvDdGC92kjhxUhgnBa6eSss5SLnXS6Z8XAgxcTXv/51/uu/9Jd4/PgxMUZ+/dd/ndVqxeMnTwSgvrlmNQxH0OJ4VrczcLUaeHD/ATfbA7vDeKyylJKx7h6/+LP/Ja+ef4jV4PsVVMX+sGN/mMhvVPgaq0fwH2IpeOPAeLTpKVqRVCVT0Moe2VilakKp9J3GMwPSIo3aYzuFtpK0UTMlJZIUteWsSY6qApmKkK4UvTEM/fo2wYi5Jc1vwmxKV4yW99CiguNadmt5l/v9RMoZjOPexQVoK2tSKXIV5rlzjtXQYVo73f3Lc1KBwxTJFFAS0u22O37w4Ues1xve+9KXMVpzs71hv9tzdb1lnmdyKTx8+JBxlELEMAxobQhzpKjcWA9LAtYADKPoeo+xiZhcYxIZ9uNEpHAYZ8YposN0BJVA/ICtrUW10gBpkW8oVdhKKSXKKD5AKcU8z62KblrbVWNmp0RI4fj8YhAfa40lJpFr6J1lmiThV0pa+q1t60DdPv/FcpX4YmkJ1FY3SQtH3zdQp3UcLHs7pswnz161e2zvPCVqe/cPLtesVwNGa2rOhCjtyaqdhcf2wGbiAuQaUFW6AxqIjrpN37KqUlTI5Vg4rLFQnT62fb66ukZpzfd+8Anb7ZZa4Z23HuGHDRRForCfDphuQLsB12uccZDSmyBYS1RRt0no7aKW75F3WY7vuzSGSopNHqTo4/crlkJGFWZlbSxCt7TtNzMSK0ghwrfPlQKyMgpj7iSzSkARrTUXZyueXV3fPlMF61XH+WZh/iZCjAKETTPjYWS722O1xg/CGK45cb5aY1unxhKoHZmdWsDbogqlChAml6GkfR5JqFORv6sVUlFHtktIhUOUeCsm8WlLIeRwmHj7rSfkqji/vI/WhXEc6Z0wKK2R9uJai+QNy7mBFJsMkKPEceM0E0Ll1fWBB2+/x6vxJS9eXElraSv0C2VJY5QVpl1Z2GCl5VIc2V2KxvpRSweD+IPbV9auJUEpsm610kjKq1jQ2mWN3CUBvAEINzDiCKMs+/Vu8V4vxfP27Ja/E3RSgDTEb9tspSUdxdnQk2OSBKcBN58rh7R1vaznTEHz5jXmIsBXLuUIMDkn/u0WFxASxfKMJSmVvzeNcUm7/lIK0zxzc3ON1gIymrb+5DP1G+A4DSyX59QKg84IoND+Tp7xZ3dt28tqARbl7kspzHPgMI3s9jv2+z03N685P+8bO1bLa6ygEMY/VVqgawPFdLuXo3ttz2Up9N214xtu35xzZap3WHUNHD4UjdeF3laMUg1sl3+3ShjGpVZi1qTSIn2jUaqgCHd/IcSZzmoShrIUxkulpkQaR+ZpEoC5KvaHiafPX2EMXF70/Pyf+Ulynnj+4hW1FQCWc3HJ+2otlDyhtJNn1KzkTMoRa6RL4Pz8jK/799nvD9xsd8whUEvmcNjTe829yzPONhs26zO+/d3v8dZbj7l//xzfeR7fv+Qr77+LUvIMlmdfreYwBlCKmAvX24nLizM264H7l+esB4u3tnV26eO6Mlpy4RILOUciUhzRtUrXHLTiPKy8p1LIGLRRkiuWItIVsoigSLwpbci3a885y7ld374LFKZEyMvuurNCq8JZx8X9C+Yw8/rqmldXr3nxes9q6HBe9tmypApKPqEKm1NnIRQJgPvZzf3F9kNrjfzlX/5l/sbf+Bv83M/9HL/wC7/AP/pH/4gPPviAv/k3/+Z/8GfEFLFxOlZoc46ihRIFXTdGWnuWQ2zVD3Rdd1vh1JpNq/pMYRbaeJaDMsfQAkGNsQ3MqhKw55zJKTOFwDzPpBhb9aI2dNhgcyd08pZQ6xZIpZKPlRi4rT6CIqTMbkqkXLnajjy7umE/T1QlvzfkxDTPrDrH0HtCVUxK061WYBI1R6wVfa6uNxgn1VXvNDEUaRnaV8aJpmuWqDW+4aSUauAJ7TgsNFYCt1t7AQmiBJnduSXXuJRB5MCnBRW1UnJmGidSrlhfRfskF5zVaGtQVhNCPCK61EqKEds0nUqRQ9d3jt12j9YSKHe+47AbiUGCdqst3kNth+HC6PN9h+u8BCQpMY+NUqmhlMTQeQbfYdCs+p5UM9bZ1n4h7zqFTJoKNVd2ryfR4YEj2cgYQ2otM9LOpLn36Jyu9+x3B0KU4HB3CKAg5SwHeVuHDx5seP78NZuNR6nCPKfjGl7aNVIu5H0ACmGK9IOh7w3X1xNKa7w3BJsEwaxyIKqGvCsNziNghrfElLDeEOdwZJn5zpOTrHvfSauPbnT0GAIxzsKmMxbnNClmDjcjfT9gjejx9J1jvJmZxijthkkorKkFfNZrqqpYp1ivHYftjvuP7tN1lppFT8o4AUxjLE2PA7rOslp5xjFIdTUk7t0b6AaPVVKxjTGRYpLKbyqkIJ+Riyxg4wy9daRYkZO2CGtEw2rtcd6w3lh2N4E4FXwnFZRcYH8QrRmlIEdJFtJetAU677m41+OtJDEJxfZ6T45V2FlR9pvSEqxUpF1snhPWCsiVkiQ2KNPOk4T3hvW6I0RZg9aZFlQoVIGUKiFNmM5L4lBh6Je2GqlqF+TgM6aB7FY1SrRu4IOsr5wL8yGRs1RUjZGALcZMLi2RNfoI1C+tSaUlY2VhWFTVNASSVMUjKBrQVIRVZo2AxuInDN4b0gTaSRvcwhJbAinTDu6cBMBawFBhFiamQ0BLHRJjDc7fardorTBOoa1o8NSQBYyMoDBYAzlkQNqQlRbwuRt6WVvWSHtB0woSFkEATAO0W3u7LzhtKMXQD538XAs6cpGAYakSGy1tnr027PaH1uasUVGSJWM1OUjb5Oa8E7Cx6UZW74TRW+WOyZkwTqhS0QaUtwJghRlyJSSpjqZShL1TCgWNtlYYo411GNOeoXvAOL1maXkQfZqOi8sLXr664oMPvs+7773Hj//4j3Nzc8O//Jf/kmfPnvHnfvHP85/+J/8pz54949mzZ3z1y+8x54IKAkKP80yMkuSVAvcu7rHd7Tlbb7g423DYXXN+cU6aJx49eIt3336XcdziveP66qWAylqRqzquTxA2gSoVrSWQFmD6wHp9D42iVGGjllJQ0lct70oJWAsNjFGgVKImOWtjTozjyEEZSso4a0UXtApAWhtoqrSRBKud+QCUSslL28it6RZRLqzAJakqtbXANHA3xoJynnuXl8wpEmJEa8MwrFiv1gxdL3pNxmCdb/INDu0sikrOAmSHOTAeRt56+x1+9E/9KA8fPkIBMSWmcWS32zHNM/cuL0lJ7vfi0UOGVU9fK/vxcJtk5kxB2tPNOFPKQRhFOVLwlFlYbSVmNpsV1iAFiCptUgDWeax15JgxVR9ZNpRCTRK3jeNe9i0Dfd+xnQU4kkJURdWMqQWVE6SAUhbnPM4YYpiZ5wltHBoI44gqCZWFIdpZg3eOUipji9ecs43dVgnzgSkHSq0MtmO97pnngDWKzbpDa9ENc0403nKFl1c7nALX+6bTk6gUDnthmWot0g+URExSlMlFrttahzGaEG6TNaUM1ieUkjN3wSmWOBHqsZIPhlQVJQkLp2jLuJu42d8wz4HXNzfEnLm6uuLVq1e8/fZbWKepNCAxRArgu46KZn12JgBJKaQsa85qYcVrAqooYcjr0uJpjary9zlnYRrXSs0B0tSScWHDYYQdpNs/1FYMVJpcFCkvBUVhEeRcoBV8hJHo0NoLEGlabKkEbcwNaQohstvv0KbSdZqYJTE3xuKskZgQAQZylneVUiTnwDxeo3uPqZ6Ye8BTlSIkATe91bhWyK1FicRBFS3dBQTxxrZ405CVwTiLqqUl6oU4jqQohYsYszCodcVa0O1+ks641YBzjv1+YhwntHaUArpkjBXGzDxLp8ACAIJ0K3S6ksPEqtek6AhB8emzl7y/HfnmT32V3/vgIHFYi4ulzb5hrRhuo/4F9BTdHYmT7HExHvEgdYcN0r7fGL3kw2+QDj5rFWGGlgpmSchZXGg9tlAv7FGJF1qRvir0HaYT6u4+kT9FO1KK9ENraavAJ09fEYJITfDFl/aGCdhVBQy6c30LCLYA57VybOe7TacULK2baql+i/bVAuLlKnqSthU9pmnkcqNRWboDcmldEarlSlpJK6FasKZKbqBWbOAqVGHkVzjyz1tlV+5B9qWAcbI3SpFnPM8zr1+/5tnz5zx8cIGzci45J50DtMICeXng3Oa+ty/3yOTSanmvbwJyn9NcrLUx8j/z/AXmEeAfJeDl8kuOn6qEfLDcbVV3oJXlqxWVI9l4qqpHwK2WTI4zaR5FoiBLQpdDJoTEp5++4Lvf/4Svvvc+m5Xn6vUN25sd1oq0xGo10K96lHGEAoP2Le9+c3Et71IhccvZasBbTecNc5Mh0DmSZ9BGziRnDb/w87+ANoX7Dx7w9pPHWK1IMTLPwi6OKUp+moWck1vh7P7FJetVzxwjq87QEdAlQlHUPEsk1K8gdxBby2V7oLnFHaW1B/d91xjBwtDW1oo8RQkCZGUDC0BOA29LxdTAH2ZKFTAt5Wf5U3IAOe406/UZ9x49ZD9Fxqst4z4TQ6Xv9VF/t7Z1glLokjDZgGvYivoPg7h+aEDYX/trf42XL1/y9//+3+eTTz7hJ37iJ/in//Sf8v777/8Hf0YIUfpaW8BQKU0DITZ2Um3aBgCVvutxjd5vtbQX5RiJJRBiYA6zHDJhasCVRaUMLeGKKUslNYtoYEq5JWZLECqJu3hlOWFKlUTcaIOuihDv0MeLIibF9RQIKRFiYYyJEDM3u5GX1zsOcaZoeH044Lwk5psMXVJEZZhixjmHNaLto01FGUmKnDJk30Q9tSR6+71CG98qiRzBq8UU4u+MvtNaV25viePTFNF9lQo1S9vEAugtB4QUXYRFYp2nHzzaSFU110yuBZULm82GEAJd76jtFI0xoFSVQQEKUsys1h3TNjSWjMV5x3iIpCjaS7lIK5E+Vj1o7Aap1ukWeFalhT1i5F3kubBaOS4vV+Sc2e/2xHHEKKHDpykQDokU5J0tLLoKkvjoRoVdnLMWhoXvO84vziilMk0BSj3qCKnWtqvgWEnqOydtBodAzlL5dNZiO3mutQmIlyyB1LDaSCLYHP3Zecc8JUKsRxZiafR9jQBuF/cGYYNNM7XO+M6ScsEPDt+JzlV3TPpomhxNkDMUqIF+GHDWk+PYWoSXNiQDJZJSZb8PxCCqWylljFGYzkK1hCmidMV3Ftsb5pQYVh5tRXS9RKmU5lb9sUbjnaHrLMOqo7aBBqtVq1DUwvOnr7h375Jh1TPOUdqz0MxJDkljNUZbShSxdescYS6EEAWUO5Pk8rCnMUCUaJUZDamy3+VWQdRoKloVxjFSKWycwXaGs7Wn5ML1XlgJ45goeXk7Ar5JlVmTMszTLG2FubZ26ULJEvxpVTFO0/WezZmATbUI0KOUZrudmOdEv7Ei1NlJ62apSJVZCXNDobHO0HXuqPtCY1/lUrBWCwMOxf5mpsaKMbDfS6sZjSmhreyfpUq+VDtDCJQktOSqBKALQQ7RnMqbTFmtUJ2RP5vel6oF6yzzPmG6ZY03sXGtIJUj8BByxWGwTnxMTJnxMJFzkhZu4XxjvSSazpmmz9BYIEnadmtu4rY1y/ATI6BQzglNxTgjrMn281ZrcjagZcBJX6UdNMZyrDiVKoMtfPtZvTCESiHG2PyZAHhNnhdlKl0vv9skWaPiazUKzbp3vHV5weV6oLPy3GqVil/MBWJCFQEqtZK2L20M8zyRo7BgYymtHV7AV+n7EBH+Jfm0zgv7CGETGGca0GLpfM+XviRMxu9+5zuM48T9Bw949eoVv/mbv0kphXfffY8QI//z//w/c3V9zTv5bX7ve9/HGNH6Ck1zTpi9Ca0169WK880a7w27m4Gvvf8V/t1v/zalFn70x36SnCNziLx49ozNxWPm+cDNzQ273U6YO1mq+kYltFH03rPfT/i2BmpjMEBhGXTSev5b8q4pb7CdIJeJOE28utnx4uU1JSsMmsuzgbOzDuvUMfC3raquaiGmILpOxzbQN0WOhfKvG0gmWlWtP+F4sBoj+1RHK+28vUErw6q3DH2P9x2d71j1XRv0o7He4TqLbYm+NkYACqDvOzabDVevXvHbv/VbPHz0mPOzM9abNX0/8Ojx46OW1+/93u9xOBzIuXC9vUaB6EOGxH4UJt52t5W1eu+CKUiVO6ZErQdCFFaSLR63GvjKV77CfrtjtTnj+vUrARGzsHmmcWwt6OW2TaNm0alp7EpqJ4LZyFl3FKNPkRQmwjyS0oRzPc6sMFozhpkYM8pIgme0nJ2pJdud96z6vrWXpwbuSaV6YYyllrSGHDkcDlKcU6Cp9H2HMxajaMXQSkkZDfRdh3GG/e5ATAma5teq74XpmuPxPgoFa+pxENNdlqMxrTjTIrE3WTItiVJLNVyAoBCiMH6V5ur6ho+efsphnAlxlhbSENhPCd91jcUrumLTPLd4aEbpPTQW012gVoonRsArpCBljaIUYRpLXLAAK0UGfFhDSBLZSFvgrb6P3E6WIh1WmMKoFlNBrYpSRQuQEFmvVlhrRBvPuMZEuptzt1Y7hFV7frYBpTg7X7cBAJ7tbse671EUxnHiZrtlvz8wTzNxlgEYJUtsZopCFYkDckqM00SKga6zTRbjdr9WCf0krtGauRZh/yBMCmOkgEIr+Mg/wiaOIVJyi/7qoqYDFAHuclUcxlmenxHttqrsglhJMaO2Yt5tvi/rvoFK1nimSbHdB/Zj5nq352Y/M1VHUblpzxYBaD6TAxzX46J9Bo0Jpj7/TZ/xcwKGQa0GpQzqD0lEGyfoyA5bPn+5lAUQW55NzvVOoX5hld0B5miDJBTEHBmsdH8kUym5kpXm9WFE5VYdrnee3x90T0j8XIoAznBbYOfOf5dSj+xhAWPqXULMnUXbwOymp6y1phQB0HPJqFpFcqOqdma11kUr8fUbjDOlMNW2hmop1Ol27tVFf/p4kXcebGtDVkY3yY2IYhH+zxwOB26ur9nd3PCNL78le9AY0RxWd9+1eWP9HT+9JV5ynXdbu//oZ31c080tGlW4baf9PHhW7/zMbfulXNvtdxcUBWxHxnzmM2hAm7xPrXSLlcQP7g8T3/nuh/zYj7zip3/ix1gSS+8snZdihkb2noB2Bn1Xj/Qz1yuPRM69zjkpvpZCZGKcDoyHSbqQKjx4+Ii3336LlBP9MOCdYZ6FxTruD8TYfH/lCLwtbe8hBg77Pez2UAsaKQa2LSrAKolaE5T2VBqwbajENojCOcNm0x+fcc7LkIHWycDCMGv/6EYbpKCPZ9kf9tJVA3UFyExVZE2kzb1Stebs8pKzm4l5Ej+qdIUam+xNiw20oSqDLk2KqrVFav1HXgHwQxbL/6Vf+iV+6Zd+6f/rn48xtkNVHWmmpk1b0UoSN6UVJSWMNiLqmKVlylmD05r9/nCcDlYa9X6pOKUCaQrEJCLrKQmbwCzT53JtII+R918KygiiK5RuQwJiS7AqipRl4YaYOIyBq93Is5db+R1JWF+Vyhwj23EilkzVld080ys4X6+4mSI2wWEK1CoLVxlN9QpjazvchFlgm45FCsKCKlWjtKXkQMmfF4GFBiAtaVKjIN5dTrolGnMusmnmgu3EGVRaBbkUudeiWPmerutZbVaUkkFnvDZHpt1q1dN3mpKifIYSth+6oq3GOI1uE+FShjiNUIWVst/NpFioRXSG0KqJvqsWEAN3xBG1sbjBYucRpYpcQ6jkkuh7R0waqmcaZ1QuqKqIh8i4jQ3wdE0Tokr7CBxZBVXVYxU9xMJuO+FdhzEO7yFl8M4xldCSWlh0SbY3e6xp2lgxEVLEOsNq6BhWnTi9XHHGEObQ7l9xOOxRWh/bBeWCxKHX1kJRK3JmKaS1ZtWTU2E8SAI3jQHrXRNIlyEC034n+8kY5piwVrFar5jGvfS+W0nqfdPKK7Xy8vlMyZVpjIQ5EabGejPCRBtWHmMUo1HUkjBO3E9Imf0U7rS6Vq5vDkyjMEq63rFad6xWnbSaFlmb1hl2hz1KwX6cWW8Sg5LJhNOUju0uvXM4745Ty5rWtjyokukHj/NC905RKkE5V2JoSYEWlpO2wnqrqjb+kWYYPMPKY50w2Vbrjt2Yj4MbpFIojBHXAKlakemEIWPQ0hLYBloslRHTWUoC3YSbk9bEmKSanio3hwlrFd71pCqTzrTWjAfZD8YY+t5Je4/WDRTNR6F4rY2AHlrTe0PKlVqUMB99Ew1tSb9Sd6fuIUWG9uc8zg3MFf2fFCXZk5aJ+oZ/uZO/iOahqiTkWZlOWldTTMfEYfHpJdcWtMvzKAXmEIkhcThMVATYlCQCjLX0DTDwzmIMxDkwRUlgU5RnX6voDujG9KEuOibS0mi0EhZcG7ahbcErabuOc0KRmjZkJWVJEhegUtit4sdilEKL1gJ2lFoga5LNdJ2Tve6blkoR8Jmqeffhfd69f49764FSK1OM1JwoKQkgW/Ib0kDOGGkdyglDwWtDrCBbqul0HAu5tdVqDMZ1KNNJlTEEuk5aJhfNus16w6OHD5inie999zt8/MlH5DY5aA6R3/jX/4YYI9/+znfIBb778TM+fPqSiqLzwpaJMR0H0YAWEMxpQoSKxfmebthQquLy4oL1Zs04zlxePCTlTM6Jm+vXXN9cU0oihZHtdosukWHooGbmkNh0hpevXgsjriWa1CRTYLIwh3Nbu7dtfyABe2Q/Rz56+oKPPr3COs166KkmEI3HO403js4Iq9wa3YJ02ZchNLCj6b4sgeXC4qncYVAoQJnGmmlhoNYYZ4mNgW2NYxg6NqtBgNqUmecg4IzWtyyX7Ekx4nuZLKq14v7lOd/42lf59OlTPvrBD/j4ww8x1uK8p+97+r5n6HuG1YoPP/yQFAOH8cB3P/gQaxy1iqZRTML22Y8j9y7PyRceVTzzLAyXWmVy5zQFStjzzuUFFw/e5tFbHWfnZ9xc3+C9JcXINB447HeEWcDraTwIK2rcyd4wpk3auiOefMd/xBCoJTGGkVKTJJJGfNo0zYRUUaowrHqc73BemKla63bvFhJHcFprRc5ezs72uxa9qZfpdTtHVWuZVgydpyJAdBYHKH7KaFargTgLeOvbuXZ5vqL3UngtpU1rq6VN1nSfS5Y+q8v1+bhMHYcWVQR4mSYpzOZSuNruePl6K9X8kgV8K5mIkSEt4pIISXTbFgb1aqUkuTm220m7vLVeWoVVRJEbA1YjQa748dt9tCSDlqx880tKYtFaqWgKYFAtUXSITqH8ziV2OSaLZdkD9ghW3nk8yxNpsbhi1fe88/gx9y5n0cSzBmUsL69eQ45QEs+efcp2vxX22HYn+ruq3UpOkArkKAMsiKS45/r1tfymRfNQKZRt0z2dp2tFaGc1IUzUWvCNaahRwpAuCztUioKLvMgC/NVKE31vLWJzJG2QwRHNRxflWCaI1wXUuLNE8sLI1oac5bwWzXvDdj/zu7/1u7x8dUMoFmqhlEhtAIygN8uHypRsVANf1SJJIb7qrmadEDrbuioLoNAAqztArvip2zbGZbDAXVti6IXJs9xeRX6HJOrlCEDSvv759KUxr6sAkhUFRVhTdek0Xj74DrWtlTA+t+e00mA4TmcstTaGVluP9baNs5Z61PgDWvueeeO+F4DbNpax1ZpQ5HNCCIQQMeYM24aMif5gbgx3c0zs5XfKDRlA6XQslL3JRT5+8xsm7ZWtgyHV4/svRUgfh8Oel69ecf9CBpQ42wD4hZF1lD6Qe1rub3nni4zFMSf5zLs+XsedaxUQrzkphEXqVX4D0vrcZ3ELoty5uzv/tK/kCE0WRRzXQlyox4Gh0n0gOpuCH0g+9smnL/n40xf82Z9QvPelt5nGiXXfU0pmmiWXM1qewThHnBWdb77Ah6OWGpg6tlgbrZlz4XAY2e0OGGO4uLxAa80cZtarDaUUzi+kmGislXbLBrwLa2s4tqCWUhinkRgj9y8lzu6tMKoXLWqtddOFvAMMtufunKEUBwqGoZP4anlv4fac0tY10bvP3+fyTtQf+O7UnUKgbmeaDCeaY2x5kKypru9Bac4uL5gniQGMSsIOrtICrJRCGYtVhYXFrpQ6AsJ/lP1QgbD/n03JQSmJy8J8aovLGBRCkU3IlC6jNTEkJiasNaTsmjgbKDTOCN0xtMkrMUrlbJ5mQmvzMEaCBKAllYmUS6v019u+depRuPWWKVaZYybEzOvtyKcvbvjo+TVPX20B0QiIFJxXVAOxiN5ZVTKJyVmp2o9zoBwmYhYBZGWVTLhqQb3QdSUZdlZRcmQcA4dDuKVsKqlsfpEde/ePYJj816KbJIek/KO00HCXkdIAJd0OI0A1hFyBc6CNtPZoXekGiGNB1cTQKeZaUVqYFjVm0NA7ASly1Fxf7RlH2fzXV3MbVjA1DaDGsCriyHIDzsoibKsqOcTWZpgZ+tsE3288SmdySaz6jlVvyZuBEDL7fZDPK6Lxs1qveP78NZVKqqLvtlCdly0nenCV16+lPW5YdSKcrcTpSQ4qDBJrNfOUePVyy8VlL+/Mi9YJ0Kr+IlIYU8IZRdfLKHNtFCEGnO2xzrDfB9HgqlXo9vWOr0ECkjgXzJlmteqpRdN3HSFLrni93bHedDjvMZORqn8U6q3Wjn41kNPcKKmpiSoKkyXFyvV1pPOW+SAio7rdn+tFk2ppr/OdI2eFMobr7SisvTGgrCQH6RDYbmfCnOj7jq7zrNcdF2cduzFgjMdbmQL6+mbH+Xpgc34OWrOfAlPIXN0c6HpDN1g6b/FdR66ZlBWqtbVpbeg7QzfIpJLcQOqUK/MYpVJNE5u3SyJLa1UG4z3WS7uhtRJRGyf3qo3C+waEeWn/c1Yz9MJE2+/a0A3NUSvPWNEDk8qLaGwt1Rvbpp3FmJhnOQSH1aoFVdJa6RzMU0Rp6HvDauVwTjMHYbKW1iIa5sRqtSKEjHVtAEOrwM9MWFdxzjAeIiUJoL5Q0kttOgBCNSTO4lNyKneqg/UNps1StdULPRMJEhX1qOXhBwtl0ZYRNtnS0rnoS6lF8yzLWp7nyDwHmeqlZdqgLjJoYjV0zWdKkpaCEubosTVF/FMphTkHnFnaZySoJ9c2nU21Vg/5fm1uk1EAHSs5RUoCZS3WtcTBaAHwym2AuNy/uMYloJR20Y5b/Zd173kwnPHNJ4+4v9ngrEzBVVGYziUnXAMNFsbB0ak3kJEWnKUvdvE0xZcGELRApxTCHNAX0tY+TTOvrq7YbfeEEDjbnAkb1Dtp1Vuf8a3f/31+/V//G2Fonp2hu56Pn96gapYWFm2ObCCjbdvPHX2/xSoRslZUTH9OaZOWnbUMvsO7jrPNGUtbQXz8mDlMhBhIYebl1RU1Jy7P19y8fo3WmldPf4DznhQPUIVZVzNHEGyxRSx/iZNKqcwxMcbE7jCzO8xcXHq0j2QzM+dMUVZiDm0xpU1bKwL2lyoaUCU34XWtjtT9RZsUrdDtWNTa0GiMErgViRGMBh0TMYOzVkSrrRUAt94Cbcd70fF4D9b10h6LtFW88/bbnJ2dMTdh8BiD6MDstlw9/5R5nqhVkvPN0BOnwKcv9gxdR0yJm/2Id/ZY/DvbbMip4mwTq9YKrTp0sdzMI0+fv+L9H/lT9MOad955D601l/cfHkHBGIShRC2EENjeXDONe148+wTXnzFsRJvVO4uuognYdf7Oe6uEOBHz1D4zAxM5N5ZkLMLQacG9McKuEzaDpLpLm4ys9wZatv+VLAxWqjAj68KG1TBEaVE3RlFVK7C2QD2nTIpJWibbXrRG03eOVS/V9JQECFONqfZGAnLclHemjXG8TPkrdavTptq1x5iIIZJrYU6RcZZibc3CAa8UEgLOlwZ8l9p+ron/l1rp+oGle0F09ETbyTZpBFUFJJax9M33qUWsurUuNT8XUyLXLwYyqVpaarSnoClNb1cSFrknXRUag0a3YTHuWGj+g4glIv8hRY+h93JON8XyVe+4vnpFDDNPP/kE13XUqgjzDFXkOTpnoLYiSZbiqLB3Hdbaoy7wUgAiF1Su2MbmFnZId+wUSDkf287uXmNdmG+3RAY4rsjlfJXpkrXIIBNQGA1VSwFbwKfC0k0gny2fswBWVAuEtl4q++2O7xwSN5M8G2qm5kiprRC+II9kwAFy/Wp5jqgGgn2m3asBP+ZO0UuK7W2f1Sp6zXeuTzKTBb64FTwvVMwCnh2ZPrRnIgD3EbhozFsUbxboqLd60MfWPHGzRXAfsTus9luBt6b11uItKAvW+6a1xyV7oAFbtOEWrc6kG1jo26ARhQx4kmuTvWOtOQ7fWn5JLZkQZsDQ9QOlFMI0HvUQF6Dxljm3gD23kMMy5VpYurfXfNduAZOlUN6YOw2wK6UwHQ68fPmK/f7AMAytfX95VG8kFQjzPSMswOUh6+Mvv/Otb5iqi+e9e07S2GACnbs/qn21vgl4tQvkSH1avrRI9y+aiyzg3xEVZXmB1pjWWivfknLlBx9+wg8+fsr7bz/k+tVLhq5jnmYOh1HIKCVjtGOcI7nPR7D0D7OFdau0JsTIYRxbAbuTAWjjnt3uhvVqw9CvyBS6Jug/HQ7sdqL1WdEMw+3nLtrp5+fn+MYW96pASa3QZN98h8Bx6qeuWNMdZVgkjl7YZlJwpxWojwv+i17LET24E5veVgflPegW/9xZu7Ek0h3wavFPIt0j/viw36GVOeb8pRSSMhRjMaaQozC+tVqKhX+0/bEGwrzz9MPAMuFHKq/6mIRVqnA5yyLaWJr4upagLKWWQImujrWN7jiHJmSZCLNoT+Scca5DqfbCYmk0xCJ9xVVYL6pNDykxohDNnWkO4tRSZTsmdmPg5esDP3j6mk+eX3OzF1q/Nhpco/4pSfa0hdWqw3SW1dAzzjPWal7vDvTdwFJUtH2lhhbM1SZUbQ3VSKUjpcw4ziK6uwSFehGO5Y5jvA1ejv+u9LESUypEKYceGUxyzY1Nwa2GirH6qPOlVEHbQtd15KIpNWJdJoXCNO1w3cDmYmA3beUwqNI6p40cUPMUuXqxY7c9sN6sONxMgML1FmptQEs7nCqEKRFmQcCNNQ0ZFu2WvpObXpL0XGb6TqrgXScJbNdZrMtMIdF1DqM7SjEY61CmQgQyFFWO7KvjvbcTNYbEjpE5JnwnI8j3u+noPEQbSAKKOaSWoEt7ge891ugmsN305WJkOhzoBw8d9NahdYdWmu0uIZPEJOGLDVVfYjHVhANFFFM0rlbrDtcZDD1prrx+sUUpuLhYs15v2O32jNN0m8zGRD84fO8gy/1RZUx8jIX7D8+4er4XIFNwTNHdOhPHPh0WMBZ850gF/CDjuDuEVWR8j65gzCgC/8ocdQZqlcl8fWeIIXDYjez2mfsXns47soJxP7EbA6lU1p3BdU1XwUDN6iheKlvMsFr3bY1VQqiiDxYqpeiWzAqoZa1o71irKFU3wX/RVJumcqyMTnNoCZwT1lmV9+zaP9MhMx4yh11ktRE9p36w3NzIQR2mzH47k7IkmqXKPu46S06G/a4Q50Qlt2RaQRE9uJISxmhWg4w0Hla2sTNlyqrSiA5cboG3khaQmAvW+dZiqdG6UKvGWkSUuAUod8/1u/5C2EET1mn6wRNTm4zWWbJRrcVVnqEASeLbpAAh/nk58HJrH6u57aMleC4V0EdGV6X9WSqqBbZKKYZBGC/L6HOtK7SJMkYLYCitWaJ3Rl3EoDMl5QZqQ46FHDOhSMUqt6RZznElbZMtIXFNO6yUpsGmWltQS/KWiZNLgisuVVhC1jTfmkF7aVV4+/ycn//qVzhbrSQcbMGv0ZplGvGicymM51Zo0ZrOOZKq1Jbo/sG1VGFwOOswWpObposkw7L2r16+5nd/91vs9+PxZ9brtRQenOfBw8eMc+Tlbi8aUL7n9c2OsouIWLLo65WsiFEJC3Wa6fuMPWiskhb+eTxQlOHehWG1XtF3nTAwjULbhe6fMLow9I710FHqhnv37rX2Xsvjt97j1fNP+ef/4te42Jxh3AZqQqVMVVrSGgVK1Sab0MLh2gDAlNnPgSkmqlK4zhByZEoFEwpFeVaqx1lLKBHVfACVxsa8e2ZyLEIcdSyWfOtOS6Qsb/mL3FrnTC2QA2HO9J2j9x5vLdrrlvhJMcEYQ1WtHeMItEqAOx4OfPz0BftpxjrLajXw8MF9+s6jlVSZw7RnHEfGcWJ/GHnx6prXVyOvXh/wdmI3Smud0bVppGlutlvW63U7S4vsMaCGyhyaXmLfc//+gztskNYUrhS+6xmG9TH5u7z3gP3umssHj6XgOAd2N1fS/ri7EnZ0KcLWqaJdMoZZgEalKCVKEqoV2hrcUcy7FeSQieO1ltaxUe6wXFrr8sLgq5Uc8xGYYfE5GZwVfZQxJGGJeil65OajpmlmnGbQWgYppMB6WB8nWc5Bpu6pavC2lymNViYiSqsJCMguwMeSGN7u3s/uYmH3pphkprWRROrYrnXMPTSpVlaDZ+i9TAeNqbWYKSkEGk+/OkNpLzovpkASBsoixI62AibfSWwUHKc8imByG7RT7gp11+PCV0ddL0NpU6HvFghU2yO6cYK00nTO0/VeikBa3ZkK93lbwJbl/62zrNcDJUfCuJOhVtNECKGBhNLC54zifLOSNld7bCRrGkAD9mGbjtz26HJfseny3AW8F1sYelZLgU03MWqqgDjymr44gxznwGq9IqfI5cU5xqhj3qnbBG3xA60NkMakaeBGVrfFJhAwfZomDsqzjA2iCBBWc+RWF2xp55YnsEyZXVg69Y2FddckPrBONyZY8613GDdflC0r1eQ67lyrsIE+z8uqINNFj227t2vwsx99ZJxx648zrWPjDVC2sugX3zKZBJC11ko7b2ORCfglqwa1AIBL2+ayl27vpbbK3+A9rrGQSq2N2ZxJpeCMprMWpw2hPeNFbL5m8QCyB2GZRk250xrdqG0VWqHwlv3a9z2HcT7e5wJWuaaR6JtGcGp+wBrd/NAiyF9JMVBrZjzs6bxvk9O/wFphT4DifGS5lgaE3WW9lnbuHt/13T8/E18ev/bFv/W4Lm7/PMLC7XPugmCVYnvurjTaOzMWfNfjXGhTFtv11Fvmowa+98FH/P53f8Bhu+Vw84p133KOLAxfAexFRzHlhKv2i5H7BQxqJsNXmixFqVyerzk/3zTSQmB7fc3lxf0jyCvyAQ00z6WxWjU59bimh55jwBkt+MAC1NYEVfQt77I6gUbIcA0HSQ0r8aDEfyyYYU4Le7dNrK2L/MQfZA3wggZ6GY6izAs1syXhOWemKLrCS9fKMjl6tx8FAxhnHj2+L0UMUWOQa1WaZQp6afejaDG2+cNW0K39sQbC+s7Td0MDdBb9GwhRNFIWdpZpvdjhsD8uwTkkNs1BWGsAaZOw1uJKxbZAQLeq1EInrJVGb751tAvra/nwBRCiysSVECMhRPZT4gfP9zx/feDqZuTq5sD1biLlIhov9yylFqYxENo41EE7bAOilNLtYAtcnJ8xh0hehAGrCFzXpmFVcj2OsU3SbSaOuGSqlhG42mkGL5UemQwmguDHCkWVYEcOljtupP2rWxgsukjFaKlWyK0LyGg1vrcoWxkPI9dXW+49vAfKsH09U1ImTjO+F3TXe0voB3GqCxukBZxyDZrDLjW9I80wiPC+UIKbkGVrzazqVpMJkMTKGKylTUhMrAcvLJcaqcUctdPCLBNzvNXsleiuWSvJQExJDleqOD3jju8dZHO2jkwJPEthCqEFRuL8a6loRJ8sV3BrxzhlKonN2cCw6o86d0fHpYTlpk1B68h6tSYmQ5wyYUq8fnVg3AdCyKiq6AZP1fL8Om9xXsSL50naQmSqHXSuJ5CwgybEwM12T60i7JpyRumMMZbVsCZFqYCXmJmngDKelTZMc2IOM9dXI7ubmWmKAjCNon9nW1uiaLUpbGslOj9f0TlLzcJgLFnaOjTCFFlYUVpDqjJRbEqJFDJg2GxWVAwVA7owxSjPs7e4TjR0Sq2EGoSR5pUMSmizRjarNSFF5mnisE2EMWIU2MGh2tQ/5zWdF0abc4owJ+Yxsumh4IHCPBV6OxKiIiUlwxaMYTwkwlRIJnNIqfmN5kdyoe8suWSc0bx+faCUidUgumu+l+mv/eBQHXivqCtHmAPW+jbRT4QsnbNcX+/RSsTajwyIBniuz1eoNrVws9kQQ6HzkWm/I8YZ35/TdR37/YGu77FNw4K8aHWURou/Tc+WliGtoZSI8xtAsT7rBYyeDSkVUhSW16Ij00JOaQtBzrGaqgQfWoLInDNhbtM2cxamjVbUXJuPEtBXszAS1LGqtUwsFNZYIoXIPAXmKRLnJGw+69hszulX9XYwijOt9cE00EY0FI6AkkJa6n0b1rHq8X2Vfd4m/9TcgDx7m+QtFdjbgk3TS9ONiVIVMUYGb8kKvnz/Hl3Tg4wpk1sLyMLSQN1Rw1AK7dt9t2l7UgRaziGONH1JEpZ3pvHeiai/aqyDNsF4CUqvrq54/fqaJ2+9jTaWjz78kO3+mQhxh+/y5K23yaWyXp+Bvp0eWj9XpW16KS0omcMyfaWgi6yr733wPc7+9FdZDZ2IAS/BNbVprMXbhEXX1u5mWLme7WHCasV3vvcBqTiu94V7j95G1ch08wmqGjAObxVeZWIIhJwIpY3hniNjEr2Nm8PIOAWs16Qa2I+RTGxi59IGO3hFsppOGbzWhJjxzjTAdwHGVAM7b6dZH0Xyq5aAlnxkWaQk8gkhCxt93E90qxW2DYcYekfnpThitBRH5pjYzrG1odwOZ3j24iX/9rd/m2mOGGsbU6YXYd+ux3vH4A2ds9y/d8HZ+TnPr3a83gvzIDRB7ZwiqRZSCPSX5yjgcBChfGsVF3YtSWrKjGPEGmkVc+52Mu8xjsjCTypK/LwwQgtDJ75qPfTkUjg7WxHGPfO2g1o4jBPTQVhktDY626Y5W+cEzLGWs7NlGrNubS2GHBLWysRaWedQ72gWLgyaXGSgywKCdc5J3FaklVGGKAVKzhLMt2lZ8ySi2zFnCsKGUUoRwh6jzxj6AW8cSTdNsgLOrhiGc4bVOX59wWG3P8YFRvcNnMtHndO72IPwG0vbG5llImatMEdhrt9tNaqI5uKDyzPWq04KqczHBFMbQzesWK3O8b5njvNtka75KpaIRZkGQAiTfQGexD83fdxam64Ux5aUiqxJxQJQKqht+qaRqeUZAXYWRpj8foXzjq7r2j02RsfCSPuMHU8lJYyI0nSBFjbqEo/eToKsaBR+M8CqawNeZmqNx7PTOdHfe9N/SnwZYyIkiQJ9mwxs9DLJTBhyJRdMi90X5ko96nt9Bgw7xty5gTfCaDRHFgV3zg9J9IySRayVaLSWqhtAsnyW7JUQItW3j6kigJ/TIo1CW3vSPX5ryyAAObBrlemuWt2y/eSyZMUJyUNhtXTilFIJIR3fyd3PPUIXn3mNS4vT3W9Vx+fyZqHh+C3qzn+88VsEjEVJzrwU5xcAbGFCtd6uW+xYSQ5l21ll7vx+AcYzeTkglz/ewNfq8fcv+c9tUUCYRuM0E2qR6dzOkqJtjMfKeNg3YCkJG1NblO/ItTSWfMIog9KOimjlTlPgME4Y4wipsD+MIjFT5b1arRj6jkePHh1lMaZpZttymVor+/1IqTKltSzDdZJMx76894DOLZMQP8+wkcdRj0DXH8SEuvvuPvs9d8EZxRf//Bd+Jp+JNRbAs62l5c1+0ScqZE955+m6nhiLtK8riQGl9RDmeeYHH3zIt771Xb7/ncqTB2f01rLqex49vM+9i3O6viNTOczSLum944swmIqRAkLb18pUnO84u7iHdT3WGlaDDB+b54n97oanzz7COdtkOERjkJqlu8YoVInEaY8feokPnG4dAbfgtQwvsBgvQz+kbb4By0YAskql5kLX+aPvV0q1Tmlp80XBIcyknLFG4pEvKtRAbexfK8mbFozls5t+8akpZfaHkWmeyVlwiKefPme/H3n1UnQdf+Qb72ONTIHPk7DxjVHkprmsSWRd8cYc2+m/oDP3C+2PNRC26Asc/dJyiCsNC/28VmoNLeHSdE6oqsvUFfmc2/7tUgrWGPqhpypwXhgO42FingM5VVITh5YAQS0yccfpRnL4L9U5qfyHkHl5deAHn1zxg+c37A4zSsukSAWsHnWEIBoTKcoGNKKQyJQKZ2imWSo4gxUNhuKbg1a6UZA1xlRB7zVkEqWBsqVKIllKIZVZKh0oUhHR6sF6Zp0F+c0L3GrgjrjgUuHWWkOpOCdAoW0T5lCSlC6tQ85oVpsB3xnmcS9tfN6jUOx2O0opdK7Sr5y0DHiDCRXfO7R2rVJxOz2w5srF5aYBDOIISqn03jXKuegTibikwVuHs7JRa3sOvlvYQaLFcLGGfhBk3xmNyplxHMkolPGUWvGd6C4Im/CAcYaYA8opfPWoqgRAaz5ZAO92+DWWljKabJagRaHaM7PaEavoxXXDCqUq3ssgh3GcqTXhbGGmivbRSlNrZnPWA5BiQWvLetXx8vmBRT9QAvjGRHMyRWxpsatU0Oq2jUtrYs50vehabG/2WO+atlmP0lKdstYTRwHLus6xWlnGWTS1KnA4zPhepv7VUiVQjOByC/SbcHmKmUMqDKuBGPNRZ8UYhSqVWBprSJWmzxeJyWGqOYKI0xSx2rJZeVKujNsRbSrX25F+7dFWgVEkpIJvrARgxlTKWERDyRYEjrTormNyM840vQ0tVVZtYDUYLi48vjcMK8NhF7h6ATEkrO2ESj0VDto2tlJrH1wmNOXKOBXGUfSv+s6ijKEHnj7byVTXrAi1MnSguorShVwzCunxt1omZ85T5Ox8YJoSMQdQa2mCyZXxkBkGQ0zS8nHsvtMa2xnR2tMGXSwvnl0LsNN5UiqoeZKg3smUrZRy00powM2xiibsRwpHcNo5jW/tu0srUq3gOpFlyKUQg7SalyrTbYyWPZ+qVJdyqg38lkEY1hlKroQ5ynMUR02YpCU6t6mrpYBWt2CxUrqB4VJBHvczN693TOOMNcIAnKdd8/GOYajMGgGhkEBNZA8UKdW2bkSfSSmFcstUzgY0aRHnN25JFAUotk0wVStpKxGNPjkL7raNppYwWa35yr377Edpr0upEpRMW51CkpYrTdOd4c3YTym6rj/+d2kCzLVpIw59h9JWWuOCsLukiNQL20jJ/t7lSRKiMKOUaIZtNmf82T/709y7f58Pvv/94wTM//F//Gf83re/LWeEdhhnqWjmmD9XCFVaY6xCL0FPFOA46diqesL+mlKi73oqUlWdp5lccgv8bn0qiqPQsLWOWiu73Z5cZWDMTYjsxo9QKGKsoD3D4LjnDdYUqBNjntmnQJhnpv2eOWWsgu1h4uYwsR8nNmvHbp7ZTTPG7uh9x/lQOF9ZNp1h5TK9NWAUWknb0cIgXSrtxugjELYALaUWYhaAV7TwJOj0WrRDQxDtOU8lJNkz1ih6L+2zSklRS4YPBOwwSFU4J4rRPHv5kpdXr/nGN3+U+/fvE0Jgv9+z3e959vKK2NoTtZIWvs3ZOa7rSHlpB6mM4+HIbMi1kkrFOY/3DqWEJaaUIqbEYZyYY2R3mPDd6jbxW2KrJTaqlaIELJVCUUQBXkY9s2jnlGHNwfekatCvnjHPE+PuRvY2FoVmtdpQgeubEbSlGwYuzlaAIk6t1Vwbao7MQa7XaN10YIW9W6rck7QtCUDnvcdqLZruIZDTRHWOFGdCnNg0tul2uxeN2hYY6caurzlx/+JCdE+9JBQhpMaeVnjX0fke7ZyAaq1qfqfM+IUkmjf+s4pQf4wRtJzn4zRJ0eoNho20+VjfHycOpiy+pEowh7PC7rTWMYapxSpLTH0MkI/3yREIoYFOilQaA6Qlnka3CW5VKvV325eEod+GQ1gDVTNlYYnnFvcCMs3We6zzMhEtCWhjjTBY797nsTBT67EYLrpsqnV9qOP7r7Uyx4mYZoyC826gs5YpTMxxZnAGqxWxMdyUkqKWsMGaTqWuQm4olVwqTlV0Say9E79bm+5QqS18FkDm2GJfJYEvRynzO//fzgjvPN2wlsm4C3CpRS1Jig3L936+XXF5MkrBYRwZzs5aUaSgSOQwEsMke64tFI0ARmICtsskx+XdNVqIugW3P2u31ykadp9dyE02cyEptXteQDF1/PfjvRzzsrtfvwOu1/pGoqsAoxdoRBi9SptjMT/FSAqxScKID1BmmTBtjsUqo94EbBYQLbTOHhB2nraq3VR751p0UmtF1tQ8HyfvKQU5JUrNpDALk6dWeudQfU/nNMO6lyKktceiz+J7l3svpRKqMDDHMXKzPXCz3XOz23OYJuaQGPoBaRe2XF6e8+jRA+5dnvONr3+N87Mz3n77LV6+eMknnzzl6vUVH3/yKYfDgQ8+/JhSkUJ4mnj+/AU3uz0P33q3sdGXfXcLLiluNa/k+soXt31zqxf2eRBsed93cZI/GgwTsFHBMi5seQ9wjJH+YI2q22u31jCsBmpFmMkxCJB+B5zruo7XNzd87f23ub6+ITjLahjYnK158PA+zlt2hxE7BV7vAn3v6Y6dFLf3sgxHWfTexL841usNznZIjmJQVSbFj+OB/rAleX9k0eacscYwDD05BuZpZh4PqJLZrIdjjPDGvlFLPmOOjKmql1b8JtlRylF4/7N+5a7JgIWM1oWjHir1GP8egTDlJQn4jB0Ly3XpJonc7A48f/GKV6+vmceJ1dDxO7/zHWqBH/3Rr2KU4u23H3Pv3jnWGV58siVM++PnmCVFAIqun1tjf5T9sQbCcipolfHWNgRfnKltDB2lhLVQE4R5YrXq8M6RUiEeRORuDiKEnxtlVBtNPwyc9+d0YcV+f2B/mAip4oCS5wYWycv21tD7pRLfLuyO8CdVktT9IfLs5Y5PXm0ZQ0BpmHMhKEVvKylmaRfLmZJbNaFdT0yZOUTQ0BnDXDLFyAZaaMvyP9eoj5qcYZ6ztKipZdJMq44cn2DlMCcokdrGESuj0bW2wOYOCKZp2lTShqVReNeC/la1XlqajDV0Xrd2vsTN9TW5yGRAWyo3NzvGac+Dhw/wWthJq8ExTbEJlUubR6362NaaUoFWDasZhl5QbN/AQglsE6loCVS0olZJJF3nMEqTI2wPM95DiCOu64BCiaLL1XkZcHALHkoVdxhWKK25vt7TDZY1nimEY/VBlUX/pzaavMJ7qSTOszBblsPSOGln00Yf2S5SPVVsNj27w15aOeWpY63GexFl3+9ndnsZFOC7yvb1DbnAxZkkYau1J6bKeAjkuNCUpTpplMb1HuMs0xxZGU8pBe813jdnnTTedxinGQ8R7zybix5jFblkXjx7hSKzWjm8caIv5GRk8+EQoCpiEOac7wwh3E7g895y78Gaw2FmGiMpFfbbWWjBJdH3noUpg25TeFITg67SulJDRltDzeCNYj9OrNeWkKT6mFLBeIUfRBy/IAHDMVDOlTglnO3JKdIkODAKtrNm3s9c3BOQqVQaKCNMUG0Vj95akycFg2ZawQ+eXnN+KdO/rq5mbl7PGA0hFtl7yxSsJoaqUOSi2R4KXa+oNwFrFNOUSbFimq5a7z05CSsVJc8ip0JUAd9ZdtcjvjPUBE5ndtsZbUTcPBWFSlXApiY07BorsuYqbXQEzi56Xr3cSXCfAtpKa/Bue+DSuONUSZaDXLc/lehtsFRIEebLar0CBOxEtRbtwpHNZKyVkfKyrBuo1vT8GvMxpyUhlRYQ1X6n7yzGyX4JkzBlU7oVxHRdd6xIVxoLM2U5+K1BGc08Jw5xbvptBm0LOUdc57i4vGAZiZ5ykT1ZoQQBpEQOTTch1QJNm+B4yCA+T8aQLy3z8vfWuiZgnCS4WhIM1UBy4Mx3PDxfEUPi7fU5F92KnAv7GI4T8ETguxz1VVrWJGCm842lIT48powioxY2qHF436EoxCiX3HknVUutW2XaMO53OCPV6BLBKUWKgXEc+an33uMb3/gG0zSx3W457Ec+efop8xwZp5FXV1d8+vQ5ZthgzRlflMkvbbQSMC+tPZk4Jx59qePHfvRHeHD/HjEGmZ4bZkncW5HBWNMKX4pYI9ZYYoxYBR+/uOLpp8+ElZYq/VnP2cWGlDJd56lUtrsDH17t2B6iTOessFKRT56+YJ4nCoqbcWachBm1G0eKKQwXPatqMXXA1J4YKtscmKzCUhgmw7rvOd+sm9D70v7E7XooR4UbcpXCjDaaomS9pZjZxsg8RcYpNl+ROIwLOCB6flVJxLefZvaHiLKOfrViNWxQWpOrIqSEsZZ3332Xn/u5n+Ps/EwmNk4Th8OB7c0Nr19f8eL5C7797W/xb37zt3jy5C12U5RkIMTbRLdWtDGcbTY8fniP84sNJTdAr1T2h4mb7Z7tzf4OU+g2vpBBF/UYdEgRBjKiY0XNxDALw8sYtHZUBevLRwznGx698w7vh8A8R3Y3N8zTgRhm5hBQtfL7v/8t5mnH6qywOb/HbjthUDhTcVrYbUPnG4sOFt0v57ojqOOcb4Uey9nZGbvdNX3fM407rFesvMXqSskTIGdQezSytFsLN0rJ+zCwGrpjQphzISXxg9Za+tUKax3zPN15UrdJ4PEZ/kE5nBLWU0ySmO8Oe6Ywk5IwOo/smQaGn607Om+lM6GBTdKyLfqAurXw3bYrcQR0Fp+yALmw6CEtLSmt1VgZKqk9htZ2ZKQ4kNPtZy0s2FoqJUVKSdQkoPcbPqO1uxprCamQS20AS/0cTiixn3RflEpbh5pcpBXbtE6KmBIxTqQcJKZQ4senNDGnicO858zLgIMyJ5ZRJE4bYRKy6K+C0xXjGgtRiZi7dwKmxJiJpcCxXXphi+Wjzq7o4tyyKZaC5KrveXDvgsP+gDXQ+aWgoo9s0OUcVkunSFsrSxHbLAB8ydy/dyHT2+INvYaqLXNN7XzORzDsFuBQgD8OrZjDKGeYMsdfpPRtG+DCfAUZuFBKPeqbqgX5gsbAUrcv7s7argsrSyluhbwWYKMxQY+A2N3sZQEdF7VzMO13pJQYwwHbdYhGsbq9jiU/A4kra0IpmbjorZUJ3bXivDvmcHGOb0zAziUf71E1sLPmpe0Ytoc9u+uR9bqXz3LuOIDmsB9FyxVpn9S1SpFqf2B3vcM6ib9MrwlJQAKFJs6J/WFinCbmKXPYB262B3aHPYXM/Yf3uX/vkve/8mXeffyQ1WrF+fkFq87x7MVrUkx885tf59HDB4Qw8+9++7e5unrN228/5urqmm9/7xNcP+CHyvWLK7xzhBDx1uKcQTgFViBclWWy74KGtfWT27n+RTjWF01SfAO4X2JNRWNC/hHWCrPH6aZt7UhotKCtd971Z4oEC3nDWsswCOhrtGi37aaD6Iin29bZb337u3zly2+xubyPrZlYKrEgg5q0FJ4HbwlO2tadc0dG6PE3NyBL1pE9SjoZbbD2OGKk7ec2QGEOx+s/Sm10okkYw0xKsXUwTCilWK+apttn7G47pLafh36U1jjt32hXvvuztUpekRq7eZpmlIrSGWZVa+O9+7O3MktvFC5qZZoDISaRQ9gdePHqmucvrthvd7x88Yq+83zpvbdZrwbeeucR77/3Ds9evGJY92Qq29crpmlqsa6sg/Z4j9f6/wkY9scaCCttGqM14J1uLQKKXGWgbK1QjKIUT5xDE//UqCwC5i9e3jDPiXmOUOVr1hh832GbtpTrHANt8eZE+gK+o1ocAm8uthAzhykyzZHtYSaQj+LQ2ipqCmwGBw3ZNlYO7NqSx1qQViFo7IdKUsKg8NZhnVQOJPHSraKqGAZN1wlINB2kvSDkSr/qMTm3tsCmY2AVuhjGKTW2l6JU27JdMWMUzltWm44cBGQxVlHbdBmpqIi22byfGiujCWobwCL6JdqTswIKm/WGmivbm8jDt84YBsdhTHhryDFx82oLSrFedzLZR2ku7w1476mlsOo7jFHMU2Bz1vP6emS/F5Fg4xQpFeapTYZrQNN4EKH1MFe63nF5JqPXp2ni3J2RYqV3mn7oiSkyHRLjXHE245zB2Mqw8cSa8L0lBAk80XJ9zhliEMDPaNU0v5pzqxzbGmpVxBTbO5YgWmvwHTwcVnSdYjzIVLwQRBRepj2uRMA8VqZ94uZ6izEZq85xw5ph0BxGTYwW7RzOi3A7VXrhRfvHMI2hiTlanFMcDomXz26gGp58ecP11cQ2VKYwc7Mf0RT6TtMNHY/fuoc15Y6YK41iK6DzOE6gK5vzvumv1CPIsL2ZJVGsME8B1ErYkjmhTUdMgRRkXfZrJwDyPrI/zPgbjXWKfujJKPKc8E7AxxAjcyyN1YcMIMiTCLAqLWBUUoRD5erVnpxvREdL9TgDvvfk60i/dsQA67OhsaeUiOfqinOV7T5QMeQ2iTOFzMunW4xepsaAdgLgLFV3rQxtriulgFJNM6RUctbstgHrmnZVYwc4L5MOc2vBiTFx2GcJipsI/xTawI+YONsMfPzJDXMsrC9WpCD6Pn3foXSHSgLqSqXZsRtHKRisHHGbpOUnHNisHf7JJTloQphbO2pjVzppFUW1irS6ZSPmlLHOsLR1pAZoLRVA74XhtWiuLYFoatN6c8zHqUy1VmIQlmxO5ciu0YDrHWfrNWlKxF4AzhBkItU0FYbhjl6FkiA854K2lvX5mnlKhFmm0RptMC4x9Of43rPbS+BjnWEcZerrogGkGnC9TILMSZhrxglgLcMlROT2eDbVIno3Stqzjy05VGrOhBwpzmGMojcyJOJscMfR3csxMod0W/3XlpwD5FY61RyT2cXk/isheXoXjl9fkqm7p5fRck/W3NHxyJkjW8harq6u+J/+p/8HAP/ZL/4iX/7yl5nnmQcPHoASJux+v+c3/s2/5r/9P/33TIcDq/XmWIk9nocNCENllJUariEyHmZCLBjnmeeIMoqrmys47hdhF5ZcmjCzlul8k1TVi9a8evESbRy7/SSBuDX0w8CDR/d5663HzNPM82cvSK3tvfOeOczs90Gm5m0GbrYH0YGaAvtxImo527q1p8uJYGBXI3PYwmHLmRuwSrPpBsYpcb1LXO0Dxnl6q7G6svIdylS0qrhFw6dWdAN9FgZCLLBNhcM+MY0zNWesVrjiWpFHWjhDlDaWkDL7/cRhDmAM55cXRw2XXODi3j367hP+5f/z1/jN3/y3XFxc8uDBAx48eMDlvXucnZ3xzW/+CD/xkz/FO++9x/MXL5s/14xzZg5BQA4RhmLoPZv1IIU5pYT9VyvzHHl9teXlq2vGacb77hiIAk07U5LGZQ3QAOujplGsxCwi+NLuKppeaT40Foumsz2d6zk/P0PAtcI0Hfj4ow8w1vHRs1f86MUDNpfvYv3IzatXvHi1E+3N8ZqUhbm1GgaZ1j0FvPc4p9mPI9ZaHj58SCmFi8tLvv7NrzNPO1R+l5xnago4K0BZqYp5WtpD9XFMu1ROJBlUwGa9FiBMSTFwYdlba/HOo5QmhIBZ2DYLneboJf4gkzbBXGtrWc+NYafa9GaJN3LOXB+u+Ymf+HEeP7yHpjKOAiBClSnjRh+BsNzYinZJKIq0wpnGtpAp4KIdtogct29sDAGJQQ0N7FkE88vdZKgxMIyi8wajRWZgyokcIiXe6t+oBrAY26GtRaV0W/CtRQYWIC2w2ihSyWjkfVgk8UpZfNM4C0i4GixVKcqsUUWGNzw/7LCGJscgRYTey+CrJbZOWVogS2trVEiyv7SB3rVSRHA/F9n3pt13pTWVtUrQbXp+x2plsxokj1kGhzhpX9dWmN6xtWPe6na9uWZkurI6Jtid91zvR9zg2R9GQpL3IzUUhTNSTM85cVsmlyEn1tij1ubt8qvHz4bG8Gs+Sp6FAGG1yrkf5oVnVo6tl288s1obwMgbLJTanmUu0t6qjhMGlhLx0mlfiG0PqjuMRY2wzA+71/i+Qyn9hYmxFERUW9KKHPMb8jDOO1RM5BhIecm12p85UWvGeotfDcwx8/pm4mzdUXOl7z3eSJHQKCNEh5hRnefe2eo4qV20eKUYcP/BI84uzlrslIgp8Xu/+ynGVbbbkRCiMIyTTOieYyDEma5zvP3kIVMsfONLb3H/4WP+d//lf85hDPz2736b737/Q7729a+yWq1RGt5++yFfeu9tbq63hCnifcewXhGLxroe4zy5wvVuBIpMjTQackWRuSN1Ke+qNvBTISy7zz1pObvLHX+wMKLumn7jPXXA/AWftNht4n2XiLJoxAljt+KsO37mXV90/AyWgqtrDC2DsYrr3R7rO9SiIwv87re/x8N7FwxW8aWu5xAK3/7uJ+R5xjjD2196hEqRm9AmknstIO5n7rM0zepahTBxBBSPBaP2fVmmGDvv29+3fNEokTjoe3KMTHVueuQzfee/EAijSuwphe3b9vZ2aEsR3t7GqXd+TM77EHi927Hb74lp8Y/COl6vOjabntVwNxZdNDk/D4DOIRJiYH/zmhcfP+Wjj5/y6dUW0w28/eQBzjo65+XMjYVvfet7vPf+Wzx58pDd738f33msd6Qpt0ttXSHL+/+TBITVpQ8M2uKQKoZqU4RgCYpFb0JRm47J7cSxeY6SQDuLmY30904ztlRibNRnZ48LWWth+yxm7qDctVamIFOnxikxh8Q4BeYgAvnzHHn8YMWqzLy6mjBJMU6BvnNYb5jH2Ka1yI5w3oiY8kKHdDKZ0Fp91D1LKbWFpvCmoaMY1n7Dqhuo8YA2u+PBe/98zW6U9qLr7Z4YJOFzTjSWYlRvHFTWamlZNIY4R4wKWIckQbVilUz0ESAksdn0hJCZAyhr6YZemErzxLSf2c+Jy4sVaNtaQQWd3h+KJESm6bT5AlWeRMmBftB0rocikz5tJ9Wjm92eci3MN+8tNY1ovDiQIPopRnlKkaEDvffEnLl36XDGH8fQxphY9x1VQYyV/VjY7RKHfcRa3dhWBd85ztXAOAZUqZQkTq5WaWuxTlohZDy6QekMSpggGtHEoJYmEH77nEuGj39ww9vvboiqMI+BaU643rYAouCdjKtVSv2/yfvTXlmyKz0TfPZog7uf6Q4xkEEGk0nlIGhoSd2Q6pN+QwMN9F8tlNAQILRK6E6pSjkpk0lmkgzGcMdzjk827Kk/rG3m5waDmVn9jSgDLoP3nsHdzbZtW+td70AIM/2mwzWWosUU3BrF1c0G2wRyEclp0ziRbrVeWEXnQaY5mpr2GIlBwJ95jLx6IxHgTecwSaKivTfkLLJcYR049g971EHMg4/HwPl8puuuMW7GN4o0J2nonPjZzGPkcH8SULKIZ1CcI2EYVk+dhT2gEfDVOpFyxgTjlOiNJJj5rqVvLWGemEPA28LxFCXEwEj896ZpxecgRXIUE9SYsngN5cI8Z4Zp4Jgm2Ft22y337zNKWU6HiatbMXVurPgijENG+YRvLaZxpDxgnarYRyZHS5prol9jCKtxcIYSyWkpMKUA1RomBOQKhyB+brXOOx+DUKcVOGPxTpqmGBJXNx3WGVy2NG2HVkjB5SzDeGYeZ2KS4IVxmHFmpO08ppFz7N1Mv2klkTYnbOeIU8R4S0hitu87h0+W034gR9n/whxRNTQg1kCOIPMDYauOA6VkYX5pU+VwBt9Yus7TNCKlmmMWQGqeVwYpWUxr6xbFPM6UvBRKFbCpaTdt65kyMEmiatdVqTFiir566l26bgmf6DzWGdrOCmCXMykqnG3Y7/cim/fyHh/3Z8KUSSGvzMBl+l4U1aBfGLkxRAG9KsBXck1gQiYZ0hTW4rlIynDOCW3EA8caCUwwBU6niZvNhlQbS2nIajhJ9ehRS19RCqSC9e5Ss9RRYtO23HZXjMMjpUzCpHiy2agnf6wxOOvEbLcyVLz3nM5nfvXll+iamvYf/sP/wp/92Z/xB3/4hzw+PvKLX/ySq6srrm8EZPnmm1eM5zO23RLGYXkz8sw0lZmnYJHWpBSZ50AYA0OE968Gfvz5j6p0dgY0SjthM1cWxTxHYpYE1Fdffc2rr78G15JiZAqJcU6EsjgpaXLR/Oznv6LvahR9kf1st+tIj0k8fIxBWUO7aZimyPhwItWwmuX5N8eEsorWJHAanOI+HiEnvnn9ADNcbRz37wKuaXDO0TRWAjNUlue1kYRYV8/DHBOb1nF7teX9QYZHp2Em50RjKgA/B0nD8+KveDwNK9AcQmRKEaU1r169ouTC3d0dpSi+//3v0Tc9v/zlr/jrv/kZX3zxa168eMHd3R05Zx4fHzmfz2y2W6hT5+3djuZcOA5ntNJko6EYyFH2rScpWKWCtafzwPvHAw/7MwDOWZ49f87Tw1hdmZrl6ZK4rA2t8abjHA588/ordrtrGt9I8/BtlGHBiyqj6+r6OX23QSnYbHcorWm7BnV7jfeOOE30rRNgF3kWGBVprAxpxhh49eY1zhrubq7pNxtss8H5Bt+2dDrg1YxVhYJGK0PMiuM54OyAAk6ngXmeoXr8KC1AxG67rdIy1ubZWHl/m00nQ416vy52EovHxge3MwtzQfbUUpl4IUbO04lhGoTd9+4959MZow1zmRmmAa0Vz69vOR8GNpuOUiS4pGtbXNNWebG5GGEv6XEsOHup718gF5HzmMteWMoKWJQqk08FFiV7vWRiKq+q6XsOqCxDAjHnlj3TOisSaGAqmdaKWbu1Im1bZErCqBTJt3VSA4vHa6mJ3CKP1xU8jkURi0EhXpUGQ2PF90f+DMJgoTAOM5219BXwilmsGZS+/L6Uqw24+lCWqBag/wlQc/laBbbMhZn0rWXNcnuoAo+Pe37wg++DypgKQCyKg2VllG/9fK4DoOXze+9IKfFnf/U3aGNR5q2snyRM6TAL4L4AaotkC6jsRwE/vvu41K6X2/TJ80VXs3f94Wf99u38G7/1yTfkArF6L68SyZI/+B7gA2ClnhpAZLYxRnzbfgiCFFZm38L2MjkjGiLNQSmappH9DkUZR2wp6BgpdViZSwXB6tAoA1FNtG3Dx8933G47tIXGGe6ublFIzXN8HAjnwHweGY0iFAE2t9uez3/wjLtnt7jWM4cZpSTgY9M2XO06fvGrb4hzZj8cUCisFvXQFCUN3ETFfn9kf5q4f/eW/+f/4/+OqR6AIcxc3VyvUnxlLE3X8+zZLc9f3EhgE5rb2xtev9tjrKXpduRplKHfCi7W9eEcmiB9DFDQZNNcwJ68BnP+xrFYCv224x8PXjxhn3zHUfKS8rqaFV2uef2XetNWthWrJ2CTPcbAMAWmWECJr+40nXncP/J7n39CmCP3hxM3+z2xcTTW8Mf/5PclhT1F2O+Zl4AHrT8ErSsILQnsgK7qJtTqhbpUaAUhVExzoG0+9IcVz2Kpt6kgUMpVlKx+y1leGJa5EiOMQjyLSwWbP/SAK0U80R8OYqvwzZu35Fw4nEYOpwmFZtM1PL/d8aMffvQbQNh3jXS0ztxee2JUqMnxtiTmaSCGiaubKz77/FNevLhlGiZ+/atXfPP1Gz79/ktOhzNf/PprlC50fc88jwLQnSextPJVhq/UP7jXfPv4nQbClqPUKX2Y45NklQ8L8a5r5cF3njgeR4aaqhFClOIUuXDjOKMOZ5yPFC6a6Bgkle/bQNhTY79pTry9P/H1m72wR7QikLh/OJEpDG3kxacfEx8e0PtJpnkxoXrZhn0jLB6lFeN5psQCWqbhakXPl2SLC8VSa40zhVCquWZxkC2nc+D9w4lQZYXee3zf89H1FXNNebJEsoGcFSHWDAgFxgk7gjrFM1YJWsOCvqtKVU9Cm67HcRB6pnGiOSZHcmoYB8U4ScJG0Zr7+0AIic3GEudC1Emio09JjHQLzPOE1Y7ttmN2EYMjJ5hDwNIwhygAXhJWoFYwJcfxMDPPQrsX1kaqUiuFsoVN70kZTkOkbx1tt2UKM1vViAx1CoQpy5RVKYbTxHiesI2jKDEhfPFsw76I5DXEumHFwFQb+mkOMj2t7BdJfSmS+oIHPVezcaCAc6CsZpry6msgoEDifJxxXpIZnbX4zrDZ7Qhz5viwZ54K17c75jGStWYaRDYSpoBvDE2riTFQEqQkIJP3Gmfg8TFx2E+EU8J6zUjBe1MZYwXrHE3rKMWhVSDMMw+HM6fzxDCMzGGqU8uGt2/uOT4ONe1M6NQpialwTsK2c06mYM4I1ZtSxLcvQu89pQYZ7MOJmCSynaKJITNOkfuHM9//nsX1HafTmZxE+tR3ijkIOCCmqFlS6UAMl6dEv+nZ7bbCmlbC2iml4NuG+/uR+/sz2lha37DfC0NIV7+UdmPp6wR4OAWMNoxDRPtEv22ZQsZvLCEgyVSVCURmBVpL9R4rLEW0yAlSSoQpoJwlzAmrNEkX+t7RNC3OaUlcVHU6aizDkNluRc47zlKs5zAynS0hTIyDgG9tX/CdJFjOMYAqbIxi03XspxGbxSCz5IhrHOOQ6LxmPs/EUYIHQhAavDYa21hsI/d702tyymw2O46nk8jLkrAedSm1iK9raZVPaMI8MxzP5Jjpt714ZBVhxaUo6aSlMrG8sxhv0UqKFImlF4CCLGbrqnVi41oWI1wpesbhWIsFQ+MM1oi/0XF/Fr+2Il5MMRWslil6yYUQIqfTLKlAITFPIptX3qKsQTthg6lq6ByjMD5K9U1U6pKelVIR6noSc2IoaGMxRuRarXHc+oZpjjgtD3KtFZnMGEXCR5WlSMF2ab704uGSWKvUmAoxwuNhL15x2lfpE9/BIJC/O2c5HE8fPNOGaSalwr/7t/+OP/yjP+LnP/9bvvzyS96/e8+f/umf8tO/+VlNwxNvSus8zjc4334XfnEpQGOURKqcSSEQ6/n+3vc+p+3ck+pNUXL6oEED2fsfH+95eHjP/ft3fPXmPdFscDrTtBtiffG3jyfe7QdihlQuDAyjxJMsTpF5jBhfmSfOkcfAMAfwaV2zAjRbUiq8fXuEypB0TtbizbOeeZg4JcXmE8/f/G9v2W43eC/putZqXGNpG8vNdY9zLc5ZXl5dM80Tf/aznwoQrTV//Id/wE9//rfcV6akArq2kQTYRvy5rJbit1CBVcQvzFvP7e1t3WcbPv/8h4zTzKs3b/j8937Mv/uf/id+8pOfMM8z/+2//lf+5E/+hBgjv/zlL2nbhpuba94/niUVM0Sq8/zqUSRed3JfhRg5n0ceHo8cjgPnQVhGS7T7tyUwqhb+yxp96hWjay3VmS3XMfDw8I5t19J3Wx4fH6UpRNJud9c7/BPz9OF0YPHZSkoM9F+8fIlBgNaSE+PpyDicSPPA+XjgcDwzjBOn88Q8B5raKA9zoO3B+Y63jwlvFXrr6HqH1wL0xMp4cF6xvbLcPrthmgM5RlKKYrA8C0PjarurMlkYRknELBUITzl+wMKMRfb81VeU32xiVsJAHYouMq0UhREW5pnFjHrxT/z+x9/jX//L/wvDfOb161e8fftW7qEKMGx9i3eOXP3m1mEEkha2ACGpNmZL4umHhB5haAloJr67Wa1lzwcMDEPEElHZUpKwsxRiTF6UAm8ZQiBVYEZr8YJUZmmqFiaQ7K/f1WQtQQraGEIdersSn8j0pCnOKXM+ndjv95QidVXrHWOIjHNgnAMhpg+uxJL8vDAkngIwi+x7laUuwNgCIpiFyafIGGHVCCQjKY5F2NfTPFOmwvl8xlZrEa1kX8wVCPz7urzFBy7GwBQDMcbqifXdhwDrcb0n15AdFK1vfgOYkF7rCWBVvZC/k4Hyf/BIuaz7tKxjueYxZ3lu1BQ5Idhc2ES5Dp+cMZzSvNZ/CphG8cTUNUSj1L5pmTpqwCuFpQILviEbhXIWHQM2i+rjatOB1jSNk5gla2mX/d0adp0nZsWrt49Mw8DWN6iiePPVO4aj+DiNcwRn0I2j6Rquu0aSI52h27Rsdg2+aYGMMZVxQ+F8mlY5vfcb5pwJOZO0El+yYplC4ee/eo3VhT/53/+C//bf/5z/67/5VxTgxfNn/PKXv67rr7Ki25br21ue3d2yf9zzfn+m8RJyopSma1oehhNjmGUg3DRYUzAqE6LGKsWyhWkyuswEJSBI/o3d6//fQyGsMHm+fPAVo4Ut/htfqe9JC1BO+ZBpGGKoQxbW55o1Zh30lALjOFJQdZAR2W46jueIYcY7z9/87Jdcb3ds2w3kzN31jufPb0Epnr94xul8ohQlSowmi63Ik3Py9J7KSEq3901lz8qQS4a6As8ch8AYjrx41tM1F3Zb1gVfvdBjKvW8K6JQ6b91QgDE89aoXFUsyz7KBYVf02Nlbwgh8sVXb/nZ333FF9+85Wc//5pTmNhuGz79+GO6psfGRFZwHkO1aOk/vFa/AVjKVTPGsLnacP38lh8oxY+84zTONI0iBQlY863jdBz4L//lv3N9vUMpxY9//zNubjuu1Q2FQpxmQggyANHy7NL6/9ga/J0HwhZABmryUjYYi3gM6CU8VEwV5zly2J85DRO7bcdwFjAspoQyRlhgc6KUCdeUalpYfT5qgyeG9JfXzwnGOTJOgfePZ379+pGvXh94PAw1VUYWbNjAJ3e3q3+NsRplEsaVmgAU2V3vZDpXoKTLBEMe7jJJXqRCi+QOVZg4Y5XD6wpOFc3bh3P1BJK/73ablWad6oTOWVPlpbCp4QBtI9PzmPNakJScV1lNCHITiddNbR4LKLUwXsQ8eklKSylxfDyAdrRdR9trut5yfesoORPnxHgK8nAtYqocJomEddqTZ43OLRuvZaJhCtYblHL01tE3jmmYOBwGSjSEAcIk8lPrjHh2qULT6PqexQ9sHCY0ifMwr4zUd/sDJWke3o9s+55N2xGD+KCknJhTJKvCs5d3NCXT7hp+/dPXNJuG0zHii6rMH6RxrRub1kK9T0XMgikR45T4lkXxYUpZGFJCERcGk7YWjJY0SS009W4biGEkpySNtQw1OBwGUi6cTycoSRKX+gbrLPOcKoVdzkNCcz4HrDXklDjvR2IsNNqT50jbdmy2DeMwk3IUqSyV8p8SaIv3Cm01O7Nl/3gkRthdNZweB8ZxJsxB5GxVbtZ0jt3VBusMD++PDMO4+hqlXDgfzszV4DimBDmv2v9UU1qNNlztxNdtHmeR/iEFlNHQb93Fl1cpcjZkpSkqkMJMjommbRiniWfPNpTiGYcC1KmXhZgDIVla25BjloRNo7GNI2YYT4HT40DvhMWZdaLrW27uWjKFhzdnmDzWiWwsRLnua4lXwzNSZbk45P72XrwmlCpMIVT/NkNMM423dJ0lpiiJmUPBO0m16RqLOO5Av7nh/u2ZOQd5MCYwQcImrGf1qYgpMw4Dc/1s3XVPnuT/764djWs4nz2n80yYRRpqnrA6rLW0nTAKUpIJuTaa169H+fuTCZjRIl9xjcdZw3E/MA4j8yRsF+scYRbALc2phg1cqO66/kGJef2ZGWUNqsaSLyDLXIcgUm8YtFVstg3WCXDgncUayzzNHPbnyoIovLt/h28bQDHPcv5zyaQ5cjhLUWCsBS/gm9YX2Yls7tC6loM6MM4jTWMoZJaEtRBmMSen1Mm+wfpGqO5F02jxgDRoGispPPKokf00lSRN/TLRzIu/xCJBqQ1ZLIQ0ETCEdJmI2Zp4nLI0zKU2GSHGGvqiP5CxomqohZZUnmmeef78Bd/7/mecTieRGG16dtfXIjsaRK4xToEhgNLCvl0T/bQmzANxGp6wqvU6xMl1j9xsWqyxv7WEXp4l8zQxnM+cjkdSUUTdAzVgI8Q1eUzAAJHIzPnCUiklQ4rkOYj8K58pFJrGsT9m5jzhiiRFb69arK/tam3EcxG56hwifevxxjEzocwM3nLzSYPvMnGeuH9/Qld7he2mpdu0XDlP2/b47grfwb/+lzc8PjwA8O7+kWfPXvDw8IAkRBv2xzN5molZsVGGxlvinAlJZB9t2zBNM4fDqa4P6lAm8ubNa9qu45/8wR8wzzN/+Zd/Sc6Zd+/f8+z5c/75P//n/Mf/+B/51d/9HY1zbDcbDqfEHIwMFaB69lliynzz+h6Q83s6yTDxPIi/agyRZz+8pe833wGE1ataPmR9LP3JIue7vr7FGMM87CmlcD6d+bu/+zsAnj1/hrFWwhEQZo5xDco4Pv30E5yRGunq6ob5fKhsFBkkbOaOcHrPpoWb654pSDjNeZoZxplYoOs2lUGu6VrDMM68eoi8PRSszmtfUYqkRKZU6JrC3a6jtRIws+0bcm45HI/CCFd6TQxfEsysMdJwKvXBWtfLfvL31O8LA0sYeYmQIsM8cTgPLAnab949CLDjXZVOG2GtrPtGDQkwmk3f13CKsgYlLFfOVD8q8d6SZMfv8u3JOVFSWEEwClgNYQlTEWI/2orPpq7NisjopY60XvxK5xTFW0uJ+nu72+KslsauvrenqcPyuVi/voAjavEvyxlTaspfuXigCQMqMU4TwzDIcAxAa/bnQNd1oDt8I6/jkBoRpQhZGLopi/V8zoU5KZTKzGkGJbXrOM9smw1eG5QymBy5GMI/8WMrkVgSMWs2rePh/sjuql/3MW0TSltSmFHZMp6FGb4ulMqUWu4vFYWlP2aRQIkX7YdMqoVdpUquw4bL9ZR+6nL/3t5cczqdmcOHDfLCErRGE6Iw6Eq95pJILkz+f+yxsEx/G8YXYhJ/04oD5rzYLyzm4yK7Ox8P9G3D/nCg8Y14YForA+TqmeobJ/ebmH8KKFCqU1nOlVFYUG2DwdNuN3Rti63P/aIiIY7MKaBNh3YNv/jmgel0xlevqOE0Mw4z8xzJSlGs4eZ6y5QENOg3Lbc3O/q+FaZ64+W5axVP7ZtiKmy2Lfqt4RQnYqrpqUqYPNoImCIDYDFX7z/7lH/y48/X7eTu7lb8Y0Mk5SqtVZq2adhuelTJGNfyiy/f4p2vfKkd/nhgvz+zPx7qAFKhjQyTZP3W+6wy8FUWi4OF6foPXe/lWq+yRinFn34XAMY0pBLXta6Nou87nG/WxN95jhcbmjqwWdLDl38LIUrgQe3lKaUOQisQXeujw3CRY1qjGOdA6xXedjTOs+l7vBOf6FQKm92GftuSVOIXX3wpMnNrSFMkZ0VTmsskY31DH54PVf/HWLv6kj0Fs2JMq6XI8s+1LBY2qCwKYUiFGR/sBdiEqmwB79wHINE/RMD7xa9e8V/+v3/Fn//1LzgPM6OWOtYHYaZ3Nxbr4PF45Pb6Cmt/Ezz/8KhFc70mbd/y/R9+youPXwjpRhvubq/55a++5otfveJXv/yKN2/fM4fIdtvzox99j6b1nE8zXdNwtd1xPhyZ56kOoGVt/Z/KLF8iPwWMkgZYGrOY59qwSDM6jLMkz9UJ9NXVNdZaximS4wwovJHo4Vyq018qlBIqDT2hU8EoS3rCfoopsz+NvHl/5NX9gXePJw5nSZk65UhQCec1zcbSO0cIoZpHC2OqaRxdZ9e0SZE/WtrOiZcOYkwpJuu6sgUWU7jCeZq56j2Nd2uRkmLm8XRmnlNNKxJbWqUyU4zS+FcYvWRIQdFeeYzXIoczinnMzIOYQTovlO4UM0Y7nNO12ROm2tJIlbWREu2yNmI0aEzB9NIAjkFi69tisF1heptxjSWFZcOTzdU2YJwlVj8x1yqMKRAQOqVSGO2wdkZlRRgFnBuCFBgWS1JgbaHrGjZ9h28U1lhyzjw8TJyHIPKkqiza3bTMWZMmSZW5v3+sDwUxPJ8jWCeFxTSObLYdb7565DREmgCd98xFExGW3+KNIbHfCYmhkqIEpUlzFkkjS5IVHI+FvpvpWzGXHx9HDo8Dxiq21x23L67p+pZ3r/dsupHzeeQ8jbTOi47ceeIs8rbdtqEoJcw0b/DaykbrNca0nM9HHu7P9F3L7qrhzauT+KEoeOE2oBVFK1KYGU5BfBC8JVOqnKIQRgXW4nxL0/XEaebu5Y7hMAKGOEnMrm/FjHg4nbHesr3qMNbw/u0jZ6u49r3I9ULi3cNDbWqksWkbS6xJQCKz01gvTC1bTVAVcL/PNJUpYU2LFAkVWA1imB6j3F+qKIZzwjcFpXuMiZxOp/pg1uQkD57tpl8L5hjknii5YI1mnBO7a89QgRvtDUbD9YuO4ZAIYyDkuG7K2ro6hawsyiolEUxD7plcdH0gC7g3TYFxFG801xi0saQxEkNingJd75jCRM7Qdg3n40ycI3MpxCieiCEFpinQtF4kstahsOTpRJ4DSSlythglRWzbCANQvKrKyqjSVmROxiqsA+MUtnGoGDBFw1nR+K5Gw4uXjG9s9TuTfTgFKcglLaz6ONQmMc5JJsAVSLZefGty3au0lj1wfb49GYznXCoAI4a21hrxNVvkoNaJ92IR8CgGYebpxeiiHiFEjIHWe2YfOZzPlPIEUK8gwDKIKFWzl5amQ2uoPmgin6hsv5BXTzHrHU3XC9NIa2wRqd50nis939B4U8Gc/IHP4NNDwMInf0EYyTOLJ4OprESHNpo4BymC69BCzKcvz5LlNVxNuttserabnp/9zU958fIl//bf/jv+6I/+CK01L1684N//+3/P6XTidDrz1Vdf8b/8h/8Xf/oXf8XNyx9g1KWsyCVLBLwROQksNaA8a6cYMRbCnPjex99fvyrNnV4rxBADw3DmfDownM9McyQg+/EC4l2atVgLYQvKMEZJRwZVrQfEny5MMkPVunqPRbBeGFybq5aml8akFAnNyFnOkypgtBFWDopUNEZlxnFk+9xhtXg1+S1MQ2I6zZwHeDwc2e16bq9uK5NbgXZc34qc8OrmGQC3z051bSVe1oHH8SQpy8p6CVIYJw7HIyk98Oz2mqZJ/O3ffYlSIhtovOd8PtK2LTlnfvGLXzBPE13X8erVK4ZhwBiJao9JWA9d7/AeNrnFmkAMgTkpHvcnQpDUYmsU3olf0RzE+iFWz7zdpq/snb+/EJUEWrnUYQor+7OUgtOFZntFzpnNdsOz5884HY9VVgwKx3A+8fjwSM6KEiO//3s/4O75M1orz/PZmMrgl64qRzH3LUXjvKPfddwaT1aOkMVjUtf7v/GelDM3V5v6LAiEMDFPI/M0EMIs9holcxwV4/HAbrsjp8zHn30GFLbPCuNpsaMQFoJWShpzIwDzt31jvstI+tvHKg8siz9LHRJFAaxlTxKL95cvnuFakXo3TYsxl3tSo7DK4qzDNw3OOkpTgfc417Vp1vfvjUHl/ButbSnCJiYnnm5FSol/U6m9cn3zZCxJJTT54iGkqDJmaBq/NqFX274OsuV3LQbti8zbGCUgWUE8a791/kpOqBzluVZff0EaSwVuwyzGz+fTwKcfv6Dvu5Wp93T9TiHz7uHI8TwzzlFYW3UoNExiTbK7anFeM4aZbdsR00DJim2/qyfdkMuS9iiMMAHElnMJ4xCYx5ndtq8+YfUU6VLlVYvUS870Rc5UTyRUVsQi91LrcymFQNtJPTvPkRgKJUty5VM51NKvt40k2O0Ph8uQpH7Hknh3+ZciUoMie2NJkEKRYZycprUfExCrPPmdpRIVJFhDZMRSL9sK3pRSmA8nYkw1eRFZWFokoxIIJIP1q6trrIa+F7aOsVbCv1IWBpepoJOz0mt5hy6KaZ457I9oY+i2vbAGEaB3RjGcTuv6RhuRT3uPbhr6ruVHu2v6xlcZvJAWTE1CN9ZjrNhbOO9IWYDCFIOoW6whzIGmdWv6q60Mpa5x4g2XMnFlzH1wOWTgo7KwaKylcWYNkVFawMrrmyvO57Ow9rNYAvSbjfgOn0589OyGj57dcH8v+5bKif1BvMu0lsEY2qLN8g4MTz1RUWr1RLxIeJ+uqou/mq6s0m/LWpVSmCdqq0K1UKgSXhmUCfCWisJrJb2vNTXMgw9+13LEyiYMITBNk3jvxiy2OLkQciZmYVdrpSQZ2Fo2fUO/7WgbaRJv767YbjooSL9lZH8dhokvv3wtg1gKbeeYYybkM2rucLUG+3D0cfmQMUSO4QhQPVfPVQ3hP2A+hpDIjdR3a4hJzh/Uh6VI2E3bxCcMPzlPT8/LPxYo2mw7DseBmDMvPr6T4KmY0Mqw27YYK+ft+vqKZ89ueaoO++7jw7g+rTW73ZabG/m5aZr5u198yV//za/4xa9f8euv33C92fDH/+yf8qMffsT3f/CyhhhEyjxCDnjrGLQMOYvS1cx/2Z/n3/I+Pjx+54GwnAXJBUleKFSZZJETHubIw/4oyX2IaXujFNM8SQNbZZTLfyVqV5GiJHStRUcpPBxH9qeRkDL7w8g4Bx4OA+/3J/bnkTnIBQglE7UU1c3GSAPpF8PbkZwKzlu8F6P8aZpRLEhtwXqL9baacyZSyXITFXn/KRdO56EWEUVSbSiM55njYeB8mslZCldttLCHSl4lPMZY4ixAl+883bbDWMXVdVdvqokQJgoZbRqZ5NVCw7YO72SjLxSoXlxSROVLc2kU5GoUGzP9xtJZkcXFmJjOiuw0jZUbclUKaCkPUkryfFaG4zkznkdCFClk0zR0/owiY3Xh5srxuA/iRYEReRJgTabx4gtktGIKM9Y4pkkK0RSSUOJbD3NNuYuKru2JOgiDC0XXeTZXrTA6TPUuovDy4x33bx5w3pJDoWlqsx2iQPRqKVvEY8g1jk3fCENHO1I1Qi9kYpDkD2ul6QpRTDu11rR9I/p1I95wbd8w17Wx3TQsigbnLX3fEmJmGGVaoZzBYMhFWERWaw6PA9bbGnrgeff2QUAiozFOMQ2yjqYpChtQK/ptK+dJsZqKT9PE+XzC+1aAnDmTwwmlxOBxmibc4o/jDPMQyCWzvdrSbXpiDMyT0PIbLx50RDHSV72kk+Yqb/CNGMVbb8XU+Tyy3W7F90drcpT1v7vbYF3B6KW4AopEoDddszZdKE0IAoaSHf22xT0OxCgSFesUwzgQgkyJ9KyYzrpOPKWJTSjavl+nmY0TCVSaE+NZdDRCuYaadyfT95yrgbQiFvCoNeVVezGJcVZTciREQ4oCHGkrwEAIsQZdGOaYcKbhfBpk01eKEgtKGZq2giAhyTlVhZwCw7mgLcxTwFpH1tXLbfF8qNMya4uA70syrJX1D8ISpWSuVM9jPNM0rhbh8qB2XpI7TTX6NfV9nE6jSNi1DBxSkvPknGUawioXTsVJTcUixVke4AurJAuwLCZc8r26UqOdwjdSvBlj1qSthUllnF6b5DVuvlTQJos8McwCOEq6mQAmZvFqqcyWeZzIyD6Sc/Vz0VoK2tNUWWML2LYAyJ5cAdKiGrzSTFPAGkMssYK3FaxJab0myyGNjamsB7UWV+McmEIi5ITzDU3joUhaVc6prreKKiLT3fUcFJG7SVEtzNnr6x1/9Ac/4S/+x0/5X/7n/5k//9M/41/+q3/Fbrfjpz/9G3a7HdfXV1xdX+ObxRdCffA+5bRqUN/ynciSEBqrlChHePnyJafhLGyMUiBNyy/i8TDw1at7vn5zzzCOaFV4PM3oIvfcFKQR987xcJwFNDVVSpQTIShC3SOtlfSrnER+OwxBvLbiTDGZ589vMI1hs23wjVy3EBJJiX8lRa+n0WjNMEwUNPcPA857QpjZ9i3WGvqNw7eari2kMeNtwXuIeWKeqxzjOwyDu04AeIXIrDGKdttjKLgKWN9e7xjHiZQzm74FDDlHxnFkniWFN4bA4fHAMJz58Y9/TNs0zCHQbzbrNXr//j3Oip+ZtxbvMkZprHUEqzFqZpqyMKdVWBvgQgEte1EMEhBz/3jg7dt7Pv/hbwfCLqyYGoDwhI6iFFztrta/b7c7drstMWWOpyNN0+FMgzWRYZj4+usvub7asmkcp8Oely9v1mFazHmV+uVUCFGkjc5YrG+xvqPYllZVA+ecyOnCmloSMOXe6UhVZpZSIMdECIHxdGIcBw77R5q243AaGCdZt/M4Ema48jPncRRvS+/Zbbc03lPq/m8qS3TxtfrwLqotQ+FSV1VWWCowhsz+PPFwHHn3ODKMA84Vbq43+M6hjOJX33wNKTCcBkouaBzKGFrvaRtJtgwxMocgBsVNyzSNiI+lrgyUjFoB9g+PXApFaRYqx8pWUBmoKZHV1xQFESP+XghLMyT5r3HC1mm8YZwi1kmqba4yH2urLBEZUokPlqXTtrJByhMvxEKrNKnWBnE5jwhbTDyCJ0opbPutmE73PXc315yHAzkvjWfk61fv+PKbt7y7P1T2YCIVYdgrDXOY6dqO22mL84bzfMZbS4mJ5zeBTbvherNbAQCl6gS6XkuUWB4oBV3bMp0DXdfK8/7J6V48L1NOFVBY4KsnQSelEEtmesLekvNnwFmmmKGkJ+zfBa2sYJVaZKdFwoyAFCN8+7oreNrUl5KrXDetCdALCro+v4v0ZSnLMEqeh8v1qADh5SqhtcEZizMic931vTw/jV77NlutFxbAVIbvcrVTDExT5Ndffsn3PnmJUUWuc/VOm8bI6zf3vN3f188ga+UPf/JPaK9uUErhnJM9OAS0gr5vAdaEWeM8MUSGwyPbvmWz7egaS0yFvvXCnu5b0AJgNk3DPBc2u63UyGHERcPxOHAeZ0JK3D8e8N6y23QoJV6SsFym38KyUpBCqIFuiq+/eb3KrI0SIMwbRW6EHboMKtq25ermhofHA28fDiyJhCklrIaPX74gZwhBJOTL0Pm7aEQK1r2zICqAD4D+nCqgdWEyLQDob/yi9f8qGcpmLcnRda1nJIgulwljwsoSvKzH+nzJsi7nOTBNI9M0S8BOZcBnFLEyAY3WXHUt1hiuNj2bvuXqesvuaoP3HmM0vXfcPLtGGc3bV++YxomUE+dxoKRUe2vFYS+DUq0VKszktkHX8JCnny+nzGG/ZzqPtF2P0vJzp9OZFBNt01YQS+qrs5PzIINeqeGE5f/knCkJPPrAi1B9CHz9Y0CwddCSEj/44Us++f4zzmOQlrwoprGgkgzkQ4z85bsHfv3r1/zwe5/ywx98wicvn1d849vHd9WzUleP48Tf/fJL/uS//QVv3x05nEZsBZ37znN9eyX3pRVv3sY5msZjG+k1lo+VktTBpRSm6e8LW7gcv9NAGEjzMs1ZLrwDalM6TRPjODEMM8O4SHYM3sEUxB+i5FSbtyeT8SIpMRnqVFqt0/kpRN7tz7y9Pwn76zRxHieGSjl1znCYBkyj6TYyHSgsuv2aNBcSakkTc7YCBuKrVXKH1q4CLbJIUkTQ9soeCll8dCSBTTxMYsyEOXI+B2KUBRxjRpmCqeyFeUrEmJiniLGFFDJN72i2HuuWBDQFSCKQNgqTqwm7xPCIvM5YlDEsMcSuc6ggD4zlAWtqjHQhU5RMPpVW+KbF6AmtFDlAnAu6Ec+NaYz185YVJJBzF4W5ljJzSJIoVzTTSVKAxOy9phOqys4x4CqoY6z8fuUccRqJMTKOgTxnbKuJodD3Mq1RSYot7zTeepEFVNqvsaaCIzPtpufd6wdiyOSoOI0BhcbYgjby+WO8MCAWQMRpg1WWrGQCP01TneYsNOEoLJBYmTPOoFItUowEI8QcsE0jCZdtS985UoSUa+JXUmhjiTkzx4CzQre1TlIYQyoyQsrQdR2n44h14qEXpsg8RObREWbx3DNOga2sv6IoyZBTEVDKGVyGcTwJOEqWIlVruq0kUoY5Mg4jusjEyiiRY7Zdi/OW0/HENFlKaVCqsN20Mr3PhTGKr4pzYthvrMI4Q9M2DKeBpTA4jxNzigJsjhawZGtZUkSMtlibRT6nZYSmtDxgYjyRSmYcI9YYVAoSMKA1GCkMJEWooMqFwdU0jutbkSq3Wy/G2EYTppmuMQzHmRQy1iiUlntRGU1KEM6KkqUQVgYiMM6yduMk/kRtK0mDy708TJF4SpzOM3MNIpjmzNW1pWRNiJFxSGifud40aKvXojPHwukwEuaZtne0W0dOitNp4vrWAwqNrMFcMnOMlfGZ5H7wFuUkkVYi0hMxCOPMug0EKptVMc8G44XhZpWAoKJSkbWxpDLlnLFKrWai85RIVfqwTFQpF+jmEoe9AGLCFguhsoyUwnmDcwrnTAVwLVYbQNcEyFw9rZTIHSmr783T/X957c22q4y1OtFevM5q5bH4NI3TKH5hxqEqu8G3njDHWsAq5jmhlHj25QBWGzZO/B5KzDSbTrwqnCdhZdZaX3cpdJaocK3loZ+fpBkdzmfO0yjTXG1o/DKUqGln+eKpI8WEXb3D4CI1cfU9Oev45JOPSQnGP/1zXr16xf/4y79ks9nys7/9W+ZpqvLKyOFw4u3bdzjXonPmeD7Qb7erhFRXeVAuCaWkkY9JprCLRMK7p5T6CnQCp/PIm/f3/PLLb/jrv33Fm/sjTdtwd3fF85sdz7dWzOxzIiZ4u08MQyRk8E6u1VxTSbUWtmeKkZwiGcV51pwOZ+J8ZlIzfuvpes9iM7rUBipJDZArk8soYYU5a4ghMY6R85DwXmSExhpK1sL824DdWna+xSRNTBFvJNXqPAzSzCnF4/mBaZrYbrYXhlAxbPoOZ6WoDLVh7BrHzdU1KcfKSoGrqy13d9cUDI1v+OTTT3n953/JX/z5X3Bzc8vnn39O27Z8+umn7B8f+Yu/+Avev3/Hs2d3bDc9+9NRTNybltdvH7G6MCPSwFwCCUPMZq1lU7lMXrUx/OD7H/P973/6D7KbFIqihb1tnCFVlNIbAXaXZaC15ubmhhAjTdNgtKQtdm3P97/3A7q25bS/Zzg84p54p6TKTnnygmhjxMfOeTEPXy6wMmJ1oUXmfmk2ayNpLFZZoGGRFZcsg6tps2EcBlKIaCM2Gs5aUs58+eXX3N3syN3EOI3EMtM6Ye9bCmWeUAq8bfGuBWXQtdErT5qFC+HnAj3klJnnmWGcuH848fB45ngaBSB9tuX5y2ecpzMhBd7ev8ORyZWV5qxBK0PnG7q2RaEIcWacRh73jzy7vZNhChUMzDW5rw6AeBK8sTJJFylibbJT3ZdFVlmbnSfNV0ITioJUVlmea/w65DJRwmSuNhu6tlmb5VKlTHJdZG+JuVSw7dIOmrI05pd9m1JWE/epSHMfo/i6dX1P03bV5+ryPsdx5t27Az/75WvO41Tfh0g3hWwqig1DZE7CNlEKYoqUVNifT+SSOY5nOteQS5R75unCRFEwNZQjstt1FFXw3vMUbspzpujl7pE6RAy/6zop4uWmkfPPkgRqHOvcqAhT7inDS9daXxFXf+Dl3KGkRo3lclaUFmWKWt/HJQRG1A/rExqvPUVdjMpF7g2SPXZ55ppq96LqPW+spDg2TYNxRhiMWtN6T+P9h8wjVSAX4jASUyE5y+N4FiCihpv+8ldfAoW7Z7fM08zzu2uMdRSrefb8OZvNhpQTL56/wDvPDz//nOvrayiw3+/54ssviSnx/MUL8cxtxNpgngOvvv6at+/ecj53dH3H4/7Adrtlvz/w7G6LVoVtJ88o3VjM1uC7hlzg3f2Zr79+wxdfvudhP/LxR3f83a++4cXzK+LzRN81UotaCSv7dlKoKgW9BP/kxbheGFDn83nZQegaT996DqcHSavPUjd479lstnRtS5gju03PpnPsjwlvNCnLQF2hSDFSbW3rdVvkbZe93ihFrvXOlAqNvQx5FmufDwIRFrr/bzm0gt12w3kYmHIdQK17/FLTXAYzwgpbhrnibzVNE9M8Mc9zDbCqNZWqwXPO0npP1zZs+w7v5e8vnt/R9s26zygF266h9Q6Mpt90MgyZZpyz3D274etXr3+DnaXmIH1UK4txIbQsf9qmxRmHc76ydgutbxnHEVOHRqXI9T2ejgyDJpMqO1ZjlGYYJ87DiLGGq21P01i6tqWtAJrR0qf8Q0dKMlx5+v6bfsM//cPfZ384c//wyPE88cXX7xjnGWct037mYb8n58x4HdAodruWu5vddwBhv3m9F8abkIRCXZct2y189tn3hH2bDV3X07ZurS28NdgizEZnrQDktZZcrn0ppcrI/+Hjdx4IOw8DcZY47KZpBGCYJ07DwDBOhDmK6WWpfgZllod5vtCSF88SqBPLVO3+6hRHUHIByM7jzP3Dma/f7dmfRklQU3KBvRYJTNM6nDcIX0sWVKw+R/MU2WxbFJqm9ZRS6PteZEwh4kLEd4bGWQG4ciJkebi5ivKnnPBVPhMzTGMgRdFJT2OQmPgCYZLmOMVMisLEykkSenznKrtYQB5jjERSa2kYtDFiRE2uyZEi25qrhGmZ8EmTKgQobY2YSCPNhjYKp8XMr+RCSQlXqV/agoojc9jifWacQt0YVS2iBECTgEVppmMsNK1jHGf6TcP948Q8RrpW0zaGGIWNJ7RygzF5LUx09d5JcyRGeR1jJPGy5Fy9qUTy5a1hDlU7rhTK2Pq9Bk3m/tWB0yHweH/mfIwycFOeXBK2keIuxSVpSZpO5wxWGeYhyrS6TCKdWhYIhettwzwmpiHQdpauL5yPQRhCjSETV4N5oxUx12AILUBHRON7oYiXZQyqxZcjB6mEckyEUQo1AREuk0plKsvhHCsDxlSzZzF+LsjnMlVmqIyhaXuKCVjfMp5P1eBUc3WzpWwyj/ePAMJAiwKApLo+G+/QWkDMh4czjXf0m4Z5ipyPE6GyxbQReak1ijBFMa1tPEvs9jzNbKofWkiROWZIM4uPUwyS2jPNkpTY95YwL/Hr0n5IMIZhc90RwizNSFEraC1TFs2uswzDgFJaAJ5ayPkqm40TpBy5uunwLlZwJ2OcXMOHd2ek+JVpbIkC8MRcmwwAJfLpkGA8BnIqFRTLhKkQ5oKrMiWFZQ5Zpl0xcfe8od+2WOd5eHvkeJxkAhuhYPEbj29bwjgzByDXJkULkJlTZkqVUeps3f8U2tV0WDJkmbiSMpOT4l9X0FAruZeaxtK0FmOFcRHmyHie5d6u+8fiYZJClYlREai69y7MPfSFCi57NPWhlzg8Hri67pmGiDadMMCMEjme0uSs1u9PKRNjrgCkpMAJ6PZ0ul0wprJ1lchBdZ2+fTgFF7ZnDAL0WiceftpaSlEY68hZ0yhVU//EK9BoMfXtTYe3Bm8tjXd0XVebfZlyd41I7xaW8fLBZUCiWRKvQpb1MYwDk5icYY0lNo7WWimdS2L1ZZAtAftkol4Qev75fOb5yzvpMZTC+wbfNGhrubnt+KM/+iN++KPP+af/7J+x3++5v3/Pmzdv+eu//ilff/2KthUjYe8MYZ5XmWWl64kMJ6eV5bkUrkopPv3kE3bb3XJ2ASmU94cz794/ig8NitMQpBGxGuUatp3IXUKYeTzOKK1IGYn3RrxAUmV0pxgJEZxK5HHg/fu3DMN7dI5McaS0BWcUp+OBvnWVbeAFWC0wTZLG6p3GNRprFdutYzhPlRUhE9qUMuMY6jMasBntLLmZGNQDOkPPrjaGwno5DQPv3j2w6XtiEIPetiYPP2V9JDFFoms8m85yGhPjPNJ5R4yB3W5D1/YUpWkaMUP/8ssv+V//83/mm6+/5u7ZM3LOfPPNN/z1X/0Vfd/xwx/+gLYRYOTm+orDIfDy2TWvXr8jRgFBlCrY6p8XEfl2KZI6apxh2zcYY7m6ulrrqN96PJlQGydgrE6J7/K3Xe5PYyy5et8ZY+j7LdZajn3DN3HkdDpAySJjnMcPGhKF/LytYNgKbirF8qKLn+dT2cn683qR6D7ZI6zFeU+33RFnMWBumwatDe/fv5NUzk3LQx202OpJqJWicVbWBjwxbpb98JIYtoA/T9+IvIkQZs6nM4fDicf9kWGYMMay3Tbc3F4zxonzNLDtNvI+vMVZLcb4Udiz3pkqK9KMY651iiHGgFGXtMtlV4ZL+iVUhUBVSxRBGsXXVtVUvWXL4imbRX6b0pLUSk6Q4wfn3FrFbtNJAE7f4r0VVnYp4rVZan2qjdRZTwKcLhim2IosX7NGzv2FhUW9TxNt29L1HdZ5clmtowkxcTwN3B/PHCcxzl8T6JQAM87qFTCfk9QlKPBeoxsBao7DyMub7omUXvbjUpnCGl0bOcM8B5wXZqDztp4rzcrgLRI8JCqC5eyuqxJFISRhWxuowJ2sJVVrisvPyL+p2pw+/Yo1Bu8dV9uGV/cnxjmsp1YrjVHVx3iRtimxNTFG0VhDSDI0XAYJi6+m1mqV/C33UalAawiRXS/DoJACvvc0ysjQVmmRGVoJq8FokSjXIVWpjHDTetquZ3g9sd+PUGA4D+uw7PWbd+SUZc/70af88Peu0NqInyWK4/HIMAx8+vGnPHv2DAp8+fVXvHrzmvNhQinN7c0NTdtirGMcB06Hju12x3g+8+7tA9/77Pu8efOKX/zyFxhTuLna8ZMffsTHH7+gbVpsfZ5O88zxeOYXX3zDT//2zcq67buGeQpoY5hCkp7DfihF/eCaF6kvV4CpFGJMvH17zw9/8MOVcdP0HeOvR8ZxXD0ZjZE9oPGextn1mXNUA7ruSeM0cTyf6fruwzpp8eOqiofFq3vFeIpYsK1zRq1WSwxQ63P/6bFAWuuaLYXGOY7HQWqv9duX+oD1sy9DzhhrAFId0s2z3C/S/hTaxkOpqfTW0viGrmtpG1cTGDWbTYd3dr2fQdFaS+cc0zRjGodvHF3fElPi/fsHdBEyzv44rOBlzgWdC+Mk+ERVTq77lELhnKdtZHC1goptZvRVOVBlmyknUIVEqlhFqb7dstd1XVOZhD2Nl8Cvxi1ySLnX/75DCBiJ8UkQhgJud1fcbHZM45e8f//Iu/ePfPXqgWEOhCT+bFpnbncWY2ZinJjCJAPzOIv38lLHk/m2bHYZlpbq9fbu/pF39wc2mx0vX9wBBWccL57fsOtarJNBk1NV1F2EYHN7c8N5nBmmgMoFVSTVVH2Lgfbbjt95IEwroWHmlBmGQRrflIS1gjz8jTVC4Y9JQJEgU2oBusRMcUElY4xy8epGr5TCVPP4MUaO08TDaeBwnmpam2IukzAF4rIgnQAsSOpgysLEiSGtDw5rjVBWvSP2idN5kHSx4rBeYRtFSQqnDGEudbJW78ssYIPW8p5DTMRJzI9jyNVvR6QAOQlarrV4GxWrsU46MrGNqJ/RGLS2ywhvneI9rS9MTdB7OlHKMa/Am26eSpCojXE11Aem80TjDdbKRmgcaJ3Y7yNf/fqRrpfUvFR3UOvEPDmljO8aYSmFJEaWSvzQpilyvetoGs00iQ+XUgq1GHxnSW4rSRgk+4exTtNkmtf1MuEJ00yeB1TrKMqAEuAz5ow2dfpQNIfHM4dqgnx8nKvcQkytn988xzWKh/d7SUarCPUCBIQSKVXxuUwmjFYiB02JMGesVRUASpwOE/OU2TihyisUcY68++YoQEvj2WxaXn3zyOPhTL/dYp14SbmUcdlgrCXnwjzMEo4QK6uuLqZu2+KmmX0QhpV44mSULux2LZurDowma5HHxSwN5cP7E/1dg7EOb6RAsU7uG20ui0bpC+un7Vuok5sUZrzXNJ3ntD/RvxB9+dI8no4Txmo23lX2mYYsbKTxNNVUqYhSBq2gaQxt13IaRmJO6/Q3hkSYJBkwBFk/XSdyihgLfWtqc6XWaSdFMQdhWZCVeNNYmcR7ZzgdohQrGqYpYMyGC4AjE+N+6yipEKPGNw6lC8NpglITI8vFsLPkSNEecllTKmWaLVO58xjJ78+ULIC6sTKa09rw9u2ZUhSn40TTWza7lmbryEFVIEDMLQvUAqFGaCtD2wrrseRCzsv9LRLGeU6UIsWns078Cowi5yggbynkkMjd8pAV0N84SdtxTvzBUIp5CozVPHYp4u1a3Kk1bctYTckyCQ5J9lZVpXqrWfwCkNVznVPifBpJCXxMlCJDC/9BwV0ZvXOQorgoVBFGo3VCq5Y0y0gpQt93jVnf02L+uxR861GLxbZr8d7L7zECOpeU0Szx1HKtrNGopHCz5tmzXq5NkVAWX4MMFAvrTuQUmcW74rK3prQYvYtsPoaIQrzXSqmJeSWCUuQ4QEpoRO6gvTDBtJIEV+9FWj2OYwWoS5VTCBBb5EMTYuR0PpFS4vnzZ3z80UcyvImB3W7H3/zsb1lGSykVQhylWbZWJtbVlDZFkZY9NTq+u7vm9uauemKwRs6lnBnnSKxsbAExYRgD45RAiQ9l33iMbnj3OIvHp5J7NkYBNrwTj7hcxA9qHmbG85nD6YhKmaISkz5z1V2x23RwjtVkupBSRGth+6QozWxV9bKEIkgTLoV9GDPnWtAqDd5bmkZA1+AjoQSO44k03/Pi7gWt0aQY6/PjjrZtxBvR+epBIsEGS4qe/GJpKK92HXNKhHBGFcscBAj23vH67T1ffvU1m+2Oz+6eMc8zf/XXf8Vuu6NpW968ec3huOf3f+9HfPLxxziEyQaaGN7x+HhgmgOLzGWRdllnsMgATmtN4x25wO3tDS+ev6SkyFdffYVzjru7u7URW+8bdfmzAMvGGXT57ZNbvQBRhdUGQGtN27Zoc8Nhf80cZlCax/v3q+coVHaZ0ehFal1NtU1lqVIu8uCccw0FWfqfpeB6AtBzAa20qvujqzJkJYnf87yAtZa+3bLtPVrVlKyuq8EdC7gpQ5DvEpF811FKZp4nHh8euX/3yOFwWr1au74FrTgNEpzgnKNrOrxDLCiygLmL7Ms5u3ofGm0wfmFOXZiQhWXP+9aAov7LysBA0sALQK5yupJrSuuH8l+tpAnV6hJGZY1GUeh8g1KG3W4jrN11BiDryBpbmblGGGdJrlYpmTQHrK8puUpYODEvgUWLpJ1VYVBKoakSUa2oskO52jEm9sczpyEQiybiUIQVSEOJrNVaXQcuVapPreuMRpHwFfRorJMUy7z4xmo0hqKESSMsp5mYAsM8Sk2txFu0lIJCV6l/rW/X9XAxHc9FEaIMSpblJeqWKsmsdbNi8a1d1vSFFADCgvTOM4zisWart1cRyjiodAHCKKgiycOdM2waS0YxToHW155CL4Opes8vA8qUGONcwb3E8XBm2zd8/MkzUgn4psH7Fmelh1Na0pQLRUKYlLhUKUA5j2latHM0rRAi3t+L5cdyhFkko0or7m5v+f3f/yds+h3zPPHN61f8+otfC5GhaWgbkUE2bUPTNOTHPTElAZS9wzhPLllSsZ3h7vlzdv2W3WbH/v4db9+/ZwEnp/AMUISYMa08n+Y5sj8MvH84c78/i4XHW/j0o1v67UbsQlpPTlKDNI3DnDX5yeepfCGe7k0FmOaZ8zCstdKyVyotid2pmrELKO9ovWcPeKfpW2FE5VBACdh8OJ1ZGQ/LPazNpU/UF+sceU+qrkfQNWgmFoW3dXCP1GT6yTqWMqPeoAvMq6DksP5dpIB5BeQvtkV5Bb3kT018VTKwl2G1BM1suxZjNI0TM3nnHMY6Scit9WjXNFLbVbJrUdA4IyqjIgob3WlSSIRx5DwMDK3HGsubt4/0fUvXetrWYbRjHEY2fYdelA7rZ754+K0+bHID0pBJQfZ7VwTUnuYRat1mja0BK4vPmtwTXZW7u2rTcVkV+YPXzpXlu/Tqix9tKZdv6r3HVya6QvHN12+53x95/3BmmBKxZIxV3Ow8V7ueZ882PL/d0HgZiKuSL/uldPKgpE4qSq2fX84BtI1nt9vw2fc+put67m52bLqWbd+yrcMRpRSJUsMERdV0++w5cdrQHs/sT2eOp7Oss4XQ9I84fqeBsIJQ3g3iJRSjIKgFYbZo50RalKOY46m80qy1rp4MStJfFJLklrIsmpwr3lQX0Rwjj+eRd6cj96eBKUa0VTivxPxQLTr1pflijWDPWVhZ85xw1pBipmvFv6ZtGs7nkSnOTFOQIsSC9gqbNT5rUlFMUySHhJjRiQ9VrqyfXKWRKzIexQw5J2HfKK3Q1tBuPdqZdRKqqI23XmiWhqRkA1spuEW0/VGB82ZND5Fm4zLVf7ofLzeZVTLtKlpVOUrifApc37RYp8nFYC3c348cziOp+GqOWVOPikT0Wm8Ic6oabzmHbWtXVsZ5DEyzYk5lbaDb2uDmnHh8mFAmMk/SUDSdFFi+8WjriKlg6ntVSlPQ61qIMaNzrABJ5nyUIiUOM0pl2s7gvCanQtMpSWRqND4Z5qmaGQZ5GAhxcJF8ClCXi6S0CftEwAFl1MqakDVmQBViLJwOMykVnGtISQrORYqwEKdtI5/P1mZlPM8cH874xkkqXZT1LMwyAVv6raPLQs3NJdO2ht3O03aWrDVzKsxj4LQXFt40RNq7mspT17hZHyaQlUyZm8ZXg9Oy+tbEMDONGrRid70hTIE4RXTXkhLkKE29sRljNN7ZVV6XQmI4TTStg8ZSShJPKFvY9oYpaOZpRhW9Nj0xFeaQmOZUGxBd7+9MiHLNmtYyeUuofiM5i49WyZmchL2Wc+G4HygFxvNIrgaw0jTL2jdW44shaWhai03gGitGsGVCOuhcJXkFlVUN6Kg/L7cmiyQUNOdhZhoSMdRpfmMoHbx9e66UYmlGXKPwrcN6S8i5etpJEVo0xDSLfn4KOGe5vunWCX+phY4xmnFcUs60FCxorJLUReUbxkkAApULJQe0qgwxpPkSmaw0/wISRHIqdQ8QOrM2BmPNylCI8eIpk0smx4R1zeozpjTrQ/8CcGWckwJZZzHenqdqqF+CJMWay/cunkTSxwjQLs2M3PfTMFGyFE3ayj0oTZv4dj2tJLRSGKvEN2/jKVhyFnZiBqxZQM1aiDpLaz0eS6useIPNI7GIF56ptPlSxBD4FGVDldReUIvfSk2Ay5VJUYowXhtrcBhSkSmtqW+3pBlylohzBVhTwWPx1GzanmkcGE5nAWGMJsVACopU3MoieP3qFf/pP/0n/vRP/wzrPNvtjs9/+EP+8I/+kJubG0lprM1SiEHYd9W3JC8gWAViwxzWYlYpxWbToZSRIAcFZJGsTyEwzwJij5N4Nm53vfjRVXBlCBkfxOIgVvD40iQKuCvNrl+NZaecGKeR0+lE32lySJjeUFTGeoUPkqwqw8xE3So/KNwE0BfTdJFJKuI4kxPMi4+NkTWyhKSktCS0JU5h4GMnARryTIW+bS5ga9EV9FHV66qybCo7wnsBMZtmRJvM/vzAXbqRh7CCr75+xf3DI3/4R3/M9z/7jG+++Zppmvjkk0+42l3x1dd3/Pmf/XemcUKj2XQ9Hz1/Qdt0GCXT8OU+izExh1i9fOowDBl0ta00jNvtjmEq/Jf/9b+REAbrJ5+8xDnPdrdh03fSzFmDMvU5pyW1Os0jznb/YL2nzZLGuhwKpRvazQZ92APCJk/TuCZMium7oeiu/oSAu5nqL6gEcBC8TEuKthbWiVyLOsleGoQPOpla8hiE2VUb0xACRhv6vufZjcIvxBaE2/eb5I4P9xUZlH1rgl8yZMT3bX/gzZt3vH37jvEsgHPTetrOMwbxrTHa0DUdL5+9ROWRnCamQYCcBbxTWiwuyGUFq9ahaP2cv2Fo/eT9r80oUJSuc52nhu4fni75e30NrbHGULwMtxbVgEECRXZXm5oCfAHdqKCsSK2ldlqYsWpp+qvVSUipArtL81zW+jRU4+xSMk1jsRpI85osK58783A483A8k7KiKINSNT29KkEFCBCwR1fw22hVvw8a13C1EVBD1aH1mmxX/3eRPaUiA+1EYGt62kZkwBT5HmsMIUriXdM29EVxHAZRpFQ/vJylmZXzLCCMUVBSxJQs61hnki4fePM9PbSq9Vb1tfXK0NSUxeVa6jo0XJQjSisM0mvctIbzHBlPE3OOTKEQUWQtHqI5SQfb1MT6w+Eo4KCSvuI0ZrTTXG1vMNqy7TfrECikIJ78CFvdWoMqhfN5Yk7wbLMl5UTX92y3G/b7I10nPksxxvWZv9n0dF3Lbrfj2d0LpmniNJwlodqolTEF4L2rPptlVYXknFE507YdV9e3NO1rbnbXkqAZAr6G5XRNh6J6PCmN8XLPCVykQTmKEoZLoa6Pothue6mPjKiK7Aegxgd3E0/3juWYQiSGsN63sj9c/AAXpqRWag2mKqXgjBXrG6VRukEbTyqK8zDKvlU93ZY6bV0PemGzfvhuZC+Q9VkFzTXgSoAVGbg9+SQK1FMmr4E4jxV8X+7LxLz6fEk/L+tefMDmOjiT8A1hyeo6OGobYb45Z+gbT9c0Mnysg1bZLXRlkC4fYkkL12QlxBYNNN4yW8MQAo/zROMsL25vmabAu/s9t9dbXjy/wi+BXzFgneWDgIEnR05pPb+lFKyxkAPL6TDAMEoN5XpH27Z469BkFkk6gK/s0qeJmd/9eh8GMeWy+LXJz/Xe07rLeGYYRoZxYo6Fj1/e8erdHq01d3cbPn5xzWef3PC9j24kCbXb1GtcT2Cp/62AhbKLH6auYJmAol3b8Nn3PuZqcwVFselbtpuWxrl1AAByj6asSSXTtS2+bZmGBoOszWGcCN9+8PwDx+80ECYeOHXKAlCRRgpr6kooiZJkg7daUu9sZThIuhc1jUPSxGLKwh6JkhYZU6kpTSPHaeDd45HjNIIrdK0DU9ggXguqsDJqpHDWa0KGNABRkOd6YzsvyWZzEoN07WTCtCC8WoEx4FQhlkSYIso4kXjMEa0kjW3xDNBKEUP12dG6Fo0iK7Te4lpPs/E1yUUMi0WPr9fJ3AIuLTeGIqGSIVdmkfguiZyyhFJNs5crIn+X4ZPEKSdkM0wxEOfA8TCy2Th2Vz1TDhyOM6ezeBfFKn8x1lRfhzrdMqY+8KUxdAiTYxwkKel4ksar3XTCeFAK37X4xjIOE+eTTNpSlMJHimTxJ5lm8c/YeItvW4xzFCWxxaBWtqAkwMimaRvPaf+A71u2VxucF0DEbzLTHFEOXCMa9DwJUFmeFGKlbgwxZUJKuGzFu6kzKJVQCmzj2FXmT9NZtBYwNIbM9qqj30jy4/E4gFK0XSNPksUDCwERF7PvMEdSyDhvmKdQp/1AlXBud467uw3DWbwwNjuPteI3oIyFVAhD5PgwcDxMOG+JEWEaIg8oisJ6MRsvStZcmxvCpFZwx1rNOIhHn+s8V1c981kmgtZYxnFmOE3i8WSFgeAbW+V4uUp1Lql/WiusNuJ9EWe81ewPUUAWkgBrqQjLLmUxnF82ZiUx7xS5F/vOMRlFjBL8gJI9ICXx2IOJocj0upRMRNH2Tu5BK3IE64RdpCPorSNFYVvNSUBsAZhKNemXh0VOIjVQWs6TtXLfpSiG7WnOpKAIc53eBGFlTSHTtZbTOWC9QZmCrn5wJUVcY+Ck1vOFqbB+Sri+oWlFjh3mXAv4Ol2roGrtcAQYTAXbSBER0kDrLa44UAml5Rzpyn4yS3FcjWytjqgsACflMoRYvBfWNKl6XeZ5FkavEhN96w1KXzyulkMhjBtjLVGV6muXqhk7aO3wuqxF2iXZVvZHY80F3NCKlCJpzmSb1/WhdE3ItAWlxLxeIXJHazXeaUlnDZppiOSYcFYmdtbK2my9oXeeTdNy1bbklNgfDrLubDXzr81cTjMxxw8+Z4x5ZeFJgyNNjXdS5HkrwEUu1V3I6MqwqOu8PEn1ZWmS5BygpCiKIbDb9milCEHCTwKFw/EgHps5cdgfeffunmESKdarV6/YXe2kSQkRxyVZEaThFPlL/uC/OX+YhOmcY7PZYrywaHJMzCFzPD8yTsL6bNuW29vM1Q04L3JIRSYqzzEI8Bcra9pavTJCrbVoLebpIQRSDJQUmeeJaZppmpbD4cD1tkOZWpgrxTQnac7MRcbhnMZoVSe30vDHmAQIs5aSB5bmVhlN21r6ztEuA4iSGOaRXd/yybOXAuZR0NriDReT66JW5pO8di0qi6xL7yxd57FOJG9d65hjfU8lkmLk/ft7mqbh+599Rs4Z7zyffvIpH3/8MdZabm9v+ebrr3j11ZeMw5ltt6FvJRbeGvjkxQ2H45kQM6dhZJ4D4zwzzYGUIiEKY1ppgzVgTObh8Z6f/+ILrm92aO346c9/iXOeZ3c77m6v2G57+r6lbRuM8yLdNIrGJOz19jtrvPUo4n+k9FP2g4Kkcb7BNA0g173ECVTGOGkIxA/GSPO5/uzl9z59DapsTZcLi+mpTxfrgPvia3T5R/nGWEGW7XbDpks4zQqelpzkz/qy9Tn2rbr96dsScDgBkfF05M3rN3z19Wvu7/fklNnuerZXGzFqng5ybxtD3224vb7jfHzLEMcKqF5knVqbaoZ/aWAv6gC1ytbSB3tHBXu0IsbqybI25MJaf3qSl0dt1Vqtr7H8sfbCSstJpH+bqw1938nzEPm+nC/i7rKenwsrBMC4xUNGvMQWSWyuoSOp0r1Szhit6dtW9t4cIeUPRDRziLzfHzkME6nI57XW4pyu8n+5D5vGVWmTwTmp171FGuOb57Re2EkxxRVMupwhSUhMORODSDmNE4bsdrupTOa0lHR1SKO5vdmx3SaaR2HEhhhX65PTpkUhjJ8YQw0LkVo8xExKFZTDrIOIxRjbaI0zDqMtGhGHGOPlGVX9iF0dYBkjQ89MEUuHFAmIND+EQAyROWfmKGmH2WTx0csZZzReS/L79mon+7l13NxuUVpz9+yGly+er6zGlBKnwwlSwTiD974qfcRj+fxw4nQOvPjY4Jzl5QuRIW62Wx4eHp9IZMUgvu9blBaPQ2UUtrFc31yxu9ry/uGBYRxWjMk3Ht94UpjFKsQ1CLia8L7h2fMXPN7f89Wvfo2vjBVdxD+yazucM2sgkG9bTA14A4O1vno/XkD2pvVc3+zwzq73indOwLlv9/YVkS0lrtdR6rvM/cMjSzpkQdKgSylMo/gkUxlhS6CQ1jJcEblxZfAZK96z40SrxXdZa70OQ5ba7fJ+LgMB2cPKJTyh3lPK2XqPyjPVqG/PFpa9ppASHE8DKRuWAIt5DkzzVINLch10V0ZYCLXWFV/bxlue13NZEF9WlDCn2sbRNsJ8tNZSqNhBBV1NDS3SVdKZKcw5Y7XGxEjrGpwRVtjxfMI7y/c/ecmzZ9f81c9+QYwzm41j0zY0raSSOu9XNcdlP5X/n0rCFINCsAFtDSUb1uTjcvHak3MqRBurBExKOROSBB4tdgJr8Ms6uLic5+W8fdvTDAqd93TuNznKz5/d8Oyl49mzG169fcR5w8vn1zy/u+L53Zbbqw2bzuOMWcLfnxylMotk+K+qzYpkqhQBihXc7Hp6V+WrVSnx7UMuk0IZg6m+uZTMdBY7k0Vpkp+svX/o+J0GwmIMzEYaSxTV96X6f5VlLxO00WqL0fKwkxhrU783V4P8wuk8cxpEZzqMkWEKQq+OhdM0YoziYT9SdKG/cmx7kSYYY6r0VWjP+clUbEWy04XOuVA8jdFkHXFe41pbQbLK7hmlvMgxVXCp/u4YCCExHAe0kiZfaUXTChCSc6lTsQJF4RoHqqCdUJRdI9TyOEfxvqlgWa6y0FKLi4yAWAaNNhZrG0pJLJxEVcQIOK70R0HKVQXhshYT3HEamSfZuKZxZjhH4iyTtVIUb9+cOI0B7wxzEkZf17U4Jx4J5Mw0Jqx3KF2Nq2siZe3xEM2PUIi9bzAaoaUai7EF7wNlmilKEYJhSeq6JMMpVNH0xoOSiQ9KCahRJzESHS/a8DiP8m+uYbPt8K2kDG62jchT44GUC63W4pczJebxklayrExRxwmPq+2dgHQmYJzI6VxjRaqrBenPsawP8cPhjNGFcRRquXi8qZWFstTmOWXiHGV9qsJ5mEihnn8Kp/2MtmB04sXzKwEuntD9Jf0po5LGFIMuWgIcSAz7idyKX13lQMj5iUVoqWuhJdNOyFzv+np+5T5ovUg0sLq+JwFicslYa2k7Lz4hY5R00gr6LfP3tnHMc2Y4J1AjTb8REDwXUhRJco7SRPm63oXJGIURWIE0SsI6UNZSsiGGOqFNkKbEfBqZRvCtIwJNJ2bwAPMY0K2n2ILCYI3FaSiuMI1JAPYoD3aUxnpLCaWaTV82CY0sDaXkQXU+TRIEEcsKbOYsg5VpEog5zEJBVq0keRpncV5kmcZpUIU5zpIE10ih6KwVgLRyYcX/zNd7YiamVKdF8q7EzymKf5UW9mLXOjq7YcgH4jLl1hCmhGo9zovp7bL/Lt3L8uBXXIBA2Tmr6qKUKj+r8k8jgBUIkPrBocD3HpU1iuo7VUEjsiI4YbatybkVjNbqUvwtIFgVLDMOY2XzXLwvjFZiqE2qU8/lHqkDlJgpWWFQdE7o9toaWu+4bj13uw19K0a/jTW8e/8AQN+23Oyu6NsWqxTEKNqvJ4PeJSxh8clRSqR5ziiRWGnZJ0upfpIxgZbzqOqJfQpOLSdOmGqGqYJc1jn6Tbc2bTGNnKbMq1evmaaZH//49/nR5z8SQOx4Yp5nbm9uef78Ge/fv5f1WyfvC4ukVGDnwuKrG/aTYllrzW7b8+KjF2JkrjU5iSzzPM4kFH2/4Zm2mM4zheobqBSUjLINcy6onOpATPaEtVlWiilE0piIIRDmkWk8M4dZkq2KIWgxud9u2lr8aj5MCJWz5qwCK+sh1891Hka0ksGNc66G4mSstnhn6FonDAtV5Qdp5G5n+eOf/IjTaWYcR0qKaBTjPIn/5npH1Kl6TnXqS/U1sZJS1nXsj3vapiGmKOwzqgw1RLqux1nLw8MDXd/Rdi1ffPEF0zTx4x//mM1mK81EiuSyJG9rbnYdm/aWUjLTnBimiZwzY4gM48g0zwzjzPF85nQeoSSMLoS0582br3n33kvDqAWc2m48u62wXNrOcrXd0PYbjIbbmy0/+sEnfHb9Mf/Q8RSwqbc/Cgl2aJuOcZIBSo6SjP0t3Lz+0HdMipfmIsf13sg5X6Qn+dv7jhThv+2YZwkS2Wy3GPWIrUOBpbmLTyb4SkmqmzSYi8B8eQY8+aVZZNuH/Z6vv37N69fvGIaJZtNxdbWj2zQ8Hh4JMWAr8CbsXM9jiEzjRAihDg88zjcoY8U2grIOUoEqXxJLj7VcqedyYVdoDUEvX3zCVql7va6pjesDbf3yIpVd9vOEUrkyrzPDMNJVOZqAjRe2xnoqcmFJpVzu8acg21JnL+dca+kVMmFtzL13YuZdioQaWffB2no4nHjYH4VVncA3mqYx9K3BaoWziu2mYbtpcVbhjAK1pGxrdn3PR7d3K5tJZV0T6Vn/LNWfIq1gY9u07DZbMcsvNZxDyZ5sreXm5gqQ17neNtX3Uhj3IQS2nWG/P5BzZg5yP4Qg/sHnUZLzUkwrm4baXE9TQCvDtm8xxnK96zhPkRcv75inkVxrEmsdRVtSvQ4hiXeRWAR0oDX9zuG7K5IW0+5SCsYL4KDQNShJWB5N48VKRlGZvkpARi9Ss5QloXX/uKdQ6Lue7W5L03hKgYe0J2aRXBmj2PQbvN9xe3fD1fUV5/NAjJHttsM5qacf7h/qGslgpXFuWs9mt+WXX3zBMA415IuaZNoQ57naucigPOXENIslTtv1/N3P/5arm2s67/lkt5HEP8TmYZxHkK2EnKlekqxD1mXdKiV93HazBSqQWTJN69G6rEDq2ttXUoLYvEiNszw73r57f2H7IECYMZZxHOs+UGvKyi5eQj4WKEqAN5EWjtPMdtdJeJe6qAdk7i73Xrksakx9V6moCuDIcXnfstcpLaFA4pn3FJCpA9+UOY5BWHh1rc6zPDMF9LoQNkoWSW/jNd5a+q7BaMV20+Gde/I7U5U5GhZZ55o+akwNgiurxcBajxexR0JrVIqUqFcLiRjF2iilzItn1+SSeNjvGYZrwkbsOPankbbpcFUivHgNwlL7lpWJuNSk1mpiovbbWXxk6daeVOq2yv7KiqQK2hqyVvWcXKxR3JOaEkRGnQtPACuRtDqj6b3n28fL53f8wU9+xNX1Fm00P/zsI5rG0vd+lfqbSqhRCqwqSJKweXLxy+WVyqJfqmCYyAlQRQYJkooOuQ6FL8FOtVZXUKq6R86ZgMLDNNe1qS/f/o84fqeBsHGchYnjzNpwZSU3cS5FpnqwpsEU6Y+wVj72YtxdMgzjzON+4P7xzONx5PEwMwVBWOeQSCphtRgY+t5wc7eRqSYstkBrmlAIgUJNb6yGvbkiuKlO4BY/Cu9FnnNXNhz2g/gwpch8nNciPD9BbmWqXiUeU0ApvXppAThXaR9KgLCilUhlFgmR0fhGGuFSTSSXCjOXi/66Ik4CgvkG23SkeSYlia9fmF85F2IItakoWK3w1pGUZsqFYYg8PJ6Zpsg0BzrrgIJGsX8YGIaZeUpMQyInaqNnaLqWHAvzOAuDQUGOkmwT58DpOJJTxnmL8eKpIkwDLdchynmRFDklQB6K/X5GkZgmxTzGysQxUBZPoiWpQ26unGqRqBUhJ5x3TNMjxvuKRMs0ZhoC1zcSenB70+GdJkfx3kgx8/Bu5HSYVkBITLwLJcuETVvDdtejjACjxoi3UoyxgmyOvjW0zvKwP/D+4cymNWgrLKrzIbF7ZteHjaqdoCSGBuYp0m8b5lBNnIvidB6lL83yUApzxDV2lTB5vzSEBoNhSHFl++VUOLw7kXYt9BatwbYWY42ArIrqDRRX3f7Vtkdrxc31htP5jKEwDbN4OjnHOA9YJ+CtssLWRCtCKgyTTEZSSDStJDAppJmfJwGaGuUYhpnGNzw+CE16DtUv0AhojDEMp4E4J9qXnm1j6VrL/jhIpLqSe7LzFp8NOcF4DrVhLPUBpcjZYp1CF5H8aVoJEiiqGoTKZFqpyOLVRRa5aNtJsELJhUhCGeokSICrMBfQ8gCTIs1gtfhnDUNcJ7zznPFe0/cW33lco3CNyJfFK04mL1IKiW9X1zU1LfQoiSpa/BVDI/fkHOb6QBbdfkpVUmoXyYAwJEOc2fY7mGS6nnNhrow1Z2Ud5CLplkUVrDf4tlllj8s6TbmsPn4hpCodKjUdUQnTLy0mxaxMOpCCoWkcqijCGEhREeZE4x0pRJEp1mSZxaRTEvqk8VRl+V0JSGgjPw/in2h9faCqp4wH+WuMIl0NURgTRmmaxqJzxhtLMYpNY/n4ZsenL+7YbXpSLuyPA955dpsNXdNwvdvRegFkz8Mg/l2Gy0CiVP9FLQ3nwsgw1uBdU+XVAsCSdGWFCYvZpiL+g3wLE1A1/VchMsgUubq5FsaDdxzuT7x+e8/hPPP23TuMMXz22Wf883/xz/G+qWBXpu97Qgz8j//xV9UDRkDVUpssUwMeViCsMg8q5xiFwhpDv+nWyez+sCfHzP504nAaVhaHMgJOmqRWnFA9ARTmOZCK3LvLv8UoksoYF4lXIkwzx9OeaZpqQ5/5/AefsLtpMK2sdQpsOmlEY6jQxDoBF/nK8sANMWER0Ne3HhUiuci984HPZhFwpWs7Prn7iBfPrvneC8OrV68lFWsW37dpGjEmY83i51Mk8TmIPMoohVGFTd/gnZNC2BjmEHDOSEKudvR9y/n9nnme+fzzz+m6jjdv3/Lq9Ssa3zAMA6fjUUyBnXiahhQrk6ilaWSye6P1OtSTIJKLGfE0BR72B46nCW8z/9uf/4ySBh4PJ0qBfrMhZTifHPf3DSUnUg5s+o7dbkuYDnz04hbNv+az3/vjf3Td98FR6zmlFO/ev2MaB64aV4GED79RGXMpkNd/vbCKCrUWqPf4bwBg9ZDyannQXirtxa9pHEZpaLdb1PAgTJpF2lQyaQGF67EaBj+ZXstak8ZZWFdSM+4PR7k3D2e0UvR9h/OO4Tyynx5YwsEEwDe1JiqkWepSbRxt04iv2QIkIQCcDOZF0l6V6suZQ3xm1SrjhYgmYHQi5qddVt1tilR5ujZ1oph4wh0rmZQjOYcKagkjLJeMbxqaRvYD8mXv/eAalGVbVh9+VcFTloyxDqssCfGPzUF8gudpRpfEpmsEWF+ay5hJIfD24cBUFQRZZ/re0DaavnW0XoYcN9c9d7cb8dEpmePpRAiBxjmuNlueAoRGLwMlYeVVuIFCrs9V2SN3mw3TNHN9cwU5sTBkRC5l6PuWeWpQFDadIxVWVl+Kgb73xPlWLBBCxFTPummcGeeZ02ngPIi9h4Ay8p6GQdg0z2970Ia+dUTleP78GYfDozCXSqHxIicrSkz1m6ZZWYRiISAelJu+I6O42u1Aqer35YTVZqXmLZXlopQSlnsKxBA4nfbk6vPqjBMpfZFAoKuba/qNAPwppupzKcFBxkjAi9Zi01BKxnvH9fWOu7sbjDF8+cWvCfMMvTwblwe69Y7dbicst5xX4FHS/CTpfA36sZL8G2IgzDP39+/EzuDxQBhHnn32Ebc315Qcxd+r9dVnUeZcOV8CXUKU56TVht1mw+3NDu/9CtJMs3j79l3HvR4+uA0W7Enme6Z+Sfas0+nMHMWrMAG+bek3PfM8k4KEe4jiSIAwbWTwbZ0TQkQpdf+ITNPM7rOPpI4qieXELbXQZZeQ82nq2s75W3uturBsja5s3eLEsiNOLKAs1HUZI8MwoJUSKxd0Xddh9f7SNbnZegG/+tbLunRWQofadn3NpeduvV2fe94LsxqlUcaIsgYqruAIcQlxk1pV50KeE2MdyNm6bwzjxJdfv0Zrw8vnt7x685bjeWAMgT5nxtNInCLZNDVtVq33NSWjjKS8Fg1G4EFhNEfqYFjR+g3aOiiQktwTaHCtwwEtDaXAXP3Ic5CawjqHUZdUZRAGWoQKaNfhgLV0Nenx8lyQ49nzW4yXeiOmKB7eRq1ehMvPpHwBREuZyKVhCVa5fCMV2xCweUmWvbxw9VG8PEqwtmWRjeblNWodtvYS5QIua2NE0sw/7vidBsKmMGODxi3RrFCZTRlylil7nXLqxXBZX3wHUhZ6f8EQYmKaAqfTxOPjmXf7gXFOGK2JpeBbwzkG2o0VvbX1q9ykFEHktVXYGhMfwjLFr4bdoSY2WoOzYtYHwvYoJdN2HkFlFKfjwDzFamJdVjBskYWVIg/WYj3TkKSBnYWuLcbYgmxZqzFektvEh0qtVFalRGLlvK00xcWIOa2IuNBm7TpdFWBIyz5YNLlEQioUbasHTIaUMY14J8xBkVMhzpkUMl5bus4xnCPkwjglxiFU2Y+iqGpwX8SPKs4iEzRGMQ0yeRbKOBLrHCO7XU/bSuT9HALWOlKYV7BQaWg7hzKa83Hi5rbhfJo4Po7r9NI3imGIpDgzjwNCCFMYq4kxMw6BUqDpRU47ThFjxJ8KVchJYbRdPbisKWyvPGEGkqD5rqYfpSGupoQi87CEOTPPgfM0k1PEe41vNL4xXHVbus6x2zTkOdM4z/7xgWd3G8I88/h4xnctqQQW/b6kDknhFacqA6v2XVfbjpwLwzDjvCXphFKFMAdJZ6nTrn7TklOluJrMPASO+5M0Y1qhnGIcJna3PSrDME80Sqjs2xtbKasKpSwx+BreUJhjxCTx0JjnyP3xxDhEgs8o1WCcxrWOtpMUlVQK4xhZgiey1tXbTVg9uShSLJyHQMwnjqdACPD29YnzdEaphFZVfqbFENToGsSgIJdI1zUMI0xjxDiNbhz9RrxvSiyM54lx4knBp2pBlMhRkaI03zlBLok5VXpyUYyjyJgpck1LBa6nKVOMJrksuS/LaEZRfYcUvrU0naVvLdvOkwO8+vrE+4cJsgAiOSfO58j2+Qbn9Dq9KrrgO4fzmhgkIVBliHPG+QZrZx7fP4rsQ2mUmSmdJ4ZMigIwGieGtiUVSvEV4JD0rJBmiYkvMBxnjvtIVopNby+eFjVNN5eEtpp+29UpT67npACR4zitDRt6aZRk34uLTNIanBdafcoVHHIWnSGOQdaDYmW5rqyDLEk7iw+i9lpM7KVWEw+xGrFqnabfNTV8RfZi54QJarVM/BfJZkHSCCkKg7DsOmtJMdAYzU3f0jeem87hNbW0kfew2W0lmcgYGiuT8RhjnT5LkluhrHuq97nuv2ptRhc/o7E2uKlIsbRMiEOKqLCAeU8mZMjktOs7kahZMY3t2o7H/YmQ4Ktv3vMXf/VTrG+JWZJW//qv/5q3b9/S9z39Zstut8MYw89//nP+5L/+N0nEspJ07KxhnGdKqd4aT6SRiDsTSzWktRgBH48nzuczD4dH0ixMtF988YWkqQJZaYqus+ZSVoa1NpVJcjoQY1nZPKXIfhOj/JFhqzSF+/0Dw3RGZyn2+65ju9sw5wPTJPKheQjM40xZ7icFyhi63nC1leeisyK5GEdpmvAC1s1TrLKLhckITsna/fTuJX/4g9/j8HgQi4OUGMfAMI1QZdciA5ZjHnMdqAh7wihFmAPWaeYwVQlOy83VlTzzjaPxLc/u7vjlF1/xxa9+xYsXLzidTnz56y+gFD7++CMeHu55++Y1V7sdfddJM6E1297R9Q1WG3R9lmitxS4gxxWY1ErVdMw7jucTOSd+9stX9M09MWbOUxJQMwvDLafq4WQMjw8PeG/53ifP+f73P+XF82cYXVhtiz7EPC6H4iJTXL6xJrS2rTR54zRz1ViKuKfIoJll1lflL+uPlw+KbZQmZ/EIE2+88kHz8ORtPGF0ffj1xf+uaRrariWNav08y3D0A/8vdQFVf+N1noBhCjgPE+/ePXD//pEQI+2m4/pqg3eWw/4oHo7VC2rxCDsNZ1JKWK3Ytg3KOIwSFtQKvpXl3Qm5fgEDpUer95le6mgQRlKEEnE6EZRZ32OhYIrIOI22K/v+6WeCVD0l02Wfj6mCYCLZ7NuW3jeSZFYZ3ssh+59arTqkQZIwiaoPEb8lWCWNzLoyaGq9rmQwnJbGqq6QMcK7d4/c708463gYIk2v0bZgfAGTiAWmCIfTiLWaXS8AX0rCYjfK4V3Lt/2AhOmxyPErI2kFxRJGO3a7DdM48fkPPhMmaEwoL8yqFGNlJ1soiSU1W0IHLs8rhzA6VM/6eSkwzYFXb94xB2HWG+2YQ2QcJnxTaJxhjpEQR86DodlecTqPfPzpp/Rdx831NX3fS0hFldQ1zpNKxnsvfpA1NMTVhnqVlRtH4wRkiCkyx3l9jgvoYmW9YBjHd+Qcqsef7Klt23A+nbiYfMte0rYNXdfw/u0bxmHg+upWXiNGQpRQo82mv8j/GpGqikx+YVkrjLV0fS/+ciGsrE4xWRdj/BACIUbxb3pyaK0hRXzTUqLY3zx/fsvNtkWZzPc++R63N3fECDHKM3oBNa+ueq62G5x1XF1t2W42KyjrfSuBZ7nw8sULXr3eg5rXfUsCc2QwI2SuKlsshffvHtjvD2z7TfVztLRtuzLCSkpoYzFaFAw5V/DAmvo7xWM2RzkXjWuql9YSLiK9tapTIiHQLSwfSL9lU1tnivWo40mKEYCnxJmURI1VKvhIKUJKWYcWwtTTtTd1NfnxatvTt46SMor0G0MPrbUwnmrt0zQN3ovUda41lBDcZF8cR/HUVVUmLuVLJuZEEaoWOReRrlJ4e/8gATf1njsNwp5OKfHZx7fVaimitEM/eb4Uqucul+dJru/FakNYFRei1FHV9kkhIWSL7/mTE1qvURElhFLwRGJ4CRt4+veMs/4CSNUrOS4uHdqwu7kWSXGKhDDXuvnD1ytZ1BHL4D8kaNpW9irWlluMJVK1+ngir/22H+VSa2hdMEbq+ZgV33rlylwWFVfKpwrI+/9zAGFPrz8skcgVLIrLiRdAYwH/v6vGKoj23daY9BATuSQigTnI1+MJioarF57d9XY1p6feOCkJa8JaRSky7ZgnmZqOo5j+QmG7PMCrvGIcJ1DQdWJ2ejqOTFNgGCYpgI2upqFUicxMyYqYxA9MGstCnBOlmkqXujl5a+l3HbYx1Xy9stTqZINS1gYRxMNniXnW1R9FzGZL9VlYmnWDtprxNDLOgbbxzCkxhEjrLamkJ5ImhdaW7dbTeM04zFASv/jFGw6PgRQKzhkB+ZTI3uZpZjG2VBSUlqnVZrtjt9syDCPTsOj4FdbKNEwBKQQ2uw1LmshaiBXYbDtSznhvJbVNKGgM58BXX56IIXM+CastowS8iSI3st7QbRvCHOsUXtfrrbFeQMyMJJpJ4Wjpr7wAgmOgCQrXWkJSxGhBLZ4/Cd82lJR43J+gFJzVbHctpnX41tNvGtq2IduCniMvP3nBw8OJaRYqb0rQbTvxAVhYjikTx8h0Cqic2W4919cbQohMITFHTb9tcc5xeNyTU+TVq/c8u9vJtEaplTGTShYDwjkwT5WdV8GGGCO6abjebiQlxgrQo6E2+T3GeUI5kXJiP8zkOdI1mWnSDOc6tRwjh1RASVpODAION00DXlcpbMLEglFOKMYoTseZ/XFi/3im7T1dv8PawvWzRHO+eCGV/DRQQhhi3llKmomxQQF9bzidZwrCXtBK03iL97YmhImRbN/LfZaTTHNSkE0ijIEwlSr1FEbfPMtaVhS8k3tpOAf6jWEkg7JQClELRXiapdimWAoZY8R3kCqF2163PB4CrhFpr7YCyOYs/mvognWKfttCLpweZ5pGwgByLrSbluP+SIqZ/eOZGAIvPr4jjhOnKfDRxze8f3+k8ZYYEr336wM65ol5OJDziWI8x/OBaYp88+tDBbE0iobIDLrFOEOmBh40shekXPdb74ghkqI0/ynVB11Z8TNKSpAlebKkIkbYMVcKtnhNzYW6bxeaTlgOZDHTNdVnI8wBlLymqQ2+XBO1mumHWQYPTWerJKlOLo0WieOmR6nC+8NjlU0qVFJ0VoBlB5Q8sWsdd92WbeNonKNrGry1VU6jabsdxTniHMSfcgxSPFdmsPe2FkfQajH7tgpEGif7vbEig57mmeNhz3k8E1LCOpmGiv9Dql5WdUiDXieyzjdsthuurq7WZ+A4zaQy8ng/8OU3b0ko/m//5t9wfXXN6Xxm//jI4XDk/v6eL379aw6HI+fTmXfv37Hf79ldvaj8h1LlLWZlfyyNpjEaVTRpLU8E1Pvx732OM47/93/+//Cv/tW/4M3+NXGeaZ3nOJyZYxRPGy1m+sszjBRoVUvOhcd3b5nz0nhq5jkxz5mYqM89qQfG4cQwnMgp4TVA4HQ48fKTZ0zDWZiNkyKFQqry6FCp+M5bmkZRMKt/HUrAbuuEoRCGIJ+TatJdynreW90Qh8T//qd/yavX77A1ocyaViQ2Hl5+dM3hdKjMOaCo6qHWVbaADNDO5wFVYB5nrjc7dv1W5Pu6IabEPAcOhwN/8Zd/ydfffM3hcGAcBj759FNSynz91ZdM08j3fvL77DY9fdugVabtGm5ud3K/TbKvyZBPY7Eyha4MqkDCucy2bwkx8uL5S37xy1+z6QxKa+aYGCdJlY5hAXPF3iDOmtev4XQ6oSjYGhDzXdWZYqmry4dyQQR8UNqy3V2htKXrdhiVwThCMVXGXygqQRZ5S0o1en3xqit5BYOW5kStXjHiR3rxA1uABQFeFjn7UlnO0wRA27VYZ4RVX2VWJfGBZ45SFz+7XC4G80+PBQwrCd68e+DXX7/h4XCSgJeaGj2GQEpBUoBzIqepWiHA4+lBajel6+cQlpap0u9FkqdLxuuMKlb2mlpIrubuqmB0khCO2pBSMkZnvIExC1tExRFFRNcAgae5XUotRvsiiXx6jbWRhm6eZ/re0zWtgBmrjEtaM6X0ypICcX1b9nKrDd55CopYpeIGWbfKGIiKGAMhRbQ1WOMriyGu6YLTOLE/T4xT4DBlFMKu9Y0lkkiheo9pTcgi6RLmsTBNdl3L8TjS9xn/re6qmkysn4ZlXZdlKpM4HweurnYCLBYxZbdK/MxOp/PKXqQIA2LOT8ILEL9jXZbAnQVmU3XgIJ5ih+NJ/GZj4fHxJEP6OjiOOdK0DVYXfnx9g7Waf/Ev/pmw1XY72upzRZEQrRyf+PB4xIe0vscYF1mTxlu/9hlOSVM+hakGnNUBfC4cjydOx4nTcMRog2uqPUkFJ2ISNk7RlsaZ1efzfDrXe3L53JeGv+uadQ9uGi+qhTUwQe53ayxtJwDf+Xz+oCFfUqXHUd6vfXJhm7bl7u6OXdeJ/UHreTwe+eijF7z55pf85Cc/FICrv+Fhf1qBJO8sL+6u+fEPv0frRZL/zat77u8P3D3byb6mDGFWaCXAp9YZZzKhMpxTSBKYpS8sLRnQRfYHYQOPKaKsk5CA3Y6Hx4caWHDphcUfzDPFKMNUsfCSgbHRjFNgCqFKpy/+15TKqn+6XyEg2ZwcSsXf+FqtuuraX1jvpX6emWk4cTodmUPEOFeHI7KZGWOrr6kAidoYnPf0fc9m07Pb9mz6lhRmtC6cDmdiurB9rYbGOXa7LX3fi5ertTLQrOCSyHcvgRqSPC0eqCULUcPq6pOI+O7lCqSdh4kffu+W0zBSkD5gCeDJOXI6T9Ib6adBLJcj5YQqS20re7LxjpjCb2AduvpAixLj6V56GfYsgRbLsZzvcZ7FhqiI/H9Tk6qFMGBYPMrletVdq0qHlG0paFSsYGip31dqEEyJVdILKifc5pqSRtCsQYJzzqiq1tMLiFqeLMjvOJb7cdn7ck3cXb8OklpcZbQlJXKKH9zHf9/xOw2ENU5Lk5BqLGwKK5Ajw0KNpCwCKJT+cOFJUqJmmOSGbb34BDir0QbmcUIssRUaw/Vmy/XNVhZ/kgnBoiUu1CTHRZqq5I+pPiPGaFJMtUiW904WD5uubYlJZFNLAMA0ipzNe4dvpBkvVL8s21B0QTlJs3POrBI+pfSKXsdZ0mSc84jaanloyQSt3bTo1Zz/UhiKQackTWqtyLl6vSRWgCmOM+fDkZBF+kY1EM+V0SIPeKGvWq0xStD7Z88s0xyJEc5nKbSdFzPj3a7HWVOvn8Y1YoI+nBObfsM0RU7HEwoxybYYjBNfGtG5G9nYgjCsrDM0rSRVzVPAe4nUnseJm53FNDIx/PHnz0k58fBuZBoDUrMvOmzqgxJOxzPbnTS+3sv56re9xLNr2O+PWC0SKaWQyYQRRpuxuqZJWkqJhFnR9rI2na9rNBW8N/R9Q9817PqGtrXoAimIb0LK0DaOFErVeRd5yG03WC/pJBQoYWY6zZz2MzlEfCPnqe0czlucrXK0eWYeR4w13FxtV/Zkzsh11xqKgeJQKjAOg0RMa4vfOByWw8PA956/kAQyq2U9IJubz1ZSi0zB92IUrhvD48OerA3nc2C7cTWNSdM0Wsy5U0LpXQUyDU1jOB0nrnY3jOPMHBTn04k3bx94PB745KOXQgG2VLqz4WhlIt320iAcH0/M0ywATEo4o0g5sD8eiKHK3EIizYHSOVxjSE7YdEarNap7s2lAZYzyTPOJKSR5EOiCbzRGy4T3cDxyOg+0bcNuu2F70+JD4PZ5y/kY8Y3htBdJgE6JGEBFMKoREEyLGbtvDdpKE3X7sicUmCcxMVUKlLHkEDFajGXFG0TTdg7vHedxwmqDbS3aG+JZ0lvnObLtO6Zh5vq6YbezoGaef9QTkoSH5FDIoWCUopBQGIzaECfL8SEyTaeVDm1Ufdiliw+XQmFm8VzLlcmTM6vsU+tlIlYqExNhhdXmRpcLyzbHBEbuu1T3Kucc7W4LWVIjwzDLcKJ2AksxsEh7VKVhK6PQfkmi0aQ0C9PWamkkqseitYpYEq8fH1FFpKgKhQmKXd8wxYDXFl1DLmQyJcW19+IP5bzHN80KYCUFetNTSsG1DWWaIV1kMPXpRMahlCWpglEFpwQszNVh1jpH3/dst2I0nmNinCfGcWLbdfX8V9Njq7G1IG6bjk2/kdQ2WJsBSa6ShEetDbvdFb//k59wc3MjgHQpDOMosrrTifv7+/8fdX/2Lct2nXdiv9VGRHa7Oe29F8BFQ4qEJKpKqnKNUSqXqrGHVQ969v9WfrZf/ODhYdfwk0uy7JIslUWREnuCAIGL251mt5kZ3er8MFdk7nMBkJT9hMQ4JHDObjIjVqw15ze/ht/93X/L//V/+L/JBN9s5J4qB50MlMY5EkIUH5cCRos5fqjy2Fzgp3/xGf+n+/8LTeP56Y9/zKff+TZKFbYrT2NhijP7uWeIPaUmrMoQSjMOB+YpMBwfyLolJsPQD8xzYhz7WhMUwjwJizgM5DwBpUpbZAj17t0t2YjnXpwknU0SqakpzLkCMYoYNN6p03mNElBC/M1kELHdNrStSF5X5kKK6hQZhpFGe7718TW7VcswHInzQAgzjobjzYgzlscpkbVHGUc2jmQaDlOEKhUZxxlyxFnLdrvh2cUVYxBw5s279/zJn/4Z3XrNb/7mb/L+3XtSSlxeXaFQ/Mkf/zG3Nzf81m/8gI9fv2S7WbFbt5V9KLYJ2mpMrjYLC4m+gtQLOUeazkIItdYqs8h6tKZpxUaiH2eGPjCryDzJoHLxhQnzzP7hjmkacRriX1UJU07r5fQ3RUJtUlE437HVnrSKAtBU9uRTNlIpBZsz2YgnlSQJT3LWIKwJpeGwP5yeCd80tG2Lrc2wWE4kaRDq1B4laYWuaWrQhJxBXdNy1BLqUIoin9In60TfiGG2tAMfvj743xoe9z2fffWGz79+x+Mwoq142rVe8/bmnuKOxFBO32m1JscJyopczfmlPqzS/ZIpqVprKAFcdAFKIOcZbdrTIFnrgjNiBL+8ryWtTSEAWiiBFKIUicvbVkkSkevAdWGyShoxKFXZJXkZVpRqOK5x1kki8izPb23thO27MNnqulhYRctgWgPDMDBNsxhd5wXohGmemOZJRIm6MOVEHDJf3+3pnOfruyPv7+44DCPGCFBotGL/GFA2VTBPBguHnLhRkc7LMOpqu8WokZhHSdbtuifXQgbT4lP6BAZ8sp6VUjw+HmiahuPhWGWUnD9DBSBzlro6Fbkepy55qeNLoUZLnGgVSom/0rEfuH985PHxSIq1tqvXVlWu7jAM7DYtOcr6eNz3fP/7n4pxdQWES607k06kOZ3N3Mv5swhDOOK0q5YIYpURQ2Sc5hpYEnh8fOTu9o6YEm+/fsdq0/LV12/46KNXPD7es9sK23WaZoZhZHspvVsuYJ3l8mLLw+WOkCI5RxRVRm4MfRpP1xE4eSWGkGq6cRRvSqNPzLGiyuk5BvGUvthdME3is9eUKp+r69Q7h7cGpxXHm1v0xy/ZrRzPfvgDri/WaG25uX9gMXwHUQz4xtN2Ddpowpz4+KPnhCnws5++4eu373l+dc3D/pHL6x1vvv6aTecwynMcIsNCZnjyOskKc+b9+zshDIRIU+V0GsXj3QPH45FY0zt1VVg47+BY2Kw71p3n8TiK1271uw7TzGk5Ve+nc0V8Xsznp1LIB0+99Csd9NxvlkyIgXEaGcaBOA1M01hDHjIXF1fc7Q+QCx+9fo2vns1ai82HDH0t2+2atmnw3rJqPZ3fQhz5cX9gDjMxGkJKXG4a2q6jaUSuZ7T4iUm6aiakxTePM1hXrRwolWgTM329difwOEo9Wpi5ud/zeOx59eKK4zSxPwwUMloX1q0hpVgBWvPBtVhYaDEK3uCM2BotgF+K6cllFLsaSiHlQKi1lQxxwNoKMmlFtnWwUQohRo79wByFwd40Vobn9X3ELKEblZOGdxpXQciiaqpkPUNkIJFRuTDte44396Qp0HQelRLHn39BGGZ+6x//L7GrKk+ta8EZTr7tSinmlJlCrP7FDrKoThbQq5RyYm+efz8nRV6ugL+2jtWqg8sNP/3pl7Q6fMiW+ytev95AmLYYFHEOhDCSK1VP/MLkwNGn6Z5mcRN4ii7OIbI/VJkcIqWbQmQOc+X4VE8TBdlW+r50D5RcqoY4V18gMWxfGEglSdIdharVNeLjYcSDplt5SW5IYmY5TVEOGmUoWRhJ0yTm+Icy4ZxjGguHeeTb33uBtYYwy1QjzOIpljOofEZXS5bEvCXuVmsxVHeNTDm1WbwRUjVLXFIr9Am9jjER688vuWBb8Q7LOVFCEoqyNUyzpBHK78indB5TPdnGfmKaFOOYsKacFvIwZdCLx4BhfzzitUUNkpSZEvT7PbvLzWmyM44j7aplHAJts6ZtO8ZxkCSZELi7PTBPM84ZfONYb1r6w8A8izRRX1uU0WzXni+/3hODNM1URDwneX8lZ5SWA8NazTzNNI3GNiKXSkmkQJvdmtubd1y9uiaMI94bulUHyhCCxPm2nWXoYbP10hAouWbGKExRJBJta+k6y6qzrLyhMVLQDENgCpFxipQkfifd2nF784BrOnIWUExbSwgzqZ9qqmZC6yRLNiemMbPdrXn5fM2+z7x/94D3lvW64/r6guNhYBwmjFe0qzVKWfHximIUmUomJoUqiUY1DL1IL26/PtCuDNMQOE4D23WLazy2euc0cWEYZNatI9qG29uxRhy3dK3HekNMqdKJIYbIZDTaFRSacQ5Mt3fEOUpcfAUQX1xd4b2w89I8g4moInLI/ePAOM1cvVxz8WJDmGe809zdPuK9YZ4VYZ5om46UCl3nThN+bcXHRKSsMqGz1jCOGa0ixkRevb7i5v3A0B9ByUSyPwqjK6dC4xrWqxZnxVR/fdEw9EHWVzXWVtpwddHx9utHKZJzYt1J0dy2jtXG07aSMDSNme2UuH0z4xfWVmdpG/GHM05z+9UBhWK7XXNxsYYED7d7wiQ+SiAhEuutZ71ybLZrmpWl81qSJGOk0eJvlkxBGYvGnWjcqhimKXHcD4xjICEgGHaJnlbLrinAmIY5RuYQRQoeC+tthzaKtvU83o8sUqRSxHvEWUtJ0giFHMAU8dlQEqqQcxBaf91blFYCBCeRfSx+fyhJLzXG4J0k3CmlmJZhCdXs/smB2TaNsM3mGmwSZlQpbDqH1RqrHa+uN/Qh8vpiQ0GzbUWO8pe3t3RefHjatqvgk8N34uWzJBg+VuaIUhpsQ9Mp5mEQTzWgIPczpVQnXSJPywtEX+qwBdisN2eeQaFOMs+MA6UlRKRp2lOi0Ha95uriilIKD/s97473eCuJXNdXl/z4L3/K/+6//+/Z7Xa8ePGCq6srdhc7nl0/4/rZMy4vL1mtVrx69ZLXr17w4sVLfvC97/PweODx4cDt/Z7buwPznFm3bS1sci2VJ1DCDswp8id//iMe/83vQi68ev2SohKxRF6/eIY2mt3lSkI4UqZpV1xebklhou8n4pQIU8f7r7+S66c6hsOe/XGshuCFOdQ5vImgAlpDUxSu8xijCFEApYfHB/EJXFhcWmwXjHcih6CQI6eGJoR4kjAoreQ9do00rUqmvo1pCfS0K8NFe8Gnz1/zGx9/jAKOw5HHfWF/LKS6RrXWZBQb23AImXkamfs9/Z6aBFoqcCODs91mjbGGZxdX1AXFT3/6Ux4OB/6b/9X/mh/84Af8+Z/9Gd57fvjDv83V1RU/+vM/55/+03/KOI1i+KyW9DCN8eZUEyw+PsvrKfiQs3j6zbMU7rlotLZgRBYm10D8bTZdwzAF7u56+uNMqnWJ0YqL3Y7Nes2vGgefajXObdbTr1zAmqfv1xrDumvqXrSAOef49YVdNscokfA1Ec4Yw/F4FNb0OFZW/yS1Vf05SiupKZzcizhPWN/Q7w9cXD8nzjIYXK1XOGfJWXGcIpzEHAqlRdqvjaFUr77FmmJ5PekbAElPe/P+npvHgwwN15KKfXf/wBwmlHsCDAGrpqVxBhWPxOFwapq9NzRdR7fe4v1K5ITN5iSRAuiDDAOFfirykqiUeOOx1M0Th34kp8pw0EWekxgg1r0NMEQSujJEBcRRSoAA+bzyXBlrsd7J0MB7YcnFfMJ4vDXVfF9+srCDakBK1csujVqB0+ed5sBY5soIjZIul2aGuScdI/Mo/qUxFsKU6OdEP00MvRjLFwXjVOvkUEHxKENOiviqWQPGGx4e9xhraRvFtz66JKaI1255y7XxNlijq1fsB7es1oNSa6V8VpyYKlVdgJiYPzyvQBKHdYnYPBNyJCknNii1QRbmWz6xVItagKsP5ZsaRQJePr9is9tQSuby6hoQxp5maX+eeOtpsdaIkzTSaEmzT1HkmyklCcwKgcN+z/3Dnof9gYeHR/b7I4fjkceHR6ZhYrPZ8NOf/oy/9du/wTQnNpsrkZMZw+7qAm3EJyo9kcUa65lD4uH+kU8+1ijiyTcwxPABC1OsLaz4x9ah6BLSstluWa/WJ/ng6ZoYzWq94niUkBhKZTZVsG+32fKdT17TNJ52vcJ5zcuXl9JdK0/MZ+/e8wMOq7bh6nLLZz9/y1/87AvmWYai3muGYeDHP/5LPvr4ikzk+voKXaWsx2Hg88/fcnvzCGhI7rQ35hxIOTCMk/hrVfKHmPq34js2DJLM3XUC4ldwSYZTSga7SA+42+0Yh4l21Yj9gWtQqUqLOUshn67FsgxN9HKP5ANbLYBuKok5BkKYmeZJPDLHkRSD9NHGow3cPuzx3rNbt1xst7XeM6e6sW09vpFhr3NyX7vWY0sgK8t23TBOFRfIkEvLHPJJUi2sKhHRd9biTWGKkSmmk4XQEvwTYmScB8YxopT4c0uteibX5Bx5OAx86+NXvH9/w3rTQUkch1GGYjWoS/ai2v/WvX/Z7M8YRb2auWCNq3hDRtnKtleLBZI8kYV8siHwNmN1IasCujDPmbfv3/P1u1u++OoNV9fXfPuTT3DOnkKYJBk+V4sOsW+yVoLMdPXmEv+tgDLybL39/D3vf/Y1D29uuX9zw/Rw4Moq5ptbrl5c8v3f/i6plF8KMuUaKmiUoXGGbtknUWRtKdYSgwxRlSrkkNAp4ky1kCrUEBCxBgkpkYpms9kwHR8pSsCxX+Xz+c3XrzUQViikEgnjsRZE+uRpYbSkBoqhtn5CQ1w2DEGj+2Hk88/v2F2tKFkikVed535UlCeUw1IKJWTyPpDbOmmvFFOdoBh1ihV+ivI6t3ytOSX65SSRwt4bPIZxEi17DKmydISSmZOo91JMKGXEtHuGi+uNILeqcHHdiofWaBmGQJgS1SqSUgrTIGmFSouRtvKGGOSQXRb4gnZLc2VwXj6LSBOVTHCGnhILzju8lkhqbTS73cWTqypShWGYhXafpFgpWeLkYy7EMTGNVe8NWC8+VLpOYYqC7W4jD+kYqhRUDDabTjwDjoeBXIQVYxAJn7WW9XbDNMrXe68pRZJU5ikLLTyLvMpaKRCsVcwxYxtF0xjGIYkHUUh1uibKZqOEJWi0qt8v6Xu6FNpVV+n7ga5thFHVNfT9hLGO3a5FqQCqAmrWcDjMbFdrVDpIU5sKqWS0E/BmvXF0zrKqqYkhCVV3HjIpyHrwbs34cFcTeMSDi1AEeBshDJEwSWR30zTCdLEis1Gq0E+JtnU0rUXlDfuH+1MD6LzFm4Y4Z4oSCdc8R8Z+Yr1rGSdJcpmGmWkKGCsb/PGQcK0mhogBmX7WoijOAectrXekkHncS8OptXifdJ0YVjbOkddr9vuDmL1Wg+N5jgzHmZTm6rO0Yo6R7XYtSX9ZgNbVupME2P2R27ueEDJr4wkx0KxaulajcmZ70TKHme12y9xPwp7MhcfHA1fPdqeDpesc3cpyextRFOZZwgtKSSg1EeOWjz7e8PbtkURimhIPdwFrM5t1Kz5wWTzxmlYTR3k2JLRC0x8Lxike7g5Q2awFhVbiIdE2DqvElD8mkWpZC+u1ExklmXmO7NyGm6/uiWNGa/FJePvFvQDswyShE1pSL9t19cgokZgNh0PPZndF42tSK9VPwVt0yljToJQTUDpmaRiOM33fYxpDDkIfb5zIDkTGqlkIEGdfnBpGUT+nb/UpwbTxUsT0/VRBBDFqTYh00iigCBM3K/B2g7aRtm1qkl4teo5FCrVOjKBt3ZNF4iRTrIiCHE+m72fRSvV1KoWSQMeC1YW2dRK97hyX6w0fXV7xanchz2T1DQEIJfNbr16hlaJtOzabHW3X0nUtTdOKf2PJKHUexpClOTXWQCxCCcygkIROa2VAoKukPkZhHxqTz16/T4rRpvG0bUNIYswr11YMjpWWs0dM0c+m8ikXrPXE/oh3jmfX17x6+YLtdsvHH3/M7mLH7c0tf/xHf4y1lmfPnzFPE7c3N4Qw8/3vfsJ//Y/+Sy6vr3n37pYvv/ian332FaXIOg9RQmdyfX5iymjEqB7g8HhYsgx489XXxOon8earG148vyb8pTQIMjWVPcxaTYzQNhaUI8dISgpVAv1RWABpqOCDVWBkQGQBU4pM/ceZZDTGa+7u7ompsloAbc2pWNZa0ZjmZGpN0QLUp5m28ZSsT15OTdfUfU2ai4hIo4dQuGo1u24ladHVO0crkVtHLQCORNob+lRQsZ6dNe6eouu5LJ5MIUYeHvd0bcfz65eo6rPyuD/w/PkLnj97zh/+wR8wjRM//Nt/WxiqxyNXz6751rc+4c/+5I8I03xulqrHZIrpA0nFU5aHADSS42d0YbtyKGO4uR9YrVpWXcMwVf8pziEPXevImxZSYQwiVTbWcX19TbfqmMMvL1hzkTpC5C3lFxtKnr43hW885MBQgWYQuUtXU+vka0Fp0MbSrSwda/mYpdA0HRe7S2HcRPFCETPxnuNhz/FwwBi4vNxSYuT+/S3vvv6atlszTuIzO88zfEN9cH6jfIPuJUycv+41z4FxnEQOrzWrrqVtPcPcU77hyGPrELiUxDjFkyfZ4oXU+I6ubXEa+nmo9YvUUG3bCZsM8R3K1Ga2Xp8FTBTGwTdMkJea8wnGo/JRQH0anHUnqSUojHF1T6tMCK1Yd2u0NpWRXqVtjWeqw4qTn8wJE1vCKE4jaxnQ5ixy7yp9NVoxTkfu72959/6Gh4c9Yz+RYqagRN6YCmOMxKIY50gsUn+TxYvQGFVrckWMRoKvSsGagi0TY9B8/9Mt/Tjwo8++YtU0fPfVx6e055hFRiXas3S6jk8+CtZZ9vsjN+9uqj+SDMbGaSQmAd5P/UWRNNnTJTklKxRinFHanAYfImOC3XrDs8tr1t0GiubYD4Q5nYYueRSg4u3NA9vLZ6AUn332c95+/ZWYpu+24s+WIkpR7Q2i1GClMBxHlnPeWvGeOu6PbHYr5jBx7B95PPTMIWOsYXuxxbeSVLlerzjs91xc7ni833Nzc1s9QzOrriFECdxqu4Gm7araRn7Par0hlMIcAm3tqa0T7+LDseei2gCIr1Q1v5/nD+Sbbdexu9gR50jO50XsrGOz3fDw+QNhCuezW1GfxY5PP/0Wlx+/gFK4umopeSRjibmrLOazv6c0jRpVxONstW5ZrTumeU+hcHt/z27X8N1PvsPLly/51re+zcuXr1ivN8SS+d3f+/c87v8Ft7ePnPVhhVwiuUj6ZwjzyUfZNQ1aCdD34sVLsaWgEJY9wTl801R2lTDCpjkQ50jf94Sp4//8P/xTnAFnG5xVZ+VVtT0o1XR18acuUNmb1Ge2EFNgGIcKgM0CxmWx7AmxABK00Hgxsl91rdz7VUfbGja7LW3TCdu29bStlf66soOUAkvGqkx2lquLDf0wEsJIqcyqtpM02pQSUxqIWgk4bUV2uXIOVRJTEk/v+8c9Ic0MY+Tm/pbhMLJbr0ilsOpa1quzGX/KmeMw8S3n+P6n3+IP/vRHrFYtqDq80obbu0eulAyMtVXn4XKFwEwNFqlcGyFMWJFH5rz06OrEIBPPsMqUKoVSEpqMUXDoJw79xM39kT/785/y9t0dc8r8Z89e020uUCaT5uG8exeReoaY6VpJp9ZWbKMK4onbjxMkePfugT/905/x5k9/Str3LOzod3Ph2eWOj//O97HeM44zzbqrq+LDVy4SmKSrHFRV2rlGQP+EKExKEc+5cU6M455xDvz887e8eXvPzd09wzjQdoaPXr3kN77/G7x48Yz9/pF3X34trMa/wevXGgibQ0DnxXtCin5rNgh1RgABAABJREFUPM7KH6W0SGpyJGUx71ymGSEEpnkipsjFhSDlxhm2u4ZQVgxpYkqBaZ5Ph8/joUc5zaXpmKuHkNLgGyPyNiV+NWFOp+LDOUvT1lSmIAfnOEX2jxMUkc0d+4mHR2EroTQxQAyKcRBmkhC1omiTG4dziWkIKN0yz5rtrqUoi7Iw1wS6UO9/Tpl5LhijKEWkXygBU4y1J7qqUgptl4KsMujUYqCfKxina1CDsHzWu/XJtLhk0b3nJAVkipkYEtM4M09T9UVrOfQyXS11Aw+DpLV1a8XF5ZrVZk1MmWmoQIkRA09jZaPfrrekUnj/5pHnz59xuO+J28jiHzAMM1rBZrfmwu0wVlh4VgubS5D1GWtl0Virefdlz9AH2ayU+HYp8qnIWkqV9XZVJ4WRi8sVw3FkHEfWmw3zNEp0thGD/bZr6PtBZEq7NdZp2q3HHAa6TqRv2ngUUVJWak2pavLOqmmYhkyIE94bxqMYxvfjzDhG3t3vub7Y4nOp8fYQB1BGzD5TDWdQRokBfWNq85XpVq76vyXaTotZpl7TeC8ebko29eFx5nDomcZAya5S9weooKVS4p9CiYyHEb/yWK15/fIaa80S6oFGiPreKVyjmcaA1YqqSGbVeYkCLortxY55DnXaJtLcGBJzyGLlkjKmTjIe3t2wvdrQNJbxOGKMITUNuWhhWhbx5dNGQiOUkWbPGgkNSHNhv58Z+8D+EDDW8eqjZ3WKmZmGSH+I9McRyCeWWkoCKLRdwzgmtElMU8HaljAemIeZZBJWKdrO4FuN9VKt55CZjlEaeisFcYrikVZKqQ1GoVtbVhuPcyKPbBrHMATubw/kCNY75hTIWWGs4vbtA5dXO2IqrFrHcBwwThH6xDQX1hdbrl/tWK8aDo897arh/uaBaZwFXDOKoBQpKEJQhCD+ZFoXtM5YrdHWUII0e+MwiTwrgvHiYzinwJZqsF1rxRQyZS7oJKxHANUKHT1Wv7nNqmWYIrt1x3bTMceZGBJxzKByPcxqAZkDmIaYExtvWG8ajG5JOZJywjQWJpH6lJRRXp38/LQqpCK0/lwl6DkWjFVo0zDsZw4h4OtevV21eO1otKb1wijzWtM5YX85K4bpIUaGaTrR172XxLhnz56z211gnZWhTZazKIe6B6ZySswUk26FbjxGLUEl5sQSijExjHNtvoSVZAxYnU+SBWvtCcAwVvwpFMLU8K3IdOY5YpRlipl0HMVTDGmIvNXEeeKzz37GPM/8k3/yT/hH/9V/xXa75f37d3z++ecoFN/7/vd4fHzkX/xP/xP/5v/zP/Mf/c7f4Xvf+5Rhmrm9uWXoJ479xDjLNH5h0eRS6oRPAL5SEiUF4bIpj/YtOQU6W0hZwJ/buwecU6fBSs6Fw3HA2hXeeaYpoog4XYhJUbIW2cfTVywgeRUkJbCnc/IMWa9AS5EOwh5URlV/J9n5xylgKayaRhJRjQDhxgowc+wTWkdh/CE1QFdNe5chnFKw27TsOkndTDl9kM7lraSZppwIccYURYmRNE3iFVSlfl3XsOpWKK3ZH48M48jzZy/ox5n1WrwOF1mx957Xrz/i6vKSECO/97u/i/OO3/7hD6XA1lZ8o3SVqlFZqkqJDJkKGC1+JCnX5OZMoy3FG4ZQGCbZh7xrsN4z7Husfuq3KoV6zBmMwhRDygnnLRe7LZcXl3zzli0v+TwS2tH3AzFGYQ9Vxsdf5wES5kCKWXz6ni6JGnlvrDCQ4Nxg6CU+vmmANTknuq6jazu22x1iRp8J40i32fCdH/wmfX/k8eGe1XaHVtIcLz5Nv+olDH3574uPza/8HFG8qZyV5vniYsPF5ZbDmwPKVnCpgM0OZ4UhRE6odG4ElrACY63sD3AKR1r+Q0n4pQ40MIaA4CtGTPTrNc8L6PLkJRjMN/5Oyb4jDEJJF9elskMTpCjAeCnqNPBs25bDNGOFO8hhCpTqKVNV4R90VQszRaFOtiiULA2hls+oisJZd2qklVJVqjwxDIFV29XBraqsaUfKFUzNIN4H1U/XqPrzqR5GipIbQhxJObJZSZrv4+HAdDWy6ToJbar2HbrKU6mNn8kKYz2tbVClsF6tmGPi7u6ei4udDPatyJRL/b2qpA/ZDk/q1FykVkrVe0trTVLiw3n3sGez3vCtj3dnpss4EWLgsB95eNxz//jIOAXaTpQL/+Zf/z7O1z0ti/eO1tWCwhTSfOTi6poUC113Sbda4RsZvrjG8dG3XotVgjP1vMvAmaW5MFIBfv755/wf/vf/R0KM9MORbtXhGsc4B7EVSLE2++eer2k62qbl8zdfi6dxmaF6YmqtmcbptC61UvimxbqxBqTNbOsl1EpzcXHB4WHPXM9oEKbpqmvZ7/fMYTxd5+V7NhcXdL/zd85rHijFV38q+Vxa1/AyK/LTjMIBFxcbPv32a4Z+JswzN/cHQp5wfsvf/uHf4uryms3mgmeXO7r1Gt91/NGf/AiUMEoFHMmoEsl5Oj3LMUZ+/JOf8tt/73dO72vp1eY51JTlUmW6wszsOs84iYpDk1l1lpv34on8v/3v/jv+3R/+MT/97CsUYs9SqrQxhPCBZl18iiNkqT+mSVLXY4zEmBnGmRAkOO7iYsPLl1dcX29BlZMkOEUZ4KYIXdfSrTu5dkpS1tvOs141LB59KYqdjzWIH5XW7DYrDtsNc7akbMgobu4PDP1I4wyN1TTWMDt3YusfxyPaam7vb9ldrXk43vKXP7+FEqodEuyHGW814zRRSma7WZ8+e6wSvnGe+OjVMw59z839Ae8cXeO53jVQJKRvsQ75Va+CAOjGCEHlm2fJwkRXWVcSkCHFmXGeuBlG/vKzt/zeH/8U37Tc3u75u7/1G3z67Y94/eI5rbcinVeaJYFGKTkj5hApo0ghyxpsJziBVoqVd8xZerMXHz2jf3vL3b4nAzNgGoMrGh6P2GtHqxQJRcqGxixyOs77VJJ922jzwX5wgndLIcTMV+/uuLnb8+72kbfvHnn//hFK4dWrS77/yUdoar1sDReXz7m+uqU/Doz7x195fZ++fq2BsBBnGmMlRl7Zkx+MNAP1xCxi+H7yiiilpguJFllrRdM6NpuOphoVr9ctSYlnxeOh5ziMgCTYTWNibiK7tWevlZiGGzmgqOypFGVhGSfTfOs01hvUIEaxw3GmlMLdXS8MqnGW9MRlio+YvOaoahIWeAPKGRpvoJhaHBfalTT4BNHg6+pHlU7skiJFgHOAAGEF0dyGWTTPyhh86+mcRVuRZAr9vCLtheq/JNcx58zYS0S4UmIKvkz6xFRQNoQwR6Yxkoth5ddMIZHLMi84Y8QKsMay23ZsLy54+/aWx4cj8xRqmp54HmhjmWPEO8t6s0IrxeX1lpIV+/0R2xi6tWfuR4bjgG0c3bqpVOZC01hc40gBJFUE7u8HDvuZmAQwUSWhk4aaxqGrhENria3frBuR1MVESomubXi4v2W1cvjGkeRc4ngcyDnjnaE/HDDWsV63zBczo5lpW0//aDH5QB8iq9azWjW03tEfMsfHHoViHAKP972YijtN03l8Z1BRZJX9cWKehb00TbHe73ro60LXWWEZYCgk8Srz7uQbonWmXTt802FtS9MMpJSIc6LpPDEXDn1EFQENcolQZORmjGxmVhm6dUcqMyEa0nHGtyI9NSkQxok8zUwKmtYzHQMxVo+dWJhDwjeatvPc3d1VALtq8MsCBIt0IcyZw3Fkf5hExnW9Zj/O2CDecOMQWa0bofc6g1IL8wJco4lzoCDmzEXBoQ+8e/NA23R88vG1JNEahVJJshS0PsuKlcQ4l0PGqIxSjhLh/m6AEkU2EcRE31oljbQC4xTGw2E/cXN7QBVH1zVcXG4Ypon9w1xBJ4Vz0KwMu63FeYXWGVX0qc5Nc6qMtwGwwrRRmavLNUVlhn7CefG8uHnzyOFxRJkaD60gpRnrLdN0YLPpJHkoFUIS1qa1EsAQwiC8j6yJSZ9jkg0op4FA11kep5EchfHR+gaDGG6qomFWUM3KYx0CaCt+A84LQ/HhThisXWMZ55ntZsWqaxhDwDZBZD9Ko5RFqFJ1Gk7BaUtR4FsY+kKYE9OY8BWMKymRY6Q48RgrJaPQlCTpPVllksn0j5E8FzqrKSGzvui4eN6xXVuMlXtvjXi8rNuG1p2jqEspOGuF5VJfXSusksuLy5pKVC+dNqQkiXTblWYcBvowSmNhNKuVw6iKvpSlMJEbL02zOu2/85yxFoqa0HVvNjUyWruWXISJFcMsgH49F20R78aYqPIYkV4b6yEFpmlk/7jno48/5ge/8Rv8+3/373j//j0//OEP+Xu/8/d48+YNf/SHf8hHH3/MP/yH/wV/8aMf8fOff8Hf/4//I0KIXF7uePP2jqvdlsNh5OGxxzrNutoAHPupbvsKpRuKssxJgIfL9Y4cjmxXmXHMwtI0UmwPcZLrVAqb3Ybvfvvb/P4f/CWbTYN1huOYWHUXQCbGA0+OexaIwS4AHAltA8aDa83JxBWgaR2rXVONu8WfyNrasFotE2ANCXlmh1FA8EKmzYHOW6yG8aGgfUHbKJJDI96X8zgzjRMxR6YwSa2iapx5ZSkKS0FR5ih+pWoJZzGVDWeJOaOV4WKz5Xg40HQ7bu4eeDw8UkAmou/e8g/+k/8Uawy///u/T9M2fOc7n1Jy4e3bN3hnayKaWOIudstayeeJBXRWAqjIboPVmpgV/SyhFVopVq1Ik6y1eKtIWXGcRmJEmONI875MuIVVLcmb292Opmk/qOs+qPeX5ywLmCKMgcV4Wxq+XL6Jop09t7QVNGqqTMTldWKClvgBCJcLmPODt7wJ2q6jrZ5PYqJ/9kiLtek79j3TOPHxJ5/Qtt0vGEk//XnnPwvA8Su+9HRNCodhEHZlEc865yzznLC6Q9f37Sw4DRfr9YcJXnBSARgrcpdcygf+SUqdWVULoAoi4cn6SeBUzqRcrTSeSuR+2Yd4eh3rOWxUxiiNKpmUpMZbb9Z873vfxWhL020kGEUpcpG8Xer/lX57SVM/gxsF8Q6jspSkplwGuRXwy5lhHE9m6JJ+aLAuQypo43iYRpawlMY0J9BvSUhunMLqTDKJrJFAiDnileXyogHySWJ6ud0xTiPrpqFoIz6NRoYqFEfMGZMUVi0ip0TjV3zrWy9ovOHm7o5vfetj7u7u2W42wqJUqhpXPwEe6llR8eZa7/JkSC1M4uNxwFrHOM/c3j2glDp776hC0wgL5/r6gpvbm1PYy6ZboY34MmmtxXu38TSNx1mLdw5rTPVmbWjaRjwx6xBnYfEplLCtfmkohkj6f/qzz1Ha8vjwwP39g4ROWAvW0jQtOaYKfMx0bfV0do71doe7ueF47Nl0BW0bGu9Yr1ZMIRBzwRSQ4AALiPn9MIxP1ieSTnk4Mi4+tQhLZ7NZk0vmeOwJMWCsRRV1ug1P64FSMqmY2hNy9sczFQQrZ7bsbrPi02+9YhwmGZzPe6zbYa1lHEZ+6z/727x9f8O/+b0/YbNb8/Wbd7z+5CXf/d63+eLLrzFFozDkYjBRSRpnEiJGyply8nwSy4cYw0mmKvJ1UKrQrVvK/Z0wewBvsnhnK00/zqCVBIFkSSpURnbZXDQpSfrqstaGcSYME4cYGY8DGNisV2JdYwxXVyueXV/SdRLu07UtqWTu3u+lF/AGrS0lTyw+jcYJk88tMkgnBv8KGShK+JtimmEo4CwYbZmTpmA/2Ib6aWYOMGmNN/LHWktRhYf+jvX6godj4F/+/o9wqhf/2SThFIKxn/fTfhxFobKSsyGmxNvbB/7Ob36b51cX/PSLr7h76DHGs9sq8fxFgMJUhznqr2AtLXueMUIy+fAlyhFdLQBSThymmc++es+Xbx+wTYu/fMmrqw3J3vP644949eI5qxOLLUMJqMrmylkTokjAY8wkK0D5u8c966p2MlqT58R+f+SzL97w9eOeUWWct1xf79jt1rx4eUV3vSWPM0PJmDnSrpahcfjw85Wn4P052ECE7JYQM/048ZPP3vB4HDkeBpSCQz8wDoEffPc13/vOR6TqO9yuGrJSbDZbNpsDwzDxN3n9WgNhqoiJvbFOoncrmoiqRT4F9NMI7EyeJkqOYpoZIkUJRfHFZUfjLH/55S1fvr/j9rCnDxOBiPa1RMyKSORhGFCmsG48Y9X7itFzLSNylTQoRdO5yhKLrDpPfxz55PUl/TATo0iMjscZpTQxiA9RKtS4cUm6cFbRbFqaRhqzprWQpQnMSRbtNIkJpXEGZaRZEkBOidd5FmPBuVIhY0xY6wihYFUhhg8LopwysU4XQIC0RUY59dU4UZ29eKajgHwLCJiTNKYxicHw/eF48joopxmeHNjea4yrjHFyTWcJlJhIlbFRlEQixznw/NUF09CQU2aza7m4XmEboW8OhwmcI0SY5oiyCqXcSXqjtfiTgeLYy+SolCoB0GIqnSaRsmnAKoXTRlIHQ+TF65e8u33AUFCtJ5fEeusJk0j/UpS0thwLIcxoLN47VqtGNM99g9GWOCqun3m+fnPEuYK2hdXWU2ZLzKB9IiYx/b286uj7GecN/WEmBklFSyUz9jPzEOr0oIIEWgz4jZFnIaRAmmTNayW+cv1xICaZinetrK0YJ7QB51tmE4WkqrMAK/URknQnOPZRJFqlnMzAp7lK15Jiu/HiNxEFYGnXDqUN7z+/JwTF0Es8dQxSaKacWeqjOYrMVGuFaxq8tsTHnqzEByTlRB6haxsOh+Hkh+Qbz3q7Jk7CRgxTpCiFMUom76pg0MSQUFqL34HObLdblFLsjwMvXq558/Uj1hS6RsDjKBoztDX0BwkWyBpeNA1jKsQQWLWe40F82bpVy2rdyoFuqSlLipIUm9Uabxtc49gfRnxnaedITkLz3mw93crQtAZnSw2AcKQkoLi1VoIGsqv7GxQdKLaIcTwRozM5SpLoHAVct85QUIxToNusJDp9mDFWV+q26PCTVVjXsF4VYZjOgRyLPMdFJpm5ZEl6TYl15xmDTPoSS+GoscoTp8QwjMzHmfE4cZjnmrznhAG2awUsdRIRPU8jq20jwK2z2JIoyj3BzAXMsxactpJwVNc7Svy8cpIuIIQk+6+qjVuR5zsiReI0B8KYmI+JNGdarVlvOr7zomG3bdl0Du81aNkbchHgbe2EdbMA/4sZp3OOtpRqYi2JjNaeATPxYJDrLBI+jTaeKRzp9wMxRL7z7ecYp09nmDR8CWct2prT8y2y+YQiyLW2Z38pbT3N+hKltEgQhiNaLV5Jld2jznt9yvkMENQ9do6Rq8srFPBv/+2/5S/+4kfc3N7w/v07/vRP/oR/8S//Bf/wH/4X/Nf/9X/DerPm4f0b5scbwhi4vbnl7v6RL7665diPeCcJw0sK4inFV8mUUUB7uUaXV1s+ffmSu/sjpMT9/YHjMKK1SLaELRUpRfOzn71ls25Fdhw0K99CmQhJUpO8tUxpIiE+NTmJZEtNktR34c9F6FNDdQmqiWJszgJ6aDHJT4kpiDeIsJQzIp7P9VoWFgeGwoTSugI/hU9fvmblGu73e7bdCuMNK78Slq4WaVb5AJgQQZn3TuRBWuOdw1l3ajhUgVXbsttdME4Tv/d7v8/b23u0Urx7/57/8f/+P/Lzn39OjIF3797x+vVrHh4eePvmDcfDnt/47qdcXT+jazwaKUQTH+b5LS1rjIkpRDEPN+YUtCCdiAwlTWXljSEQo3z2lAolRUqWszxVn7i2bXj5/BmXFxf4bkXMi8vdh68lTVGCVGTw5moarDTw4Rd8QJQ6R8VrI1TrENNJwrys9SVEI9bi/ATmGPPB10ldaZ80u8JoV8rUf/OgYbX2dKvCOBxBK7768R9Q4vzkZ4k/65ICfrqPWkyln3i6f/AqCKAYqsm4d5YQAp99/jUxJpyWoQ+ASpG2WUKfqsxbVUPhUsNDrJVQo5RPIMqy1nNlCXnr5NpnYT1Kqlc5AV/5ZJZbm5gn//bLXsuaUWRIwiKR2yb2FeTM1ZWEcmiTaZ1GSIkFlBHQcWFmsbxnYWaeTJRrWu0QjqfBUZgDKVdWVIykWa5fc7UTcDVlyIowZ27uj9g+MddwqOV+a61QQYbc8ziTlt+5fDat8F4kVsv3eWs5DhPPd5f0WtiBznueX6zxNSxk6AeOw0zO4JuGm9t7uk7OuMPhQAojf/6jP+fi+hq++oowTQIcfgMIOy1KzgxKrfgG4FQ4HA/87PMvmSZZk3OIWG2qdN7QrXxl0xS2K8tm5bh+fslHz5+jFKdG2FiRrlnXYKw7EQ+WexKzDBud/3BglKof0TcDLJZXSokvv/ySmCJt23F//8iLF9en3902nvdvbypIkk6fFZXxznJ1ecU4DaycQ1to25b1quOrr94RogRXKcA6T1GWaU6ntFC5z5oXz1/yl5/9mGkaxc8pBunBjEF7Tz9N5Jjomk4eh1SkXkfJAq3PwcJGk6GrPvUwCwgm54oVIkbjeP3RM0JKeK9o2obHx0c++egV/+z/9f/ko9eveHt7wx/+2Z8zTyP/7J//S97f3tfrniGDUVpSlauvdUqZ46FnGAYuan3rvPiVjuPIOAubKRcBIEMQ9rZ10jc8HmfmELC+kz4sJLq2w1lLKtX/rVSW16ISmGaGMUhNnkSya7WmayQs6tNvf8x63dEPA1or2sYxjhNffPkl0xSwtq2kFYtRmovLK1JKMqSr9FmtxcOyIGeOALMS8JLmxBAnQsroAJSMdQ0QUEuMLlQ29ozynlQ0Y8zs7AqtFS9fvuDNzSgWO2lkKBCfPkZV1RxSoa3rd6h+kpsagHQ8jtzcPJAVvL87cPPwyMN+4vKy59NPXqO17N/OWUpNmD7VuHUGszwhqj7a1tpTTSLPUHkC7qlTnfq4P/LjH/8l7/cjf/fv/g40WxpvuMLTrNY0jT/hJM4ajPUYzv2jNYKozyFh9RnoXfy+lVI03rBdr/j445dcX2wI00ycZlonCZyXuxUHY+nTSPvVLdts+PZmRTgNfz7cuwpCeiBzYvZSYIqBOcnwpvWeP//xV7x+fck0Br776Wvu7w5MIbI/Djx/dsX15Y71uqOkyMG3dN0a0g1/k9evNRCmsTgjKUWnAIvlgFR52SXlixVVDiMP7ONhYJgjylhWq45CImZEi7zxrCaHmwx9lAjtnAuNVvT9zDgVxhh4vl2xXbXCkKjTpxDE30RZmQCIBE2J38QoGt/7hyMUwzhk9g8zx+OA954QIlpbxB9H5Iy+82y2Le26xVpFjlEkUSXRukY05/WQiXMmVvBJ1UJnniNtJxP3xjdM40QumdWmQ2MIs1Rfy3QAFCXlOlXIUA3jF9+T5elTdfJmrKlyEc3xcfgAMRc6bCZHORTEjF8eBOfVyXhYa9hsthQK+/1RgLA5kSsbztRky/2+p3WWOIlZOhW8CmnGsZJmKxeMsTS+oHPEW0vjHSmI0WjXtkxjRBt5j+NUvWdyEhlHBm0tGmk2c85MIRCyQuuZlG7ISPrnMg1erd1J4tQfB9ngciHHQrK1wAxBJkvbhnHcY5Rlf3ikXXcMh0E+qy5016oGLxmM8fUwBX/03Lx/ZLVruX9/xLWWaZamunCOnpfrL02ZU9V8WaIvaTuP1oX7+wMW+XtvnZgiWsc0DicjyW7lsUa8RsIsfgrWKbaXHTnBLiRQhfubI2ihKsc4Cz03J2LMkqZaMofHnvu7PUa3xAmmMYm3k5Nm3TeelMS8dBxnfNtyuL+naS2rTUvIYsqckyKIWgJjFSnO5CJG3DLhKjTXGlVEz34KAK4U7U4bRgr7w8SzZxdS0APozHq7Yd2KnVDXShCEMpaQInMoZDQRje0a+l7AMI2haS0x9AzjJBJoN0P1otMWOuMAkbbpGke93W3Y7/dc71oej5nmak3jZuYpsbtseP7qgnmaGfojcyhQZJJyOMyUkrm+3vD+3YyxCr/uaFYdn37nY372s6/JGfohoLUlxlLpwppcpNhXFZxRCpzzrNeF42EUADiJX1lKUZh+UWGLFmpzWibH4FqH3nVYa5hCkELPC2NFmo6GOAtjchxn4hTRldGRcibUqd/DbU8qGtd6mk4KFm81ynlyDjhtMUlXg+Jz8lnJCm3PfjGLHGAxzy0VWLVeGkHvFEVrhjmIxDsq3KxJY+aTqx1ziLy8WuMbw6bzXG48jRNZLhV8LUUYRc6I74gwUUSOXUrBWsemaTFOfBEWb5Zpjhz7kf2xrzL7zHGU5LJpimQitzcPqAKvX19yud3I+VGE/aLV4iMhMow5BO4PD7y62qGVx+iCNRZtBFg6DDNuJcMD5xuZlJRyKn60Fv/H5drllCu4JE/LIgm5uLzENw3X19d85zvf4cXzFxVci3jnKSlxPB5IYaaxhjSOvHt7x8+/eMvXb+8YppmYhDXitDmxPyUF6fxsamNQCTYrYRj8t//l/wLvLJ9/8ZYv37zliy/f8/7mgXGa0dZinfjOaET+GasZckqQ40yJhnk+8vXdnlQy67XYEsg1lSrTGIUxpTYvnNbQcZpYaY9JwmKwTppSbYQlXYj045GCeNiJNOpcJReeurVlMdivQ61SCqu2ZWuF/aSVPkk4lFInAEwpSfdNKbFqPCiN0qayMBqs8wLqVIsD7xzWt/z0xz/jizdv+OHf+R3u7x/Q1rHZbrm7u6Xvew77PQ/3D/zJH/8J8zzx0auXfPLJx2x3HUVlkpISCgQ4XtKjpzkQQ6TvR3L1UF08XM7se2isxnsn52IW4HzxhpTAllLvkyTMSfiMqSESLWGK51rtyWsBFpfnCc6N9AKA/FUv+Y5f8kVlMVf/xX8rFR1awJSiFteWc3ty9pyt74Xq16LAeSmrc4offKLl2VssKISdpSsj7BcbhKevWAdsYhYt4HdMss/5CgxqpejahsuLNRcXG1Qsv/DpldYoa4kIsBuiMKkkPezM3AEBJkKMtR7NKC1+WtJAp9PnrhdNztNfAYSllAS8V1QfvLPXUIgRqxWtVSidWDdSr0pK5RmUFDx/8ditbPEzJacGZOnq3TiLbCuK5cUih1TIYNNqC1pRjOztzoi0agiKw/EoXjhUMKxUlqRSMqR+wkRzVtO1nvXKs1rJfY0p8fzqQlLuahOfsyQZPr/ecrmTYcwcoqhBZmlEv/Vqy9VuzbPXn3B1/YJXL6+xzhPDzDwdJYETBVqsBSoyeFqrSiXZL5SkI2t1VqzlKq9uvOfh8cA4zTTeC7vSgLYQc8Qa2B96rncNxkB/3NN+8gmNd7U9qICXhkLkbKMioE+qiZa5MqS10jjnJE031V6jrqsQwgkUKnVv+O0f/hZv3t2zv7uh7wcx7daK7bpD5cR6LXWH3AN5JpUCYzTzPHEceq7WO5RSp7CMMAemccJWU3xlZP+ag8itx2mirSC7BG5Exmmqg2wBFdu2QRtDjJFpmmnbhDFL+6zAOJH515ADsfYQ4NtoGc7E9OQJV9TrJSz3Vet5+fIaYxR3d49orbi9u0Mz8nD/hk2ruTfw5z/7kruHx1OdvmxLsmUJe1grRU6Jm9tbUphPrbExkhi9nwNhmpinqQKm4kU3TwJgimJqFvWOlvX94598xnrVEVLg8fFwWufjKDX7NAWRguYPn8nNZsXLF1f81m9+m6bzDP2AtYqhH9jvD+IFlZKso+pFIFI5XYfVTlITqy1CoZDIHMaRfprEk7k+16UkHo9HsWNA1/W/eOQt21SiZPGGzYi9BSlzGBPaaaYSGceBu/sDRmvCL/GuVBWdEvvBQiyJiRlrNF3bEmPgzbt3/Mb3PuU//Z3f4t/+8V/w/v6B16+e1bNLQMSTby6gSsQajVUJ7+R8yWlRctX3jj5JYa0Wz+qIJdU9UmXwjePjj15xDG9RCta7CyiZqxcrjPcoMqpkDBL4JdW9LCAB9A3Oiefp4r/ma3jV8rJGsVq1vHxxxdfjhHKWZ88uub8/cDj2/Ks/+SkvXj/nD//sMz7++BN+iOfqYs1ut/qVbphSfz79DzKce3KeNM6SUma77XjVNXz3Wy+42K15/eKKy8sdXddKT54iznWsupUk3f4NXr/eQJgWY+9fmCSqX/zvZ4pz4u4w8O7+yKEPNK3n0Ec+f/MgZr4p8e7+wH4ciSVhrEgNJc2toAeYQma9rlHzKtIoYf2kXIGfevNMPYnifDbhpUCKEGPgeBjp++mUZFhKwZh0lnJqhfGazXZFu/IS+a0KKY7n6cucQec6NcyMwyRUycoCeCoVLaXgvaeogm0lAW2aAn0f8BXI00YT5yiAWd255X0ZWK6FVlULneUAKbKhKKWZp3A6MFMSH4icqjfP4kutFApT/XqojKAZ1IphGKsPU0XCq1+LbSyKLM1/54kpYp2k3/XjxDAFNOKPZZRsEs6JJ8M0BYZjz2bTMQwzKUOa8onBprR4SqUgPmgKK7qHXH2JkBCDeYo0XeLlyyvev79DW8XxMHF53aGN5vF+4PA48fzFTgp3vUD7immaGMbEZu15fLToVuNSR9duePP5W8I0czhMbC9XWCPvy9ZmNQT53OttK+bBuRD6eJINPp38Ve/KkwwlJ4VuXAW1FP1R/MPa1rHaNnhdvQZKxhqYYq6yyUhBDMtdZ9i+uGAeJ4yGprG8e7uncZb1zomsZx5JIfLY91KcN4b1uhXvsghkie8ueYkQ1qQQQImE1jmRxxqnGaaMayy7yw2+9YyPAyFUyVCRI3O7a1jkiKtVx80wAGIWWRJ4Z9hdNKQs79dZQw6lDpQL93cPNG0LKJquYd0JWDlOBes081TIGFIGYxxX1xvaVoC927s9K2+x3nJ4HDGmlVRY77F+xhlhnS3AUa5swhASxhqmMGCcwfiWDfD27YGSqmzVOUqSiZtCCoDDPKDQbDeekj3740guIyrX1rtYbm4fmENkGgPeFeZhYA7CwnBO6OSrladppalTCKDVH4bawMthOPWTNAgxEjK0VWY59BPzNKMbJzKJriWGhCkJ67T4TJRMzIE5LCldpSYYxlNyU6m+JfNUwfsMxlmcs6ji8Y0ha/HOUkWDs6RQmBEGrULjbINR6eRZM88ylVRKjOcJAiQ5I1I4pRSNtWyc7KFOGeYxEtYFqzSX245V51h1jnXraBt5VmQbEzmPNQZvPApJopI6XDwMtTYyUTUW76Bzlp/97Auunj3nOAW+eHvLw/6AplDKOZGuIF4L0xx49eKKeRbfiOeXlyfZUqwS7AIc48DD8cDD8cjPvn6Ds45397esmhVXF1somRdXl1xsL6X4XaQpdaIO1SPFWXI9DwTMP0/FQxBz7abxXF9f87/5x/+YaRzZbrcCLlrDixfP+ejjjyVl73DgsvO8uX3kL376NV+9uWOcglwbLXu30opYx6pt40nFEOLCRJMkT60trbNcXl9xt79ndXHBK+N4d78n31mUmyn6QCwO7zdYU5kIxkgZWAoqauJ+wviG1cZQckTrTMnpRG1aCtCCFZBFI0a/CryXcJgUM21naVvLkh4VUz6x+qJYXWEdHO6f+GugBDBPCW01QxhQRbPpdlyud6yaFp31aahUamiCMebEdiqlCPNkDujqaWiMQVtT2Woj2gh7VOu2ej45jv2RlAvPnj3HWsun3/2U3/yN30RrzTAOHPYH9vs9X375BT/5yU/E0B1hiefKTko5o5PIwPppFp+3cSZMPTlI02SqX1HXraSxNDIcE1AmSVJiKuQo8vpYJxel0sfW6w6F+L58/NFrri+vfknR9qR8UzLtrtzPXyTC/BLwqKT4CzPn/5BXzNJolBMYlln4Nk9T0J4yWxaQTv67yPn2xz0r35wNyzmzqZRSlL/eI//885FwhM1mxWbdVrA/su5arNE4a+kay7ppuNh2IierTZyuzEQQs3BtxB8s1DWNWT6XwTlh2s9RgIvyjc8JqjLFFhYYH4CJ32TnfcAQqw2pUgplHMpYSoxkFSgl0dhApsq7ayq5gmqncb4OsjcKEGC0sE2Xmjtm2S9TBVv1UkeTmWMgx4hTms77CurJQEUDU5sYgjoFoBgt6eSqJGmqURglFh1aF6w1tN6yXjVsNi1tp0lFUlS3bcuma3A5oAaRIbYGdOeYgzRrSinGWbHYFnSrju9877v4doNS4ueotCQCinT9zFJdQJAPgUie/LuwO+bKlreVfZRzom0anPXynCaISuxSyiRMaRRc79akGMkp0Y/ivwrVN6jI0Fxkj6FK/sXnLVVaY8rptJ/lOnD0ViSUSmsOxyMP+/1pfc5zYP/4yGc//5Lb21um45G7+0f6YeL6StZ303g2mxVxDsQQToCT0Zp117FZrTkcDuRn29N18M6fZYJZTN2dFW/EcYpV/p5Pq8v7pg6cJqZ5pPMtClitOrxzxFrPnIGVgjKOdvOK+fFrcsmnZ62Uan5utIBE9evF501TdJW5pgRFsWo73GtXU1Ph/v4erTLz1IuPpJdnYmGG/8IeoapPdn3e5yjD5Vwyuohn5Ga3ZawD75KLZBplYYZO4yRWHlokvNM8Q5o5jkL0GIaBYRg49gPznERuHkVyHOr5rpXiYrdh1Xm22xXf/c5HxCAedMeb40k+HoL4hi0Asa7BB0oLoG2Mqf6iMrhNMRNNOvl15yxelgJ61fMrZgLip5jCJOqUJxJqgN12TS4ryFJjz6GCUSWhcmQYEnMIrFYtD/vhl17jomTQHpPUMEbL8HicRnKOqAwqNRz29/zdT/82P/n8C97e3kvY1PI9thBzwuZUfe0WYEzX+5ErSUSYg8ZYnIKSA0YVsjIkZT7APowx7HZbutUd65UnzDPPLzPbxrBp4LJNmNJDEpZwqM2i0QLWyrWXAKKU82kIu+y7J4asUpUIIoDd4bHn66/e8+7hyPt+ZD/OrN7v+ej6gqvLNatO+s8UxFtQV7B+kUMuqZnLAGbRi5knZ6r3jr//Oz9gCjOt91zuVqy7hq7xrFqPdebUYyhj6NZrVn2Pbxr+Jq9fayDMegGgYsy/stRZokGnGOmHgYeHnje3B97cHrg7jFhrOc6SCDPXJEZd5YUGTevOU86Vt5SYKWXC6sI4zazWFuPEv2ZpMHMpWK1otEalzBwTOQmzrLCYByZpLudwakigGntWZoOxhqZ1OKvE/JmFcntu0mIsoAoUVTfgs9G9dxajJZVNa9k0fOsISYyZCwISzHOEogg1UjiFSJhmwiyglrXuVMxJ4SHm+d26pWs8OWUa79hsVpRylGjZ6j2UC9XjiTP9M4NO51lq23isNsSQmcapGvMjfkRWpjTdqsHoIpOfEGSyqsVnyOTM129u2axWWGPpNk4mp0oOoXlMhLmQQiGnIOyYUEMASmVKKPGOmUdB4JpGDK7nECujAqYx48fAOM4iMw2BUkamXg6Si53I8uZR2FNN6/Ftg6QSRVz1CVAUMLDrvExSQpWwZonmtlrTNo4QlhSqyH4/8bifxC9KSSKLNYqrizVffP6hDrrUSYVW4tWUgjRuU4yEChq0naNbt+QKIDhbUL5KLmMiVvJfypEQJ1wyKCu+InOUTTKrgnUKlaA/jrKOtKx9pZSAvMNUG6IiPnPGVmlLApSAXyhIWaSzSuSrftMyx8T+Zk9/lIZMaWg7zTxmtrsW4xRxmtEkrC4M/UB/mDBKYy2gxAhca81wjARTsF6S+4ZxxhgrqTpac3iUA8042eBd0y7dLaqueVShaR0fra+YDhMxQR4D4+HA9fNnaN9h7Eh/HOT5aywlK6YhEFOgacSYWtIKYZyliCxxFqZN60UmOEeGysDIderfeI/zRuTZ9xVk04q7u57V3LBanT05pikKC+XE5hQ/QWtl8p+T7Jcx1gCRPAlQoBWoQpgFBHf6nMgjUm95XpWWJNJxHDG+FVqzqvfdQEhTNR8Xpov4yUiDEkM8eQulKEWy9a5OoBy2MgudztXEWzOTxVMuK4yyWOsxJsoUugj7TgAFReOMDCxKwRmJq2+NlT/eSvormiMzs5GCdNVa2kbABW/VBwUA1Kl2XbciHxOTz4KA0r5Gd2uleOiPMERuD3foN4/cHgbe3NwzDBNGFVqraJ2wZ2xtQJ2r6Ue1EHFW45w/gVQxJu73e/70p5/xr/7wDwkqUlSm845pzujxgUmNfHR1zRCP/MXPf8IPPvkeTdMgsiLFkjp5rgkX1kf+wCdoYdd9/vnn/Ot/9f/m6uqazWYjjNK24dNPP+Xb3/423nt+/OO/4LDfs+uu+csv3vGHP/qimuEL8xEFpqhTWrLcI03jNaiE0hlrPSDm3auuJSnF46Hn7fuBh8eRrDp8t2HuIQQPxZCLk+l3nWBK0hKMIaN9oaFgTSTGiZSDsCGsfOacxdPTWMCCcfq0ps3C1NFKhixGn89aLftzUNWLU8uBtiyTU2OUMiFR2QgapRwai9H2VAAaK346c5pPd6KtXnK5CMPPOQ84eYay+KRNcaIArTN4Y1CNEeNn69hut+QY+Z//9b8m5czzF8/RSnN1dUW36ri8uuTFy5fsdjumceLu9j0hzMzjXP3lNKqytR4e7hnHkX6ODP2hgmCSzlaEpsM0TwzzVI91RUwFMZGvw7+wDFRKvS6c1oA2cjauNxth4/91rC4ljIq/+esJL682SqhvAjr/Ya9y4vuda69f+Io6ZFFKE6YjxykwjQPb1Qbvvez1QjGrTXxlz6vlufvGT8yFEEOVPms+enVN05r6fCl83TOUKnhrTuwZpRDPMCv7tzrZXmhc47HV5iLVc0AhZ5xWSpilJQnTFfHZqX2K/KxSIP8i8+vs9VI++Lu8/JynclMWWamw3Z33GA2q9NVQ3C+XVOTQSZqipQZdPDuXZimRWQyWcz1vlt9vtMLVpL6cBdjRSkki2vKZF1ajzxQlZ8AwSDr2MFimeZaQopBZOQfVAmXVOtpWEuxWa0/TaGJOGK3YrldcrzpslRyLFElsOrQuTLPIdbUR+a6xntV6y+X1M6ZZwJR9P5C1JJTLfgeo5RyuHXk5y6U+vL7CfHW1l1AIG1cpQ9sJgB5mGSyW+pyWIsEX2/UK5xrmeeb25j2r9Y779lgHrMLsk2dAZF3GnEHjxjf0x571bk2YAt5LWrE2RgZ8VjwOvfdc7i5OtfXDfs/bN+/50Y9+zN3tLfM08zxEcrWDKKW+//o+FTXRV4nXYNfITtQfe0LKLK6Dcq8dKUYB8JDQH1f9mcSTMZ2+drPZ0nUbYirMIVPFNFhrWK9WwqIM6bSfLJ561nmyNhTvKZNYGiz34tQDnZ4LBOSN0hjJsEvqDG8dV1c7Hh4fyFnIEykl9vsDb96+IwaxoPlle6aUhHohCfL2zXv2+4M853VoKCynmWkapc6qe4RcY0AVnK09Zg7iTQXsjz2NUbS+IacD0yzkACprbL32XF7shB257ri+2jGOo7C/xsjh3YF5XvzLPmT66DqRynUodN4rvmGaPgsbL5dca10ZjgDVNzUwjUI6kV5KVCIvnm1RKPopEFMkxkCOEvogJMXl51RZaRZJvzEGTeRDaJ8TAy/lxBxkuGaUIkZHaTMrr5kC9KME8r15946m9qvDMKOKxpp08gO1VfWz1PtZ1aFPFsDPGLnGiz9n1AWN4YO04cqkWzUd3/noIy43K5wxbNaFbQveihfhHCsrs4jFxqIec1ZLOrkSySTx6Yddgi3qZap7xtuv3vHTn3zO7e0DN/3IXchMqQo4VeZxzNzuJz4exQcyhcRYCtvOYlHC0H8K3n9jGGa1AMm5wItnF6eAhnUFv1ovZB6tFEkp0pN0ZOcd3WrNat394oPyS16/1kCYqwZ6sZppA6cDUSELawyR4zRzd+gJU+D2ruft7ci7u4mHYyDnmSllnC1kEtZrts2athNKnbYa1zoUCuc0zma0kYnuPCWMB+OXSXMW/xwtBYmwQcppkqzrfR9nAcCmEE/TCF2p9ou2XArFjs2qkYM9y8NgjME7X40c1ckQf0mn0qaCZbWI11kmYzGKf5iAYkJBNc7gG4ubDEM/14TNJCboqZpLa3VKjjJVGrlIJo2RxnouSZLBvK30xOrNUITZcarwFoBXFUKSJ01phfeWzXYrU8qQRN5YJynGaqy3rFYtXWt5eNgTKzgVpki7WlOiNJby2eSwzxliSRATJSWaCjAYVw0jg9DICxbrZFIwWsvsEvNUzSafpNvIxi3X+/H+yBSF9WK04nDo0cpgty3rdcMwiEH1uuvwTVvBFAFdQpWTYsSbzGpJSrLOijl/MeQIU0zMc6hJcUtDUdjuVvSMjMNECnC4H8TstyAMhzqkzVkmJNkaUkr0g8htcsg1tUgRJikCthspRGO9x6lIquhisO20haDQ3pHjLJ8/jJhiIcnaGIdAypHtRYuxmpgiaZSURFn7hrZ1eGfx3uKd4TiKMb33jpgj/RhIleE2zrkefLXwyPV511qmIkZJ4EBKhDChisF7Iz5ajchtTd1sY0ikQ6HpHNpauralpEwcA/2hJ6VK8deGZy82NRiiYE01IbciB7FO064sbWfpvRKvtjGwdRcoLWwu7y3DQQBm653o+lWRqGfv5IC1mhgLKUWmMXHYDzSrRta60hwPA/1xOqWQSjF1nrjJcydJkylmDqVwOXas1x1GK+5vDyeGwtJeKUVt3uvfFjk4xjGAkgm1UYZmtWIYepx1NM5DgTDPVSoqFYAuMlk1TpihvnH4xsv7TJk4zZQoqrwlPegp0B/mKJP6Asoa5klknraxGG/JSCHTNp55LsxIsqwpqjKaPConQXeRpjvMSYyInYZiQYNB01nHrm3pvHh+aaMosUDjcSqjlGbVWAnEoNQ0qg8PZFWLgaVpRQngJ0lnnArMXArHfuRhGrl5GNlPtzz20+kZVmS8gVVjab3DW2HSXl3tuHs48PrlNSkX5hhlvzWGxjvGaeYvv/iaP/iLn/Dzd2/xnWa1lmugrSGkxP3xjqwCL/MFuSSaN55PXn2EbVcnxsFT4d7yWs4nWRiF9WrNi+tr3n79Fbfv31c2ocSrr9Yrtpst680GZx2fffYz7u8fudjuuD28FY+9iy3GaEJKHMdJkjzNE1ZVEUA2ZlPPOvBNi9KacQ6SvpkSMWTGIVCqB6jSXV23EGKVmBlHUYGYEyFmxuiqRDRRSChtKzvYSrgM8swpsrC/msJq4wW8qetxGCLGyRBqnkXirTjLUxdWowyzzrHnC9uHyh4paIx2su81DdtuxWbVCYtT1VTK6n9nKlifSiZV3xWjwbqOZUI8x/mUPmq0qbIRj/crlNKn1KthGHj2/Dk5JX73d3+Xtm24urqm6zqUUhyOB+7v7+mapg6fxLy6WI2OI+M00x+PzPNEnGdUrtJnfU4btNaBUozjRD/NoKWxXKbzWsl++QvNWmUDUcN7nj27xlj3V/K1lvrmqUGx/OxcG9u/nu11hq9+yT/8slcFphScWWHL/a2xAosR9jd/YM6SPD31j/T9kc4bURYUSS7UZWGbKlSVA/0iy+38J1UQar1qef3ikrYRKwzvDG0jLB9VmTo5JZFfZ0nVs0ZAYsGulEjCfFPT5soJ0JB6QKRIIMBMifEsv3ryxgr1utfGq6KM0pQWkVnmJ3v9klr41BtqYTQtzA5rhIGSSsfKNWhthI1UGWEpJUqtWxfGiFIiEzpzeZCzNp9v7NPauiDArDVGmI3GiEdO/Zm5DgBeXq3YrSwhbNkfBkop3O97Hg8Dc5J9Y5wjc4hsNo7dpmXVWbrO12stqopNu6H1Dqo8WgFOSciCWVQaypDxeA/KODarNc575iCDzbgkri6fUSsEXC+nOu/DdXNGSLS2Iu9WIgFPuXrOWo12BuctsXHVS1XkyzGFk/2JtY55HGmbC968fY/CsFl11e+UWoMIUwUlQ4QFUF1v13jnWbctrfcoUxtpbSqbzpzWGqUwjBM///xL3r2/oR9G+mEgRvEKXkIh9BIEo/VJZqvRWF1ZvBVcM0p/wHBe+qlxGNjttmhlRVrsZB2kmGo4iSwi7xvadl2lm1FY53mReSr2hyPHYTjJ2hZfx5QiSlGDR+SPQgzW+YbsWXrUArVnTE8t34r4Es+TKGOmOUhN8Sjy9pIjVskYWbZEoV+UUvfKmq6qjZXrGKT2oErEvPe17hyZpwlVbP3lMqR63O/RSsgYaI32Dc6LHP+jly/xn30pZ16txVbbDc+eX3F5sWWzWTH0R+Hz5Mw8Tbx9I6F0MqzMJ+D2dC2Q4atCat0llVmIGhXkSuk0jJ7HmRikPtLmDATlLECZrI18Yi1dXnT041DrBmE7p3D2lRRS69PT4WwjYfTCQ/7wWVsAoZwzMVaP41qvabX42IrKqB8mYeAnqVH3D0ca42UIkMU+INkkIHdRNSBMVz+u87rIRbAIY+RZVgXU0+Ov7sdGaa62O3arjhwnrJpZ+adcK851TCmkLKqiEBPOpAqCFlQR5Y7Wpg7IqQDrsocXlIEhBt73Iw9zIhRQ2rBtG64vLnj98orvfPKM3aarP0I8n7XOp+u8XPpvgmAohdUKmzIhFS42DU5L7b9uWlkn+gkYnUFL1SfPapU/b7db/iavX2sgDDgxJpZpd9dYnBG6dAiBcZ7lT4ikCGOAfswceqGjDmMClZlzAi0x2bpqup0zOG+wjWzACknY60bH8SDm5e1KzPCF5qkqe0AW2TxLil+usoNUY2T7PjIOkTB/iIpL86PxrWO7XYl5pSqESumxNRLYVYbWUnDm8iQtsk75dD2oloWbUhYpBuVUtECpfg2iKR+OUoDrVkA0W1FsmdKpkwl/SVQZlwGTySFXlotMq6wxZJNJ4ZxgeHrVIkQesio5TYX+OOG9ZVp8fKgNvztPCIy15CzMn6bxhCC+S95ZLncbplH8h47HqRrFS+GqalE7TwGdxC8hhCTSoSpLIUYBWcoIKOY5SHNuz946C8Qap8RwDGIcbwv9IVBShLx4fsiEI8yJGPraJNV1Wk28FYqQhbLsnJjsh5yYJzlQxd8invx7JPEpY21mdykeXvd3E2Olsi+bytIc5KxOmvpS2YJaK7TVp/s6DjPaGopSzBmmpJiSwjdLkppsik1lR6AUs1LEFHCtxRkLRdN2LcPjKJPpRsxUY5JCP2VOsrXWWxTgrWbVeTAK7xQYSzzK5DfEwHAcKRmmMTLP+cyQ1AJKNZXmP42TFMbaEJKkyMyjmHRqY0k51gleRltD2zm0gm7TYpVGawtZfJFSzMLSGiMrY1BJkZQkozWtI6YsIQTOCkvRa7xv8d7VQ27m7uaBcThHWC90Eecdq5VM3GKcSSFhjGecAvuHnmmK+LZhniP3tweGcRQ2Rc4VJNUnSSEVWLBOi+Q0RVIpjMPMat2wXnumwTENs0xbP3j8xAhZpCOFkjVt69hsGgF2KlDgnadpGozS1bdtIoWMMgplCiFH8XQLUx0Q2BODac7TCSiIUZhTOlczzFqUxhBAi5ebNiLXsNnW/UX2h1L3kUAUNhoCvAtAIIl5uWTCvEihtXi/2IRVhpDBKMPKe67WHV3jULo++ymjvcbqclqPSxOrtcPaGqCRS/W/rczbIt6Aso9V8ETBlCIqKkKM3B9nvrybeDjOHKZ4ZivnTCmJqcaID+NM6zWrrmGbi9zDaWZ/HGgbz6EfaJznOI78+z/7Mf/2T37E5+/eCOPS6RNbKcbIMAQBjcNMCDOHqQcsF7sLtr49ySJ/+evMRi4FttsNv/WbP+D+8ZFhGJmmkWkaGPsD+4db3hlJZ07V7Hmz26Ct5+7m7sRILAhbQCuD9cJUySWTp5kSKyBw8j8DrU1Nbl6hdce6u2K33TPNMyGCcwWnIZvqC1dZIVpbxnkghJ5kOrR2ckusQxeNKhOKgiagSkbnwjRniso415D0RNu6k6F6KTDO8tzOs8g9wrTYA3Bm8RSZbsrZYdEGcklYJdisdwrlDGGElbuic2ta5/Fu8dkR1pmmPgNL8VY0tkoHZDouaa8oaNqGZQCcskzVtXEY2xBC5P3NHdZ5/uN/8J/wW7/928Qw83u/9/so4NXr11hr+fzzz/ni55+TU+RbP/ge61VXPX0itihinDge9pUtEIAs5uVamB+6+raUIl6k4zBxHCeatpME0woSKsovJNs9Of5xxrJZrdnudmRlfkFO98HqrD/zKWteztJQ79mT3/FLgK2/kgX2za9/8qW5gjoftkgC7mnE2/TDVwYVWWC3qd+TUhKzZi1DOZU1RjAkuf8nQKhuJWXhJFQ8Rwl4lZEJ96rxpNbLmdQ4nBFgZa7Sc6NkYJtLxplzGqU2VkJ/mhbXtJWpJd+jlIAXC2Ag11eue0wCHKHODKyFpbBc2+X6L1Jyo3Udop6/7um9PLNty9m7s2nrOpSadbnHJYsPk67fu/zOBbeGJyzXWtIuLES1DGwXwKhwkmEVo6ukWMAwlID0YYw0zrJdNUDLqhVZ3Sn1sErt5ySA9bqDzcbQ+kZ+DuK7qUpHa5uT6mJZKRIiI3WMPEsWdMEnYY82vqFrO4YhME0D3aY57ReopVlUda0VFmbhsngLCrShEOsQ06ARY+00y3WJVZKey2JKvQCUMujxxqCQwJy2a7l+/rKudcNmvcI7K8ClE6aarTLWha23eP8pFJ2zWF0ZSlAHMhrRfEs9WUphmmce9weOx567u3vmKODpOIodg6KmQNdh4zRKsvGz62f4lT9d2/VqhdKK8IThrLUApv3hSH4eMMrL0N6aEyAcF9saFNpavG8JUViR2lhyrGwt77i5u2cYxtNwWhUZ9oVpRhdhp6cKkmmVqwn4ea9YZKvSk5RzncGy1yVKjJSajvlw6Hl87InxPMDWJ/BAdEhg6mCgnPfcCoDPYZbebJ5AqZryKQPOaZzIOTDPgfv7Bw6HI2/evD/5vja+IaPox5mv3r6HUpimmW7Vsdnt6FbdaTB7dbklhpkwjaQUOebFt/dsHXBayL90o5b+ZnkeUUWk06UQ51lYk8YQyTjk76WWPQ9cFvavRjxH+3EgxsD++KHEUUBvVd+GOu1N9V/rcyzki0M/YVBCqvjg/dZQmXwenurl2VYyrAqp8O72ge26ZRx6pmHGIOoBawTIoWRKBfqLkvr3JBc18n5yEU9UlMIoqZc5221/420t7C0vXtalWtSfAKy6T9Z9USsoKlNSlHC8Inu5Ko4YA4qIrXL5hTGPQogTKPSq5eUnL7hW0k8qY7jc7fjk5TO+89E1z59taZyoJbSz2LahkCgpoHQ+f4Zvfg4lwL+3MqC2FSuwmgozn58ZltqMZcAk3+8b8S77m7x+rYGwZZpmThN5YYEYFKWa1QpVGTaN55gi687TeFOvfb0DKld4ddmMajljNMoIEi3G6Ukawlq8tJ2lXQnLJRtwRszspzEyHkeGfkZraDuRwfR9YhwjY5+JgQ9iuzVC87XO0rYe38ghGarfhaqAyOL5ZbWtTJYFzKqItDn7QjjvRPqRBfn9JugqCYeykXlnmIZEyoU4F1yzTJkXQAyEfSEeTLYV09asZAMOdbKcc8ZqQzGFpAtaxXNhd/qwShIH7eLBJcj4WFJF+4Ul5FsHdVoXQiaEjPOOOM9Cx/YC8DTeAUHee4i1gNNCt69PmEI2mP39I03XUiRqDus8aC0Na6lygTpxVa05xaRrrQXYU4Y4JUo0lKTRTjMeA1p5xjFjtBih5QT9QbwMdPVVyTkzyaAF48RLJo4iEZyGSFSJu4cDrXPSsOcIqlSfI3n452ng5eu1sKwctK7j85/fMYdSTfLTGfyqTERllZgqO5koKCUARJwTVin6IZDQHA4T0xTw3RrXNeQCVieMKxUAKBRlWW86Li+3UkTkhGs6SSBUjoIiV+AtTpG5n8Xrogi1XUzgZ7quwdmaYGdUnc6J/0JMiZKKeDhMT2jQLstB4haWlLyvtm3IeSJGAcZzCWLEH4vIBEuhcVLEWqOwFja7DlPTG8deCps4R2ISsFobJ3uL07SdYxjmKhdRSBy7rNumdYxjQBnN/uHI4bGXDTudwVsxnxTpcU4wDTNFFx7ueqYQ8auWcYykmOj7ST5TYwRYz5xiukPMpBBlsmsMXecY9gNYRZwi1DSftrGEKXzQwKeUGccok3EkASalxG6zxjnL4fFITIl5lpTCMCfmFCQRZo6oVFBFGi9KYegPxBBo2g5jF3PoJCBXgVTkdxkr8lxjNU0uhFlAeedsBQSr2WlRlKIYjxPGgHPVdyhmVK4sE+qzY9MJVJbAB5GNeGfQZFbWkbOs+ctNx24lE6RcRGaoKkNJPK0XU+FUE/EW/wOZeqU6xEy5MlGQJvYEhAH7YeJ4mDn0E7fHyPv9zBDSkylvPWdqYl5MpQLTGjUZ7vcDvvF8+faWcQqMcxApe8r89Muv+Td/9Gd88fYdmIJtxRh4AbfmObM/zKy7BusKN4975jiilKFrG67niVXTcLFes2pXAoyW2kct52g9F3IGaz2vX7/m1atXAs6HuUrAE2i5TuM0czwMwu5ylhgyX715h7WG4yRyBJRMw701NN6KDEiFCmIUObtJWNsChdY7Xjy7YLe9omRFSIVx3jPPhXEsjH2mxEWKmMlKQNcpyvNgraLpLGvvmWZhc4awJ8dJvB5zxqBpZsMUpurRJUnNaaxG7UrOsTBzLpJrcSgehek8ECmwbhzW2FrLadou03rFutnQx0LKHq+uaJ0AWjEXjKprOcvDaZQ53QdvDKqmxAoTxNbTUaSa1gvLI1WfGIUhF8v7uz1fff2GFy9f8ff/wT9gterQSrO7uMRoGRD4puHFy5dM08T7t2/Y7ba0XSPNgxYgNqUkQ4EUT1P4U/NdmT6lSommOUiTWgoLNnwCdKAOwH6x4SmIBPr6+orNxY6ErrSJX/FafswTysRSty0svLIgHafXGcD6/1UO+U0Q7PxmBKQ5m+Uvfx/ljxJ/z6l/rOwafdqDxdOzVEaPMHWWa/ZNs/xl+QnzSf7eaLBa9ierTd2fJOQHYN1JunAiYao5eS4FlMNYjW9XGGtlEBJL/d3qjOmrc1MogFeCmjxJHd7lbzbc9d0aI+D409fCrFgM5+UzVQCQInu5l7CeHGQosQxpT409Rc6qCi7wlG1YzhLNhdUWczgx0Z4C/GLVIUNGkdPJkNV5GVBlAlOMlH6srPPCPAf6ceZwHJljwOkCRrNqPc4pmibgXcZoAUlBSZpgXEnDpsppcxWsScAfbTQWSypgotQ0i6n8bnvB474nxMhWL/fkDHid//cy9PzGS51BJuAU9FCyDMDnKdQ0X3fyzzyBlimjUQKiotlsd3z88UdY41BKhqHL2WMXKZW1sHga14VbkFrPLxf/6aouqZq+SWGt6meZpomHhz03t3dSd2kjDMdJ1Bu+ShR94ykUjscjQz+w6lanNeadYziOH7DoxGPJMAxH5mlitepkoFo/y+LJeP56S9eumB+r6broUVEKdrstX755S6h7JLXOzikJe7b2HrJjF5TKCMuH+jNU/Texqqh3SEAJQcQosfprKiX1YLUcsVW9oxfpMwt4rhEIIJ/2mVIknffYD+wf98QY0FkG/wqwxlFyYRgG+qGw3x/42Wdf8JOffMbd/SPjLMbvynv2w8A0zQzHnnmY2HrNt7/1ivXugqbx3N/dcfPuHfe3MA4CPD0dTvyHbL8lm5PHtjFgnWNhzS1DXUURhZYSD704S9+nKpGka2QgK334xOFwpF59YS0W6T3lOp333BOju/bTBVivO/TdkVIUKmWeite7RgtolQSkMfXaKiU4ROMtIM/F65fPifMdCs961dHUYYYwXjMlKYpxdUAh1htYeV6VrjVPHf5x2k+fgj+/4nrydE9fzpRqBaEWy+4MRLSOVFyOWKDUgXmpQ2w7QaOak1WE0ZKy/q1vv6LxAoQPY8Aay8V2y+tnF+w2LWjoh5miFNpLcIgkwaeaREwtjZ8UpKfFA94ozFJXKNnzQgpiZVFDAk5DslKLj1JQJdE48Vf/m7x+7YEwq4SWr+uVmmJgP82ElCTGOwvzq7GGUUesKRhTaFvNzd0MSphgy10Yp4BLiUafaa8qP6HAzjIh3mw93cqJn4t3OCNFSM4TIWSmIXC4H+SwtRbnBbiKQQr6MyLNCaBazLW10RRdZPEYaVjnOGOLPaHJqo4QxbtDWFPpZKy8SEcWCrb4okgT/2RagvwubTRNZyFphjEwT0JTbVpJq1oOmpwSYYp1crgAhOKLEOclUlem/UZbrC3gFVGLxKSGxkBZEvSk+bVGs143HCobwnSatvU4L8ku0yxss2kKEgFstEzI50g/zDR+LekeS+GTIZEIk/gzOF+Nj0umP85o63CNlWLAaKZ+ZDiOpAqGaQXdyuMbfYo2TylRGoXGcD9LsZUp2Gw49hMXlx7IpFiQuF7xAzmBYKVIkIASSaoxIk2chpkYZOMNQYAQ5UU+V7KwcJw1YBTRO4xSdJtOPBRerthtdhz6gYe7gXkW2ddSKMokT2GcTD5dZZKknHDWcDyEyqCbUdZyOAw0XnZDpajNl5dDt9RJ1HGg8ZaLizXDNCFym5kCssG7hhQTj/cHpuOMylKEWmsA+f8xZnxjsWjmWGqalKbfH7GtY7tbs3/sK6tNihVjluTSUhtLaJuGQhHJjpF4dO088zwTkviypQoEUsE/reU5sxZiCuIJpmWCk2IihyKm9q6cCj5fjUfVIjMJBaMcYZb0w7Z1WF2YRk0oGW+ELSlMKYfSAsiN/UzOlmlS9OPAsQ80K1mL435knGcIhdXKS/GkhO3YtK4ariZilibMe0POlkpqk88aEv1xqsCtreC+PDtDL4mTSkO7sjSdByXg/pQS4ygphs45ki7VRFYo2BaFrdNeYwzGGfqhR+jjZ9ZpzokwT3jtaRqJwXbGobQhUWhSZuzF/84YI6B6nZbmUkhzpg8D2ijazqJ1Js7CQD2Tu+UVQ8R6hW8cJUTxxNGZxjTsuobGWhrv2a26CpSLbFMjqWHopdlVApDlhC5ysC5mtxT598UdSOTSC6Vb1kKMmfv9yOdf3XEcC31UxNNccmlUsjQA3zjpcymMc+buoSemxOE48LDv+fr9Hc4Z3t8/8POv33K7f0RZ8dWC2vTVtRhDqawzkdvq2tB+ffuWw/FA635O1zT84JNv8e3Xn2CNZbfeEKKAFdWdgqLqsARhSpZS0N7StFL8NN7KeefFg20Kch3GceLdm3f8xY9+zJSo0/jz2XbyctHLCFOSFgsRckDrtbCHcmK3brm8WDPMR9ro6XpLNxpWo2Maa3Ib1dsxwVwCTduik8Nby7q1vH52QcorGue5fzCMhz0lOVAyLe6iY5yt3EdtIGmmPvK4HzEW5iCiFoPCtxZTmZIxCUPXGiOS6erZsQCS1ip2a42zmrW54PHQo+IVFDHmNsqIsbAqp0JcAcbr0/PTOAfGUGKUZCfn5YzN5aRO0EqhrRO2h/bMsXDsv2Z/OPD3/v4/oGk8//yf/3PapuUf/aN/xOFw4I/++I94/vwFV1dXfPvb3+b+7oaQglgMVcP+fk7kOUK1F0hEMYYOoXoy1XTLIp42ocqJGqtP7K9YJSnWVB/L86jx1PSVItP2q+srnr18SalJYb/0pTg/8GVpVn5RXrP8XHkKquzor2gQ/iavE4DzN3wVIM3iPzMPI2EegRpYs5hjc8b0pO6X66l/FUti+dm1Lly+WcJXJDk8y+YozJf6daoOiZZ+tNSuefFVFR+tM7CysBnOjLAKLpnFx+ssFxKQ7MnQuH6t05rEWcr3QTP8C9dVvF8W5tAcxKvH1kTjpz9bGFny2RdgMZPPoFrlBiwsK0ljDISaWrjcm1xZzJTqEfhEbbCEaA3jxPvDI947+sPIGGZRliTxPk0xMA8zbWmECaXF/yyWIM8HmsY4ijrLwZclZLTc60WCuXzGXBJzjDgrzFTfbarkebkWSsCUk9gORJpbKiC7nJ/ne6KrH9TTq18qoCiSNRlWPb0vpeSTVNYaQykiQ3r14pqUzFk+f7qPTz5cWWBAeeWcKUbSSUvKHxpkIXVCyomppmY+PD7y+LDn7bt3pzWrOAeHDKOYlysl3qTb7ZY4R4ZxEI8lK/WgMXWPffJWtdZsNivevvma4/HAer3CtK2AydV7bFkrqq7P9WrN/cPxFGqxrNv1Zo117sTWP93DFAlhhhBOO57WAnYtljmqJn3KQHsxeH+C8ZdSUydTBcI0XdOw7ToZQHpLP0w4Z5lmAeFsndLPsQhgp6VflCCByOPjnsOxP10jGVBwYpuFIBLft+9u+PKLN/zsZ18QMigtoI4ohSKaQuMcm1XD5cqy3u3QztP3PWHsMRoO+8cPnvlf/frlX1OKIkfLmGP18FRsfGUs5TOIaI3BKEglkbPYHGgWmbd4wIY5cnP7ePIjgwp+64XpX4FlJefEoqqSd7f01I7GO9q2pR8lhT3lhXgCjZVeOuSM1lZ6xDrkm6Nhs5Igrk8+esl21ZLjT5in6pNcpeIxRciQrSFGLQN+aetFEmyMnKV6eShUvS+mMg358CE+Xdta05Uixv7165YzR4Zast9N0yTrsSRcZRqDeEMvg40wFXpK9cMVyMhoxfe+85JPPr4+hRJorTEY2rahawTY60dR5F2aFdroD99ufa4K5VwuPxnILL/naajMudfIp4+7nBXCHJVnTlff4uVM++tev9ZA2JyoU3ygTqvGELjvj/SzUGqdFnqudYbZRz77euD+ONK1BuskOefpqSCpH0lSjyiEKQkg4CzWGlLUuKZKtJxFodFFzJS11jRNxrv5xBoDSf0rZOYpMs2yuGSgsIwDzwVJqsWyb2SKF6uPWEwJo88SgQWYWxI3lKLKZczpUNCmxhqXhKKI14pS1bdBpvUpFSkgrUH7gq2HnipLBLAVYESr6veUK01VrvfQz5LANkeGY6jNsQT2Wmtx1hGCoPMlyOI1pjKVlMGozBwyDzePdOuW1a6RSXSllWtb8Egq2zzPrDee1ls26xVDf8c0Ry62a1rfEMNAQSanpcAwTOSYuWw32MZKSkd9kFNM4AvEGa1E459SJsXIauXYbj1NZ8glMQ1SqHWdh6xYrT13NyNFF6aHCect8zRjDTSNls3aGWEUakUMmf7QS4GaxFsJVT26pkSYYBoToURW60aaDC0pPSkkpj7XZXKmg7ZdQ5jFyP7yuiWHmX1fiIlq5ilspXZt8V4KTknykwSWZtswTYL4H/tA0zlQ0G3XIkeoXhy5yH0w1uCMxsWIt5ZQ2TjrVcfj/V5ip1FY7wlzT5gSJcpBZqzFecM8RS6vNsxBvD2c92hruLs/inGr1mLweLEmpcLxkCGkUwEohXHCu46usYxzwLcSlmGqGStFvn4e5Z4Za1G2nIek9U+KiWEYyEXMY3OVDptGCmNOxWTBekOHJyVNCAWyNIzGiORLK/F4mysby1pTi2wp+nMuxDkzz9LEPDxOzDGxu+ywjWbqA9uLFeOUmOaJmAvHIbBqXTV9bClKwClIrFcdSgdC1OL1EaMA74+jsMFSqT6GBqXlme0PI+Mgcu+u3Z2ez6JFGm2dY5pSLdCKhGbU/cU4i7IWbc0pqVFVk9pFEgli6p1iolk7msbXhDIl0jHk/a9Wkn40DyIte3g/1XANSCGTigCWKZ6L0KXAsnbxvEmsNw3OVo8PFfGuxVvF5bZl672Y41cvgZOvUE1HWvZ6XeUjZE4T85QKpQjYr3JNMqoshuW9LDjZnBIPjwM3d0fe3R1x7ZaQJHDBOkMM4TRV45cWibJPTjVpNwYJcejniTFM3NzfE1LCOVP3jPObX4AwSZd19X0L+FmUNHqfv7vhsP8KozVvbm/51puveXZxxe/84G9REnRNhyJRyNUfklNCUaoekaVUGZc9TyS1FuNn7xucdaQ5cn11wWE+EoYPWSFyBi0SyFOrhCqTeLIpjS6ZFGaeX+9Yd4ama2lzx+X1NaiCtyvW3SygeckMx5FpyiSkme2nQNt4nCpcXqxoGsc0Be4fqjxICbMz50Asge2mI+bMOCt2qw0qj3z11aGCWgVUpms9jfMUEnGexGw558piQMIA6ksBbSt7V+cajn1mGlqsiTTeyRpEGH4qS2O0eF55405y25gSmsI4j8QY2dimTjozJUOOkZJFnqisRluHNeLFEmLk1evX9MeeP/+zP6dpGv7Wb/0Wf/qnf8r/45/9M77//e/xn//n/7D6+piTlQG1DBkmkde2rsUoI01/mEmpNonanqbduTz19yjkGIgLQ6qAq4EwRnr4E+FreQ6t1Wy3mypl0pRfwQhT+jwIXL5XwJ9fZMIUlkK/YFGnZ/z/79cv/Tkf/mUpkFLk8e6Bw8Mj8zQggr50+srl6DkV7ct1zOK1skz4T59GPf355QQeDNNEjFHY+NVTrm08beuZQhAJv1KURTKkaw2oFMaKxceZRSfn8yJX1FUiWbLYKPia2Fa+sf990yhfayXn7BxPn+Hf/8GnfPT6HdfX+9P3LSy75TzPlW0Q01L/LmtoGeSJF2WurBoJTNAnsFarJWGtnnX1+1M8vw9TfdLClGtjlzFaUqS9M2Qqe2YYeXg48tmXN1xfrHl3s2e1clxdrVB16DvNkf3DgaZRFLXCmIamsaCDDJ+VQZFxLrMktS+NndJyT5aEy5zkXE5J7C+0luZUGS+spK4jlzOIVeraVvWe/fJ1WAFLbfjwparXlgznTqwi9eHPR2lSlDNLVaa9rbWesI1y/d3Ss+Qg4U7C8hCWiJiRR0rXUnKDlwk8OUWMNgzjyP7Q83joeXdzy1dv3/Fw/8jt3QPDVMNDlKIokeZOc6g2C4nGiw/YZrvhsD8wTZJGKLVnoetanr+4PjEhFQK6r9eSNHk8HJkuJmHIOkfXtcI4m+Yng5tC1wmL5CmrUClF15wlsE9BhxjF89Qu15GErgqjkOqAQJeqUimn7xYQTZp66TtjlcBB4x0vnz/j+vqKn3/xDm0VwzDRto14juaM9w60EYsKpU5G8wXxaM4FQpgZhoHNZiODLyVnvADhovTp+1FArRCZs/RnzlpyjBgkrMBrQ5kT+wKPx3cSfhQF+H9KrjitxSeX6Ixr/OI+f4aFAbWsX2qomIRpUT25Y4rsdmtKyYxDL7VR9fkbhomSI/uDhLUtfoIpphocJgyuUw9wKsnOzOLlkdLacHW1w2jNarVnnCJFm/o1icYppjlKOnHJhJIpRuG0ZooBVywhQj8cUCiuLi5qOJImpVJ96cTqXuuqfCiRoh1Oy9BZVB/n/VAQs0ypirCcymk/+PDaCp5RcoAcKUYLuKlkvcWYmEPkcX/kq7c3jNOEKiJj3XYtH726ZLNpzyA8cvZM4yjhYF1zwiq61tPpdikDWLDFxe8cZE+4vljJXpMCRUsvWrL0W4v/KiBb+6muqJ+q7mlPn8NTL/vE90UpVdPDf3l98Ne9fq2BMIBhjjROC9PWSDEaU+axH7DacL1xp4SBx8NAP054pxnnRLcyqMkQ4vlByFnAhxTE9PTpg2K0MIuoc0eDeMcoAtpYAaOsPjUM1onB7BxyZVgUhl4mqVrJZGQ52+UvAQXOm+qXI0CZNNz6BH4t8bI5Q1K5yiSoaXzqVAwt9ZRSmhQnjG1Om6VGJEWRItPKip5qU2Ontapm1/Jg2Sy+H3Zh1VDoHycxIo9iBLiYHC8HqEw+8zIjqbJJCIGTv0XJWqb7sbBrPU2ltobFcwy5DilmmlYuVLfqiCmRY6GQ6fuJnIqwvETvRN8LTVfrmlrG4pklQJFDU0KkbRwqw2rl6A8DY5xRSAqosAwTRclaCHEWo+ATFVPul8hmcvU5a3CNx1hTpxbi+9XvR5rWy3XNtaFOwg5ToRDLBAXinE5+cItnnHOS9Nc0hqY7sxO11TROsVo50lVHLDPWtvS9ovGmfl8iRaFOz3PEeQdKsz9GhjFVg8lMLghAMUW2do2txUWq0+NMQdmG9dUWQqRMBRU1wzjRtp6UBHicxgkoGKyYOlqFbz3eGWKVLPjWElIkTVIgDIeRbuXwbYepxbJ1AuAtEo6cSmU61eTVKD/beYjjkiIk18Y3jrkyN2VflaQy6wzaIiyIVDgeHwjBc3m1E2DYO7S2wryqvndKCTDTrTqmITNPIyXNIk/2LSmLRyAlc3WxYtW6mqajCLFOCDPCFi2avh85HEey0lwoYURur1aUrGhXjlLTNFMIJCdMUufFfNxYjQriM9Z4LYzHpPDGywE3R1ZdQ2ONNBcmQ5KimyovFGBIptOmFsxWGVLiBBJP0yymss7SOIP3rjJMBdyFjDFimh1jRBmZ5ktfrSha0a032Kap4H0gpKmmYym6zjB42a+nQaSm81BOksQUCsYqUOKrVxIVXNQ1WKOTaTgQc8bohpAyqyoZ0kpAGu983dP/v9T9169lWZ7nh32W3Xsfc11ERmaW7a521c1mczgzNEOKAt/IhwGhv0yQAEFvkiAJ0IMgSBQwMqQAiS80oESOND3dM1NdpqsqXURGxL33mG2W1cNv7XNvZGUPm4+1gcjIuPacbdb6/b6/r2nTsW/Qr3MtKISxaatv17vJeRCPqwtzdwVy2iQ85sLD48gvP7/n3eOZwynCMoncVomMIvvENI7Esk6Knx0KlDKX1zcvkfMcqA+JkCNVZ+KzQpwqDZtkrLYGpjHUtNJY69HGY01qLKKCUkVYrRg+e/2az9+85qO7O949PHDVb/hXf++PqEqAhpQlPMQ2M3RJ1IrSlH74sjFWGjUxzYXtdsOnn37M28OXjPP5iVHSnuWniZ2EoEjzrXFa0TlJD91vHbUkTodHAK6uXrHf3vHx3SfE8SQm+qVCjszjyBIz2nje3h/ZbweWpIDCsBn46vXXEjxhPf7qipoWqAlrFGan8VZjjGOOkfNhZpoj3//kFZvOc54j43yi8z1Xmz1LmFFFk3RBq0znXZMFralVSFKxN/TccDt4ppMY9+6uBozquNrs8V7ur5rT5R7UWpFKokVaEnNGl8I8y0AnzLPUH3VN3bMCnOgKSKCHqpLgKMyHHS9evOBP//RfwfuO3W6Hs5bdbkfX9eK/OE1QYRj6xtIVmYS1su5VregGR8rCpi9F7gu97ufpyYNpPUopLNNEyNB5MSZfCSNa03z2xH+wFjmHd7d3OOvWOeBvHCIVulRfDZQVcJa6fqzdk0o1vtXT8PFvx074cPr8N3/Rh/94/j21VnJKPL6/56vPvuT+/TucUXzn1UCCyzDQtLWjVmEzVhQUYYesfmMrkFPVh+tULUXW9xR5OBz5+u17Cor91Z45BG6vd9zUemH6GKPRFWouws63tg0uVilca1p4GsCKDEdjlGZ5OrFAkzI28GRt2C+giwKlLBiDcpYyVf7v/+m/zv/hP/53gMr//H/yP2VllKFWo4qn5iam3CTZVszJtxuR7FQFxhFLA4i1afVkA7iaefbFy62BdWtKJfDEYG5gvAAbUicPvaNzsgYsS+R0njiNIw8HkSXOITH04lkr+zvEIJYXKAG1z3MktbpJGDmFcZ7YDp0Y1LMCYsLwWOchpflEPmesUCvePrVjxlhSk/qsrNqL1HO9bvoptOECMWqRgV+ARaWg5kvQ1XbbE5vZeN+5tgbJ4EvkXAPOWx4eJ0nkTKUNzg0lzwgZX+qLJ/ZfIedA0oqcxJ+sWM1Xbx+5vrpm8B3zOLHte37688/4y5/8jF999gXv3t8znkfePzzIoN+If5J3EiYDhWVpiZ0hNlWDsHSmcWogYsRkYcg4b7m9vaaSiDHifSdrtfdc31xL8m4IbIqoCPrey7We5ssej1Ls9/s2FFtTqBTKGIbtgLWG0jwaBVzgcg7kkRHz/djWiJRXab0wtzvXzMjbgDTmQipigzLOM52VZOrOdXSdLI5f+QPeGYaup/PuwhbMMTGeR6qSnnRdj7Rp7NMK59ORL7/8jI8//i5d17GEQD8MHMaJt+/fU6skvr979yBDj5wJS0X5XurAWlEZpiC9nncSSqX1OnjQFw+9ZyvWBTj9toAeLuuOrINyDlWrIxV9Z/Gdb0Fqjkplu+l5OD7y8sWtSDrniUohNB9aWc+U2LA8Y0NaJ6CRbiECVKlLygVceb7Qys+oVcDB3XYDVAnIWCTh3WiFNxXfGXJ2bf0qLSzhid309TFzOp14PI7sNsfGaDSiNtGV1MDLUi2UjNYVbcUqJDXQyrun54tWwz5fs2vzwGYNMOH5+8kfXJfVvujr+0e+/Oodn3/5tVhxTIuES9TKpy9uGafAv/Lj7wngW5vKpj0Lsl7VC9t1vY4roP4MGxYbQ6XoG8OMUqlhvgCRBfEMM8ZwkWZ/4zZ6Dn5d9ptnpIgVRFsHOCB7Zfn2W+5fevx2A2FFCqvjKdN3jk0/tIm9mM0NrsMby6bz7LqOzlmuNh3OGOYQiUXii5egG1BVLgsIrXD/zXMqJ7zXPVEvHI4n9rsNzntyKoTGsnHW0PW+GemLx5WmYHUllaYb145a09P1r7SHo1Hq2xWV6ZckXpgqm0XJRYqHFDBZY42j9w5jxRw8N3NtmZY9u3FrQ1O1ar43iloE9FItBTKFSo6FYhPVaYyXsNYYCqfTgu8s00mkVjGW1pCVBppBCJEYVx8NKRpWFkXKbUqcn9DeUirWC3Os6zQhiu7bWovWkFPF9s20X8P9/T277RZVoTcDJcI8Be5ebVFKcTqOYqJtDMOmoxR49+6A0koM0xsAEGNGKd98X2AJuVliJGrNIhtVGqUkvr4mzavtnscSMLZ5vLViP6cokczUVvkXaNfWuooymvNpph88WmvmuqCVITS2oHEGoii2lVWknCQmduspqRBjxVjPPE+kkHDesOkLWln6wfD2Kwlg8L3h1XdeYJvRf9cYTtN5wRnLchYp8DSOhCWLeXQFYibMmav9jrQUZha2VxuUNbx/OJLGkf1+z7Xv0J2CIJvF/kpAs822Yx4XlILx1NJqZIBCV2XC5Z2n33QUVVtqj+Z8OlOiFLPnw0g3eLY3W0rKIlFr0xvnNX1v2u6rGDYdrpPCC6S4TUGSUWstGCsTS7FZ05AFQPCdpOTEnLi5umGcBaQe9haqwhsLFeYQRJbaNRNYVdlsNKXrmEYpDo0t+E7hDCyLXMNewXgO0kzGzDwFUiwssySwVCWAm3WGzbZvXmWVlCrLObDf9SxzIC1aaNTGiG9AEhlmUc1vbKkMXrz9pkkmqaeHGZRjf9XjO0cfZf1Y03SURphFWgB8bRUoTYyFfnCULOyyeW6DAK3QrnkPWttSnwT0E3+RxmSJiX6QoI6uGyjakpVG5UCOCWWKeKr0Fudhs3XsbxTLnBlPkelcSSSIAjIopbDaYLuntFalhSbtnCE3aYAA7wL8+Ab8OqVwxtL7HmeliCpFitNvDopKKYQSGmtJCjxrBaDXGFQLnPhAFqJa4Vcqp/PC2/sz5ylQjQcsORdslQZKNv1milyh1sz6IlYD6JyFaTDNEeuqFFxOoUyScIJLwSjDgGzUxbekZE3O8nnXjNit5cIgltcrgwpaytPj8chfxp+iCvzkr3/F3/+TP+Xu9sWlMdZKPNtW49Ta2AvPcYXaBi/rmMhawyefvOKz1yfmkFvRKAlGujX/q7zLGtMSCzW961DGclwmAWmN4cvX79C+p6oF5Tqq6Qk6Mmxlf9NaDOmPp5l5LtzevJSkWQRIfTgc2G43hJT4wfdfEeazSFdSYFkeIURMUZSS2Pc9nfG8+frIP/i7f8C2L5wncAY+f3PP3a2kwR7PJ8ZlEhCgJJY0o7QRT1JtGNyGl/2Wj/Z7UoKNWbjeKIyqbAeLb/LHqhTiNCLTTGssuRW5SilMKY19o1t6ZBTTa9WKxZzb8yfm3jUEaiks84JzjtPpxB/94R/yH/wH/yHWWrbbLUZrbm5uuL29xVjLZ7/6NaVWvOtkOt0K+NWXU+qg1AywLbbrQQmTWYCsp8n55ZFQkOaF1GSOqzgR2sBPQS0Zq9d+s9L3HZthcylon6po8XctNUNu95iqoCsq16agaMOx55KrBoYVIP1tQTAUVn3wgfajnj6oGxPugyK9Sgecm0Tx+HjPl7/+Fb/8+V/z5s1b/t1/4w/Y9R2nMWC0wRor61Yp4rfXahtTS/MKNG1gZy+M/stwFGGmLMvMOAfuDwuffR24Py1UHtkOnk8+KiQUG6vptEUR8F0vDXsqDNqxGTa4BpLIEG81pV7/SJNhnaOO47eeLyEnlm80KAhj2Fl024sFBJMT+n/9T/4t/uF/+F9fzmmp4ke3NstSo8r111rj+638rvUKqdp8ngQUys9kaet9W1qYQkr5A0nkKiE1uqMiYJQ2qtUiDZwsldA87yQgAu6P8v6Pk2bJzV5BwTRljK30W03MhTonlliwJqKVESBrfuRF2rPpJJjHWUvnntqsy56Vn1ihK9yby1Mw0mrpqwQJQzeJ6nNZJe1finb9GvvPWPeNCyfs765zvHxxzd2N+AP2vW8sWCU1QO/Z7nbUUpinmav9TuoaY7Cqst8079r0xDABhbIdMUXIBee8JA1rww8//ujStPdXO5ZlptbAdtvx4u6G4+nE128nnHMSWKWUeIs5J0BujZynmRAT4xTZ9J0w1I0koU8pMS8TvveXt9r1nvfvH5l21/h+B0rR9z1LWJiXmevbO7ZZ+sNSqxi8N/BJBjsCEt7sNlwi7zuPqY6+H/C2QhUmkGn1UEqRHBc6XzBaiApLfGLb1iq+ubXIEFyAMBnsogQMfnh45Isvv+Jq6DkcR3KKbLYD5ylCVXz29QPGej599ZL9tudwmnj7+oEwZtRgWBPBnwIqlDBEU+B4eOSf/MVf8cmrj7DWcjiMTEtgXhZilHM8zQsxBAnImYPcVUXYbLlIir2zlhe317x8uRfv1+bNVco36oMqpInKNwquZ4cxWgILlGR1y5ouQgzrVyZUZLfdc317jbWOTz99xddfv+P+4YHw7Dlft45a1Tc/JAOH5t9FzlS9rl0i6b9IyC/Dqca4qjDNgev9hmkKF6aeoeCs5Xq/FUCtypDicJpIRQazoJiXRO8db98/8vL2hmHoeXw4cTqN9H3HeJ7oBs/V9VULX5G1yjkZVFdqY1835mbNF8YVleavldvgXBD2FUxaEylrzhTNBbj66uv3fPH6Hb/8/DVfvH7Hw+FEDJlS4Wo7cHe34+OP79pwQ0nCsAoY61jmSdyFywru10t4w+W44GG1FbiNIabBPFNr1wqq2wirXdXLnvJtw6vnH7/YFSgZJkiK5jP26wqKlcJKXvrbDsR+u4GwmrG6w/cS3X04nwlZJAz7vufl/op936OVYgyRlDND71EolhKxnaZTImm0RhNCEuPRIie6ZiSmoD5Jq6pS4oPkYTAD2+0GirCHTqeFh/cjyxypuV7Sx0TSYxiPI2vsLiB3SNEf0jVLbROjctnkRNC2TsZkkdBGN9+RZtCoZPNTdZVFtsjkmEhBUGPvlby3WCQ1zhkB7Zzj/v2RYesxXjyTlNIUKuM843FstztKEVbN4f4J2YW1QHq64UrzhBJDwLXhe4qRfg5cV2RyucyRzdZjO4vpNDnK4ppixOiCUpZ5jDhXqUVzWGZyLBgr6VW+MwwtddIaKaBSKijEEHUcJ8gSE9t7YcZYDdMkqXjWNQ39GhPfkkdTTtQKfe/puoGUMtudZ9hoTuNakCGyzb1ERS9hoVMtTKDKfXB9vZXo31I5HkdKKQybHmMtNdYL3XueAlp5QilsBo81hnEOhDmgrPhpLLMkVtZaqWS6TtP1PcYVpnGk1MLdR7f0G8vQy+Qr3WZqLhwOM1/96oFljpxPSTzQ1mm1Ubx7fCTrzLBz4CzdZuDqan9hHJ3O4gETY2J/tUUpiVzuhp4Xn1yLGesxSLGrFQUao6zQbzYUVXh4OPLRq1uG3hGjBzWRS6FzSNEYMmRJirO9QTU/qRQL+11PyolpnEHvCKFiiM2ovdANWsBEJf4GpYJVlpIz5+NMrZ7d1QA14XxPGUdp5JIUQHNcKDHjrBbTyir+ZavfnjIKHTRucHSbDp31ZbJrjeH+cWa78Tw+zDzcTyKFbemtWkWgsrvusabSbx3jdCAsgdsXd3Qb8V+yRfzrvDfin1JhWSbCw8zHrz4mp8J4SrhB5DDrM0c1LCGQj03aNVis04znyjQlVAO9cixYZzgfzvS9p8bE7npLWAQksE6xnBbQlty5p8e1lktIgHXdhekBQsGPUTbVEhK5HFsCXsU6BVh6Z9hsDV0v033rdIt2VyjcJSnNdyJJpCj6jRV2GM0fqQFb0vg8ybuGzuKdYeM83rpWnDU2U210bfPMGLgduSRK1Q10N60R1S11qwgD5hsjplIqS0g8nmZiysRSqeapnY8xyXOsV9avRlnfJnsZakKrQkmBXGULTnkhxFEm0sOeWEzzFpF1nyafKFlTkkjlclolQbQCqDYvriZ5MsJ4S1n8X4zWaJOwWaOBx+Weh/me63rX1jEFpjaZeLy0XTIXqh/cByEGSlaEsFBr4eXLO/7en1m+enPPw+FMCpLWpMgscSaXgNUK3bzjgAb+zqAiJQf+/J/+c5Tt8b1juxm4vtq3ybDm+mrL1bZnt+mpaLbXL+T6xcx8ngnzQikFp8So1nlHTLHJhCrjeeTXv/grvvjVz5gR64I3bw+UUnl5veXP//KnvLzbMi+Rq90gYJCufPJiz+3OcX/uhKFBJueA0Za3h0d+9NELSlV87+Ya2xo0rSq///2BuRiudwO9r9gqXhxFPzGqVl8n20DAFSxw1uG0xtoO1/WS8BdljZOLbQipQFzQamWyav6L//w/56svv+TF3R23d3dcX1+z3W75t//BP2C73fJXf/VXTNN0AVaneSYG8etch2U5Z+aUMDXK1FzJsCHHTGpyeG20MJm1NNjaaGkAooQWePcU/V6AqkEpg1MajWa76emHXqbGqFYgPxXUuTx5HsnNzMW094ld2Cb731Ls/m0HwvpZDbMe68+9fI02KPV0bXIWmcjpdGA8nzgdD8Sw8PDuLe/eveU0zR8W5+trev6iGmhhrPxp1lUy1GkVeVxS+57KsiycTyOPDyP3DzPn80LNWewsNFAjMSxcX90xTRGUeNEsU6Qg9aR3FqeR0CUlA0ZYG6qnF5dlQvmM9feM/VfrpXG8TOARBsrTW/vwhP6j/9s/4Go38+//D//8cn7Xr9AKdF0ZkfWSXllygtom+xUB1JFAKAG0mr9eYxPkFIQdlsUb7LkvjNZaAMiQiDExdEY8KrWSUIgqFh2dF3bY89b9cJoxRjwi+84yp0LvNavyUHxfE0vOhFhREQZ35ng7cTUMvLrb83CYuLve4pzso6skUs4vDTKuUJLI0doAI1c+qLHbbXNp2p/LuYy2H3iEffAANJDTGPEqvr7e0XnL1X7LfrdjGAa879BG03eDsEBjYBzPvPzkI7yp7XlQxOJaGJOAFdaqluIG22FP+uagqRZMYz2nlHj79i0hLiwh8tXXb3n77h6tNc55vPf0fcfd3Q1GaeI8czw+kmJiGSfibkfKMnTpuo5aCsfDkavra66ury/np+vEwyvESOvosc7hu45pGkkpU3Kl6EpK4oFIDyknnHFApe+6S5hQzhm0MCKd89gmL6bUyzWU50D8WNfXsR61ynq2PmKlii1ObqxtGhAQQ+LwOPFf/5f/LcOmByLf+/7vg9pJneS2fPLxFYfTmd+/+hE//fkvef/+iOsUIS4U213GD6v02VjLV1+/5Xg6oZTh57/4JZu+Y5yD1HEtiGNZAsfTmfvHEaXT0wsFtNUsQSTefd81P27d2MQrgCOKmA8P8fT84CPP+r4QpZ+gge9yH4p/8WVlqYUlRLQxvH944P3bd+TcALa1Ob4gXh+uO9I3y7NrGtEBZah1ZWRfhMZAuay1MUapGxbFeZI1WCuwuhKjeCkrLAWDGwac0egY2WpLrZplWTBKcb3b8HA4cv945ONPX/L4VydCKPz5n/8LQLEsC59++orf/wPH/novg5XVAoCm+imKUmRAQtVi+avk5WttKLUNuNvJrTlf7BtKStL/KIUxEr7zy8/e8JOff87rdw+8P5w5zQGtFYN3LDHz2Vf39N6x3/0A50ThZrse5zpqLYSYLoMMtYJx37zqF9bqs4FZe80SFNM+EGfG5Om9wevf+DHf+jOfX/PnQNfz/Wndv1NZSTnp237kbxy/3UAYjapdKkuInKeFOSa8k2lmSPlCq5tjxGhNZy3FF8pSRIKoFcZWnDOyETeENCzCCLKuTZs9XN/2zLOwx2qRRk7okJpllgUzrxtdQ2mN0fjOUrJsyorIB+M+1Qyt2v7lvGs3oXoq+NrG7rTEwq8xrTHJpl+L3KRrehCAaimUWmnmGAFFThFjnk+LNMOmR+uZTz59QaYScmKwNGYGguy3uOhh8GyvekmUmxPlX5L2VGvGaAEZQ6gXRoCAxQqMTJmtN7hBqL5LiJwOI9utw7XUvJSkkdxue/EhWxbiCXbXW7y3AoBtHPMSqLkyjRMxiXSr70R6Np1l4TdGNV+GzNB5TqeFfKhNdphxTpqMrjPkkjieVlaSYrfdMAydmJGbwtBbxsbEMUZQ0rgsbDcDpcjGKZICg64KZzMLMI6BMEecl2Qe6xXpkLm53bNMC7VWxlOQIsKAUkXiqtu9Oo6ZkjPHe5HvDFvPdEyNJRSebVKyYcSSmY4HTseTMDFMx4uPt/zqF2/bztTYNl6htCWkRKGQauU8LhgvoQXiS1AZp0CKAe/E+8Zbw82Lj1C6iOdWqqSkOI9y/w9eC0Cx8xhvqTnivaPkwBKEqVZVpSSZjJ9PMyFkxtPEsHGUUnk4TJSquLvZcHuz5TTNjKeAsgGrFNOUOJ8Dw77nfFqYl5YChzR4ORaSztSdeJn03hObSfTVdde8VTLeDwCEZaHoBgM0ny1IF78011tJUorSCC5hufj+WGO5fz8xnhdSTNSqUUqkfqWK511VVQB2Xei3A8475jCjHdRU2V87cpKUxphEMrDdDGxqx9B3FCqn+4RVlWHomEbx2dJes3UC6oTGiHTO4Ht78dPw1bLbb5u8SsY1qVbG8yzS6jblqTxFda9momtRCzSvIZFRplw5HKcLJVlrRVXNx0BV0AWTC1QLLU2zDXY43he87wjnBAirdLPzeGvkXky1+UCszXpjEiRpygGcM/S9ZTO4izQypkAuzeurikzEOSfJYjkSGrAgm2lGa8fqGZYv4JxpSW+lBZYUxikyxyw+bmfx5EGZxlJIKGOFkRXTZfK7Ts8VGmUMWnfomiglcT5MknRWjzL5N5oYA53viCUSF2EuSzISmF1L+1UGWx3OI/4zpaCsTJtlCGrQGEBS/nIqVAu2yJRbOwF3C4X78cDL65cyMSURaiQpSZ81jSEma/pTJSv+IPUik3LW8oPvvuJ6u+X94UgIiW3v0Srx9ds33D+eOJxmHk+jsL+chL48nmdK9hIsYSun03vef51QyrHf9xcQ+eVHNxzurwX8wLLfX7G/usa4Dq0Muh/IyxmtM5++uGa7u0IpRcyZ8zTx07evOT2+JyyBw2mm1nop7EpRKOVQxrD1MC6VzbBFVcOgC9f7Db//wz+kGzY8PL7h6/dvWeaF3315y65zLIsYyzpjuN5vuN5tiLlwYy2YglXgtMHaDq1FUiqsjyKmyN4zdN2FidcpwCqmGUJM0JpPRfNNqjKQo1ZSqXzyyaf8cYj8+rPP+f/+t/9vpiZ36IeeYbNht9tzc3PD8XjkzZuvuNptxPsTGgN0uayVkjAn/iK6rREpSKJuTvlSfGqjsd6KBUCbEnvXmgYjSWaZymVuXyRZ9zvf+ZS/86//a3z/u5/+jbXD31BQXECUqi7wwaXDLJe//3Y/zioZ6Dz3u1prLcEO1LOPri9BvFTevX3Nm9dfEOeZh3fvePnRLeMSmGPk+59+ROf9B78rNom9MVrkZ0r2WmFh0fYHd2HYPmdYhHni4f1b3r9/4HAcmaZASUWYr05hdeV0nhk2lmmfKDVjVL3s7ZUGgjST5kuFqJ7e0+phWFMgprZntlCQteFQ6ikxUq3f19aCtT4tpfBNIAxg2CxP6ED7W9h4FZNmqTWTxlnZf2up1JJFHqlaI6sqOUZQGmfd5RwrVEtz1R94na1SwlJWDqZmGHo2XkIuSs6kLM1iioFpDtQiSanrSao0aRuV45jEG9iIr/B5SW1AoMhJkaPmfJz4ah755a+PUMENht1+hx8s1zc3fHR1xXf3nqtenr0aJM3P54BWcBpn0jIRY5AG/FskZ8//d71P7EqgqU+eQc8xNOM8SRW2g2do7NTOajbest8M7PY7ut4SY+FwLBjf87KlrZUifle1VpawMIUZayybYUBpS8rIkLIUbOc+uP655Iv9gtaad+++5p/+xV/w5duTmNG3+8VZy8u7F/zxj/+IP/nTH/PF559xd7vnf/u/+d8RZvHEE+S2WTlYK4mCWj3ziGvvy3s2/fBhgqnScg7OZ5Yo3ofaPPnmzvPEMi24nfRGm03fTmj+AIj0nWO33zYriSbTZgVdZA0yKFF5rOtR0c+YStLkpTSjapHQHsRKYtt3XO8Gjgt8fT7z3Y+umJfEd374iq+/fktBMYbEq09/yP2713z99i3TMoqBe2Mam2fAkNIaZy2HU+D944mupYTGLM8STWEk674MF13nJX3cqMtNVZOEK2w3A33zufom0PftpJvf/GDO+Ym4gcjtvPdstjv6rmvhaKkxMxWhMaR2mw0hBE6dZzovAnp9IB9/8hdc/alyLcKsqgI65gZcWl3as/O0Dq0XOeb4wZC0c04slHpL5xQxWnl9uTCHhLYR34nE2u010xTxTljeKWf6rmNeIl988ZbvfPoJ/4//9D/neJQUS20M07IwLTPXek9t1kcxNmmnFbuSmJof6YrIPTuU0s12RXbZWsQHl5SapYGsCedz4J/91a/5x3/+C756KzLkOSQ0im3veXW743uvbvjhpy/57icv2G26yzVc5fRd36GdJcRKabiKLusTud4Lst4eThKktSwB7+ScCTtW/Fpzrtxeb+k3GnIhfVtiJI0BxtMeVHhi0a6/K13AZ3X5+lUiuyyJ02n+tpvzN47faiAsNp29NYbH48T7hwOhVuZUwBhur3ccxhlqpe8cuVQ2Q8dpmcVvxYjMKOmWpob4YMQoaWXJFygK4xKpiARJKTEO/4ARqGGZWmKbUbjOUpvB43KeGxtEqJiOTH5+2pWkga3JnzkXUm6FTnt9qgpNUhfd2LqVeZmb6WaLtS8i5SytADKNbi80fknhyDnR99tLumQpidPp0CBm+TmmobcxZLrOsN31OKWxVZFSYdh65jHKdPhfUnWWBk7WqoXdtn6pEhgwx0pxUmTEkOg2LT62CNjjOpGlAcznyHi4Z5oWun5gc2XoB4dyCdtptIUX+2tJ3EIoyH03YMzqwWDo/Vaa5HJuoQdP0h+lxQutpHLx41oWKZ98Z/CdoSJRt6se21rFRy83hCCN5WbrKEUkTt3gJFygSKMYQ2GZM85p9rueUQk4mpNI3rre8fbNW1nEqhSCV/seqwvzeebm7or99baRAQqPhxEFfGo21GrwXkOdqEXkRCBgju8M2hrxw+h75vPIeJrw1mJdk1G1yyKgnTQS45Rxg2JaIhwnNpvKeF4IMYrJaN/z4uaa4/kgflVa4zqHd4ZDPNB1VuR1SeKnrTWS7lRym8NExmPijEjuXn60p1aR1KqSOZ2XFusrANLdnXgzWOPZ7R3aFc7nhDOa8XhC1Yq1wvqYzqF5Z8hmI9MVRUiV44Mkg7rO0nsxdLZWE6JnP4jvk9ItuaVNUa0TSUKIDfS04pPlmvzg8eFIrZXjQZrr02ERLyKtGDZepjoV0AJyWKtxnUYpaVq0ssIyVRrlFKbXhCXQD45alGj4S2XoNmgnBdh5XvB705ie0o74zkOF8xiwDcT3XqZ4251Qw6dpIYTAw/0RlJyHwWhh3bSQEG1U8yg0LEvG2kg1YKgopy5muzmk5i8lvoGrFAAgxkhvOowXLVTOWdhL7R5bp28AuSrmgzDAdBWz2LxoTK8ZOmG02bXSb4dRFeM0qo2SfCeeL4P1qCJrj22szhVBWJsk4CKpqUZAsrVxMq2BX1vuCswxM54D53Fp/lGReQqUWuX/Y6Fq8RQECSGRxNjS9ognL6PVK0eaYEeez0xLROkD1hi6ocN4AdLGMAkbta2ZtKCUnAs5CPCwucq4oJnnSqpFaObty2Xw0N5HlcLYGGkWdZtwFyq/fv0533v5u7z+4gtO5wllLHc3VyxRjN6HvvugGVh/7MokvUwA25yj7zvGL9/S9Y6XL26wKjKNBw6nE7fXA7/z3Vturjb0nchRvnx3xvmBaZ751eeveXl3zU9+9jOudnccHmamJTPNEz//eeXm5ka817KEntzdXbfzLYOKru9JYeT2+pXs9ZsN1jgG17HrN1AVh9Mk69rl/Ygs2ZjSmNyw0zPZW7m+S8RSOLz5GVQItWBK4aPWNIUYeDgc2fYb8A5nDdYaBqCiCDg6q3FGmkExavaX5yIVYWpmpUTkoBTTMtHpru1dAgZUNLlKMrMyBS4SD8XLu5d88skn/Ft/X5q6w+HI4XTk4fHA8XDkcDrzy1/8nBgXdtst3/vOJ2w3AyD+mTk34FYVrKpQIrVKcjE00DlJEVqRxkKVjEPOgVk9RQsyEW/AxTPxiqwLKXE+n1iWCd91/Pc5Lh5TKxCz3uPt+Btq6W//We01e2NIpVymx78Jgj0da+E9jifevf2aL379a2qBV69u2fQ9796944vX75nGmR9+54bNdz+max5MFy+sKsl98l5qs4RtgUR6TdSSfWdorDKtFNaPzLFwOE0y8KNgrMI6UASMEbbp0DtOp4y1/qn5j1ILKiVDFWU01lmRIq3gonrGgrt4HUn6dwwLBdhs95QqtVrSTw2j1jKUFZAw8S2njh987+tLu7me31oliVWSDw2Kim9rXFoZqco/gTlKtfVQi/+jF5aCePcKw7jmgreOEAPOiYxvBcJSSnROhiVrcnbKYnLe+ZY6u+m5Cpl3D+GD1x+S+IQ6MsY5ilIsKwOmKkxx9A5+fX8gJUhJ9o7rumFM79hEx5/93g+wbkDpcmGXl1Kx2hBrwVAxSmokMfsvrF7EIA1nQX/AYvyAeVifWBgfXIIKFGGir77BrH2CErAk58x4lsGSoYpX6Pr2KFQjjKlxnkQC6SToqaTawPkn5vXzX/5hkqWESFErp/OB03m6mKwLq0WRkTCIv/dv/j3+L//oP0E7xRwXTueJlErzSZZz65u8NSVhAXZddwFBV5+g9aVopYhRArFSjDI0aufPew9UpnFku9u1tVYeihAi5/OZzW4DFYbNhtvbO8bDiRgWcs44Vkkz1BouQPw4Zh7u3/Dy7gWuDR20NqQamxzbPLu2ipIKX7090A8byjTz5n7iu99xOOvYbjf87K9+yt3LP8J3nuvbHdvtpg0sK1TpEVXzWNVVrBKsMRxOZ/rOMIeASYZSFc45vLGscP00F7y37Lee++VDWXSpldubnXgwW8PQd42J+ewW+7aF9xsfrLUyh8g0LZe+ve87+kHkpZvdVpilOhDCQmcNAdlrlmVmmmc2m4EwR1L6cLHXWoD+D3DinJt6QRj1Up+sKiH1jTVeyTAN3foOhVYWhWHwYrVSjWU7DMSUGKeFnGTPXAOcJFhOBisVeP94lPVdwePxzDJH/r1/79/iP/vP/ktO5xGlTVMlrT6LQtKIMQrLugjzKqZE38mVqimBsQ19LJfnPTf2Vy6ZWjPWOdQzH6+Sq3irzZHYhn+vbnfstp4Xt1s+vtuxb9LIV69eyNBKSZ8jg9WAdQrrHc430k7DFJ4fKRfe3R/4+S+/BGAJkZwr07ywHTxKKe4fz+yGnn/wd/9A0nmjKBW2vSS7t0ev/S2gyAqGPV/jQIB2YRB++DoE/Jt57pzw33X8VgNhRouPzjwHDtPC2+PE6/cH5pC4vtmRgcNZWDY1Z5y2jMvCYZ5wGEJ9AnOs0dhBJDExrt5EihwKykkTSYXtrpevtY1BlkUuVItIIJPLpFTEbDuWZjbZKP1ZRNC6fji51FpfQG7fiVmkc2K4DjIdqzWhnRbza9EbNjCq0G/kJjJGU7NIGHIRj651SmIaSyg2H4RlloV8Hmd879nfdqA1uSgoFW01ymhyrXgH3hhedlfMNfGoP/Qd+7ZDIbHCOesPF8312nlpxnLOOG8wVjawx/tHrq42OKMYp0BVcHW35fQ4YoumqICxWzJBIu6dIdfC6zdfc3d7zbDp2F1ZQoDzMTKeRlISo+6HhyPnccIYx2boubrypCxJjVY3Ku608P79EYxmdzWgtLmYNFcfKW3KdXU9oHVmmRVVG5yphKAYOk0tifNpoRbQxrEslfMpoLRhGiPbvef2ox0hJs4PkfG0XLzlSpYiVxpVYTSM44S18nqurzY4oxvAlvBdwnQdXefpfIf2VhoTpckps4yzAKU5Y41ld+XonOHTT655kx4Yl0q1WgzsS8JbJz5mShHnyJxGeu+5e3HN+TzRd0KzXdLM/mogp8L5MHFzt2WaZ+Y54L2m7wyhtuSwNjYS2n+mc57xlOn2wvYopeA7T0YxHx45jzOlVLrOcXu3E1CoJuJcJOHQiLzm7Rf3aGM4nQLjWTyZchLTTaVWVbOYEXttsVahrWEZE11LzFNGsb/e8Hj/iNEGZzXLElBasbE9pkmEJR5dgiXAEGMgx8LpeKZkzXhqdHOkKDFGKOW5iv/ddtux2Xi0EuP+EBbx79l6Ho8z1niKEb8yrcX81HlDDGKA7LQA6cdxYg4RawzLUp6mj8Lwpus8KSRJZNEK30mqTpwDU5XN6vHhyHY30A8CtA1917y3Mr5z6F7hXGO0FRorC6yRtEBnNXPSTGMApRmndHnqaYDTPM/Edq0EFKqkUCEZUkicDpHOdBCVpD/GTEgNVJkim429SGKe1hRJhLVKXdY25w39YLFG0xV3YZxqFNY4dJv6Xkw1EcCzcx3Sx6unilmtweZPx+E48cXrB94dRk7jIoVUGy5UoF5YcqqZkwoLzNlmLt2e6dWoP9VEzqMwMBo7yw8eaw2uc6Sccb1MRte18qm9kZ8Vm0xZaZGmtJAr3nx14KPv7CX2vIh/lSKz3ayhAbUlCzcfphKgXnM4naCILxwZfvnrL7m9FfaVUcKgoNrL4l0biCP+Ek/+PMejGLG/f3/k449vGacJpwuFgnca1wIwzvPSTpnmd374XeYsaWB/9cuv+fH3XnG1s5wOE1+8fs1XXz9yHKNIa96/xbbnqh88IWW2W8+297y4fUGIZ3bbK/7e37limhzLMnN9fUNKEUNgv/Xsd1um5UHOR63Mc2JZMvut+DXu97tLgXezFYBzDlKsWSPJuWua08qOClGu6dBJaMVFNqI7dt6wKsesERaceLglYpvk6hbqgFJtz8zEEFHKNu/NZsAcQwtJcTi/wXUbUGKD4KzFOZE8vfroJSANQCkCAizzxByWNo2X+qGUwjIHAdeq+K2GlMT7qrEljZa9v9RKSIlYCsoovBJWWCn1STZOZugMzmt2G8d8emoMldYMXsDRj17e4f3fDIR9mzPryspcmUirj9J62Gb6/bcBwyqS+JpruficmAZEafVkyNuWs/b7M9M08u7d17x+/QXTeObFy48Yp0BIhT/+8e/xZz/+Xf74R98hhiBG2EW8RqX+M6Qkr8/5jsH1XDR2VfhzGvMbrjrGWkoDJ0JKzCGAkuRp14HVBqWRtLSQub69xnkPtWJcxriK6zrxe3MW63uU68T7J+cL4CUJw8LSX1lyK1AhMk5Hbs2/gOEy3DXKUIOwG5dl+Y3hqHORj189PDHBGgsu50SOi6Tfre/VWBnC5kpCAihSC0zIq1SrMQ6dleeomILVlhACMcmgre86quoYlxGNJsZIpZCrxhrPpusptRBMkBTOsAjAWGGcf1NKMwwdlEjXGZQRcEg1VYcxml3fiYH3MlFCD0rUIvMS8MpwNewJxXDXOXbeiM+V1WgViTEToqTFGgr3798CldPxkd12yzIZhmFDcY7Kv7zm5hn4c8HLWv1Vsgx6Y5CALuelx6moi7LDWHMB2NejQfGy/iTZk3QDMldG9voLaykfJFbWWok5YpTI/K9ubvje977D148nHg/T5eu01nTe8+qjl/zxn/wx1MAf/tEf8k/+6T+h8z3eWUnuzZVSDdY4nPeX9es5qGGNJSWLbuvcWkF474lJMy8ika2liDeZ7xhPJ94/PHL76tV6Ghk2O969e8vheML3/sJ6HIaBPAdZJ2oLgJGWiZQqMdYGNnlub160lGs5Tzk/BRs8P8taa672G373+5+QSuHXn78hpsK0JB4eHthsNvzpn/0prvNY71nuA6fTmSWE1lsVTA04u72wz1MUdtLhNDF0u8v7Whk+FwZthpINm2FDDCLPjc+uq1IwjTNX+y2oSqmZXOwTSxxZH5ollHxPrRdPtPXIZbX7qeSaWVIknBPei6ecNmIl45yj7zp0imzRnI5njscTd9dXhBg4Pp7E3P35bd/24ZXlPIckLCM+ZNemnKEuKDRGi1e0fK8wqbRqiYbo5s21PgNSe6Vc8N6jjZb6THHZi56/llXuUKswur/44i1//+/+KW/fvqcoA90GXQv39498/fWWm9srun5oCqjUGK6rPFJqK2cNOQtR4LkxfEqBECU44nI/FfMBSK6U7A/f+/QlP/7973A4naXvHaQnqkrRdT3WDdy9+pRu2BJj4nQ8oJajDEra/d+5p5AgGYrJvT+HyJdv3vEX/+Kv+fmvvmo2OjPb7YY3bx/FG7YXq59/99/8k4sV0eD0B1L2D64r4tt3YS3/DRLK55YJ6x8jdph/6+O3GgjTWkz2zilSNRQjsaZUkVodDiNFCSNj23uMSjzej7x9OGI7Q6QlsRkxYZZsPUWhFS8ZCDKlrUZAicM0cn01oHYWoyTem1IxVuSWkkxYiTmzLB9SLXOVBmRdOKHxDtZCuW/NullTep4kAEorrLfCMgsJSkVZjR+sNK+SHUpJsuBoJWmD2jaaeDPGX+ZZGmVgPI2sMbPaWEng0erizZBTIRlFsYpqM6d5hFLwncX5RAz5ssjIzxHT8pIFeU+pXFD5y1Gbb0iqzCnhnIYEZZnxG4e1Snx1KGy3HdYPoArTOLNzA9MchNabKqpalilQS6ImAZuGnSXnhfOUeH9/5PH9gRyzSE6t5WrXM2w6lHFsd90T80hD7y05Za7vrmRaqjW1iCeENorzuDDNAVXg5qrn5mbAeZmOvPl6ps89j8eAaNFl8p9i4e3X9xweJhSKftOx3TtKLKgMzsv1BkHQtaa9lwV0xjsk2VJBKRFrNPvdwBxmut4xjxPOaZTKIqnUgevbgQ5LDglnhNEWqfQWhl4ap3jVUz654s1XR9BgO83d/prHx5mcEuMJXOeoSnFuVNfOS7OljTT5u82G8+nAZtPx1esDcQ545zE6sN04bq568ZZJkv6Xl4xzcL3fkNKJ+RTRVhFTYoNmPs9i8t77ZgieiWHGOZEcmsaye7yfePf2RIyFeUmkWCT5zxpsZ7DOyGBbKWE1tCIthIRPAhLnLKBKyXB8nKAatNV4X7m9u5YluAp4IZO3TJgDqIgxwhQtUfPy1S1vvjiIn9VgWsKUgNTGquZdUii5oqxiPi84ZxiGQYIpokiPheYOYSncXG0lPSYlttseU+F4HJnDwrBxdM4ydD3hPDFsrHgaoKBAWEIDseWeKkV8rkKQKOzOQqzyDM+jFPclF4rV9IM0p4f7s5wrr+kHS9+7dl2E8ZKibNb3787Yvr1nxD+wgkjxlkqcxGi+2yqurh3TnKgPM/OxoUgp8uJu4KsvH9Gq4Kyw93KulCQTMWMVu42jUDgvM6VqitJsnKWzDqcrZDHIt8q25lVfACjjHb33EsNdYIkLWmn6rv+ggK5UUiksjba/LIHzOPP1uwP3p4kpiFcb7R4UIEw4HSsItj7HtEZRTPWFlZBC82zI+ZKehwLjNL4f6Da2ncfGaHMij5Z1u613VFwpxCVwPI54bxkGj22/9+7lltNhxDlLN/iLjM5Zc0nTFaajBh3JufD+eM+Luxcc7t+zQ3F1c8vh8YhpCZxP76f9T5t4xpg5nibO50n2yiJTf+cdN7dbUknMMTGVhZQTw2Cb2X3l3cPIT37xJYdzIMTMT3/1jj/44QvGMfCf/r9es9/0TPPEOAWOpyPjNKO0JQZ9SfZMKdBtDfMScHpDziPeO672G2pJEv3uvZhlq0ppQJLSSGOVM5bGPHRismytwlkpjneD527n6ZykhFWt0d6jjCYty0USIPfQCoxlztMsYT3dhsFXcg7EWJ4S+5J4gZS6pjOL2fCSA8661txUQkhNRiLDq5JL88YTj7JaosTcuw0K1cCoJ7DhYgKcM1aBGXq8dxfT6GWJjOPE8Xhmnk/UHCm5EtPqXyQAkXdGPO9aelvMAvQNvbuwBp1QkwgxiAwCxJainSOjNaX54hit6ZwAM/99jlwyKcVLU/n8WBliBsiXJvM3QYOcM/M8M57E2+t4PEhQAVK/3Fxf472n63s2m42wnWyTf+bE4+MDX375aw6P95ScePv6NYfjCRR8//vf4w+//0KS9rRB6RZE0F6JNYZaFbEUqjKodZAKAgRVBIwGMuby+muVoeVXr99y/3BkTotYGdierrcMvafmyuAcunkhXWRCxtIPjq7fUN0gEuuYMFiqakwKa1sK3RNTS0DSCqyMbtmP13RZ8dVa+UoyzFzC8qEcrR3eR+LiMDY19pgMmyv5AmzmnFtdIYqMlZW7xDV9VEHzopLnqBmd58y8LJefEeKC9Z6NF3VByKHJH4VJWZVCW493T2yybDM3+60EH1XN4fiasEjydWlm6VYt6E7qhZoSuSrx8bMdVvWcDonPvnyHqZ3IJ5t/nlIKbzu86vho43ixtU1xVi93qlaGgmKKinCYWH7+1xyOZ968v+f29obNfsfN9TXDsGGz2eC9l+FcA4QV6tL01loxzkGRIfTTs7Eyx1c5q7oAnzGnxh534ic6JWGYFLmW1jqKXpPowVsnfoaXh0+tND9hlqYsnlGxsdAQSa2zwmQROVbH1W7DQx4vCZZd76BGfNfx1esj07Rgtebu7orDw5HdZkf5WFhhKBl1VWQ/kFpF4FRjLOMiVjYlJ3nnJWNdxxwM53PicJi4ubnj6lqYTss4cj6fV9txAFzXYe3ANIqh/ForvPzoFbvNFlUqMUwYXWR/yfGJyULFGoW2v9m51/IEnFzCBlSl7zzf/fQjhk3Pqxc3TPNCqYppOvGHP/4DQoo8Pj7yi5/9lLdvPme/2/KD73/K6zevCWENI6vkFsSw2XQysA4JowSmyiVzOJ6aV5PULlpZ+m7g+uqWYbvh5uU1MWS+evM501n8pnpnCDGw3/fkGsnFcjEZREmAyzd8EXOsH7DCnFMM/ZaU5JlVWhFSEBsgrQlLap7abWhpFF2yPMwLj49HXr58wRyWZz/y2YC0MR1TTG2dkj58fUbkBS1oFCEXak04A2ZNIF57UhrgU6UHfrI9U6ylXW7D8858GEghw8HCPAepc5SoEVLKfPXmHZ9/8ZoXr17xb/+b/xr/zf/n/8fj4xlVHSVHakmiTlNGEutTaumkkrKdS8Fh2mvNl3Nf65oK7MTvsEgaba2VYZ2OtjP18sUt/8ofVe5udsSUuH945N3795zmiVw8WXUY33GaAi9efY/xfGQaR6oxLZG51bRKQHGlVVvPJb30/v7AT3/xOX/1i895/faBlASIOpwkHXPJkSVEXr645nSeiemJecw3gOH1NV8AMNrFqc8+uX6+fptHaBU85G9nDwb8lgNhpyWBgdMSOS8RYw2vPr6RNKQi7AqMTNqzKTyMM+dxkiJwnkWq1FtcZ0hqNTA1dCjCIgaAqkBZ4DjOuE5JzLs2jLmgN55hcJgOQhCta8z1cqOWb0CSIpEyEknLuuE/PchWV/peJncXEKw9rCgBw3IRzXbnHda5ZorsZAMKiVolAbKoiqW04liarhQj01n8nXKWqHlt9AUYyFVi5b1rTDTEF+R0CIxUwizslBwz2licE41510sB4708rCHk1tCqSzOmG+gAbX1sLO0YBSSwtmKSbg2cJsYq8j2j0NZKUuUU8NZDLZSieTydOR6VMB604vEwUWyP980kNWuWRaO1JReFqXI+jdV0naLvFDFEhs2WJUoJ6ryl6iRGtC2pSBoLRW1sEF1hWSJKdfS9whjLm68XlqUwRzFYz6kwE4mhMI4yrVRKsTEKowQN3/aOw8NMjJKo5Z2hJEnmSqViLGCEtmudYzzPlJrpes9u32Gdp+s7whlS0nSdMAi8c8Q5YQbX6Lca7TQxik+cpHhoUoG+Mzw+TvTXHcNuyzgmUswoK5LU1NIKVSns7nYXEExTmcajgKVZ8+7Le6qqdM4w9IbOG1IQsHborBhJl8ASM+O8ABrbyTNhvTTtRWlJ4EmF/dWuTRdb4IH1aCWppe/vRx4PE9509IPH7DX72w1+sG1DlOknSpGSBCLUmjHWoluAxTJHofdnSKlgrcwOY2jFUxU6fS2VnMSryWjXXmt7Xq38/dEne8Z9aMCvJEQKGCq0XefE8L1WAfRKiyTvtbuYt07TgtaevuvRWjOPoZnBS8Fcq0xwnRfAL4ZALJFpXJ4AHS2+Bnev9m2Km4WRp0ROOJdMUdB14qlFRViqtYqfV2NmGavousay8vpS8+i2Bq2yZ2Wl2N9stlSkeSqpsJyrAHyA0mC1bqCVpSwaXcRQ23WKw2FicM3cs4oMVWnNFAM77yUFLSkG49kNnXguOkkcTCWz5AWnNXsnTYLW5sk3xGkwkJWMNyQBVtP5/jemUAqF0ZWaEvOSOJ9n3j+ceTxNzEH8atbmfW2iSgXVpBqq0X6EIi+vgVKbDF1ADPE1E2+w9WdUo/GbzUWGJgwN6HonLLqUCUGaUt3kiDGKh17Z9GhrQBmMetpHxlGm7c56vMusYTDI9oN2rUkyHq89P/nZz/jhdz4VL7qh4+Zqh9FtOhkz3hiclj9Wi4wplsI0L8whchon5mlhDoF5Cex2GzrvUOeCUcJOrAoOl703glYcTjOuN7x8teX9OLHM8rtihnFRjEvF+x5nvfyMArV68ezTjRXTg3WKqoQV1DkvibUlobIIbubpRMoLtzd7nDfc3RyhVqZJnlmlNYfD1BhZke3QM80zX3wN3315JdLfkJhTQTc5g3eWkhM1Z17d7dqEvPLwcKTrPC9ebVsRJwAhCnKVGERjzAd+e5VKTLFJwiT5TkAHTcz5UkfIvdPsGYwIOZypKGMuDMlLrfE0absAs2sPLh52kfP5yOF4T87iLZmS+P1YI76O3hlijsxhIcZMKlkGfI3FklLB3Rhhf6Z4ASW2g+HuqiPXmXEpUBKKys3VnpcvrtntNljrOZ0esVbY7M65fzk4Vuulof+bDgUcHh85TwuboW8Nl+Hw8EA/DIQQefPVG9KycLUfKDFgreGjmz3/7K9+zheffcYPf/eHvL9/wDvHfrcnZfGB0VpzPB744rPPuX/3HoUhpcIyj2w2A3/yo0/5ne++JIb0wXXwzjf/NA/a4KoMVnWpbIxqxsMFmoRPKi/Nyh2pJaOtxfmOVDMxB3rrsK4BIE1mabRh2PbEOOP9pjXlTfZ9CQ8RNnttYSPGGIyTYJY1WWxNgrycU6Wx1rGGk6zg1ZpmCJBSvFgHUOH66sTjQVgo5/OGWDM9YlWgmuE9VeGdk/pG0xKJXWMfKExpsnpEMth+NEqJxcfpfCLGSGjJqUprCcpCApHSJY1S7vfxeBTJkNYiZWvAQC6Zzg0M3ZbNsMWZnjmcmZdIKon7w5mq1nRVLmu7xmAwnB5GYf4X2HRe1mJv2Aw919c7rvc7PrrecT04MZb/pnZU1cv+vqSCnpfGLIbj6YTve+ZpwRhLDLExaCyrKb51rqk9noIOlFZi6l2rDIl51jBWYX5pY8gVMsLiqoix9DSPnFvgktGSUO+sZk0izk1y5pyX+6+qNtwRFmuYg/Rd7fxCZR7P+M5jvcOqyt3VllrBasuXb95jjOajlzfsrq44nQMP77+mJPGCOp1nrvfXbPcbGXQ2H+baGN4r23W321BL5f7dg6RvUvmLv/wFN7c73r47cD5N4oGKMJOn85mcEt47dvs9vnMcHx9ZDeT7zYaXr8RiZBpH+mGQ59g6TNehSpWfV2UtrQ00VUo3P9U1BOT5ErYOM56vYaoBjIbd4HnzLvDu/h3bYc80B7a7jp///GccH+4FHD4fieeRnBecK2y3jpxlHwtnkTWKEmSiOMOdvxYpY668vz+hlLCUYkz4ztP3A/MSuLm95e/9G3+faZqYx5FPvnjJz376Mx4OR0qteC+syxACxvlnyaTfeJ/tPpPlRz6heQKNVrVTKQWbLMqIn1Otc2PSC9NTFy6M1ePhzMP9Y/M5NPBMdH+xMLH2AtZrLYqBlAvGVYyyxCgqmhUcEVm2BGV8cC34EHOBlRmmRGXR9tKLzcUT9xJjDL21mNbcqnYt3j088otffc7f/bM/5kc/+iF/+Zc/4fHxwGYroTGyVbfgo1KglgvrXIIfpN7Q7f3WZ7iCUlr2TaUJYeZ8GumHLYfHM8MwMM6F7dU1xjqurje8e3jH2/f3EriC4fb6Jbc31zhvScWiTMc8L6QqIHiKDlUbc73VzGq1xGgD0nkJjNNE52yzbtI4K4Ci9xL69fFHt9zdXbHbDHz68QuqMmIBZRuX8DkFr+EDMnddf4+c//VYa/wnObj6ABQzRmHM31wrfPP4rQbC3h9H0IopLISc8V5kXTFmDseZkBZ0hTlWplI5zQuneWGsGVPBxUJF5D86gzKViniOaaNJs8jPxAy2EJZCSgspRvb6msVqrJMY2NNpQWtNvxUt7Dw1+Udd0WLVUGou2mGh7wkt32nNbuvQVhhVOabLhqjaDVBKab5TQpnstMY5cwGTapXfodr0WWlJgFM0wKnJJIa+/2B6Z51hWWIbeRVJjQRAbuYYArVUlkk22rgUdrue3bbHtRSeWiqn88R0FnM6a9fEyNY0rhzr8gzYLYLEOydyotoacrfzWCc+bKVmcqwYa+iHjjBHDg+R07Q0qZZmHiPKNkbPxqOUJy6Zq6uezcYSl4Ax8O7tiavtpnlJVGpeSHFB4SRe2nox6FaG2xcbvC+EZRb2TzEsC8yjsDN2xuO8vKHjKeK85XCY8H6g5EgKM+O0EGZpwG/udgxbRykQUgAGrLWUkuk8hFmo3JdNUsl0SxoFYR/6wVIQaeJ+37HbdjzcT1A0V1ee69sBlGK3H5iWgDYSHb3b9YSQOZ9nxnOkJjHX324cOXk2tbJMgXdvHqhFKMTLskikNc27C5lq994ynicKYmY5LVGmD0bjnWKz6VgmAbr6jdh1bzqDs5Wv78dmTg3WWXKUjW6ZArVTTNMi0dnNxNgZh0IA6aAS47hIKhYF5z3eG7rB0W16SfLce7RR1AIPb88c3o/0Xc/L6z3TdCYskfm0UFJmHsOFgeOdFwlfgaKEAeI7oQDnVKm5Qi1o4+RrAGrFu/aMacX1zcD5tPBwP9F5QwhFCv/a2I/HCFHYOK4zWGPbxqK5uR3oNwun44w18Hh/5HyaSTExDJ7NtsN5jfMCsqgC+23P8WFmu+s4j5GcspjIepmIGaNl7cqlsU40Wju6TrfkG8V261iWeGFxTVn8feYpUHJBWS8yj8a2W9muhQy6Mmwlgbcik5sUEmFc5Hw1toBp6bYxVMKU2O869jee3jsODyM/+vSON9Yxz5GiZWKqlea8RDadZT949oNIN5Wimay3FLdaubFbvDcYRAp5mY5TL6y4SiWWKJJGI3Ii15rD8g2GyRLmBpxLaESuTwyZp4JPWENqNe6Ep9CiUolLILadfJ0A1wIac/Ggq6qQY8QN66Ttwwln13mcUbIuV4XVpk0lCzFI2o8wVTpiqlTd4qyNpgbxvfJOtcFBYzZaMF4m+9IQGspJrut5Grna7iFXck0yHa8FqzS7oWO38RijL1LmqVbmZeH944GHw4nTeeI8zlijef32nu3Qo3Wlc5qUxJtujQifF0k/rFqx2Q9cf7SlxApVjHh10ex20izVJg1IjY0ibKrMHBeQKwS68vbxnk9vX3B3dcXVdkNIgZwiixPWrHeO25trAbxVZZkXNp0npIi3BkPlOC1QBVTYbxzeaZYUSFWLQ2QGUxPaO0orQAdvCCkz+CbLVQJulByhSiDBNyeYfKMhXu8vow1UmPNMjBFverQWibkY/kZyCljrBNTXBmUsVRlyVZgWzKHaJDUGeZ6fpyCq2sp9VSglyv6n5BNKVbxrzZ5tnj1pYUkCcCmjsdUQSwIF292GlAVQyaVd31Tw3vDqbkfvPSkX9ld7liAm7t4avvry19z/P/8R251IQl6+eMVuf0VMCessXT8IU0Wvaa7PhTfffrSnjS+/+Ipff/EV282G11+/xVl7MVM/PB44Pj5Sc6AUqfOudnucU1xf7fmTH/8RylpevHzJX//sZ7x6sWOaRt58/Y7H44k3b96ggd1+x/t39zKYipmu74gpXQr2yyrRgISLJBZFryq+pUUqVaXxaRPCJ2ZbpiIywVWKGEKU39FYpNqK3yII8/VmvyPmiv3GeibhHFqM4JX4kRlrn4Cw5iX73D8RaPJKhFVtjNSFReq/VVYljOl8CRT51a9e8r//P/67TPNTWIDWmbA42DVZr5bnxlAgBWHZKmH3oNd2RD01gi1oYK1IY0os8fgk21Qa1xrBGBPzPPMf/6M/4euvN/w7/+Av+dGPXrNMk3iEDR3KyDDEKLk+8kfjuw63GUBrHh4P8mykxPc+eUGIWYD1lb2gntQa4WXkdJy4vdqLdNpZzuPCzW7g1ctrXtzsMMbSefsbz/wKGFhr2XUe1W24udqzhEi/3bHZbthsdxdJ/7qO5JRYu8WwFMoi98D7t1+3awm1KIZhkD2wFnKKhCWIB1Fn6bqOoevx1lMRadM4nnk4TpQckHQ9RT/0ZOeY5pkQhGGnUXjf0Xcd1ojXY8qZmCLH+8OlXtzutmy3G4aPemqtnE8naoXtZkOIleUqsd/v+fS738FaQ99pvn77lrePI7/67DW3V9ds+w0pFY6Pj4SXN+R45ng6cX9/QNue/X7L4WHkzVcPPBxGwjjxeJz4r/7Lf0apXNIfS6045/j93/sOh4eR+3dnxnEihInT6ST3uf1vhB2qaM+HYrvt+dM/+QNur2+A2mwCBGwsSVJZn/NZ1oHl8/VqtWWI8ZsgmPR2VmusVgzecne1Zbfp+Yt/8dd8/NEtP//5X2P9wG674fZ6R+8st9/9Dm/vHy6hIcfjm/a7pVcqRQa42mlqFkBzSTKMX19DzpmYRpYlsNls6PuOly9eUnImhMBXX32FNjIAmBfp6VLOXF3tn8nunig6tcrQLyyJzaYT1iWVrtOkIMO7y3tu97Jt61AIMnDPRe5rbzW9VqgcidpQYmSaJjZ6c/n+CxuysapVu++tc03eD8YWvKksQRAb8WfUrRwy5CJD3hV/WddfpZonXyNwqOevu4E0F3N21XgqSoazIfMBUEWF83nkqzfv+OLLN/ydP/sx/+qf/ZhYYhsgRAmyilFIBrQXoJqPrVxYAY2eDVs/vLdkIPJ4OPP5519zdXXHr375OddXV3z08Udc3b7ki9df8dOf/pSqCv3gGYYOrTR3d7d893vfpxs8VSViySQqD6cTJhVq9YDBmSfwUasnH+U1NfR4nrh/OHGz3/HpRy/xXvY7hWK37dntt3z08prtZkArzWkMbDv7xJ7jya96xcHWf0h6ejPOb1jIGja0DmVqC094bo5gDJcU3v+u47caCPvi7T19J+DXWqRbJ5uitoHYqLp+K2aYIWSmmJimhNOKKRU2xbHkiIkZbTW5NWIpFaYpXBYOa2XKqn0lFkfNIiNMqeCsYZkj2pmLb0a/6bj56IowJ2GIxEJIMimptEjiCputwRjNZjAMOyufzYlU8+Vh0EZdqJer1Gr1WjDWUGL+IP1opStXAZdRZk2Dyo3a2NIQa11dOCEUWRGMIqt4gcXXBlei05tXihewQhktbCED2mq67FjmCC25eD1nOcE6Zny+sKzYmLr8q3lilDUdq5KbFGYYOlLMjMeFZcnUmJljIbapp/EF33tiqrBkaota7ntL3XrmaRbz8jnhB5m7zuOEsSItnU+B0JI7tFIsU8YoR9/toUiwgFbwoKEoYboIeCey05igVDERT7mSosQkO+vYXW1xnWVeRkKciUkTlz1fPd5jKKhOo/EYJ2a0MabG0svUatBGft9u23E4B2xnOJ8yt9ceZwsPh5FxjNy+2IARKUdtAQqHw8jD/ZGwiGecc5rD44z3hu2u4/u/85K3b8+gM+/eLoQgjLntlWw6uVS6vsd6mQz2znGuZ5EinBasd2KQ3Hze4hKx3gv7ptEAl5QZp8jSTNyLNuR2Dxut6HrN2zcHlNJcXe0uxVzJCaOaH52S8xtDvgAV3b5jt+vZ7NwllVUbxRKjxHt3RmKh7w8ihbLt+cyFwsLuqqfrO7peUVMA2hQ1F8IYWUIixCyBGdY3QClf5CMog1aazlS2m57lPDN0wrB0VhHmSgqlJf5ptMpoHZnOiX53i7Ni1FqrRKArpfj6ywPztLRCvwgov1cMg4BYvVeM48Jm2GOdI6XmtVEFBLFGEealeepw2fhzlmQy4yyusxRE3oaCsEjhijFQW+FYnjXuSsBy10x0Syl0ncV7eXrFJFtYc1QxVe2tFSBfiU+YM+IRtB16tn2Ht4a7bqCzhm3XMU4C3IqPA0xLxFkxwXdWCp01yfJSCCgBIZ21MhFsaJRCsaoWvyl/BEg1o0pgTZhp3yQAohaJfK6R8yTm1KXIeWydZzsv62RwXcNEUlkaI/dSVcHTiLFNEI3qqDVTTWWaRtxJZKmqKNBZErmsJaGxWdE1cFOaUXUBlMwiMlVjNcuS2Q0dfdcTQ2yFgsL3DshUlTFWvB+1lcQ/qma5tzweHvnR974n3nS1flDIaSu2Adaa5g0j99LpPHM6jXz51TumZeHd+wNLCBhjWJbA0Pf0nUUbCGEmrCynJEyiWir7qx3v3o18+vIah7B/rTJUrei2HmhFa5v8yT1dSCUJUKIyNSecd+w3OxSa3WZDzY1FqRTv375hnkZKTmjj2Wy2lLrgTOV0mum8vK9xXlhCYrvpUCpzOgdy9pymke1mYBgGjJGGr8yFGGa8MUyqsF3NbNseN5fCJgeovt03XD6/+tWt92XJhVwyupnhhyhMUBBQTSSqiiVncjEULWwOa4XdUpRrjJn2M5UmV2HGiO/V8yZtLR5FFnfdpIAxSIMsS4AM4pTWxBSwjWUjSX6gm2OKNoaU6yUVyliHCuKhZ43hdu/45MUVFY1znpAaSGbg4e1rlvQZa0qrdZ7vfvd3pd4xBjcIu9N3g/grbnYS5hHjRQJCe03n88R5HEk5cXtzw69++Rn/5J/+c97fP+Cc5gff+YTrqy3KGKwq7LeWZZ6YppF5zozTg8ieY+Uvf/IzvLV0vgOVef3Va16+vMLoSlzO/OC7HwGKX/z1l7x9d8QCnXf88Hufcnu1/aDJVSiGfoNpZvIUCSIwWphOS4pIjI9Mw/WaMt0WDsncFMD/8fHIqbE8fUt/k2TcLF41USQy83imcw5togA8VpjnKcla573HWodrnnQrU3S9H+X1NyqDekqHq6r5HD57f6WK764UmbLe/Y//Z/8Rp9PA8+PFiwceHq+5u3tzqediFQC7JtmnlPcYRMq5NszrPae1sB1pzXOl+S4WabOMVVhjUcpcAPN//I9/yM9/8TF/9Ie/4vd+9FqY1QqM1S3sRj1JbhCPGYtIyHebjk33khDGtt6thvvCMqmCYlOrfF/OmdN5ZJ4jvfdM80KMid2m4+ZqS9+aPfvMU/cDPxvaoMk7kjVcX+2YlwhzYRh6dtvdM18n8TJaATTZf+TjVGEvhWVuoTcQU0BV2bNiCJzOZ5SGrd7Ift7uBwEjFsZ5JuVCCDMxzAz95lKrr7LiaZqEOdxuk4XQ1irdGNcrJC3ybOOs7DWq0uWBa625urnmB99bWWbC7lpC4P2b12xDIZ8fMfnEj3/8O3jrePHiDqUUYZmZ5zPz+URscsZ3bwqxaH79xRuurq/55OUdf/3PvuB0OjE4i+k6Pn51y9V+w+3dNa9e3eKcI8bEplMsi+V6P2DNk2m5a+zsvu8kTCAGsZXoVkPvemHmlFwu6/vTs/+0F1ArxnlqFcWJ9AzrV3Hx4FRtvR96kTZvBs+vfv0ZyxLYu47N0NFZ8dLshy0/urnj8y8/45/95P2HwIiGEnN7gJLYZqwAbhXWvgRFZBlplizBEqVwOp14cXeH95791RW+71GHJt0Pga5zEvpRxDOWUolBGIIxJqY5YJ1lu9lxd3sl4VmHM++mDw341/18BcRKeQq1gEqImbks9MZf9sxxmnnx4laY0M9CkJSSejU3oF9sMQqaiCaTopjFr7WXkpVGzgdPFkXPLa/Xj6sVe1bfuMSt/K+qEnKGKudwGHpsY2VKYvza82qOpzNv7x/48quvMVrzZ//qjzmdT4AoV5Y50A2WVdaeYmyBXM9IMFo9sWMvBBOxUDieJn755df88598idavSXPg5RTRTgYf19c7YoF5Wri5vqLvvaiHvMN6g/GaWi2pZF6/eUMKC1sj97tEaEhN9U2Wo9aKTd/x6csbtr1HYUgZYip03lEqOG/BKPa7DQ8PJ7766j0lF+ZPbvjuJ3fcXG3pnAUqLXbjcu6+uac+92S7/C0I2G/cY2+/esvP/upX/G2O32og7H4ayVHxPX1N11mUkVnaUiuhIklMSk5uaQ9tjIJap7aZGVPbRZMFJCcpVEuuhEUACaA1lUCx4uMRpSh3zvD4MGGt4nicsc7inMYYxWbX0feeeQqcj0H8kEKm6yWdzGgxex56y3YnzKpUCuNUmOZMriuNuT0cDcBaN0Bo+NJavyhhw6wx5xSZOlq30gblxg1LaA2UobZpaaVQU8V4S9Xi51GzeCHVXAlzkM/vOoyzcDENlgQ3KhhnMN5hMpBbA12a2X9pINj6INVGQKtPcvNaxfxS64ozvrHowmWKLsaOkvQ3n9qyKb07OYsR+LIk8RZS0sB1nW2myEEANF3pOk9MYKyjaM3j/YGCwbgNznRoEs42w/lY0FRhnWh4+WKD97rJxsQf6f37gDOGeQ6SAleNJOoow/XtNS8+uiKmkZQ7Ho8n5nHheBpxVhYhiXNW0CZ99oIW1gaGCniTioCPFIXxhvv7mcPjxP3Dkc57dtueqiW+OSfxzsoxC01Uw3heOCwRrRRuZy6JYZ9+d8dXXx6FoYWYwzprKBV8J6zDkkTqtXrHGAqhJEo2FKXE7D4lUkioJAusM5qqxJw8LJklVFwv/hL9tmM8zey2A4dTZLtz1ArjeaLrnPieIWyQGfCdIRfFvBSWKT4ZJ2rkZ2ahvOeSOR9mub+MbJJiQC/FhtWS5GW0sOA673EGCkae9yBgQ86Z82lingPOe7a7zRNoW1eZjmyguQFBnTdY2xNTZRojj4swz8TjREBWoxU1B5nctclcShKqEZfC+bhIQpsqFwB8fVacLqgqzLwYE76X9NRpEgNQay2+t9RayJHms7VKgZ2AcVbjnEIpI7IcAGVknWmrSoq5AWjNn6pkltRitZW8bzEmVdSsOI2LgC9tbbLOsNmKjFH8tAq9t1xfbdhtO5w2dErkswrFdvCXiXltjXpZ77UVFC3Cgn2CaNomWERugLLNR0ZdmqT18+tUTViykgwUcgAUuq7T9trixMVHbImRVNqAoRRQ4u2zzn8vLLFn+5FS4k1QlICDq9cihQtItwJkShmRpGTNOC4iY9WKUpM00NZIQILSKBWIIZITbSJmmgeasINTKFhlcezwQ2KeAyFUSicea8Zp+b4GKtcKeVb46jHakNaY+6rhGf386fw/vcuYMm/vT/zsl6/585/8nK/e3gtLI8R2zeRaxZgIwYOqxBRIOT7zPFPUrDkdorBBbkUC1WlZV7SxhFRQCMumKg3KUI2l2IouGlNF3mSVPBveW7b9lnmZOJwOFCWSZ2MMqkrqaykJpROlJmnEayEnSfSDiveuNeKFh8OJ9w+KojS7bWLTzTgjyVDOGqwW49hcMvuh43a3oVRhlfWbgYtJ79PQ/DKJT8/8s2gNtULMx0PzCFtvFQFHtMg/Ogu2FzuWZkCdEaDs+XWS0JV4aZbXOiGXegGklDJstzv6vqfzniUslFwYxwWlhI10PD1iQniaOlfZf7WS9eT6ek/feR4PB3bbDcdHz/l8xhnFZujpOi+ePg0+K0VCh86nCV0S2mp2veNq63HxAErxL/7Fl6Rasd7z+u0D+6sr9vs9r158xH6/Iydh/az32HmcmOaZSsEZx1/+5GccDwf6zpBzJYTAeRTWrzEGZ5DcB69ZyJxmaSRKgvFwIhjDqCRZej4vvPmqQ2sIIeA7gzViHP873/+E+/tHcsrc7DdcbQcJNngGIos3ZCHFjFYif8qIf9rSmAAaGlj2ZFpvjWUKSUD1NnF31jIMQ2PjNYuMs6xXnbWc5wVlNWwVuUwyhLDX1HHicHrN9Xbg1Ucv8f22SdYau7iBrQ3ZbzWxWReAZ+/jyddQwSUko5YnZ6VvgmBQ+frrFxhTWMMOklJkrTAqoUps92aTD9PAvbV5r7XZIzQQrD793ssaxcpYk5u81srDowzxrq7O4o+5hLb3C/ttNblegSyj5TnOtWKdodiMsh5X1WWAK79Myz6j9GVPkaGXZnSjAEQb1wBPJenRikuq3HrkxrrJDUh0pq27WrPZ7kn1iG41izG6yb7UE+NhfU3fYIakuCf2fVtP2u8qT1LrbtOjVMVY+8H3lpJZQmAJa01j8L6TABfnsMYy9IMAtu37VqbjOvBc66uu71CNrbwai6+ARbfpcZ1YmzgtwSOicBHJ9RwSzkN/u+O6/yF938sz6ztSrlAz5Ih3Grsb6J1miZlpybx6eQvWUkvm7sWeV69ucEDXdbx8ecMnn75gGDq8d62+cJTSNf/aiqK0NMlyYfYNfY9zTvzRyMRQ8F1LTSyF/C3AgNyT6/Of21BGUUh8IO2uTx5L672hlQQ8WV0pJXI8n4TRlhacQSSFWer40+kMwO31DW/fPl5+t9aKpq8W24YqcsP5MhxrRvUpUluv4WJkCQJoppQwxnB7c0Pnm6y7F+/KUqWW87bijYBAcYmEEMml+RkPlv1+w/X1FXe3L1iWn2HtTAjPK7cVBP4QvVCN1ACZMQSGYbjUWufzyP39o5BRng+XaP6AJSC+cVZk5mUGKqWYxtJTYux+MfB/2hfXV3ZR5jUQ7DlT7MNDXz6++hfmkpnmmf2wYbWoCFECp0xLr79/OPLTX37Oj374XU6nR1AFbRWbYUPnhpZ2L+ckxkTXrb0+MjgtMC2LDC+MfjLrVxrrPMZ4Hs6Bx8NMZzVLKszLzDhO/P7v/ZBusxGLINtzfb1Ha0W36UglURcJWKjNI3caR/TNNUPXAYpcDVY1Sw2l2jmQAqfvOl69vOPu9hqtLDEVjqeJw+nMPIlKIMXET754y+k0EZbAbtNzOo/88nXlcVr47otrNkP39Hy0674GctTSkHf9NNBrN8DlPlrlkTFGXn/+NT/9y1/wq1988RtX79uO32og7DAvVK+4X0Z67dHZkqu6ML9CKSir0FaxRDF3z0keQttZYijiDWUMIVSRq5R8KfjWlA9oe4+CsFS0LZDE+DEumfdvR46HiXnJWGcuqVOShuK4uh3oBpmwLUuk6xqzACl0vTd4Zxk6xxwTphkNxkWAL2ONsI6aL8dzf5uU8sVXamWNCUqfxei+GAHCmnl0KZUcY1s0FBSIWcCSUgoGSV7x9qkIikum63lioqmn6UJtyXAoMRjsNuL7kENLIYMLoPa8qFDaQJuOXFJVUmaZZkoK1JQJnW2MOFn4nLNsdz3zNIpX1zpVsVZmqG0yYZ3GteRC38mmX4EQMs6AKpWUFdo64hKYS8R3PaAvvkoamgm0/ImpsNlY7u6Gizm1dRrlBOSIMYl80ch9ZbRGW9lQXWcxzsmCnTo65wQISQLepVgEhMlCay6NBSGTpdWAtLAEadzOxxnrDDmdKM0Lb78byDkxj4FpDhgc/SDSGhAgcB4XQshsdg6lIYbE0Fs631/ktdpqkQ/pZ5NixMMFDDlD5z3ncabvDEspTOfUPNPaHlwy/aYX6VZq8+1SxRME+bfSlX5jeHgcMUbx4m5PCJnDYaJmg3Kqmc3LdcslMU2RZU5iPm01OZXWmBgxsWzSOt9bSqoYk/BOQ7XClnLCvuwG8TuYp0TqM2GWEiXOQSK+m4Q4x0JaCqpGypBQzghjQj0Z/SpkIriEmc3GME7ymhSw3Tp0XRufTA1QNMIWWxLnaWE5BfxgiXNmfAiklsSntLrEYU9TBFUoWyMMTJSkXJVKzU8FRO+sgOkpo3KhiCke3htcZxvIv87CajNr1ihEhqQRKYqxIhcxVjbbEBMYQ9cbCuUykVMocoL5nEg5tWmdPDzWyZrmnWHoLNvBMQweZw2mKmyz4KwNfLNrwfwtW5KcZynCeAaGqTbgyKlQXUEZQ2kT/LVAXeXkK4tFt42zNqCiXn5sIZdEKpnzPFIRv0SthMV7+WIU5VIIPW9EnkAHrStaQ0rq4ov4/FjNzFOV4I8cK7FkSpMW1xUY0fpph17ZRFWhtEW8/+W9Z1Poug6tLDknnOvEW05J77ZiXOLnUkiBtsY5rNGcz8sF4H5eiCglDY3Ssn/MOfF4mPjiq3t+8es3/OrzN5zm+cLQWb9nPUenaWlBE4lS5XlZGWE5akYy3nqEjA/eOK6vdpKY9XC+FOfGGLQFZRyqSYprS1ysSnwoNpsBcuHd+685nc9UWqy9cRKUkRZSWqgkQIy1cwCyprZ0Ru8t1qyeF4GYAeVYwsiDUTgN3skAxFmNbZ5tKWcO88x213OaFs73B/re8elHd2y7juvt7uJ9sgYLrGzYb8ocVskXCNhRGxMyKxk+ad3AxapRZTWNfpJq0fZldUHhZF8uFUIqTEuQaPGcJAVPAYgHnjYdrtPkJM+LaVJjpaQJc83kXivoveGjl7ds+p7b6z3eOc67DQ/v36FVbd4gHaVUxiWTcsU5g8agq6KqjLaK3nv6zlDyhELz+WdfsNTC1++O3B8ObIYNv/ej3+Vqd8V+t+N4OvGrzz/j8XgipdokNYUYJZTg4fER55pMGsP5PDFNs8hJjUapImB70eTiUFXhTEvyU62maI9BbCzXXApLDJQidgyvXr3k44+vUFSWuHCz39D3TpgHCURYzAepelUrYtHSNKEkmCMEMTVv68ppDGhlMMaRUiGmxDhN/PqzL7l/PErDmQvEAjQWRSkU63n3cCDmVf7YUUtge/ey2WMMYDrGUEgPR0kYtRZnHfvdQM0O720LqBGJrrKurZGlJTxGkQjmlbnBZVBSqySK/k3HdnN82i+VEqxdZWHDATFFNpttuxcVIQScc62hLKyhJAJclUu9SFtz1+YnxcD9Q8f9vfiT3dxOhFSZ54UKF9VIKgVThZEigEAmTcJqX1LGOkHXVeY3hh3NKFMW/CpASGcNwcpNY9D03rTnWYYjz3/ACvysf1YWXk4J02u876kcgQbcrQhgG3QrpX8DCFvrtG8CXPL7Cs4J80sryDngvLsMjORZSMS4XNgx1nZ0vhc2utY4LwMTraQOFLDEClhmhKEq5IFMvxnwnaTUm/b967H+u1bpnWQg2VJAq2PoFcp42cN3w8UjqiJMmFoKunOUIvWV2m4oVbGkzNX1FXOupCXyB7/3A7yzqFLo+47Npmd/tbnIbeXeVYDBucbQqk1SmGLzzJOBrdG6Gf2XRqaAYp0sEd/wgL6c81avlMYOinEGJG13/V3yIuR11DYEqe0c7XdbbvY75tsbYVjHhO8dRTUPvGUh19ySXzVrINnFu8qst4ywo+YQyaU2oL4SsjCqV5Apl0KplZjS5Xptt3u6rmOVdVZqY5FVOi8DoXmqTPPS1lfN9fWOu5cv+MH3f8jp9CA+YFZqjEC99NDfBoLRnk9rjQyu1fNrJc/wOE4tqGNlr7bXX+U8QPOiTiO1JnI2jWEkz/pTbtuHz4j6xkcuANg3EbA2vETLsFk3O4EYo1gZOIu7dgzDQOc7jscDx8NR0ug7z+PhyEevXnJ7e41zSlQ7NWGNFVZeG5SBPLchJobOY1SVtEgrgUpaS+1X1xepZLDqvAC3p+nMpJ9sCsz7B374vY/5w9/7PjFmSW9s/X3Khdev37KERAyReZyIMeOd4XroGxAGpWjqKs28hETldt3kWfYYFBqfZVD/2ZcnfvnrL3FOfOhKhYeHIy+uN9h9T0yBeMpib3S1x3VyJbRukR4fMJXbfVMkdfS55+HKsKxKnsnpPPP687d89vMvuH/38Bv32bcdv9VA2HlcqMHytRoZasJqh9HSBIuha8FUdWFclCIN5nbXMQyeeY1KVpLetjYtuTVP3zxqhTAXrKvkxi7LUdDb8RzIVFLJ6EVo2M6LDnnTebY7hfOA6iRVMUrUrtDFJTI6tKJOKdkcbLshxO8jye/LEvvbBkTC/iriKRZjJoTc4twlGjxHLRGpVZRPKWRSLFhrZMBSErVCP3hQClUlLcw1w/4Ys3i99KXRPbkADlWvvmRiHG6MxnqhqFejKFm16ZCWWO5nCZJi4q8vtHuQlMqcxbA7BpnO+c7S9Z1MoKxhv+94uJ8vaLx6ZozYac0yRQHAvMc4Q9Gi9d9ddSgtBVKYInGOVCwpcTHuW+WYykixVnO9MC+WJFPd27tezgEKMridpusVKWQxpfceTb4UpZVCShGlBbR0zmEHjXWOL3/5ThagNlWBlXIv50lC55rRdinMcyYska++eODqZkvXKXIqOLMao8J4ioxjYrf12M6w2XUYo1i+WshJfGtylHvX+2bNqxqDTQNVpmK1ChNB9Nm1eVTJNNQaB1o04GlZeLw/QIWu60EVnDd0rRgqtciirQrb5p9HraRmqPr69YEf/OCKq6ueaYocj1MrdM3FTyTGLGy7KZKS+OzZRsPXVgvjpsVUG6O5ut6Sc0VXSEtsHiaNrVKzmN5bqRbE10DCAcISMYNuoPGTsbVCCVuuV88Ku9U0V6akqch6AxrjFCapBopnVMpPi3qRqeJ0XIhLYhkj3eAI58J0bK+1VlSRUIa1gElJPOoUBe8sGWGQhSVJjD1iUOmsNHWnZRGmVAO0JBVXJu+mAZ1aSbOmVfMkbBNaoyVFSmsxMkVrmeQqGhCjUEVhqhiG51iEAm1FHqusJMj2nRjA7rYdfefa94O9hJq3dbWtByutHT4sTASkkQdC1cZWbf0qtT6TKKjGCmissiwT/5Ib8GDLM4ZMvRT+OddG+c8UlWUdVuIF880NYAXvaH//hvnx5R21oqxwoXt/IMWkklnQSlh+tVQUhs3QtTRAGqNOQkdUzZLEVVSr0OT1pVQwVgYZWS2ElDHG0fUaa6VhXosKmbBBSdD3hq7tAYfHpa2nT1O+9SIYK0XwFCLH08xXXz/y2et3vH7/yDgvz5o5LsbnImeSwg6toco+m0sR0/k5UJLG6Q2qBZSMcaLogSmIZHecA3MIwnJUBp2FIaZUESC6ro23bWnAex7ev+d8PHA4jRSqNNdakgznMLLEiVoFIKwUrPJobAPaC6oUVNEsp5mYK6mI8fEU5fyITLviWmCDd/rC3p1i5DoNnKeF8zKiJ0XQI944Pr6+Y9/v8NphGtNSa0X5BhAGkLIAvSFmUpjpfEdRmmqcyLPbdDlmhHmuCuoZA0QYjM1XqaVf5bqe04XTaeLx8cg8TRhTn6wXkOh6lCJGYS7kHKRRqwqlDb7f4HyP0bDxms57Ou/oO1nXvbccHh+xRl0GU6ukK6WEIqOUkdRmnRFfMmFg1lIJS+XxeOQ4Rz5/c0+mMk6B735X0rdDipymkXcP97x++5aYJPCl1kpYFnIuIpX2hpgilo5lFuYnWtLx1jS/tZivcGHcl0rz/JHPPMlKBSTORVjQKRf6vme/GXBe8+knL4SNrD+UD67HmpYIssYZLXLRrpckzNRqt9PYZNgIcLMsgbAsPDweePf+PYfjQWSOGqLVl4n5ogPGaGGx5szQDzir2SuRWvUtMTYWyMtq3ZAJRvbgI4hExhiqEoZVR7MkaI1yTImQIrHVQeqyAgq4k77Vi0VhTGa7O3EePf/L//U/5O/+nZ/y7/8P/rwNMdr6XFr6WWM6PK+9nxsgl/yUirb6nUmAVBbmwzzyv/hf/UNWk/zN5kBoKYb2ko6phL2axOpjzlJjPRxODFvPFBZur3ey9ioJWHp+1FKeOucKqiSordYulWUJ9M63FFd9qR/W45K8WVZpk5jQFypdY1eJb7SSelJ+Karo5hn0xH94OstP+8oqTVwP05QbSmlSnDCGFkxhLkCdVrl5BrfhZ6v/LwErSgYyNlnwaw3UGE3WXhiESim6vhNmlVKXPw2P/+CQ1M/m71OfXrHW69CJlvwt7PvaJlayt0g9IAmkhg5NN2xIpbbUvuYrWGvzN31K1L2cs7buriERtVZMKyqE7c7FgqDr/MWrT4zaCygtw/hvhO7Iz5IB9jqyKy1oQaG+UX9kUguSMWo9SYr9/ooffh+2G/H6neaF66stzmke7ydCGpmWmdN54f39Iyl9eJOq1e+2qjZ8l/0t5UQu7d5b78dSSFX+nWIU9lKtbDYD3vv2nDWgs6zruGpAqjDIQkxY19F1HXe312w3W8bxyOPjfasrWr94ufZPYPoH541KLokQw7O1t73OLKzF3luWUImxiBdnKQIENqDYEMhVfFUrutV4im9cfjlPSI+l15Jq/eC3faW2MojT0gORIylHUlqIUQaJXbdhf7Xjxd0dOWaWZcYYQwwR12SlqRRSKdy+uCOROR4PgivE0IIA5LwCpGWmdE7AcxSmyBBaKVCtxl1fnzYGrT25thCMXCEUzqmwLZXj8cSPvvMRXS/DqXcPB8Zx4TQu3D+cOZ0l7bpkAaZevbhjaem5l177kmb8VMOuD7dqapV1vS61cDyNHE8zWmViymw3HX0nw3GjhEVnSlOdVCjaQRZJ69MC+417pEpgwboGylrfduxSiSFwfDjx8O6B0/H8rUnG33b8VgNhx1OiapkSxVSxOuGso1Yl3j4VcqrMU2rMK1kgfSegSr9p06yQmedECjxR2wWneeJNtiOnyjIJSyMfJ3o1YK3BbxxxTaxA4ZxomXMVHfzuqsd5iYhdloQx4vcwjjPjHJpkMV3SgPqNRjtzaeLnSd6nGGE/0QVzM5IrITFNgTmktjBIsZCTwpl1YiSTB/GQSdSsiG0Cksu6qK9/2kQaJYwmDSmKKV9pyVbGiqwohtyitBvA1ZrQFDMppGbk/82KIlMujVf7UDvXWQvwkHKhFvFPAsN4CkgH/GzlapMDYxvtPRdZ3KymGEOqknBonaLfCG1zozccoxh3xlQEIMyFQsF5SeMSCdUKoibCkpinyGYr/hpd70WqFQ2KhLNGfNSqsChCkeKm1MK8REqJhGVhd7WlGxzWO4aNl89V4cWs7JS6Pv+KS2OfYpYmcoocHiduX27Z7zrGc8RoaV6UljjktCRmk9Am0G8tu03PduvonGJMsMyJXQGUPCfzvG5usrEYw8XLxhgwumK0CFxiXDifxjaFrSxzwntD33XUqhmPJ1y3af4vjVlmQNuK7w1D1xFCIAaRHmolRXiphRBSm3i2+6HSGGGFsXl2AVhvLoEWKzjjmm/d6i9HqeJr1jvqHIQ9ViopRUp2rUCUyOVaMlaJEf76/FcxycJZKyynJpOoWTYLlEiG19vaOpHGGuuxDrpqUBqWRZocdQF/NAoj12hcBPyNiflRTOgVGqVbs1FpklQuhqo00MQ68YWqVQyoddWXz2kjsqA1+Um3lBfxEJN/e2/k+W5+ZvMcUZhLgWlsi2ivtASkJq9GHlldtRirl8LQe1BO0jG9rDPeajZeM1iFU/IM1goGjeWZ11ab1q1eSpfEx+eFNLR7WwtDoMjDofSTP0pKwjB47r2UUr7IxHUr5NaHa52ur+mwuqwTpooxTrTWRl0Kj1KlJHiCHKSg0xeNrrpI3C6fL2up8Ox9PoMAlWoecErL2mzkPrKWJrO1l5SuHM1FaioSO0lkTTnjMWiTUS5QZzlnzksa28XPrP1OrQQsdQ3ICUui70TmKlPY5/INwbFSEYn1tAQejmfevH/kPE7Nk+epMXWul3OqRVbtXCdJTik+Me+yDKVyKvhOZD/bYUvIiaQMhykynk9M8yTNiX8Cz3MK5JopujHm0KA04zLx9u17TscDIQZh71RwXWSwHu8UuTRgUzVzcDRKdYTFEaaZojSncaGgJWmtXe/UhhDygQxFnk1rFZ23GAWxJJaSGdNEotANtaVZH0BBqoFdd8XWb9i6nsF5HLaNMhuYkIt4mlZNrorjOHM4nEQ+W0UquN0MbAbxrXFOACirKlYVaolU1dIB20RPgB0B05cYGUdJlTqdzpxPY5OKChBUac2iEvAsxIBWhU0vQ4PSXpdqjUVujD9JfjI4Y1hCxLhOJr3LIvfk+uy0RsxoYajLtr02hXK7jUEYkuM4yuKnzCVFcwmB83TmeD4xLxIkEpJijs3HKYl8TzmDUhaLbbexumwm8nyvEE5r0BHZbXn2pVAxNTc5swxPnfNoXYhJQmS+88krrjc9u93ARy9vRVJXnoB2eb7VBQS7MKwRsMNoQ+c7AR97uH84sttKQER+5sdVcyLlzDiemaezMBG01HW1rPu1IaXEw+FITImhP/Pq5StiWBg6d2FNOGOxVgJlVsBv9YVSk+yp1jm81SLbbOydlAshxguT0FlhRK7WBTGli8fcN4+720dKyfwX/9WP+ec/+R3++U9+h91m4d/+e3/RwBDZ042RNDkVU2OfPx0rO75NPi5+QMu54//0f/49fvmrPf+j/+gfo+rMZ5+/uHzfEo+oKnDEru/w1jZlRRR5bVUU7SglczhPnJeJOS44a7i52omv2LOydQ1XWVU6sixlakmXWyfGAPhLkt3Fz6h9f0iJECNrt7uCYeUi92oAjRYwTLeBjIIWTtDKwhVf+pZhjdzV8oW13etaVWG7G0Xnu+YXJxLvbL7l57T9UWlZA+VjWl6X0x+EzKy1wQr8/eYAqb3/NpjKubTBgpHBwOVlV1RZ2hBLBli5pNW9vn1dEYcGo6ktBVprw6Yxj9KmJ34jfEJeH0++cN98q+0/CtD2w5Y4pQ9TYFEtFZBKRurN9Tqt15NW969jM1rtQ0GSB5VqwFBtPWYSlnmRgVzX97x65djuNjw+Cjvw9vYKYzWHx5HzdOTNu3ccDhPz9ORF9fR+Vihf/j+1QWwpIjt+fu0qAkisQRbre91sRV5sjMF0nnGem6xfSBYog/OOvu+owNB7lJIz8+WXX5Jz4ng8NpA/ynPCinH+JggGTc0UIzG1REfqxR5Ea1jmieH6CmcNIaZGXmj1eBU7kVrbs6iknlm9vrR68gNb+1QB9OuFVEL9Bmar5NlR2qCMB+2e6lGUKD3mhVITm75jM/RstwNKQSrpck5REGPEOcv9w4k37x755NMXuK7Dz52ETIUVCNNoLV5dWokyRVkj93rK2FqxRjVlA81nW+OsF4ll12OteJznKveTtob3DwdePB75uO+IMfH+/sjrN488Hs6cz3MbqGo2vefq7orb25sGehbxsFMK2p1/uV5FzoM2pvkbNRC79Zau67i5uWE79IQl0nUWrSq6ybOVqm2Pgapk0DaPp2Zt1AbiWrXwrWfP6uXJXtdgwSxqzcSQmcZZrESeMbL/u47faiBsnhPaWiYExJIpSgDV0tmcQakqzB4Fu12PM9IAYqSRmuckm0rzd4lRC709yULMs+sLcgliEDPndK74rSwE1ms0IoVcG8/SPCNiyuRkiCFIN6DFZNZ5oQyuU8ucC9u9Z7O1+N7QNUZSjJnxGFhSkGai+Z0ZK/JDbXRL1yrEUJ4VDpVaFBR58GvRDBuZ2tdaCOEpeSeGSNd7afZyJZKkWGom3hJHupoXSmqRMRrVJKQ5Z2FstGuTYyHOiTClD4xJ10OaYPGc0MZ8kO7wJE9QlCTvNSUx9H08zpQkRsi0IqIzFmflug6Dpd92YAyxiHG3NrLoScMr6XnaGEkTigljGx2bIn46eZ0miHFjiuIPcD4nNleJkhJXN/IAh3eB82nkfKqcxwV0pRsaqFglaWWeAjEFcgpcXe3ofc80zuz3A+O40HWWEBLLFFmWtdGXSVFOAjbBTIxSkMq1BFUNfd/Sp4AlRrwz1JpJGXIW8/ocLbutZbv7/3P3H722ZVueH/abdpm99zHXhXvxTPqCSmQRKoCiQAigBFEA2ZHYUl8tQdJH0BdgTw2BgBoqAoI+QEGgGiyiyBIoqKgqlmFVJjMr7TMRL+Ka47ZZZjo1xlxr73Mj3svsZi0gEBH3nrPNMnOO8R9/0xCLojBXPbp4/hz2s0hjy1JAlBUsMU7YPVoXpuHIOATu744CYLUW2zi++OQarQ3HR4leVkXVqaCAVd5ZdHaSYtk3MgUfAuMw88mnV3hv2R8m7u9PlYlYgdiQGUcBeKdJpllGCdOy8cJeWJheYpQv5uHHpxPjMFdgxuIa2cCsr0mkZNKcMMasJsCCOcq9b6yAGsaIX4aY2Z5BmCzpDxilSVHkANZYjFHEJCwaiYpXhJSIUZgkOkFRmmmOXO1apikwpgnfGGYrTakp4rnmqgeArudCwBILKjNMCZcgVpNk7xS6GDQQxkQqQfzdvKdpPUbrVQqYcqJo0I0hoqq/h7ClQL5v2zcib9TVxF2JkbkUr0vxqVA60hTo32xlelwKxsq/nVc1Lr6g5Y3rsy1+KJkK6FR/qqVwWIArYzTOuLo+Lc2sFFFKqyrjkbVi8UUEOfdQDZVrobRsm4vR8PKaxkuKo0Em5zFqUrIobSlEUg/hGIlzYg6pQkTfHRmuEiGW60Vl0tS/q9+XWtypLK4hRhsa0wh1vtVEhNnxMQMi5wxKzol45ue6P2Wyk7UZneq0fAFAc53E5rX5X6b42pqzFZhK7LYdIUa8a9dp5PK9ci6wpAgXkckeTuN6nS5lkfXEVmC/oI2kiqYLKekCeJbFi8VavGu4al7QOIPrHYfTHlen8MIGdpLimRNJibeJLsIGiCnybn/gT+5/gSmRtm/EvF0pYoo429IZzabbUFRbm+/EOCfG0XA6BUKEVCzHYRImb/0e2lTGcxHJQskRXRKKzBwU0zRjrGbMASwkDE1niLOm6QWkbBvNXEYeJngYB1rd8rK7Ztc2WCUszlxkjx+mmdMYSGju9ifuHw+MU6AgCbQ3u54Xt5IqdrXdivQdMGRKNV8XqQ2rHHK5zCklpmlmHOc1TbYUqQ1SLqDyOlwqpXA8jeLrljv6tkPbghpndEwSJmMUzsi64GtIx/E4sN30HE8jh8MogE0u5yTXkjEmUbTBLOyT+vkyEEvBNx5rqGl3ch1inKuP0cRxODJXyazcU4DSKImIIpeC1hZbPElG1CvALV1RuRiirXf65f/UP1Frh1w4J+dqI2zn2+stP/nic7wzWLv4GspALQQJDZGABXNmA8vCREyxJvDldXA6jrGCJ6Z+ZlmT7u/uGEbxECw5r8ClQklSrNZYZ7m62jIHWSueDkdubzL7xw84K55m2gowc5mqm7KwaVMRKa3SBZUyQSmmeZKmNwuEP00zwzCScxJ5sLN1ql9+LRDmvYRWDdO51fi//qf/IT/8/Gs+ff2trApKr82UhNqI9Egew8p2qky1S5nM45PnP/2//w8A+C//wQ/5P//H/zFPT7v1fWKYIQtQ670kg1NE/p/CTFYG13QcxgPDOPF0OKIMtN5ze321DjDqG66slLiERhmzDm9WOdWFzw+qgnhFUs1ykWsfk4A5egFKlSGr57egMQvatrQg5cLAW9W9RJ4PBefzUj8ramE2VhaZKrRti1bQtT2tb3DGoJWY1WvjIEQWiXzOilwHZ4tCwRiNrkl/CzNvGVwthtXLnrdcu8sjJ/G7yzXJWi3edM9+iKreEQn5MI0iz78YimWEUWaV1Ci6CNDRN45UDA81WGJ9hIvU0c/eS6nny4CqTbU6XwYBTDRxqSFKQSWNLbLeLZYpSmn8BYi0SIqFMV4ByUVtos4Jd8s5oYhPW65MwdZpotX4xrHZdOSUaVrPPMte8LTf8/D4xPE0i+pG6XqV69IWpacTtowWG5NWGP0hxfV6LsfiXbl8caUUbdOSUsI6K4NsrYixsnGKEA/aruGqFNqxYWEgP+4PPN7vMUYzjlO1GEoVADvPJpb7dH1UlJyfFQSrrD/ra/WmpN5svaH1jnEO5ClWIDrJly6RhSeulaFii+v7LtfZ1HqW5Vl59ne1V1SKojSpLDLA+ir1JGstgTXZeUoWe6CcE0+HPd++fYsxhuE4MM/CsltYr4fjyC++eouxmqurDucajk8D4zzXAAexGggxELUXyx3jau1eMAsCVpHw5Uoarbm53vKTH77i7u4D45wIKdI0llIgFjgcR66GiRATw2ni3bsH7u735CxhXze7nt2m5faqp2+sePjVkCEuhszU5y9n1vViWQAVBaMKXdvw2aevcNqy27bs9wO7bc/peJKk7saLhVHj6PstTdvRtj3zOEhgIef7cblHWd/hAgRbWJcVF4kxE6ZYPcm1+Jn/FY6/1kAYFeWfxsQ8SkPVNPXiWMja4LQwopaNa9N69uNE0fJEaC3SDFW9qHxjSbEIu2qcWanZWa0BOTrDnDLMibEdajy3mFh3naPxhhASx+MkRXTO7PcncoyQM03v8E42e2urMf8803aOpjE4Wym7TlwU5lmxu/YMx1E8TXIhzLXwqJ45NovXlCRL1vtSCdVf27OkaDzOApzVxc9ZVwGlsvoEpShoqrKS2CbeP6ZSfKUgMUYWGm1zTZQU/W6cE2EUyVcYvx8Eg7rJFCVAg3OMScwNl8MU0RuXXBgHATeVUcxjhCJFky6JbKCoxDxKepjxBtt6UimkcUa1juQcc5VdGiWNRwyROMn00VrHOA9nxouWRKxUKcTaGFxjmB8Tb7+dSDHyzTeDNNsxM41BGpkxcvuyq5usMDJqWyIyRNdAgWmYOR4GwhTpe0/bNcQYefftE/MUBHApAt7OcyE/TZxOYhCfc8J5x34/s+091lq6VkwtXbCchoCtYQ2mmjvrWjxvrnoiGe89c0xs24ZpmLi58rwLEl1fsgQOOO/w3tH2jpgD02lEKcXduwPDmFBG0RTFJ19e0fX+XDxU7zHxMxJ5otUK1579BozR5BjYbjtuX2wwWq6rJJMVUomV+QLzKNK7swmxeOdttr0YB+cKMtTEKDKkFAXcMQanxBDSeCspdqpQUiKlgG89JF2BosJ4nFC6hQp+GS3gg2+sBAbkTM4CANfMm7UBwlisDZgKGjw9zhyeZikeqo+eNVLENc5xtb0itIH79ABJ43uwtoVKCxbKvvjq9NuWdtOQyYQhMgfRwecorJjWO4yShL40Z4Z5xnpN01isl6TIUgrTJA2YbSxTTJSiGMZZAAhnq8TZ12JNUl98DSBIpaAxNMYJE4ZMZ3sB+BRoLSalCYm4X4xhUxKPCpsyTmmKhqjLuv7knLHGMsdZwBUWuYSVifHaRC/mzOXcWNaCKdcko0xCKYmDX4rK8yT5vLYsU0ldzsUpSLMLGVcU163FKkUcEtMYmVOhfIT5yPJbG4HKBhFinqLkMyB08c5rga8KGCUR1vJcS7G7JKLNc4BcqrG1fP6lKBWfrbQQilisT4YpVAA/sPDP6jYp3zlBCaUC5/U7G7BKMc0jm37LZfUh30v2tTkIs3WcxVtkCTO4/Fm4ZAeI7Ho5B/I5hF0So8wxu06o8o32NFft+lq77QZrHKdxYLvZ0LYNwzxwHGVNkSQ3TY6GcZjYHwbu9wdyitj9katdhyrQ5UxIQdKNrUyHxyFwGCLH08z+qXA6BXLKGKVpuo54PK7ASYoRMaUX/xhDlkK0Fn+2MRgvAT06JyhmXbeWE2+MxmhJdxoneJwKD4+ZXWPprWfXO4w2NfQh8/bDO8ageXd/4OEw4bzBO4PSszAFO4024FvHHOdVdgtyryx4z8UQldW3LQm7eU2+XW9iFhL4+vPOOTKShjxOkcJUk2dNZWfW7IwSKXkJFRLJhbNWrCnGgZALMefVVNtYQ986+taJRxogSZfi42qssJAtEgSgleJ0OvIXP/sLrLM8HQ6M0yxs7CxA5SrDQoDonBQY2bdB9ujnfj4f1yQixf91h4ScgKpeSTknnDWyR4VCioEYZe887IXF0ff9s7UqU4hBpE7DNBOzsO9Ow8RpmGq/p6rE3DCMJ5RW9F1H24qnSikChqm6jzrv2HYtL29vcM7y9LTn8emJ0+kAJWK94/rqBu89zpgaUFRqg6jlMyVRKAj7PRBjot90oGRNN8YQVlZJYRgD4xgqkFMBBfX95++rrz9FactuOz378//vP/qb/K//g7dSExhLUYpxDoRQv2Md0lhrWWRZcDZpF0lU8+w1f/qLL579f+8l8KDR4KqnlQwRs5iYawEthilwGiae9gPGF05jh8KglKGogKoDwhAih+MgKorKgjeVYb34ibWbhoI09Lnkej3rM17HKLqCMKusTqWVafns0LLAF5Tsv4pVebEAPLIpLa8sx2IOvsgSlQJlFco6Gufp217sVXTE6EzK4jupdUKrCvBdfp66zmsjz+NqYF0u5K11H4w18Ml8LBks8vteVYuEKi3MIa/sKFGw5GdyJhl6XVoKyEeLRaxXMkV8f+tkJ+Xnw5mSi+T75Itzq5ahjKpp1PXrVp3cJUDWWLcCmlKbnocMUvdkpjmha08k5LVU72GWYmOtW5b6hnI+f1ktYJikl26cYk4wpkLj3bpaKSV7/zRHxmmqXloOa3wFoqQeMXX4lRH/vf1xWEE5teBK67ksVdosrNvLekjpmvxe7MquWbjtYtNTzvV8tfB4/+6BFFLdY75zC5xX3lKeXSsl/hBy3pTCO/G19Y2wr3MWRuPL2yumOfHh4UDOsQLmsf6zHBqwlRhTCFlAG2FZ1tv542JOnRUsElwiLGlTxONXJuARtF3XaWstmoaShXF5Gk4MXw3rvSJ0bHl51zpsdIxh4N2HB968uWG7bZnnyN39Ix/uHrHO8oNP37Dd9qBgJDKniNdn6X7MZ5BwuUcLAoRdbxt+84dveLx7z2maeDyMKCOMrabv0Cju7h65vdnx4nrD203DOExorXhxc8Vv/OhTXt5uZVirAhTDaRiwdd9evreQfNKF5P/ZiUQp6LqWNy+vUSkyDiPbbQfaMafCcZy5fvGKF69u2fSSEN1ttihtMM5Rao25oJiZvK4vSp+BsOWmKlk87lK1cRiOE/MUuH1xXd1n//LjrzcQBmeoV4mvlphii7HsUhBmhJUSYuZ+mFBa4xaDR5fROgtiXjXfIST2TwNKKcIs/k2Z+lpZ0VoYTgHViOeQNsKQCqkwh1hlLbpS2BOnODKPs0wVjaLMkb4oSknkpDHOsPWW7ZXl+looyzEVEhHbaPprSy6e+/eaU4jo4ghjIM0ynQ11wpQr5VhRhDlQJIVkkRMqKmUSWajWAqOUqgcHpYT+jxYj28VzyGj9XePnOkR23jAdBdEeh8B0CsQpPvME+/hQiuov0oPSTNPI89q8UAUblUEiSC9oUpSJmSkadGIaZ7r+ujJbpIi0ja2TOiVFeZ30O6WFjWE03abh/sMTWmta31BQQlsv4qmScxGT4MZz3E88PQzcfTjRd45xCBU8LCilq1m8sC0k6SWtE1drFW3nSVFO2Ok0iu/YPLHd9Ww2HY8Phyp1EFS7ZKGqKiUeQbLRCouuaRwxJJ72R26udxijCVEo5NZqjJWNxTmNdWLsukyDx/HI4Sgmoof9ROMs0xyY54hGUtIolZKfI2SDKorhFAkx8/g44FtPt2vpdh2+Rkovk2pjNMrLJhTmSIqBnCQRzzvHOE7iTzJH6b9KJs6F02nGe8t4WpJRhWFYFJIKWqm7MWZ847CtI0yT+P8Ms/iR1QLMeYur8skSQp3sKdreU8LM6TiRo1jw5iRmlWEWc+ytlSRQZ806tXJWV0AoSxqUtWIcmoTt+c3Pfslv/OZnJK1QxjIOULKqgQ4iL6AWs84Zrm86ASqtx7deUq2UBp1xxkg6mVUi7XQWY4XpdnocmU6JRGIcEklMNMhFpIgpJ2gNpgjQPY6RRpkKSsgymVKiTHVj1obxNBKMpu86FArTOsI0CADopAmPSQtjYB2bRnb9lpQiW9/QeY/SmpgTp3kSs8vyfIPMKZM1q7RQikCR1SzpXQs7zFm3+mbJyxSWsA8KKxvs8kg5MQ/CGrXGrsXn920X8vOyoGtTnvmEXPrTdM5xvekZx0TIiqGmCF++6qWHzTpZFZFmldFcysJVnYZKU2yx5CJpoxRIJSBkkoJRZpVbgBBZrLOYolEqMNZzorWk46Zlyq6yeI9EaagXWWHJEEMhh4y2GoOwGV7cvMCrLddXNx+3YfU7yT991/DZmxuGaeabdx94b9Z27HwNSrW1Xib3uZBSrCBEBQeTNEFGW/qu4dM3HZQAnJva2+tbpmmi6yQ1bHk+O91h7I45BAKZu9MD94+PPD3tGcdhNZqNqjCdJkYiH6YD7caSc+F0nBhHWd9zVBw/pBV48JtewOkwE8KMpKqKR5bRBaslZdhWhqy1mqb3qJIZhgFNIudIjhq7tXXvl/M+58Q4ifQ7RssUJg5PCa8V6MKr7TUhztzsrphD4ul44jiecF5zfdXSNJbdxlfPOWH+ed+jtGOOkbbUbheFypHvue2lLqgN3aWJ+3rkciYOQjVZd4RUUCqjVCAtXocLEFaZApvWroDcIgdxzhFCYJ5HjrWwVUjBPs2OebboImyipDTdZoNrxIx/6fIVUvgO48yf/Mmfr03xHNJa38iA3hBSxhph/eSs0E6x+uNpRFqymFtdsmeWTuLiqf7Yn4Z6TxekGev6jqZxq9dOyjBVr7wQJRHQWkuIYQXyU64yYhRN22JdwzBHTrURaRovtco0E7Mw+x+fjmy6dgXZtzU1cw6zXANt6LoNn726QSvFOAwoFK13UBJN60FFDqc7rC0or9H1uTfaUpTDaOiaRgCxKNdJBhQKtDAC4hQZTieG4VRrquq1ttTQ5fu90S7XBePmZ3/2n/29f4f/1X/4D9BGoWyL0uIFmlOszEEH+RI0qOtibVK11qTkn73mv/iXv/vs/ztnGUuse4JZDeNFrqREpjhLeIAsWZr9dGBOiRwDbdNXI/JUr2FmmkW6pTVEWwfDFRwVv3xNymH1xVsM4pf7x2glptPP2EnV229Ft+QoSuReCwCplXq+4l4iYvXXFksHqGEcyBqjtbR63lnx81XS3MtAQ9N6Lx5GFyDUx75ay0BlGYav17f6TqUqlQcw3j8DVShy3tUioYJKLDizyi6NsRdpYdu3AvBXH6hSEKlolb2FmEhZ06mFCfv8PkwxootZmXRlXTSWU/gcYLv8xgWpV5ZmP9fqJWUq8CnAe+vEMiMl+QmlFu74uZ5QC2Pmo+HRyqZbLmn9nI2RAfKUigzh5BfkOlUvaAFE9EWdUCpQWoeDRYD7aZq53nbEHFFKbE6sFvAqVDXPaRjJUSSSl8zLaQ5iG1G/R06ZcZhRLEOfZdhXVmXT960F658st0MRwHYZ3khwjLCHjTZs+4am72gb+bv9caBvt/zxn/+S/XGock9T+UHPG1OljNTTCPNL6tH87P5agWLOjFRdGbmLvU/JMixN1YJIJolKQP+SMSQZQipbZZkXtZ66+EfLfT5OE7kohuHE/f0DN9cbrq93fOha5vCBH3z+CTc3V7Rti/Oeb+7fk5IoiZJrsNVHTqTZFRBbzq1StI3ny89ekcNv8rOvvuJv/s6XfLh/QhtD20iYS+sMJWbImR9+8Yof/eDNCnJeXQlAHqJYQ3zz4YnbOTBOgdvrLa1farQKaS6T2MsLW+9x6xU3bsPDwyOHuxPF77B9Q1KGKRSMb3n56jO2uy05i//4/cMeVVLdkjWUSIoSxLUMFcQj92KNRIZhpWIcvm14/flr+m3HNE2MIcDf/c7t+J3jrzcQttz/eq0DBR3kHPNbUKBNpc5XKZ111QxaHmDnZFFyVlLxrBE7Z6M0p8ORVPWmZeUvF8Yp0UXHPAvbp6BWs+pxClijaTtLCJFhiMxTkAa9MXjlmOaAvzK4FjbXLWlObK48V9fiAXIYI8MUasGj6DrDdudRqjCPImuIQZgzuRRCkamPUVWuK19+/f2Lik8WyiQFT7e1jNOE9Q7nDDGOpJxwxmNNpZRfyHW+c7gipvuLJ1iIxJDWDRMKv+pXrROvrGmq7DZVKa2cF5NSoGQxbHbWUZImE1FaTI6da0FrnG3BVEZOlREpJeeoJGHiOWPY3Gy5f/vAOMzkGLm+ueZ4PHLz8jVNJ8WrKhDCJAWUK/jGCntr15BS4el+lKLGGGLWtdEzGGc4Hkf63uOsFj83p2lbJya1IfJ0d+DpaeSHP36JvW5JeSZExW7X8XW+l01xPW9FJhXGYJ1ld+UEDEuFaZ4ZT5G4iSJNSJG2bUhJsbv15JwroGLWwsgZi9Gew+GRrm24eXHD/unEhw9HpmNlCRh5DryzKIp4hVRW1OPDnnlKoCIvty1N59cJS9/0PL19zzDM9TlKTMNMigFjQTdWmpTawWjj0GgpLqdEjHB/f6TzHSXDFCeMs8KCqadEa9GdN5sG22g2fsPT/Z5SMttdu1LofdOITCUEkdGYTNc5NtcN8aQ4PR3Fk8RalIN5nEilgJEiq/VW/BQmuXe1krSzMQRCgZsbz/VNT6nysNcvt2hlhJEZxXPw7TdPDKf5zFZQoIzCNw5nLEULc9N5S0wBqxVznLDKsNl0GK9oWisg51w47gP3jwMhaLTOHI+zgPBWGEX3T0e8BY4F03hy7WojgeMwV29BQ4oR3yjIAuKXVBjnCWssqgRKDhilwIBxmkRhjBW0XBojJcmYrzdX67O8MDJiFEm1s0aK/oXFVc5eYyAFpHbiKRJTqiwfkQsuXloUxIdNI95si1loNVAr6TxpVUqhiiZEaVSMNjjjZLKXLwqUZVBXQNXizlZZdQrP1yqtNduNJ6WNFLTlREhiaJ7KuWy+ZJsszULhYxBsWdLOEp+cxduys0oA/VnSYIGVnbpOZ2vRXTDoFDFWynRjFmldoQb8CBCfYpWrIgm1kzTXZIXXBZMNVhteXr9k027XovB5K6BYliNrNdu+5c2La17d7Pj6m3csEublh0TCqapM2AqzOAZxnVS2nh2NUg6lpeB6/XJL0QOUMxCmlMTeL0eMEV2L23GYOE0jd09PvPtwz/3TgRiCsALqFXj/ds/1rqVEUEnhsIzzxDzOzFMiLcnLDWybDfv9nv/lv/23+cf//U+xOrB5IebLIesqF7cY42qBXFPMNHStJUwDaRYG3jzPWNfgG02YRC53OkViVtw/ZHJ03Gwa2tYwTIH9FHn79p6vmnuazuOfHrFKMYaA78F3wop8eXNF3y4Mcsduc8V2c03jG6jTUrTHCEKHjpcM2rXtPDMQfhVAnIWFHKtc7nSqIQqdqkwa4Z3ktYGRYUvOYsiutOJqtyEECYsxVtjeL5t2HajZuibM88xpGPjmwwMPpxO/97u/TdcaQhKgzlBomClYnh6eVpPxjxtmAOsk6Kd/9boa0bvKXilr8qZaMLCLekSeILmFdVkYDx+BDcs9WaQpbFtL3/rqnSfyZG3OZXTKZxP087qjWBJDrfW0XY+2lh1UVoOwc0/DTMrCypnmCDkxDCNKa7a7HcM0iCTHt/VzGhrf0Xcdc5TfM6Zwtbui32zYXe3qcFOeSVtBZaUV3nvatsV7eS5F5hXFbDkGsloYG7EOIcR7x3mPc36VfFIy4/HAOI7fc9bkGMfEPD8HX//df/e/5T729F0nicbaUiqTO6Z6HVT1YVQ12OWjKzNNzwcif+/v/+1n/2919cOl1AZX9iRjHcY1wj4MkQ/3D6ScmMLEaAK9b2icsHVjHQyWkmuDKEBKqvvRwmpWKJzWArCPYlHh7BksWpnAtRZYmL/Ln3ORgr6CJXUICKyJhxcQbh1uyw9ezlqooKFsIKX2AwLolCID2GQWTFj8j7SZng1eaulZ//v8rpmy9qELyLckNWutMcU88408v+DllTmjIeuzUn+olEIsMjyJIdF3YjuRlQBtIoESIEDrsoYLhWwIKT1b99bPrr7nI1x8jF935FIkCR1hMyu9rD3n/V9rMHV7m6Yl7Ew9Azu/68FWwbHMd2oE+Xmq9FPSiqdUiAr2hwPjHFglwx8BT8unmucq8TeZ7caR5hFv5XPEJHtTyBlygpIoKXE8iDdn27TMkzD0N5st4zDW3lreR+R+dh1IynBEPvQqBf41Q0g5ZwqlllTRsio4vJegpk0nyaWfv37B09Oep0Phq7dP0stdnkNl630UBaiScct3z6UrNNYzTDUhuQYtqApSWyu1qDbnmyUFYTrqRWJZCuSIQryz1PLiqg4+L1hp4sltWMSaMmQIaK0ZTgcxos+iTrnabfjRl58zh8QPv/ycq6sr5mnm/cMdMWfmaaSxBo3IL6F+/gtMqCj5s77v+N3f/gmff/KSt+/eMw0DfdNQ4szjwwc23Wte3m7Ybl9xGkINJQocTxPfvP1ASpnDaax7V+az1y84HE/8jd/9ki9ev6TxBqUS1tY7TRXOaNz5wizg7utX1/zZ7/8Ru093vLq5YhxHjoeBaQj82Z/+BZttj3OWaTiiSiTNA1988pLea7IpxBxXTztbZdmpppcClCJXYglIUdbw6otPeflZIoWZ/eHwnfvw+46/3kAY9eZMkJMi5LACIMuhVcEYaBrHHMRMzVlBVZ2WaNxlEmaNpW3c2vzm6vegGChR0HS9TkIywzShh0rHla6FQSt5DQ/WKXY3LYWJx8eZEqQwS7FwfdOgtOLmhUXZRMHSNZB1xG17rrc9Zj8wzzOFQrOxXL9sMdayf5wZD2FNwlzPRSjSLCmq55nIuFag0CjiLM3TxnmeHkdSyHSbhs22Y/FlMEbCBJZm9uPCs74bILIATSEpGI4BYxVXO0/q3dmwOomcLaXzhCRmeNofedofUcZQ9CLmkcU9BFnsnfMoDM5t6doWayxTEZljjjMhTBQii89/CEWYV6VIGuMoE9ecxalmGgcaB23rCHPhcJwoOVFyYBwsznp0SXhtiCViUTTGcDfJd+uvNmjv2D8d5X2SgK6mtWivGaaJlBNXu45u09D1nsZ7inHcD/dM0wmlDFfXGzZby+//wZ+RU2K7uZaHuVQjR+vXZB1TC5lcFK9vN9W8tuHDN3egJKm07xedvhi8p5LxrcW7glERZa1oekmUJI3qT//4G/pdx3F/YhxG8ZTqLdtdS9NZavAO8xx5fBw5Hada/MD4NLLZSIKYMyL96zYt+6cTc8mEkBmOgxj2dg7vHMfDgFGKtm2JUeKBYxCvug8fjjKZ0QnfOna7TmTKJRPzgAmRbut5+WrHlAu3b254un9knhOHw0AMgZvbbW2+TGWHaMoohVC3raa4d0eMNTjlsFaa1+NxZtt3vHixBa0YZin8peCCgBjNY4ykwcwRc5rRBtrGkkZLDAHBWwtxkOjzvnNEJ6ND54zo1RWgMwmRZGgDN7cbrFeUvCHNkbZpMW5Jb7RonVFG4s1Px1hZ3cKULAXGsVRplTCNWi3SX+81KkkTJl59im7rySkRJwGHrYaSRS6y226qtEHuwXmOzHMgZmhbkW0eTo9cdzsaY59PN6lFKbk2vfpi3SiovJjiy+/Y2jwmUvVjM2vDZmqwwDJFL/EsPTR2AYrWDUCSaZXBkomxnKfMpvDdcqzKGiqlf5l6O2sgKRLPJ7Rd4zHXhjkkhnGSokoXppBXW/ml9JbvK/6CUFmVXEx9Lz6MnAdNyRITL+a0Fz4iK8vnYsUtiZQiMY4iu9a5NgyZptFVPqBovEf8mDMlG1S9H8JMZVpoVLJsux0//PRLSZIsl+8DSoksw1qNUoaCJPAWa8BactEoY0EvSUI1hj1nrDdQUvVV6ijJEsNcr6FdRzJzmDiMM/22Idav2qjnYGTKiWmaOJ1OHE8njuPAYTjycHhkmguQznk2CsIkrMFQ2RvGa96/m8UeQIt/Ys5VGl8SX32758XVNX/37/9XHOPIl29e81u//YK7xz2bqw3zHDgeRo6HPeNJoZWn6SxXt543X2yhbLl/25BT5u6Xj1hvOR4k3VOGOGB8R7cx5FmaYO8Nru05HgdubndYb5hH8X7MCkwjBblKmt31BmMsBTG53m53XF9dS2KjtVgiTglbtpRC/D46WBGvynmWBM3veMQs57qIjGS5/+3SyKsqydBlTXsSVowmowW8Gmc2vef6asvT457TfsQbI8a72y2dc6Rc2I8j+9MJpRxFddwWxe3r11VWJIBDqbH0nVWMVQKstUJnYdV+XIvEIIzakgvb7ZYX1ztSDDRLGArnukPkWwIUKqTZRFUpaan+pN8zvFuAv37Tsd1J+vTiLxnC/EwikkvGYFb2aIaaIq2x3mOsRRuL05pSLDFLeqPvmrp2QAqR1ln+6b/4fY7DEas1L65vyCiGMUoSonH0jedqt2FKitsX1xwOB0KYV0nhwliyy4BBLdYWVQKkkHOnFoA+o3tJxk4JUtsR5oCOlqOOZGXQzqGNE0CnMgBzFplYzt9l6/6dv/O/4W/9rX++/v+nn77n3/v3/gv2+4Szln1OpA/7FUzp2o4GqT8XGSHKrJllVPbPHL77XsvxP/13/rlc6yBMRvS56ZZUEktrHbut48Pdh8o+k4secmIOM36YKK6j1AZUKy3sOSeguCpVhVFZ4ss9s3EbHsZHtn37nDmVZFCcU173haXHKPrcillra9+xAGIWKkMqcU5x0ywzzsubVdX7tTDMEe80roiP7LI+67r3OCMDZjGmX/yC5SyEGLFBlC3LF1tBsAUUAAnNAZF+qlIH73q99+Bi21sB6MX3rQjrUJ8ZPcvwJ6XybMCkxXBUwOfK1FmYZMsw7W6YcLoO7OrvGmtlkF4WGXY9S9Vn9NmZWz7vGWc8/4OAOylnslUUc/5+68sqaBpFCKCr17DK312v1u+klYT1KGooyPebe/vqcZysYbft2bQdj/qp+rQJ+J5LWdl8RovMefF2fnh44stPb7gynhCt+ChFOKbMXIT9eDweub9/4MP7O0AkmG/fveNxf1yZTnEOBK2llnBxtchZbREqA3GVsNUhqGCyl0jt8v01vg75nbsA6LuGu/f3aCbevruX+1OJB+RyCHN4AeIawAvDLMUVDbROwLoxDIIPzDPauvq7i7ca6/xvGZKoOjXRVhPnVIeglaHMd11izyC0qvWhXWXPl6naFAmnezo88fT0yDSONNueh6c9f/BHf8xut+Xu/if85Dd+i3EcuHr7LXdPT4RpJjYtRgnLM+dCUrJWziESY65DseVjaFIuHA4nnh4OpD5xOBwJc6C1lutNz+5qw6YT4/y3T0e+/uaeh8c9UxDF0TTN7DY9zZeen/zoc07jWE/UUvUuXz5BrPRIVYEGVWv7GIkhVAIEfPnlDxmGiZIydx/uGMYTwziy3z9xPB1ovebHP/iEF9cbet9Xr7vz2f7qm/e8enH1HcB+vSL1PBvnMMajVYuyz0HRX3X8tQbCtBIddAxCRXbO4XLClgxFEk6sE0+NIYwoZWh8XwsrCAmUcTjj1g0ggQBCRWjaMUQEdRdbWo3COTF2jSni/EYWfxRTBdlQklLYNDKRD51lv9eEKZJt4fqqhZLQWmRl210jFTOR4zASEamA9Vo8hhRor7m69XXDVYyHIH4YF7TQZdtRWuEaT3fV0W3ac0NZCmkKTPsj02kixYTzHdu+Yds3zHEmVg2/s04Q/18zNdFqJqGYQpZkPPm6tJ0T4/AoJvMlF2KXGU+BaZRUy1JksmOq5418coBUU+sE6c85YkwmZ/Fc881WUjQiKFq8M2gK02nAb4W5pI2SAmieCcPENAUBhazmYb/HzLIsHw8zV9cbhlHAjV2r6gRGggVCEkr1NM3S4FnNZufY7VqG00lo87aaxhvF7npDmKKwMRxcvei4ebmlxMThYaRpG+Y5cNiLQeH93RFnHWGOPIahGvpXKWgudWJSr1stYmJK9F1DTIndlRhpPj7u6fuX1cNFY5LFWE3XtVgnTTypCKtj6zgdEof9SIyJ/eOBN59e8fUwE2PkutuBhnma6XpXgRiROb79WtLYjPbsXu5ovUjYnNGEeeK4P5HGiRwi1lusAtcIs3A4SkLidtvRNIrNpiXtB375ywNzyMQIXWfx3nD7aodrHRQ4HUcpdqym8eJFpnRhHEa6TUcp0Gx6jscTN9aQlEzxSk7kGGm9xbfCbptPM84ZnGuggsYAqhR2Xccv7x6wrcNqedbjJIyuphNwWYAeAC0+TWOmxMycMqeTnL+m8WyvOqxVnK480yRG66mmfaFUjaJSzEnM0bf9hqLBN5ZpnGrqo/zOaRgq2DexP4yUYpBlW+aUS9KfUoYwR4oG6x03r3dYrTg+nZjGQJzlHKdS8K3Gt57hccC5QuMUKgeScjR9I81HkSld03r6mlJHTni9QWtF3zayNJQz0JNKkmCEC/A8p0yONVW2gmPWWJxxxLSY814kjNZUzYXdJ2CCgBvaXjSblTmikD/XyO9bbQkp1OJNvDJ0jbDPOZOKeGJZZ9dY8BgTVhu8NThtmGKsU9OC0wbXGq42DfdPjiksUz9JPjyDMKpORJ83Zyuo9VEtfCmnHA6Ktjf4pqsMkfJsmgxgnIQhzGEgxhmlBajqllS/Kql2VksiaDIc9jNdp2hsi2s7+laafJMNOlmuNjdyT1SJeyFBiZQ4Yp2nbxt2mw3GWZlr5ox34kn06atbCoWffTOdATulVyPpsySmer8kmOZIiJIeZZWibT2vb3tScWuhfIwSTjKPQ5VeZGIM7A9PfHi45zAeZSClLW0TxfIgFKZZ/MNSijXlFcaQCPsT8xSZJpHux0WuX5stgPePD/zGF19y/PBzAfR3DX/zxzf89KffVoBZikvnNNZqut5ineHwdCInaJqX7HYdxnyLVpHhNBEnAXBiUlCEjaKdnIO0T7x62dD31c+ulGdMQGN1lb1CSDNzsLRNK/41WtJ3MxPZGHx3i2k2dY8QL5SPWRG1c13ZKJcMj+UIiKHu0kBqLcPD5Ugl1jVBWLrGmTMwrfRqlvv48MQ0DKSQxMjaqnUgN6fAOM8M08QcAyjF9fUOtMMYwzzNOKOYTgNWwXGunkq6YJUSVp6qITU1PGV5Ap3zbDc9t9c7vti1HKMAg8Hpi6ZQpugxLk3nOVBDVNeqgurn5zblXMHngFZwtd1we3tF33cieUmSCKb9WaYXY6LrejF/lzkM1rVYa3G+EXVCHRwYbdGU1Sx9KbeW2st7S+M80zxzGA7kAtY09H1f/UEtr2+uuLra4bznq5Io9DT9Rs5pmGu9a7HW4Zsl0VDXe+H8+JYiIQkLk806Q9c2lJLp+xbn5HOnJJIVhSEgQ6P/93/99L0gGMDVbuCf/tN/a/3//8P//v8hbORSSGEiJtlnFnbQOAw0263UGhUYj8qs8sZC4XQa+Obd976drCODx8dsHK8AAQAASURBVPgWaxu0thSgbzRhnqtcu3A4Hkk5stm0FKS2Mlaa+SFnPAo7D6imJasabtLIvifBLoGi8to/1FZ6rW8f9ife3FytjfnZs7Gs4MKy1ueLPcJqc2bcXaTLXjzNUj+XxdZqAW9rUX1xpAxlzpJiXy9PrCBTMksjORKCgCq2pj5KYvFF8FZ9X1Uy1f9d/mzxLKoJ3qtsdv246hzasdAv129TJZZFLCaglkdGY1pPjOf7Sb6v+Mmp6qkpXpQaazTeqmcCuUtwJuWlQa/XQMlHucQPlaoV1cXWq5WwT+wFG6/k6jdYzg32ZYskg476p0ZjjCeHSK77nqqfaQFKXE3YzkV8padJgI1lWLQcYmGTGYaROWa0aaqNTxQWfhKWbowJjwM70borjM6119S82NwQYmZOieNpEk/GKtPNIfLw4Z4P2x2+aQgxMIdY7wuRzzZebDpyyRXMlTAUrdWzPV9dnOusamjccs8sYIXWNI2n7zv6vsN5J+mkpTAcTuR8IqbK9CmFzabjdApSO9jLoKwzeLmkPJeS6WzL1e2Od+/ff3SRLp+5RJjFG01rRds20vt6x6bvxKPQWOYpfC8Adnmfyb/EQmU5LkGw5Z7KqTCmiQ93D7x7/4HdpsU5zXE48ps/+RG/8Zu/wdXVtShWfLOCzvM8y7NVLZdyhhhLHShnqUu1wlaA3FjD4+Mjf/EXX0nyaIEX1zuuuo7bmx1t28heoDWhDrybxqN1YpoDzhq2247dbsOuepYtI9+zH+yzEyGbIcJKN2pGW0PXNHz+g08JquH3/+W/YBgnPtzd8fD4xLv37zkejygK/XZDf/WSORveP5x4seukV8CS6pP9yeub7zANtSooEklLwIeu9kQiT1YX8rhff/y1BsLEtPDsTxBCIBdJOAAxF0c72eCUwXlDCqVSrte18dlhEK+MVGTqWajaVCVTFVAicbRiIDcMgb6mrDmnqxeSpusNfe/JqfD4OIkhfy2wDseJbisL0AI05JyZA8zzQFGz+InMcW0Qnbd0naOkwMHJdzBOGo/lWGRDqciiqUpNEFNmXTCMsygjBf3LVxuMt0JH7TK988RgiSFTlBGPKlMXNa3Q2ZDj5XYj4KE2qk4kMtYrximy3bXc3PSSuDZF2t5xehx5uB847CdCbcyf9YiVvWesMDS6TryeJNCkJnySULmaBZbFlFthdEOaZ9IcSXPgatOx8y1PqqBVQlmRKHrgOJ3IMaA0fPX1e25ftdy8aJmnE0Y5qNNIqzXDaWYcgyzc3rB/OJIzbLoGX8fJ1zdXtemHL37wml9+/a1QWBfwJCVCnBnGQfynTOZ0HHjxcsOHO5GB6VpMiEmj/I5ajXFBqUyYE4ejeNy9fnPNzw57jHMc9xPTNHNze8PxeGQYAyom3r9/JKYgm7OzeNtQiqGUyGnIeCfIZc6Zq9uethcQcRxGrINOGUlOm8XgerPzjCfZPONpIHWeFkOYAqdTYTiMdL2nZMs0CTvTWVMLl1JNmcWXwBiZbr1/PzJOkg6XS8FvWrknW19p3InrG2n0wiwghIqF8TTiW8/nP3pNmmZuX7yuVniK8TQBAjy1jUcuRAZfGO5H7t/u+eyzl5xOAnD23vHh6YkpRjZNTwaG00xJefVfyrlQtAGjmYYAjSRyHh8rMOIsvuvxDryFAXjxcos2ijkXMsKwylVOE6NIqnMWX5mbFztCCDRNQ6LAnHFaY7ytMoqFpbBMZWZUURAqhKBAGSXAvwbv5T7yrSPMkriGlnOojUxvdzetNKlWmj7j5M+da2rc9GKwqlFJY5LQx283HbaaBNvqXzbMI6VKkp+t0SmRYiQVKZrtBSgFtXBG1ehooAjbKCQxByZXA1UUOea1uFg2RG306h+wvIbcN0KpLilhEAaa8x5fGbOLZHwpps6yFGidJVspmFrXkHKhbRxtY3k8wJySRHdfglWlUFiSmr6nZPqeobA0QhAmRYmSUsRy+up6ra3GNx7XCmB+Gk4Yq3HG8uJmRyzyHMeUSakwjoHTUNl+xkgEdmH1mpPXNNzsbvjizQ8rg+4sOpJiP6FZmqqlZYGizjNRASrP19pUH0krUaviKZlz7eHUs4JVK7lvutaRk2IKgXE6cjiOnE4jIRZO43Gdzo7zzDiPpDyDSjijhBuRNdYWXr50pAy//PpUE9CUyD5k0iWFfDmzGQT/OgORMSTe339g1/fs9wPTHHh8zDSN43QYUQiTbQ7SqL945fnsB9c4o3n39oBzBes9P/yNG7796h3Ho7CatLPYZotShs4LE+5UZmIInE4Zay2Ntzzsj9iFEVIgzom2cXjryGliCoopaNp2g3eeHBO2tTSuR9tmbbAzi2T3+RFTYhwl9W9pbNZ7UAHGokqBKD6XRqvV7DvGiLeSoDmNmd1NzyevX7Lf7xnCiDfQ9T3TcCLNkcMcaLqe47in61tKgg8PT3wdAiFG9scTh2FCK8M4TZKKWWAYR5Q2PD4NkqY9DhVbs1jn8U01IZ9FsmO8RiVhgBcKjbdsWgdpxjY7QpXqrUmMF4eAYmJ1UYpiOB1w3p+ZIPIUSN1lNSVrktHEKA3D6XBc93ethIEZY5AGrT67rmkx1q9rQVkkcM8WgPw9oGU9NBivubt/5P39He/v72sN2NK2HZuuwVrNde/Z9S27xoo9gtFMM3RGfnafC7mI35uq9Zz1hr7pZJihkCTDmJiqP6pSijlEtFka7cQ4BuZpYkF1qsMmMWe8Nfz+v/g/ff/3AF6/vuNf/MvfW/+/8YHjUH2lUmTTbSWkCRiHkajFmgHVgpVkwzTPqKYTVmcFfP/Vv3r5K9/zv/1nfwPb/tc83t1BKbx6/YrDfk+YBo6HPVlbnPM8fPtWANmrK77+Vtgwymhu+g3vnwIvVEDNI8Z5ut11HY4HmCdhz1Vv1OV4GgZKVlz3Xb2M+jxo14WZmXGeGKdJgKZ6Pq2vUjNTw0ZQzHORVPC1DV+pJ+v7Vavx1eu3btwX91iR3y2K1lhhJxZJV10sJ1KUtOaVYQN1qFMll8+2s+cQzTIEU+j6/BQWxbzUm8Ju/Hiwcz5kz4gprfWNqluoc5dsOqhk9fPQTIkSwen6mUohTs/Xt2fdehEQcjVo58KI/+LH5K9LNekWtYnI5womq7WPW7zmJEzh+fcrWRPLLHWSc8TiIUe0EjsLpQRwX2Z7WolBvFaKx8cDWss5SUmYzQX49sMTb15c85tffk4Ima/3b4HMbttx/3Sg7VpSiuSseLV5gUJze73BNw3Ge2YMTWdpgBCXoIMK5MLKFH1x+4L/5v/3j0HJPgALu0rqaWEeS4K71gLuKNSvxBxiliGNfM9KYCnip62nmb7v2fYb3r1/yzw+AWKhUrIA78o2nE6n9bqmnDjbMpwvbkyBlM+KhhUEO99qsgartA46CoIfpFg47E8UCq9e3UIFWTvvmKdxHZp9fIhqp4Ky5swCe8YE4wyw5iK2IsfTxNP+xPE0cbW74nd+67c4DSN//Kd/xm53Rdc2/PDLH/HtW0H7wzzjnSck8MoIYL/cO1rVvTAKmGitWBo1HQ/7gwQvAWEKHJ5OPD0eefnyFu89Wgkgudv2tK1Y3TjvGIaZ66sNzlnmENlterRK0osrViD3O4cyyKone2jbWF5/+oo//fO3/P4f/DN+/tW3DNNMyMI61cbQ9x3lOBLjW/rmc+Zp5tsPD3z66nZ92aZpJUjlInF1AVuVEjJDqQi9YpHI/tWPv9ZAWIiVEn9xj8YYmKMYqSttydmSVMEUYR/lWBdqWRVlG1IKkVgUtPeEWYo2aZgEibA216JBNr7+pqkgmTRVzjvxC0hiVA9yo6osqRelFNrO14mBxjgxAJdpg+J1u+XBToQreHrcE0NaqacLS0hi5DOng8j0chKAYw7Lwy+F7SoryuIndSmZVgraTQt9Q4lJHiKrCUEau2XadZmestxTrnEko0khUpIUWCVLIzHHJIlwQTbvnDM5FW5uN7SNZZ5iZTQIkOac4cP7I59/ccMwRDYbx/aqYzgJMm1qIpOpoN04Br799oF5HpmDMEC8ayhlphTZcEmGecwcDxHFROcleVIjpop1NMrTfuDqupf0v1JIEb795QNKKz775AZlFWEuDENkmiPWCtsGzZqAYbDstp2kevmWlAr7xz0/+/Ov8Y0VuWnf0BjNfp4xxtC0jTBrgH7T8vUv7zDWorC8f3uCImyOGCIGYc4otZiRyn3Xtl5YXtPMqzc7vv32g7AdYqq0dzE4//rbJ07DzLa3vLztaJxnGCZ215q7O0M8VRq1NRLTvG2JMTKeQi1CnEhaU8A2CmMRpkMy+JJRRTEOMx9+eWSz67h//4TTCuM0p+NETJlpkgTLm5uN0G2JlKLQVjNPkZvrDa9eb8XA2mj2jxPHw4mYAqZOaFxj6Roxp9fGMwwzdx/uca3j5uUt/VVPd9WyPxzpupY4Rb752T39znN921UWhMjG5iGQ6nMlnlmKGBRRKYZpIk4BbZUkns5S3NjGyaY9BXxj8Z0hxsLjw4EXLxv++L9/ZLttuLqxeCsT9HE+0W8tx+MJYy1t38nzoCEWQ7EyjWzbRthITjPXqGlrxHdnKInjnJnnzMPdgfu7kzAyVJT5SC3qUk20kqJO2A/jKHIurYWJ4/qW201PypkwzaQ04zqNb6jpopa+25KCyKf2xz1plslb24osQ+ss1Gyr6jorDMmUcg0L0WLSH8/SqhyFMbc0gCknxmmsHl6S/mWWpB7kec+psu8yNfxAAeeU28tDaRnjrtN1VYu7nEhFipEFJFj8c0wFzuAsI19cyVj3AsGjQskMcUIhAOO2bziOM8PdcS3snh0xoygUZdYCfElC/b5jSbpSShFPYvSpmkUyUeXp3uJah0L8DjXCjNxtGj59c8vT8USsGt7hMIp0pEgQQa7N/K7bsnENThnapuOHn/+Am/ZGmvO1+RDZkOLsh7GEdSyHFHsK7yynKbI/TdxcXQv4VfeWvpN73VU/B2ukKPKjYg6zmO8qhfOGZuP4b/67P2a76yVqPGaOh1M1XYYpwpI+WkqsfkVyfY3RfPLZFbvrnqvbnl9+/UjXN0wneT5yzqiUSGMFYquf3/eVR7lkno5HrnzPZtfzcLfndNICqCUxY/YNOK9wztJ0mWE80b244nC44+bmmqZ1eJ/Y7Bqe9gNjSLTeo0xEqSzSwiz7uCQxeyARQuLd/TuuulsMmpwy3lp67yX0gMBxGslMaJPZ7Xoa32J1i9WN+IYszBIumCPqLPUqJa8+G88OLVlbRim5hkqtsoNhnPj6l9/I+S8SdrLtWl7fXPNbv/Pb/M7f+Jv88pt3KwSHskzTTN92/Omf/AE//epb/vztwNPDN1hnGU4npvnEPM2cxkkA4CrDaJqOECK7TcMQG3ZXW3wfhA2tM9oawjzL2pANYR7lGasyKPF5dcQws2m2jGEmpMpqqubHK2lRkB5JztYwj4GUM421LImCjdfr4ME7S+MN0zgznAY2XUPfd5KwrHL1ji3iiZfOIUTa2GfNwtp4pSSF2kdG5B8zQErJzFOtQ4GUCo4aUKASSuWa8FfwVvazEALeWuaQ6ZqGxlomYyjG1aTwZaggA45c1MrMyGVEhUDbeyhgnalpftRnpzLSY6IokZWnLOyBUgr397f8quPv/5f/k2f/7+Z7dtZSmmuUUhIQUwNosnOULAwIgOTF4L6kQmTGRLmPQwz85//5737nvS6P6XTi8x//hjCd2g1H1WA2O17efk7Jif3jPd3mml9+9XMOh4kfffE5V71DSmZDnx9F/o2CMGOcx/gGXVNeUwprI53rYGTbeYytCbjpeVLmpWl+/uiZ1ErSJWV4ugyJ6nsLXfejo94/BUqS65qrf9LyozEmggJvDcJK1XUvF+aEcx5tHNM0Mc0BeY7N5at/5yh1sKtALE0KlKJE+YHc2pYqz0tpfQ5/5aEAqll/SsLYrezqND5iXC8s14+DupDgkFgy1lUbD4QMQc7ruZYm7PyFVl+2ZcBTWSRWLYb6XDDLyjMcTXy5Fm8oqr8U0nR9tLwKm6UjpZGCq+uVeJ1BxqrEYt28MMYlkXXk8Xjgz376Te3rCv/qz74m58y7+z1d13Pz8iWlQGsb+s2Gtm359JMvaJqGrmvp+57G+9qTRrxvGKaReZqYxpHWO05TYLvp6doOhabxrYRhRPh//mf/L1LOfPv23ZnRDvRWelFV67Nldnkpg/34SHkBiur5R+oenas0sYJiIQb6ruFwd6x2OOfIkpIClymPJecLgor4fJVa84CEsI3DjGk+HoBIP3h564lFhlqHkqB4enrik5sfUBAQ7zsJk/WYY6pgdn0uSmKazsPDBfy6vP1DkPp8mhI///pbXr2+5c2rF2w2Hf/8v/sDrHV8+HDP9W4rw8KmZZhEvRNTWgfNuYLllQyK0kj9rZRkAdfU9x9++Rn//A//mBvXY5EwwZjzysxHaV7cXnNzvePpMOCc5eZqCxT6thFmnFK0njXJHmp9peaPALGL563e0wvoWUqRVO4krD/rHVnBNMxMo4SdNV1LVprH/cCnr674H/+bjhfXW5pmB2iUDqh09h97Jk2u9GZFwRlZQ1L+q8Nhf62BMCk6nv+ZdZYSMyFEuQiu6u9QUBIytCuUFASN7BpCFvN5q+SBMsbQ9S3zFMh5wBhoO0OMYL2AAq/fbDmd5EYYx1CL7IWNYZjGxNPjRM6ZaYzC/DKa7bbF6sCS9xDmxBQioZnwXY9rHM578sUmulCpYwoYIxe7lMLjQcxFHXWvrDS3JeJ8eQrjnNbEpLZrwZtzLZbTykgrsRoWNp6cFUsqyOItIc2RSHSG4QQlEefCcT8wD4F+0zANE2FSNE3lrlT2SwhJWDZFGBg5FV692olvUe/JWs7xmzdbxlHkqEZLGMFYEe2bm479fub+YU9JSgC3osVwLIt8sjiDKYbpFEhjxFhJVDwdnihp5ub6it/7H/6Yn//0G4oS+Yc2ijQDOpGLpNY9hZFhlGmoVtBvHDFlrsyGw3GgseLx9vLVNd++feR0kFRQ5xzTPNEVSSGdQ2ScZsZTwHnHN199w5vP3tT7TMwNH+8GpimSUmIYglCvs5iDGiMpZZLkKJ83xcRxGqFEXr684Xg4cToOdG2LsfKe17uOvmuhRJH1eENKlvuHmX5nef9hz4tmu062mtYyP84YC9Yb2k7u11wLT2s01iu8kgZdW4Uh0206why5f3/AWsPNTUO78cIai5LoGULk6mrLbrvhm3cf5HxHaQh2WwG3Ht4f+PyLV9w9HOScpSiyBRpAJCqu6zBB4ZzDYOp6GxjGIhG/KJKC3YuWrnWEMTKfAk0jUqYlJKLxwpIaxojRipvrnsc/f+TqZst4HDke6wKvFUUrtBNAQltNNuL70Haa42HmzevNyjjJKbI/1ICLVmOaBkohBAnbOB5nHvaD3HNKCgrrrEgpbMY2AornXPBW02rF4xyZp0ica3LV6o5Z/7VusgVqOIN1tcBIIrMowDhO1azZVJ8ahS4GbS0xTByPJ7x3VfJk5D6or9VojS7iN7FtPLf9jliBV5FDZ2KOa5x2oUjzdFFwynqdCaXIZqgi1siz5q1DK8Xig3ppV52RglvWp4Dm3Kyrj3w6Qgwi745JPHK0eI3pKjNKOVFiqQ2BmIKLgbL9zvumkkV2VT++tdD3DvcksqL5khm7YhCVL1UKRWn55/uoYBSMKWuCWeMd202Dt45UGrIdqwGvsI4XCa9874xG0dqGwzCgjaLxFpsjw75wOpwopqwVgLcy2GluGz579QqnDA0N2+2GOcykJEMcvTTqy9DDuwrEL66N9c+t5ZPX1/z2jz+laz1d68m5cPd4kOJMK0mWqrLiF1c7yIF5OlFKwq1pypF/9Sc/ZRwGWWdDqUC/JcYqj7ECbuSSyCmI7LFOLPveVzClsH+KbLcd43AQf8zqczWEafWdWjgVqiJ9kvoqEiHnDPMU2N+fiFMkpR23N1e8/sLzxRc9RhsMDZ6tANPDt6CjpDr7AvqEc7cMpxc03cRu1zJOB5QupDjJ4MjtcKYhTIkwiUFu0Y5xvifNMOSR+7uBNy92bG4aWbONkUaqyEAiVuNyVRSd72icqT6OtYhfMLCF+rb0yjkRY2Cag4DDBkqtV71SlPoM2SrJXgBDow139w+EeeLmeofdbthd3fDpF1/y27/zO/ze7/2NKkOvwQ8hMI4zP/3zP+LxMPDzr37KOE8reJnqmrEOH5UB27N/kkHPcY50raGYGQ+UMqMai3UtXbcjF8Xp6ZEYJOFXVDNq9XI0Shij4zzhjCYVaWTHmmbmnLAW5XFS6zDBVjm31ophkpG3JO6J6bXVmlOlo3hn8cagUyGcBmGLZfhw/8CrFzeEMBOjsLBLORNStJFnWVlzwfo8rwjroHu9ZnKPhhCYpnHBBiobIzCHEWd62vqcHoZRGJVTxDbC2L27fyKkRLMR2WYui5l/Xpu8RKJ1HZlJkjWRwaM1pSYAZgG/G8eSvAYGYyWV22jFafgVrLbvOX7vd/4U5TZYDd4K6+zFlcd7R5wK8eYNznju794S5pnTcUAVRc6RzXZLv+mf+SH9umOOhaIszons7OHpAwVJwO17kQa9efOKn/zkx8xz5MXtDW9/+TV/9Bd/IdJkEsc50DetDKPLTCkiyyraUJQMheN8ZiFZb2sL/xHQqZ6naz4HWOr9UZvK5WfchTSZhclUQYfLV19M1+svX/xFZaHU9TCs50wSR7W59JGrRtzKPHuJlSW5AEkoAXWAZzGzFz+zSO1XRvCvOYQlg/Qb2AWHk+e5uwUCOS+S7rzu96VS1QqKKWZ0FKYPlcWWCysrZdFArh6lS69UX0dpKvvNfMzrEkZbTKtVg6q/U2dpKxDxfYdSkINhCoGYQz0/srZO88T7Dw88PB0oOfN0HBhOI/dPA3/282+JF8m+P/hkS9M5XrotxkjIxW/+5Cfo33Js+p6+b+nahs1mg/eWFzdXNG3DZrPjF199ze7qmp/9/Bd89dXXOCNg6PXVFY31EnIWM6lITf5Hf/SHvLi+4s9++nMBu9fPUZhCrICDojEeXcPUfKW1rRY3Fxf9EgS7vOapyOvpaWKbguxZRe5x0ciI7dGnn7zhm2/f/oq7RxbFhdlljeJmd800JUpXJEX9ox9f7gO5PlLTtp2tIK4Sa42QmOpNnKv8Pk3x2XV2jaNzhmCUhCelDDVg5KL1fnYM48w4BFIu2G3DMM4cjyPqjeX6+oY3r9/w+Ljn9euXolRpN+iuY3gn7OZ5liCykBQxS4CRrxJ3a+SsiRemppDZbHc8nI70XUtJBVtEklqyhK3FlNluepq2JZfCp29e1jVIVSug84DT6kgu54FSTEoSOb9zPcxaD5fKomu8xXvF+/cf6nmqw2YtwJzIegv3T0fun478onmLMYa7hz3/0b//b9NtGkoZnuEQCxtMboHzUOAMyi4J5n+1vemvNRC2HIuwRc5PqXTXSimOGe2VeAblszZ7s/EMc2JKcdU3pyzTDu8cm40AYe7xSDBlLTh9Y8T/y4G56pjGiPOLGbxciMMhIokmsshMgzDXOmcwRi5goyRNRxNwXqFUIaVJjPFCrFMRTcwFW0GsZQFejHG9WIwho10x4Vc6CzujpjxNp0m2ZS0Sm9xkvPc4iyRt1Q1rnmN9eEttgsQjrFw0QrKOi2HnMSSRzSH+BtMQGE8zxmq2VzINzTHz9DCsscz7x5E4JxpvyBma1uO7hsYJoOcd5DShjPC4Sh6JMYjHkDE0rePhfk/JgRQUKc2gG0CAvpwLw2lk+MUR5zVtY+m2jqbzlHJNyQL+zePM9e2O02EizfDwuBdfJydJgqAlattoxtNEzAXXWnxj2N+duNr1bLqWEArDMDKNAaUT4zCRc6G/8nRbj3GKOM/M4yCmnSS+/I3PUUpz++Ka/eHA1z97YBwix8NYzWLlRBetKDpJQmbxUvQjrJiH+yeenp74/PNbtrtNBVtn7u8fMcYQogC7jXdVViKStn4jxdvdnw7c3m7WBWM4jvzyF9/w6tU1V9c92sj9klMWz4IkwLJ3irY1tF1DniaGOfDikyvefzMQQxE2WywYI2wh5wwly7XeH44i3cli+N20XgCinCgRKIn794+cjqMkTGlFOCXSXOi3XvylSLjWcn1zhTGaq6uOKQfZgAvMWajRKiRS3RTmKTANAe+tPB+omhjpSQ6Uls/ab3varuPD/Z4QImgjptVZZHBOafHkm6Uowloo0GrDWCWWp/0J5TKu6TBJ1qVFoofSKKPpGvH5M9bivKSAhjBhajHhalGqtOJwmLl7f+Kwn5aFjoXFWgBdWL0rkxI/lRgTKWQOTyJjKaiauBWFDdq0YIVh4FuL9YZpsMxZgFqlFd1NI292YVZpUHhraKwlSckqBXYuJGI14w6rFLbkpcItK9i6AFipyjhyKYSUyErjla2Dt+fFdQwRyQEulOoJZo2EnCy78MIIm+OMNpbGN+JxEsKaDLmkztmadHX2YHk+WaKetfTRFNBaze1VJ+CB1UxRIswfDwJU6KIYBjEiLxSJgc7CgCzLpOzi0FpiwVtvuNm1XG1bclHcP0bQmmSrqXl97oVZJibcfeMxXs6/dQbfGo77GXLCOPGR8M7ReJFmqSKgSmM9Wjka36K1YThNWNc+//61mEgxVTPepYkQprF3jlcvrtFK8+r2BSnDFAtd94Gvv/4aiyHpQuvk++4PD2gSikjfaCiG05gY58A8T1VqlOVWiYnjscapWwPTyOIRknNEqYgyIhU+HWdcY1GHkdNpxjlN1zVMfWSeI6dpIqRYiyG1EnByWdLaqsQ2FSl66z2ScuZHmxdcvVTYNuM6i9KZeXxknJ6YxsJpPuGT48O3HyTMRp0YhifIrpowK5rG4Z0YAUMDuaBTpGsdRmsOh6l6sCSu2lvev9/jjCdmOMwju22/3vco8NbR+qYWvBHnXE1hFERraXYVIsu8fJJSFkCllIyyCpWpbGjZ/2OWsJ5UgWujZVC16TuenhxzmSrjSIDjbd/TNi1NIx5nlxX/P/nH/4i7uztSEsPxxcsnF1sZACIPN1rTtC1zmtZG19iM7xJkR47UBGMnYLC2tLbBqkycBh6PU32OVF3TNSEEjqeB3W6Dq7LzJSVz9Qmr66x4DArrV+ZO0lgvhXTKkvQVQ8TmQKksmMVYXJUF7JD17Wq7qczDmaZp0dquV0B+VFLSlD4DGZczjPXfC8ZA4TQMDKPUBab6rAmpJxLCCdU4dp2vnpLy/dq2wbctcwiM0yTgR9PiufRAUmutp4que72ACEZrSe42skeEKGmzKYlEHt3Qek3fNjTOMcfE7//hjr/q8e//z/9vfPXtsN6c2+0G227ZVNgiHO85znKOcy5st9fMIfD0uMdMpvouSR3z646XL55ojAMvw3LbOU7TyDRMUAqlJJmPl8DTfs8wjswh8V/9f/4hNy9u19cxWmT2VlsZXuVAScLaygs/6ELeunpTKrM+f8veNM2T+GLC2tDlLAFci3fmJcT1bCBUAepLpqH4c0lNeymJlteXJjmktGzDpCLBTvWuXeE6pWTNIhWcPYNTpdrsfPdQH/374m8uwbBqW6K+/0XO56z+ZO1rn71LjtLYL8/Zcoif6HkQlnIijxPGNxUgL5J+mzPKqHW/X8zcz5+3ekPnAuEMtP26j7w8O1ClcbH6AmuR4U9zIqaBY7VVeaws58NpZBxn9seRcZrZHwcOR0kE7FrH9a7HGs3v/uTzVaboW4ezmrZtabsNvunoug7rG5wVybiA8wpnVZUeCjjinOdHP/oxv/z2Gx4+vJNQkXqRGt9AgtMwEHIiZJHq65w4PO65urpifPtBkojrkWJgmCaCMELoN4arnci0x3Hi6elYBzJy7mMqZ0/Oi0NrqYtjkCdomkacu8WoDqVsVfbKBXj77v13fr9eONCydikE5AHDOMaqaAK+s0R897PI9Rf+2SLz3Ww6pioJTVG8KD/+1RDC+vqaSvJdPvXFUCos75xL9R6WwdzxeCKlW2KWOvjNm5fEEPjBZ59yOh74yZc/YNN3/NEf/ytUSRS0+F6npj7/ilhJCo3Tla11vje1cVxdbXjz8iXH+xMGRVYa6ywxRU7jzDYENlbTWg3asqLQgNbm4nkrTEFjTbXMUApUW7/sZZ2s1tdYVRqA0eKz9urlFcM08HAYJPRGCREgqsgczkOy0zDROMuPvngj1kzwnMVZ16uP14CFZAOS6juFxOP+V6cZXx5/rYEwhRazUbVIZyLWiTl2rCyMECJmmmmsIWkFDkIK6KCfGakV5OSlyghz1tC2nqbzxHnRSVcJAZkP7068/vIW6zThPjFPifE4kVKi6RzdxuMay3bX8Pr1FWFKTDGijOH+MJJ0I74WyVFqyqEwgAzee0JNd8pLKEMUiHkek/j8UGi8QluHto75aRSWDct0tiaHGGG2aC0PAUXQ494jjJfaRSsl3iRkSCajlfiMpcXTKCwSp5o65BwxzgzDxOkwnRkrIfMwHzk8DjhvVqNJMUxO68bjvMY6aBopyr0T2YjSheuNNLKH48hxCKAzxoFKWsy7Y6J0ljBHbNsilG69pqWkLMmY0xiYpgnfOIxVXL9p6TthKg3DCNqirMNqL0bTzjOOgXEIPD4NlelHlZxJsXy17SpbpNBvGk7DxDSN9L00mdM045xMIWMIzNOMtlbMbWsRcxpmTsOpGsQeV38fuJzAKciaDFhTb9UCMWS6rhOJV5JCaJ6TeITd7Igpo6uctmmbysyKjJM05cNRfvZqe8VwGgnTzPFQePPpK5pWSTIQmhgSzlmsLeKtMUe6rkUpkQz5zuK8JUwz+6eRHDLDaWazkesR5oAykJHYcUlm1ZganOidY5rH6kUCjfecjiNhkucv50IiczwNxDyzu2qxzqFVwXmFb8RDrDGOp2EWjyWONJ1EwmtVDZqnyDwGAU+8hWwYTjNGiQTRNY6n/YmcCw8PB+Y5knIhxUjjVE3zCfhoCFVi65RafQ9CyDSbnlgix8OJrffVq6xgnWaaEtMpYr3HWo81mRRDpZgX5vl0IS1TVW4g0eHDKTANUYrBcl6nZLLPeSoJlKq4URpOw7wawadY0KbQ9CKBDUT6VlLBchIps3WGMMMUEq2TXHVbN0JTFBaDU6puuJDKTMFgkHSrpXmThFgxxhemqUhsF4k3KEKMpBAoOQF2nSDlUjBKL8Sq+l2LyJ+W9T2fja01GZWVyCHrOqWNpekF4E0hVANiOXelpPWFnVKVZSXspaLPG2zdWLBWJGfLRFQpYZTcXHV4ZziNM3PMbDeeVAr3dyeOp7D8ujRbOWJKFvmaMpRK43dW4Zymbx3Xu46XNz2Ns9w/jVgDh2lPmTNab85TubruNo2j8aKtFVap5eHuKDJcY7m5bvGNw3thWVhjcRi27QZnG6431/T9RuQTTSMs3VgorjIarKPrr/HO0XZtLTbE9QGtsLrQuYbXt4bWjzweI2oMtG3D6XQAFP2mZxyn6gMyk2IkzDPDlBlGSd+c5/lZQumaLlWvfYoJrQqFIDu9kTQ1Z6143JXC8TDJ/r6AyFbWpGEMlKJJMYkxuZKiseQsLL2iKZVddXnkXCQa3iripMhJ/Ma0VZgkLkaNK5hYBz1kNpse62BOB073AUqi3zYc97M0qrB6s5msabUnGkn+e/f2Ay+vdxwenqBY2qYhl8w0BN7fP/Hq9qo2zArvmyozTVidiPFEyJ5mBfgyKceaNvlRoVTpYkVlrDPsup6+60iVOfnNu3eEJFJOb+u5PQ6M00xKGW89RtnKOujWlK+1GbwAAn77d3+Xv/df/AOO4zmd8lxQa0ox5LIKjOS5pOCcZbMBbSzeOYrL5JiFtUKmlEhKet07vBXT7ilHrBcvvBCC3GshidflOK4N8MKAX6wopjQzT5Owt7StYFmt82xloBYjTPOUUFk+cessfdtckLqqhyJQ0iQyYN+ija2eenL6tWwKLJ4m53WCOuRkTQEsCPAxDqOEEJWC0QZnxDDeKIXKiTCP4nenNLvdjs0mM8eCb1piSgJ1KAFFFgAEqKniIqVfnqVcfW2stawfSy1NSCGnwv/2f/d/BKBpAn/nP/k7zBFQim/fvuCvcvzOb/0TtNkzjpV1ZwzTFBiGmWlOdb2NxJBo2w6yhN4Yren6LXOIPL57R86Jv/jzH/3a9/r004HPf/hDHj7cobVmTiONn6RmaDzeGyiReRZ/1TdvPmPTt4SYeH37goenPWESn9a2AZPNGsyglcKbQjSQspWBx7O15PzfJRdOw4mQQmWGV2sQ61BV8q+to2lEchnqM5dSxq/NbV4HKcJgXmhTFXTLue6nz48V1E2LZ84Z3SkLO+3c6z4DrLSi2g48xwCUUt8BGBZA/dk8pdT9u1CTSX8dGPYMFn7+58qiiqp7QQX71/17ea+y1ge65JWNSalSyDSTrRXpqX5utL+y63KmpMginldGEbMkYBddLWaK9IfWnMMBYsrcPR75+u17CUyryo79fiBnqYljTByHE+M4EGPiNJ5Q2uGcgMrWWoqWBN7r6w2bvmG728igw1mMlnreGIfzLb7rsV5CIMRrTOGtpLd/fBhjuNrtePn6NU+HoaacVssZZ9CzrmFvugaDSErz4ZQwyq7gg8iADeM0yJ7mGq6LPJvSuwZSDCxSx3mSdXVh7qWqLtr0ndSMFYwOIXAajuyPJ1pX16J8rgMu9xa5XjXpU52llRqJvQ5CB683xffdZ9/9w3KJWlEB1Zo+uZjU/ypri2XtVpz/fX6cCiFEQhIpcuMdvm04jZP0bjlzd//I3f0TKUsYydX1ll9+8w0vr7e8urnm3Yd3jONhfTpKKYQoaZ1L2nlKhWwWCxE5pGaAly9u+cmPfsDdV/cMQyA5Q5jFXy3nxDSN+BpCRk6ynihT7/tLaEgRsyZljdEJrQyZxBxFLumNkGpkjZJGdWHj5RoC+Plnt8xp5Gl44n4/cDiNhJjXkBBdRPq/fP5t3/KLbz/wb4Qf0ras96Gqsu6P14DL7x1TZhwjpzFwGubvv3YfHX+tgbBCBWoQ41LbGHI14rbWMNVNZZoCuhQx83XycC8pgKU2O7VUpFQDUxUFJGpaT6qpH7kIKGW1qnKlwPEQyBnmWSamOWfKaSLOkXbja7PdsbnqmObIsB85HQJxUrzYWZ7SjLOKbBSbqw6lFwaXQpezdvl0iJSU2d9NDAeRYjatl8/jNLNR6Kwl5SrKQm+dPDDnCYYs5kZRHyTxuShqaTZTTVRKlTYqRVfRogdPQEmZEAulSHORokzvxCpaFldhKCWGQR6GxSBRa2haMcD3jameJ1aiwL1Q8lNMUOTayORRMwd5b2Pg5esNm03LcIrsn0ZIkRAUxoT1cxALU5gkHUfBplfc3naQPQ8PE5utxRrDYZ8wXryzGmXYbFrefvtIoXA8TgzHSQrPzqF0gRJxbcfx4SDss0HkJlJaixn/8TgwDgFtBmLIWKuwzgu8ZDXjNOC8l3tMKYYhME9inA6lGnPK4pBSZd0oYc6EWNMtrzpCkAdc4sY9w2ngdBzoN5saNQ3OG0oWLzqtYZ4S+8eZXDJt49FKEYNF68zV9QbXipm6NY7jaeJ4GpnHmeE0EpMAcFJcQdOJZHE8TVizFPwClipdZXXW4L1l0uIh0XausqMK213D4VC9LUqQ6XOQe9E0mtYanFNYW80QcyFMQSZknQCsoUoSvnxzjVHw/sNjjXOXKa3SBmMUcynkmDDeob0lTIEQJlzb45yWKTGZ43EkKS2x8bmgJ4NRCasCs5PwCOctJWeGYcB5kVekOvlsNh3KWYqGIczkCHMQ4Ealyl5QkliYcyAXLcVM3cSWvezhfuTwODAcA3PIGC1sqcWPpuSlkAW+O6wST40s0+xlbROQDbQVvyt0pVEX8K18N+tUNQ0CI6NirDboLBOnxtekMQqpRGKKpJJFt18K81yl2kbXNcYIeFHBMHF2KKgYhchWxPAcxHh9ZWvUSbnShsUrouRM1rXoZ5myC4tVGpSEdTVCughzsuQCpTafVGM2ZK1z1slkE8hFNndADFeLMFCXJnqRiANiYu4dbesYp0DjNHdPg4AU+oIcUGTaiSoYVdCWmiTs6DtP33m2G8+2b2i9ZY4J7w1dqynzlrFSwRf/GYum1Q7TeXZNx3bT4ozmqu+xN/A4DJLEZxT3oxjqd43n09uX/ODNF/TNlv3TiWmYaG49beNJOTEPlTlV9LkdKdKoWWsvWHPL6ZP/t6bKp+LE49MT9/cfGKcRpS2HSoEv2gKFFAohiEHvHIIMeRY9GwtTMK3Xfb2PCwJEaZFD+9YI0IPCWk0IwuBaTF0UiWnZ10eFUg6nDVllQjUGXro2aUK/2zxaq5mnGXVrQTUC6Ce533zjaboWKDzePZBzpu0bjNVM0xHjrQwvIqQgErypBCBgraFtNNpDGeH4OKNmzeFpxmrLbmeZhhnfyFBmjoGQJrRtaYzCaScyuTACkZIHNFugqUBKBXmNJauy3tsgprQhyiDEOYdztrJxy9q9WuSZ71pPLgVnDfMcAU3Xd3Rti7Oyj03TzDAMIoMuz737QojMdQD0sTdQzvLMTjFgk6agsN7ROE3bioWBcRbtnGDkycpQIEkxnVTEFOi6lqIsJRfalIVtp4UV9bQ/MY5fizm8UmIIbJbCuSFn8RNamA5K6xq3rpkmkcnqmkC1MKaXBXaRkC1Nx7l9X4ZYgaYxhCTrHbo2baVUP6GPQDAElFILGIb8t3gkZnIKtI1FGYcp53pM13+8NXSNh8q4VUqjYqBrPafTeFF3XTzDmtpA1nOiDTmdmZ+6Aifn9FC91qDLMU2VjWgMcwychr9aG/G/+J/9I17eXhNm8WXTRuPbdmWgziHW4dDMOE10bcMwOJq2EyDY2sp4j/wn/5f/6Ne+V5gP/OKnf4wxLdp4WeNUETl332M0TFNGa4c2Huda9oeRlDL3Dw8cnvZ4o4gx8up6I/dgvUaohRGWcAaK8jXYSM4nALYF35OGe0Jlg+Vqju+dp20aSt2utDY0bSs9yyhp7ksqpTFmBcEuO+3Fa2xhsuSLKuBZiInWGKVw9dzlLGumVgVbWaQC2ItXm3hzXrzdBUal6vcvl/dw/fuLpeSjo5w/9Pceoob5+BC8uhCmCes6ShFp6RKuc2bU5QqO8ax5V0qhfQNVdrVIItdz99HadL7B5bWWQIaUEcuGLFNHU0/EAjLmDMch8bOvH/j23QPTNKMRRnhJapWOp5yZp0fCPHF9+4LtbkfXNnRti3eezXYrw6c6vG7aZmV0oxTetzRtJ8NgLQO15QstoQGmrjclC8BwGgYeHh552j9xf3dP3zfcDSd0kX1OG/GJayv4kVLidDwRQmQYB0BhlCXntKZVLz5cIQRiCEzjRJhGTseBWMOeYoqUItYXc01qnkNku2nZbTq02Yi/WwzM81jX7QN6u0GbVvb1i1tm6UW9FzZUynJNC7qeZ5F26mpF8as86f6yO1Fug7qflcoITuk7/m/PgOGP/n0Jq53mIGqSSm7JQL/pMEp6I200x+ORh/sHdpuO7aZnOBwoOfD7f/T7wpgvkC9MvmOYyc7VNV3VWrdg9Pc9Q4offPEpX3/2DUrB23cf0E7XX8uMU+1vtYCx1KGU0eZ7nhEJLnvYT1SXQ6zRpJTwFl5eb/BeQTpcnKclmKLQto6mtWirSIhMe2ELLneyQvaf7bbjJ19+wo9/8JpN35DzWD+BANDPWLPLsKYI4zWnwjRF9scaRvIrMMyPj7/WQJgcwmER4CCv/iM5SyrKktqHkiZcfA3M2mDItKVKd/RSMJ1Tzby3UGWSKcrUdZ4yMcH92wPDkOm2sqMJCCStW0qFubKLTvsJYw1d73m6P2JRjE8zc+NxTlhbqThJ5hnjxXRcXmccEsMpEobI8b6aajtL0zcwJKwVXmZaUNNcRN6mhCq7bF7WiHxKqcJZ8CgUbmMy2qQ1JcjUBEOlZSoutP5Mqga/h8eBYQzYuvhap8lxOdeiHxZ5QSFWEM4Z1lj4giTIbXaekmuqTo7MQ6xpKjJ5aRrx1ChaJCW5VeQYOZ5m2t4TZ2EOpJwxVnzOUinMc67GmzAwizecgrY3bHrFOMg0I6SCax3jEHj3zbHKkWRa4ZxM/qdJvCxUyWgH/a5nOk1QMndvH+n7lnmKOO9pGs/h6bQups4ZtBX2G9pQikyvW2/pOs/VdU/fJw77me1mSW0MK/suJpGt1rt8EfzS9w1hkmmF957d1Q5r5P7bNA2H4SReScaRsyKEzDQnhjFILK/K9NuO8Uht4BX37x/o+pbd7lqu2xxYUvWMke+htcG3vjJABOwT0EKtkxOloO2cGOvmTNM6tJ4xRtLQYlSEIAbW8zwznALzFElRCrqcMn7jsE7jnLBnUkrkEAia1QQ0RwE985zoesdu2/H4cISsSDljdaWKIxN2pYtM7Btbp1oGaxSnLI25NjItPhxDTQure4MClNy3uRTImqbdsOktvWvZH48iG1OaYiAreRLnIGsGRdd/z1AyvpPYYmNrvH0FrQqab7+6Z/80ESbxTVoZSbCyuNYEye/UcpkUMko5SAWtpeBVSq6Pb5wk21bPl3GOS52FNgJ6KS/3l9OKvmnQ1YOvqQmg8j6lTl7S6ltCTVpSRSaTWulVgrg0MCKNFSPblOq0r9S0qGUnqs2bUopcC83V7LuCGGLULJOfRc5lNWidCeN4lvpwnmhLqpE8PVotZthybkX6Ig3JHKSB1/X9VJV0ZuokWUkR2eIqRJfZRMfhsIBGNdHXgLEeayRt1ntH13q2m5Zt34hvnRX5g16/k/hLmBEIZ2Cod5adb9n6ls737PoNV53HmUXKBDfbqzrNhM9Lpt1sePHiBT/+wQ/QGO7uHjg8HiklV1lc5eRosQ9Yd9NyTkGSZ/mCRXBRZKaceHi45+uv3vPzb95z//AgvpFKkYomYVAq1WJJwAwBZEtdY89S2ZIzSkkxt4CJuWpltLYYYzFOYVtD2worrGQox+dpTiLBLxW7UBjtRd6f5zPIVgcQWqtn4Wog1/XqumN71dRhwxJLH3HO0t50eG8JQSwA0qmAzsTTTE6lMiYtwz5QsiZMCtcVAb0zWF+43nS87m9w6hHjFBrD5GeO08Dr2x3OabRtRS4QM21tgqypa8YSaqAzqpqmX3rRpZKr15c0YRlhagrTVeqf41ECK5b7OwVp2hSxGr9r+b6NR11Jop+rTdp2s2GaJv7wD/+Q169eglLc3d3z4x//mF/84hdM08TDwwPDOD4rpEUeWdbmdUqyRu68ZbttMUYxjtLUzNOMTJWjxMOrZVBQMNaxvd5xeytNYoyJMAemaeZ4OjJNIkeSBp+1Q/HOcn295fb2iqvtRlJYQyOsxLWpLud7crn/F9ptvT+stSswIc+eJhUINShDAC9XG1VWBFmeo8tn6aIxU+sWI09ZgRQC4zCgELBGKchJ1kNnNY1z7LYb+rZ99pooSWSVhS8LI1KrdbhqtKrsMLX+jng96srqOZsbW+uq5Pa7h7XCug4h8i//4LPv+YnvHq9eZv7sT/9N/vnv/xa/9zt/zP/o3/pDfNez3XakAq4Orp2zxJhw1hDTjMteACatBRB3f3nb8ju/+cdMwyPj9AGQvcJqkeU/3BVQZg1i6vsdT/sjm+0VN7ev+ObdHWHObDpPmIRdYJ2hrQMj7y3OyeDA1r1TFUtBAFS5DBpMsw4WLk+iUmrdE1mvmYTH5Iu1VyT2ssdQ/XnWJrAsf1dfOi8A/3PfTL0w/ypwknK9z/Vy8eW1xNRaariFralrbXAJcF3gSet7F34VCPZ8//j+v5cXMDX5Uenz+wI0rdSvKGRYc7kflQrkFWFzGX02WF880ApZhtgXx2qk/70faHntMwtHaj5qWBHPGuxS5PX6tuX9hyecEamefJ3qbZapbKtC0za8ev2Kn/zox2w3HdYarq6Ega302SdOV7bmIms1xq2+p5efXQIsAvvDwOFpz8PDAzEl3r9/zzxPfPhwx8PDA+M0suk3bDY7rncb1MW9orWW1NaYyFHUCLn6COZaaOacVhAMpJ6e55lxGCX8xRpMlsABaww0XtLiY2AaxV5FbRq6ztM0YiEwz4HDAaZp5HQ40RrL7csb3n7zodal5758AeRzTrWGE3mcM46SVfW/vECsCnzXweq711wM9GX9X/42p+WaLa/Dyo7MVNlwkb7CAItF38cqUN802Hp/5Mr+bJyjNRI2kus9H6LU4dc3Vzit0HHk6XBgTiv0uj4QSyKlMRqUquqQsvryrTdlfS4OpyObFz2bxnN1s6Hxjs22F+uQ2n9F71cmsKp1YcnSey77QYyRb98/8OFB7vHH/VFSXUuhc5off/GST97c0rXNs3Og65rdZNhsem621xQ+UOoz761h03quNh27bcfVrufTT2758Zef8tknL1b23EeP50frwFklk4t4X8aYn98Pf8nxrwEQdj6WE1ZyIdeJqEKSgHJOaGuZYxRqqBYpYq53urswTM05CeiVcvXykZJlJsAsqTnH/cw8RfymwYaMdcLuQFHBuESOifEYcFb8TERS4CgJSijkEInR0GxkkjpN4WxCrZYiRQz1j/uZaUiEQSZP1ju01uxuRN4C8iCWgjx8Ssn0r8hNo7SWjbMywhZ+8wKISVS4rRP5svprLFTspNOaarWwmXIsRDKt9eI7ZMTXYSnubAFr8momKP2PLL4hBOxOinvfSXzvMIhB7OKf47zFR8cYZsRrR75zjCIBcc4RbaoPdCErTc5V2la/h0KSRJ/24kf1Qm8YT4F5ShgFMSSsF5r6MIS1cJU0KynI5hCwc6bxlqb1XN1s+fqrtzy+nzDGModFljvx5s0tH+4UwzAyT1HkETHLpH8WSZi1VasdBSSaxpnt1tI0YhZ9cyPeKzGKGfQ0JY4HafrmOfP0dKpBB4J+T3Ok67fsNpZ5liQjVWD/cAIMSoscZZokijkVQBd85yWSNmf2TyNKWaxta3OQMbYyerxEJjvnsNbQdJ55nAlzIoQsyXZeWF8gpzCGUO9jeaasVaBL9W5JHA4D0zgzzTPTGJmnJD4XSjbIFB3Wg/Xi1yffdSZXcGU6zqgEOWTmyWGtvE/TOmIyHA8D0zBTkphoagVxnrF10w5TIM6BZDXjKWCMY7cVU2G7c0whibzUiw/PMolXUZGSpJEZe5EMpgS0TVkh+Uv5LM021dSaKit14nuTszR9jZNp0Wk/sH8amCeRI+dcn1/OzcnHrJm1ItMCTBUKFpFDCsifVlaN1sJ2SEnYSs4rrFMVJJJ1c0liM1rjrUEnI9JKK8BFYZEoLtPY82cwzqAvPMEWSaRa0Mjl+TcaoiamTGNkoTt7HNVpr1IsKWe5Am4LzR4lHj8ih1i+v5LpL2WtCJZilnIuquwC8CsplheJSC6ScisS3oIustbphdWhpLnJWSStS9OoFLSNxTtJa+2vnawtBtrW0nhH21hhgjWObetwdRpYbxwKCqsVm9bhjBbZZHHM1VPqumvZNg3bpmXT72jaLW3bYvJMjrL2C7jlyAU2WrO7uuH66obPXn+KtQJKv/1WorjXcJRSC8EKQC2qgpSEaX0GEWvTsYCSeflH1rL9/sBpHKu5NhjjMTUdVxUBgkqO6xtoIFdgQHwd5J+lyskXRZ21Dmc92iWMVzQbR980qKIFqBpDlRItcfDLEEneP8TqQ1g91qgDpoXWsA58jGKzdbx6veX6psNYw3BcEo0k0c0YibcvObL4VExjYA4Jb22VkiimQTwaFabul3IPxblQeoXtNTeve65fbBiOAzlp3n/4gFc1JKOzjClIaqfW9N6yaSzGKkqRgBitbAVhKitkAcJiomgBM1ORZ3WcAnOQ4WCqw7+4sICyEj8uOWnEOdBU8+UXt1c1uEUa5a5reXx64p/+k3/G8TTRdS3GGt5/uOdHX37JX/zs53z2yWt+9vOfk9KZkcZy/yxsPLUYhwtA2rZ138oiqdfWCIhTf09B9UNTtF5zc72la684HUeGcax+dsJin6bAMAqzaAHRlSp0bUPfNVDZMM4aSVZzlpiy+AdaURLEaWbTS6JvvGDIeGfpO19T+AQMsloA7JCy+JXmiZBjBSWWR1xkPPpiXVrPC2cmcB3wyzNT5cQKJXYM2VNKwnuRVG+6llcvbuQ7La+Vywr2r6wu52sjKWC70dW7ql6PkpKEJajFZLz6JGmF924FTD9mWZjaIM0x8v7Dlr/K4bXlF199wT/553+LFzcjV5s/o+la+lZ8nSar1+c4hLgOKkqOdW8AfWE4/+uOEDtKyczjgTBPMjxTiqfDicfjRMznulgbz2kUNuv793c8PO1JUdi/w5C4ezrRtY7txtH2lu3Gc73t6NqGpM5NVL6ksWTxlNNa4Y3HGCN+oYsX0wpOyYVfBjWXDfkyyM5luUcqarTeOWfZ/gKCfdzry/21wFVlZTItd6fIwOT+zyWRURVAOq/Bvw7LqiFwzwCzy0+5/sH3HCuwpyXpbhkind9PaqVhqqMstYCMZ7bKcr68E/BfGid53pZ9fz0XH93Hl55CK4S2AmAXJ7CUtc5JRdhNTUo43HoPUYRRaxamTv3eAkBLwIk2LdbJXvLy5Qs+++QNSmvapvleYK4gZIJUn4dxFNZVqp5k0zQxTxOnYeDbd295++4DD0+PhDkSY1hZ8SGIP2z04nlYiqQ5p+oTWS6+bAzyM+fPUH1ZnRN55Aq+yv6fiygvrNKkKD6NuRSMk8GnMYqcIos8PefAOEW8F6AMJWCbhIwkPvnkJXfvH0QBZG2t06Tnm6eZtD5XhqZtcF0vTOXDiWGYPgJNnqdGft+tWCFfll4RapliBDdYfPiUOgNgv+oFy0d/YZ37zg+trGIl+0kMkXfvPvDJ6xe8efWCbdPw9O7r+tyXFRBc36MIVmCtsINRak3mtEbYleM089VXX/PTn/+MP//ZzzmdRn7rRz/kN3/8Y4zWwkqrw9CYswTaUNa631pLyYnD4YBSmrd39+yPAz//5Tse96P0yuNEW2vaz15f1+/4/Owuaw1AUYkQFblYPn15y6ZtaBvPpmvY9Q0vbra8fHHNm9cvuL3ZsN10YpGwDKTOq+J3rqkAtqz3svQmwmDQ6rv3wPcd/1oBYYsU0FppXhdJy5ryoWGag9yAc67oewFTp2LVwyqnLE1+TGvTab1hjklatTp5GI4JbEbpIACYEXlPqUASGlIUI/nhMK+FdE6yQqYkKYXzJEyskhaas2hvTU2ESFE8ukLIRMCiV2qsc5aBeR0plsuFvMhGbJ3Beiv+GCVhzfObVthY8m9fY+/XQqmIP0wpqS5Ki0mzxdnEPNXJslqQe55tNkIXL5K2p3L9fehai3WKcZyIMdG0sqlYr9Y4W+rEZw6BlANtK787h7gCnNbWCOc0k2KWKOmU65SJmggDYU4c8gC5MM8J4yUd0zSGbteilaKdxBMspUyOMkGPKQsoGhNu27DdtdxcbfnlV2/pNw03L7c8PZxqIZnYbBumueV0OgGlemEF4hwxKhPmge3mlsY1TOMRipx766WIMRZe3DYorXk6BFLW9KkwTRJG8PQ0Ypxosq+uPMMgOvTtlaFpLCnH6peSOB1nclH4pqEUzTQmpkkAHvFrkw3eNwJW3Nxc0/SOeRqBQtN5coF5ChSEFbDpN+QYeNofSEUSSLwz5CIAs4AsjjBFVJ24WqtpupYYUk2pSUzjIPd1vVYpZbpth2sU42kUrx5nUarB+QZXAdRYpMkMQySHVItHhEZMwRpEUqdkw3DOsKlyppKlavPeCaukZOaQUBjapqteJJ7DaaavxY8xYLzIYUyR53kcR1wnoHFSCWcMRQn4lHOGHIWmPctYSVvJwFGVdaQqECFeCQLGKq15vDtUL6PKVs3i17YkzJZnFdryfMnzbrymJGnorZPUT6WEIbZMgmMUOQpBvBlML2maJRUscBynFey0VY6pCjhlsWhSLIRyweJ69kGkCFym1JeG9DkXUknr8yQNVwWAFvl1kcbVrKEz1eg6pRUIW9YquWUkoVBXo21bvayoAB1aiaFyWYB+SX9bgI9FSpQr0FaKpPIuyV4ppQra68qiskLNV3VqXsQQNteisusst7ct241nGkUW0HaOtmtw1cy2sZLAeTb3hJVlpaggnRLmnWqYc6L3jt5Lw+2tonWF1i0szgu5zoWvRqnnTRJnFbttz26zkc+xsG/LslcoCfIo8l0UqgIo8h3NGTNaP2tBztWSKmetEVPuypQpgClxneCWMgNRBhymyl5yqYLisqC9z/ejIuwaY4SFoax47m37jqtNzzjNtJ0V64NRpNUp5WcgcSmJlIIU7HWdWV5fGyN2CdbgvKHpHFc3rrJEJWVungKn40S/aeQZrM+DWUAFq5nneh2zRLanKTMcMjHIuirgoakSG8UcMmOe8Z3jpruGl5Bj5sVVx+HxiU3XkEviWivxKisZZzVWF2FZKktMhpgdc4I4zuIZpBamQiFlAecK0kSNVaJxbhKUyK3rHosSQ2lnDUu6ZuMdV9uN/H9FQ33jeXp65P2H9zw9nTieJqYp8Lg/8A/tP2F/OPDp69d8/c0vCeGCPZBLfWakNnDW0rmOcQp1uBNXxppKggY5J+yHUqC14i9ojbBxCoVhHFf5/jBMHE4ji82FSDrL2qBDwZjIPItP0zxLEp0xStKHFSsYq5QApl1jmUvCt5YxzoQgz5qpz6jIkaSeE7awJhUPTExhqcfWG7oOA77bLCzPy8WPQpGk4ZIjV7uWn5gXWC3gljaGtvE03nO97YU5r87Jn8rI3pLrGmY7YVAuEpjlsy8LUM5S0wooINdH7DQ03nsOh8Pq9fbxZ84VUJ3nv2KzYQzD2ANwtR1onWW76cVeIGd0geJgTkXWpOrLZrTGGlM/n372jP+q4x/+o3+Dv/23/i7OiOF1401tImfmeWQKwqLIOfN4OHL/8MgYJM09JWmihzEyh8JxmHlx3TOnQBsMU5hRSobnyhjSAiopMMsanIL8qdtiGWWgmN3FcPA5W2WBqkDqLJSw71Gy+y9hUKqUylK8PJ6hR8+OZ8BAHdxoXYdJdTCQciIsIIdStZ573oB/37GAZZe3h1LL4OTiZy5v8OVnVkBu+bszm+vZN9OKEGaxKtBnRvq6liP+QgZF1rVWUtR6fFG+sA4Knr32ug8//7vLAdDlKVjA5aygSYUGRW14yDHz2ScvAWEmD8OIMWINoJfXKRusld4w5YRzripudFUBySAuRgFMQ4yEWWTt4zAwT6MweKZp9ZuTQcfEw+MjKUW2/YbSZrrNVlQQagE2CuM0Mk5RCB71mVrBd1TtfeIz5tdykr1vmKfhGQAp62oNr6hD0TkIu8k2BrL05AK6yM8f9k8Ya4hBZPYxRNlXlQzPtVJsdn3dv5SEpdXBW4iBYRjIKdF1Pc57YdBf2Fg8/9i//v6tN8b3/qyAYFUVsNxoa/1wXt5X8OwvWZIWKfOZVa+Zp8DTcSCEmc8+ecFv/eSH2KblVNdq4gxWlCKX301ATrcySkuRRMrT6cD7d+/52c+/4quvf8k4B15/+gmH41f8yZ//BX/jd3+bvmur3Lru9KVwPE08Ph6wxtD3HU3T0m02GGN49/6Of/Hf/zn3T0eeDkfmuq8rpdhtWqyWsDaRW//q8+2958X1jh/94BNe3V6Rc2bTN3Stp20cm75h07dst33tzcp31q7v+2/pJRYQjNpfiqrN+QZr//K9Av41A8IW/6mmcWhlybU4TlUWZbQTamWRTcUgDRtKpmkxn70Scin/f/L+LNbWdc3vg35v93VjzG61uztnn65cLldRgJtKDMExOE4wMVxg+wq4j7gAoSgRWAIUuAAJKRJIiMQ0EiEQFMkSEr4IbhMncaOyHJfjSjWn6tRpdrfaOedovu7tuHje7xtjrr3POUV8VeE72metNZsxx/ya932e//Nv8LPH+yjm20ajnSnGrFC3jilnpj6Uok/hKlOmtpkYykTTKI4Hj9amMGYUqjz4MUOKieM+okvSnl5AqsxqcBp8KilHmZDAOS0Ph9ZMk183FrNIwfTyzGaMkYK8bgxrrHpWLIywBUGdfVh3gJXGv3x5AcV0QYuNmSFKoc6cGf2MKt3S6SZVZbqS14+bwoIIMUsQQVNLVO04E0JF0xg22wq0+JqMk2cq4JQ0xalEQCvxbiFjjSOExNj74le2AAjFb0tD8WZkDoG344H9buT66Zat0nSdo24kSXD7qCOFxNjP3L3ZMY/zKiOYRo8PEVc55nlmmibee/85mSTeSkqKn2kcySnRtJamrWnrmpwiwU8Y41BIOtA8yQLvik+dNqb4kFEWd0VTC6XWe/ldtFL0vRih262hcg4fhSoc/cz9vbzHBAxTAKOxxpGzYh4j8xgEsEQXJpjHWqhbS93UVLX44/hZgA5llgJrYQ+CVZb9oWd/P1J1jqYVNt0iv5PrLQ2MKSBOziKtjTEyHGb8JABWDJkwq7VJqtuazYUrQGgCREqqlC6TW43LIkPJIXM8jlxebUrDJwyoBGgjTbOfpJhsGifa9BAJPmAMXD+65v5wZBwm2k6mDwrFpt2I2fIiCTbiraVWJ+NITqEwMhS1czitmdMsv3uOVEaTgyaMS9pWYh6jFAUOtC5+dlkkD/Ps13s4+EgsCSpLFPjyH8uf6zMFplJoJ557MWow0G0q8VbThqBl/ZAUN4+yTkIDQNbC0sglH5j8JKa9pXjSSaGzTP9V1kSfGFNJtQSMfliQq5xWY1zr3Cqbnr1fQaOFlRJTwioBGEVxqdeiM6FWgCqGsBZZyy+tyCXp9zRhs1rumbQUMCzVinzeFTr6ItlUJVlJjHiVMIdWOWUx+0zLj1QYbTClOVl+xsKI01pxua2pnDD/No2TtdgYqtpinMUpVTZb9eAaShGdy+RYgCtnpbiuq4ramtX7w4eIn2dqO5KJBWQqj6gqjURefkZi225W35Tld6vrMwZJzoVtoAoDTCIQ9Grey5r7JQbbZRFYTR0yIcxcbDpevL3FVg253FPRi+9eSJGUJfBE5TKkchYVIjEvSUHn0kx11sQgRsFao02mqiyVtRKtHiNVbUjRyrPi0woEKa0gi8H6AoK9a3i7DG0UCqM0bdfQNPJMz1Mi+8jYl70nlmeo7MNKyb3krIW6omss4zGw390x9ZE4y3pZ1YUtkErTmw0paFIyNFUDGZ49fkYKI09vLjnuj7jKcjz2OKdBCUtCEufmIhOtickQk2GaI4qENcJIn2dPiOK9MU3Cbo5JwlGWaPvlflbKrKC1NdKwVIVlrsp02FlpcGSYJnuErQzKQOMd0xS4m46Mk+f2dk+Mif/kzW8DGetUMWKHlEJptk6gr1GaEGQotduNspZpVZqqXFi0JRCmgLymMpA1d3cD43hgnhPzLHJzMa1fwDKN95K0uAYOhUTfjxz2A8Iu70VqxALCyvmO2VBXslcZq2maGj+Ohamuz2SD5iRjQoD4GBNDtJBLLVXWoOX5/HHH2ZeWhjnhp5EYPVfbhseXLc2SMqNEfqsLq8AqRW2NANraEJXCp0TICor3VOWcgOylrltrNHXu7ZkegDPLICPEL4dKLGvHsi8dj5sf+7udH0ZrDkcBwtq2F7uQtkNbR549bhmcqFyujcIoAfrEG5BTF/pTjq999F1evjnwwbMtl5eX1JX46mTkvBwG8d+cgyfMY5F1G3xaQJbMYlQUk9SjJii016gxcBxmLjYJa2sCurBEF2AGCs2S7DZk7+UeVRI2s1zztXlWxQ8YqOpGFA1xWhu7JdVevGPPILNzAAr1JVDqdJ2WwUd+8HGxG6Dce+oMoHp4ik+A8jtH+bjRXwaO9PJelpv7nWOxoFleKP+Yi6qUJAwuUOs5YJHzAgxmkcSv9erpDaozkHCRwAGrL+uJqfrOz6UMbJDzpLOhuJ3IQBSpU7Q2tE3NsyfXPHpyjdKaeQ7c3e1xlTCCRKoeuH17R84RHwL7/YG3d7fklGnbZgXZxnFkGiemeUKhSCESvYQ6LL6wixdyVVW4qmabM4+ePhMvvbqRYWZVkZP4Yxujubu94ze/+13m+Qil75TrpNFamEG5yGZzloTDXAB8vQKoJ5naYi2Uip1DKPeqD4GqtuURyiI93lTCVlVawsuyk+/NMlgmCUA/jzPjMPH02WNevHxDCAJqLOvVIu9FaQlRWeWScl4egMs/BcT9SUcudf67D9PvDlJ5eCz1qVJCKLG6yEiNZrc7cL/fE8LMyxevOR6PXG4vsXVHDHeY1QNdjHFOg+VU7hfLNI/c3d7x6s1rPvv8c16+fEWMmfc+eJ+f/4X/HH/wD/5B/vbf+lv82//P/weH45FN15ZzaDBWep6xP7Lb94QQqKqetut439V03YZhesGPPn/DoZ/KGUg4p6idZdtaHl9tuLzYYLRFKcOXkjTkLHC3P/DB8xue3FywP84lNEqwGknCFiBtGZKvtcLZ8e7wABYp5KkvWgZhGRkonPuX/qTjPzNAmK1MSbmTCbI84ApjMyEKW0cXZoPKspwu0j+FKnGuQgm1zhYZkYZc2EdImlCzrQk+YsjEWePnyJwiMWj6o0xvjFm010WeCDIuYsI6SeRDiXdHf5SNLRG5uKyw1uBqkceoYnAe5sg8JfFQCmC7pQmkUFll+p9t8TizMu1c5GJaL4MLCRLIC7hFuZFiYhwkUSdHkbrVtSw6CmmUTKEYOmtkwqhhGijgWiKccLT1WKmkpdk0VrFxamUFVbWkAAYN/XGgriXxLCGIvHgQQdN0qwY8R4VravrjSEYRY2AegwBLIRVNfZYxVAEzLLo04CfjSl3S5qZhoqE0y7VjzjOL0CSlLJ4QToyMx97jZ18S2kSG9/rNK7aXHTEpiJa3r+4wWnN5sZV4+ZywpqSRRM3V9RVtW3N3f5Rz6RT7/UjbVUJlrg0+ZLSDzUVDiDDejlSVIYZMP3jxDEtSDOck9+39XkISrNPrBiHPghHgN4jUrmsrgg/yvSpweSVMrRQj97czQz+Jga9WGEsxvzcl0Sqx2+0JPhB9xpDouoqcoGla5mkumu68Mia0gqn37G57plmc2I21GGvF2+UoyYhkmdwmKrqLjbA2QwCUAM1ZfEw0suGiEmhhm0liqGWOk0g1G5kSaWOFKRISTVuTnWFWilCAruCD+M4VJpuzjjev99SNPLTbTYOrLCFGuX5JzJSv7AalFa21tLUjB0uYy2RLK7ZNxzx6dnrkME0MswC42kSqJuFHX3z+JHQDBf1+Ivq0grkCIqt1Ah5CYvUGQ55ppSSModlWKKOojMFWsNmK4WiKxWFAC7N1mjy2cjSbFqUiPs0r4LPfD8KGsRarNBp5bqxe+GjlvwwxLSmXQqWva8lcXxomY4wY5GstIFiIxWz4JK3MKeOssDoxqaTQweL5kVIkRpEAkAUkWrwgxexel/VIgGUQk2V5YwACQCqtirGzXgu6d41A1WLAi0Ih92zWS4GVH1T4uhRiKYXiDyF7Q9s6mkqo/KmsMyFEopegFhavHq3Xn71s3oukT2nx79JWXr+pmrXZphSa/TCj0FRVXIEqoxf/tkxKamV4iMejNO/TNDFO85q2CqxFb15rRoVWCVdvUKYq6X4nD4zla40xNE3Lk8dPydmRs+F2fyhG+DOVNYzjINdvElmTXDqFMgbXGNQ0SoepynsuDVPOVn4rVRodLeCjtQI2jNPM8TjKkCmDsZpuU3PYTwVEKJdfxRWwzO8wKGTy7iX4Iss+YbQiJ8VmU9EfJxIy4HLVKXBG0vM0IVrGYSSniq55RFN1fLH/EVMfGQ4RbWpcpQsgJx2hMgqVDckrcgSjHSqL+e2maWiahkfXNwBM8yQs6pzQOjL0PcdhJiaNrVqMbYqnkFkL7ZSEuTwVFnsszcE8SSpezgJowal5QAnr3DlL21RYZ/G+WB8gDVxSYlHQdA1N22CMxs8zfk7ELSVlW+OMyBt1ebZkvVgSXU9DMqUUo58YpglQTFNmv89sN462aYTVjzRqWmkqZemPUwFBKxSOFLIA3ybgWvHPutw2WKvY7z2b2XM4jlxsGvpRGGDOGhpXEefA4f6Ij0nk10XeC7okuDm224bDPnJx0RZ2hDR0TVtROYdWBmfs2XOcxac0evrUsG2RRmo1LVcnMEydQIPyWK/HAihIarAXuwWjaYoEU2RYZvUSalxFW7fFJBpyebb7fiTmjKs72rqhsq4MLxbPnSV17IxlnIWtvBxL0xvOJIrnR4hSJWkUde3ZH770JV86/tV/7U/zRUmY7JoDxlisqx549WmjqUr9ZbTCqvPhaqkpf/qP4o/9U3+dlA3KWN57/oSm1GKbrsPaW9TtjsMwiW/qNJf6VhHKi58AIfnZu+OItoq6MWV4lRnnTN1VwlAOXlKmYQXSVAG/YtI/8U0vpusZTbO54HjsGacZM0wYa6mcLd50agVM1x/DGZiD4t0ftEhiQxQQnzIMP6WpFtfZ6uS/lJJ64A++SHfPX1md/6nO/p7PQLHyQbV+9xk4kU8cLaXUWu+s92R5ReckvEPlVLaF5X+sIJhmYZP9ODDtJBtdFUJfcUFOPzeX3/vEmEpo0A50Fq9cSZ3AOsPNzSXWWnzKVI2kfx72A9qI0bwxlt3unsP+yP3uyDTPHA4Hbt/eMozDKgHLORcTemHHbrqO2tXUrqJtS2BEJWb5xsrAaqlzjZE0ZW0tdV2XmkiOqTDIUoorc34cPQv7U5fzn1Jaz6Atr2WdeJ+O48R5CAO5sNd8IAYhmIQgRBJJtE9CIqktG1PqmCyenyD3eyrXPAE+gY6JefY8e3TF55+/XH/eImFVStF1m8LKLcPc0suerly5dmjeBVLO74evOs4loquMv3T/qQwNl0csUyweeHjXnXtBrjLIJf1VWWonXrGQqSshWhz2Rz7/4jUvvnhJ942Wqq457gdCDBxHT9XW3B8GLi4v2HQtWkuwzP5w4JNPPuH7P/gBt/c7rHN88OHX+CN/5I/w+372Z/nZn/1Zbm5u+PSTT5hmz9u7Ox4/usEUXzRbwqwy0Mye27e3vH7xlnYzUbct11cXJaTEcHXR4b2EwdSV5WLT8PzxDR9/+B4fvf+Mq+1GPMN+zDP4xctbHl3UdE1NU3eFWSbkIa0y6dxKYQHn36nTl3N6IivBHBU+nNbqlGXoVVXVV37/jzv+MwCEyUnYbhthQhhJHozIJrTATBjN/tiTkyROOHOa7i0LZU55Xfi0hqpyJyaTUqL1LqCS9hrvDDEkrE1UTjMMC9iicNqgjJLYXRT9fcA4mEwWzx4U8ySSPaXFd6ipM11n6VpH1Sj8HIlhEkZYSMS57GNKpq2LiXkIE9aK94M2qiT2yfRJqKunG2KJXo3Bl3MjxtLeSwrm0qw6ZzFG6O8WQ20r5ihNmGyuqkxci/k1y0Z1tkEnihdDLky3JZ5W45xhnibaVlh297cj01xRN4KY55TlwVKamDVkXcAwSYhqu4a+l4m/+GJlklKElIuHmqauDW3nMFbTH8RE108SkR5DJpCFqVHVqwzLWIVzhm7TCMgYIm3lcJUw6nb3B9CZx4+vcU7z4os3NF1Nyo4YEi+/eMPFdsPV40tmP2GipqoNlW4w1rLdbnj65BHaiKfW61c7nDN89skd2wtD1zoBwrKYvQ99pD9IelDbanb7kegjx2NgDgKoSMGqSmNj1lSw4MXrzhiFceI9k1JGbSX9cJ49jx5dcn935HgcGfp5TW9sN5bO2JVd5yq5ZuPRE1Pg6lFNSMIw81Fks3Xl1qmQdTVoUwIqIsMwMYwzz58/4eKqEznMGBkPgTAncGCcgBXdpqJtHMd+oO9HUo5cXjRUTpF8QBf2181VW1JiNUkJI+TuzY5m00mRXTtUilirBHQBclOhXWIOcTVUHHtpOFRj2O1Gttnw/ntPJBlTg8tJionsaSpZzEOMVNYU2Z5EZttsaHTFhWvJuqH+sOLN/Z7bfV8krAGVEuN+lmIzZcbRY8wSHnAGdmVFzouk8aHsSylwlSYFWeMEmITtRc1m09B1NRRfhVAKq7EXIDdvxXB6ngLKFb++4DkeRh49uYQs8Rk5CcjjtEEljfSDGUNYfWZyNhyPI9uuw8/TOuFdmKyLxJCcxETWGDLCtHXGiKS0FFTLtCfnkv6Sc5HGKCFrlAJjLWIL0LMkBC+Tyii6FvmeRQ6pFRRfL1gKnpNsfimMluYgozFlBi0SI2kGF2r7wjJ2JXRlLnIXVxlckXOFFJlmYeySxEdjmfCvAQil2VpWzZwykbiyP5VappNlRU0QsqTyaaVlKp0hW1NkjcshzYMprJV5mjkcembvabpm/X0Xf7VU2GCKki5Wzu0it1ouzCoXKOfq+vqapm6IIfLy9r40JJGurri9u2V/PKIOmTzmUvhoshLPOePEF4gogK5cC2GhaYQRJ0zZhG0SVS2F7XCc8FPEzwlbKXyIVCXpMENJxVOnqUwpoN8tiFLKEnDiZLiVUmKeI/v9zDQrXCWvZ00JNDC6+CxqhsFx9zriR8t7zxuSVujcYpwhIwBZLuc1Zi/pcsqBSmQiKmUMlrZu6IcjTot0YPGKaZqGhOxPOQdi1Bib0K7GOpHFtW2LK+lRSqnic5WJRUK3yFFCEAZx09aQ68I6mFY2I1oVP0xJK5vnUUIbdIlV18LUbdqGqq4koWv2tHVDU7dstlturkYOx4G+H5jmib4X35rDoS+Nqibrcj2XCTkL0DwzjJHtxlG7CvGkkZTfEKFyNV0jNYvTFddXF9TPpNET/z4ZENZVzeRnYpSByu3djpuLDYd+ZLc7rMBOLN6xMQsPcRyysBLCxL6Xe/u4c2w3DfMwQvISSuHqB5LqEANiRZFFHug9+8Md3eUHXHYO8kTGFo9WAdooTd8p2qA8Wu/8GaMk8pIyddeIp+sCCpd11FqLM64EfyRiTmTVlO+Xs6itLV9n5ZlCY5TFFUZCGTusfm0P/FSUkiFG8ZIL4eE0/v/1l36Bn/v9P+L/8m/8KfrhoUHyjzs+++LJ+vftdsRYaerTMkVF1r3aiqxdv8MKELYAvH7TfOm13z2eP5s47DelyV9sUMQSYp6mtWlXWq9MtFwGTCAAUlOd9qRpjmWYLhL2mBLDONPOUVQZOaJysepQEDC4IEMQvbC/y0VeQNFzr67oJYE5xiisoNlTxUggM8+ey4tNAa3Ws3H6ZXNm8dNcTpcqAwthXUsfNIwTqCi15DKsUoZc9JzzPJfhwckXb53DnAGQS41/vqTmd75GF8BX/jxJFNfrCCt8tQzaKNc3nTE8tBaGR9Pqdf+VcZWSc8vD98ADdpc6+//lvJT9oKAZmUzWAqgtQzj5XTLGNOV6lfpAKzIJs/w2yz1rNHXtGHcHcAatpD5KMbHf7wkxc9gfsFYz9AOHYSjKBbkf8wJoaU3byLpe12XY4Srqqi6gsQBeqrCK9CL9KUyamL4MWOec2e/39ENPjAGtKAqEWL5f6osUT2sjSNiUhtU3dmEhSdDDAgHJhYoxyr1bBsWSTrqw87MomLJ46JkicU7isLGKk2LO+JzZ9yPu7V0xb9fra0HxZLROah0ltkBKsaZQx1KjkSGrDGfPw/JMPADzvuJYniNVWGdaiS1QDBJetPjk5sxaf5UStahIxJN5vdGRPjgDIUcJ+tAS2FTVFbVzHI4TL17d8aNPP+fp4ysutw1V5fjer/2QTz9/xUff/jq//f1Pef+DZ3zn2x/T1DXzNPEf/YNf4Td+67vc3Dzil/6Jf5I/8kf+CN/+zndIKfHyxQtu377leDjw1/7aX2W72XB9dQVKE1KWoUuW38Nax/bikhAih2EuoNm+MKoy3/zoOdtNw+HYc325KUEtHU8fX/Hs8Q3brvvK++70XGb+wHc+wJR6trIKYxylNSgudAIOij2BMPHPpctL8vFSs6eU8AnmYAlJVhDZC+X8WytszPQVz8RXHb+ngbAFlFoAr+22FYDBBwGkSq56iGIYbbReo7hrawm5JKgkAYzqYjx6ks4sSHQBxxD2rQaUs1grTSyqIhFwDWRfpI95adbU+jBGLzT/GCPOaULxZtdGrSbywqSwxTA1Mg9R4ucnAW80am1GZKJTJCRW5AvaCAtKpBsy6VZlVLMwBBbzYJDNKMdE5Sy+SCiU1tRNwjlhN3iCMDBiZpgnSfMJQs8VCYUAFAuwKDuSIOnLlD6lLMbY5Wc6Z/DB0yEyT+tsIV5Igk7O4g0W/IRSlovtlvntvchLNRjnyCqgtBHPDwVRCWPBVZbNlePm8YZu0zKNgZiOmMoxDRN+9vTDTLaazUUDWpPmeZ20dhdaWEtas3u7Z78bBVB0wo6aw0C7aZmisMdCEK8h7wPowkLyEZRFaaG1agxOGw77I08f3eCnSEwyGUFJOIIwKQKb4KiCZZwmdrcD0+Cp65ZoEk3jGJH76rAfRbJlHVqJNLiq3OkZyKBiBp1RBtpOvG+MM4yjp9u0JYVEJG0xRKbBg0okn9nfTULd3shUIKaMaw2MxSw7ZmIUuaZzppjnZ6yTYkQ2Esrv2lPVjm5Tk3OirgxDP6+JPrqYpmttmafApnN0jSTzGSPFbAyJ7D2Vc1zebOj3I1oJ4DNNPbVr5P7NET9FpmEWdmYnLDRhMo2gIORM8JHXb46MQ+TmsmPs79l0LXVVgMRcTMOjmC+7yrKtHc+2HYdxJhSPpnvf07gaNWdutt3KfgwZntct1zeON7dHdvupJK0afIZxmplmAYLIMhtTxVAjZ0WMStI7Q1w3LSlwZcO2lTCdgg8oIxusdTKRHL0kfrra0jSautYCnk2BcX+knyaunrTkKGEcm21H5Sqh3StL6ywbK15q80Rh5UUqPLasiznDzXaDDhuGfuRqW4ncglNRvZinVk7M90NKGKWpihfTAkSdU+BTLEUH8pwv9HxZxXgwTQYKc/BU5GqjV/BsSYg631SFVu5X7xuZnsq6c+5FZoocaTGGX4q+cfYyOECKH4dI4ORVZC+xRpjH5FK0q0XmepIUmSXZV8PC1EEtPkQyXROGYJFAIucqlsFFXVdgrMjFS8qaACOheN6JvGicJvaHA9M0ofX1eu2EeZjJyHWyWov5YAjlnpdB0LIBftUUHSWDA2cNHz1/wpObC5TK/NZvR7qmSK4PPfvjRD9FYhYgQPZXAwxoHVBIgq/VAgQoJCzEWLi4FM+7eQrcvu3ZvR1l2NNYqDTDNJILlcMUI/OclMTXJ2QCarIUyjmfhklaFTl2K7HkGXJWTHNE68zmsqVuZFoffJJwDb+nP85M08gXn00Ym9leTSizkcRWLXWHj4F9P0vgiDFiWWAyiZkUPITA8bgHEqRYYsFP0tUFSE4o5iDy8taK51xdia+GeIQswC1lqOSL9+jS1OVVFu59YLc7cDwOZ/e41AQ+RvppLvURBdh1uMbJNawqYgiM/UD0sXhjaTZtQ1vXdG3D/mAZR8u2qxn6mk1ds+97ptmXJleGFjZY5rIuLKDdpmtpm4YwDYURCcMY8PORi7ajLpPprmv44L33ubm6KinJEWcU282W4/FACCM6zVRlWDfNgddvdxz7mWmWGmXykf1hIMbMWPwvU0zsDwO5rMvWava7nouLDuMclxcddWXZ7fZ89sULvL+i62oB4orH4P6wp96MtHXDOGbp9JRdazvO1rDFRODkvyfNodbgvXjhgEJXzVI8nrHKTq394u8Usvg8psKkF0a4NHKqMIl0kfSKaf5pXYvBozkBYblc/8Vw+7u//YzKzQ8e+//7v/2H+a//Scf3vv+7S4x895h9Vzx409rYnJYUVRjCeTX3pkCkKcO/+r/9pZ/6+lVd0UwKlSJLIEpMEojQNhX5/sA0zdTWsKQUCxu6DFOBrnP0vYCBSi3822WIApOPvL29Zx4nLrYtt2+OPH60pXYV49Rz53sg4awSL9Is94TWWnxPnVvBjMzMtu8JPtD3A9nUuLpCwMsi6VRLb8KXEm8hk9ICZEj/YosyRSnFOHl88Pgw4pylrqoHtjBr47o09QWsWF89nwFd+SEQ9s4tKd+n123jwedOr3difmWV1/v/nXlFqSPyg4+vfpZ5AaTkTZwcEJc/z2TA7xwi98+FWUYBKjM5j3IGdb0CIqdhmdRo4uFaksaLXC/lzIsvXjPNkXGaiCmz2x0YR1/8fg/c7/bc3r3Fx8A0zWy3W66urnn+7Gl5NgXccqvJOsJCK7KinCGnxDxPay+X05Lsl9Zn6Zyp6r0voJmibVv2fk+YZPBorBULoBBXL64wl0FBSpicmYaBRY6ntfgGWqMLY1/WGqDIJKU/MVpROUtdJJIZAeePo8dazUVXExPMHkziwXveHQf8NPD06SOiD0yTZZolRVgZSPjCEHdopRiGmdnPwj5PsTyrClV6zhW8VQI+ffXdcHZvpfKMqxNDNp+x7E1h2C/3EMuQQr5Cev7CFsxR2MTLe1iDrgp4VjlH17UM08T9/sgnn73im19/n8ttw5Pnzwi//j3ujgOf/vI/wqeEto7nz5/inKM/9rx6/ZoPPviIP/vn/hy/9Eu/xH6/52/9rf+QX/kH/4A/82f/HE3b8r/4V/4V/qO///f5Z/74H+PrX/sa4xxWJYBcOwEnq8pysW0I4YLdYeRwOHJx0dE2Fd/55gd0bU3tZO1snBPLClN85jhdw0XtoZQilSfSJ48thJxUnl0JAsorGHZ6vuWcLc/tu8+v+JGJaiZEu7LNyRCzAmWwVUsq0lb//xfSSFUaEWe5uu6k4FgWEhVL/CfURgr6BTEPMTJ5XxqmgiDn4i2CGJw7J7pmH0JJNJKLM5eGKGtF1chmPXlFxJFULPHERY4RQWctkpjlcYhKvMqKb5kuJqriC6NWM2eZemeUMvgZ/CReF2mR+zizgk7WCspbOY11gngboyRqvrKl6RJGgrbif6HLwpAzEMWMXxu9Sn/mEFGzp7WO2ijyPGJy5jBLgzpPYuQYw4zRkrCoMAVYKQ98abS0koZEK0dVwTRFkT1OmaOJVHVF2xogYRDNubayWYfJM0+B/dBTu5ZeH7nbHQjRU9Wace+RCYaYn6IgE7Gmom4slzc1IVb4UhxuUosfpZHqdwPOVNiqQa1SKFbgY9ksrBOZmdKa3X7g5nEnjboWFmHTNPzoB5/jbI21FT5kPv9sh6scj552GK0Y/MwxH+k2La9ev+F4PHK/O9DUFfM4UFU1l1cdsTAIY4js7kf8FKnrihgSm03NGzKts9jKkkNCN4a6rsl4XC2pliEEaTisWtkrxmRsbYgEXnxxz4cfPS0x5UJlDnPi/vWBlODJe1sBw6KAYJuLpkjrJA1LJpQdKszUm5aUNWMfSvR28RCIiTD5U7OWpPEMIXD/Zs/NzTVNa3n7cgQrC940TtSDY7OthEmTM5WzIvN1Cuc0/RjwcyZMgYurTjb7EEjJMMXAoyfXpBBEC3/REnyQRFgFPieMNiVuOeB94tH1Fq5kgR17jzIJYxV+HvGzwlQGZxBmZ8xcNDXvXV+wbVt8Stz1Rz57BU3lePHmnqYWnbxRAasNd8eZcZ7wIdIPkmg6zwJuzTPMXlLgIKGyR+Uyqc+qGIDntVCVpFTF4qgRU4YY2V514pFWJMfBZ7q6WiecWscCJmaG/Uz2nm1XYbXEtaPg2c1jRkYS8nzXSosfk9YUwYdc11JcLYezkhh2cyHT/pgO5Z6TBuIc4MpIIb9pqzWR0RRWldyjZt1QVc6rjOfdWva80HuX0RVTWtOItD73BDsBYYshrUx9DatxC2fJXWVyqJV+UNT7IAzUlBNGKZyxjDESp5mINJ8LmGGtoSnXcd2ylFqp8krJ10A+rZmlqdBazGNDCKvPwcKa8wswpjVVMVQGCnioWObtukSyL9+/pJWtjLAsLK85zPTHPeTMPHZsu5aNVeKtZ+zafMX4FVRzBX1/5PHNVpivlUi8XVWzSWBdS1Nv2DQTt4eB3XHEhxN4oNmQfI/WmdpCioFsNcHLM5GTxs+SPOmnVJoz4QR0Vc2QZf0HkSKqAiLDEpbgRF6bEuiMceIXt6T9hTnh50DVOJJP9INnu7VcPm5xTpjJMWbGwRNDQhtFitC0FR9/25LzyDjA5mLmJlzRTpH9rhf/rqQxWZ8p5BLGRlIYePv6FU3jqF3NPPsVDG59K0wspZhCoD8KcC+eSeWEKy3MiZBWqcnKTsgiP5XnLa+Msdl7dvcH9vsji2G3sxbnKmYfmPuRGCOVqwoop4Sl1jQYZ5jHiXmcSA8Ky7zeTyEESQdDmPTOWbquYdu3jLMv1gQin5mKYT1KFePjmkM/YNTIpu3YtB1aax7fSCNlrcVow3bbYbThzds75smz3XRsNi0hSupYSpGLzYbjwXO7k+CR50+v+OiDpxx7aahTLglbhVGhClB0OI7c3u1xzhaALrPvByon4Sb9OBFmz7Hv2Y5bqqomRM/5UTnLPNxh9A3bbstxHABT2D/rKTsBYO+sa7Gs6ykGxnHi8snTFUDTVmNyhEXuqzRRyTBy8jPJWHQGvwxOkki4RFqspHFcgkLKArkAROST9KjcYRijGf3MmzcN/6v/zZ/hq463t19mAvxuj//9//nPYczf5J//5189ZA/kxdOq7DWhNJmFNZJR/Me/+t5PfX2rM7WW0JoYI9M8lj+F8TAOE4fDgKsNSYkCQhtLUoYUPClEhtGLYXkZ8s5z4HAY6fu57BG3aG2obIXRpWY7jLz/9Jp+nPns1ZvCwsol8U4GXa4wf9qulf3COhm6mJa63TJMkX/6n/rFEpole9o4jmWolDBQwI8C5JS+hbXljuTFB7moQeZJ6p2xeE2dUpgFTF1sCBbWmTNikZZSKeP5Mkh1umanv2t9tp2y3OKZL93sZ//M8OV95ex+2G7bU/9UQNFMJii5V4qVF8a4M3nvl18vr9/P2vPFOKPSLKD1ehjAkNMM2qHUMrBLLOdWhq+TECm04u5uz6//5u9we7dbQdXZR9qmYfKB+/2By23HMDaY4HHG8vTJE26KHP4r3+uP+0ABebQSACoUD8lxHAkhMoyDvL955uUXLxjGgbe3b3nz+o18bxCLHFtSe4dxZiwWFtITa1RhgIH445Ez3eYKSMQYiuTPsixoRmu6pqZqhG0qy9apLokhUlvNNMxcbtsyWF/k+qxfb7QmTEceP3nE/u0tVeWY5nndQ1PKJOFKE8oQfKnlFnar4FgP60aFOg0FfuIZX2rLs5RyFi81ymvAMpOQr12A/EwuwLv6MWmFMQlzbmH4NU1D1zQM08T3f/SCb3/zDY9vLgkx8/mLW6YEcxJFyt39ntdv7rjYbLi8uODm+povXr7ir/+1v8a//zf/Jr/yK7/CdtvxL/wL/30+/PBD/vz/5H/M3/vlX+a/8Sf/GX7h536WrAyzH1mUZOQCnueI1Uokm1cXGGPY7Qfmeeb954/p2mtudwc2bcOmbXHW4CePM24dHseYOPYDr9/esz8cabsCJAOmcnz43mOiAmcMxlhc1RLjjNaeGCnKpsyJi/rO1TlbH1JMhKQI2ZDPVhhyJmUJe5pnWc/Gaf7K13v3+D0NhN1cb6mtYw6J/jBgrGa7bXG1xYcgk0hYi7WUZCI5TZ5p9tS1xTiDNmLKNw0Baxy1U1TGoWwGHYgR7vf9mvAxTwKMNa2jqgwcAuOUUGgwQZILF79mwwqiZSXTWVspZKGVJtSaAhL4zHE/MQ2e427i7vWB3f3IOKYSzXwqEOZR3n8udFSiSD7xiaYxNEXLWzeVeCUlJf4hOUFKaGu46mqOY8DrSF1VUgTohI8RPYsJb9IzOa2VPJVzxZQ4rBMcZx1VUzMOHlemDDFFvC9gJIsMJxdz7Mw0iXl4CJmrS0ewLdM0EEJitxvQSpIlnz655O524NPfesXjp5e8edlzmDwpw811jS8AnnGSdGaMQhtKwZs5HidiTlxctoQg1MtDiBz2e6qqwucA/ch2W+GnCWvEMwXAOJE/pBypNw1Zifl73weUEsnZxx9/zJuXtwzDjNcw9sKuUyrLYqddkYol5hAw08w0zrSNpa6u2O9mnj2/4c3rI/d3A9pk6s4we804JvpeDMObpgJVEUs4QlNJ2EBWmb4/0rRWDIGHEWclEn4uBuzjccRVjqsbSQLxc6CqNG3T4CrH2I8cjxMpZ5pOGqHtRYc2RS6coO0aLm8c97d7rK4ZhoGbJ1fEaWI8Dmy6iqYRAKGqK8in9xPDTLuVif5mK9G9h8Mk4KmVxdHWmovLmt3dgf5oePxsy9WVNKMpBqIP+CFzOEbu7/ZcbxounrdMU2AaPWFMxbvGiy/BZsPLl3fknPn2o+dcXXe8entkGiL3dwP9ccYoRddVVI0V6Z8eMdaQ0ISU0DqjIxhT4dq6GFhDVorbfqCuDB8+vuB4OKBy4vnjS4xTTOPAMM1orRjHwP3dxP1uYhwDkxdJpg+Zs5TqEzWAWJ5xvU4AyXkV1sQk8jEKWKIV7PcjVzct2cA8DOA11olv4hIBnXwiB2g7YRGhBDRRRtE1himPa3E6LYmpIawg9u/2cGZLP+5wdgnXcCzFxZIACYVxkMIqR6zMSdO/yJhOcskvF7WpvD+RdJn1NbVRJWJboUvajhJ0fC2mF/bBInVawLQHm23xBlreh9F2HaBIiq0Uov00Q4wUy7KVsaXNuV/ClxsBU1i7RghYayGHAh+TbOhhftBlrOcki6+jDwllxCfuXGZpjEyRnRXGweQFdKiqagVBBDCNhBTxZaKqlS7y5qUx8ihqiemWC7G+lxWMTBLPTo7lmgLKUDcb6mZLTnA5eabryNNxZj8M9OPMq7f33N0f8DGjqy2KiGaQZw5oakvKCu1gPM4se1/wMqnNWTMcA7MPuLoqQIEl6QlyJaltBWCm+CopBZnEmAIqgVMGY8p0sgABKoMfRX4T5kAoiYYZcLUTn6hafD6qRpKYl6lo8Edm31M3TrwqfMTmE4C5JIENcUATmfeKytRYZ2UNr0WC2NQVwWeqqiYFAZZoM6EMv4TJoZF4+K/wHyq3WypMh/u7PW/f3jOO03qPWmsltUyJB+PynPjgaWxDXdV0m44QAuOhJ3i/3jvLazgnIOnsI3Xt6HvF1eWVmFsbLaf+iRYgkpNcOpMl+MQaQpJUtKRKGI7PxS9JvIrUGaNz9p5pNhjbMM6R/fEt4zCilHiGkeXPujYoEpvGsTuMhUFgRdKTwS33cqkJQwg0jeO9959xd5h49uSxNAsKKgv7/aEkvyl+9PkX3O123B8Grq+2kAM5CwB4dXmxPiMCMIn6QKlawDAyem20ymU7BwQyq4zKJE+I4qUJGauKNEspkdAHD8YK21EpjG1QVMQ4InaV5RrbxT9IrxJfudYLnCBv5N0GUWmN94HPPr/mxx2/+msf/djP/W6Oy+uHTUoGZi/Xw0wB684SIhezwq8AOL7qyL5fqQY5RZICnzJzBJ80SYudwjB5rFFUtYRfjN6SbWQqgTXex1V2Pc3hATt7AZvEp9ES/EgIIufLGe5ub3n0+BqlE1XrsNpJ+vscsGagaRppEGLEWsvdwfPk+Qf8zLe/wTAPfPDh19hutsQQ+d7vfI+cJQk2ZR4G7aqvOisiGw8x4awRS4yyVqwy/7LvSfpnlFRMXYsvagaf4iqf/6nnu3yZ1vLeykznxLj6CuD3wbs9G1S9C4xOowx5F7BPnX0+KtH9WNSPefmzIRRIiEFOpZY3GFOJhUeYoAxVlKqQgCfIKYAq1gYEYXLmk8WB1hEwtG3No5tLbu92RWY/k3xgPw7ELPvk3e5AVorLy0uMtasn9Y8DARMKYiSrVAYJMmye55nD8UB/7JnGgXEcOfY9u7sdb+9uub274/7unn7o2e13pce0fP1rX2caxYTfFDsJSZj3TL3sDdYtLPhAmBZwcFmzJKAnRWHzjkpklqlLZS8Qz2Zf1n9TiiIFWK0I0XM4ztRNR9uZcq7P76Fc/H81d7f3bDcddj9R1xU+zmeDzwXIXzwoY0mwfnBDfeX99aU748G5P/t7FtafJNCLsmp5WX3+vOUvP3s5Pjxv539f5PmprMNV6eOOw8CbN3f88Edf8LX3n1FVLT//B34ff+s/+lWO4yiD+mnicOzxIdDlho/e/5DPPvucv/KX/wpKwbe/8y3+xX/xX+L6+pr/0f/wf8B3v/tdjDH8O3/tr/Pv/LW/QcqZ954/55/9E/81nj99QlJLCBRolcFYuq7DGE1TGaY484NPPufJzSUfvHcj9bwxhJCYo5CCBj8wz57d/siLV2/50acvefH6lo+/9pxf+83fIQMfvf+EP/nH/zCPry9omgpXbzDGEqMHMtZKQEoo/qbLvXB++LAw1WEOipAUS4TWMvAPwRe7m1iGHr6Y/P/04/c0EHbdykTl7jiu02C70BlhNc8/Rd4nbNLkmBj6iaqRNKq6NdS5YqsaTPHWymrEB0Fws8rSVGYp59q2wWpDzgnvB3KwtC5zGGZmhLUVVcTWmrqV9A5jNCGJKFrpJHIcJT5gGkVbC0vsxY/u5XXnSH8UX6vg81pMsxi/+5lYZGV1pTFJcxwDKSRc0jS14/mTLW1jOIwTmYzfzSzJuLW13B8mjJL0PrSmbQ1uZf6kghZLsa0QTbvJFSF45llQ7cura5nczYGYAzktCVQWdCaPkZwUTWVxTtEPYlRunWIcpNHbbgcBrGJEKWkItptKprNJWBMff/yEH37yhnnqsVFjm4p5SmsDqxRUhS1jrcU4oV6i5N2HHHn7ds/jx1c8en7N7du3XF5scM7S3w9srjq0EdDJGoMzjm7TQpKFd+g927bh8aNHHIcdn33+midPrrBa88HHzxmnnv2bCFGhKi3JGo0RzzYrjLlpnghz4LA/cPO4lelvimQFdePQ1nDzaEPdiGwwBtlgyInDbmDYD1zdbEg5sb1oCHNgnAahnCZN3w9cXG5IOVM3FUolhsPMNEW0lqZNG8uTJ9fs7nq6rmUcRiongEkKkItvFlpx93ZPionHT68FxPCKi22Hs5o3b+85HnqOh4mUhCFY145uIxKau9sDrnJsry9Qaiub9jTJx60sptOUePS4E1amUgz9SNM5MXBX4u3VNpZpTOzvZ5KXZql2ls1lIyBLTujkuL7a0B8n9vuRcRh59WqHcTVd69gfB253B4Yxcth7DoeRi82WFIXqk4JM9Z5+dAlkUmmAGyuebc5VaGPYtg1PLi/oakdMmQ8eXeOD5/mja/7er/0m7eWGNAMJhsnz5m3P7d3AsfdMU2SaBJw8pZyUI5dJSCm481Ks5sUvjEIEUYSlgyqNGj5TXRqUckz9CBtNt3UoKwm2fpSU3KqqmKdIfwhULmOUpnaWEGVNUCqJ/5mpqNHoLHKOlDM5asCgtcEoGTIAWFuVydLDjcvYhpATBE9bC9v13IdqYSUskh1huxXQK+a1UX9XMgOsDK8xjhKpbh5O3hYwKaa4/ozzSWAuLKiFgbYAYatXpFLFjy2VCbAcSsmkKcUFSAochglnDJslWORsClrGFpyKyHyaehrxcFQKlhRN7yOqeEfmAuKrr6iPc8oiJSlm/NoE8aYopsdKG6p6Q108pJQ2DOPM8TisQQzDIBKwOQT8NOBLyIDS4sPYNrWkHWbxpvRJittQqP5LRxNj5HDYsz/uyWthWkCSqmb2IoWoqwplxXh9DoH73YHWGQwJRc/kM8ZUjHMpwgHNHj8lbHGfnmbx53FWEUyFMpoAGGdJSsJAcsoQLDEkwBTzVk9Oy32gxOw4R5ROuE4YiWGWoJUcFJV1WGckuTUG5uLhaYtv5Tx5bGVXxmFGyTAsZ16/OlBVmqqyeF9YOeYEtuqssMFAgBRnjuPMsX+Jc4ZDP3J9fcHhMBSLBwlW2W625BR4+vgZz5v30MXnyZoaRUn7XGlGyw1Trk+Y6fuRcZwfpCedms2FNXJKFl0kdVVd0ff9GlevlCQyyp8iUawqx/3uiJ8DdVXz+OZxkT8K8CRgkgyfzhc8rcQKIqXI4Cf6cZDayFmqWkDOnBQ+CHB48je1uNI4VFWF0oppEM/MwzASY+Lm5oYcNC/evC1hKHCx7WgqR1s7mkoSFI2WEJwFEFLFi1SjuXt7W4BCi9vWfPT8CcbIc7S9EAPhruuk9gCijuzfvkSh2HTFL6sM/nIOmIXpvl6Zs+f5DCPPCBA2TiOvDxOPnmwpI1N0cVLJFC+a8l4XIMOaCqWMAOgJMI6q6cQnzNiTJLJQKxL5zGg6wwO3pWUw64nxx/t/HY/tj/3c7+b43/0f/in+wO//93l0c19+KqSSLi2yPg1nbOSyuPzU133y+LUAYci58j6iksJnxRzFrzCEQEiB43BkChPOVHRNxRiS+Eq2NeMUJcW2uFjNPj7Yt2X7MmRgmMVj1anMcYqk+VgkkTPtpsZYSWWtnWEfZg6959CPUO6LqnZQzTx5rjDWsWlrthdb6qpGZcXzZ8/54ovPmGZp7Ja52ckP8QzwWdkop5CPhcGyhoCxSKcXeksuTFTZBwwKFRYp6JePr4IktZL0S0UJCmCBv9cAznIsNg9ynxmrVh8lX4KFYvCk4MkpUSkgmOJJU3zCzu6DlBN9CGyr6ksN9CpfWz+wDNdUKaNkqKCdIYexvD3NWZlFXrOTy++cRLKbqoRtLK5yGDuBgqZ2jOMs9XJJ6jVApSCQabqOyXv6fjgxmXLGF2BtYXaN0yyA1+FAP/Ts9wfu7+/F426epZcI4TTUKwntWimeP3uP95+9z+XVJbvdjrqpaduW7XbLp598yosXL5jnwmrUCldbOnsKUbF9xewnSA8Zr2F++O94NhhcWP3zLGCiqwym9L2LT7V1mq6x5DBJonvZI5aawmjZsz/95AU31xe89/wJ9V2PD545nAANAeMWUFiut6ToGnz0ZfD58Lr/OCZYhrNU3Lx8sXzrmqqq1xpL7p2ytpf7wwBZL0x0AQxJp+Hku/fkCTTWVLVcG3W/4zhOfO8HX/Ctb3zAB+99wHsffcT1937A27dvS5BNZLfrmYaR1HZ8/LWvrSDoe+9/wP/0f/4/4/nz5/yb/7d/gz/4h/4Q/+Qf/aPFS1Tq9OPxyL/1b/1b/Ce//uvU9S/y6PpGQNGzAYPWmqaRFNM4jgzDwG/c7gkx8a2vPyeEzDhGJh/oh5Hb+z0v39zx4tUtr9/cc7870g8j3//sJRedDMF/83uf8Ed/6eep64qmbmjLOZT7tyhBlvXo7Fz5cPJ4G2dZixYzfFGfxvJ06dXjbvaRWCxZvPfSS/4ujt/TQNgxB5oIXe3AKJTK+GK8lXJab0SjNSEXOaA20EqCjNLCXGo2pjwQBmcryOLNk6IvU/jCpEhlcy4XZ7c/SGJcmjDKsKkdMXjmnLDOsL1o2WwbYky0XcU4zoSQIIfyAEvU9zwlkQuGyH7vGQ6TJAOeSWpEii7FaIwRnJGJs1XUlWPrrHgbxShx8K7iettxc9mSc+bu2DPPdxyHhFWGy6ah3hrmELHasBsnsjWoEkEfCyAiDBRD0F05R4n+0Au9PiOMqZgZJ2GykRWNrlZJAYAx0ngoY7naGIwTDyuR7gWmyfO1D695fbsvMe+5NFZgTcbViY3JfPjBBdN+ph8kfc1oRXLSEAWp6sQYvTJUTYVxFXXTYE3m/nbg2dMtTS0S1MvLC5GN+sQ8eoa7A+KvJ79PSH5lvPkpkNKM0i1fvHyJnycuLzr6YebDDx4zDz2XlzVIkjuUibdWMB5Hpn6gbg2by4q72wNKZa5SLQunVjx775If9bccbkeO9yMpg6kkOj6GjHWapnFcXnW4Sp2ABw1d10GW1LkpzMLkUord/cA0JXLWVJWjaixNWzFPnuNx5sOPbtjd9iXZDOY5STgEma7WIg8oEtqUQylctDTfGIL3zLNMiIw1MEUBY7yEDqATWQlLyzaWiycttbvCBMPd27dYk/nom4/JWfHJJ2/IKN5/74Y5eKYwoZDEquAc8xSLL41cc20y2mnu796y3W65uN4Akf0uEYEpQec0l9uOrnP4eea4nwkJ2qYhBiWmyjExTYHgLK7W1IUhYJuOpr1kHgcGn1EV6Jw5HHv6TcOme4IOgde3t0zzjHGyntzudlBMjHe7kTdveu7uR4YpiuH9akL7Dg2AvNw4KzM45yybfdmkxSPLiLdLWdtjgqwh9IHLK8PGtagKfMy0ZePXWpfUWYlwv7ioabuKymieX2w4HBy60sUe3tAphTPCWwgLA2QFkUTyXTlX5H9iop/iXBiYxS8CkQ2KnEszz0IVr2uZKJ3Pbs8ZJsGHL1XXUlbn9e8Lu3dhkp0fsbCSNIX5oL9Mh1+8Ebz3D704OAEE5xHh55/TSnz8KCtUFiMKllN0DgCA3F9zYddppUtKjyQCg2zo3ss6m9drnouv4zJCf6eIQgY6wYe1kRBfEUkjtE2H0o7Ly0uUNsJim2diVmRlOQ4z/TAJCydncvLrz3DWUVWladay1y3nOQTW67Ac6+Q7pXXPXQ6tNZUywjrUBmVtGYBY2qbm6nLD06dXfPbiNePoudv1jFNgnCPDFIhpS1V7cvI45akaLVLhDFVdktjKfeR98bZc2H/lsNqQVSLr0sYInisjXRWYj5lmozkUr0FrBFyIKbHbRVwlSbVotTJBbNVQN072jiT+auMoDO3dbqRtHXUtzC3nLJUzq4TeBAGf0WCVJlWJ/SHx+s1uTfa82G6lBgEOvefN3ad8+Px92naDLcCmUpZFuquKme/J46fcN0pkvCkWD1GtiVqVpvjheVrv9bU51RyPR47H46nRUgqco+scm02Ls477+yPHXqQWKoqn2LvPZM4UGQ1fOrSxbIp0jZCIcQEdpF8VpmNhX6SEcxVVJcBMThK6kZPIHB89vqJyNdbJkOLx9WPGaSzNnqGfI/fHoxTHMQAZZy1NZamcw1pDVdhTlLVr2zV0DqbalUTrBlvDu4bLSim8kudeGYuxFd73+MljtAUXUNaWm+/s+xamzDvXoapbDkfP9sLTNBVWndLcluGBUnI/L2yeqtwzqbg3y3pUAGCzDB40WYnEcL3WBa5X+uHvNE0zwUc++vDNly/c/09H4iHIdjp2+4Zf+41H/Jf+ibt1ZanrCudOKdXvMnV/OgwG41hLnc2yb2aYRmIUwMGnjE+JyU8rIKCNJqJoXSKnin70xTPtjH2UAjG/21jJ2q6Voa21eMQe36KUYnMhcnHrHFpXZCzTFEpwyOnISpOy5X5/4NPPPucP/Rd/kZizMEFXJtWXAalTo/3uZ/QDvPBw7Mu3ZzFcLwxY2UtiAcj0g6GTXveg03lfft7iqbb+kLSc5/L7FKml1Xa9YM5olNWFSbUwOWSNmmbxLxynCXJmnie6yq1fkwE/HQlJzMirSlITz8+DtW4dNv3EQxlQpoRnnp84hdKVsAfLh4tPvEjNlXgZi01ECYzRZk1VdMby3tNHkDJv3t4Xn+qIn2fGfhKwJMNl29JXFa5y/PBHn/Ar//GvkpG9KsTIOE4yRMmSHjzHibZuqaua7Xa7Wi9YJwB3VV7LWfGMFFZ3LbVPsZ7QJThlHEa+//3vSyJ8saGojBGj+rjUMWLd8FXn8d1nMcTEOHmGcWLII/kMN5UlUsKkVH1C+jNw3Pc0Cbrtdk24BxlQTmPg6mIrthARHj++5nA4kEL+MoNrnTNK/ZozaFUVeZzCnt+/X2K8Sn8pqqViPYEwgJdESlX+b03WXH7vFMWDqvx4YVVJzvrisRmSmMIv27F40GlsCTM71b1wsen44NljfvjZC16+fssPfvSSX/iFX+Q4fMEHz2/45NPPud9PpKwZxonjMHKTwmqrUVcVNzdXWGuY55n/9p/5s3g/M88eawzf/s531p/33e9+l+/+5m/wnW9+k6ePnqDVUgOf7mtQ5V4ClQM2z/z27/wIHwKPry+pXEXwnt/8rd/ht7//GXe7kfvjsCrwIGMNaJ1pnGLyin/4q9/jv/pf/i8wF+C0rjRte0kIA/M8lGT5uKpPlJKh0OzlAzHJtfdReny1rocRP0+iyIrCJk+UpNTgT33VTzl+TwNhwzgRTUBpuHDtOk2nLPCZTA6JpI3EI5cH2RhN3VhsLSd7GoV9UFUVKrsCnsUHm4E1GmUNVjnmENgfjry5uydOYuyak3yND1K0tG3F1eWGq6sNMSaGacJojb2wpGggeMYxsN/NIkE7yAPXtA7vJcFqWVWW4tQV4+gUT+aRKUHwia4xuK3hze1AVgmjJBmzrhwhRJrKcr1tqcxU6KcD2Rguu4YYNVNUHLykADq9yEktMTv6YEF5KTzLgmqMbAJDP7Cw1ChsihgiwQM5YyzkmNHK0HWOjz6+EsO8ckNLYz9xvz/QtpV4MSlF0za0m4oUB2xM9P2EypkPvnbB55/s+eLFjmwb2soSfUkCLSCYSCCEPZSCMAkuLxrmcebFZ7c0jePRk5vCzKjQl+DHEdddo4zQ5od9Dz7hrOXyasP9vUSaV9pS1TW2MjBNZC8m+01jcU8apn6SdEsf8TpTrHgxtmKeFNttKw9pSmgMm058xT7V9+giWTMKMXTNmXmWYIW2tUCgbRuOxxGtZRIVYij/Fkliilk8LypHiDO1NtR1S06ZaRKvlsePO4Z+ZNiP4pGTMnNQBSzTdBtJS7x+tBV2X71IaBLjscc7wzyOdJuOur1kGARoyVk8ao79jFJSrGQyldFUWNJBis8UEiHOxfy45jd/Q6KZ3wS5Ns4VY8kYSSEQfMSHiEIM8C8ua7TJoAzee+7e3uGc4v5+wkcD84wuiUhkS5gjYRZgJ2gE6E6SPjqNERU9QRkubE2aFfM4U1sJXvAx0vc9jbNsu47WGPaHgTBPWGewdcWb+wNDjFAZVE7sDz23dyP7/cjQT8zhNEleZXqlMF06oZQX0CsTgvgXyrS2TPAVOJOpO0uMkgiGXoIxEuhI21SoWqGKT4e24pGUk2zSlZXk25wilxcb/BR4tmnYj4GUDQ1gCriS17emzmpwhbGWpq6p6xrvRSJujABCsXiHGa2ojMW5MklTVhJeosJVtszQv3yY4l+YkxiOOiP390J7zyw+fg8LWHIm5ogPfgXJjDI469bibWG7LH9fZJHvHksxvU4Jz4A6pUTGLkEkmrYU6yxeCEv6WHl/U/DMQWRTWWVQGavM0pNIERbyWix96VAOkWs83MxzFi++4MMq26ycJS/m9zljrTT31jqxx7KWqm0J3tMfe3bHA7YyXG22nCrYYi5vzZry2zY1krA4yZCkgCw5y1Tcz4L+5/wQWpFCXN66Eu79g+Jv07U0teXqsmN37NntevaHI6/e7Lnf7fE+4b0mq5qMI6cZpQT4EAaZ7LdWaxprZRpYwLCUU2HvFTlQYQkqQQEgW7SpcLUqpqsjGvAmszsMuJ1ie6y5ftyh0Tx62lI3Is0xrgwD5kBVS6jNOMx89oNbnj3bsCsS6BASXVthnaVzNY/aC27qDZW2q19WPU3CFteKy4sL7g9Hnj17wtXlJbMP3B97jK7YH3r6fuTxY4NWdrkJTmxRVCnM1TuAhmKaZQey1gq7PZ+CJVaZZfm3deL3EXwg5URd1SVRUBiIqjDgpjmwPwz4+STtSSmtrE6l1OprGCmNBEXZ9s59nFHCbtOKmBTDOK1NmCnhNVVncFZsGQDGYRQ/w1I1W6u5vrrAGE1MhtkH6kaaxfVMrGC+eBxO48Q0T4xTZJiEzaGSAISuMNqPx57jsWd7vxcvl65js9nQ1DU65yIZFm9GtAwVsTUhRHyCutnix54UZbJdclDKleHE5Dtv0nLGNR1Pn97I+QyeSEA7cwZ+ypocYigJahZt3Pr7Ka1LIMXCvi1DEXU6D8uhlZLQF3v6uDTOArJdXoz84xxVFZjn6sd+/v337la24vLWxOcpF9/kh6CRefcm+opjGBve3O1om5qq6gQALPtEipBKCnLwYrAtEiXHe8+ekLzn+c1jPvn8NZ+93jHOx5VR9VXHg49rGRBeX20Y+wFFwtoOW21xzjGPI8Po12Z5fQXZPHBGcXVRE4J/IP8jQ9dtUFoxjhJWIedLr8PpcRhE9qYUTZPXdEG53rMkI6KwSlMVhsh6L+oCYqNWACUDdfFWXdjSy56pi+/cAsIt6eSqMD2106T+JHsV8kAuVhkTu92eYRjw3jPPM94Li+d4PPKoyJLbZ8+o2y37+x6IzFEScJk9wYvli3VmHRBqBSHMD4YhWhu0eUc0uf41n/0hJviQCgPwhLdko0/At1JiXp/TykxdfU1TYhgmXr++5frRFeMwEXMkBmGv7oYRP0x8/8VLJh+53LTUOjOMIzEE6qbFuZqrq0tcJa/rXFUk3eIntYQrmMKEX8EuYyTJ+6eggP/wH/0q/TCeLBaUKl7H+gxQVevn3j2+SsKZc5J+p6TLWi2+Vzll/BRwtSnDjHwKPSrhcCDDRekbZzIKpRyX1zcc9rd88ulnHMdJmOzLQPjsGq7laV5qkuLhVdRh57+DL8+cXaT2y0UuX5azrHvamPK6ywA2iU2K0lht10ErcBq08vCeCWeDzSWxddcnrBPbHWO/fK2stVxfXqCU4uXrt7x+fcc3P/6QFAa+ePmaX/3NiZDEUqNyBqPFs+7Zkxse31zw1//G3+Df+5t/kyUg4uOPv87P/dwf4L/yT/8xPv7GN9Ba8+/+jb8hLL5pWoOSZChkZWDDEgoiz6yiqE7ChMqKF6/eSHha0/D29p63dwd2h4G7w3EFrED2GWdgHHu66oKf+eb7/L5vf0TX1mQyPszyuimSUiCGxFgGBDHKnnhKiZTXTElUEsYo2kb6Aj8LeDZNE+M0r4mz8WwofwLMfvLxexoIS8GTjaKuKrKGrBJzmkvFVYrunFFlMhZiEJO3C0HRfZkGxZipXYvGkZJa07zkBZAFI1HSncyDza9ujbCnQi4eZAqrrUSSV+IPdSypF67WRKOYDn5tnobRCz3YREmAC+lkWggoloVPaOI5Jaq2KVMcVoNldKZpLJebSv6p4H63Z5x7SaVUitqJrEK0tIG73T0vvCNnw5udIM6Vlc1PI0Z68xSZxgmUIvhYZB7SxF1cdFR1JYt+cdRUSpqL8ZgKU4CSrJlxjeby0qG0hayoasfFRUff72Uh0obdfiT6xG53ZByOKCa0Khp0o7h+IhIA2zTcvhZ9eFdVUuSQcbUT02bnZH7jI1gpMr54u2cce9ruht/5/hcincme2c989PXn+HnCNQ3kyDyO7N4e0FnTVDVt2zDPM3f7nk1X01UNVe2o8Whbo1VFP880nRH9chTJkzGaurZsNy3aWvrhKDJEMkM/0FatvMcM/TEQY6LZWMJ+kgUTGAdB0LtNh1ZCHx7GkabrGO9HYc1kWbQ1hsNOCntn7bop+MmzuxtQwMVVQ4iBGCyHw1HStLA0jaFtDKjM5qIVecxxZL8bRf8fohR0k0yqtRbD5X0YMcbSdA3TWCjb0aN1htoQfWBOUSR4CbbbhvudyLU2m4qbm5YvPtvRH+V++fgbj6gbyzROvLw/MgxeDGpTpq4N2wsx6a3rinEY6DYtn33yA7S2KHVN3UrS1nE/MvaemBIpi/9IzgKaTnPkor1kGHfEeWajGuYxFnN6ebatzVDCLw5z5jDteLU/0hrDe4+veO+qY9u24nXlNHPMDMdAfwgc915ei2LwmdLatMq6JIv84sFRBvkC5FgnzatTq88CiFl+CgnXVBirmcdZJpVa4VoFRlL3tBUqukKjSsPmnBLJh1Zs6oqrpqIr7CwTFZZUCodS9JbJrzTLhpxM8RupVtP1hSXlKrvKCVPOIi0uSUXyyyoaJz87Z5jR2AL4LousNbIugaTMLAWGTNuXQvTk73VqbMWbMSf5fWNJzlq8LuRrTkbdkhiZVqr4mtx19prL38+Nd5dpaXlBrNa4M5rLEi2utSQTj7NnLMBzUzkBqmD1bVnAUK1PXgfrvpbEHFrkDg74MhiWSCWVEmkYI2AyMYzUjTTF280F/TBwHAY4AzpSFlaZwgrQWs7vGBM6BC6NEel+Pkk3U0zS8AO5RJorbZimRbKQV9DkbI5f9l7xbJKCVZhcxmScddTVFdtNx6Prmd3+WMz2A4fjBEQxUk0KdEPGorNnUwtI2tQVOUeuN1uOw1hCDITtMYTA2J88sdYjK3KQpkobcHWDZlOeyURlG1B7nOnoD56rRw2mMiijcZWhbeXc+jmioiKlwP3tzKtPZ+qLiXFWtJ34DUlC1pYn9QXXdbemLSkksKeuKrq24cmTJ2y3G2LK1G1LCIFN17G533F9cYXShpvrR9SuFgAlSwImCFiklUyi0yLhWQAFtKg7CrN5+U8pVlZAVQYuOWVstOuzEEKQkIiFsmQ47f0hStt4ztTRClvZVaIqwJmwkZTRJRnuxGzKWTw9Rf5QJJe2eJCUIlYYdXZdS8SCQbw5UUoY35eXtFWFqWsJ8ZmF6RniSXZ0/kzDSV692WzWRvIcMA9eDNK11UzJMu167HGg2u2xxnB1ecHTJ4/RStF1G/wc0EHTaQfZME/LfVekNCwo2Ol3FynIMuw0UNaalBP98SggtobsZ3GnyGb9XcRnJjLNYtatXLsOeX1h1Mu1UevauQwI7MJoLUBxLIy580MkRhKbou0/Xovw03CrTSeMUgUYV5/WdZA6ShnIcb1vzu+5H3fE6ECp4gNcCZNSKZyWBMYQI3NJrARhdFSuYttt+dr7z+UeiDOPHnd88XrPvp/4/MU9MYtv3dLgunJuQpQQj023wUcZQl0/ekTVtMQxYoFKZSISGrSCLAVgqusaVMRZRT8EARLOB1AZurYj+sjtm1tiEkuVY39EG1OsKG652408vtmQ0Lz/7Jqktzy+1ri6LUxo8UUV78jTNddKr/6RABSgwFktjBF18jl8gCmVekECvhYQTRhFzmxJQZQxTSN7cT9OHA6e29tbXnzxktvbWw7HA03T8fjRI7puwxefvub65gpQ2Kri4tqyv9tB1gzHXoZRzsogoRa/RmN0YRMdS1K5LvudozI/5v7NCVVCJ8gZlU9MsHIKAFW8PtcPAFLv1HUljMvlnlTQdQ1dW3O4P9D3I3PwGK1pu5bHTc3Vdea7P/jsVCdVjmdXl7RtS920VFVD27Qoa6ldVfwB3z3fP/74SZ+PMfKNjz/m9atXeD+jKOcxJXwJOZE1JD0YIPy04/xx1Fqjrca1Dq00fhRwK2cxQ18ADmMsikiME1qnMhxewKPIMERQivu7O0zbYa1eWdVyVcrPVsv/Lb//Ms57eC6WveZdEN2VBFlrhU02lzTwL/2OpbZJOQkI9hWnebGzCEt9lTLRFNcXFGgldkG5eL0+oEhnnLFs25aXb2/53g8+5/s/+oxvffMb/PzP/wKfvfyCwxS42na8ebvnfn/g0fUWZ+DR9QW/+Iv/eeYIv/lbv83P/dzP8af+1J/in//Tf5rLy0s++dGP+D/9H/8Cf+kv/b/5/LPPuLq85Jf+8B/i6ZMnjNOE1jPGWIxeAg6SqLmUDERtGXzvB8+b2x3zHPCz59PPXvDi9T39FESNhYBOWmcqE3l0dcn7z7/O7/vON/jWNz6iMlIbW63JYV4VeiBD5yWozodETBQv8dOJNgUBtU78DsVaZy6hZ0ECc4LIIo2WhPqYFOGnz02A3+NAWM6yKFW1yC5yGbmps8/nUvRZa4kkPJl4XAAwMFYxT4mmeICFkFbJ19IAxJApaZwChmlFU1c8urmSi1AMsMMcaZsaEnRtjbWaYz9wOAygssSrG5HaTcMki4Y1JZEmEnRaqe1PH19w1TXMc2TfT8VPQNLftl1N21aMo2ezcYWGuyRxBXLMpChePnGYi0FqFmlBmQal1OPDTAhHUFsqrYuH0Uwoch3gBAoUOqcvSCxADlnMzJ0lt7IxzJM0mzGktWgxSrPZ1mwvKrZdxaxrKhSmjkx+x/bKonVNfwiyMZEYR09KwmizVtG2Gw7HmcPOU9U1dRu4vDZFZz8JGElCl425chU6a5JPjCpzPEwYDf3Rc3OT+ehr12RgHAZefDGQc6I2YAjkUMzF4xJ5myRqOE3kDMZaYs44A66p2e3HkuKZ6DY1dasZhrEs+kUKpjJNBff3vshswNSOw2FiHGaO/SRyQg9TH6ha2dxThroWj6Wh71FdXUxwE0M/EiLEJJHCXdeJUXNMvH65Iyt4/PSKpnEcYuSirdjvBvGO8pnNZcdhN63R3o+ebHBOM4ZMkxV9P/Lm1T27u15ef9NgjOX6ZksM0PdyPsKcGYeJJ0+fYq2l7yVhLUXZgK1t2G5abl/vuH97L6wgY6hrw9vbPdMUefreJcMwozXMc2QYPMPgmaZA3Vhurlpu3xwIXjHPgbpxXF5dc3/7lte7O1JK3Dy+4YvPhQ58nHpyGtbCFZQENxRmZVNLYqKPkoTm58RxP2Kdw1VGwIlcpmAxQY4Y60ArXt3t+d4Pv+D5e9c8ud7w/vNHXDzb8Nn39xzuPWMf8XOZkiLNQMxLKsrSXIpMKWYFOQAadBa5Xk4yvQeqyrK5aKXJjPJs6coQc6LbbgWcquHiuiLMkrrjipRTFWDeYFmI/Y0zPN1uqEpRMA6BFMQLzFkjC2aSZNq1siBjrTAuY36Y7qgLILRM2pYUynPJIzwsTqpybqcMTiUxyi9fNPsZg1D8M4V2rk9s3tlPDyR4C0MsJUVlG1KOhOSZZvFFlJTQExC2NJMLC2EBsACapmHxCZPXjOvfl4+fg2be+7WRXt5LKEDXHGMBtFRhu8TCtClpmMVMXy/jyHOsBghB1hejZP3QOrCkfT1oRrJI1JOPYBSkwOJmcr+7Y384iOSkfEwMoMXLcWkYzjfUlE9MnIxidxjWwUcIEWWMpB4nxTgeGMaBnOTZcFqGLUJJF3BfGYVWxTNGaXIWz02lllSnTF2AwrqqiCFyf3+gshVt3TCOnmmSAnWexej4smt48ugKY8Rb6/H1lk8+e4W5MmJGP3n0OOLHeS3Szs+uUqmwFGTds9ZR1RWuqggRhrlh6ANPr5/Qv5jYfXHg4rqmuzC4duL6qqPSLTk6NvaK3/n0B2zqxxwOBx4/ammrDReXFY1reHR1yePLayorXqGpWA9USoIknLVonYtfXT6732C7aQHFprumck25X8wqgVmu3Gpo/U7Rl1JJES24pNEG7RbQyZ5ZF5iVMbJ44L37/C73+Xr/c7pntdHY2gqb2kuhJPe4Xj3SlCoDhgKW+pgIMZf3rspa+44ZvzXiSbkylCC65TlWWFdR1dLIoDQxJ6YwyZqgMq5xaDR+9sIqKK9vrKE1LW3drpKwcR5P65l15FbSoI0x5R4M7MJIUxvaxqEIdG0LecbPE/M8iQH2bEtymqw7S3OpSqppziKryYWFqdDgFyQb8jRze3vP7ds7Gqu4aC1oK78ziHVEXpK4xUOtqTaArDHTNBNjkoGIEmCCwmYVZl5pPpQi61Ivv8sm0ZoUTgzaf5wjJfUTP991J9+hc8npgskUYS9iHf7QG+rHHd/8+NdIMYk9hjUlOV2hVKKtNG0tNiLOOnJhx7R1Q9e2tG1NiJGbqw0hBTZdzaGfuNo2fP76XoBblLATyjNxHGZiAXO7riXMIynPxHnCOUNTKXQSRv2SGpdKYp6wqx3OaYxO3O/25JRom80Dlq3SitHPvL3bc787Ms/Ckk8pM4wTL1++wlnH9374Gf1x5hd/4Wf4xjc/5v0PfgbrGsiBR48e8aMf/jaH3W6V0Bm9DLUic/BoI6BzmANz8iszWK6POoUXlA+nLGzsrm1BiddqZRW6dSvqvlyyrWmZ5sh20/FKi5n/OCb8PPKdbz3m2Pe8fvOWqqo5HkeevtcSW5jGiRhlYB28F3lgUxP8zDRqmraVwQ1KLD0KgBVQ5DzSbS9I75ipq5zIRNS5dGr51ZZ1TaYOD0gRa2+5hAkVCwFhmgZev75jHKYV7NZaM8eEL7L+q4sLqmrCGMtmc8mHH37A5eWVMLcLYCM/R35SiInTKRdGjLV6rbcWpt1YpHAKYXj6Zb2YA7v9roTjeIZhpGk72YdzsRspxvaL0fiyL38V4PMuwWZl4Ft5FqpK1uT+0LN4L0oYkKxDtirBRsV+I6Yoe0I6JRDn5CGJAkdZz9W2YzgemN9RuX3V21sAvS+97SzWJFaXQDVBfcgUAM+on5oweKo7VZFNy+lYFE4hnZRacmmEmW6UoW4Mm4uWm8sLrDHEIPYcYZHQhkBIUcLLxpFPPv2UFy9f8o2vf42f/c43pM43msPuSNc1KCUAprwBDynw/nvv8S/9y/8yH3/8Mb/yD/4Bf/kv/3/4D/+D/0DM+I9Hpmni29/6mF/8+T+AsxWH45HJe0yMWFPCDlIAampXAbnY3FREGwnHnvvdEWM0z5485jjMjNMtF42hqWX4sOlaNl3DBx8854MPntM2NcM0cvXoitoarNJrCqktibhzCGWYIMQRa85qmrP7TCvFFAzDNIv0s3ifxpQ5WQKc6gdrLbZqfuI1XY7f00CYTMlk0TBamteFkl/gTfmyZTEzwqoYj54wR1xjcaZCYTkcBmm44MyE8OQZ42dpAGP0LD3ipm0Z3ITxERsS0UX8GDFWEnfevt0RU+b+vid48VmSjrAg5PrUhKUoPiy6SEr2h4l5TtSNw9SGVjkMlpAybVux3VRsO8fdrpfksei52w2EObBtG7SRVDayB5/X4pksgJjWAhYpanzIVBqy1RwPUzGuzyeKfMy4yuIqu57PkMSbQoxnCwOrbAiStKdIUZPJVLWl3bYYrUlZNoa7+x13d2+xxnKx3dJ0LT7C3eseYzJWZ0KwaN2RleVwO3P3tufVqx0X2xaJJY9MY6BtrYCRGVxt6NoKRWQ4DiKZrA0hRQ73PUaDn2be+9pjpvFI01xgtDTK8nlDiop5CJAVs5cI1spZSVcLgXkMYAJNI/GtSsPd7ZEYFFXVCv28ltTElKBpHHXj2B17tpctd2+PjAdPvXWEGXa7XiQkTqEL4DqPGVsM96tKUPDDYSDFRLdtCNEzz4GmdTSNeMZoo7h7u6OqK6pKy0RfJeZxxpfEI2M0wafiWyH36aMnFxzuBw67gQ8+umb2IzF4lNJsL1vImf1uQjvHNHqO1tD3EyHM1N3Fg2m3yAws0zjLVMEIk2waZ0KMhKgZdhM3jzZ4H2k7x+MnmzXl87Afeft6IpPYbB0Xly2VEyeTm8dbQhSGUlVXBWgQqWq3ucBVNW1nuL8dmOZUPPaEEbVKnK1lGjxqVGh9RFVQ146YA8ZqCS3QlHSehEFhCxthYXHWTc3u7ojFcpgi3/vRayKew35mOAb8LGaO2ih0XMCTJYUwA2UyVGTAIJJYTERZRQoCWqCKgTWJbuMwtmWcPdYZjn1P1zXyNcWjUFfQdNJYl0AWVBZ6c20sl03NzaZlDvKsZC/MuMX7yRdzVx8ldXEBpzSRtqrRRnPsPU0jbIbFW0VpjcpQO02y4ru4Gv2/cyy3Slbgsng6LqbP3ktcvS7R2kopzOpTJWCw0QbSqShZWC6LjN0oaXoyEkyyTJtgYbTkLzV4y/6Qz4reJVxlAZ7OAa/lvUohfJJYLmyZWJI6lVJUVnzd/DwzjpM02sXnSArejKLIqwq4EVPmbn/gZnuNqSrETtmiVCiAQl4L5VQSMlPKBezQGC2N8uG4583bWw7HIzEFFolKLomY+h0mCLLjYayAA0YvwQGZuSSd6uipVCarinEcpJALgabtChNQwlcUeZWDZtI6uVXqTJrAw8ltXTm6tuXJo2u6Wpq0FBPjOBd/QPHIIGc+ev8JF9uOeQ6M40TbNhyOg7C+Y+Kz128ZjscCOCw/i5Xpp5UkvdnK0jQtTdfhI4TJY5SiMZnj/ihJRjnx8dcu0UZx/2Lgibmi3XR888MPUcrw7PKGlE57pGIJRJCAknPgOMdM9EuKokZpQ7NpIM0PCvusHZdOpNaqMJbWZydlkpIGPuUyrOE0nZcifJEAzsyTMOUWDzuRvuoVnF6YlzFJmMJ6vuQqlmbJnBqVfPIZW9LnZBA3C2vYGGGlnvnThMU7EhmQLWzZs4ew/PtEg7FGURlNW1fsjn0ZXJpilC/P0ZrImUUqKLKuTO1qmrphGiZIIoNbQHqtNXUjCZ3BBwFuz+/F0ojmLKztEAQEziliTUVTNcV/S+oGsqerQauE9z2qbTHGMs39yrY6DkdcVVNVViwQynnL54bkOUOMHPuJ6EPx7JRmNnOSp5olWCQL88s6WU9CiCJzRAKGlvvdaPGm0Q8Ar1y8nvhS46iLF+i7QSX/aY6Y9E/8/KYLhIDsIVoX3z1OgEtBH3IWoDiEn/x6ABebNzhnubrY0HVtYbio4iNoSAsoFQLWWLq24fpyS1tL0I/4w7WAMMivtw1XXcWjbc1U/JtmH4U1p+C+NxjjsEpAxeMxkJORtM4MWmWiz6TQF1uTZU86GWpvOksu0ieRwTWkWIiCCna7HYd9z3EYOfYjUfAD8ePygXGYebF/icx3HK/f3PLxN75O2254/Pgx1hrGsZegmLDYCCC2Bsjfzz3+jDUoHx6sSakEtCys32maOQ49rnZcXV2tDDmVRE67AO3LoVTmcNiDhu3FlvzFG/b7AWsrXr56y34vHsFDL8EXdd3STxO2sKljCEzjiNcS7hSsRuXEfNyDrUV1USR33mdMyry92/H1zZYnz99nngUk7/sdPkQZFpa3WGYFyHOJXHvE+zAv0kEttVHKp2fKGo2zCqMtTd3w/PkTfud7P1p/52n2xDkQsvhGxbJPiErB0DQXqGwlqGoBrs+OqTyHKcle71RezeJTiizJj5P3TPPMMIpf6/3+SMqZ/iB7mNYwDBP3b9+SgqeqHU1TlYGn/PLBRyFklHVy/e/8OFMqSyq4leGxM7hKhvBjP+K9F/azNsSQpb+bxQpA7iVO63EhghiTsSXh1IKAJWS6tjm7Qqc3tPzrwYpQ1jNdvI8XcEqCXlg9kdfXKDWbimX9X8D4vLCXFZt2gy0pnyEEnHPCpJvFAiGt9eRD0Jiy3yciyhms0/JsG1vAQ4NzTs6VMWStmGMkzDO//Ts/4NPPv+D9957z/vMPORwn5mlk0zRSu5iTBcd20/H86WN+9A9/lb/4F/8in37yI6Zp5uJii/eeP/Nn/gx/4k/+s/yb/8b/lb/7d/8O3/r4G3zn29/GOUOIYd0jjLXYbAGNzLNkPWu3LapOKCPrw7Hv6Qs78/HNBV0jCjtb9uaLiw3Pnj3GOU1KYU1FjyESij/6UqtIEntJjg6BXBir5itsS2LZl6YpMM2RMItCrmQfy7BnXVML+el3yWj+PQ2EpSg0uLxEb2aRx60dnIJo4qnO0EVDnGGahPpOBfPkCT6uiH9Mwipy7qSz92Fmf+zpmpZhlLQX5yy2MtSuIuqIz5rkpHCZx4mqcmwvWmKMvH4laHPOFFlBmUoohSoGjVlrUjYYpJhLsyepTOUsbSMbYwqC/DdPOshQTYYQZvqhFIFKgLwQIi4ZUg5iXGlPGvOl5NRavKfyMaJrK1TDMRD8EmV6Mq9efMm6wvyK4ySb4pnxn5x10dqLd1EBH5zBNZaLi5q73USyiuurDu9HxiFwf9djlKGqNNMwsz8MaJPpuprjkKSAQ66H95G7u73Is4xFaUmZ6bbyMKaccU5YReMooJVxWgIRQqKunBTTLuNHRW0z7tEl/WGmP8pGa7QpEibZFBbWn6DSMj3ZdhVtA/f3B1LMPLrc8urNPeM4ChW8aFIkFQeUFRDm8qrl7m3P3d2A2XuaUvBYY4hGABRi8YtrLJsLR7exVE7YFJTrC5BDoL1qMcaUBVpT111JAVX4OXDcDVR1RV0LczDnhJ88TVuTo5zblDLPPrjh9s1BPKBMzTzP1LXl+vEG21Tsxjv6KfLosmMOsNleCliGJsyJpmkYx5HKVVSVo21lU5OpqVo9msS/SrzBUo5o7fj464/57m9/RtM44pw47iXxY7MR5pZ1kipUt4bbtz3jONEfe8ZhLky1K5q2YewnMb2NxR9Iy/eFKMllSoEqzVIIiZgTl5styi4JgZn+OAiomMvkrbZU1pFjJERPTgFjFLVr6OdA11jmEAUwc5Y5DKvOvaqLNCkrbCXSSx8iSlnmKcimu3S3WprEBXhQCmpnqGqRWCmtMM5Q6cw8e66utmKO6SfQBj9F6tZSWYOyImNbGlSLZltVXDYNCi2m8knOUcpiZLt4KIQQT+snsrlYnamSpa5qrjZbxslTOb1u5pU7ecAI20NCRpYY46Xp11mXuGsxZtXGULu6ND1lwnomhVwadX3GFLDF+yQEvzI8QD/0FMhSmEozW9bc0ljZsjEuBeT5sUijls8vDcsy9Txni4np9jIciVIohbn4MMl7t0b8eRaZtDy/0vBRwCCtFlr4aSoac2L2/h3mmy4ATuYcQkgkIhFT0s2Mc1hb4WePAsZx5LDfY4yRZzQnUFlkL1+pW3rIegO1St1yyiibUQQoMenTOEFmLYJiDHJtlRLWSWEAyXU0FN39l4a2Czh2c33BtpNUZmEnsjaNUACNlNm0AkY0dc2ma7i63DJ5z/3hyNCPvN3dc3XRUDu1SlHgnNkk06yqdlxsO8Y5cLHd4qPHpkCOItG9ub7iyc0F192Wrqn52Q+3PH1yg7FWWBDApmtWSr4w/ZbpZEkFTuJZGgsj0VhhKi0spZRSMS0vXkTaoZQk/KnMqi9TSpYLYRplUgG8FtBZWC8A4lnjS3N0DgAZZ9ZnQChWpVAvgG7kzHj/wV1xGiou10trSWvKUO5v+dqYs9jCa4oHWyB4jw9TYUmceZ2dHScfsVw8uMS7x4dZGviUoYBhrkg2lgTbnCWFSilF27TCCC+BPnJeTx3vEqARY2QcxuLZ6VFavhcl99k0TszTXBrRhFZSdJ8kwPKCxhTjbCsSsBwjPgt7JWoZtta1GPGf2HbSfeaikc95caSBHAPbrsGUVPDl58eUimfQiY2QM5hilL+sqzmLFw4skm5ZO1aWb/m+kCCyfKx8PaoAUe96Mf6nO2L8ycCV1ic53rGXQeSSYnrqK9Xa4PbDj/cbW46b67d0TcXltl1rUDkXuYAWUoNcXVxTVxXWamkw8Qz9XprmHKms+ENpZTEXNV3l1obXB2ngpJ4XObafy975uAMyu8OM1Q6rNff7kTe7w8NfC0hEfJgIXrHpGnI2BB9wVUWZbUAW2dY0z8xLEloWiblSpkjNhDllbIVScL/v6ceJrttQVQ5tNGnIq1UCKRODZ7W5pPiDmpLcW8zT1/q/rCf39wdmP/Py1RtevHrN5dUF3/j4azhX0TUNtat4e/cKrQwhjuteIO+7DK+iMOZzVhjjVhsY7xMpKY79yDyL51aIkYR4WfkQGIYe4ypJC04yBFG24cmTK0I2tFXDZrMlpcTf/ju/jLWWb3zrW1xdXdJt5eP7/T2vPv+Uw90t5CVRc0lxhpylTi7eM2gsaCP1UhKJf1gGXsuzmzLHfmR3L9d4qR3mSYJqfEj4LM355c0WZ05KnqAX43X5X0zC9Ms5M8zizTwOg4TCzDPzNDLPsr6EMDN78ce8OxxXJs1mu2F3GHn58hWLb+CTm0fknCU8J0Vm78tyoJjnKBYpC7vmHAQ7u2GLS+haW1FAlJwz8yQD9xgD3nsqVzEMA0Y5nrz/iOg97aYjhpl5HPHzRJgnYggYTtyVGBMJRWVAK8PjR09482bH3W53lvB4OpY1b3lWjJYBKhoyUk+74om33NK5XHfZN07o3uKxmct+JmxeAcPu5rv1B6YsoVQL7iBg0rJPy09RWZK/ZWU3jOPEQR9pquqUqmylhm6aBmU14zhxVPD29pbvff+HfOsbH9PWjpurS96+SeQqSsKyljXdGIOrWr7+8Tf5/NUtf++Xf5kPP/yQP//n/zxVXfPrv/5r/N2/87f5q3/lL/Pf+e/+9/j13/gNvvvb3+NrX/uIy+1G1CqRQpSRC7DUuBmHqyFpx6aS2jmTGMYRV1lurjakLAzPx49vuLjY0DS1gMNOBheVtTSNWBctzz9QjPEXL9dI8p7gZ7J1JBxKSa2ri2eZDPw0IRRCRYiSap9O/pJriAcluGq1lPrpx+9pICyExOxlWiZUdGFhGGs4C3ck5kRIUaZkWiRSPgYYRPLRNhUxyIQ1L5TlrpGb1BjmQpkUmZ6mco5xmjgcB+hFztQ0Fd1FzeaqIc6JsZ8Lwu4lvlmdTWzX91UWk0SByMtUAMBI8zaXzdZr8SlzxpHCXJggwj6bJ/Ax0HUN15cdbVX8yUxi9upkNl0e2GXqu8gPrq/EkBhtGfrANAaZ2J4VQrEAQkfSmjqzFGcZHsSVisTgIU3Rh8Sh96DA1Yr3nlxh7FF8nvrAcR+ItcZPieEgNOO9jTStTC/a1nF9s+HqquP+rkcrhY+yKMzeY0bNxdWGfpgkjW2OzGNg7GeMVVRNy/VNR7cVMGC/F8PAeVIMw4RzZXlXssl5HzBG0zUVkzpNZZWWhfbD9y95c3vP4TjTOiPTCytTdW2EqejKQmWtoW1qbq42xJxoW8twlESv1GnmIUruibHoRoCJtrVUtUZbUHoJFtBlk4DtRcc0zuQcqZuOmlq01UYW4RASQz8TvYBdF9cdxoGfxHBakfFzRBtFTImnT28YjpOkpZZzap0qRX+iaRxd1+DqhukwMo09CsXd7SvZ/HJA6wG1FbNhWyjcwuTJoFNpBCPKaKpG5A4xZO7uj8yzp24qRicMu+3FMj3XtF0ljReKe9UzT7NMCXOm61qM0bSbmuE4S8PfOprCEozh1LCg5HlztSEcRdY57D05R7RVxOmINgrnrEiWlJhIaiPPVyaAksAKjLAFqylgKgspM4WIbQ26ElBjGieqRoOx9IOn3Rq21hFDoh+EBTpPafXPASXgpJJz2LYl4bFxaKuxrqxrRVajrYao0Fnoxp1x6+BMG2FMGxSNtWyqilpL0qwrARs5ZRongQbLpC8//L/1KPiSSIDjqRkGYWedm7X6uEyb9TqZO4FZp0ZsaQqVzoVlKsbPqfz8FYg5W4cWs1JhN6XCUikeEpk1LexhspuGkqS1sLoWJtcC1i0g2EkWuTDOThLQdF74LuCO1uv7iw+o8dJ6C1NLobA4B/rMKFWzABinezQlYRpoc552WZ7DmCjtj3xUL8a2WSZpVU3lOqytCCFy2B/p+55hHNhuNiJd92Jub7XGalV8UiR1KyYBREIEZ06z1oX1szBMZOI+0R8ODKV5rauKphbZtvceZ6oV3EELG2Upsr40ZT47quILpRf/s3LzLT57lTt5tigWyZeAAxLPXTFsRn7w+Wd07hG7/YElyEXYqhXOiadWVTkyicc319ze78lkHn3wiODF+w+lubna8OzJDW3bUDlL19bUVUVCEbNce6MNOi/gYTFpLuzo/rgvfmpLgSbvVZXI75xySX8uZ9u4ApCfF9WsXYIucfTa6NU17gE4pYQNmXJJfl4YHAVAy+mURrv8/JVp5MzpOSgs2ISAaDHIx+R5lWu4rIMsTVE5FhCc0iBmAj6O+DQLQ85qSJklbn557+szRSL7mXnI7HPZTxH5Y0oJIkQdpA46k0QsdUdbtwWYDiuQvjLhVrNkxVwaQqUVKks94yon5ta7nbDJyhGjsHXFWys9eN9VVcn2Us5PSgFSRKmIdY3IiY39yqJ8GdagNTkrMXfIqYxCZVBBafJCzKASprBAc87y2oURFsvegcoFXFgam4XooMoemMs2cbpvVGnuMsK80VmYozH847LCfsLDDqfmqACT5Mw//EfPOR5rfv4PvGK7KdcgS238+rb7qT/xww++KLKYs2cpS005hxmtI9u2wpYlxmiRRf3wsxdlPRfgcdM1oERK1bQN13VNXawuJK1TmmWjF6BGGJUKGWT6RwL69n1iGBcZ3cNTE2NiHgN7JuYp0nUUQKYAzEn8cfr+yPFwwPvFL1KGS5w1gItnVcyBfhgZ57mk8skgu64bKufEs9Jqog9MKmOdWYcDtnLio1kGVsPxyO4wsD/07HZ7Xr655X53JERJrTPWEkOm6zref/Ico7R4Gh3uqTXcDwM//MEPefLkMfu9JNFmNE3X8tFH73Nzc0OIiWGcyWm5h6E/Hnnz5o2wPxVM80w/ee6PPcNwizZSJ4Sk+PrXv871kyc8fXTDz/3cz/DZZ6/4re/+Fnf3By4vLnj54hXvf/A+148f0TQd3WbDcDhw9+YtMQmDdUm5E2BE6qvVj7QMZKQCled1YX3LuirrSV3XXF5fUrd1AdhntqUuFBkrhVkdePH6Fld9Rt20K6ulaxoBO6eJaZrxMbLf7xknz8XlllcvX5JjQGWpD6yRQbMkGxsa5wgxYY3DKEfXKK4vLtfnXVN6thBXqbVY12bxWiqWLadn8p0HK4vpfI6SaLppGqqqFol7SMzTSI6nNMX73YGcM8+fP2McekLxb9xuNlxdXBKmkf1ux/EoXxexVM0ldSvPUwqewWfGydN0HfpweJjamk/DgEwhl5w+JSHRWpFKCuYD37CvXDmWAIizvrcAwPM8S72YJBzA+5M0+atO1fnHlj+naYaY8U72mKUGNUZq8FwG4M5aJh958fIlL16+4md/5lts2hZ1HZhnx+2+l3XBOUlhV4onT57ynW9/i3/vP/xb/HO/8M/x4Ucf8Rf+9X+dn/39P8sHH3zIX/2rf4U//d/8b/Hxx9/gB7/zWwx9z+Pra/xsmQlfHaSilQC2SZFQNG3NNZekGJmHkWE8Mk5DSRiX2m27aamdEfWGUWzarijBcmFgLrVr8aaNEYUM/bIyAoMYYaXJ9yi0Skw+ELOwvqdxeoA1rKCmLj7IVkAwdYZB/LTj9zQQlhNELzIVawW5rWorxtBG2FGpTNzOz8cCdkyzxxmRcUFp3BFpV12aH+eKP0NGIlyteJq4ytIPQzF4lifQNVLEh0oK33mcRYJZaZrOFTPutHz5Mv9lhd9L8S9slmL5UujIuhScqUwrxmGSiQVKGDDlIeraik1bl0I2YBHZF3nxh/GgRPrpXLVG8IZsqZpIu6k4HGfUIuWEVUeukEYzpEjtJI1ynKTp9V40/NJM6vJ9UjQbrQlTYJ8CwhaLfGYsIVjGIRCCZjjIdGqeMnHOTJNsDvOcqOtImD1tAWNSlNc+3h3JSqSXSmuhq8+SZDb0gXEQ2U4iMw2a9rqjaxtSVvjgZfp0lFQtk6FuC+J9nEU+ZMSjqa4bkfaFxDxJQuKxDwyjTOaU0oSU6LqGfjhKvKs20mhlKfAqZ7i4rJm85/mzK77/23uR0U0T3gdS2Wh1mVx224qmtfh5FsQ8U0zPRR7rXPFJCHJ/NG2FyaokyZ1SN8RU0LPNmaZxZfqc8D7SHzzeJ3KhozdthZ8DcxhRSqSF8zCjMmw39dowKZXxfuawF9ZJThFtRP4ihvqGzUVFLMB0XYqrmAQMc3VN19Xs7g9ULuJjQBtbwKBEVYu0VJfEHldXMlUcRRYYY6A/DBitubp5TIpCv9WmIiUpFBW5JI0VZpeTe7gfRB4xjiM5QL+XlDJFJkxSAFzdtNS2eLTFSNSR2c8sHiWLyXD24vXiVAGwlWJ7UREKuGKco65rUrZU+xlFFICKxMUjAYDnITGMHh/KGpCE1r14mKtiEhrmwCpVgnJPSEGUgrhha6VIJLJPhDmho6bRhsu6prMOUhavsFy8KHKmshofyyChgJ4nRssCNkjjmwrDYG3oSsMQQsBUJ5mdMBjOpmw/phlSnJowgKZuiUmmRaqwWlCyXuqz1xCwQZMxRQJUALlSlCzg0jn7QmSAep38LuDWOv0q6+PChlr+XECy5XML8wRYWbbLUOBdI+ecpbBXWcIAGltjnF6nvqoUneVSyPOKbANVXaE0KxCdc0QVUGKJa9FaY6si73O1SMWMxboarS2H3YH73Z4YJeRCKyXyhAIgmgLWKcDZijx7tLbElIlZF2c5HlDZUTKZ3++P3N/e4r3n8uqauqpxzq3nx9lKvIdWFopaf1ejdHnWv/pYSJLnUrWFNXMi9ghIY0oxmUuhZY2lti3f/tr71M4V1kZJ0jO6eHIt7BnFOE1cbVv6J5dYLTKDECRVNRdW6KZrqCqHKcCjeL7BMJ/eo6Tzlf9KWM9iAj4X/ylJ8iwM6gKcLF50MQlT02l38q3RZ5U94sW1TJBRSlidpQuQZ7WgJpwYj+dFfQqJQCBqJc1XOrHJUGCzlSYpRYxa2JuSQnzuHaaKzCQWac4i6V2OmDI5eUn1NBmlIplAJha/VgoAuIDi5T0XQ2KlZI0cx1G8t4ylajqRAOoTmBe8hIUordHKUNlT8MUCWmsjcpRFqrmwXUIIZJ9Pz5ESJoxzYg6+gIDWWnTWax1jtVtVAousbQHX1+c+LX5Whd2Q82okfpL8lVtba7JVoBYZ8FQA8sXHjgJmGWHY5RPzTSlNVTUYK4EHvtSparkfH7zPd0AYyrpcXv/05ikpbZEUPfe7n87A+sc50poYeUpf+9f+wh/k8y8u+F//L/9dvvOdkUWKm7Pir/+7X/upr3mx2WGqBp8N9RJCANzte97c3nO/O3DsJ/p+WhnYr9SBfppR1qHxtBsNe83FpsXpmsrPVNcX1KYT0KjI45aZUYoR4wxYGQKKOmORsHrZl+XKCOhcgOQcIZA49jPDEKjqlqquiSvTEQklmaeSMLjsqwXKzKzhJ9aYYlmSVrlvzgJ2LECAtYa2dpIwXdYslTKjn+i6Ijn0gRcvXvPDH33ONBx5e3/g9vaOYz+yPwz044TWhs2mJSe4vdsRCrsjxpm7+x2//Pf/Hn/ij/1xOtuizEuGMfLq9S193/P+Bx/wnZ/5OtuLK1KEz794xV/9q38D4xR1U6O0BHVN44grqoJ5nrnf97y56zn2fTHITrTthvffnyWpummoqoarm2surm64vr5mv9sLmLfb03R3jM1I121xrlrtOJTKLKbtsh6q9fwKKBlLzSF1SC7rN1meS0lItzRtw/sfPCP4wDhNjOO07p/DINfu85e33B2O617ZD0cOx57D8UhlhA1oy/6irAy+m6Zmu91g9HNqZ6kqJ4BmU1FXVWF7CuA7l8F3yd/izZs3+NkX0Cbx6SczfX9kHP0KJPkgw7fVl2nd70/AkHh35QK0yvo5ew89jNOEswbvA23tRNpojHh7xiCm/0I/5Xh3wPeeqrLknJjnTEpWTObF4RltHI2TnmGeRl79f7n7s1jLsjS/D/utaQ/nnDvEkBGRWZXV1V3V3ewm22w2TYpN0hLIpgybEiE/yE+0AZsw/GCINmWIgkSYMOABMAy/+MmARAsCLL3aoihRbpIW7W6ym5TYzZ7nGrIqp8iIuNMZ9t5r9MO39j7nRkZlVpt8Ke9CVkbeOPecffZee61v/b//cLUlZ4NxPSl7SgnMaYBSQ8ppL9lM80RQQWJT9P0prpRlnV6sME5rnJMjpcR+OCxzKSCAekifmss/78i54EdProbzcyNVG5nnZ2sCrQ0pJ7794Uc8f/GC7/++L3F5+QCdI9ss41TWE7EMKUXIOJeXl7IHKJnb21v+1t/6T/mt3/pB/sq/+b8kxMD5+TlNHXdf+8Y3ef7JJ5ScePTgAW89frpUD2UZ+3JN5gRbrRR93/HkrUcMuwNX14lcxCe3pIifBvbbzFhDb87Wq0XiGGv9rBHDez0H1HhQIaK1wVpRTuiSCIjtUBRNMNM4UpTBx3iCM6iaaiv7IlPxmlmJ9Pu5O9/TQBhADJBKIgaJOC0KnJNiURmFNdXQsT7oIlUSE7+cEr5ERl/EkDVbnLO1a0bVVh8fFF99llxjWW96LpqNmDenuoGqv+O9yEa0VazahraTifIuHxiG1w35jl25OQYW6gOuj5tQrcUHTWvxRdrvR/r1SrpTScz8KSLBiCWiq0zCWlcZvtJhmrzEhjvrWK3XWG1JWbTv0vmyrNaNUL+9dLGcszgjk22u3YsZgBuGiaYx8iDP8rdZhqZ1TbXSlAQJWdy991zfDFjbMhy8dDtjJkUpHGPtVGsjG/EYE8OQJa2wdXSdE6AsQ9NojHaUrNjeipRBJJGV2q9ninIkxcLsmakw7PYjhSLUTV3QTuGKJOA1jUhcRKLocM7WxIyBaUo8f74nlcjF2Yqu1cSUqjGwFMbGWbpeishprFNMTeR4/PiCl58ktnd3jGMklXwEM7No5mVMVBlPkQ1PUUaKK5VrdL0AoTlnhsOB9WZDrqlEM6MkxISagrAJG0cIkrwl9y/jx0RWiZcvb7m83BCDAC7WWEpWslAV6TaGJADHzBA5HDxd58g+Y9vjwmSMQmmhfmstRZoYXYt0WWvx5VJKMY6erCThJ2fZHtvqb+Ya2UgPh4DWECeRXTWNo2lFBrvfDZXFKexLKXkjMWS6vsE1YkLbdgKomTbhR2g7y7AXKriiIhEh4awWpl4Nypi8F6PTlLDVAFl8kTyFhpwTrbHs/MCql7GjQhHWzaqh6S1N27E6a7l5tWMaA9pqzh/0nD+Em08mfMxLtHSqksZCxsdAky22KILPS+cwxYxrLSkEjFVVXlUNqjWkACZpem05axvO2rbObwKc+drJOna/CnMqm4AuM0C1QPSy0UoJldXSgS7FEcMkhvTFsTCIZkYI87NWmUuvESLq/nuZ//q2Y6ySCUAo4Eq8qtAiV83kpSCz9mjePX+u3MqMGCzLMRvazoXdXOBCpXuXcv98lVp8nU5ZYLNMcvYfmD2XqEVj68ATjr9Tv7vRmsZZumrsHXNi9CMpi2H4qTtSQuZN6yypZFTy8n1KlrmlFrwaCX1oW/FCctV3CApNI/L125sD19e3DNPEejUQQ2CcJoL3YnjfASWhtJEueBawIGVIWbqyKpcTH4Zc17eB27st3ntpJjXSGRZjcZGa2QrY63rNUw2f0cbgMIR6LUuVc73uJ3NvnMwg2MlRV2WROQnBSPx4srAWv/8Lz5aAl9oZqBs/kWvmIhu+mKSpoym0zmCcliTU2l3PSZ4NSa46BRZKla7J2LqfbloLSAVt25NLYfLjInGbfbe0qR36KptslYETuW52x8621scERqVUxS/mq1CWR2tOIE1vAMJmkFLX6yCg8JHhOF+PmDNFH0GyVOTuL/LIquoupcodaviAUgJ2ylwpkgvVidZfGnhz+lZa5pc5zCSXQswC7ld0iRxCnYtBmQQq1vAZoEj9pnR9lkttIpVCDBIeU2rjQluRZQvrqSzz5QysKiVJ38bKM+8nLw3DeR7UVcKiNLaGDc2Ngk8fsmFMOZK1IaWMKycz3XGPzQxdKmMoylJyYDjsq/xeL5sIVeta7UDlI8PPWE3b9tKIS6nKqetcourmWL7gEbCtm69cjsy25b5SsHoOjZJm6cXZ/js+l/88jllqOM/P2phFTvl//5t/gH/3334pLPUictu/+bd+6HPfUxtPu16Da8mqIZGYpoGPPrnm/Q9fcrfdczhMYmmglby/kjTJrCPnK4PNiTEMGAdOw5A9m0axrvc/pEhMka51VfouewVnJTymKKjEaawRUDWjQJna5BbZL7nO+0l8/3IW8MOHUFkyhdZIOu/kfW2MUGswYfDEHGtTzFByXDa0EtQiYVzWKqb9UFm1lrY5AropZ0oKhOABzfXVLV//+rf51d/8PcbhwDROHIYDuXpcyVpY8NOIURIIdn2z5fzsAToFbm9u2R0OxFx48uwZXbdi2O/Z7nbs9weUUjx89JAvf/9XcLZF6d9AaThbr2iqH+hq1dH3HV3XcTgc2N5tubm54257EGPxGDFK0TcGcsJ7sYz55MUrXNPy1luPeOcLb/Oen9je3XJ7e8dqcyasnKJIKdZHUq75XAfO41Fk5nNj7ehHqpVYLuha02gtNYg1hs16hQ+BXTzQtC1UUELqn6ogcJLy2TYNbWOwdmb/d3ROEi9XfY+qAS5t29J0PV3b4ox44zZOkjJdlUnnOn/O3osgTMJcCo/feihA19y0bRTGtVxf3TCNIz4I82xu8ojUPUu4Szn6ZJdSxE+KIkxyMtM0EmOgdRZNw7KX1eJ82vU9NjaAZrsbSFlSF9PtDmE+iRfUHCChrRIJ/TSR2hZjHW3bcbcTyxXXrFC6IYxbSg7H+vS4bQbgmM8xz3nc+x4gjRjrnDy/WdROkz9aAZ3OTyklJu8X9lWe2YDf5XH6SrFYSccGQAW15tOdvWVjjLy6uub5Jy/Y7vc8eXhWGf0Caqoqh57PsZSCs+K3/Uu/9Ev8qT/1p/nzf/7Po5Tmh3/4h+n7jq9//Wt861vvMQwDv/rrvyE+0arw7he+wGp9zmq1rh5uStqM5dQSTioRoxS277BacxjumLyt9YR8t/1ux+g9XdsQg4Cl1lo263NQSliMarac4tgoVTWhVWkyYmmkbUMIgZI8YZrIIHuXuok3qipDKuBpjdTZS3VYjgFln3d8bwNhWoy4hUeS0GRsI4V8zNI5d0aRq1QuJZExBB/pGumQj142Llmre520UsB7SXQoWdgW1hpJ5SmZpnWcn6/QGgEWlKakzDQlpikIKm6FseCcZhxnuvrJUQqQK+JapKirZvlSfNeiT4G1mq51OCuG/cPg6fq+dnuEVk+p1EEvA0yMHCUFafayCd4zeenoUBfUKUR8lK5511k2mwbvq4me1WIqPPuq1IkkFWEihRhwRgoZo40syHMBxklXv0ZPi3ZXOinTJB4C5CIb+sSy4ZIJXaEczIlTfgqMYxDWV5TrqwxErxj2nuA9PnpSqBtQI5uglBEQLOUKIkkhfvPqwPmDlXRqi6SIutYKYyFXwKhI3K9zGmsT45ggZ4ZDwLWwXneUkgjjhHMWY9ySFDkeJomStnrx+8lJEigfP1nzyfMdyadqNFw3+BlwmslLYo/RtVtan+fZn8SPUiynKADNOAZSynUjK4VyiAIQu7apAIGAmvvtxHrTgRpJAdxKMwyet544pp2vEjyFMhafCuPgRf7UOVKWFLeUCq7RhBDIMVCUplsJA8zW7pCiyD0bfA2LKFWiIePdNZZhHIVh2PZYNO0qk5Vo69vWUnJhd3cAhHqbc6mJkRu8Dzz/5FpkpdYyHLz4VZV5obN0VYKJkgK/7UQOt9k4xoM8+wipAXKib2zdDAljRzasGTToRnwipilgmDd7EWUEMGtbSSrd5lzvs8iou9aiVCalyP4g8s3VWeTRkzOGba7eNA3GaqbpaNxclDwX1or8zRpdE2YSxWhKzBinwGp0ERq4LkjqolOcu4bztqMxGlVKHYfzwnA0iJeN6LxpLicA2BGITzmTg8wJrjL1tN0wVjauNRGtbS0USh1vJyA/M+BzLEaO3k+zSazc96b6lIRYWVtGL34/JAExClT5Gct7ztRyYQndl2Z/etMqnyeGr/fBlnkNOGWBnUoknXPCHJmHMiJZd6bB6gkf65pSQFuFs5JQ5ip7baZ0x5SJOS8FTVJqKZqE8VaNa+erVDtf1ALCNRKz7oyVxDg/0LQt1tZu8+HA9dWWTOHWbVFKVTA/YRQEHwUY0gUfhspu05SihYpevatSjNWTLZJSYBwPDOMkDAelsa7F2halZHyOfkRFuN0OVYaRqqxL0zQN61Uv5+8kSKCxYrT7+vg4rpMs687poZWSAibnBfacPT7W/UlakLVgzNI6LqVASnVNtTS2qfe11E0AlQGQxbdRqSpBmWHhKgWwUvDPQBjIfHBqMt62HcZa1EERvJfvUXKVFBYBzVRCF4RtdPI9azgzrREsT702pufxm9IRqJyPnI62BZ++ltB0wiiYQyHEcyPiUySVgn6tgBTmmYDBeQbOmb3B6lyCIiZJaDRGJE4hSaGa5+e2NiONTlAMuRhKkTTaZW7SGmWsFOUxgrKSwKvqGqJs3bRmyEX4vyWQFimYYzGdgRqYIa+PdSMyy5qUEs8xYYzp6mcmG+05aGORU9caZ5b7x5j51LSC1GA5JbJrMfbIWJyHRZmRinnM1v/LKTFOIyWGezLKUk90GX7UOcoYrGtlvQqxeoDO11CMquexOjOCtJL5KKWMJxzfsJ6YsZZU04nn91qvB/b7/tNf9J/x+AM/9Gq5ALJ5LvzSr7zDJy/WAPxX/+QZMcr6W/Jru93POLTKNH1lVimpkXa7A88/ueLbH7xgfxhqLaixjYQ8zZ9PifR9zxSk5tgOA12TsKUwBE8omZZCzIGQAy3C3rZWfImc0XPnqP5LLZvpVETCrrSlmh/eO29V50fZewRSyXVjWpimSSSLuYZY5+OadGxAH/1g5hT5OVBDG8142Ms9dkcQTD5X1UavBGt8+9sf8s1vfciHH79gGkdEGPX6NZZ/Shap3N3NLYeHe3a310yT59HDt7i5vWV1/oBnz97h5uolfd9RSmZ7d8f11RXPnn0Bs26IMfDo4SXWaDrnAFHl9L343+62IsGX4IpASSLt7ztH37kazJUoObLbHQjhBj8dON+seHB5zt3tHdM4cHe7pes6hv2Bu9sr4NgEzXWPB7L3SkmaikcwSLzBipp1PLVWOLmGxhqurm958eqmAqyx/p2wgVLJuMayWa9Eom8M667lfLOhaRo2mzXKGKx1IqF3DdY2YGawQVVygVqaIZkZrIkk8rKj10VqqYtHD4C6HiRpSBvbsV4/5/r6mt1+ixvHBVwXtdFIdgLwTaP47k7TRFZZwouamUkPzhr6tqnhISzsc6UNbdsyexDvRgHUrTV4L8zV1kZsZUNpozFieiH7252XWsa1aOvQrqXViobMLkko3MLoZ1YyUO9MraPq90kpUpKooebU7qZtWZsN6/MLQLG9vSOmiZJF+VGq1YY1Qj7IORNrA0saKMdJfKmTXzvy0mJ47Sjck9efBhAAi5Sw5MzzT15ye3fH5Vlbm3PHmnqZN+o/q77jy196l3/6y7/K7/zO7/Bv/OX/Oc+fP+fXf+3X+K3f/i3+4T/4Wd5//9tcPrikaTq+78tf5uOPPuLr773Pl770A3xxtZbvVWqifQpY604+58hSdo1js9kImz3VOrI2xmbG5jB63I3l7OyctruAqIkFjC1oU6SeLaoyZ1UleghLM4wDuhUFA1lkkCGK91wpCBCoqh+c0biTpvicIlngXi32Wcf3NBCmKy2+xCgFJSyTBShyLITKcsgFcsiELAVO2zXiIQD4oI60SsUyySwXtG6ImtZhbH0QikRfO+dIMdV0pIz3kiZmjHQYMZqSRZOdTga/2GyUZTFUQvuqN/borzP7EbjGcXbeCYBzO2JQ1eMjC3NGSfcn5cLkA7kaOK/6BuU0rjKzhnJg1a/ouxWTn2QgF01MQsfV1rBaO6aprTpbTQxS+JqqS1cgG6UoRtg5i49C27TMbKGK8QmoUSn9GgEprTXib5ULzkrsakCi7KvlBzEJGFFKpt8IzXE4BJSemEZfmW6GnCCOkd3NAUwi5YAqTjrnpnbStSImobQam0glEnzBj4EcI7RNNahHfJey4rAb8KMX/49qVK6U+DYZA5MXTzZrDYdhRGlFt2pRo6pm3pn9do9ScPFgTV83A/vdAVCcX/Qoo8Aosj9hpESIsTAcJpHqNoac8kL5VAqGIRBDZn3ecXdzIBdD2/YEH7DGoap5uBT7GmtE8uKndEw20wrvZXFvO4eiiKdYToQhsdINjTaUGMklYbWuk15hdzdxduF41G+4frllPwWc7qpMRgyoU5J0jzlkYKYsWCsylVgCRWe5Rygaq3HVuPZs5ZiGuLA4U5RNhzG20oYzV1dbLi43eC8yzXHaYVXDZCD4soBhxjUiGQiRMHqa3uJcqTKZQo4KPUuQKjjQ97JBjDHRoUWwWmSs5ijAoGuahRVxN+xFRlQ0Z6uOELxIcmowQ0qFw37kMExiEmsUwy7gNyKBPb/saXsnibZDxDmRb4EUZ8s/WgBkuxHmgq5zYH/eSocSGLdButZWVR8oAXWTkk5wScfuybyZBqqk9Aiqq6XVJv5a89ovG1Dq8+7Y71cM44g2GY0w9koGVX0z5rmt5CKFGvK9xOtHwPEZkIN5U00FxPQijy16rj0U5COzC2RjmaPMhdZVw+p6/5dJ/d6hln8Lc0f+PQNf9+RuJ4yzmcq+hI5UpkxOGatkfDorC/TcWTZa12jqWbKVZLMdEyEKOKBnuebp2oYszhlpOiiqLKOIbEzOT75oTKE+m9LVl9sqpqb7/cTZ+Rlt0+NDRBkHpixSilSKSGtVlGK0doa994yVAZqCGOBmZLMRK9AXU+Li8oL1eo21LSDMlHEUpu3Ll1e8fHXNbncgK42xDcZazs82PH54Sd+1nPUNzbrH1lKkUIglfPpWveEwn/F3Jzft+M+9H0s6kTV2MY9vW103LzIXmzkRtRbWQsGvz4NSNbnpO3/0qY+cNRasSDkpApRnVVBGYdCszKclaL7KWwzgTmUcJ5dFq+Nzcw/TyFkCgN5wflor2rbh8uGZjJ8okjwzenxNk5ufoeX9EDl4qhvzmYMWYiJV42hhoU2UnJgmL16iHGsHo47yTmsdzjYYIxKt109TGSv+dSlXSeAx3ELCVxSUen9mdqt4JiDzy+zVWdOqQqxesfleCIUqCqUcClNB57LI5aRunO/4ca7QRuosHwJtc18WOTcOZv++xlUAvN644waN+n4ypyoyYfJM03gPlBd/zdoxr00KrQ3WiPm+No6Y8z02GIjPjK0GyLM8fB478/iZGwfq5F5rpSXd7gQIm6bjZui7OzKfov++dvxP/8e/wn/nv/11uVbVB+Dr33zA/+Z/99+697q7O8ejR1EaUZ/BGj09jDlAkXFFEabjOEzEMBH8VJnjgC6kqKqcqFT1gyHnzOQjrhX2R8xR1lclcsesxL6hLW19m8pmgCovu39dU5yBxRmYLrM5071DG8vmbLM0uFOqwObJepSLWlg/MI+jytg8uTzei6l0yhlb72MIAhS/yauuIGqWF69ueO9bH/LBxy/Z7QbZi5y872wHIIeoVLZ3e779rfe5vXrFi1dXuNZx9fKKw7uBl88/Jk6Bw+GOGD1dJ8mcr1685KMPP+TBgwmj4YtffIdvfv0bPLw8Y5oCMU6EMJFTZHd3i9XSgFu1jTR8TxquMUVKjhz2W/bbLVdXL0khLDKqtu8pKfH8w2/T9ivCNJBSkMeq6HtrwzzHWjsDXPNmuiwAdilJLEkqa88YOY9hGLm6vuXbH4hHXcniG9xYYbqUavPw4PKc9WrF5cUZDx9c8vDBpYQjoEhVFaTRdG1PMe6N69c8Ao6SvqO36SmIn+reU/xyM/u91KrWOfrVSpQefVtTKOW67ndSvztr2N7N+1CZM9q2rdeEGlbT0DW2goZUULihbbsF2B0OA5fdmTTGK+s4pcyUPD4JyaPVDdoKW7tpLTmM6BKYtgOXT5/ROEVQc3K4ButkflfSfImnwFKtlmKWdSD6iRwSwzjUGk+kebkolFvj2g61DzStJseJuUNSiqhP5salKFbkGa5EpOPdUPfXX16Dj4/UkM8/ZrZ0KfDJy5d88NFHvPvOY1abFW3rWMWWXNSCISgFyijO1iv+wA9+hd/5vd/jV37ll/nxH//D/NzP/Tw//3P/kK997fd4/PgxP/5H/ghf+cpXGIaBr371h/jlX/4lfvkXfwHvx7p2WcE2isLPhJl65pIDVNNUleL8bEPXWAmbCZ5CroQhC0rIHOOUcC6Ri15YihImJuM8FUUqhoSw5GIqxJwxzuKDeGBTxHJnDhuiFFROtV41C+FI7AFOJL6/j+N7GghbigRd/TKyRMDmVMBV7XwQP4m5czmb4jtn6WpnTLpm0g2b/zndEBUEINFa0yKLQCmF4CPGilbXOcthOEjHok4Izln6zpFjQqtxmcsWxoVWzHtDpY1sQoxIO5RRNbmx4JwwjERXHqWD7iwaYWx1psFuDNWPWDyU9mONcNc07hgzPicjOesYvRftejZo24BSKJXoes3FZcvtDRwOkbkHknMmFhYZldaCxFK7Ca7K3WKQruopUwMFDkWpgYraCXsgBomjtVaTtPipzWlhcu0Vpe6CQ8iMU6m68oT3BddqulXDKrSM00CJwnQzdtZR1+ussiQvpkhjYb+LOGcW2c/6coPShahTZXRI5837xGHwrApAlT42ht5oNpuGyU+0rSRltG1DURLA4ENGaVcXCKGEep+4vroGLI/ecqw3jsPLQEZSSkvJ6E5YS42rm4gap51rN8kazXAI+CkRbw6s1yumIaFMEOacq4bQjaVtG8JSaFLjwxXnF2tCiDSNxvUiOb24XHH16g7rRHJRUmE6SOF0tl5TSmEcA9OUGMfAs3fWWNdy2I0cdpI600R5zmIUr7bpIBKVzeUKbQzDYRBgo8DoA20vTBanLSUWhulAodC2FtVZ8WPzkjAUQsa1Cdc4jE1styPruGGz7gDNhx+/koLEJ0nWK7O8QwAYP0xolTG9ZdNbfBTQ1YrBF5gaAqGBIqy9phGfN21hNrMfhhHvI9k5svdMXnzHtCkcpoExBGFTKC0Rv4fIfpi4ub5jdzdibYNrROY0eQm9eOvtM5m7YqRfd1X7j4D7KZFjJkeZu3KSQgEtG3GjDP2qwR8CfojyGeea8zom541PoYi0tUjDwBh13JDJzLDMa6oWXuJ/IddHYWiszFFKawHScqCziWmqCZRKgHGdud8Lq8U6M/usbkbL7Jd4z9SyHCdIKsiVpbDRtevKkrRY3ytVNlgFvVGyyUszi6sCGq/7QCybiAKl6JOCt9wDMWbQ63RzeFyDxI/F6hnsquClFQmFqpd2kX8liTr3USRoUK0emcs3mfraCn6iNXPk+LwazXHdKSdi8qisK/o4M4OzbKxDQCuNcw1nZxfkUvBZEYukyJq2paSIQdM1tgKcwo6Yu5xqll8XkdXlEiroW2j7jsZ1tF2LNoaYxXDb18SoVeeYprrxNBafJnRKtG1bfRObe5LU+VBaVzP1k02g0ih9vDdyPWZw4lNvcfJmbwDBUFglHoRW2zpG5g2Qrd1EgQuUNqBM9QustYKud+OIIy/nNDeC5p/Nnd3WOVp3TCwNMYERgKhXnw005HncqcpQqM8wRZLfSkpSVy6eRKWa/EZm2e3r19dYI0EgVgG+epd5ZlkwsEgIOX5N5vj5mT0aU+IwjOx2O1LdeGoNu92eGf0xWtM0DtdobKNoGkPbdPTujK4D69xSY5yyN5U2SOSyMDEyWRJppyTNmRpEo7UwYpVS6JTISqOqXFMaGhHvvdyLmfnDPNfJMxOigL45xir/l3tcCkuCnrFaGP4V7J7P9/T+A5KemgvFyPphtVnA1JPeZ/09UKqgSiaGwLC7k+elEZuOZSSW6nezsPMN1jYobQkx4sNRUmuMkQ1CTc26x1ZQMiflOnce2QwFowSwy1SGSSq8960nfOndl3z9G88+c4yeHm0bmabP9hb7F/7Yh6xWAR+UbC1T5v/50z/8qdfFNI+FEwnR5xwlT0zjSNf3pGnEIInMlxdrVquW3WG69/pTAFEpxeSjBMIUBbnUa1/HvoaiNaqIZYXKQMooXUhFgDClwFk9d2NQSmoLZg5PzlBen/cEDIypsN3uePvpM/GRVLrKRfMCRiySXup8Q14+a7kG5LqJrP9d5GfjsEc5i12thDU4j41SGCfPze2WF69uuN0eMNoiTQF5E601FxfnvPXkCeMwcnV1jULx4sUrvvb1rxFT4umzx1xerhn9wNXLV7SN5hu/9DXe/eK7dG3D0ydP2G53vHzxEj96ulVH168I08jV1RVvP73k4nyDtRDCVGlnkRQ8F5ue83VHChG0jBsfAmEchXW0veP61RXb3V7AC6WJGZxSPP/kY1xjafyBrutkjkupAsxHZpeMgfv3RfY7NZGVQsmJHArjJA3WruvRWtM1DZfn54zTtyijWODMSpq+7wjTwDSOPH32Nl3XEHOiKFXBJWk2zom2pUrmKeZYs8z3ckHUWeqSmEWds9vv2O/2jOPIcBgYhoH9fk+KiXEUee0wCNvRVfVKzhpFWgDS8/MVZIMis+46DuPEuu/Z14a/BNRB4xx939BYSfGmiLepMa7WjrLv2GzWdR8YaRsryoTKeJjBeGFUJ3zYMfmCsQkNtC3EwzUma3a7EWMbaay0bQ2oCKR8P/373t3TBus6tMu0bUNMuSqRFNrKPJ2GQfbf1qK1JaejKmMOkQgnNgN6aRAfj9dnJqXEc/ce2l3u/+dnHVppMplXV9d8+/0P+aEfeJcf+NITztYrYVpHSQqdyTUKSSlf9z1fePaMf/CzP8vXv/Y1XnzyggcPH/Bn/+xP8ZM/+Sf5/h/4fm5vbvkP/8P/gF/7tV/DTxMPLi/YrNdLrToDscY1S5q8qt95DnGRVEdN33VLevMwDvgwcbY5h2p8n5JYOaVUMKYcG+zIXJmyImRFjKIImxnbMYp1hdKlKhLuM+2FN1T399TkSdT/TyAYfI8DYbNxrVLHbh5KYkyNnrv8IiMLQWKwu66nqZKAuQNUkmFOizxlGoAMgFkqtqzDGfGiiBGtBfyZpolpnChZmAGNs2L4bTV+8ijE12caw9LRkUlAV3mOxji1bEROEX+KFO85Q9c0bNWBEAIr51Cqyhz6pi5qQbTcWuRi2hw7HlprGfBKEXLCh8LtrSS2nJ1Dv2pqI0+05P1KwJtxTAsrheq5JpNEXdzrxjRMsvFaOq4FMUpQBeMsYkopBngllKVxmFXBR/Ejy5R75tE5i0eIgICGMCZy1hxCZLcbuLhY02461mc9Xd8yjhPj5OWBCBFnxVC2aQUcCwH6FTSN4cHjnmkMQrlM1YC2JqDEkEnVdy36ROkKGqGbX7/Y8+zJOW2nOewO+LFw+fCcafJM48gwZna7SJgiXW9peyfIeDG4ZkUphv3eL+xCYxRN44SVUzJta2Rjpo4FtjGGFBKts/iQ2O4jwxBZ9V4WpBU0ncK5ZgFtHj4+F5mmVvQrx82rA9u7G956dlnpy4XNuQOtaKyhbRXRC5C1201QAmAw9kTHj+KtJ2va1oEyqIKw0IyqnXRh5jStMCKHfcCYwPkDYaERoVt1+CrLstoQfWI/jNxc73j01nmdMBWudcRcME6hnUVZhWk0WolsdbfdUQrCskqK3TRwed7TWEsB3KxTj5mSErrRtYsCJdUCUoFKYJzmbNMye8I1lRqek2yAhB4e2e49RTlubg8EH2gajW46lC7YtjCmxKqx9J2heAEND3cThzuP9zX90yoJJfBSiBmnMUZVj7kCSHgHyGuNsSQtGzvd6uOmvREm0fZ6YtiNmCrDs1ahTCGpWsbq6pw2pyMiBtilzFJbMMbV5y1XAMguG+KShAnaN+64SUVBGFk3sG4cUAhvYgHU7tYSS13uMzJSLmLwdHLMkfeLwXN928UYXAtITEGYZ6q+RWV/qDr3l9oRzUXA5FmyvfgDya8QY65gm6UoYY2YUpbU4NlbaS4652s0z0/iPSRsyFlmo7VZvNJmV8WUMlPwjN4vBYau3nAgi3HhPlN+ZjgLnlNIJMgFZ5wk5sYgUtIKuuXqLzT5wDRNuMbSta0A7RmapiNjabqWpm1xWsDIRsv5O6tRKdM1zQK2UBpK6YklMvmJcRxk3rIWo4Qdl3IgZRk3TdNy2O8ZhwMPLs/o1yuGMTD4gHEWazWvbm5568El47CHs83xfqgKxJojlCrXW9+bD2e2zrw5/BTUNf/gTSjZXHgXqu+JXONU5nshzAtquMLM3pHPTrJJqLVCxR2Xc5LEtbKwNOrfLB+9+G4lYRo1xpFKwXwGmpcr2nc0FJdNb8lJ/qnP8PxdS5GEvJLzAqKeHkarGhqgSUHk81KfHkGRUoGXoo5/nlFaAUUTKSfG0fPq1TUvX12LDyRwftYxTonN2tB3IocyWpi1OWYmQmXbZ7TONG6zyEDXq55pCgKMKUXW4su45HNUADikWKPjHa5x6HRk0+si5ruphMUY/3hfqqQoV/sFBcY2zAEfKYYKeMtACTESCpQYOdussVYLq9o5WmfoWjGqF5bncUOWVMOqaat3HwsLax6Sp3i6bARFwhPGAaDeH4XTljgD9ggoa2xD2zagHRmNrwqAeZyZCoDZk4buvAFZ5q0K0ip1ZOMdx7rcm//0P//j/Gf/xR9bzvPpky3PPzn7juP0OL4+X45yeeE51o5iL/KH/xvP+f/8zFfuve76uufpkwP7fcN/9rd/8HPfF6BppBmbfEBFaUBr5JmIcTbnr02G+jtaHVHtnAoWUEl88bSSNamoQlIKtMMWi6lgU6mMRaWkTpq9PmfZXYqZ7f5AiBOQ7gHoy6E1KEvX9Vw+eMR6c4azRta1XNjutoQk6dyZvFibUBIlRQHWcuR0pOUcBWSVD+Cw3TEOBywdKTZY9zobCs42K1arFaBFFlWBisaJVPHx47d45513+Pjjj/n4449pm2YJO+qajvEQuVUDbWsYDwfubm4xqvDrv/pL7HYD42GgW2945wtfRBnDt775bbbbPdfXN/Rtw2G/561HG7bDnhJHhhA433Tkp48J00SMsQK/YsRevVO4vrmjaxtC1vgsdX5KE7fbLTe3cHV9x3rdcbZZ8fith6z7bvHiLZ/DYFS1KThf01KyKMiyNAJCCCgUMSRubndyTUKoHqCJkjSRCZUz2joJm9nteOutB1ycbeo6lpd1ZIbhp2kiF18ZXrXxN/v05rw0p4ZpEia2D7x88ZLtfsduu+Pu7o4weVIUc/ZcMpuLcw7DQXxFzy5qXXFcNxRgtCGS8SGRchGShMn0iJ+creEcsw2KNgqL1Ptt15ESjGNEq6Oh+TL3IV5W0njIaF3qvjpRsvh9T9PE44vz5ZxiGnnr7AHDGMUrsHo0lpllWU7XV7iPOEltbUhgDLoqpZSxjIcD8KrOk8Iiabqe4BU5xeM5a0eBpQZUSmPUkSkla/proNfrx3Je3Jv83/QbArrKXO194MOPXvHxxy949+1HuNbRJyd7JF3wIRPj8V36Vc+P/cEf4cPnn/D+Bx/wl/7SX+JP/6k/zcXlJR9/9BH/xd/+2/z8z/8cnzx/ToyBd995xh/7iT/MD37l+xhqSvLsVW6Muwc+ifVOqXYwdllXZL9gcG1H261QxkJRy7o7W3WIUk6eoxAhJAl3CKFagORKoqjppdY5Uh3/qdxfU06Ba2HtFqRPOas4llXtO9+Tk+N7HAgT/5IU4sIQSCGjc6GvMrLDIBHbMciE1bVdReDFq6VtHQoIkz8xgZ6lagLcHE3r60XV0i2agaycqBJKmUgaJ4wtYY0FSXBxwjpzjSENopG2WsvG2Cja1tF2FuuEQjj5wDgeyZVaq+oBIYvXYQo8e9jy8m5HyuI3c3m5xhqHn0ZZiHUipEQoCRXh7KLFrBrCFPF7zzhKYp3Rrm74jl2mmBKoQr8SpsA0iqeKqX49GfEfkO7iMSo9FikGZ2Ng8fgRHbeyDbYBNYkpobaG6KVb228adncjTaNpGs2gq29wEb+QlGC3G+S6WbkWT55dorVmGEf6lXhluMai95JYkoKAN/264QtffMgH3/6EGAvjCE2ryMViG8NuO6Kdod/0FKSLu1q3jKNnGCQ2N/goxu4F3n52xngIQMN6s2a/OzAcRowztG3DbndgPASMotKiFZMPpFhomhXDMLK9G5kmkVaUommcIURRt4eQ0EkSBsHWeyP+bqOiPuiZvhMfMnduGceAdY62tYxjRdAjqNagSuHl862EP1jFdIiMJcq5HkY2545iCq61bC46bq8H7u5G1uuOtlVM42xanFHWsl5ZtjcDhYGubxgOIsvwPhw3/KNIbKzTC404V0aTUYocHG4FOQjbMsaRzVl/lCaiqjmlpqBo+pamtbRdQ/ITFxdn1Wi2dvOD+GCtestbTy745PmWaRrJWQq6Zt1hNcQE/hDZHeReFl3oHzZsznvZ5BhN1xjaTkC00QdGLxKg3d4zDOKB44MI/R51wq7xscqFihJfEgrGVZ+hJF4sTdNQEmzvRqzVeC8sv+68q7G/dYop4m82AyCNs6hGcdhNIqflSHQRRirceQEvH11uqvRVC8CsJLVw2SRTSFr8IjJ1wcmS1KO1XjacpkprZq+r2Qwbjh1pmOEXORqt8Fmk0KrIxlmp2UNJQTkGZpweYuQqf7ZWL382Gop5U6mglkJBOQUxIanyYiA8z9W5bpoVCp11ZXfJ4h3jUQKVa0MdXSgaUi3cDMIC0Mh3n431Txk/slHSy5+Lku6xMIPFFyTXTX+IkcHfp/G/DoAIHHd/+V7ACXEEkSaEMhTAp4RRpgKZAkIpBcM0stvvsUbSvZxzlJhZrdd0vcSfo8CkSGuqn6UxdM5gTe1+FwWqYJXDWCchLEYYUVpr9DAy7sfF1DsEj9aGZ0+/iJ8m/BMvjagQhbJeDb1DSAw+8fLqBY3JC4tqtiQ4PeZG0PJnqL5WwlwJc/GuKmMGWWeXWvNk838yeu5/Rr2yo5dNbGtUZYkUajeEnKJI72CZz2aD7xmUK0U2M0c/vPkDq663pOXz5JwMey91x6rrlu+vgHBSgM5jfSn+srBMqDyqGbAsKaNM9a8KkWnynzKLFZliTVXKAsCdXh+tFDHPvoEn13HZJClB1kkEH9jf3XJ7e8t2u0crRdNouk5zcbEmp4FSBmIsTFGeM2Ml7ZhGMabMuskYIj/4xaf4mHjn6QN+7r/6TXyRuUewhCw+e84s9VkOcn2maaJbdfSmr2SbsqyPuYivUphqgIUSADIlYczNr/XTKOtWDHIdKxAk10tudqpAmTbC4JCgISrju6CzPrKrCjR6Tg+dxxxLx/0UBBOFsqz71oCPkbZ1NI3MAlVpRwxJ0rAai2tajGuJGYbJ12ckoYs0VtrGYo2wZ/XJuJl7CvO8VPHVyooHu7BppYHwu7/39r2x892AYABtGzgM3We+5nzjiWVmJ4s8+Q//+Pv88A9d8du/83B53a/++hO+9vUH/Pv/wU98V58NMB72+FEzHAY6C6XKaK5vduwPozRltKnpf8IYvly3XG33lGIxutC6lpQDVjusKjRa0xpLry0rbZEohrQw62TzWnDGkLM0K2bgfk5CXR6zGXOZH/EqDS1kVn3PZrMSsNXU9EAlLGNjpHGfKkgvi4WlWFfXHVn/5m3d4eCZg2dkfYNUZr/H18DKur6llAne03WdhGUVON/0PH7ylM1qxeO3HnN2vmE47LnY9CJXXK159vQtLi7O8FPA+8D55RnOWV5+csVmfY5tNtzubtjuI304sD7bcnF2xn4MfPD8JXc3NxQKz54+wNgJpWrKXNPQtB1FGW6vbrm5uZU5usozpzhyfXvH2c0dN9e36KJpu4amcwyHkWE/En1ky467tmF8eEnTtDTaLAzd388xg9iz33MIApyrrFj3HW8/ecQwTaSYuLrd1sAEWSN0fR53O7FMubk558Wray4uxB5hDiIIKVU5tyd68dcV6aL8vNR0wUyu8sdM0oYhJPw48fyDD3HW8vTxQ2LMDMNB0iWNqfd1YhxHAdSKAFHKGPGli4kxBVDmtS+uadsWSiU0lgIq4yw0raS6yJqplr3z0pxknv+OjStTWeefWvANtKuWqaa0o6B1jtvbbb2OR6/F+fNeP2ZwbKk9tchTvfe1SSD+XSl4gheLHa0V1rWs1itKTiKhHkdSENsJrSW4TFQ1M4B8r0q7B8gdz6X+LKQ6eNJrfy9TxfxNVN3frVYbcharpfc/+IhvffAxX3znCY2dG6Nqsf1Z0h2VWHFcnJ1jjeEP/ugf5F//1//7/OzP/Aw//dM/zS/+4i9ireVHfuQP8JM/+Sf5xV/4BabDDmsdSgsjfLYmMVr830I8+mwVoCixlJBUeMXMjNPG0BhRlaUl0V4kqKvVihgjh+HAqluxVwZjpUbyIeC9ANzi83dkoKUswYMKsMYuTG2N1BFz3Sk2HZmYFI2zaCVBd/Mz990c39NA2GxeK+aGMuDG0XN1tePmZi9msWUGkArWCTsrhSgJcpX2qLUW6nKWCS6nLGZ8SuGcdAC1bUVec2pAq2E/HEgpY40k7aXloRF/HjQ0XcvKZ6IXnfY0yobC1snUWmGEtZ2jXwnrYhiFfj+NlZ5ptDCdhkzrtJg+BjG2TaPncrXGaDFvj9ELAIhGmULMEVMKyrS4xorHzKGwWVkO+4bgIYYsm1Ct2G09wyFyOAS221B9NBSlxqu7xi2LeinlKJfIR/POo+Sl1MJZJtA4xcpckK7WOAZ8gH7jePxsTc6Fm6txwfRDyOzvJtm8JtBGClmloFu1+CnSrTtsaxh2g3g7OFlw9pU2uz9MfPDBS5quoWkbYhHj8ctLyze+/hH7u4lpCFy+VWg6hzPiB9d3LSmI4fvUatpGcX0zcnOzZ7NpCGFNv3ISX05BF8fkR/FmyYmMJkVFyeJ51jjNfj/y6tUtlIbGKnKnaVtHTvDu46d88MFzpjJJoVJk8lVKNuNN15BSYdW3oHYYbTm76Dh/0NVCSyanaZJ0IdeJ59Zw8Oz3E6t1w8Wmxx/g9nZLv24w1rFa96xWLbd3O1KScXiGTMzdquHswZrD3cQ4RMYpcDgkDvuJvm847D2rtfhiiXeS/OJq3ZKyAD1KGa6udhUciBj3QDT6MXN3I8wqZzV9Z2mbBmUs/aohpsJuPxFCIqURo1c0Zw7TyPNuMxXIFf+hEgMlS5KptorsIyVBt3ICQBdFyPDyei/prUrRrzusEQN+VQqrs45cnytlZdyOh8Bh5xmnKL5yWRKgunVDCIqH6xZXn5GmaSTVJGem0TMchInaOEuJRthYBXwEvw106wLOcL7uOOwn3npyzjRMwvhAk6vXgaEs1PUYU5VsGNYbJX5300TbWM7OWmGEKRaA4XUKgjAiRHZtlF48kuZIYxBWgdRwx00UUMEMof13rlteP4PiKYok/BR70EqMhFMFx+8fBZjl6d+hezNPBnMfQmvabkVKkXE4gDJkpUFFVJaQBpHRVZClet7M7K75ECBMUoatU/iTuT1REAs/tRRB83y3nFY+dosLwi6i/ntmrswdxFQyoRYIpyyE2dhf1qo3f33mO1Al4uaebL+IASkiL+v7FY1zSJLWxKo/Z9X3IrfVir6X+PW+71EU0jRAnGisZbXqWfUdWh1N38dp5Pb2GpTBdT0KWee8knU0hkDXtkt4ytzNbLuOtjtuhnOpCYnVt0ajlvWia7tj4uKbe6TMuNQsWzwFmgoQa9E9g0NHYGx+UalX8XjdTsfbDGTO0mGy+E0uAOcJADozLxZTXua1j+Uz3iRJpP5caS1s1ypny6WwH0dWXcfkvZjrf+rc5v9I5KyOctplHCADMst19d6/UXZqjKGr4H1TfTUaZ5fXFuYufE3qq/4wscyG8+LhkUom5dmz4wQMd5a+b4SVWdma1ipJyFTCpHLWVEZYgiJePcYafvT7v8hv/+57pBD48L1vcqgyWte0ONfIul6fxcY5rNHEMRJ9xJ0JM0yC+HJlhVbZUO3ka6ehCOtLNpCSFjhx7MDLrRdPPNlENZJsCkv6q3WmXvvjfJCShKt0pmXM0lnXykiCslL358N677QCXZ0lUsx4P9K1jdhN1GOxOdRzA0Qvnmr5ZPMl7CMJy7FaVS+6OvdXoG0Z+5VZcp8hlklR4xpqsEHhnXeu+O3f/eIbxvFnH30Xuf6c1ygNJcoOUFWJ3uVF5t/4n/1T/vJf+anldV/7+gP+0T/+/Z2DMdB1LT4EHl5ecrh7xTR5VquOs82a3UHWr1wyIYs3zdU2g7b0656HD87Y7T9hc9ZhtcF1kbfOL/nSo2ectXNogCBbShuUkbTSUsAatYBS81EqoHkPk9YV/1IiTZNZI7Ne9dzc3PD0yVuAlWAadLUjsFjboIN47siRKcWTiyIWFoBLAZt+BVWFQckMh63IDZtPy1YV0DaOi/MNF+cbVv2WlAdydPzEH/0J1ptzLi8vePrkCR9//DGvrq45DBMPzgx5/4opbvHpwPn5GaE3HLY7/EHUHz5BiJLqWHLCGMvHH7/i449eACKBbBqLD8eQiFOLBq1NBe8SReVqh5Bl45wSY4g8//gTVJFgsFyKNElz5urlc7rurCpKCmcbSabMMaGcsC5nBcpxT3O8c3BSPlWkQuYgmaNLFm+/kgSwefftp7z7zlNutwcO48gUgjTBU+QwTljn+OCDD9nvd/gQ+OCj53z9m+9jrTDugGrlU2sbPwpuWp9Vow3WCXGBKpu1jVgTnG8MTdfxh37kh7BOzMwpME4TXdcSQuBsfcZ73/o2v/t7v8Orq1fEFGQfqiyDFwklpn3j+JivRfW3l5JMi2WP+KQFdrtdZc/NLDuFWGuU5YqWk/e890gYdUw9rut46xpKUdxuI0of67eZ6eqqV3RM4m88j53Ts5Y1rSLR9a/mBoHKiRxGQhzFU/vsjFIU+1iYcqyEDqnhrJXvk/KnG3avH6XkhZwDs8phbqBybz0oJ//o+t36biV/l7dsdwc+/ug5L15d89Xv/wFKysToMVphjSInRUxHK4+2a/nBr/wAf/9n/gH/6r/yrzCOI+fn5/xr/9p/jz/3536KH/nRH8U5x//1b/wN/v7/6+/y8Scv+cGvfhXrnAT61GsnNa8EyMz1Qc6Qq4OtUSeyaQqUyPQGlWrTNPjJY5WwWGNMi02ID9PiaSeLgcydISYmP8nFKgGrHNYYQhLvT61Omd2ZkApam6VOl/A+S7PMk599fE8DYdIdF2BkHvspZXb7meInP7NWi4+OD7iuIQRPf7YmeL+gllqLUW6KqU7YmbYxKFwFPhWmGuNn7yUpYWY7pUxIYnaJmjuu4sGhNBRdMFktCYFybtKFb1pbmW01Za4VOnupi8B6IzK9afQ0nUVbOPhA1zSsz894/uoGMTpvuDjruNysiCFwczMQQubuxmOd5vxcJHPWNZigcU6zDYFh8tL1agwvr0b2u8Djx2tyhru7Y0fZWSMDdwysVj1d14AqjFEenPNzMcrPSUMx0rWoYQO5eiIUPZGLMHdmg2qFFGrOWZ49POfFywONa7AuyAOTCj4VmL3Tasf/4kK81x6//UgSUYInhoBtDMN+wk8JbS2STCWJeePB8+jxGWd9pfYqxeZyg3It0yEINXeKrM87VhcdXeu4fCAG1N6H6gWlaVtLziweaU+ertnvt8Swo+t7uq6VEACEDZWyUHrHsTDsR6xpePHJDf2qr6weR9cZYhxRSorUrrN0vUQShzFIwlnXUZIwWVQWTfT63NWFOuGs5flHt2y3A8Yaop/wJgK6bn5aghdWjtaSOudjEJ9HZRiHibZxNK1hezfiGita7eRpVw3aSvTz1dWeGAs+FNbrhsNhxDrDdnvAtY6zyzVWF95+54LDNnD1asBZSwwRaxzBB9q25bAfuHp5g9aGBw/XsumxhsMg3l5N67BWUUpimhJ2mLi+htYZWqXJpjD5xNUrifY2VuEjHAbxxlmtOlSRjZDSnskLZTtM4qkgK3EkhsJ0CDx8+4Gw+tbilZdiJB6SJKHliLOgW8vhcMA2LXFMNCsxpu36NSjwYaIxBopIHZ0D5zQpZEKp3YwqFS4Ig1W6H4WLsxUUMJVRaq075sDVYIwYJN2tdbLhGQ6ZtjM419B1hilEmijMrkgScF8fi8vZP+g0/nk2gM51kRGfv3BkRWCXhd0YQ6e7+nMBuIyuPj4FFIGUale8HloVnM0YrVi1q+VcQqrdVDUDKIbWre6dV8mV6TJ7dSCBBvvDTS36a/IMGrSjKIsqAXKkVBPxxUssH1MgrdXiS1CkME9lFjDWz67ek0gtsAD9c/X2pvjsXMeUWMvMjBop2ENN8ZNN8exLNnffpKGTTsAUOHpMHNO9DM7qahQsdH49jHx2AAEAAElEQVSnbTW49ljdYq2lbVqmEImpcLnqWK8a+q6hA0LKFG1rIahxjcM2is1mw2a9FskVRUBrCr3v6ftOWEI1NGKaJg7bAzkk+rblbLMi5oKfRmK6DxbKeevacKrG9Ee08d5R5nJQ3fvh8Y+fV32e/Eqc3yYLnCz71jkZTqSR+kQOk0KqXlCKIWvszJSpwFhGiumS6w1Wr53c552TEhbHKYvs3t9X5pt17t7PloJdyfeYfdGWQAsE9MjVJ6wUkRncSxCsR9s6NhtpephqmTD7oLjqjRZTljEy11P5OGfMRuDiDSHNwmkKwqSCmtxU5RIUmkZYSyVJKmZrHU3j5PwrSFwybM5WbFatNPzI7Ld37PYD2Rju9ne1FipimO2MMNO1rK1aKfq+ZYo7Hj9+RO8ull2FXoIOhJUzJ2SmJOlTOWVpXs5gU625mr4hDZFTzzUB34Qp3LbNwm4AAcHGcZTQJN1SVLWpUPOmpyzMHPmc+s9JjZ5Two8jsViMlDuLd5UALBWIr8oDmdeOwNapr+Ex4XQ2bRcQTCGek0kws6WjjoK/9r/6Y/zCLz7l3/pf/Cb/4p/+dSiFZ09uvuvxPR9d5zH286WRy+avHMHcnDN/9++9e+91737x9rsEwo6dksyaxlpiVuzvbjEqc3m24gvPHpESfPLqjv1hqqmfmgwEZJrfdD0+Dlycn+Gsom07Qtlz1vY4ZINbH8Ba12aUNmTSwoBR2khHCECpKsmMn5rACvIc1Lh0MJ2s/9Zwe3vDZvO4/kr1qDOmsh1OvMCKeBDmKImS1KaTVgrXKAmgSoliTfXzriO3Xq7X54iuazjbdKw6w/WtsBA//vhDHj6KNI3lW++9R4iRhw8u2V+/wulCu1pzd32NbRp248QwjkxJavrt6OlamdP2+y3DGBjHUZpSOdbE+aNtw932hpevqmk8MPmRru2PUn5r8ZMnRE8qibZxdNqSc8QZqetLKqw3HV2n6Nqv4oMAjCUjCpTRcyhSR7SdPKt2dX8rPEvYZzy5lHRvzc9Z0jhTKuQoFzPnwsXZhu3+IM1hldGNwXUN3nts23B3t6WUTNe2bNYrVn3POI7c3Nxyd2foup62EcLCk2fP0Fqz3mxqQ6ChazsJGmma2lRwNE1T59zKKPoO/UQKhCnw67/5W9xtdxJ8UgrZi/xMK0U2tq5V3F/e1Ot/FnDdGEmHbNu2StiNGPLnfG+cSilZWWBL8+Y+61krS0bWkrk0iN6jlRb7lSLjHMTLs2k6jHU1MVuTpv1y745NCpkv/Ym9Asz9gSh7cl8xssZRfE1CDoHkp8reP07W1jY1mOmz1/4jEFZ/UIN1Ut0D8BoY9ub3KDWEyPOt9z/m+YtrvvpVy2q1IYaJVPe1kNF1DMYEq97yR3/8x3n/g4/44OOP+et//a/zU3/uzxFC4Nd//df59/+9f48f/dEf5e23n/Hw0WO+/o1v8JUvf4m33377CIQpqe+xc+Kx1EKxWKpWAlUKWt0v4o7BV8fj5uYGqDWXNjjjJLAu+hMQTD50tn6Yw7vkxy0hbWncpgKfR+We1CaCMyiQRqKp/pjWouOnm4FvOr6ngbAUC4VImr0ZTlhK838IS8Nydt4xjuI3YY1h2u3kOdcaVSOP5+KlVmooLbpna6RtVyqVPpYiHQUrOummMaLvLoqsdY2/lcIlJokXbmpxEuPRPysVmKbExYMV5FSNC8UkXxKfxISaUuj6Bm2pXXfZZD1/eUVRipAEAFo2UwBaESfxPWt7XY3fM6WMlbGluNi0JH/GGAsxK9Z9Q+Mc45DwU6ZtLJOPhCDIr3RyJWHKOYNdcubl6e6ceK/tDiNFiSxOR+mAG+dIQ5D3aWetXKbrHS4VrFK8fLUXP7fJU3LCWlGmlIyw0gqVHq4wzgrVO4jJYy4F6wy31zsOw1QnXvHKcK0RA0aj2d4NnF+sKBzY7SbW6471qmd7N7C93eOshQyuqb/bOZGv9RFFpGTwU+Z2O7DbRqZpoO0sfqj3OwyUnOl6i2tcvZ9ZmEF+Yns70TgZUzklzi/W9J2YCWoTUVoWVPGLkmukjRGGU46s+w3PX1wBgv73vRFfJEQ62nYt6XZPHBLtxZqzC0kgurs5ME2BzWbFOHhClOjirrWsV2tijKxXK2aDbOfsUnALo7fw5OE5d1c7SVw0iWmcsKbw8PEZ25sd682a9aalbR2H3Ujw0knXpnB3fSDEyGbTE0Lk5ScvOb88Zxo93WrDcAg8vNxgGsfhestZc1Ylv3XFyKGagkY613JIAVfmxUkxDJFpSrStpV05+nWPJhEm2aCkKRGSYnc34ouwC/tVS6pguGvE68A1DZYqdaqm0qu+pbHV/NFHxmkkBkl8VFbRdw2HKdJ1FqNE7jsNCWLET5Cyqe3/Kp8uihSTeI8pxXrVAIqubSVko5FwBGMLVhliEHPtTP13zhjToI1iCjKZPLrc4EsgpMxhqkCgM3NPE6WUJLucLFJai1m4RsCvECMmZ5EAUuXNSTa+qiS0sTS2kTAG5+pYOcoUU840BaIfkKXluNN7vWw4Ms80YIhRQKNxnFhkmHU+jyZhTU0LUuLH5ZOEkkwTtdCWedWngDMNYzRQPFpl9CwhSInZBN1aizEQieIvwP2qZGZiLswcwTGkMfAd7CBCBf/mtN+5D5orm2Z+G6OPHbyCpELOm8J6cQikBYM73i9hYzknqXFWn5qsZ9rWsl6vyMAwTXT9mocPH3B5flZlnQJmTEkAsaxKBcNWrFdr1quexjl8Ev/CXPKs2qGg0Ea8MnbbHfrVFednZ7SN47x3jD5wnRPRi5HuTN3/jgbX5fX//A6FpUISgPW86avMrFpNpvSdi1IFi5eKqhK3BURQmWLMMQ4dUPmEMaNmALVwvHPzTSrVI+Q7H59mhSl8lPS7rm3J/v4moHVu8YaZjznq3Sqwp/wzpZeuu9YJUxDAqZ5mSoHXvVNWq44Hj85pW0uYQo0hPwmEmCWVJyDY7LWRC4unolIFlBQvkhIpBWvXShiAQtK6u5WisT2gluafpN4J4LdqHI2znK/XNM5irOLm6prD7sB+P+BjJHtPwBJzOvqSTuJZY51l5aoM0HaM48S6O6cgLIGUBFwwRiT2oYh/oI9ejPNPpY/Mt3aWHWtUUWKcH6M8I21D17cS6pMkhe1u2LPZrAlBksJnxtXRgL56MGY9Bz+efNb98ZJyIuVIKrD3oEPGqFSToo/nGJOk5CljF7BgBvkXOZCu30GJP8/CtSyFrETqnk5OIHjFL/ziUwD+T//nH+Enf/KXKKXw7Nnt68P6c49/8U/+Nn/v7//Bz31dnj3+qi/ZNO6wzvHN9y7uve7v/Zc/8Ps+h8PwFkpPnK96bN6Ts6JrLG893LDdjYSY6LuGUIOzXl5vWTvFFGGaRlqnCVHRtpZV19A0PeerDQpIlaUwg+RoKEUvbK+UQUICjyEnQGVYfocTrt57Skm9EXyo7GmYvTC1UriaSmx0DQSbr2VOCxPMasuUMgnY3g0CnVcv35KhZCXN5RgpPuCsq/6dipTAoDhbdTy8XPPB8xcYLdYxH37wPjfXV1ycX/D4rcekrBl84Wyz4ez8gouzM25vr+m6FWfn51x/6z0O00QEvu/7vswwDKSU0CpDDmjD4nWq6t7CKFh1Z3z5S+/wzW9/wkcfv0+KmcNwoGkaDuMdkQnbZ0xvUMpJHaQdOck48lNhtWo526xZrx/h/eOl6RRjlMbIbEhfx9/Z+Rk5Br7T8fpcWu9KTdGVmtQow81ux29//VsVIMvcbPeQEyFDDEKeSCGgNWzWPbvdloLi8VtP+PL3f4XVes16c8bDh4+W2uPYBDv++3XmfC4zA/qzngo5nr94SYhBPO+isHGbviFGWQsnnyRa4rXA4U+/dakJkbaSPgxFFdq2ZfKT2AEdX1rfrCyNqNNjbsZ8pyMXCUlpXbvUcQDWZqxSONtITRhGUppD2nRtQIiy4g1f4P63KWLR8fLVvkIAhdcBnX8eR0hgtdyvN51SKcd1XClVA/c6bu9u+eZ73+ILb7/Dl959G2UcKnjZ+2a1WI4svLNS6LuWrm34yle/yn/8H/1H/PRP/zTf/MY30FrzR/7IH+F/9Jf+Ev/Cn/gT/Od/62/y3re/zZe++MXq31bfS4FGUtKNNXWdm2/mp89eAY2W+vJNh7DJIygkqEclKMcGwTy2czlRjswsPt3w0auXvP34SV0P5XfEcL8se4YZtEsodPPdscHgex0IS+lz28SlFMYpsN9NdL1jHIN4H1kYpsg4ZNq+XSaXJVK6mtbP3ikpZ3KMi8HmMBzIKXJ+cY6x0r0PPtQNltyUlBIhRnJMIrMxapn8589yqwbjWkqagbDCfj9x2E+knDFGpHP9SmRuSoEPkXHy+BBqomBcJDbb/UCKBYNBIcVuDJncwmEI5F2hcZViazRN3zJuPatVTQBpDDkVbq4HDrtA8JHt3Z4Q4fZuZLVqGA8R7yMxS8JDKpmtArXR1Zze4X0gxhpAYLRMvk66r7v9wOWmF+moyqzOWpFi7icOe884eHKSbou11aj0hBmRi6QSNtbgJ08OXr5LawnRV3NhXX9XUqFkQtHc3R64fLCh6SQcIOWEcxpFw2rVc3e1I3ovrJaU0QrOztdcnJ/x8pOXhBAxznG26WgcNE5aRr/3ux/w4MGKlDPn52u6foV1hhgK5EwpDrd2RH/NOE2sVh0hRPwUONs0nJ05htETo6ftHBcXK4xRHA4TRQnIF/zIPme6rsE1jrbTVR+dGGdO6hTZbFbklDCmdqOrZ0y/6qtZbGG1ki7Set1xGAZhaznLNASMLXSrhoIYSJsi4Nz7H7zi7KynmcQT48OPPqHvDdM4ScxwSigFLz58BUoRfWIaPTFmGbNjQhOxJpGy4urFgUJLCJmnzy4YvTBnckrsd3uU1sSYaDsnaW4pEQ8T3sjELKlKitXK4ZxhtwtMU2A8GNm0dC3TmJm8Rzkl8kafsK3BOcPDx+fcvLxdWKFUE9LtuJXxZK3IhxoJlphCYtU7tDM0yjEdAmplpLNck2Xmane3r3IcZRYZhG2zWAQkYbK5tqNxiungsdYwDBOrtXSFFcICUEUxHCb2uwGldPW4EeZK41rG5EFZQvK4zhBSZqyeW6ZEWssxBe7Ut++EDUJmSaabGTDLHEWGIp2mGEWrr5QAMq9nQouPidDaCx5wgKmdbwEXZE6uhQblXhEUQmL097nVRktSW9S5+htJBzkMB4zraF+TeVgNMe8xraonZwErLLjgMUXo02m2OEBT0FjTsgSNqHmTL6Cjq8CgSK0y4xjQRdFYS+vssgTFmi6X8+wpKUCnzklCELIAMkILTyLLqAYRpbI35FDkEskUnDKVeVcDLZzDmtnclWXzXYr4fllj2O73xJQ5v9hwtlkLuM+xHpWABOlQRnUsRLUSsF0VuTjzSDDGShS4Ek/OaZzIpdA0lsvzs3kxE0kwqvpkVWChKJSev1upQQdvPt4Ehr0uST0y/GpCqdYUNafuVgbyDLwYs4Q0HC+ANJZyKeIZxXHcayX+lzFIX9pQmM2mdWXYzMyteTP1pkMA4vtgQymlevepCjAqjLWVEsMb28O7/Z7z9boCiiKFoYYxCJtDGl8+Z/LJr8ckwEyp5+2cE6a5qZ+JNJAk7GdOKavPY32POZJcV4AbcjUnnn3JaopoTbNbdy0hCnATg4RPrPuWy/NzfPVwtVqKautEIpFzYb3u2Gw6YgzcXt/w/JMrhsN0kpSaa2hJWuYvlRIqRYpe4Uwr8vSLM2xj2HQbmsYyDDvGSXxwXKchaAgZmw3FzWuVOpHk1vuUM4fd4VP3U+qHFqtlA+mcwfQdKYpX2jx+BC4U8+tUAqVYKmSJKkdJKwhLQnqshSl4Yjl6JSrEB25+buYufM5i/q9MJlX50alcaL6fukrq/skvPOKv/rU/zl/489/m3/2rv3kEd0ttMJXCb/3Og3vfN1Tp6Bfe3r1xfH/W8Xf+yx/73NcsHn6CmFNKFumftby66u+99nD4/W9Rvu8LH9PZJzTmJHEPWHWWr7z7kMcPVtxsxUajaRw//JW3gcIYNF3fs+pbNCNOg9VewAJrQYlstNSNuDQrKzPoHluoNngqcD96X9k3nz7Xig/I2MnS1PXTJNhYEqkr8zppLQV9D1ArFeAVNrJaPuN8s2bVi/y6dPJ7UwgEn/E2sz+MuJDpulxTfBUxAGFks3b0nebZ4zNSzFxfXZNT5uUnH/HlH/gBrMl88dkFf+iH/ozsiZQlR2mUvfeNb/Lx849R2tF3llgSh8OezfkFq/WacRyJPixgQwoRlQsGePDgEqULv/qrH2AawzA+5+Lykn61Znt3i08jyoidg6SmWqxraJsO7wubzQalNE3Tcnl59LPT1ddY1fG+sKcA1zQY59BGk4KXxkndg2tNzRvV9fWzZ/N8A8Q4fJgOWO0IIfLJiyt+79sf0bUtw+QrSzBXJmekc5rHD8/RGi4fPOArP/QHePr0bdbrDU3TfiYgdHq8ae35LIbR+++/z9nmjPPzNV/+0rsMhy1+OBCjr+tekSaksUv9eer/nhWL7cl8BZap6eSchI1j7zeCPgdPku/y2UhVKUe/7LmBmE8Aypxmnyxdp7X51QKG8V18Rs6Zw2uJsqi5mXess777o1oDGEMM8r5Gz4E389mdjKbaY00FnBVQR1cMguL45rc+4ge+/JwH52tyCMtNmL3C8vw1C7Rty4/88A/zq7/xm/wP/uJfrGGAhqZt+OpXv8q/9Gf+DE+fPuVXf+VX0MqwrtZKTSNA2DzORYIrNYvIXxPeF950Gerj9R2Pglg2eCsAXkqB06TbOdl99hg7/XnfXHB5+RQ/7uV5Kmphg6Vc6nqpaG3LqjuqTr7b43saCJvNaT/vyKmwvRtJqdCtRepYAGc0h+BJSmHbRnzCnJVHuEhSYq7GxyEmCpNsmJUUHV2/Zvag0ZU9YqypIFiunZ20POilHI3ngKWAMtay3qyIRZGGQIrSDQ5BtpSdroWbPprBnp+tmSaRDz68EOBDzjUxjJ4QZFMiEeJi6D/sakKWNyiEhWVbx3n1zhFDaINyspAPY8BPEYwsdOdVhnfYZYKPOGPrgC34KbJXE2ebjn7V0a97eShUTVArouW18iNCKPgsngEvX93x+PEF19d7vI/VGBcKCZSoxo02i9yoc+K90fUt/hAqii1m9A8ePcR7iV9digyjSchm/vLBhpwLV6/24kswTeRGfE32d4m+b7i62jMMAec0Z2cNIQxs70bazvHh+3dEn7l42LNZN2zvtpyd9zx+dC7gi9PknGhXEWsUh21kt53wIXBzdSBlz5Nnl+SUePTkkrubPaUo9odp2Rw0jWO9klQ4pWtse6spJRHChDKdmH0fCvthjzHQtobhIJ5YSinaZo5O16Az4xTRptKOc66gasGPAaUVr17e0HatGDVuei4uV4vM2E+RIXrG/URJhbaVWN0HD86FjnoQhuB6LfJc92DFyxc77oaBnIXNuFr3BJ+IqXB9KxuNvm/p152YUVrL2YM10Xuarme3PWCdoVm1uN6IF8Tgubnbkwo0rkHX2PslQlhJfLN0mAPjIM9X0Zr97YT3qXp1yBJ9OIw0fYdr6gyeCil5WteiajJQDZcDoOkMbe9Aa/rOMBSRXcdUuDzvudtLsIKYjop/kjYGZQy6MRA1bS+d6M2lmHYaJ+auJUl6SkiJxolPjFYG7yPjNBFCoO3WuEbRKvm+MYgRfIyFzVlLLiIzFJrwaz4lJ12XN86ROddYaLWwC2ZGyjEE9vh+QnHnhCgjG2mtxKS55IIkLEnHfGF11AKpTg3LOYkpdaqsrfuHPmHqiNxR5icjWo/lvHIOlCxFthKLveOHaE1WImOXjpswxiSevqnnoQlRo1Su0pbjN9ZaGDPeJ6ZRpLuD8nRtszBhYpwLl+P3UohvkqvA7SJNLcdiYv4UMSrP4jGm5bvFknFKwChTJfzzZvf0UEoi2q217LZbrq9vOT8/F4NbZuAiMfokTBJt5l8U5mNtNpATFkkWVbXImEGwxbTd6MXfrKs+YDd3d1VGYNH2tTFWjt9RlVq9KaCCAJ8nM5i/Xz1d5qTOuVCcB6GMI6Coug6/XnS+mXc2e46lkkg1bOH6ZuTivKex0k1e1u15Y1Dy57LCPvUZpSysM/FaO0FF3rixEc+yPF+vk7I5V8mtNKLubzjEaDlUNpRICeaNoIQdOCTs54SxEuc0VAi1odE1joJImGP1RZPxLWPRWM04TcKwKgI8mqgpSZjsJUfOzzc0RozGtRYwyFQGfooZ68QCYLgbxTfo+RXDOMlXMQ5nHKpocpm7/VL3hRjZHQ74GNBoLs5XaGXQrmE/TGjd8+TpU4w20tHWimka2e52jONICJKqWkphf9gz86aePH6Lb3zr25Qw8ejpE7nvdc2TNGG7+L9mLJOfxPwfKMkRYiKpiMFSypGxqd7A2KiYrCw9Vc46v7bv5AEpcxFTdz3C+JJE8IwTRmSdpxf/tKapEnD4q3/tjwPwt/72u/w7/9Zv1rFzsjdVin/zr/6Je+eVq2rh8aPhU2Pyn8dRiuIXf+kt/tAf+hgB94QhoFBcnHs++OD42mly3/F97h9ycTer55ytV2gUtmSytsLgq56HrbM8ulhzsemJWcDAmGZRtiYXQ9+AVVZaJGotoHVlvaSaeCqAIqgqd9eKo0THCmNTGchFJGevB3Qw3/sKNhSVQSfONxuRJ51s3FP1v5mTbu/t70qpIR7H99fANHlClAaqNojHVs4cpgNoCShSSjMMlVU7G0ynyKp1fPmdJ3zhyUNQkq7ngzDnQzE8evKEJ48eYBEwPefM5COlKNbn57ylFOvzC3a7HR998pyYosjTEWWMseLvZ+teyWqDdZbNRhLtTWM526zZjw3nlw8ERHeWs4sLGedK1edJy/NtDNpYlBWfTMrM+4aYMzlIkvLZqiOEhHUtXd9XNvoCr6BtS04BVSIxyrw74ynWtUAmR0n0FpuAY10SkqdtNO++84gXN1e8vBnv3e4YAsNwYK+kke/DmoePHmNVQZVE30vytlKvMdNeZ5/nWP850m4K0nwMOTNMk8gvgdu7PS9fXTP5iatXNxQKN7db7m5vCX6kcYbzs7XI1SlY5/Axweyseb8jev9pq+eVQyZM4iOtq3nYbKExe6Z+FhA2135vktR959+pkvf6LGgtLHut9LIW3vPYPMJ2v++jaxtWq5amcdzc7pj869qB4znJHj+d1NqwWa3Z3l1DEZN9a/RnApYn5czyPbTW7PaBw0cv+d2vfZNHFxucBecUbeMWtQEnv2qt5fu//CX+u//yT/H3f/YfYozlp/7cT/Fn/uyf5cd+7Mew1vKzP/Mz/JN/8l/Tr3reevKW+Is5y2T0SaCTXLs5DV05TYxh8WTn5FXz7XNGmG9vPjJTPGDS8blTtQGpgFikpjl9d2fFEoRSaFcb/LA7qeM11qiliSkegRL2Mhv0fzfH9zYQlmdDvtd+jlCUQRgCIMXzYS+dmX7VUFrLFCN9K3KPkpIwb4yGIgNB1YdrTobJRfxR/DRVQ9NqElgBrTmuulQUWluF0y0lFW5uDoyjSOuMO0oyUpRUo33ZLwAbyHtJB/lo/mqMFr+iIIbJ61VHyaVSGQXd8yEt3gdaSRdKo0iTYvKyEfEIPXFoQTdaTAqz/O44RpzVTJN0mGxryVOkqEhIIk9sWoex4nnmtEEMnA0lFgHIGodprHSx6w1RSuMamSijD7SdwznLNE74KbO9HXHWcHG+wRjD1fWOtBPPImtEI54yNK0YObddx2444BorcdkT9H3HubMEL5vu7c3I3dWBbDK3U+C2wOO3NtzeXXP5YE1jHXEK+CmgtKFfd+x3W3JMEn5gFUYf/WR8SFxc9ly92ON9QBvFD/7o27jWApHr2z0uy3e+eQXWBLbbyPXLQeKLU67glqJrxFC47VvapqWQmYInZ4mEHqYAJJSSRBnnDAq4ud7TtrBeN0w+4j2oAm7TUjpNSpnt3Q7OOqxthTWpNNZZ9vtxASoUEiPsnKlJNIVhF1mfdVLwhAxaCaCpJm6v90xDpLWFZK0wBlxD0zi0Luy2B7qV+AtZZzi/WHG3E2aj0ZrLB2us0ez2Ix9/ssWPE5cXPaVkvM98+72P+fZ7cLbpON+ITAsy2QcKXpKljEFluHl5x1tPH9GuHN3KcTh4KCLP2d6NhKwYEO9A2TAKK1LktWKi79YtfduIHCVB1oWikxg8a+nOSiSveObELOPOj4FuJVJJiiZF6Ri/eHlH07bc3BzY7yaUKrSNYbVuaaoPxSkYlavnl7VGkt6QInrucFjM0h1R2tK2Gq2ddJgHT24KXpXK2mBhrbQYMNJ5cvN8tNC85yQdtYA0OWdJPNOaxhxT2ebNlUIk6BTxJzpK/k4r8poUk2Rsu9aRY66Aj4DwKRbCiQBxJsFIF0nmVwU0rVkKnOVakYCE1a+zH8DawhQgZ0+ZE3mWhoNewrVE15qWIrloi9It2hyZpk7LohwzuBbZYCiYeTIly3wNYI34Aypd/agqiA2y0Ttld81/tsbW8xfZd865GuEea8VTaRqwmMdKstHxXr5eTLWuYb1aMU4Dt7stq3XP5eU5VmVynCjKEHNNpMIs66LRMzu4ntvM2qN2KIuYCWulCD5w2B8YDyMUKgPIyqarSiILpXoOqjeAO/U+17blwvJiZmSZN9arrxvHfx6oOzejTAUv6yXm+M1YgL2jPFAdx7zSvPVoU72j5ntaaldaGjvf6bPnj1BVHltKkXCa11+u+PTm+LWjayT5Op2ApycXQmqMUpDVh6Xxk3Ou9zHKHJgNxiRZ5+p3L6XU1GpLTInJe1LKVYKlmULEOWnk+eiXDm3XtXRty/ZuT4qZ1XrFdrsjFYi1SSesJWFyXVyc07UtnXW0xqBLJsVIiFH8yGLm7uXA+x+84Orqilc3d0wVEDK2oetW3O4OddNZwbsCIQfGUaTelzWh7uLsgcyjRfzLrLX0Xb/IH4119P2KkiKlRDH+LTURtMCHH39CioHnH78gpMj6wQMeXpyjcqZvHV3bCCO1jgfvPcEHdCdzVsrSPIjR0/VHYErVwAGpg+7vC2OGlBVoy7AXj5u2EWsGxRzocUxKm9m4RlsSZrHKmNl9usp9tdKY1wDpuzvL+Xm4h6Rst5/eAnz9G4949nTPevNp0+zPPt5cj7/p+Gv/6z/Dv/Nv/yx/8k88r0wO2dj23XeWqH03x+OHL2it5WKzRiuYYiD72gjK0lBtathBSInRz6oK2F4fePigo5QkHjPaYLVd5gmxFJH5uaAWZp1WLAEmziqcrWExyog032icrWOgBqzo6k0WT1Lkuq7DRy/MJsS3E2QjODeRZg8+WX4rIFeQjl39HUfmwcU5JYhfYAFiFKB1aXKlTDYyF0/TBEZMx0E2/9/39lvSLBxHYlyx3e25q96zwe/56OMDw37PuB9QSnG323E4jLy4vWOcZD/UOUc2WsD6HLk8P2O97li1PeteUrp9jJWdaVj1K4IP9WeRpu0WlpEx/RvnfVP/kestTWgKyzzXtS2UGjCjDeuVxRh74jNEbcTIRdVGmgREv8ynSuvKLJZnam4GGX00Tc85cxgHXlxdMUx+YZ3lAjkGkh/RShDoYfAVrNVY7VifraT59oYj1FRY8UpN5BQgByjVOifLmEwpM/rAR5+84Dd/+2sM40SKmW+89/58hmJzEwObVYfViq5r2GxW4lfrQ91Hzr6I98/j9eVO1RdJ0yWi0TXlzzONkyir+HxwawaQluMzLJ2mcZL6QUuSfKpsy0WGrGa2/6fnkPzavCQhzsL4Pv1WagZHC5QciTHx4PKClBPh5bWE7aX76KRCUapdgVJH9cXF+XpJ+Zwv2mddjaUxvPy3/KltHeSOF1e3PH9xxXvvf8gPfuVLYvE0hpNmrUwDOYmnqMPQNg1t0/CX/8pf4U/9qT/Fbrvl7/6dv8PP//zP8/Wvf53NesUf+4k/zLMnT4lZmv+NtcQ0m+YvI1zgX5XpuoLISJR45VULm9d6hfcOaQLV5yUXyuwlqqjzjpJAjSDef/MF0SDKsfr3TrWsNxcc9luij8zewaYGWBhj8MEv0twFjP2c43sbCCsykMUsmaXQQIkGdwbE5sarUtB28pWHMdQNV+0qqyyJLNYKtV2cJ5dFK+lc6YgyIKyT9K3ZkyGMQRbCxh2TJ2MkksgxS4FWzZtTyaz7FoyRuOHJ03SSYpmLeIq5pqHpbE0/K5WNEAghLoVd2zTSpUqRyXtCzJSQ8VNcNhxaHx9sbaUQjQVSYzBZWCqy0awLfcyMB5hGKQZKHcA+JnxIlJjJUSaRtpdOq2ts/c5lKQh1lkJ9ljNYa3Ha4Boxenz48AHvf/s5Dx9ucM7VeHDL5eNzASDbF5SPxSutaRybtSyEPky0fUu3bjAmk0uQs1eZTKRxhsaK34NsbhDatlYYq3n16o6LixWvXt6w2zZoxA8n5YkYJrSp+v9c6I0RD4UqIwpeAg1Mo0lBCtDrl7d0naPtGlZeFnBbU79SNThrWsv5ZUvwgd1WDH8bJ/Gvzml226GmhQnra46OljEb5xpHwFmjmKZA22qurkfatkUhk2XbugqCUo1exctpt58qS0lAqpmCLxORommcJM0pSWtURjNMkWnw+Enkm9FnGusqmKmIIbM568jVM2593gpzzWlizBhr6PtGDIkrg69tLSFIIToNCUmvVhjbsN9P7PcTF+fr+myLP9F+Lx5flxcbAWSjCHjGw8SDB2tSynQrLZReL9LelAvjwXPYTrXbrCvIJH5lEtZQO4va0nUSgkFGKhct9ORUGUAx1c6qUiIxGiN92xDDAd06YgaUZr+buLs9EMbAauVQyjInyAL1HDKlMiGwhhglQEBZXTemIrFsVCJmMdrNKRMy5OilE1IBDRMK2hacaYgIwzORaY2htVbA1spmmTu3c7E7z1szCDXHEb/umSOSjigdv7m6q/Pm4s2IyNRLFvaiUgrjDCprARmLSLdOfSulpypz6SJ5qhHdM8U6xEApiTnZV76LyDhnMC/GWWZRU23KLP0ByOgiJ6yqJHSJXE6hdparG271LjjvjPgT5Tpn6JpQM68VSrpwxhjWnfinTFHkkNpKgVSH0D2Y4+g1prDWyXumREmBkiRMI2Zw2hBPQA+rNU4ZjDqFTe5XpRZD4xrarqWUwrjf0bUdbWPJaSLHQtYOHyWFV2o1Key1VjTOVMmWCEVn6Gj281hOvRod+RCYqufJex9+gDOWT169ROkG6zqYGUy1MioLCnUETusIu/c9ckkVHDr6oByBv/m/+czi+nSTlHNZgJN5HZvP7dRz5U0MO6NECpxVzUtQCqXMZ0oi33QuoaKk4tOr7v2ds27ZYL/+nTqVwNWsvzpOVUVTZob5fFktVVJRQaCyJKrFyuSqcuZJ5P4F6DonRrjIJmuqhskiuRZme9e3HMYBwrHDDXPyZEvbt9hhkK484LMkSfroaRHj/LPNGW3XY21DYx0lehgPKBNoS+HDFze89+2XfPjxFVc3W3wyJBSJ6pc6erxPjOMkwRZqfoZVbaJ49vuRUoMIzlYrLs4vxGC5NgLu+ewoQCtKMQt4MDdCv/hFS86Z77u+5fFasVqvKUrYbVaLSmAchUXWOEMInhAC1jm0aSlKVen6rBCwi6ym1OFXeG3Ul7Iw3adxQlN9m+r5muoVKlOtSEu1rYbWCzPpKHnX6jhXvj5O/7f/hx/j//i//8V7n/+z/+Dpp8bt+x+e8fYzxSef/P6AsMeP9rx8dfb5L6zH17/+gD/5k5/ca6p84Ys7fuGf/r4+9t7x7OmWs7OzJVVMmhISXOWsxhlb1QUZvCfqIPOBNbBy5CTgby6JvumXdWZeQxcgrBxZvbkUpuRRKLrWSd2bjvxTkZwf5aAlF5Fk13PWtQFeshi5Tz7SrVZoZzFK4WOo9dDpXDXD+gKiattgijwTw37HU/eY9VlfgYqED4GQ4nKt5zRVqH6YKVCSqBJUgRCrEmaSfZIuGqMMh71n2AoravKRYZgoVYkyTRPOOLzOWC2g3Ga1JuXI3e6AtQ2pwNnZQ9r1OZvNhsePHnO3veODb79XQyz8sr+yZt6e1ud3nj9PBnCiDp1cIATKCbAxq3RQx4S5iDC+VQoyB5ys1AvL2FosZTHwpz5jp2xso1RlIbH8btc2PLhc865/gNEth9Gz3x/QSjGOaxRwcXlOTokHF2suzzeQA6b6UUoNdWz05JSIkycHaeyXlEhxIudQbTyEaWeMIcTM9e2Oj5+/5He/9h63t3eAYn84VLllEfasgjANdE1D2zxAW41tHG3OdKuecQxi33FyjfXrxczJLFbm+q2c+LDO3sIzoPQd4B+lTG0qvfbWCEA2N2/nY5HL1RogF1nfVc6ULKm936k2KNxff5ezeh3wY56v5e+tMey2hzo/+3s17+l7KRRzV7PUmmkYx/ts93IS4vOGz/5OxzwurTVcXd/wycsr3np8ydPHl3S9W4BQoO6/ZY231vLOO09RWvErv/zL/OZv/Aa/9qu/yna75Wyz4Ud/6Af5/i9/H289fsT1zS23d7e0jePh5UVtAks4mtLzd57ns7KsoyobSAVTcREQKwWtZA9lq3pAzq1UD/P5vso8lnMk5SKqrjx7HQr4L8nKegGWL9YrHlyc860YCfFQ505bm0O6EoPEogqkQfzdHN/TQNh8ZGAOc7GWZREEFpPSuYBOMeND4uF5z+3VnmkIdI2hXYnkCS3IrjZ2SVaaNbhzfd/1Ha6CYPIZGj/56vshYM80TkzjVAdpYfKxemeISaTVcLHp2CrFuHRADSorSW0CnDM4p6ohcK7phxbnpGBLOdM2DbrKt0JMVSI5dxLz4hVRlDwgWYtxp98ONN0GYywlScEfY2a/D/gx1WJOVcBP0SV54HyOlCJyDFNTnExlRgiQQzXyVAvzZfJTTWmSZEPpnCput1veenJBv15jnGJ3e8f6osP7yGrdcnbR46dA09iammi5vUuVqSesKm2kQyCFaeLmbl811fKQtZ1DO4dxsgHe3uwZp4kYZdO1WouExk+FGAoh5Oo3U8dWFtnnnBYpxvuJHALDPtA2lu3WE5MARDkm+rOetnGMQ6RpNGVtBOhrLOtzkRKFKbLfT7jGkEOmsZbdbhT5qJXUwJzEML1thRGWUqZrO65eesiJzbplZuiIj0rGNYbNpmPYDUsqjjFaQM1cGIaJxlm0PnYYY4j0a4lgdq1FO0MYAtMYGfdBfFacLPwCyCV5nZZERLTQZv0USTX1NOWyJFxRO0Pb3Y7hIJKU9aqjUBgGT79pGAbpvlAkLMLHiDGSCBZDYhxilbsqlJXksOADRM0wTmyeCvNyddEx7EfabBmGiD8EYpl5NRJtbqyp6ZsyKTdao9yx6zsNI7kIw2EaAtEnjDZ0vSSGDYNIpVHiP9ZFSR683Q9MY0QVYaBpJ4wHm4r4TaQkQLaSjk0qhWLBGYUzBtc5pkkMtYWpIM9xTJkwyTMphrcJfKGJlvEw4dae3jk2q4auEY+HEDJtU+fCVDfHWTo5QnMGVdQ9oCOXImWhUgvoNMulDcIc1cgmIAQv8r16zEDYXKPPzLYQJTr8mJInUhdZsBNGnxrCyudJASosMKWOjJ3KYVuKoBwSqp7DnLCWXys8qJ6P1hyjlee0r5JE9q1yqu8rUlfxg7GVhSggQi6ZSIAEY1Q416GIUM2elYJTAyBV7/Hr1Y7SGoyTzbzJlOxIPqByRGkJBDBJCkutFE6LR+UpQDkfmiMlfLPecLY549WrV8IEVIrsxV9QafG4DHFO/lSQNdSNlbCbkWtNlYRUJtgCXak5Nl68Wc7OzkhJAMMxBO72O843jxbAq8y/rCqYxdy4kudQv9HZ91hEzscsSVz8IU9MwT/zyHAvmbGey6fM+18DDE7/HFOkMXoBQ9/0mjcdshHOxKKomVOf3kdkKKYs8/c94I8ic2qp8tNG5h1rbB1vs1dZWWqbRaSZCyl4Uk19lY3BnFIp41HX6yCFaZJEyJTrMyQpc1qpo3xprmqZO6/zeCxS99Rz0Eq2F1MYaENPLhKdrhA2bbYNRVtC1kw+c9jv+dbHV/zeex8zHDw+CFsxq4ZQFCpmtBbWQ6hAPkZJIQ7L5rTre9q2J2Rh1RybSOrkYs9hA+INJ9JoVQENARm6fo0Pnq+8+xQUDHdXGC0sor7rMBSRu9eCaxgnaYwqVUE18arLSeMq41sv91YuUqbcGwylyPeYponoA84WrLk/1mKUudhavSTFZaUWAA2O4R56nufUp734fu4fvbV85nz8v3/m2afGb84JrTS/97XLzxznn/69796cGOQ510qRlYxDoyxfevfu9/Uerx//+Bf/Bf7y/+S/lvdHZIXzM2Z0fZbrhklwZWmSKBStM6TqqZqS1IdzM2C+5/Ir5d46k3PisBfW/6rvaVtXm7aR0Qdut5Lgfipzk/lQztEZqWdsBZitsTSt+BYXJWC4qevAzDz71LXUBmUKTkHf9zx+9ICmkRCewyEwjHvGcaQowxgSU9iKFD8mDqNH1T1G2B/49fc+4A/84A/w67/9e7WWL5UFB6iZ6Sh1nvhxXeLIrM42PH7yhJgST5+8tVy/R48e1nVD5tG+72oyokNrTQheUlNrnXB8XkQBOCd1lgqqqBlVrsXLnA5LTPfm+FSZOOLhLI1QVEFnSYhWSRI/ldIUdZSvlpOiaAaarbXLRp9ldJ1cfyU+gt/3xS/w6MEDlHYYa4WxpJQEOTUO1zj8OLHqGi7ON5ydtcTxwM2rVwLQpkiOQSwHKtBz6o8Z4oguGaPkuygEMJtl1bL8KoZhPLFgqPN8le2ZUtAUQgjCWKIsqgVQdd46GeN133vsXx3H/vysnDas5r3Ici3fcChlUNowm2V86u+NWRJPX6+hTtc/IVuIDD/n+F2DSycncvxi976knOPoA+n6ZtkbfM6bzWcIIHvexcZB4LKcK3Pru+ul1fNQlGr8//LqhhdXN3zy4hXvvP2Es/Oe3Z3MmXK/jjUWpbBer/nSF7/AP/5H/4iubXnr4UN+/A/+QR48fMBq1XM47PmFf/pLvP/hh5JsakSi/GM/+sN84e23q63R/fNVxxMDXTDVakNraRSHKKQNSsEZATpnIBr1mi/nXFvnVJ/XeT2z9Nbhg4CJmdmrFnbjgaJkrysNelNB8xr4VedJ4L5H7Gcc3/NAWCkCguUKhCk9G9KrY1coz1H28jsKGaQhRlIRPhS6YRY+CxAippQhyUMnnhhzpP0xbWg2B9ycb2pRLRvVuRMzTYGUwI+J6IXN0XYix3QG+kYKzViqLEML/V+8eTNaWYwzlCJU+XkTKDTttPhmzL5H2lmJfq0AxFywUlQFz4R5YLTlMI70SoskpSBGdmPETyIVaFoxIZ/TnlLMEh1rZIJ1jaFpxXMtVwbdvCHWSn4vqYTKAraUKKup1Yb9YaDvXe1wanw40K4dhYyrgNNq3WKtsOZcI0bgtpEha50jpSC6dApda8mlMIyeQhFKaGeIvqCtpl/LBvzu+sB+K1K6VdfhJ3j8dMP1qz05w/7OL2AYVPCwQKNlbK1ai990bG8St7cTMUXRkLeOprGkqOn7tsZDW2IMDIcD4gmjsE42Bt264fBqK/pnZ6uhYpYCwdnFEL3vHK4RQHEOEAg+YjTEEOm6hpwzXWe5uzlgMDSdpWRXwZcsm6m2QSHj0q2aylZItFoKmrPzNSiF95lp69ltJ4aDx2jFxYOethPmWoqF9Vknss7WME0Tfd8QowQYhJTpjIBmpuqvSl0UQ8x4H9FVgmyM5vLhBm01TTMhGyuh1Y/TxGrdcnm2IkyR25sRbR0pj6gK0KSayCqG76VOjJIKq1pN24qUMdY2jPjjyOSYqpG/rdJo2czIohVCYRwC0yRsrMYKoy36xGQCjbN4H8U3pGrXh0GCJIb9iEKYXQqIsRC8mKVP3jNNns26x/uAcpLWphqD1R0hCuNTaRjrpiIm8UFMMRNDrkCzbHKnUWjaKzrsWnOo4KXVmhQTfdMIrRojz2dIFDJFC2vJNUbukzoajRejFg8OAcvKsmGZS5ZcalE/A2hZNPkKRckCDMUqjUwpSYEy9+RUqp1Ylnl0Xrh8KpXKnJmZYOqEgVNqcZaL7MsLGTUXa4U54foILNS4bFkT9CJ/o86jJUlndfZqUpVFYmsxJ3NYLapTpChD46RI09YRMWgyzsSl2Cw4lNI0VbKaclrAHNnUSBdaDF9FcqGMhAyIqVn9jlkses1J1bTIQqtUW9eiwlhDv+oxxjJMI9M40a0UMUxL6lxISXwui2zOqR1bozTuxKB37uvNTAeUdBattZUxJJ/fOEe2hpQS+/2+SrNOPLPK/X+r+c6c7iVODnVakM6/Wmb2xeuF8NFC4PhX30UF/BrotXznE7BtLuaVUkyHA2a1gsrw/axD5J2SIFbqpqPv1zRKC4tx7oTW5oCs8/KzT/m9VThSa5E1dK2wWbRW9Rm4zxxAgSlz7ZGJoYLP9f20KhgtdUlOwrZYgMUiXHWKBIXEakov4ST5nqHU7E8119nG2qWDC7K5KqVILQUoZJ4U/xsBnVJK+BgYJs9Hr+54/+NXPL9+hS6i6ygYipYQgVSbf6VkNJJiOrOsl02b0hI64z22+nctF2X+U8lQU2XVyf9nZKOZ8lFW6GzDO+9+iZQi39zf8eGrF3TO0a165gsh7Duw1pFTwjqHMeJFpdRcNzlMDbpYNtiKGVp5bfwlxmEi+gnX25MNzWyCfGy4Ouuw1hGKpiANSalfjwEoxzCUN4zTctzHlgK/8msPP/UaZ8Q39Fd/4+1Pv8FnHHfb7vf1el2bGNIAkXN+8tY/my9ZKZqk9bKm5xwpOS6gfbFlUV7kLGb0M1MwazDK4PHoGkKQ0zFcxjknYRcpk7PI/JWSJnJqGozWtdml8D4whsAYhfml3xATZ7TCWUNjZ2auk6Zj42ia47WM+YQxWnsry/RaQQHZrFaf4iqhH4aRmDIpa3I27PYT0zBijGw6Ywj4aSRGMQnfD54vPHnMsy9+H+sHT/jDP/GQppUk+a7rMZWl5VoJL9KI5Ua36pE+kGa93kCB9fpoWN33HTnMARh1DTOy7g+Hgzw3sMy9pYiKI5VUpd352CAoAkzPYJfWcg4gCXeqKEqSdSsVSdrW9ugVWYok46osdY6u+y6U8NPnwIujmma+xhmFOdZCqu65khAC5jGy6rpqe2Lo+168SbUiZZbwLT9OdM6x2axo+waNhBppVWqAi8aQ7ycvcgRNl/mBY6N+GCZyiPgg/orOOeI4Luc/j51cm8IxJUIMxCTgoTG2+jSJL5oytVmVj3Pn3KiCskhLpearBueLX55e5G3fkb190jwoy905/Wux3NFF5sf76/sMgCXmVNUZLF1Ql08d83p52nid08nfACwj9VqMsh8WBrcYyX83XmYzgFoKErZUgbDP+83ZJqLk+8xva8U2IuXEi6sbXtxcMnjPpVrLWp39iXz+OMf3XctP/vE/yievrrk4u6BxDS9fveI3f/u3UcDddsswTbz7pS/x5e/7MsMw8mu/9iv8k3/6K1hrefvZs9dPkBmHns+uqArucbSYyHluOLGMGaXUAuzO4LPsJ45zGFTvP2No27au+YJHdI0wSqcQhQgR5BmwRixvtTZLnX8apPDdHN/zQBgcwTClqomynSnislkW9pKm7SyrTUvjDLvtKKawWqGMFJ4g3lDaFsaSGUfRX2fnaBsrXT5YTI9BPs81lqKqT4MVw7ycxKsrTFmYRr4WoVZ0u85ZpiDMlxgTyrlKQ9RVSlYLVFhSy0JN9osxknI15K9UzZwiysz6denaU8GxlDNoaiohFJWx2qJRNC5SVMLHxH4/MXkBflT9ftYaYYJMilkW2rRioN11jqZvGKeAnxLBe/GyUgp1rI+FkhwiYfKM4yhsOzvy4MGFyAegspks3ntW6xVt25DPepom8GoUQ94YS/VzqB335IVdgSSqKaBvxdBfV0+1prF0XcvZWcf13ZacMinIYrCr0rmcdJXRZcaD0N/7dSMm+0XAI6UcrlV0ncFu5X1vrkf8JN26kkCbLAtQVKQIfsrCKIoB58SPy7Wmeg4IrTqMgfasR9fOe9O0kiyHMIW63mAdjKMwRMKUBBQcg9CCEUlRThJtn5MAXXQGkQXMLItC1wmjYC6Y94cBRSem9M4x+cTd3cQweKZRrsNq7XCtsIGCT7StSIKNUTSN5tWrgS419ZoWUixkJ2ucMAcM3ie2dyM5F4aDLO593wibsNH4KXJ+vmK7hf0w0Suqv5zMpEWJmfPMziEXck0k9TlVb7qAbQXQbduWZDJtFxgGJR57SopjY0Vak0shTAnbWon11mqZiHNWoIwkXvqIPRMG1TQFMeNUCmUsrVO0OLSxwvyyFteYmsiWiSWhbFzk2DFE4pTk/UzBpyIhCEqxHwdAijSrDcMQFkZd8Kka1qsqgxGAzQcPJdN4S+lgux2ZO9sxZ15t9/jUHLsuqdAgxZNCoRvFuu9IBXIshJQXGS5106ZmGjTU96hpmFovfg7LXFgB9VyLzXkTex8VmbtqRxmmqowbQ1o2RXOxM3+2NDPmzlEBdd+nqVCkEF42yFLgqGWxpbIzZFwuG4icKFp8n+bxOicozp012VQJcKu0wjJ7usnfCltTgIRMRCsLtZt/KokrxZCxFYg6rl/GIF212Z/DUNP41L2iZik9lABYRw+JltVqxTSNHPZ79oc9tpEN9RQiVgkLNwRhLs7XRmu1eJ3NV3EBwhDAUSEyQaMUsch5lQqQKWSOzaVUhsCbzePn73/aSTyWvmV5lfzVyT0t9xlgpxK347x2em0+Gxj7bCjrOI7nz2mcXgq5Ugu/0w3ZkXkk4yOmSMqBXCJd09FWWY4PAnxRwVKybDTeeK3mL1RkU29NZQQuMLRCFQHd5u8oRTvogtQeOUunf34uraZpBMyfpXMlZ8rSmRXD5tnKQBp/GnN/8NVNzgwMpyOjoL4m5YjVLdYKGJxSIYRI10gbfE70zLkQc2E3ePbjSC6yKUNpirKLL11RBUNZpMlzeNCckG3U0dOlaVdYY8gYGp1J+XQElNfu/Qw06SrvoF6PBCXQrR/Rto7f+I1f45OrW1ZNw+XFBQ8vL+g3a0wjHog5JllP6nwyH9bVueLkf/dH4cmZlcr69aEm1pXl51AWr1tVmTi6+hWVLHP6DIQppQQMRS3Pl9KK/+Ff/Br/t//4K8vnncrTf/O3Lgjh08/s/+Vv/Ms8ffr/4Bf/6Zc+9XefdcT43YdHyHda2iN0bYvRBh/+2bckoRR0KXRaL0b5Mzsol4xJZvnz0TpkPhMBVEz16MwVdFWqeqtqRTaZki1KCZss1/GYsyTviV2RYQqBbMQ7d0GwOH7OfA2sOUruQkg0Xbf4gwFVwnjSoELq87ywYo7jSatC17VM00SKsTZyNH3XEUPiww+fk6KwtcX0OqCVERDIrjh79Jgf/cI7nF9c8PDxQ87OHqAbqQ9VDV8y9XzlqwgjeZ6IPwVp1BrA50g5YePOoQ7SJH0dHhbvqdGnGiIRZK2Zw8hee6Zk4y01ev112XMUCQdzyZ2wwUuVT6rKRtcLsD7POafnOM/xc0NsBj8LVNazJORaU5Z7KKQJuwAYyhiyqsFO3uOMobEWo3SdR8TrkbpvTCnRNs3SfDo9jDbi6VjtG2QflAhKgBujVW1yNkx+WuYTrcQvtVTLGtc2uKZh9toyc7q4uj825Xse78vM6jbWVAuY+t6ohTEle870qXV7OZSpTQ+ZmTXz8Dk2hY4sWyo77b4vlwTlpfpaUT3Jw6s4DRI4HSPL+853cn6YTmqQ1+WYUoOIosPWxs/9BFgZSzJdHxnoi8GEUktdlMsRUvysQ2qvjKozkQTzzCqSxMuraz54vub99z9i3Ta0layiVKpAsa41gswZX3znbd5++x2McfzKr/06v/k7v40ylu3tHcM48BP/zT/KX/hX/wJnZ2fc3t7y7NlT/uZ/8p/wO7/3Nd5+Nkvn5xq2TpWliP/urJRTx2dfAnVqI6GwqNlmEs9yj9FLs1NunVxHayxNJYxYo4lBSXprykSfwGnZC2pdLRMyZ21Du+owxjEOE/v9ru7bv4sLzv8fAGFzMVzZ4NjG0LVihjhPEhmwVmEbASJmSVZMma6Vbp6ulHutch30mqYRqNNajTIao6usx/tF+ys3V+KLpzHiGrFvjDGLQXTIRC+eAVqLd47IDTTD5Bl9pU8ig8RYS9+LUf7M6hN2QpWCITKfmW0xjJUKWRIkKkMKXCspJMYolFPiixE4MfHNONdglJjt7w+ecQyVgm+xRi1x71LE101Arg+lE4Cs7Syjj9Vo32Ncv5wvIAyALCBhDFLshjyhteFs08sDX5MOx2ECBV2X6foGYwrbmjY5DBPW2qXz27Ut19d7dCtRqpOSibep3SGFwhmF6jVdL52ccZCwBIUixcTubkJrxbSfKbUyAc11UY556ZJbrTGmEXlgLqxWDbe3E/t95Ows44xoo9uuYRjEmHg8TEzjUKWFuvq+CW0+BkmeC9PE+UVfUXVdZaMyybvG0fVWfNBiInoxrVmvWg6l0DSWpmnY3+zZ76blgVBQOzamdik9k/c0rsHaep6tQ6X/L3X/Hmvbmqb1Yb/vOsaYl3XZ+9zqXOrWdNNNdVG02612mjiAABMilCCwkOJ/LMuROyJyRAxCsixFoCAs2pFxhEGxIyttYRkkZGGZyFG6sZ3GuM2lq2kuhgbTXfc65+xz9l57rXkZl++WP95vjDnX2vtUneou7HiUTu215ppzzHH5xve97/M+7/PoqjciAf20n9jvR9EJyMjY0UAVwW0aw2bTsVmviVVIMiUxOiBDtxFWXsrClrLW4LwlBGkDpShp/VPgnThwTTEJuOcsjTfkYtDW0DSOnDP744QqueqPiWYGVQw7DBLoZVWBg1q8mhM2YxTGKmyRmTpFeXbkewrWCoU7xwhGESdFUmoJHnKBKWT6IaGMCLuGJEDx5eNL2ga8dgxhEqOAJCB2GANjKBQy2hryJjPrqs0LVUxpeVaVgqLEhVVr0Tgbh1gBMGmzlM+WKkItmjFaW0oRsG4YJmJMNUhVpJL58PkdU+5oV40s5ha8NpRwqt6t1i3P9ntiEbBcGbOoZhQlLXLUhU+qqXFxwhUjBqlkS1V1LkqczEUeFmXm1gfrW1Iea3Agk/isW1fIMLPDKgBIXURz1T8wSpxkToyhSrmuARb1GVjYEboCKPVv52CYFA/m5LUWAeqBF0HVlwqxmj9TIoqZ2Xhy3dUloVEVRKoLfiXlilNvwVl5tlCa4xigBDgLnOQZVqf8DJbvnynf84lIFX7NarWmH44cjge5R1VHTVsH2pKiBM0S68p10lpXI5ITIDKHgbnec1VbSGOW+Uc0MionZo4yVGG92rw86H3Jdt4KeHrxAVTxEIDRJ2epe8Hygz3P17GoU9uYmt/7MYOieeu6jlRBz7kLeNbUkhadc8CVenyJ1rci0l6ZlrMWXanJWUxJmNsvBOf3z32GJGftFRHflgJKuY9RLWeeKjU+1SKJOEFJIc9au1Tf08wE0MI+0EWq6zObxNf2WvLcinQ/qB/HkeOhZxxk3ZnZF8Y6jHVoJTHKFALTNIk4eNUuE3RVTEJW646Lyy37/ZFSCscx1PlXLwDffKICsCeSFpazsgavNc5ZjGtwxoK2ZBXJJZyenZl5WRJKPDjrnZwZp3oZ+Tn2OAu73R23+yPDMchclBN+1bK+2KC1IQwTxIw2UggL8ZTiaPMQpF9gXpZ2u+V3KDEtbMuZBTbHtVPMlCLM3VmjT+azU2tkDV2YGXuglnv1v/9XvnQPCPvn/7e/id/8m97lt/2Wb/AX/pNPv3Tc52z4P/9f/nleBiZ/1LZZH9kfRPS7lI/XjuLsKeksFVTx/tu1H33r7ff+nv+KQz8SjbTl5pwqo0S2kx7lyUlVxsk8KkAXc2q3Y457BcxemEI170ZJsqW1k5ixSEtk41tMTgL0hLnAc/96LsyJOkDEwbiu3ykx61fN7BCl5y+tpYoirbZzC1yOkSlLN8M4TUuMYYxFZXFX3+/23N0d7rXcaa1ZX2x5fH3JxXbD1fUV19dXXD++Yrt5dNKXWY47n+k1zUCcMBFmRouoMKSq0SjgQc5pYcaoVBjGwNAfK6j24rWZpomSYRqnpSNn7pp5+N5SsoBYdTexRAE6s66FzlO79Awy38M85vX+JUUXM7d3FcnTJDzI9RpKTJeyWuQX5tbbKUyknIRJaAyqQJxE5zUojdYTOpxkWEophArcNk1bAwfNOXwyhUAIQQTBaywKiqI1QxzY73f0Y2V6Pdhml81SNNpIAVcYZQGzaMfevxUvsGrmoaDmnxWzW5PkLXVtnDubzgrM8nkN2ixFGPVg52Yuys2hRY1VVGU037/xct9mwogUPT9qkX/J6yU/OLZ5nb4PhqmqYxZTkhbABTCbv38GpOd2UJgLwHNRdw4/Ps7MeA4Kl7PftdbEmNjFA0/e/5CvfvVdXnl0zSfeeIxzUpyZ2VlFSRtmrPaNGXj/gyf8d7/4D7h+/Aqf+8Ef5Bd+4Rd47913+Z7Pfg+PHz/mr/21v8Y0jvyGH/ohfu33fz//4O/9Xel06dozAKz+mzLKyr2fY49ZAmO+F/MzM5vILG26ZFAao06tuwWWOdlZg1FF9PBSqNcWMftRGjAYJ/FrSBlUEp27VSvyUcViJlNzjY8DPf5PHAhTNVGbwWOpcCtpubOacYwSoOhchbGrTXVMDKMEHsJ40jjXVKq/tEMqbenWkkzPT73WlpItY56AgoqZUgJTlOQvhMg46FOVLwqCmWIRppe3oFiEKvMsVmkVQxjRKdNqUMpWXRiWBM7URK2UtAjBHg49pRSaxkANluekTlUR+6azKCt6J2vbQtHiKpGl8pVRxJQr+CFBu/cCRGhtKOja58ySpOYsIu8oFg0ekB55XSu0omcCgVCD4BmocsQgiZpYrzf4RqoLx2OPdqKnJS1nondUQFxOGrfQha31pKzIsaC9iLtTClEJy89bQ9sZcgNKZfqxl2PIBavFKSsrAXhMRbPnh1HpqhU1VEp7geylNXToA6iMc4a2tRyPAykKm0101Tz9GLm7PZJiEEHsnEALEKuUgHBKS7tbAbTVhBjRGkKWmSaEEbIlJ8OxDwzHwHAINE2HdpaNbokRlDKMU2CagrTBKeF0GGvQSujO89g0WtomcxJdtdVmjWkcOQ/C+ApRqu418HJO4xuDbyybdUvnHUpbVpuWu92ew2EUl5ZaefStVBZDzKQacGhrUDlL22TVWitZ2v2MNqgoDl+61WzWUqHKKJrGESZhpVmt6FYNpeoZ6SqYPAyBi+sVzcqjVa0s1HNNsdRKjqoC7gZbBfvXnUdZAcpvdgMaAVu1FhAOpYghLRW9mKDvZwZGFLDIaIySNkwdZZz4xqKfS0t1qgFunAL9bpBnoe6zoDn0A6tNS4yJtoFVJ603OWb6m4No5kxiix5DZhriUo5pO4d1Fq1r8FmZFzP7qRRpu4hRWGALi8VqsjWUmFBOkUqhT5HDNBGzOMA6DM74mvyKk1/RparSzkwtYXbMbFS7uE3yQrwxzw33qta60syT2G7nXKQIoWXhjDEyxSAsq7PQRoLoymZTWUDpArnMNH0JHGeXXWsFjJ0BrpIzpQaI520PS0uRqmybdApoTgnAKVCeCwIKtRhj6CqKrVS18p6rhMuFQIosKuAV2Np2OdSAWiklrVrlDMApp32IsYZUtstcNFEK5z1t19I0Dc9unhJrm9fM2ttstoypkIfDWfIn52XqNVr0FF4IwOqcX1l4MYheICpTSHVulmesbbtlnM0g3jm76fw63Md9Xh64ztd5vq73dZ8+elvaaJWC88RzOZSXNWKcAv5zLTZrTS0un53HveSp/qmiFtIyalm1q/uJlNLSMow8I7EkHCcmx71zKqdjMVoC6pgSJmdpH5yLY2o2ubm/zYy9edw7K26HwkgWtlVaWAJK1j6V0SSsSmDcMq7FCba6gNb3gyRj/XHgeDgyjuIuNTNutDWgHd41FGRN2e2PSxSttcY3Db7teO3113jz7U9xtz/wd//23+Hm5jmHYV+r4TWmohoeGX3WYiIXXtXWMms0OQZWnUgphFTIWQookqh50A6IkONpfKApRaGdoqRY54GCs5r33n2XYQr3sj7rHdZJMbRpPIbKMNKapGFmuxrrqjkD94Z3nSHQnFqxi6raTOOEMtKeKXNFdRVPwgyYj2IG/Y0y9zTCVE26Fq2wGTh7MNafPmv5T/7iZ/hP/uJnuP9gvmz7+MjxJ9+54e//4upjvx9ElF86mgpDGOm05Z239t/RPu5vhd/whZ9hOBpsZwgaUqnFHB48a/XZPbXKy9mmGYxUp/VhduQ0xSxJ6cI0rlpjkrAXuYcYihJTFSs9/HgvGl7EGaw5gWyp9vqvVg7vDWGamF2PSxF3y3LOXlMyz2YyuSRmdfMUA6lIXtN4xzCK+H3TOo53R7wXp3bO5h7qoRhjaBvHar0GY3BNi3WeQsbiUWfgZiqp6vbkKgMjXQ8ohbLiQh5igJTIMZCrvl9KqSbFwvAfhp6hPxLHfrklywEBpcyGAlXrWM/37wEQlqVdWvZx+t/pPp2tS5zdc2bgTi0FOaXyaQ15AIrBDPYIAHavLTVB0KKBLCL6p86LEALet+JCPhde67E551HmBP6oojBFdIjnK1HIS/507I9SRE9JCukpM0yRfui5eX7DV7/xNQ79kRhHXnKpMNpJx5SWLoYpBKZRWIFz/pfOCoEPAco5j85ZjErOdUOVrvquCKHDnlXy5l1mZVk0LB5skufKHJ85A9CUzJlpXu8qYLUEEufHmF8GfKiXFOlqQfP8baW2851ri6LQtbtqmiaMdQKMLedVx8PZM3UfPPx2c+zH23LOy5wUU+awH3nvyTPeffKUR4+vudxsSNO0uIxjRZKh1DEXxpFvfOOb7PdH/pf/q9/FJz/5Sb78pS+x3+1o25avf+Mb/L/+0l/Cec9bb7/NF77wBf7GX/9r3NzcsuqkTft0WdQsu3m6fqpqlNXpTWJ6OKmkngqYOWdUTifgsJzan43SaJUJoZd29pTr/G0JIWCsWcgzIaSK+Zhl7RyOR2KMGGfIORLT+LGu73cMhP2Vv/JX+Lf+rX+LL37xi7z77rv8xb/4F/ndv/t3L38vpfBH/+gf5d//9/99bm5u+NEf/VH+9J/+03zuc59b3jOOI3/oD/0h/tyf+3P0fc9v/a2/lT/zZ/4Mb7/99nd4NHOLxKmqQr051mjw0hIyRXFDbDtXhUlF7LprXAUKQEj4tmrQZMwy6cpEq43Fmkyu7YdTdW8bBQVjvWnZbFpxHSwyEFIU0K0khXOSaIlu2FQDnCysnrYhKdH8AV/R9XnilslanGxybYGTVq/jMOC0outWsrgEaVsyxiztkdY5jCvkMVGUNNOaYghTJiTptx37IABIKZXyKm0UMqBBXDlrmqTrZF1bakT8G7y3FG/FlbA+jrouQhlp1dBahKiHWJkJWjOOE6vtBV3bcRgGQoyElNBJ0GytFatVg9aatvV02vP02YGnz54KyKcURlupho2J5DK2tsZ6L2y+kqWqMrMtSg00E4lpmLDWCdUSATS0nZkp9aFOhWlIDMdISRplMygBQ7rOkVOkH6ZKWzaM/UAcpwpkatAa53w1SxCQzTeV+ulFv6nkgjaatj7YMU7s7gamScZQmBS5GGwjx1m0QhuYQsQoB0XaRlOOAt7kGnbrE9vFWkXXecZeElqrYTgOGAv9MXA8DszOgtZpnJfErvGeVdcyFM3NTc9+Py0OSjEU0ZFoxAUtTZEcxTZ8CvU9MTH0E+NYuNi6WinS5ARjH3n24Y4333mFq6s1zz68BSUslXbb1QkyiQ7CcaBphEk2jqmCDhrjDEbJRCnPrASvMqblPWJA4KQ1uTE064b9bmA8Thhd2O97rHN0q5amdThvWG28MDtDJoRcKb8GXanIKQQmNWGMJsQ0F8YwxuCsjLUUEvvboyzmVuG9rZq5iuNhpK0suqyMBDchMRwGhv1EloFa2aS1H96Kfp7zhv44iP5GlKrjrG1BAWc1VnsB75EEbwZ6hhwxTceQE8Pz28pYUYwpYpNm5Xx1W6ywXe29n5P0XMQAY3FgrIuYtoZc2w5sbZlTylKKkkS5IisKLSBxKeQsiYo3EimlJA5XMYrDlYjBz+DG+cxfA1VO7SwovfxmraFpHXZuhc2ZOJXqMvUiq6jkTKn6R/fjJQHGijqBMzm/BPGjtkTUe6S1JpW8JKrU702l0I8Tmgpu5SxuczmLfbVSFeSaWSrSuq/M/Up4RnSTmlbmxpQSu/1uEcVVSooRxlqoduILq6oevVLgjNDTUWrR7yrM688pUJwNY8QhLFBU1UVLEvCgJAieAcXzROBc/0G9cIG/3fbxWGYPt3MG2dmuXkiEz7dZfP3eaykt7L3CiUVxvzVnBjlg066qPsX8XRKQzouJ0noBT8+TtXk8C7ghAPisy3cCOKqT1hlYdjqGmjLWOGG96pjZK85avJMkWC2sY2GLN0o0Q62Gxshap7SAaLMIslIaU6isAWEQjL0wwmbHsEIRoXZrUVrclqcYOfYjfX9LCNLavl6vuNAN7brjM9/zJp/61GcJMfLs6VOePbuRq1qoTHRd9VILziiKcyhlTglMTWCta1ivPKvWk4ro8ERrsSmitEMZJwUD3KJfNifHuUg7eBnlbmhjWK02pCLCu1kJe7nkTA6ndp+zVLuyjGoipCqDZA5G5+R7HihI7CGC1JqkqKzfSEZihZSFZDGFSIoZowtZz0m3MJoiarmPIJjvLJQv41Wem+Pxfoj/W37zNygZ/vtfuuQb39h81OPzHW9vvnHH3//FtzhngzV+Ypw+2rXrv/gvP8P/8f/wRYk7tQU0vvnVMMIUu+d3XLy6oVWKGAYyDnSGEmp70X1wfn5Wz5Np7USEGRAmbdXMA+6tG8KQTmgk5k4FMFqEyGOm9R5nDHut2a4arFVS3CpmOYCUq2aVtgubL1T3VtGWLhwP+6U4aWb5E3UquCx4/4JdFPphIEYxvXBWY7RiChO+sWy3KylW1vZmbUydnjLdZlvbMxtKzhwPt5SUMVqE92cGUCYz6zQNxx1Dvwdt0a4Rd/txQKsiMdI4kkJkHEdmky8BxbLo+w29gCNlOQWKUmgtQFi7MqLHaiqzs7bi1bSaVIkJdQgAVOZTWQDleZvjF+RRrQXbfPY8n72vgipmKfTN4Ek5W8JOa4zKLMm7tYbWi+FByhmUBSXEgpgLJYqWq7EWa5u6J4W3QILDYS/HVwK5JOIUGIe+SsRI4XaaArvDkWd3dzy/vaXve+72PUpJUdwqTyl1PjJScHRWdGO999VRUxNDIioxp9K66iJTeEBgfOl27qZ5XqxS6hRjqPp45SzBRZ7jmjqO57Dm2yloyfonue+5dux3dSsPgDQ1g9yydr8Anr30OBUUzUMG6MfdZtawrCfyfSnHanykUVXv9f0PnvHlr36Tt95+i9dee5XpuGPsx+UYrD21eqacuL29w3nH66+/zpe//GW+/KUvnwC2ufCoZD27fnRNoXA8HiWWMUXEEM/AyeVCKJilNM4f4nqXa8H6vt7eAn7Ji0scoYoWPeSaXy5xVtVancYJtBTeYg642mE3d5yVnAmTFNFDnDj2h491zb9jIOxwOPCFL3yBf+lf+pf4vb/3977w95/4iZ/g3/63/21+8id/ku/7vu/jj/2xP8Zv/+2/nX/4D/8h261YK/+BP/AH+Et/6S/x5//8n+fx48f8wT/4B/ldv+t38cUvfnHp5f4428yUSoklSC0IAppyqe2OMA4i/jn0QbSBptoaxHxjlIBjQajEsy6WUpBiJE6R1dbVYE8LrVNnipFWr+k40LQe713VCsgCeE1R7OqVwiMMlJQy1hlSiFjxZadddSRybeeSpKMgyK9S4uySs9gTz8wLmYDKUtUfY6wOTqpWFUWjI061jUAZFJZMoXGutilKReFwHJdqhDxAul7Xme6pRbNJCUhEEaAxxYTxos3lWzsXxiWpDkMFjk8aCyhFqFbQInYXyV4zHCasrq0bVe8q5cI0TPTHkZQKq1VHSIXjbV/pnolu3VZ2XcJ5WynvpbYYZsYpYLWVgLm6BxktE78AR4owSQIuotKAFlc1643oqjglOhNBkhPXGvI0UIpjvWmlGhbEpU85CNPAcDyiSiQMiYLi4krcOe+eH3GNJBurdYc2oik1jiImbjR06xUKzW2f2A+iNSVtsdLmZKwAJs3Ko8eEtZrjqmMYI90qiuh2RedTjqQKjrRemHjH/UjXOqkq1oS53wd6pRh6MRFomgbnwTupxMeQ6I+i0fbue3eUIq3GFxe+Lp6K1aqV7wvi2tFtOkoxHA4Tx8NIfxzx3kvLsfNSqagA2TQlUoyVkiwMRBFWrQFIrgmdsxzGnuvrLf1wYHd7oGlFp+DyelNFFjXFCRt0nALjlCogqmi8CHDGkmiNolt5rq5WknAURQkJ9iPOWbq2wbpSWXIZE3N1mkykIOwsCejEWdVkqk6YgBO+kck8h3RK7FBYLzoD4pAJa9MsYF2cBFwQLQ5xkpqmWrEzcv7ynGWO/SSfMwrnZ8dPScBmEILKeBQ9LrBa9Axv9xkzJEYiOlkaJ4F5TInga0tBDUxVTcY1J5vrmCJKK0z1qlsoz0mSVgFh5G9aK1KOEKZlLpiZpmUsZC0acCErnCrL8ZtKR1dqtk4+Syjr3C8C/TKvzSCYUsgrte1PKy1zeJCxObdzvgB45Iwqou8z73/ZKvgwB0XWnpKhmX0F4I3F1vYVYzS6IO0LtV2gFBba/QLq1XHUD4PML85LYlJKBUA1VtuTqPN8vQFlNd1qjfOOZzdPudvf0ff90p4hwLy4ji7VuxnQSwLwGcpJI0+XU9Gj3tOaJcr51qT/eBwlMEIq+wBzJ8YM9qGrw6hcqGXsvDR4fclLL3PJ/E63h1Xgc2DuHBRbbN/nROcMQDsedqxXW3zTCBimztgUZ8edc8HqJI7C9e/OeVQxaCUsnxCDVMsfxDh6+T5pJ5kL5gVZy51z9XkqS5U3PwzY5/OorVGqFo5KLotjmzUiyWC0tB17lYXVhLA6O2/QCaYiMUUpEu/MUtTeORrnMIh+5bnJgFbCWLTO441mGEcyin/wj/97rHGMQ2a92XKZFXdDYruNhGL45Z/5/zKNE/0w1mtoSEESyVW3JoSJYRgrWKJxZm7clrEWojC4ttsNhUycBpRRNFqB8cwh7v0a/QkEiylQYp4xf1ql+J7v/X7+m//2b3C7P3B3GLhcr/DOCzuxlBqbBMZ+wDvL/jgQk7QTixyBqbHPyZnwhbF5luyIAQCIWzBIl2VhfwykMbFeGYpOlCpIHVIilLNxWDcpwEh7vUgjwM/9/PW99/yNv/kq/9lf+P/wx/7ED31XgbB33r594TVtvn1bSilz3Ov5+jdXfOUr35ng/oO9sWkSXiUshZAmimrAtOgsLOL5Xihdr3+W+VeKLXW+MErYuEVavGx1SLzX7nqG7Kc6fIT7IPtYdc0iPh5C4vpizbp1pFiEHZrn9UyRCjTWMXtT5FIEPIqi7ZeDaITBbFxT8FWvK0yJjCKn+T3yvmEQRpBzhhwCrfcM/cD24oLHr4qjYz+M3NzciEanNqCyzBH1OTqmgecfvstxf4d03misdfimq8ZD8nsYB1JOaN8RjgNhmlA5Yiqb9dgPOKMYQ1ic7cVEphCnieHYo7wX9se8VqIwrl5PbVDKLgU7dY9RdHZPzp7yhfE9J+ZzkeeMfXIqap1imHOW7vw+59yydsxXeC5yz2txKRmLFNT2h56L7bqOH422XkDuAuMUOR5HbJ0/p5Qxw0ieQTsgTBN3dzcYo7i72zGOAe89Tz58BkW0ohWKwzDy4c0dUwziNKs0l5evsrnIXGy2oDRd29Gu2jrSJPbWVsgKYRrZ3d4y9j2mrYUuEgWJkzQz4PjtASejtZzj2X15Edi6DzdorXBGL+ufgCKRl25KSStnmv9+Xly7f3xzCeLh9lIG9rfbagykjaOY9NK5/FttUiyetcxYCj0ftReFWhph68hcYua5KKyUyLQ8u9vx5Nktz27u5Bnz/gSE1e8zWpHPOyJKYRxHhr6vRSC1xCTdquP6+prPfOYz/NzP/U2ctTjviCnRWEPRnIp6D65h4WQ6dO98lDDbc6yFv3I6+eUzczxb22bHICzSQqn5eyGXWIkBllQSU5jQWtF4j9aau92Ow7GnFAhjIEwj09QzDf+EGGG/83f+Tn7n7/ydL/1bKYV/59/5d/g3/o1/g9/ze34PAP/hf/gf8vrrr/Mf/8f/MT/+4z/O7e0t/8F/8B/wZ//sn+W3/bbfBsB/9B/9R7zzzjv85b/8l/kdv+N3vLDfcRwZx9MJ3S12oalWISUAySUt1E1tqLoYmjFE7nYjISZmnr81mpITXdcKQFNbi8TGuOCMxejCMMZaWTnpxKxWDVPSDEHcTqy1IkCpM7HANEWGIRKrXb2zdtECkHYLofqiwXlXxWyF1bM47dWAPGdhbeUkib2zhqbxjFNmu+6wTtgaMxvE2Fo1RaOtw2tDEwuTkpat5TyUItVAIOfC4TjStR5vHPN4pYJ3c9DtvRerY0u9ZgGtM01NHlNtuzj0vbDVvDgpOu/o1ivRP4qRTjWE2GON3MOUk7B9nMM4L5piY2AcxHFze7nl0aMr9rs9Yz9irAIlAUzTeUpEmGhZAvypVtRab4XGO1e5rbSL5pAwzorWSqtZrRxt25ALPH++wxhwjaHtPMoUjgfRG5lCIubCer0hTorjYaDEwjAOtNsGqwtaZzZbj9UN+33g+fOeZ88ObEKmbQ1d6wmV7qm1tJLudiPOq0VA3hrLwTp2uyOHYxAHQgXbi4bjsSfFxONXr2RMxRnJ14Rp5PEra9GLzIX+OEIGby2PX9lKtdoawpS4ve3RutD3UVoJc21pdUbEuzXS6gfs70b6IS4g7GplKFlAn3ZVxXt1hBwqkJt5/rxndxc4HCbCVDDG07aWrnM03pGCJNTjGLi62hBi4pvf/IDjfsA5y2rlMdZXVoAmHhLPn++Zpsx2SKwvVlASu9sjcQqQMhePtsQsVRRht6UK6gqoVIgVIBK9Gl2EOUUx6Kr7louSFthhYkoJ13jabcNxNzCFEdNochJx/lgGLtotYQpStQnSlqu1wRoBxQMV0DDQtL5WXArWmarNJDbex2EvlY0pMh0CORbiJMwoyswaSEQjOkTaKWKCcRq5vNqSCzQdeOs4HjKZhPVi9hCDnOcYA3HK3N72PP1wV801NF3Xyn1pLTZpxhzQyt1rz0lpOglt8/L2so9YFKQwkCtbVUv1WStpvxqTRKghqcpG1TRAtvdp0/N2HuSUmmya82p+NcnQWhb+GCNhEp2ieT8nVzV1L/jNFGLO91wU5+9UVFFYewKkZvahApyWezm3UkOprWdVyyfJWjAzNTLCztNIq1lR4qZbcsYYcSeaQhLHQONlveIUwBdgs72kaTtSytzd3XI4HJZ1o1t1NG1T3SLFdaeoqiEVoqwbGhHKF4SOlBVTEZ2aRF70XajnKe3iE7e3R2ETdbbq2ZQX4sMcM7m6oZ0PlfPk/WXsrF9RsPoxtvNE9hxQfHgsMcaFsSVs49oSqAQEeQiuzYlWSiNRKUoJlCxJqdUrZvvuhYlAkbnB6KUYVw+gJliaZMQAZMwGb1uKbSlaE0ZheThX9VyY1+k6fkthqpbtwzDWlhyHqVIMxlSAGYWmoIy0gs0tCkZrVhq8tjSNMEC6xos7b5G5xWlLRGKiWGMmAGtcdaMstNYxhSOxT8QkJilDP/H1r39V2PbWYL1dtARTzHTdWlKuAo2zrFrPq594jWlK3Dx7xn63E3fHUubcpBY9I4fDgWEccVZLC3kFogT9rW1IiDZOodQYUABDbRrGcZhvQWX+KIYpcjz2xJwYqnGMoBQCbO/3B57f7PFOGP1yjoHVquXxK5egKqOeanpx/yFgrhpKdVzELc/B3xgT4xBqU+R8n+U+pXIyI5m3rBWubehaYSHNu/qf/9iH956Dw0EYWj//t1596XPyK920fjEJ6vtvDWp95tPPUQq8NaSS+Vf/1X+WcfrOBPcfbitPTabPQY2aqMdIIS96SDMTP8aAs+4eAB5LxmEWNpDsR917D4pFt6qUIsKdnJzkZ/YmClZtw1uvPuKNR7L+h5hJRROzIqaCsw3OelrvSGFkv9/x7OlTHl1f0DpxrKQWxQuFUBIpVFOuMJGrO+X5OJuqHpUIt2vefOMNXnnlMev1GudFiP1wOIp8BYXjccR70e7pj7eVAaxYr6/pj9KymkJgSIFZE3TeitJSKIwZlSIpTpjqrn0YJq5a8Eb2F+TxE72snHn82mNubg8Iu0vOCRTOrlluIDBrpj3c5FGSezIzz+diQ6HGHykuBgjLel87bETq4P5aYK29p/25/O3eEeSazIOpzB2UGBDlJCQDqywkGKeBUsSwrORMPwQ+/OCGaQriAF8dZ61RfPPJe7j6TNzeHogRXnvtdcKUWK/XrFcNxlgee89nvkcKht1qhdKKzWYjRQ/XcHl5Sdu2GGsWjWXnPSjN17/xDf7u3/3bHPsepyDEyDiNxBgWgf7ycN76yE2K6rND2uwoea4Mn7O7FyMoWBx1lRKws1Aq6EttPTxndAvwqhEn2Fxdyu+1SNbrr7SBs9ZViV0qiKy/PeRxvqbWgyeriDDSvhVj9XwMye/qLGA9rfUvrf0BVQes3IcQpYPG0jatPF9FCuQpJr7y1W/wd6//Ea++es0bjy4krki5Oj5LzGINXGwaPv3JN/ny17/GV7/yFd566y2+//u/n3Ecubq+ph9E6uDR9SPGceC/+Mv/Bd1qxbvvf8Arjx9jrUi3LKdTi5snhvwSIi0nWWbBMmAGA0/x66nQqmqnmOQWUJI6GSQopABZxD3Xq8Lc9xFj4vZufypqKkWcIv3tgVImpvHIFP8JAWHfavvSl77Ee++9xz/3z/1zy2tN0/CbftNv4md/9mf58R//cb74xS8SQrj3njfffJMf/MEf5Gd/9mdfCoT9m//mv8kf/aN/9IXXG9+K9pK1xDhh9YkCSqYKAQv4sD9M5Gqrqy04KwHgOA5st1tSlJ5nithx0la9K8mbl5ErToSG3X7AN46ua0RItw6+/W5kd9dzOIyiMyQZVJ2YJQEOIZJHeUDnRdRaSwzxlHzWSrvtJKHZ391WgEtuuq+GAEqJsGYMsbraaMossllERjDrSvWulOBlcimQw8TN8yONkwBQKdE3A0mcYkpMU1oWB+ccSUmtM6XMlObdiibRNJ1EXwtiOtCsGowzDH3AWsMH7z7HNxZyZBwzmQOvvnbNbnfk0eNLAbmUVLFikMGegoCY3cazblrSNAmtFqEX3zy7FaZdvcfoIgwYY5hyxjmhiDtvmfqZIWHJOXAcRqaaLDaNXXrgU0g4pHU2TBG9bTEW9rvAaiW051k3xBjNFDLOG95++wKlLU/e3zOMpWp4JZrOEGIhRmi8F3BJ29py53HWYp0lTGKDHOLENEmgvFpZSrHc7XquLzekKHoEjRdNN+sc7UrsGqV1ZWL//IC1ls0rHc4ZYo6MY6jORoEPPrgj58JqvWWz9uTiWa2E4Tf0Ae8N67UnBLmvJRdWreX2+cjllcV6EYe/utxQSoAirInb24H9buSwD4SxtpOY2bFHMaaJdbvmgyfPGYaJXODqcYdSDVdXW9F+aSw5ynVTenZUCuwPha987SmNd0z9gVXnIGV8K9dvClJde/XVSy4vE7vdwDgKE1QVVRkFEgRZI/TllCJGWfqduL76xpKSjGdtEzaZRS/2uO+XNsG2aaRlTCmmYUJry2rdsjvc0G7WpKPkXE1jUbUFLRfFoe8ZQ2DdrDjso7jKDoHL7UZsq72GkGXtyAjYqUG3lYKuDKkUSolcXq7p+xHfeFIsPHptjdE9+8O06BRmZUjK0ShN5xpyAOsdSjlSyoxjxnYjXmn6aeTOKIzb4GuroLDgpPVTHBVPrKn7YMJpbp5fT+U+e0XaBDI5R9EwAbAepRQxi+aPsQWDWbQUz7f52/JZAFSUsAeh6kTa6jI3SsAk7QTSNjsHyA9BMACjLdb6GrzMBP7Tuc2gzukTdaZVp3MtRdYISfIFhJf5OS1aYNqI+cocezvncVrmUUohx0DTNmRCvd/CuBG2QGSYAlNMvPGG5+rRKzz94F1ud3diLgCsutXSyjOFKM9uqUwkLYyvxlvWqxVN29a22yStjSWSklThYoyULGtYzoV+mNgfe3a7AwrFtdnQtPalshxLG3qpPAml7q09DwWPhflZExL1kqTzV7N9C+BrBhOWxKn+PidAlxdbtHacUqD7QJ2ssWEBvGaGgW8vUeqU1JciGmsxR1x1BIOq6XV6U2U1FPow4le+uiMZkrLo1mFzFk3GEpbacSmyXoVpWoLLnDPHvpf2WCMalI1vWHUdShm0KlhdaKpg+fm1cUScKiSjGZTMkdYa1qsWaxTTUVp7V13LNImj2wwKlJQo6fTkDGNiGkcOOxHDb7oG663860SHrN8PVXRf07UC1GzXLa+9+ipTmoH4DPqITqL/mGJBZdiuV7zy6hXbVUvMsUbj9T6egZcymUYKatGPkwKSoetWy/U3aeKX/tE/4itf/mWGcVzMMFarTtaLJOzWJ+9+ky/+rb9P4x3rzZrjkNgfJ370h38dn/7s24K1KZaiwXnxYF7PZiBvrNou3su9mre53VLGYtV0M5aihSV0yhFFAsF7R9c0OKf55rtr/voXX+V3/Pb3Xngc/ne//3/B7V3zsiflV7y9/8F3zi5TStD5XERRcbOdGJ92v4qjUJTUUciMYU6ACkYaSaWIm7IwuGtBemEgFRYGS5o1mJSmbdplLjifk2KKpxZ0dWLszm13c6tYzpnLdUfrHY8v16RSdXmjtEPqpmEcC7lo9gfR29s9f87Xyi+Rc2R/+wFxGpFOiSDxSs7VyKmQUySGiRCEUWzOEn1hdSZ0AW0sb7/1NilNFUivMO3jS9H8Gyc2mzWbTjFNkTAJOBzDxPG4J4eIrQZI0mGRzi+7LL9pRPZcCGHgeMg0TcflystMlRNaJZwW2Q2nNcd+YHe7gyW9ZZmvtfFnX8BLfmbOymuL/qloX5IU3VJOi3ay7PrlEMR8XxWnGGF+fWn/m+eU+auLAANGiV4nUGUdErv9AMpRgGnKCxtuGAKxCt6nOKFV4bVXL/k1n/0kX3/3Gd16zfd93xe4vtrSrddcXmwoKLr1pp7qzN6T1sVZO3FuR/TOVVOFyubSBtGzuX/cz26e4n1L26wpcSCEqbaTnl/pj1eMyjkRkzAQva/GNigmaTSq+mvSfip3Z3avPz+ssy8uoPIsucAChGSlwBg0wlz/6GNUde2tTsiz1AAf4WqtdNVp05QcK/NWEluljOCv6aPjEAGBCkrff4+cX+IlUp4vHYdaa3FSjfcLi4kASdh8RyXPeSlinLXbHXj3vSe89+QZrz66knltpm2dgVRt4/jEa6+waTv+zt/+23z+85/nX/nxH8cYw26346d+6qf48OlTXnn1Vd59912ur68IYc3P/+2/w+uvv8rb/q0TplXElVSpLF1AKZMTSFv8KS4SRrl8JMapmjPkeq1r54g+6Vou8bjSKG1FI1UJnqFLoXVqiZuAahJS43Qt0jzKgZ4id7uDzI3TRzAMH2zfVSDsvfdk0X399dfvvf7666/zla98ZXmP957r6+sX3jN//uH2r//r/zr/2r/2ry2/393d8c4770iAVxIxHhctKeeljUDYC/U/JRRhcbmT5IVcuLhaEUNgd7dDKY0u4lamSGglE2m3allVJkTjG0oRBlCjoIQIlT6YCuz3A3d3R/rDRIqZmUKotcJ5g6v2y4d9z9yeoa1UKY0VO2FAAKostEVjav8uohPjO4dxBl0Ud8/v2F5URorWaKNwTSsTT63OhKKwzuFKIZeRnHIV+5eBFyqQJQ6QQqlPterkvUM7amuWCDW75CllQmmISZGC6BflIpXdGKIwPiq6O40RaqvFettCgUc5iFBjAkUilUDfD6w3XRUtV6w2KwlUlBKdD5RUr4zm+OTIK292DP2ALopu0wqNs7ECPupSNcgUwxQ49BNaiWaQ0pBVEldDn9HJME4D0xQxWjMWAVW01Rz6HjPN7aKGbuXxtuHydU9/HFitPdoIPb3fB6wTNkVMmTSNkpjkgnBKNce7yC4KpdNb8HZOYmqbl7Y07czEofY6F5wXlwxlTA36Lc4acoZYlAj3N4axDxzujoQpkhGxfGsMMRV8p7BFJslDKjx9ekdKmYurx1w/vhChfSAMgXe/+ZSuE20lZy3WFEIIWK243MoEmCvDx5oKRIckbZioSptX1UGygtJK0zhPt+44HvZcXay4vd3x7FlEGcvdXc9rrwkIZiqTJEyFMEWpNJW5OhWhGHIc8Y3DO4PtPHGK7HZ7tDa0K0+YhMYsIEIV7te6UoyrsUMJ0vqZBPTVXtG0To57jNKqkjOJgmssQ9XEkYqbJo0Tbt2hcuHm+VGEdhDgIlV0wLbCrIhjxDaWZtNhrKWtvfnWFHZ3h3q9MmTRetGmLC5hsYggfqMVm4sNkJnGaWFypJighbZzHIcedGB70dIfU6XcK4ignGU/jFULy+DXlpISwyGhrWGYRrxyPL+9wz/SGL1B57n1r+rRZCi66gEp6c0/MbbOgy0R+YWE0dA4SbxyKcRYzhIV6PuJ1Ur+nvLcTvRRYIgiq9muulZ2VSYSaY206sZ4VvU9dcOcFudazVZKiQA50jLd+u4MIMm1WnUvWhPbekVlr0iwNrNqcynEqUjwUw8vzs+AOh1DSrNrpwSDAqzWN2iFVoacYr0mGm1Fe6lU4WzrDE1raNtWqvr9wBSE1bBerXl0/YhXXnkFimI6TIQo1VNnDb5pUcaJcLKtOhYVt7DGCFyQ83LP5/MoReaAfhjIJYkmToKhl7VJtDFPlfXlkpW6gwoivhC4zsBTlmctRwELiy08fOvHjMtf3MoD2+7zMfUAHHvI/nBzG2+tiGnKSUibQpjGe9q/YYo02wvut+/IeEqVEXjO/DkH/mZNkJwzyTg671h5g1UFzUnXRhtNSSdzCqVEkF8pma9nloNSBWWEbdg2hs4nrA6SjBdpR7ZFYQj3HF5Ljkz9Hu3X1UVSigZ5GpjigEkTV9sVj642HA493bajH0a6dUeJcUko56JdrvdWKQHxjTYnoCDOrR9SrW+8FC+3m47Pft+v5Zd/6R/XsdoSnbj3Rp3EHCUVVMm88eo1r73xuFag5TqmIHOaOrvWJwbi3JpcU7PF/ROaruHy6prNZiMJccl0bcPFpmOzavBGsbsbeL47EmPiK1/9Gl3b4pzj7bc/w2azPUvgWMbJadxXcEtVZlAI4sRajVfmTeYoYYzNTtfaWLxrSNaRh3CPEWZ0baF1lj/3Fz7Dn/l//FpA8TN/5UXm15e+fPlRT8qveHvyKwDCrD0h6KJrN/L0VwWEwT/60vfzT33+HwByv22JmJqJWmuJ5cSwFqaQXNsYBbAvcXbGhUIm2bS0mmut5TkuiaJO88AYpgV8nnVKffIYbRYQpW3cqd1YG5R1KNegXSMatb7FmoZhTNzue4YjZ1qCSgAQVfV/azVGhvB9xvQ88LRWPLq+PBP1LnSrNTFoRGN4FuMXkDWkxGXbotJIU0Gt6SiaXo02IiB4vs3AoFb1St2vhvimlVi7LiMiZXAy9bHGUEyR+GvOVV+Y3z/mhF8KnOnlzec7F4bO15wTg0Utu587fRYw7EHhZCnqqJPy33L9KRITLJ9TvPfkOV/75jNizIQo+rJ1lWScQmVoJ1Qeub7sePONR+z2e77ns5/kzbffZHNxRbdZ4ZyvYIJFaVe/7fzKFChiwOTNSYsvxkRMGcysD3v/fFLK7O52og+sPUlFVJ5dg1W9HxL3LLNW/eKlbf8ME5SpSsaRm8dDjLTesW4b3rs5LkAY8zU7u33CuBZN1dO5wSdef0QpheurC95/csPT3UHWKaW/5cg43UcDam5nLHAm5aHOvqhIws1SvVCnEy4PjvUl3wa1YDwz4k7H8fJjO7WunwwBpIuhmnG8pPg3g7POecYxgNaU6mL/3gdP+YW/8/fp2pbPfvI1Srh56TFv1it+3Q98H//t3/g5fvIn/5/82I/9RjabDb/4i7/IL/7iL/LWW2/xg5/7HD/yIz/Cj/7oP8Nf/2t/jT/97/67vPfeh7z52icQ3TPZ1zRONM6hsiGOUkSlapnO2xwXa61ompahH8iAWboM5rhALZp+KUoejhUNbY1aCgphji2UMGQdp2d31lDth4FoNJtXHjMeDqTnN9/y7s3bPxHXyIdo50N66cu2b/WepmlomhcrWAWZ7FqvWK1WXFys8E6AiZQyYUp0K8fVVUs/RYx27A+jtKitPNMY0SjujgNWCaOmAH0fyPQ0rcc6QStVHhhDL/bdUyaMkTBlXJPZ3RzZXq2IoYrZ6fuVY2OFYt22njGITkiMiW7V4BuPc07YaPVjSilc4xYR5HEcSCnSdp62dQJcYXj1ldcYpp672zvaTnrSjZ11cRKu6lzNm1aaMVTByiC1slwSXhvCkAltpmlEfFzrGaFV+KZBKY2xBhelrS2lwjQJ2u6c4fJqzf4wcFopZEs1OKBkvBa2xXrbyDXOUqkqpXB5teXph8/ZbFeCHBdx6bi7ueP9924oRUTZ1xcr2s5wvAusNp1UyKoLIkkePKPAGRHXLKrgWyei6kFXAe2JFDL9UEglYZQTgd0YQUk1KeeEr2LbSsHmosV5w+3zPbfPZPRdP94y9AGjC+3KctyPjKNimiwpVZ0nZ4VJUVtVNhvHarsiTInGQy6Jw6HH+ktiEO2RlLPcR6vRJaFry2Xbedat5ngcuLr0NF5TQsY1wlhIUYFyTJNUC2RxEhfO/iBsxM16y92toPjr9SWrTYfvGlKUKpV38OrrLSXJOBwnYaVs1q1o7ZlMt7KEoBiPkeurFaUkYshgFWEMYiqQFetNg3eWaZDFpO8j7339hutXLni676s2mow55zWbTUezchx2vQSLPqO1gJeHwyT0cSJatfhGc3l5wbpT7O4ObK/WxBRF5yqIfXTOwmKy2girwWS8VWBEN8p5x93+Rrq/tDDrjDdgNetty2rV1EAtc9wPGG1ovV/cl1ZXlwL+jgljm0UbyTcrSlbCQqpBt7DLhPllN7a6wEKIiaZrmEIk54hzsz6UiP3HlDBWwMa29azWnr6XwKI1mlQifmWwXjNNhdZlQoBpmMiVyTj1Y23Htks15tgPvH5xCWisy+JwZTTOGbRyjDGBK3irBRwp9w07tDFoa6W9t87bFoOtkZLRktzmfKrcyYJXELZVbRlS0DUwVmeulCSoMLosi5xoddTK3RnCsqwZpUi7VtbksTLDlIAzc3VQqZNLjZgm2Hk3aHRN2JO0b+dETCJmq6lin/I1FcQ6rVdZw+zqnVIN9XJl4s5rQBVBXgocFVgqNUHLOUvSXtks87pBkWRea4PSForoqhhjubq64vr6EfvDnuNxwNmGi80WpeDR9SPW6zX7/aHqS0qgpZQkdNaKu7LTkoybRcxLWqINiimmFxhUpeSaJFYwker4afVy32fQTBQIzhOQKnyqTuOB+WuLtI7WDwt2NiuGn4FTv9rtnO317d4nejBVbkAFUrYU7MIMPdH673+23V4AFWCdEV2EVWCMru2/9nQss0bNcuOFJaRMuzgi6gqEzQF7ybPt+8zMlD2kHEUTJAVUqWz0Gtt7p1l5izOFXHppTdaaSkIkZUWqiYIlkcNQWyJrkJ/Csl9rDOvOs9lsWa8PNI0j5UjsR7RR3PY3OCXrF0oEwlMRA42ZyGlQkCRIdq4Bq7Ba5tWua7Bac9w/4fJyw+72kuEoKckwHcl5QrkCztA10Fhh7oQwg3mFaeyxpcF5fwpHavZzbroxG0XMQX5WDV/65V/m0Ad+5PO/jg8/eMLjyy3etRg8WlkBgIeRfhzFhKayNT/44AOGYf9CHnMCwuY/SMtxThPTuGeKPelBy41S4BtDGWsxxxiRjdCGlCWZPQdArLG4avjz5a9s5pPliz//6IXx/Yf/T3+Ln/iTP/TC67+a7ckHF9/xZ7bbaflZK812G37Vx/Gpd54t84W2DTaMJ6YB91sZF/CiiJZiygXnirQ11nuWS5aWOgohhaXNrlRAPOfMFKfKPMqis4tiGIfFNCVmAd/srClVMqoWRLGeohSbVYPWDR8+ewo54b2vDuwCfKeY6IeDSKN4xziGuj7OBcIZ7KgAvrPc3Nwyi3/PDMRYMqZqA86vay2FGO8etK8ZvQBpUhiQ3EYZNS9nC6ggMfNpPJ4KKXJsIotQ9ZNjYqzvyaVIHJEkItDnOoz1uO4/UC+uBQqNWdp25sXs/kN43qZKgVILQPeYYvUyLu+FOm+LPvKsuKpgYRIqdf+cUxIQ6vltT/8ArJ63tvF07ZpVa7i+WnN5fc3bn/4M3/drP4PvLkTjWXYoAM00ging3D1AnSIxzSwiL8CVIsWJgoEshbxTK2hhv9szDAOr1Zqr60fsbu8oOZLThKoajGMRgxSWy/DwWp5AnkVCwBjWqwuuthfc3t6wO+xoreE4KHHMTJGU56Kp3B9VizhzvqyKSPukIPPAK69c8U/90Pfx3rvP+Po3P/i26/a9MVHBsPNWSL0wtOu9m8+vzK2dosM8i+PzMb7uvkzCaRNzByMxn56df1WNv6puZZkZ8/e3F762jtOZ0CNAupUxmUXG5enTW772tfd59dEVrdAzX9hH13p+/ed+AGsd/9Vf/W/49/69/zuXl5f8wA/8AL/7d/9uvvCFL/Daa68xjiNf+cqX+At/4S/gnOPq8vIEEM7XsjqECuiaCFWj8DyGBdFYzxX0iylWJtnpuit9YoIqpRZX5mVuqN85P4Mvve7ltO6nlFDGkkumWa/ZfEzN+e8qEPbGG28Awvr6xCc+sbz+5MmThSX2xhtvME0TNzc391hhT5484cd+7Me+o++LKWP1rOsgVOFpFGTbe2Ff5Szi9E1jWK0szivWW8/jxyuGPlGy5rAfeX574G53EI0wa9nvB7y3XF6vF00Oq0XzZZ5PjVE8fe+O/hh476vPJaCvWmDLpFpFwVOO3O1Fj0mqT9Qqu7j8Df1AjhnnndD8KjssxolCplt7nLfSVhkKGk22hbvbkbEv9Hd3XFytEPdyQ/YiFp1SDfSUJLInKFy0kBTw6I0t0xBw3mKdtH5Ky1SQBEVp0ctSwq5pOl/btkb2BwHWdnc9SoP3orWgzSmBSZWCbozBt4626wih8PyZODo0nee9dz9gv+9xTkCCbt2KZbBS+NYz9KMI/TeGV19dMyVJWJ3O3O72oAq3NyPOO1zn2e9HpjRivTAnlIZErfaZIsSiUkQnCblHSgszpFu12FbGlDWWzUa0u1CSYPvOMgwZoy2by5YPvnlDmBLjfqJcee52g7QwqIzzhW6lGAbNMML+EEgM0pKEUOI//ek3+fqXv0Zjr6qQukxuINbXzmnatsU7w/5w4Hjs2W7XojGVIwrNh0+PPHnas+mMsBqVolsLoLjb91xsV2xWqyrgCuvNFZfbS5q1k8VUCyttilCUQVup5oVJgKrNtmO1bhftGec1t897cbTJgXbdMgwDUxA2odaFKYAyltWFsLya1tAfep68+5RXXr8mzoCfKgxD5P0nz3nzE9e0jV+ESFOq1uBTJmeFbzyXFw3TOHJ3d0dJDZfXW5rOoyYwWVU3SwHnchJmhHVgnSXnSYSYV6Jf0ljP7ThhraVpZYFJZEqKaBykQprExVRlCH1ivVqRx8w3vnZD2zXsbg9Im3WqAGYNDqwWHStV0F7EyGc90ULhMEy01UXSYzFOWp+zUoTaEsQMmuSMKpnxOFbNMYsmc7Pf8T2fepvdfmC97cQQwERSGBh7eTZzgWGYUETarkNZzVQSz296Gm/xjTkLsAzWKUpSNM6ybRpSVAxDZBiHpcpaYJnHTDUWEQHqdFrY6v+nytAyhqrBqGqluDrknely5ZwoOZFVbTGsYHwuCmFu1MPU1EAQ6XUvmSEMeN2glaG+XUJjbUA1aF2qo9oZ2LFEdHNgn5lhiZhFh0dXluo8Z0u7p4wHY06ulnPwdQ6CLZuCopXoNjz8W43bBegoYBC3R1VQZKmUZgkaVqsVXdex3W7ZH3akKaAorJpO5itn8E1DzllaroowEow1kgRWMMIaCcpijGSjF1mlGfErKd5LQOR+J2mFU/fbR84DY7kOnAKiwv0/zmvj2SZSBlUwVQvz+X+s7V5r5IP2zfPUDipYsRyrIiYt6+Kcj51tSiuMs/eo/ee6NMtrquCcJ+Sqa3beMnTvSJY9188JqyMkAZSdEk1K46pjcDWPsA9MCDTzOK+/q2q+oRVTyKxMxvo5wHWUYqqTI7x6tSHGV1AqY6wjk5hCFMOMWDBREevhKmUwxuK9F6DLSvEmxCTtE0Uq5U0jhiqXlxcIaSPzyisXGKN4fqO528H+UBirMZDzntV2y+HY87Wn7/Gpd97EW5ErkLYxVZ0sqwnEg0upEO2ikGSeubvdk8fEJ157jZU3tBrWqxXWOhElx3IYEs9u7oj9yAbLxnm22w2Prh9JK+sD4LZCARVELcsAUjUmm6ZAfigSrZSwsa2rwL3D2IaiHSFkAbepmioIYw8lye6v//wN//lPfbQD+//1//aFj/zbr3R7/8l3DoRt1tLKG3PCGM12M337D32b7bVXezQt1rcY10Kz4dnT9zDL9ZeLn1MmhVgLQ/J8SlGrsGrODVvOdMNS5FzfZjZ/EV0ryKECcFq0KcdRDIKGYVjWGokxa9EjJYgjqvF0radrW375K1H+rjXWyFyRciKphG8a7DTdYy+BdHOYCpaJ4L2lbTvWq5V0lNROyJijiNo/SGqN1lxt1yRZilmkIZGOgrkANoWJkCJTCAvjPcVEmIKsGVnYz13XUnLh2e2Bz3z2U5QowEbMhVW3whiLcx7vG/m3aRj7gTc+8Rb/75/6z6vJi3SSfPvtBALefw1OMM7Zv2e4w4khKuNBna3xshTfB7lmuZcCqJKBtCx+MwO4IOPm8qLjOLx8PDeN5+JyTU6BaRq5utzyqU9/Cuz6xGCd195Y1+E4Qo5gHXXCpAaHpDAxJekyKkmKVSlnjkPg+e6AMYYPP3xKP4zs9wd2ux27uz3Hw540DXLUZkUmobXEVOMUpQBfx23OhWkKjFPEe7uUsZwzNI0lZUXMA77bcvXKI64fXTAcRuLTPV6Ji3CMsQJi8xxY0Krg9HwqBYxdgLCcMt/8xofEkGi8Q/XjdwyGUTRGu3sgbc4n508pFs37rBGQ1mgtwvzfSQlujjWNMXjn63N80vsqGUJIjPFsEBaqQ7fExs4abIonALWAsgaFdIbNhhUqJdCFojVDzDz54Bm/9KWv8OlPfYIf+eHP881f+vsvOcJC6xs+88l3+KW33uITn3iT3/W//t/wG3/jb+TDDz7g53/+5/n5L36Rvu/5n/3Yj7Hb7fjcr/sBvvD5zzOOIymexrOpANaQJoZJ5GiMNou7LVQwK6eqU+gW/KCcxS9aVRdtRAPs3tFmAe5dK2ShnEUq5eEYmL9H4onA3Oo+jkE6ij7G9l0Fwj7zmc/wxhtv8NM//dP80A9JxWmaJn7mZ36GP/En/gQAP/zDP4xzjp/+6Z/m9/2+3wfAu+++y9/7e3+Pn/iJn/jOvlBlrFZ0nUysMQZSFCH6VC2KvRMwzHthV3VraeMyVtGtHUaJeLcxcDyOVcfI0DRO2ilDZRF4K+/TtVqeCzfPjvRDkClJF3I8VRLOo2aFUPmmcWIcw3IjnZfAT2mNbzx97AFBP40WcWTnhHlhrdiKllgggbaK435gdxyJyuC92IsqRJNodh6bt9mie3bfO4aJqR/xraDWzarFaI2m2uAWIIsorrWzg0p12owiqj6lgRASDhjGia7ztG2D1gJSppgWG9S2rXa9RfHBkzs2a6l4p1y4uzvQriyPX7mkXTUyiR9HQoiVQppRJuNbjdKiuRXCQE6Zq9e2HA8joPBORH6LoAlSJXUSBM/tD7515Nt+0XKgVBFsBVMRQfCmtbSdq4wqSeRXnbhZDENge9HRNkYWhzHSrhqsEzFimeMN4xAoudB10sY0TeKoN4xRkk5lMNazXbVM08Sb73yCUkQg93AYaFvRkclRgKAyZXbPdmQdcc4yTgGK6BqN455+iJATMcKq8wsb0HuDbyzrdcuq8Yvxw6c/+Rq7uyPOekIc8E3Har0ihEApopERYnUVSYW0m1Bk2gYu6/suH69RRZ6F3f7ANGaOu5EQwfsWrcSJsCBshZgLl69ecRFhPB4IU7UJL1Q3s8zXvvYBTePlWarPiGsc/ZAoCYzTdJ3j+nLD89s94xi4fX5AGUW3aqBIQpgS+NbTraomX54wJgmQdr0lJTgeJm4PPfu7gcvrrbjF+trG2Ugr9dhPDMeJEsVo4aoVoHp3PJJi5PZmJAYWgKDkhDe+Mj8Mq3WDbyxxEn22khLDcMQaw6r1WF3YDYGr7QbrFDFEyFRB6UyOqSZ8Fowh1OfYFlCN56rZgpHWp5IStztx4gzDxDTKszcNIr7/yqMLPvX267z77BnT7cgwTkwh8LjZUqJnGCKsIr5pCKqIzXedQoTROru0iiFFrG57zlu8txQlLdKqVoBzKZQ8u9zKIl7TiGWKlH/rGMhJBI2LcKWyFQvUcvIfZC4UgyJpU4GzE2gz5ZHGtIAmpwpUGWlfQJUlYE110Z3dFRWVXo1adJ5ymRMeJTEvEpsXSk0UEOBDy/GnIsDZR4VqOVcGKtzTWVMzdQdFVhm0MDwWvZccyUqCM2cdj64fcbG9YByOfHBzg581FtCsV1s2mzX9ODKFXAMnvdyTuY3OGCWg4HwPygkkmNv/ijYsVtdJXItDnJkIGqOl9SLEiHf6VMmugci9C1Hmtsmze3+WiAACIpv7gsbf6aYrAvWwVefjbPfWy49gIQh7KhFCFO2/eg4x6fuJVZnFfGeQFExl5C37ehkQRiHkygSpgfQpr5OAT8bnWQKooFSGUMqZnAJGiQj5qhqwnBEpUXnWOapi4blA9bzLRdxvRVhfPmSq61TOqeZ9Yir06KrDOCl0PbpKPL87EGJiCon3P7jBa01EnB3FudbgvDBbS3VyFgkLlmfVe8t209I0kkhsttLGqy0onSi1nV3V/N67jCPwn/5nP82j6wv+6n/z12kbx9XlFmfFCct7x8XFBdvLS3zT1Kq86Gp659gfe5TWPL89sm4s733zXV59/AhyIoVjLewZtPXEojkOE4fdAXvMfK6sSEfNdtORfMPm6mIZMRohNUqr5OleL/eiJtAxBkj3A/aSCzoVXOulHc7M7nNqkd0w1WUu1jknFdGP+oHvv31hXJ1vOX/3gea+9xiTSOkEkK9XBw7H9Ud+puvivaLpdwMIkzYthzJeWLSITqIi440RuZ80J1QApbblyk3pR0PjKnvYgi6SNxAFGDmf3SWx03jjySoz1LWrVBBlbpUstd1ZK3EAnud+SqaEkTx50fjtqtmL0+Qo348SdoluNG3b4bzkNatVQ5gSNze3WK1pvefVtx9zPAw0bcPl5QWf+fTbFDJTGKEg4DHS+XAcBVTQShNrm3XJjnGcmKaJYRgIUy9A7dhjnMJ5R9u23O2PPL/dMU2RaQoM/cTu7sg0TqAN0xh551Nv8z2/5rO898GRT7z5CT77PZ+mq9qVtrKcdaWHlpw53N3yza9/Dd/4kzHaA4Dio7ZcStXMnd/7sNpSFv3JuR1NMC659wI01SLMA3OXWR5jYc5RAbWZESzwOmJ2IWM/1rnYW80UM+dLSdM4hnHk9nmmaxRDzrz3/hO+b0xgC5Bo27ruVxBsKc7EwNQfmXIWkkD9W0mRMDtjp8yTDz7kl7/0VQ7DxLNnt8QY+eDDG/p+FGJFySgKXdNwsd2wWVfAtIBvPPp4pAQBNVMd7wrRP9vvj9JOrEQuxntL14pOYtsZjFG03lNywyuvvc3d7d8hCIl8MZBQs/htNf/RVESqZEK999ponj6748tffZ/WOw79IM/ownJTy7N2rwhXZB483wS8lvswRwelJGY5aXmW9TIHKKUwzjPrw33L8Vfze+k6EJOMru3wZ+YbY55m9JSHRdCC1D5LKeSYlthzLq6iascCEk+3bUNMhWMMxArUhpS4ORx49/0P+Pv/6JexuvDmdSNgf6rF4nkMaUMIE8f+yJvvfIrr6yv+ys/8DH/+z/05bm6esV51hJD4+te+xmuvvsKv+/7vRylqZ9MRSqFtWpquFRmLflzG9xzbnxfuVF2jcpYW85iS4Ay1ONs4J1p+JS8C+TPbHk4O2ylVx3fus8FAns9pCgLQl0zjPbkUvLM8+eDZR9+7s+07BsL2+z3/+B//4+X3L33pS/zCL/wCjx494pOf/CR/4A/8Af74H//jfO/3fi/f+73fyx//43+c1WrFv/Av/AsAXF5e8i//y/8yf/AP/kEeP37Mo0eP+EN/6A/x+c9/fnGR/LjbaiUP4hxMmWqnaa3BO0Mumd2+r7bSotMVYhbGQzndnIt1y0Xb0Pcjd/sjMUo/d07yUIWS0aaQlAbrmMJA2zraxtJ4y/E4fWTgPsc/IUZxDClleeBEKBQaY5iorhi1pUiZUmnPprb4iIaLbx2qKO7u9uz20jNtnWXbiW6UMYoSorQv2bl9Sdq7okiDMaWJ4TDRrIS1NAe2SsHUB+JBmC2+MYtjoSawPw7sdwe0dlUgT6aVaQpcrhtQStypFjZPFn0aNWteQCqRdm1ROjAcDijfsFq3lKK4fb6n7VpKFg0kiminrdYtV49WTCHhG8XTp89RCpq25fa25/K6Y7tuef+9ntvnB/p+pGkc3VZAiG7V4p1jOo48v+lRi46NWlB2YzSmVvYK4JwEy7OzV86ZoR95fnNgs225utxIu16MDMPE1aMNu9yjKHKczgorUSnGSQS7fWvZXjrR/NCK3f7IOI2MQ0/Xtqy7ltv9kZQTbee5frzBO8s4Bu6eH/nwWU+MiaurFU0TMcaSpgBF0XrFTkHbeprG0bZW2vyQifY4RA7HG3FRdIrjcY82I4pTRbREabsKo9BcTR0/MUnwdLFphEFnDKaImUAIiudP90xTYLNd0XaeeBcwStGuPfvDwL6f0LrQHwdxF9PQto5p1WD9mhQT4xhwfov3AtaqVlKJkiHFTEoR60Q4MWUJ4ITFBq4VwFNrDcaitZgjhCgVHe8NpTisFf2l/d3EcTdx87wnxcx2u5aWHS3aFcpAmKTSWTLCXjCSuMWQiMOENprVpmM4TtzdHurTXlitpXKTUsR5Tc4RraHbKNHjS4VxN+AuN1Dngu3KEoeJFLVkTUZJ1a2AahwlF8IY2N/tmUZH4y2JQttIu8WF23BUPcM4korl+bMDTa3UDbXVdpwi33zvQ548fVZ19zRFa64fCTOuZIVpNSFlppixTmPsSRNAIZVsrXRN4BNhmgi1FUChUPq+z5C0Q7j6HEnQKYDMqV1DawcGppiWSiCINmkMaal+32PFFJkjC0Y0g+JUI1tFJhHShDMNSom4vJlNRUompMCsE7aAUXXuPW9XS7UqJ3OZWgCuBcar83pWBY+YF7zAAjvbcs7kHEgpiqZEZVVpe3KmyiWBBm89K7+qduoS1E8pkhA3yO12S+M9h92OOI2VXSMssm69pmk7jrd70KKZKS0TiBGDqqYh9tTSOp/O6RqfhKHnn2NKDOMMnkZWqw7vNBlTRco5JQqLMMzZdXrZtVnWTHlvyYVMWiLbpbK4BOPfvj47O8LN7UyzFue8n1K/9+MAbSfp17NDRqqh4qooCbXSLxEer8EtFbSdgcEcM8rdZyycnyNVQByqtfw9VtopQDw/MsUpSS9Vk6jUivf8HecMPVmbC1MUB8SSE7YEMoUUIsV5SjEVgDEYLZ9PqNlvB60UnbdAS66MzlcvhT3/7GaPU5IQfnBzh1WWZm3xjaVtGqy1ouGIgF+pthK3jePx1UYKBL5Bl1kUXJjfj7aGy2ZNyQ0FzRQLViXSNPH2q2v2xx2tjZgcON6KTMPuRq7h+8YwTZHjcWR/nEgZHl9f067W3O3ueO21T9CuPGnqeeW1V9nd3VYmluK662iqXs/YHzjcPmc89hTgQOE6QplGXnvlEdv1BUYrfDVjVfUGzf+ebmW9lxlCiIxDoGnd8mdh8rPMDbpKU6RyVjmvfy8KWi/yDwD/6L+/enE8/g+wbdcDz+9OwNe3AsEAQtCncV9g/V0AwmaW8Pka0zYeqyDEqs+Uq9tfBVBsddnUWjMGMXiwNuNwp6JNORVw5uOVgs0pOTs56ErsElNkmAZSknVMmxNYLhIDhUTGcGQYBm5QeCdmDgvb6wGDc9V1vPaq4vH1JQXo+1d5+61XFmOli+2Kq8srkV3xHuc0X//61zBK8eT9D8QYyGimaeKwPyzMypyq4zyKr371K3Rdx36349GjK5wzXDUXeNfhfcf3fPYtri4vaboO71thTDpL061kji5wcbHBGOk2MJUlOYxTdUw/m/mKmIiMhwPvv/eegFX3GF3ffs6X2OQBk+peslzhqnJ6y/xzStIip5H1Z9E3rC+qcmKwzIBYLvl0f1C1dV3ibG0d77zzOijFxcWWfhjp+4lXHl/x/pPnrFYe33jefOMVXnnlmlIC3iqe33xQtU/FuM0bsKowjiN3ux0hyH0bxpHD4VANnqRAmJKI8R/7kSlE3nv3ff7qz/5cLXYUYj4V9TRglADGx5zRBpEKspbt5oJh6FFK0TSiFTZ7IihFZQZGRIQeQhA5lnF0jKGgjOfq0TWPX32TbnPB3e0tq4sNcXesxk01N8yZkCK5JFI2lVntMAqC3C6UVtwdenIpDDGSa2Fn1vnK1RFcnq0TSJmLaFqfWg5LvV9VhkK+ocapZ3FlyeQS0VTmtNG4piHE2vJ8xlI/b/+T2FL2nMt9wDSXzJTDPAQpZ3q1L9tyLoScxJDiwQiXsQat94SQHsQFEj9/cHvHu0+e8rnv/zV0F68y3H0ohfV7W6FpGi63l7z37rv8zb/xN0VqJUV+8z/7G/l1v/bX8vz2lmkKvPXmW1grclFKKfrDgDGa9XrD5uqS/u4g5BLnZX16QL5ZQMIaCM5tuqmAq6/P5MBZP3QuYArAqTHOk1JcTNNmhuLD1sh+HLjd7TBGTKAeXV7y9Xff48On37ooNG/fMRD2cz/3c/yW3/Jblt9nEft/8V/8F/nJn/xJ/vAf/sP0fc/v//2/n5ubG370R3+Un/qpn2K73S6f+ZN/8k9ireX3/b7fR9/3/Nbf+lv5yZ/8yXvtFh9n2140bNZdBSkmnBMNLWvF+S6lQqc845RwTnNx1fLhkwPOSbLqnQBk2mi2ztC2CmOFwhuTJI/ExDRF4gTRW6wztN6hsji4WKtZrYSFNI2BMGXKWTE650JOBd84QkhV1O30txgTuztJpEsWdoJ1ouMiKFq98YB3HukBTxWAGdHO0VhD03p8IwyKFGSSVFkS3ElDQTH24vx32B9FeweFcWYRlp+frRDFzdC1BufleFPMlQ2X6fs9F5sLckqL9kypgUEImaxFq+z8gbZVA0drESc/HgPKWnzjJMjIidWmwVpJPPu+ZziIQ996u2IajnSNUC+1EZaPmiLWOppiuDlOTFGokEZpnHUYY6WiVy2ch0MQFLpr0EMix0LMwn5CqWXS996SMoR+kiVUSUvmqum4uspMY2AKkzDfYkYpuH22x1oj521mnSMJXmPKtK2ibTpilkrONApDaJ6Irdb04ygaEFYYab62t6riSOsWUNzc3NLvI02rWa0uBKCNe0KSBXm3O9C2W1Aaiq4mDQLIhCly3CWuHreozhCiuAo564UGrBRxSuSY0RqGfmLoD0Ch6zyj1RjXcjhGxmFimiLPnw2YmvD2R9G9cx5CmtAmY0yBFBlHYRZO44TbrtDWgjmg6tiQ6mKicUo0Z2rVqWQBElMEiqZdeWkbg2oKIMhljAnfiMbMMEzs9ntpMV6v0FoqR9YqCond3cj739jhW8s4BOzacd7JVRKkUDjciXNS1zVSOQ1JrOtjJk8B78UN1TkJLKw1rDa+JiriNNm0Ft9KdcY1mTgVXNLkGEQHRGmmPhGGUYDrKoabqjZY2zp5RnIhTIEQIiEGtFHEMHHx2jXf+PBDXGMYjoG2Eebo7VEs1UUvMS2YxNSnyrKD7aYhhILznsN0JB2DPGtjxOEZp0jQTtx2KlAx66MIyaHg66Kfpki0eqE+lwowK2XxVuFc1eAphRJnIfoz5qrK4BoII7GwLJAvi4VFtF+0uxLCqkgx1H1BJKByNUopQNYL8JVKqsYe6dT6koo8z6qynGY2G5mQayvkAxbOXO0LWYTvy9nrWt+vWglTJy4stKIURYsIvnwIMklabVA4406tNCjGEMgo1m1H27RyHlmAjxADKIX3nrZtaZqG/bFnf4wMIdB4oZWfkVCwxuDmpEwB+qEO1ylTWcCoulalnEi1ouxsoZ+kwpxSQCrshnstLTOQOuM7DwNBdR/eWsTjF43KWYsFQD84zge7WjSzFuTr9PP8UimS5ChOQFl9/eF2DhTu93egLBebi+Xex1Qw1kkNtMysR07XdTmpF6/n8h0VYKdQ3U9Pm63A5Yu7ub8PpRTGnzRFSy3elNpmn+dgvMoTOGMEBEh50ZxrWkOMUsBIMSCcTLswr4wxkngVYfmCkvjJmaWK3TWSMr7yeIv1mn6MXF+vmSZhBYeUhR0TqztblWIxVmO85fFFy7rRdI2i8YbtquCtlWc6NcSgiaEjRTEBmV0VldaMoSWlDYd+hFKYghjyzJpEMWasUWw2nm7l6ucEQG99IkwfEAbLECbuDrdcbdfsDqMUlqzmEzktBbH9ceDD2x0lZfZGc5EVdI6kxA2aooghLXOY1jInaqUX9lNBjEHGKdAPEzGXGs/IXBur011OGZwwJLS2xFJfq+O7IGC9M4bGCbj92qsfzzL+u71dXR3uAWHfbnvygQAnJReyymzW373jTtMg8gHa0noHJIq2tQUykUMUzSetqm6dAEGNH4GE4gTSnVr9VZUaOEmglKVYUk1R5mczwzidzkeKLTMINgPRsna0OkKKXG3XvPvkBm3E8Mc7W/d52hpnad2aggaliZvAunXEFMlKYZ2FIjpeN89u+Jn/+me5eXYrQNuz5+QcGUdxnvONMNevr6857HdcX73KP/3P/Ci/4Uf/aTbbDZv1hs1WTBC8Fac/ay2u8QJulYzK4piotRb3dD2zWe8DeCEEcpZm3pSr5mjKhGnkuN9zHAfeeP0NPnj2wWI4cG9Knn9+MP3L8yXXN6Ukv8xyMAvDpxZZ1AN87GzXs/6XzMPl/nrBXOC7X0yQtUS0w4xWi/ud1pq333qNw3EgRBkfKRfeeutViU/HwOXFitdf2dA1nqI147Rn2CnycCcxVJhEVqOOkVIyMYykrBkOB2IcxYTIW7SpZlUpcnt3x5e/8k2MMYxhEnfqmJg7rzNULKmgdSLlIO1kRUCx031TWAvWgtOWmEo1yDpPbqtJUJw45IyxlhDfANPgfcvjV1v2N09R5obnN7fS4ZJlTjZFL9cxpFR1Ws/GzNkcmCoAKffy7J4W0dgqRZ+Nl3IWNyRyqnQ09a1jh/MtppNUR13Q7323MVpcQsupgDUz00ptIc6VxeusJcQoIFc6Mb7msTUDlPfGYi4vAF3z98+EH6Pvq04CDNPEN775PrvdEeNapviiXaUqhbZp+J5Pf5K/+bf+Nv/lX/5pVquOt9/8BN/z6U9zcXHBer2p8bus7SXJ+N9sN8QY8K0XkC9KN9zcwv0whhLRoWqgVo1GKIV+6KHtREPxLP6T50RX5nm9LkWYrCFWB3Wta+FCLwW/w9jzwfMbnt3colE8urzAKM2rjx/zD/WXPtY9/46BsN/8m3/zt6ymKqX4I3/kj/BH/sgf+cj3tG3Ln/pTf4o/9af+1Hf69fe2GMB6w7EP1WmOhQ0GqgrFZ5og7gohCGhhtAxiW9uXjFGMTGALxgt13CmD8gY9RaxNUo2LAYW0TPb7xDhFnFPSI53AOcX+biJM+cFxRvbPe0IMWC+T1nrbMRxH+uNYqyDQeLMARqj75gFGSYJcioBSsxjlyknL5tp5TCONIbpA6wQQHGPhGCJDLEyjWPvOE0YICetqC1F9yLTRWCeByRgK1qq6CMI4JUJIlKQZ+onVytO0VhJOq8lJKrgZaXkwrgrt1gRhfrhSgqZtgCNd59nthGE3jRPTMIrA/iiui8YIM61ZtWglTKqLqy2z3XKIgZgi15uW3QdHCay9sJ5KSZXaakXQujicF5BuiNOSOIlgsLAAS4ahD6QURF9HgXdGXKi0tF9OU2QYIq5q0yklGkxatyit6DqHs5YpTPSHsT4XBaUzTksLk1JwOAqA07atMMeGiTBBu7JcP+rQShFGuUe+EYAnBmgdxKjY391C8eRc2G481kAMoYJLVoCHFMnaEMbIuB9oWi8AnTdok6sLkqUfRqY+MfYC0M06W1oLmCMLzKyloMlRxs1+P7BZy/laZwg5iJ6cbqUEQmC9skyTwvg6VoxGNy2ubSFHmtq+OoUojE7npA0mZ0I9jpSEHUhtYWtXHq2lTVApAcX0uoI9U2IaA+LEJYl/KYoYDUM/cXs7cXc30OWGR9cXYrqgpeJ13I2EMREnIYV3W2EWHQ+z4LyubZzC4PHe4RsrLZGNFcdCpXFOoWYHuCQAQds2RGPoa+vjeIzc3eyl9QfYXKw57kcOdz3TELh8vGVz0UpglDPOK8YeprEsc8Z0GIRVOClK0uQwkoJoSonuXUEXceCco7hxjAxRquLrbcd+dyRnqYyL/phmmCZ2pmflHCsrQvpjHqsRQUQVWLcCzJfKltLaVLDrlKjlVChmbkmUlkKjRReulLSIr5dSAw7jKJUZJkdbaj3gfmCwJCIzBHXGXkJpsqrhbZlVlgScmNkV4uKXIMg+5mN22i9AR1GIMHCp1eJ70/rpeoZUHYqK3PNFsLfSgZfEKc9nJKBQKmLskUtaAqpzbRqQZDmkvATx1lqGQdYS4yyvv/GWAHbTRNc1OFt1v0quTsKnfZValfPWLAmLqoHevUL68vPMSpaAZnFCrRVTaxVpqBp+Z06YzjYvAXzMwmCZER2lBcScWy9lSTslIct1pwrnkylF1SDxxUDxPmg0g7Hq/vmr8yqwJD2F8oJYefVZWD67XjXM5jLCHMgYI/qZqgiDQJ0BoPN4m+9/fXEpai2aM2csxGJOA2xuH5DdnV+QF057MW/QaGKQNhllxHl4GKal7YUCjVdYfXLPgloE0warFEkppnGUy21KdaqrlVgDHomzSjmdS4iJNGu8Ia35bSv6lOMY2fejuKdF0RBLNRkag8wnSguj6XrTcdF6NqsGjGHlbAWRapthURhlSUYJwE/GaGn9v3LdSZw4SUtaylU3rX7vGCIhJoYpMIwigzGGQGcMKQdKivR9JB0C0xgYQ6IZHHwSKInj4cDucCDFgDeGQwokk0lELlE8vr6SJyXDlJPIGiiWKrY2GlvMEsCHkDj0A/vDwDQMeOewJkmRIyY65+m6lsY3WOvF7CS9MBWK8YE1+Mr+/8Lnb18cJN/F7VPvfMhXvvbKC6+H8LCQvcALL93G0cocZTVpSqxWw3ftGEsR525dndAzSEx/Nt8plTl7TFEkNm0CRJ/rXosPkpDHJIWwWGNwOzvvIvOirDdzWUTfa9HOKRNyoKApRaOVdA1YI/RBRdXRrA6TaInl1fnCU+eQUn8W8EJhlQFzckktRbRhv/7Vd7nbHXh+c8exH2prdRBtJmdw1vLsw1s++c4bXF6sMFbz6//p37BoHc1zhzUWXa/f3ElBSlCLbCDAu4CL99kzKSXGSZhM4zByOBwZxrH+vCeEiWHomcZA27YM4xGnjLSMVSJBqbHXy5AwXRniYlI9xx61mqa1LMM5SyHmbG29N15UbQ4/XweXP9a58mw9OAfKUIpSDTNmHTrRvFuJm733ovFnavKeM85qGi9MxFwShkIYD6TpCIDBkuf2TaOIaaqFr5GUJrrGstkImBBiYtfvGYYjX/nqu7z75EOO41THpnoQt0gb+txqF1MgxJFcMs4ahnkdO1tnUon42hbb96MAjtLZuFzrHCLHw4FnT2+5ub1ju+5wbctbn/oUh+ORvbOEarwlwudSIJ9NJqKSXMP5hmkcltbl2bF1HkucvpIZ9JrBtYdOzYpK0qCK1Z/9XdXPvzCY5nOu5jZKndqmQfJkq6tUQAV5FjOCehwxxUULUFdDIhnL9+fHj5KAkNdeDtrNMkutF+O9kE43N6XM7e7ABx/ecHN7S7O6ZP/s/YVgJNcv45zls5/+JG3bsD8cubq64o3XX6PtOkAtzK6UENMiJTHCarOi5Ey7akm17VLVvy3HfXY651p7+exyey8GaMI2l1bvnOfiVUKZ07WJYZSiUUoLszalhHEGsgjw3x323NzdcXu3o/Werx97vvH+M1btimfPjy+9jg+3fyKukf9DbeI4okWHqBRa40S42VTqZJYA2rcOmwrDNEk1LZul7UHYBaGix4WQMzGJYK+tAsPeSxQZYxKx/CKDwBooVtoKQ8i0rSOMmRQnZm0+qUZk+sOwJETWG6Yh0K0bpinSeEOKpVYVhJk1T0SlFMgQS2KMEykK2DQMI13b0rUN1mgMisY4nJHlO+XMoR+ZYiYkqiCrJLnGSs9xUQmrZbGwRujFwSSmkIlTpvFWhAYr06sUuQYKi7Ea562wGmpQP4baalEyMUqlTYO4zyCAYI7irJMSrDYrjFVst56SZSKMIYhGQCm0XYN1lm69ksC5FycrowvWSUITx0iMhv1uFMp7yujWkFSgJIVBWoMKBd8ZTHRL21cIuepTVZe7LAh4fxgxphGdEiMJ4e5wrDbnItCrtZUWqhClha6YCgboynoT19KcE9pYrLMiFhkDvu2YJtmXdZoQEtMoTJ+SNT6LKYJ3GmVyFVOUdq62lb81/pIUBfBJsaB0oO0ctJIYeC/6SaoOppyk3XW7bek6z3EQDTbnHWGamIaJ42GCCtJJa6BMdHHKhCFijaFbOygy6bpqcTscR1aPO2JKUsEn0zSWqRcafLdqMS4SaqAUU0YXsE3LeNiTKlAaE0whU5TGWghTYZoSfT8SKqtTHIuqIHkG62p1YhJ9BJVnJxLD8TgwDgldk0LvLZeXK7p1YTUJRb27sFgnLQ2ptgQe72Sxb9bNwrCwzrAfJixW9LpQjGOga6rzmZexWhCAvSiIaRIGoBIAwmkJriebSFHmBGcdoRpVpJiJU2I4TmKwEeXcJdGRh6lZe1xr2D09SPt3SFhvGfsJa0TXrCTRCko50awsxlimIZGCXCdtJGITa23DNE6kGGivr8hJDEegcENP57xU3LLGVo2jNAmFvHF+MRKJUcKCTKn4U4GqD5bSyV1Jghtd55JImVlS84wsPSrME6iM/VO2ci8+LTJujNIU66vmiAQRAoOdN1mcVmijZQEOMUhbH/O+FSFNUINw2Xd9po0S7YmzIEXNNO4KEpd0EpYVK+2lqaKe5zKpy+KeZ3bSWfSwgCcZpSxZCz28sZbNekPXddUUZuL6+hGb1YaYAjlP0h5lNCkWYYHlsrSWih6MCLL6qssAFQQBQspL8L+AkjOASA02iwAPrhYESp0HHt6Pl21zy4kIRldgZr6nSqGpbqlVE28ZLC8Eqx8dJM5byuJmTA2kzxkd9/ak6tgqCq3nyu79dsp5s9YQswhOKwVW1+LOPDbLebX64fGV5R8J3OtHlpfrd9Y4PcbEZtue3EbVedD84vmXUkiT6JCkEJmCtH+haxtymQHg2ppQdTjmcTEnt9oYqaDXsTeDxufJr2iHVbZMoc7dtUKtBaC2lb2EgpX3bLqGKSSmKKBUrP+F2NT2Y5kn2ka0Bu2s1SNci7PzrgX6esFLLkj+r/FO2ra99wLKJrcYz0SqPl/OAohNcWnxHceJgmJ/ODCME85EvPWokti0nsMYqqbUxDAUDoc9cRp5/XLN9WuvkJ8+x2GxrcNfrmi8xhlZ90LKS0VcKYXORdyBCyilGfqhyiNMxJAkYfUeleRcjRFmu7Uyh6NUJSjMWkXyn9EirO9rhb1pX4KWflc2AbZ+8HPf4IOnW47H+y3BHz7d3Pvd2UiI/iP39rnPfSA/FInX19+GEaYYKbykDblu283u3u8pBXRKUtAoqgJLasGTlb7fxq8ptQ3YnJLHCoDN7yllZgeXaqyll9Z7Y2VdSTESo6yR58/X4jSoxdXRWb8ApDkGjrs9KUOeoujA1cK3Zh73suUyA9HCsBBBanEH1obFbbKUwna75Ze/9A32+2Ntt6071BLjmVgI6cjV7R3bbsXd3Y5utbp/Ycvc2p5Fz6koVC413k4LGCFSFIpjL6604zRxd3dLLoXb5885HESo/bA/sNvvOBz2pKq3XChcX11zeX0p52oEmRJW5Wn1funMX+/v7DB9ftykLFbI8wslVyCyAvlnNZVSmLvSMS/7ogcHMTN/ZwmB+TrMa66zIrki40pMO4yuJfzqDiyFU9lnilnaI0shlkjJtR1TI8UgIOUo8W9RxCRM8uMwMU5h0aDNKRNiRuuCwbzMQ5Cc1VKQEJAhLGCDreuAgK0VQFJShFZKy02ZzRJqq7zVhRQCx/2ew36HUm+gyGw2G7YXF9wdpOspTEGAFjI6i0OoUvOazaKzNseH5/psUty/D4aVcl70ktdlHFT9MG3k2Vf6XhwpwPNHb7lkdFGnMVK3udsn5XM2lxRSRU6jjj8hVDNNsa7YSogS92KDef45G99nwJuphbCczqQlFNVIQxzayxnQXpRmnAJ/7x/+Y1693vIjP/zrGY53jMe9sK8Q0F4rxWq14lOffEcK9F1b1015hmM10VM19p3jEm9d1V3uOB56SqkmUnNYzKm4VihL3KJ0bTWum9Eaq9WiCRaijNlCNfA7W+9nsG0BQyvpJubIcRg59D37/YFjPzDFwDAMou08FVIoPHl69y3u8tl9/Vjv+v/TLedMfxTQqSAgj55dNqvYs1CLNV4rvDFs1g3GlJocF2Jlv0whs1l7CoopJPKUZZGrFXWhKwqjBCUDXNx7xM1uvXGCqPdZ2iPrzZwThZyEYRJGeWC107Wd0VfvH5mvnRXapSq1AhUS0yBgSwyxOl7Itt22+MZWpVlx9UhabMqHEHi+60W/LCvQqgZTldppEs44mtaijMM7SRjMXHWp41brObnL4g5Tg1ClhIZt3UnceNY/m9s3yQXnTW13LIzDKIwaRFi6XfmamBkBInNmmkRHbba5ziWze75jGoMwcZwR8etKRV5v14zHif4wEELGrz1NZ5nSJImrMsukL9K9hRQrGDnGOYcBBb61VSBYQJFkMkoZtBZ3z5QTXdeitSJMQdzvaq+6wuO96LQVBceDVDS6dYfWlmkcAU3KYp88DhIsjbWiFWq/u9GiXZdTQjcyDmIsjJMYFxgjrIRpHMlJkaKAENZl1muH0gXnhEU3DbkCZeKkqLRCO0UhkxJMY6btNHfP96Sp4J0cl1Q1Z2a56L7llDnsLNurhhgKTefp9xNKSeVkHALtyjKO1QV1GBmHABnRE+o8dzvp+Z+mQOGINgbnHMbWxX+MpAz9ILpOpiZhwiaWds2LiwZK4fb2IO2v1bQghMDxKMKNh/3AMCWmIC6BjRXTAGOEvVAoWKdZbVtWK0PImqkfSaXgraFZSzI1g8ZzorbetvLsVPBShKbF0jjGRLdqZexWfcJQ3ZYk+UxCIVYSCB37yHE3sr1sSKFQSuT22Z4YMiVWy+4MYx9Fy9BJ2+167dlcrLAYQkj0Y2TlxSlxGuWZK6owDCPWKtablourNUZbpjGw3/fsdntWq04A4mqwILTkJA6Rx1SF1DNPdnvuzIhThkZZdC7EGCqrpEFrU8W4AwUjAY2qAuuVHTGDYYvejV6eOgnki8zR8+prrCWG6kRVg/BZ129mV5xvwqKaXzv/t36+FPQZEKNrUJRNriL4875NpfonIjVRynppdVSqhiM1OL9/FFWjLGtQmUKqQXIN1Oq8fQ/IQ/QSlmaEuuArLUnV7JTpnGO1WrPdXtA4zzAOVY8msupWWCzg6jqiKitLLddsBsGM0TTG4s5YYotALHAi8gmYOVekpbAhwJKtRi7eS3vMQ733h1XZ820Gw+YvfEFPQkkBSlcWwmy88MJ+HlzH5Q7MOlk1sV6S0BdaP+evVEvAdv49Kc0ORPlMk6IChJRFY6UsV+5l4NfZwZ6d5v2qaTnD+k6AqK26pTOL7nTA84B68BUVQKS2CqZcpG2FUvVTZDzNmhwhVl1QU5mT5Ux4ueqcLKDeWTV8ZoDN/yetHVQzBgEFY0kLMCDMiDnwNXibT99TL4yq+5VWcGHzy/eIIPTCzqzPUIoyFnMVTdZVRy1ncfGzNUGb4zuthRGqjcIUAYg3K4XS8qynqm94t98zjAM5RlCGYRjYbi9Q2vDma9cCMKdISoHNuuWzn/wEF9oybVesYmH1+AK/akV6wSgUhuLnuU0xt/Wm2kqdUmAYRRMr58yz53esO5E/cNbgazF3Tqq1MZR6zR8OfmOMJDr647f//Eq2mQjUNBNtG14Awsbp/u/fCgQD+OHf8K4AF7FU9uC3PvYX2uUebG+/8fXFhV1pC9qR0FhVnaCZxzgv4utn26wdWUqRAlvVdDV2jo9lLhDWplwUjfxujCbnE/CulT4lcZyeCzUXcYyu7eSaKRTiFNDOC+yUZ6dCeX+pc9A85xbm+UTWz0W/82yhef/JUw6H4VSwmOcQJa2C83qzPwyEEPnEW68TQlja2EJdh2NVPJ+GSeKeKTD2PTGIO2aYAuMoIvv7w4Hj4Yixht1uX4H1wpP336M/9ljn6nOQaBsBB5x3NG0j89RSUKinoiUO/hYjo4LECo1ewJMXtkKdY+e/qxd2M285ny7VfO+WfXAGgp3d03nM5JwXw7MZqAyTuN4XpVAkyjznqnmN0qdiRUVqS4Si88mJWL4AZ0/aw7kU+mpwsNsfub3bi240oEsSHNBq0oMupVIgJwXForUjp7wImc8xmrTfyrySalHNOUeOc2wwFyul6GgzTONEmEbRyMXSNG3VE7VM43TS9spSKLzP4hajl1NSNuuysazl5+89B43mm6OVqjpkaQFQlZrdG+d7WAHhF+aAAjnW8aQrgePeIAB1Yn4tTO+KBCmlKux4GjPze2qEe29Tap7T1Auvwblg/v01XyuNtwZvtIyR+m2ldiU8ffqc9z54ynvvf8inP/t9/Hd/479ms96gqyTUnL975xbDGK0URd+PdbRGnM7rZq2lW3VyXrMEw3y8hSX3KJTFVGo+3lTj4XkLITJN+ypFAsZYNpt1xScUw9ifXROR/sic2Gl3zw88+fAZu8ORw6FnfzgIo2wKpCi3cX8Y2A//I7hG/g+9aaXpDxPaiuaFqQi8qoFaXaOqo5dMCF47tMoV/JLKi/T+q2VACf05kZLG2ixJYpSBn4IEZ+MYGYZZF0WxXnuM0axWqQJhEvRNYwVfUhFkN9U2ECttSO3KYxSUmJbWToUSF6iQmIbAMMgEQs7sD0fRIupams5KwFgKupGTnKZE1DPaXxjGwNDHWllMNJ0IwDZOnPGEgl2p4rrSrK24igkjTBNjYRgTh+NESTJZG1Mdi0Id4LVaXHWbCaMAN7MmRoyREIQaOzNkVuuWQsZ7C8pw++y5VDRXDWEMTKNYRYcgP1vnhRJJpSBrhbee4TARgrRndCtPKZkwBoy1aC26SxRh2KQ8T4AFlAhol1K1U5zGNzKJ5iKtFbYIeIVSWOfxTUsKQXTaQsZ5y37f450E8/vDiJ2kMia6SHPwqkEpAWcr4m6NZnd7xJmGptP4yuiQpFRERgswDqMI2KtC0ziy0Rx2B7xvGcaC9wZtoWkETPBe0629gHl9ELaDkjZi4zSplIXteNgH+uPEZtWhFEQtQvZda+j7QN8HchBR+v44sb+tgGPrOO4GrDWs1x1t06CdTFBN50UTIma8FSBRWU0tHlQQaaBbtdjaJicBpTyLQx9Ee68VJp0xmikXckmEUfSSpiFBUZiiCEGYVM9vRfvu7rYXQA9qe5iAV7OrJ6XgGyMMQW+JE0xRHEpDlEDZeYfzFtdW95iUaJXYhQuQrDkcenLSAtxUxoy1GusUGEM2dknIUs5kJIIIU6I/BMZDJMeafKKwbt63UIdzFJQk5MwUE9ZJori+0LjGMdZq6n43oJVm6EecssQxkUKkaxu2m4br6w5nHeMYQSdQjQDgSJvlZr1iGHqsNRz2PdaJxmKXHSkMHFTAaUOrPRe+EUFudNUYytUO3ZKSgOgafWo1OwOpZmDlfEWcA8fzKEHrk9aYfOLEomGpqM6fl/+0scz6FSfdJ0hkmfxLWZISNbfGV4ZerkL7kkxAYZJE5TwiO9teBMHmUxV3ylzdkIQ2X5lfWQCU03GftYvWoMNU3S5rRDstjBMFg2s6VqsVbStGIinIvLi/u6FpuyqyrVBZkngp/85uVnJmprZEemvuBZ9za+JLT7XIdRe6f20zr4GUb5qanAtD4l6rZb3NpQaIyx1Xc0vSi8k8yHpuq7ByqYHqzBY9P8CHQfFyuJy1GiiWe6uKFGeW9tgXvrycjZmqO5INscyaX2VhRul6//NcPfk2wMMMzNXTl7efPwJzVfkkzcKqc7V94H4rkDrPcM82KVTN2mCn+2CMqvORxRglBcNKTDSVdZV1IVQXHTnOtFTe7zlc1pN4eN0FZD0xIT8KiFGqto7VMzBG1SLbfA3kfSIoXmob2kTKgZxFm05csPKixTa36ArQLtSESWyHJPE512yqx66UmFF0rcyJM0613awgBWG5FGEjOO/ZbLa03QqlFP0oCZ7xDe3jFW2ObK8v6XJBrzq0k/leKym64mXqAUUulYWitRTWmJYYcT73mBIhTDjtxAkyu+XwZwfEcjb31JRDgMZzTZt/Qtt8nN4Fbm+7X/X+Pv3p51DnDwr85J/9kW/5/ly+NbD2zltfZpwibSOan+hS1b4MCksqSWK7XJbkU6myzJLn7JNSwZ9pSsRSRK9PWyEsK3HYFdJiEVdtlWqBZB53J9B7BuLnf2V8BZSqTrvWomxDyKoyru7zd+aZfMHQ7wECktPn0wy3zOPWGJQuXF1thFluJUYtata0EjCcqkF1eblCpcjXv/RLNOsttx98QFbSbt33PWEcORx76c6YJoZ+QKFEnDwVUowYY+iHnpQyXdcxg05d47i8uuLi4pLVaiWxlXWsVqulILper4VFtrtl6I/1/qiF4SZ3aUbHTj+rImuf1pqiCypLW9oieVCf8Xtz2gJcvXwsnb8+r5cPwbB5ny+bE0vO5KIXFm4IIwLUyJo/a4JSY+IYqcxPRQhBdO0qe1HrOUaRhH0uJMYYCanUNjUxGLu93ZFDZN1Jy+WUJVpZtCjrZm0tQmuz5MhTqOwlNZMmDKVU+ZgiRBDvGmIQkFYkbwpWa7yzOKOxphCnkeG4Y7Vqscby6NFjnj17KvFynp0M83J/zwb6EvMp/eCaIoyrh9v9tklV433QcVrmSrlHZ2sZFXxS92/+yQFUBszcbnkOhs3mMpKr3PswRt1vfVQv/M6D39VLXz/f5/y+eyCa0TTe0XgnTqF5vpZyrP0Q+Ob7z/jw2S3vfOaTWC9u787V5PwsRppBvTnmtqbqgtWrN48H5wUE01ozDKMA4wsIP+9TDLESJ+MoAStrPnB2uacYuNsdyKnQuIbL7QVd1/HWW28yTRPvvvdN+n5gMdvQhkSNBVJiHCeefPiMZzfPGaYgBJraRk3Soofdj6T88dbD/0kDYeNUmRJS85MkwtoaMouYQlMn0jnAmQ13jkOooq/gjUUbiEmEHOf7G6PYi2ctE5a41837Oen/rNeathHkvFs5qU7WwTlNlr4PlDGRogyWkgQgO+x60TFToHImRAkqk8qC0MdEmKII3HkZxLe7vSDczAh6rSx5ha1tBPI9VBBCEYKABtJbq2hbg3Oq6pGB1gXbFEIAtGhimaIwaMIx0Y+B/hgIY6FE0I20IKUoDhfTGKS1sTJoAGJQ5CBJf8nV7pd6XQw0rjmr9M4Poq6tEoakEkmlyjqT/1KoLlJe8oacJck5D9JFaC/jZ62pilYbBWMWsfJSBKgrKVZatkLpUsXJPSlNFGC9dtXOORKTJpXqpBIyzkl7qlKzaJ/MW+MYCTGzXnu818xttKcWGmFEGa1QBUIfUd6wueh49HhLDJkYp6WSrJX0RMcpYpzGdY4cNfu9TArjmLi42DBMveh5NRKsNc7QG1uPD5wH28hYm0LmeAgcj4HjIVQTBxEl1EbRNFLVDDFjQiJETSowhcTzZ72M/7seoxXX11usNWw3HWMQZ0c168pYI+LLSdw4Y0woY+tzlXHDJBTs2kLnXbUWL8LEy5XSbKxMhKTCfj/SrBqOhx6lnRTLimjXhVq5HaeqL+DEeEJrwSGNlfkBICkRqi61E09pGHthT8YY2V50NJ3HNq4C5XoZq7N+QKw0cusdRQNGiaumKtjGUkwz3/LaNpRRSY41TkJ9Hw/SOjmPf601zjtK1WFwXoKVKUkrba4BfN+PslDlwnEYcdYuOnY5ZLarVhyKvMaoJECQznSdpus2Am6EXNsqBBhtfMPzZ3eM0wwaFJzLGGWIxmFbj/UrTLWVF3p+IaYzQKVuUt0ECS8KJ6GK+1UymOfb++CSMEurFkOGWE5OX2JgscAipFJOYqv1A8IIqlVXZmDZYJUc+1zJNdrUQ9PLsSoUVs3uXZwAoFzux04PIhhdCwkxIW2hzMDK3OLByUwgSwvwDPIszrVamLDz/G6tY9W1rFdrjNYcDzv2uzt5jseB9fYC117L560wMvIkLEKVs2iEaamSOmuwD/RblGJZ85bXmRM3mb9yEcZGTvLcWi+VxPm+hRAwjXz3OZti1tI6VVRLvcYyWT5kas0MinkgLBob8zpRg9RSA+ZvxX6ZK/YAqSRJlpQ6fcfZdgJcuTeGZ3Bo/j6jBbzMWS3ngpo16s7O4gzsLA/GywtJ0/x/+vTGxp2ze+r55kK+t7PT5owhaFP/LtfKWY3zVd6hAqxzTDIXvLRWEndQ75OIZS4s+EXcO88ssTnpOB37fEwV0pUkP51psZ0B1meXdbkWWnHvOVJGnvtUnb5yKrU9fW5FmXVeBfwxSvQTY43L4qJDIzFhrs/xkjzX7zLa4GrVrpTCuuvQxXPsD6SUWa86rDG0TbuIAeeUGcaBKUXa7YbOG1pnabShVJMIXVMWoxWuVH0iZN7OBXQxFC3PtjDe5XpfX67FUEXX9SwGcm4qGF3b/ZVGUWMlXc196hw2P9cfFwZ7/bU97z/ZfPs3nt+2Oh8Ogyel78zY6sV9ZdaridlYo5TyAsPsO90eP3pCykVaaykoIuSpPlqS8JNry1ldR+SJqa30VQJBDkicsinCas56jjPrv6W2tOWqgZMkV5D66qlNDuTZNe5M97G2oAEY5zHKol1L0VaK4uQX7uOLr8z3Ws4hIznE+XO+WrW8884btK1fnNZ1ZX6XLOZXWolkiTea4+HAX//Zv45vGt769GfYP3tKKpL8hxiJIZBKFqMjuYk0rllMWiiF66srYbBbs7CGZUoX1pfWYuxg5sTb2aoZJd03u+PAhzdPGXrR+y31mTU156lfe3/tKEA0lHltKyeAZNGPOgMjH27fCgxbChdnc9m993D/ni/3qxY/tbXUHkd0koLf+TpUEGO2aRKDpZRmRm890SKxlQFUyfJv/eYcI/1xqi1iA2M/MvUjBimskfVSaHDeUtIJuGtaR9u4KsUjRc1pCljnsNZT30yqcYzSVYfQe6YgZkM5Zyliz/Nxzb2naSRMgwRudb7eXlzw5Mmzs2t0gvOX8azqd33ELHZeAFuKHeVhp4E6rZ2VwT0zmRfWHoqs1As3Xqlz0FOumzDGFXNBL5dSi6T3h8M95tjZmenKChRXRM7W8G8/U+cs11bX9Wv5ZJUA6NqGEKTNf46eS4FhDHzzvafc7Y/0xyMXV484PH96ypPPrnmpwKStHVj+DKwXRqBanuV23TEce+lOi6ITPMep8/UrUNmbc7x8ul/l7HvHKXC339P3Iyu/ovViAtU2Dev1irvdHX0/1LjWiT5m1oQykLJ8/ziOHI+9mBEkmacpCoNimgIhjHMH77fd/icNhB12A+1KgApliugsFGEbKSMVcFsdHkopDGMhp0gqIrQKoi+TkgQj4yRg1GyjC3NLj1qcKE89/0gwt7CoDAUtDm+oShsU+uoUMiZCUHFJ7EqMHEtP11niFERcfYw0dcGU8xBtGglm/3/U/cmvJVuW5of9dmt2mtu4+2viRWRmRWRXPVRFqSRIpBqIkGYCKWjAgaCB/gINNdCYA/4BAjRSA4kDDgUBAlEgCxBAQAMRVEFiFauymBkRGS9e591tzjnW7E6DtbfZOdevv3iRVQIY9vDg7veexmzbtr3X+ta3vk+SAt85Oi90wjDW9rutwyhxvPSdYSqJEHK1fq3VegWukwqR0mWtxiLtC9ud5vGQsEnhlENHGI6Bx8eRKSZSSHhnySpjvSWHRPYZ33VSMZqEmedKFbgtApSlkMheS9tnL3bU1hl22424NQKPDyes0nS+ByMOM9ZbrLfVzVJAlailf9koSVTHkslB2kdLEveaOCdcZ9lfb3HeMc+BaZjQqiaxuTCcAsMwQ4oCqCkJiL1XbLaelECbzPXNDt95Hu5PDIM4QUUTRMssSvU4hCQAXi70nSWkLGL9prZtGBH0CyHSmGfdRpwx87eZ/b5HKV03GU2mkEMiRsU0BxFAnhMhBJyy2M6iHOyuthwfJ3Kacc5wOAmrpe8tKcaKpAPIhrzZOLTRTHPmNGTefHdc2oqNoYJHsg3N1RQhBPlMbTS6iiEfT/OSUOz3npevbrh7fw+IscL2SnTDvPOUJFXVGEWzICVZ2HNCwGAVKTFBJ9Up55xo1TnRPImpCP0bhfUeUyQZoRRhLvmyUKxjiBhjiTmhqM/JxuKcmDb0lWURQ6R4Q5pDrXaJPpDShtPjARDmXGNRaEQ8lCKsA2M0KQjbsWTEXAOpyvWbbmHfSVVN5kVOGY0w47QCpQRIN0ZLkoaI56O06Hxohe0s1hucd2AUOsv9cb4Tza85ig5dCNgKfnW+Oo1az37foYwwNofTgDFyjS9ue6xVDEPg4WHC+8T9uwMvPtkRp0jXGU6jODDOsYLK1uG0QatC5xy9uSbHXM9BhPiNUYv2kKwqwurJlclRcqqBpQYtlf1UgYJSJNl1VrfCEkoj7omlEGJCF8U5FV02/ixV1VIgKrS1deMVbaSSq86KUqQCqganirS2rKjaxrSU3wroms4qU0EreS+5XGzmrd1JrreKVhtpzZBEvr5KtdYHFjB86RlVgsJqI0wtZ92SeBuj2W03vLi5ZrvpCdPIw/07jgeZp1orhsMDu+trEeR1nnmuYraVVaAVlW1WW3kuoreaAFY2zUWMdgYa5MZsqImU77r6XrWwxeTj1AJGltyq4uXsuluwJPe9sazW0zkLcmmgsqUJ0ObS6owVuPkNLpLnRwNpzoPsZ1llS9CqL+61tLHms7NrSVdrv6DOpfVdJV8CYc+eaQ3kzxFWaeM4C1orEPn089phjBGtxPy4JMHiiG1Wl8L6XJWz+yznLOtbA9vOp/e55EHTYDl3FaMmySBrYHtdc89rGNdzrImnicTTX7bkF4VoLSlpL4/1e5rblBQmClPVRVOsc11VFnbRusZSdkmecmVftQRGyw1jnCbmELDGcnt9fcE4iCkxTqJFuusN+6srnHPVxbUBomtC0kxxQApxBgGdJR9uybCi6zfsTGScwhlQLWB2TEl0bpQUWOQhWr/HVPFprdbzBPif/zu/5N//D/7ax0aYTz+Z+Pa73ffdhYvjf/m/+E/4P/5f/nUA/vznn/+g93zfYcwle/NyXf2rHbc3b1kwzzoOLjcBfkmMW3GFLKZOaLusDSJjYM/RD2EzK3V2X8vyO5bTb89CrkzCFWBdkspcRPeqvk/afCMhzJi6T1nrZCcSu3doGmMVhPmAlVkKqjTH4hUUaK/pu44Xt9fEGDgej6RU2G47pmlmGEUKIqaM1RBT5D//L/6CkP+CFy9foqxnu9lijGZ/tREJhK7DeYf3Huc83juc82gt+5TKmf1uj3eOmMRdOBVE+xa1dDvklCgVZGxsUgHzNNurDdvtXtbgyg5t60G9SlohrGXepWiKlX20lLpC1zFqumGLHmSdChdHWxOfeRTqranmPmdjv9yCy3m7gjJN31GhisaZy9blpchXiiTvdW7kVLDOSVxQXxlDQpWEKlKEnefAOAdOw8S3b+745rv35ALDOAOFzbZH6x7vNFlbrFkF+6X4J272YoAAMc6AGKl1/Yau68lJWtPE1EfG0TpLzgU7GWZjqnjVqo+lvCPMkXEYmOeZaTxxODxyfLzD6nV8zsesgY1Lq+pvWAZaIbuxLYtaAed191VoY6uj/IcFM3EzX+Oz9ecrY7AVg9qcKhf3el0DPgbaye8KW+fl/JSSvfb8O8uHl1tgKQ6IWZs++66zcTC6AmFJ8oC4Ij45Je4fDnz59bf8A/4eLz/7guPDeyHCGCNFdsXS+lkSlKQxvqu5qDiRojTG+6VYJx1VeWFnt/3rYiDbX3MFpuo81kr28BDFiObu4cD940nkkva2ar1HfvXll3z6yaulUCf5mUFrMQLJJVLKSAyBzmr2m44wG+kKSqJhmEJ9VuaJcw217zt+p4EwYxRxjsyp0HnNNEceTyPOGbQVAfi20HTeShI0ziiMiGYi+03KskEcQmKeBABozC+K0PXnqVYlK3tJkHKNcyxaE7EolBENq7Q8PJKI+E6RkqYxDhorYBxG5pO4pOUCJ2TCW6vZbDr6uvlIRaOw2/QYrQhzZp7Sol3QggnjwZcq1h6FbXL9oifGQr91OK/RplQxZoOqbYphThhd2G0UOhliKByGxJzCsmnvto4mpNzaQlOSKprSYus9x4Cugs2lARdzwe09zovwvrUiFhpDoCiYpkBE0eOx2jCeprVShLS0Kq2x3uE8OCurcyqJNIvznLTVaEDaPa0xbDcdBsV4GNBeYbUlu8A4RnIpVfRe1yqAtMu5rrDpnLRxWvnulqyrLEL9233HOAbZGFJiHAf8xjBWYcTOWJxrbU+yIc6z6IFYa9hcGWLMXN1IT/R0CmgjPc3eu6rLkJYK/Fyr3EoZtLFMw4mrl1eMpxmjM9bC1gubKkYxDBhOQwVupI3HdxZnLQ+PkXlIxDnXhE9hrTDpFOum4jtbxTwz3hm81RVYlc3FGC3mEnNiGEZevryqLMlU3YgUD8dZWJvW1IpXpdHHTCkRv78iFNHX2G02pDChFMJcMYp5jJxOszhCVrA5G8U8iI7cPM/MUXr6S5RQSinoNpZ+69hfeVrNVwI3zzRIW9nGVxOFZChFqP2tqKNr25DSmqYbLq02Ig6533e8f3+sxhWF+4dHoGAsXF/3uN7J+Wq7sEZzFJBJW41z0mot7YSihaaN6Gt13kp7x8Zhva5C6FSNPwH2w1jpweOIQmzLi9Fsrzy3NxsUmXnKZF0oiKGCtRnnPV3naUKtItqr2e5lM5vjyNVNh/WmtooL8GCtpveazmm8VVgUQxLRZ01ri3o+KBTdsSreDZLUVbHhXHWMShFdPMTkt94DcbXKSVh01HXR6DVYkXaBmojnCFHAPlnXBQiTJLIyYiRbqfPXQhFA+pyL1sRaAVY6fQXeVKnWVPVbVUGZqit4EXAJ4LZqyEgVsjF8ViSiBl+mip9aTe97vPMitqwNu92W25sbUsq8f7xjHIYlGStFS/V1GtnU9q0wxerEuR5aq6pFsyYdtQYiQHIDrmSrlEpfLfbkTNVkyjgrzlHSOrcWmKxtrkSrFs7SEljW8VP1by0o/GHHygZbrjvnCj7li/a98+NjAJlo1+UV/Dh/T/3TaGHmNZ2xhTFWCgmxem86c+vnsoBi8v21XU+1xGwZiiU5Xt5HuWgNzkWcSDdu/awK5V2eaD1CLqT6vlRkXRHxeFagjfUEShWOf07PTevqdFcT+2XMioDLpoKqqiXmLc6pn9vG7/zaJMFoSdB6H1ZA7sMEtZk5yNBIyxNJ2H1tP85FnODmuSYCRTQ2KZpSzTlyZV5aJ7EPVgoZQz5IgF3BMsiUHJmrK67RRtoal0RdwDNhQUgi0nkPqha6ImzUegkp82wILpIOhblkYgykGOi6Hm+kKJVTEiC+IjoxRYwVVnKpgPAcI6nk2t5UdUmR1tSWUP/P/u1ffy8Q9p//0xcfTqTvOf4H/90/4//wfxYg7Otvb37w+z52bHpZo6QtWFFURutMzh/XGPxNhzHHC8br00MBVpvartY0w3IFmXMtbAaMr4CBMZRcpF2oinq3Re2CjcQZ4FLWGKoBH42ltbCS1Np+OU8jxo3EMOO6XpLRkmuyapa5R4tB1dkkK6XG40375+xa6/lt+l7ameaZlBXDXWQY5xpjZsgRRSKGyDhOeO/52R/9lOvrK168/ISf/P5PuLq+EmBt04tcR16/Q4Yko8koMs44MZtQmsMwyP5U24xb4WWOkTjPWK1x1i5yTbEIQ3K3v8YYYY/FFBdgSymFKhlV1j24NOBTy3qenoHYlVJNwhMaxln/bNgy7dY+B4bVsW1s7g9ZvWVxtj4Hwqy1NFaSVhLfLcW/mqKnIox2hWKKUsRSYyF6j3PiCPn+7dsqKyNxxuPhJCBCCNw/HPnmzR277Zbddssf/+nPcM5zc3PNdrvFdx277QbnPH3fL/I0rUB5PAy8fv2aaR44DY+UovC+YxjGClRWDbByqccl7LpqZFLyMj8hMxweef3Nr9EU/vJXv+bzz15xGgZSDLVw0iKBM/GG0nLYRaj0g0Mr0ShT1BbfpUCjFs0uAZ2RwsdzVaOn8+LJv5tTc9NchJrfl9p2157F86v4SKyhlGbnNTFJnJtXyfvlAp9iSKWoGpO2I9eupbOjSMTqrKPrPMMUiCksn6KUYhxHfvXlt3z99df8nb/zt8BYphDwpYASZ1ynBICiJHLSKPwyBs47jLW4bsM4TYynkTmIFl2Oa+t2Kwnms2spuRCDdGvZTqR4tJb8YTiNvHl7z+t3d9w/HEg58eknn/Di5Q3GCmv3zbs3NXc1xCTu50qLSU/OQrQwSnG72+KVZp7jYhahUbx5e4cmQ17d2H/T8TsNhIngecBYTVe1hEJMoBE72iA3vHO2OngIOBKrq0tO4lQRU+abtw9Y1zOHzPE4M0+ptqmlKkKpsF6LiLmmirkbYgj4a8PxFEA3+mRiOJ2E6t45fKcJU6bfiLNgSmv1JoSEqkBbrG2OViFMCBPx0WO2GtcZYphEWL6I5lhKmd2VlwVKUVsfhUa7KZZ96ClaQI2QRIurBUpocY9z3qAMDEMUJ0ajhL6bqk2sUUzjxDhNqFLY9VvuHk/iXJNEcCSliHdOwMC5iNlAWi2mlfQMUagbhGHp891f7aSaBFAK42mq4J6mqKZno0khk2IWR0S33mdnHYd4oPM92ij2+x1K6YWNJDatAkBOkwjSK2DTefZXG9mgSRwfjziv6bcW44WVZKyuC2wiTDMxiMj6ft/jt57pMPH+zTtSFNbK/UGAHOM03jcqPqJ/sO1Ep0FrTo/i5re72TINM2oHIDoNFHjx4pZxHJnGahxgNC8/vUErRy5wPB5xWzFKiLO0xGy2IrTb9Y77d0fGaUJbi+8cYqOqmMfC6X5ijjA8zmjfkbOwet69e8BZw+3tns1G0/WOFMVhx1lNCokpwOkkAWyYZBx//as37K99bVMVpmEBrHNoHTgeT+JCGhpo0URi5X5vNh25JFKcBdiOgZwVOYkb5XgSHQrfC4tIa8X1iy3H41g16wrGOdEDSaKR1FtdBW7t4uDkXeD+dAQ0fe/xfUdRmoJGpUi3be5cFQCIYtygjDDKtNIoJ89E1zkBxWPm4f2JOYI2cDyN9L2lv9qIC2RKVVNMqsHGaAgJ3xm2O08MIiwtSZckzT/+dMtX3x4hi222QoBNMBhdTQEeZ2LIWCPA9HAMdLuO42mm7xw/+vyah8NIt7VAhJzEyKFexzjN0iZqNNOQ6XeKzhtefnbLPA1YG8TwYBIQvO9Fr+1q4zEqVbHUH1BpOUswAAEfaoKbL34uf+TaUmW0rEFzOWG0wxhTXXpYRWhRxJzFRakeubIBlaJqwdQ5qRSquh4VVSq9neczVdb2voXOQW2pKKW2tJTaNii6X02fRym1uoxqFkfNfBHIqLPPbcmZ/N85v7RrdV3Hzu7Z7a4oSjPHWfatlAhJquneeXa7K3KYSClzOp4Yhw+d1xZttKWCXlYgqLSxk/FNCONWfiY/jyEsAspX11eiZagNCl3BWXs5blDdatvn1++twJ+0v60U/HaIY5W9CG4Lqz16e+15i2BZBKXX1lt1lpA8dzz3u/ZvW1mF522ahcYWKQuQ1lotP3aUImOQq0g3BVRe70U7j6bPtrgqnd2fvMzRMybYc4laFjfexo7d9B2WKMyLBY2s7bcaShGZBgUoI0Fqrg6H2mpUUkvrS05ZAlQkGRKWX22rbAkqLCLisWp4QQVgtcZKQLPKSRRh3mOd6BiptWVpYUwsALIU6tpcqNkCyMpIiqLnutxXWku2/DvGKNXtOnClFErK4uZbpJhXagwzh5U9pPuN6DfVDysU5ijJRuf9omUXoti3W9tDbblO+UOXtjYnChBzIVRGWqqAt+p2XNmOh8cHCuC7rjKKpSCmdNV1Q7QyUdB1no3vsNYTcoGY0U7O99XL+aNzU47fFnBar+j9u933vtKY9BtbJ7vu3K2XWgz5q4NgANa9w5jdxTOyrC9F1ulc51ObS7mC6q29pyWsGnHslHWv6U1VMe7FyVQ4yarq0EjXhoDoRT9lvpQFDGv/Tkna1+f5RAgTPiVCAm2lgGvKh+tMKQUylV2+tnY+hxy0pLbpDN89zoQznShNhjJDmiDLazvv+PFPPuf3fv/3+MM/+VNA1mXnXZWtaK1aZ3tYkf22UJjyxByl5XWs7KBUyQPiiMiS2IeUFvZoKYpUIiEWXr76HGv/C9lf9eU8aterPrjeVb8xLWPSnvcz5ELSifZBsi4vn8BSDHp65Arqt1zrch2WNcQgxdMGiIU5yHpXW7dS1TcKjVlT5W8K0rXTdZavvnpNKQlnLZ9++pIpZP7JP/lnpBSx1rLd7dhst2w2O65ebvnpH1/x3799wX63x2jNj37ye5IHh8DV1ZXEWKXQ9xugkLIUylJKHA5HfvWrL/nudWEYJrzr6Dc942lY8ULFCoZlKV6KaL6VcpeS/YQGKueZ8fTI2+8iw+ERtObP/8s7TtNaZFSVbZ1L3SdZFuxWQltv9vndrUUlbcRETfZ+jc7UNbw6mKYfEJvKh11IObQuDu9dbfNUi/Nwi/tWCFP+pVkNTJ6yw6zVhHSu6fjMWTyZa4ratnkWX7e16fJ9sgc7a3HeMQahGmsjmm0pRd6+ecfd+zu+/Pmf83j/KB0oXWX1u8YwrmtRFnaquIMG5hjpeiF8jNPENE1Vn1PGWPT4NCpXl+/SViF5lmOsZfQk+704mlumOXA4nhiGkVyy7GHbnt3VjpefvmAaBt6/e7+QP0qMFTOwgHR9pZCxWrPfbNl2fdUsDByPA8fTgFYZo6rGdvxN+2C9Vz/oVf8VPYR1AdYobBVHLVnAJXlg1fLAlKLo3FqN8d4LYyomaIANihgzx9PEcZjIsaBT3ZyrHoM20G+kn15rxcuXO1IuslFYwzxHYYD1nnmYmUdJ8PXWwRBAW3SU1VYskqVvPNdz11b0t5rId4uAnRPhwoZAixYTC6NHK9F+KqVgjWXTWdipqjlWUDphLVgnD8F+Y+k3FucMd/cD93cTn362ETpytkSTyUYCycNxgALDGMhxks0g1bajUuj6Hno5r8P7geNhlLFNpQJ/heE4U1LVqSqFvu+WjUBrje2MAAMo5hAgJDorSTBFWrxijDiniVHuiTWaaQp0Gy/6BSlxeKhGB0HaGKZ5Yrvv+eTTW7TJTGPCe0nQYxxRWliAXa8qCKIW5yHjjABwuTBNiU0vLpveW3TOlD7jrBUURCtCTPS9iKwrJeRnayu7CEsIEaWr+D5bdnsBJ1OKGKv56i9f83p8xBi1COeXnPDeVEcXSFEcNQ/vD3VeOBFy7zucsxQ0IcnC4JXBeWnpePd+5P3rmXGQ+2asCPHHCHMQS2NpC02VCZJRRp6fYY445/BGMQ6TOMgYRUzCdprGVFlUmqurLakyxdp4jqfF2kQAMG3AJBlnlbEGXn2y5f7uAeuksj2nsDjViQAxOKd5+dkV0xSYPtnjH0cwlmEqhCnU81WkJO23221HSZ5hHEEb/LanJPAbAdUypbasZoxR9FvHdJrpNtLCO88BpQud7rBeWihM55hnCVTkOZTEpmTY77aiW2P0AoJJMFGDsqoxVZRid9URpsjxMZNCkt4ZBT//8kEcO7Uh91nAaSXA7+lxxmjNPAXIIn6aVCAH0CHhvKaQOIwDc5qZHiaUUnSdxZhCihOHxyMpa1KpczvMlKxxtiPMM9rA/kaEum9vtkDBacVWb9joHm8cU5gXRsd5Ve45RtglCGZRxrC2LTbm0RrYGi1gY9ZJUi8lrExXTGWxqBWE0q4CJedpZw1Pziv/JVNK1dhRRjQeivkwCjk7b5QSpy45SxRtTZZ50OLh9nqlRFtuqQirVZfioiWmrJCN6BSJlfR69pIwdV3P1dUNvtswTLMEDmjQhhhHSi5sNpa+6/jJj/+Av/zqO/QzuadSooUnwEXTuBBau1FrxTO3e0mBqveWi7TqhjmQY5JgxllCjBX0y1hjz7Sn9AffrUxtC31STV5j35ogUltpl3aAqr1T8pJAPHefUklLULje/zpxzu/n+XfTkp4Pf97+ft5eUxAB5qJWdlrO5dnxXr7zSdibS1oCdFu1GxUrAKaQtTaGgL66kqmp6ic1cKwlcxeHWth8a4sIlRVYk/WFoVID35zJSlXHSA1FmFHKriBB+7wQozB2aMxoavIja7m1TROrmkKUqo1TAW1nRR5gESI3UqQKOVKKQdWqdEu0xV11BTObnlJ+kgwUKkhb206kxlAWllsp8ru2/jY2pmjzrbOktGzvyae3dqJWGCyhLE7Cfd+J5g6ltopkXL2fSitiS64vABn5zpTFuXgaT0zTQEkzHbDbX2EVpByZQsRrqci3VpU2X4zW9E4KYra2TBotGqXt7qcMxmWur2ceHp4XmN9uA6eTe/Z3zx3xDEBJ+ftBrh+iH6bqs9QA86d7x297fPHF/4vNbsLZ63VtoSzPRktYU9WakxLTE3FEedN6jkZkQpS+aIZe14WWEKayrE9tPTPGiMbY2ZFLxiDdE40RtgAMMXAaJ4Y50hvRSiu5LK285+tTzlWYX6tl3T4/nrJkb26veHF7w3F8X1uL6thUxo8yhn7j2bqOH/3oM7abnmkYlu4XY4SZPc+zJLxao41DtfwkJ4GlS65J6cTpIEWZlDKmFndSkA6WkvLinhqrgVWpbDEx3/owjlj/Dk128qLN/wzQshSW1a8BXud/V0/+zZNltZxNg7N9qugVdFRnH6KQ8E03kETZ6mI+8O79I4/HgRAiOWcOp3GJDUMlYyil2O96/s5f/0O+/PK7WvgLDHPiv/EP/uv80Z/8zaUQ9+nnn4tzvTGiv6bWfaqx388HS1sDORPDSCkFZ2StzTi+/e413377umoWi/xO3/WEaV7jufrstHjHe5G+6TtLSp4qkCBMMzK9T8Q4MoYN4XhiDMh6qBxWqkNk8tlziMRadYxDeh640FUDdZzHs+trm6QCZZZnSuffDH6UWmiKubVIis6sTplPrrds+o6cBQs4HWc0BVNX2PNIZBGF/wAGk0JFmT4sTH7vecGyJjWG9cePVb/LTZEpyJk19uowHPnuzRv+8Ge/x/WLF5weH5Z3ituyXtaWlBJ5ntC6tnXPgTBNYBxzEGmeszNcgG2qzq1IidRXVGCyKEWs+/ZQdcRjivXy5L7dXO/5yY8/45NXN2x6vzhFpygyUt76KksSBOSuBmFkAY+9c/Sbnn4nOMxf/MUvefvmjtjDtkCcf9ge9zsNhO22pgIBcnPmENl3vYA5RgKxFBJzDKSYma0RxLkk+s7z4nrD4TSSs4i3jfPMPEepaJZWYVCUVJae2JxhKAnfaV683FKSgFTzFPDaSPtR7yglE+eOcZyZxplhrALGRbPde8IMWkVCkOhyWaul36gi26VWNRN3bx/pNrVH24rgvTZ6cQKUin/mdJjJaZZtu0iSpantIDQRXQl2Nxu7BCHGysLnnaUkRQ6aThu2nSfutpyOgZQLpyHgrSGkwq4oVFF0vRf2VZaqm7YalWtbahZx+ZKCgARWY3uHVoa+7yqF2BBLgCztUNM0k1MWS+ZhwtTF3lrDOAY2246corT3eUWnOk6P77l7GxFtDWnnM1bjO8v+qsd3CmtE3PP+3jAOM33v+PyLK+7uRmKc6HpDigmlIc2RsVZrtS4Ulbi6vSaXzN39o7js1jaSl69uGEOgAF1v2W6lNbDkTEhZxLmV2NWOs1RktvuA0pYwx2owoPC94+H+REoZbSZub/fsdsKWiyExzMI4G08noDEhirQOGmEsDsNctbgMfe/Z73aMQ+T+3cxpEHbRwpgoWZhBEfreohEA7v5+wFrNOEr73O2Lnu1GLJZLrb4/HmRDSqkwjJGHhwOud+y2Pb6T1th5jqtDXaWmpwS6JLKGNM3gO1CiLTDPM5vNhvdvH2uQpvFKkeYgjMabDSjIUUAEay339yduX95w+5NPyErzeBg4Ho4Mp4lvvnqHc2LgEGJEGdhuegGcvYHYmGoOpSa017jUwGexqdZWQ4bpNKGdkYpJbbvxG1s3q4hCqjBoL6YDSq/JeUmoWDecDCFIi+U0nvXPaAnsLEL7LaEQh0zXd/Sd4XSaGYdAjgVrHdM40288D/czJcBQRsreU3JhOkamKeD7Dtd5FNVAIGe0NhjX8eabt2w2G3wvbqHWWUpOYi5ganXbgioKVww713HTXZEqOJlLriL1LPbyKbcWxrPgTAmQp4zFWFkXc3X/aboQ6rw/QT5g+ZysIs5avOqIMSxJ68Lg0Y5QN1txjlwrlHBe8RPzAVJtrXIaPsLqySWhqUBZqcHtIrzarm8NnhsA1pKGdrRAY2mDa/BIDdqNKouTXilFwO4U8b7j+uYFn33+Y46nE3fv3jJNk7R4+Q02RKzR7K9uuH3xCm00u03Hafww6DKuOgeaszawmgwUudil+JirQHla7lsFWVImhcg8zRRVljmllLRFznMDNc8YYSCMGsWzY3x+LAwpLoGwNgeeLaV+7/HhfX0K1i4C8JzdyI9/2gWQt7Y1Pg8At2spZ38XELa1xUiVtwGCSmtUNbOZxqmGiAqq/s/F55x/1fk1lqaXKD+WIs76nLUE/bx1C8A4V+/b2u5YAOv8Mk4xFSjNVl7OLqNQWS8M89Raa5uOmRKQrDHHROD9TPOosDDBmiucNbVVg/W5DSEwlQmVhKFnrZitxNiYZwKCWQOYJnOwasUY66pgt6ottdJq0YS1m8j+JZguc/Lcra6oQqzJu7Tyyc+sN+zKtuqqSNL4dD616ZFzY9VJAWYcRmEcOUeOgXEe6aymsbW8E/1Q3dxt670VHVkxKzkH+p7O+b7LPPD8keJvmPRPjrdvb/mND8pvceTFzUt9gEX95uNDRHi7fcdpnmhGbQ3oyRRMbWOeQmCKQRJwrSDK2l7qORS0OO2FhHdquZfn67e056mFTaKNpphCGtLyupTE5Glpa2Q93ZyzmIAYXePjXOUPCmEcpajGGVO0gWBtza57rlnWkg/vydN5EGMiFc2Lmyu53pwYx4lhHOhszyfX11gNf/cP/xC92ZHnzH63ZRqOON/LecdImCbmaarriLBkUhbdIWUUYZ6hwDzPpJhEQ7SuQaKpmrFaCuG5AhCliAZVKlKkiXFmGg/Lvrn8T2t7qwWzp5ddx0jV2WEopApNXQBf67R7dl9RZ7+6NJyTjhTl7JN9rq0/8pwaY1Da8Hg48fNffcuf//IbSilMU1i+QCPkDa3Aai1mOJ1nDoH/yb/9P8J6cbT96R//tOns1zXUfP9eWioc3gqNJS+gjRAkDDEXnJF5+PLFDT/+4nMOD4+oInFrnPPSMp6XYqcUAp2zWFfocHXNrPO0/t6bgtWJ05Q4jBIqN6k0qyMpqcXhMp0VKUwtPP6rPERLrMpvfE/3Qkq5Mp5mtNF8/uknQIsP2vP3/SufgOSXr/Cd58X1NYfHRwGUfstFTgyavv81Wis6Z2ELOSbCOBNjM5OR7po//4tf8kc//TF/84//lJ//l39GnAUQTTGha2FKzlxaCbURAoZRmpwC8xiIuT0V7YKluJmrnEtpz12LrWo8fh4Ll1IYhpFxnDmdBpSCm+s9u34DqRCmmcloKbqm9f3e2zr+8tmn44nj4SSmKM5yfb3nxz/5ghAS/+//7z+XNakkosq8+PSaaQj8kON3Ggh79emWXKRtaxwiuoh2la0isTPSshZmqUTs9sJoSBkeDiIG2PeeeZZFezjNjLOwWzadI8dCGPNyYxdqfoZPP7uSwLYKs5oz9lauDbPaiPi6Nkraw7LoU+yuPMUqSlTV/rvQ95ZxkJYXpQS1d16SsZwKcc6kGKqwv8L2wpQyztRebQhz5O7uxDjOWK/Zbj2b3tNbiy2amShukUYRcrUhNwrvDbcvenIpTFPGKM0cIvePE8djpOs8JC0tj0YEzGvLP0321RpLmAMpZbwT3ZwQUmVnyXcdH0ZQ4Lzl9Zu3xJR49eIW7a30/xp5qFIqTNOItaGybqy0RHqH9watZQHb7q/RKjOdJnrrsS5RcsfVzjPNwuy5vd3gvaXre+7fPVYBdc/D/ZFxTBxPkf2Ljs1uh8pKhNCnWVwNO4fpDEZD54VBB3A8juyutqis2N3syCXx8sUWY2VDKDGTaa5xotWUE2AMNzcdp5PY1fe9xftrvv36NTcvbthf7bh7dyTGSVqOrK06AyJMPk8RbwubzmJU4ebTa778y++k/aYGXcY60BplDDkVDoeBh8eZcZjxHoajtODlXPDWQors91WXzClOjyPzHFGq0PWOzVWHtgXXSZX8dPLc3R3xTgQKM5kQYBzE1ZKWPOfMdtvx4kVhGgWgbRW4nKVKJELyic+/eIHRMs+/++Y9XefpNtL/npMs2qCYplDbY4W9VkphnBOPDwOFwv7FFdcvt6ASp8PINCViVqgESkPnJQEy3qE1hJQJcwaE4fXJJzcMx0GSEyObTE6ZcZBWxKI0YYLOiebN/mpLKTDomryKKA/hFDDVXKMFLs2SWBXovaXoSJwch5BWF8Va5WzBc4yFeZiISYnmV07Mc2K/3WCdXZivAEyQNomu82z3G+4fH3kcT9Vco2O/27Pb7hmnkdPjzHhUXG82uB6ub3o2W4WxpbI3hLVgVOaq37BhS5/7yuKSm5hKJpYsGnwpYNDMYQVidEvgrMc+o0UEAgDIZ2ZEX7g6v6XKKFGmtqkJO9Eqd1Fll7EVNluD0nKepSWsgXKmOZGyMKEAUpyxrqOsdX4pJujaNyFRWg2+xfW1ibs/bctoSWjf9xfAV/tdAyCEJVpBIi06iU1bpr0m5ozre4yV1tphHERsuH6mdY7tTtzePvn0MzbbjejuVUepBGdAhMU5K61tSrGQ+0vGFF2p7isQVu8AOUcxKlAaSmYcR7797g3v7x/o+44vvvgc53ytIK7AxTkAilozjQug6AkwtiR5y6/X35mqQZLOQIrngKfnYuhzFoXck3ORmFr80RWoO/vOD+u6zx8NsDsHxVqbJgqmuD4L52BbKRCCaMHsdtszAEPhTM/tSzHD0Mowhydab2dgR0uAFRBCJKVVG07VJF1ZYS3ltAJgF62oOaPPcpA2d0OI+JrIC+MlLYloGx2tTU3+pOCVFsaQBEhanfubXT4PLUBu52UrUNXaUYUps+rOnCfDbQzb97U7mtIKKkNthzYKZYTpoNobobIRnjLM1n83EOxc3HqaA4+HAw+PB6yx7Ldb+s7LM2atsDvr95zPoTbcKUuyD1Rzlcg8jxxPB7ZdR0TuXVsfQNZHYUKYWmgQHZyYCykKY1oby6bvF2bY+fHd656PHdP827k+/sN/9Pd+q9f/pmO/nyX+VOt9vr09cnf3/W2Xcnz4jF5dPbDZOEkMaYUFYaIbGsO0MgxjJMe4aL6hHQUBRWNMuJ2h855Q9eJyZTqJDq2tDPW1xTnlxnRa52qs5khtgqqzZ6GxJRIQS5EWSAovtlseqhFKK4gvj0695JSrA7tSFQ2qe3IFE54CJVprXtxc81/7W1KUH6dJ2DtKEWLgcDihtGKcJg5O86/93b/Dm69/zdvXb6quU22FUoYQZuIcmMNcOwcUzjXpgqbdV1leKVVdpXXt9tYuLG1Zi1QFcyV/maaRYTxIh481y5q6sM7rKCpdLtd8JQ6xF9tyYwnXTqF2rKxnRAKmudqdfaDWYs6llHRLSPBQxe6beVddI6yxUuDXlXGuNSkGXNfxyauX/NM/+9VFK79G2LOKgrWW25trrnY983jCGM1P/+gP2V/fcP6GnM5B43Xda3up1ZJHamCcwxITliI6usMwMI4TKHj39t3S6nY4nri/f+Dh7gGKGFzdvX9ACHy1XfUMmC11XNt3tyKIqHoIQyhrsE7Wpp13VHsTYi7L83W5f6/o5G8qmD09lqLiEnJIMUfcSuuzmcTA4mNgmNbSAp1z03aTjhKtFeMUqlb497daPnfWzhh2fc9+swHg7d17kbsJ07OFs/WCarz0A3EzIVhY9ruecRIWYoyZrKV77fXrN/z6qzdcdT2v37xl23d4bytxRTqSlLUYJa7i4jQtjuCRWA3TPtwrlBI5hKcFlZjE4KV1CLU9ezgNjKeBYZgpwDwFdts9f+33f4/NZsM/+af/AmeMtP32Pd53H0pIAF3v6fsNMQYeKsPt5YuRfrPjarflV3/5K4Zp5PE4gnHPusQ+d/xOA2FdL61gsy30Vz2HR2FNaC0TvzEV5inWB1ihd5r91nEaC6dxwhjpzR5nzTAMzCHLoqIabXKt4gOgxJ0x54zzBr9xaFuR7hyAiHFSHSyptmgqEXi/uu4EBEiScGIym84sIucA85wwjeVlTHUe1Ljek0Kg3zi6rSFGxBDAe9HsMCwPstKCxmedGeNMLJGioN+KULbWmofHgY23+K4ysmIkTIU4RaG/GsWrT7dc7T3jMVE2hWEIDFNAm0hGcToM3OxviIfAOAURmi1ZmDXW4nNhPM0Mj9O6GanCOAz86Z/8Af/8z38B1Adf6UrxL/jOrtVeZ9FWVWaXZRgncowUlRBmn2UaHdef7FHW8/bNibfvj/S9IVcK8uZ2wzwGdruOYZz54sfXvH3zII6ec2K3d3jlwMB4HKRyZU1161RsesvNzZau94zHmd519L4TlPvxLdc3O7pOAMmURG+s78WlMWdp00NprFKEOdL3WhD5jaTvn3x2y+Fh4uFuoOTCze2VmAo4y36/wRnZAIdxqoGJVFMOx4Grm63Q0aeJvq8i1saRQqKgiRmmMTBNkRikTSUVET82RrS39tcdj/fSWz7NIFbjEaVg01v2u46ut+QgweVm0zNPkWEYKrVeEYumpIx3jpJlAS1FLWKHm61nHEJ1WQVjFSEECo6ipcU1zJp+d4V3oisjbSGSOKWU6TSiOxcLfWWlPJwip+OAs45pjISU8JuOft9jbX0GUxXVLoVhntibjTAdQsT6NXhMObK76RkPcP/+xN27Eykppkk0Hfa3HRt6VEIqGQpiycQxUayic0YYkLU1lyKOPzmV6niioLY7dJ0jzOJAmgugodNngY4Gkoj8b3YOVWaG0yQCydaQc6wbtehixRzZKo9Wivv7R65f7Mk5M84z1il8L4LEkqYWbl56/F4qMNYbug0Yy+IYqoE05aXy0rSrKCxtjc7I5nleBGhHbpbhH7TLaYzrlue+pHmFJyRblTHIpupQCVCitcV6qUQ+bZNTaAmuS6VN12JCK1xIzPsE4igFcpKodPmRMB4biKJUS/RzBdby9wZrTYj2A00XOPtMCdYEpHKiMxnjEjho49nurrm5fcUcAo+HR6ZpWpkIpbDtt7x69YLPPv0UCozzuOgkaWCu98lWEwZprwFKBeirJXrM1WWv9fip2kIEhByEpVSEzj7NE3f3D/jR86MffY61hhD0EnQ/bYtsc6A0ALhd+5LOLDfvyfy4/IHgkXqZCw2oXJ+T1v56mewsbIxyGUidB82FImDrk5P4PjCsfZYk0Ge6aGdBbJgDf/6LP8daaV3Vlb1aigAqSmmur/diHb7tl9ZQECayMQajLKWs7Y3tS9rrFjfJnBlPB9FWLBntRB/MwDK3QwnPtpaygIWXgbeqD+NiGERleZ1TKhr4dSZK376ypIRRYlYEVK1J+dymJ9ISXGFgq+V+pJwW4EHWgRU8qF97fvry+UXYD7rS5ZpgurAzakthEztHrWpyqsohAPPZXDa6sT5W0DRGEdIfhoF7rek6j3WW3nd45zCde1bPCAoxN42hFbxsICMl07kzzamzpL0Bn43peppm7k8Dc4yoojBofE2+G+Puhx+/XdL5H/2jP/2tXv+bjj/4/feyRySkcJgLp9PzbZw/5Li5fqC3dmEmzGFmDjPeenEMXIoawphQRqNyM4wQkxVTMsaLWU+7H9LK0+5kXcu0Wtb55mgbcsAosxhqtedN9G5XDUnrqiTFHJmSFME0UgA7Hd+j4gDqekmGzxlopRRMA6Pb9CyrQzAIGPO0lbLrHLoabWnTCudVe7E6pY41FxoP77m+3nK8v+PNN98RkxRmBKs/m5ta03UdWsFwvK+MSk2qXSIA3jiUNWCk8FTSRMjCDFvXZGm7VtrjnWGaJD9ZxNDTCoKtoOJvmL1KUSrYrrWSPN6wuhTXy2iAljHreLT71J4l5x0hBlAiQ7JoGVJlabQYWDVDnlIKGEuMJ968uUMr6SxIKZ2vngDcXl/x2Se3nIYR43s2u20FCj8s9IiIeluLxbDDGzE7i2EmJc2UMnOYeff2PYfDicfDgcPjgWmauXt44HA4cDpJm+bheOSLH/+In/3sp2gUv/zFr/jk1StiSMxTFA3qUi5AvLbgttb4FagEpYrIp1iNM5powyJb0Frt5Vl7Grv9dutQA3yhtgijcFZcTNcCSl7WAWvXNVzeI8+mc47V8Vr0xeV5Fma+tLCu7LVWjPsh+JRcs16ebaUUr25fcDwdOZ5OHMfTR4E5AYl/uyFRSuE7z8uXN/jOcjweq+lLETOFb7/j7/3dP+Xm9oZpOFFywXcOUWHK6FKqvqGhOa1D1V97xtRIzJcEGE4xLQWtNs6NTQfr/c05M44Tp+PI6ThgjOHm+oo4R7799dc8PD5wc3PNbn+1xIrnn3k4HPnm29d88813HI8nPvv8FVfbPb/3xStu9ju+/PYt337zHY+HR/zO8gefvwRqq/UPOH6ngTDrNEUr/FYSq3lK5BmOB2lxLFRhXSWC484JwCPObIHTOIv7T+crCmyEApyyJHlak1UinU9/Dde3XbWfrRscoivVEu6ut3Rdx/EhcP/2fgHTrLbQrZu9s1ZAhJQrYLCiwUoroZYahTaKcZgZTzPbfcc8lcUWPc6ROGaGg7gebbaerrfirlR5EkopYf9EKFqC8b6zlcUhItXjKRHmRsmWNju/12hn0Raut47715rX7xNjLKhcKBiGlHm8eyS2nl4vGlkokYLa7DrilJhHYTUc7yd21z3v3z9ye7UXQdiSebw/YIy0PpQsICdI8GG9R1nL4wAw42wnFWcDU/F0O4hD4nQ8COC19eKkiSxuYQo8Pk5MU2SeEv3G1UAhs+2bI1Tm8PBISpGbF3s2245xmBmOE6porq56OuewV4aHuyOqCAPv+mZL11uOh4GSod917K42hEmcIDdbzzQG7t4daC5A2giT7+7dkd1VJzPIWHxvefX5y0oPFffFmDNzkCqm7z23L3eUDI8PQi+dVQCtGMZA1IrDOPHwcKxtpp5uY+h6xzQdGMdCKYaua539hW3ncQ4++/EWEV6fCcHgXI81Wp4xpFp6HGamEDk9TnS+o+s7Yk5iWPA4st3sasVM4ZzhdBJm1dVVx+FxpN8YUgLrqGLMgOr41S/eY1TB9544z+hNj+1EBNJrYReepol3bx9AiUaLNSKI7/ueH/2k5+79kf3NllIrJApTi6XVTUsVrm+2qE4YAik2a3pZqGNMbLcdzjlO9yOmiGB03zuutlJN1QqmYUJ34n5agNvrHaGXFgFKIQWFtooYFSVpTsfMOM6gxR1TI3v5QzlgdC9JmYFOKRKFzkrrgNUa50xNpFfNH200x2HEGld3ZVWrc/L6GGbeHw98+sk1pSB0dmsYTiMhnMTEwFoSmmFO7Dc9p9OA7z07b+u6BDprdHBsrKd7RgzJ17bRlhB8tMr15JD1TRKQkn9zta0dKc3kknGuI+fhgikS56kaJUjQa5yXxAbQhRqsXerBOCeCqLlk5mlaHZDOSvDW95WloqQC/xvCoBa8L9bb59eMrGVNi8NatwTbSoE2DrRjf3XN1f6anDOPj48cDgfGaRQHSgQQurm64sWLF1jnGIaRaRI6ea5JhVHVnMHqi4S+gQtN1Fm+ez1PpUAjwuhaQUqRkkUX6ebFDdv9Fq2rUUlpJgFNmejDgPaSxVMqs0A/V2Bcz+HJ5xgl7W0ZezH8jW2hUFQ1ubNEoSy3+ilDr13zAjzVANcZt5zrbzpaQpxyIpFkXz87rLX8+Ec/5u7hjuPptGjreN+jrSNGST77rsM7y2bToU01HvCWcQg4PVUh+TYuH45Na08ZxpGH42ktHim12K6f3wPZe2R9KZzd+ye5TvueOcb6zMi/jV5BsuX3UV4voJIkx6XzC8txYcSmvCSCOadapU9455nGSQxDdNU4yZkpTChEyuD8WV/voexJyzjURFMrJOnVl6OVchGx+bMfakWVXRC9rdKs3q0w8nJGigKV3a4q0DCFwDjNTNNci0GK6/01282HbKZYwefzFFiSSCkoGGXFUbnEylRRdV1dGXVGSxwwheoYmYS1L4wQmTebrvsARP7f/K//Cf/uv/e3Pzin3/b4H/+bf8E//I//8F/6c86Pzz6rzKdSiCFVKYW/ejry4vaR3ovGaUxxZV7os2SMCEr2Huc6nBe2Rl7AK2H0Nf1PkPcW6prOylg8B9tbu6PRZgHe27U13WJqreg0zIQoCXiu+3k7vPOkOKFKxmmHvrCSRQC9uu6JWHXb0uq+VQqlrPvxOTu35EzR0l5nrFkS35wzm64n7RLzPDJNA9ZaUo4Ym6WgT6SgFwBLIfh3yDOBqiU4h6qVW7UPcyLUwoXWajk/6uvz070/TaDMygRr+0YVui+6rffPHxdT31xuMCLu7oS91lyl235UAeTGGnq6V7T3PkXftFKr7lyMlbRgW8aFUgarNX/ysz8Q7ccYeffuTnSjCtW1G0KMbHcbYspYo3i8ey/t3M4tbd4xRsZxJMfINIzi3FfduKfK8IvVfGweZw4PR47HE13f8Wf/4s/Q1nE8Hvnpz35Kt5Hc9frmiq7reP3da0KM7Pc7aXPVBq0toCnlEkTIuSxjcA7Yt/FMKYJztH0nlbzoGBYKKs94I6ZpaQHQzga1gDvbS89vqVIKUzEaI3QkaYcvYlznO4+qe9t0ejz7BLUAXHLede6BrPeqoGpraysKjVOEqe0rtQ3/4nLXWPCCTb7sr5neW2JKknfXwxjHtpoWnMbxgum+DEFruvgtD+csxveEGKWYhJBAHg8n/uLnX/KLX/6af+3v/U1+/Ze/ZHg8LEWaXLXaUK2guK450oorIGc5K+QIeGyXAr+qWtaF1VQIyipTUAteBbBO9K6vt5JfNnZp3/d8/tnn/I2//qf84he/oBW8Hx4PfPXVt3z19TfcPRyZQiTlzNfvHrBW8S9++SXXuy3zPPP6zRuSTminmee0uJn/kON3Ggi7vx9IQN+JtkSMAmaprIiTAEvKiQ6FMZrjYWSz8WgL+23P9X6LMYZxDpSsOB3nqosEQeul71cjmhDGadzG8fLVDu8N0zgzTgGXjCxMSRho9jSSo7Srba+2jKeRXGCaC2kayTW5sl50rJqYrLWa61sBRrRVGC9U3DBHUiw0wVqlWZDYFXwTYdpcCkoZCkaqWYAzlq3vqgARoCHOmTlIy9E4inV3c/PCSMGpQ3G1dZStW0RjjyFw/zgiEx0e37+hYEgxC8vN1spXvbZ5DBgrzntSGS5MYxB7XuDq5Y437+/pNx2qaOJZhdiYUlsUFEYXUhrlAcyGzc4xjxOhjBjrmI+Z/dWGlKmgmyKEzDBEjPUcHmf5HKcZTmFhZXUbj/MW52G760XfIGXinOm7HpU1x+OA6zzaSGV3s+9QRrHZ9UsgFMaZ65v9wpSLIXLdNcbHDKpWF5PheBqFBnrtOT4e+eTzPboCTsZLJK+qRtHpNDJPM0bL+cUobLXjYcJ1jtevj6Sc2F715FrJ2r98xePdwMMJOE68f33k9Ng0ChLTJOAKBV6+7Ok2YgGfgd3VDdMQ+PbLR8I0cv2ik3ZSrdFOs7vqGI6KYZIFyRqD7zZs+0ROicPjiHcJtGMcI/f3AyjFZt9RMrx/dyBG6IxG6cL+puPrL1+z6Tvu3pzYbl3VntAwzxSTKRmmKbLdbrHOgtFY3zHendAaYgxst3UDziKG33eGkhLzXCTwrLp/42FCbZS0OsaqSeSEFWqtQSVF7x2zm7F2g7UC7G73Ox4PR4bTgK/3/v39iXfvH7i/PzCeRCNPO9mYlbLiLhXBKZagNuUoluCup2h5Zm43PSUmcWmtAaxzRlozT5nhcWIMk7QoZVEkSM3fKies1Xz6+QuO40Qs8MnNDaYYxnkQYeYpCGU+ZT795BV937HfOkqJGEGKGIfEbmPpewvJQoCt2bP1O5RpWmgCHBSFbDL6vFXr8jjXrJHK3Rmjo+QKPK0V2FbxPn//00MSGEmy5yqa2pLgnFItnSJBaBGmmlZIa3KWapvWamk5zlXUW1eXnadHnEd0BXbPAYDvOxZR8HNmWH3WdE1aBYRzK4CoDBjHZrPjxe1L+q5nmibGacRXM4wUJVH2nWN/tafr+6UVag5pAcEaOOSMxVoRMqUIS6e1zumzROH8ikrNNCR80SglbUFUVsNUWwW6TjOOA6hSDV9AP2XDPAdAPTd+bVwqEHl+389bFzVra9/564qqHmLLz1qQ2photUJbVtBg+fzKBluAomfOr7XQnbd9tr+360sloc8CSKUUu+0ObTXTPC1BnSRVwmQVxrrothSqrk5KhJSJ2TBMEZMzhqo9Z01twxOWc/rYUAABAABJREFUeNPXGoaRoer2tO9eTOmVWk07Sg1aW0W9MUtKInOe2EjbtyRaiWYnX0qhmXE1phdIASEm2ZO2tlu+93wsmpOwrn/P2dTWrAp6nabK3lqZGBoRzp/qtTXNFIXon6Qn60PKpZppSPHTai1Ag5I1trXKXGgqKUnIOF+HAGc9WktMk6uT9zzObPyGzz/5DKXOwBKlmMNMiLKuN4FxpYRNmRtIoRQUTRHrVIy1bPotcz8JWzhFhpMYMHkstncVtBbdoSln5iT6tY1Ved5e/ZxG2H/v33jNv/vvfTClf+tDqx+ms/LbHM5dtjvHpPjs0/d89/rlX+nzPnl1pLOGcR4vWpYbAyjm0vxbK2AE2rb5JqCMtYac1IWDqdYab72wvc52ucZ2XeZm/Zk41ssac+5iV4oWl+OqN5ySuJ4LcKRwvkMZS9df0bvNxVqzjJNsYoszIReFGxDwolxce7t+efbrtedMQlr+aUCw1RjdMU0j07R+hjwfEVTLhuo6rIrEInWNmeZZzCVKXs6olEyqcgltHivVCjIfFsAEeNHnOMPZL5dRqGv9R35tLdo5VJG2wPNxtJXFcvmdKxOsyRS0n1/sYQVhuunK1LxA5Qq5MQeNxKFXN3v+2s9+f9F87DeeMAf2uw3jNNN1npe3VxituXs4cHd3T46Rb7/+htffvWGOhe22J0YxlRpOJ0KIhBiY51mKK4qFqZ9SYrvbkXNmd7Pj6sUVfb/hJ3/wE7b7HTfX1xc6jTc3NygU4zjx8PjIf/af/mOG07jonVrrFpfcZXbpNi4f3Lp1LEukFPmOmIKs18ZU9+4EWliDoBa22XKPFHTmeVZoy4pQMpe0FeOlBj4ZLwXeQiZHveiGn39CKwIaY5iTdKxAHRMKIK2bp+E5sf0VCdVP7cZr/KqM6BHnEBnGSOdnzFbXttnKwi9gXUeXC+M8fq9+2XPHOmbr2qDkF6Aym01PKZlxGkhFujsejyfGYeYf/aP/hBd7Kb51teitm3FHFs3fkjO56YZq2afMwmiWI0aRPKLGJ4XMXOlCF2uPRGAUhFGdYyLFjLMehRbX+6x4PBxxXrO/vlru59dff8u3377m1199w7v7R45TYA4JaxQxS8zROU2cB16//o5hHJhCkFZishTlvP9AAuFjx+80EPb1l/dYb9lddZQkLg0hVOTRaGF8FE3nLNYZae8qha4DClWDpYrAlhY4QgpUBoFMOKPBe4PxFmshJMXeO8ZRBN7F6Ug2VBDNDhCUdrvd1AW2kEsgnGTT6DeOvvfEkHBe9H6Mqxu0VrhOYb30fhtj8J2pNrbCboghMY2iodX3HpUNOdUNv2SMk7bCAmhrKEYtmh5hyKgZVCess3EIKCWBne8N/dZx+8rTOc38WEXpDXTKcvvJpjo1FY4PkXkOnKaZiMIpT4qKeWgWttLGt933qDxyyrJ4W4PoLpXIj+0nZBW4vb2mpMLxcUIpoaRSdG2xKDgjrLlhSny+3zKeJh7enPjk1RXjcWCOhXGc6TsR/c6pOthMia4XZlrOEkj6veX+TuOcZjzN2F4SY3clYM2vv/qOwQde3l4vG+dwHLh/98jjw8Tv/+wLHu9P3L7Ys91t+ParN1zd7DkdJ15+cg1kHh8TY4i46v44jqLvlnPg4XHgaufZ0HP1osP4nlQyu6sNxUiLoUEzjzPjMNWkRTOcZrx3fPvNe/ymJwdw2uE6y2bbSVXSWh7fPTCeJkJIzNPM6Tgvm7auvePXN56cMlNI/OivfcJXv/qWeZK23Bef7Mgx8/71gRQKKRScsRRX0Fc9w6Nc36ZzKAwqB+ap4K0k7XeHRIqBaYzi3mcMzhnCJOL5gQSLa1/h6nqLQrHZiBByyoUUItMs4LLzDt95dNU9U1kqGcdjwDiFdppYMsPjyMvPr+l83SCtZVtdRVIqzNWtdZ4D8xSZRzEZAMgojDPkknBO8+rzaxF6VYoU4Hg/UFKi96KHgYrsdwYVEQhCCQimNDjt0UmSSy3UiyW4M9oiKvSKVEBpxXXnGMtl7KeUtE8qrUhTwkSD0vJMyH2URHG73dJ1juPjAdt3WC9obSFzvZf2zXGaCTERY2GaA7c3V2JDnAqbTmGsVCnHKdB5ATx0MvQmEXNiPgURay+ysRmlRBdDmUYhAUoVKKWugYmicgVcL0ERASAqXKHF4VFpaS1cnIRYx6P9O8TMlGa8dWhbSGGUz1kj78WcAy0MPW9bRVqLBtuZoH1LYhYHrydBiVS5qk30s8Dc80y4CyYMa5K9tNYotfyvjafznqv9Dfv9nuura7qu43B4hJKWtS8nccnpNxv6foM1plbfJLlvbJYlWLNirW2NW9gnqghz8GOabZfX1v4i9yOnwjDOzCGSS+Hmeke/saI3OSdMtzJ42yEBsHoW6Hw6js/9mXJzhLzUf1nB1+eB09U9sQIwWn3wmoUVdhZQPneULM6URl2y6KxatYiW8zg7R+MMe7dnu93WVr+ygK6tpQolBipd16GAYRxRWtP1G7yxi1NXa+eY5shpmqtOUK4AW+Du7p6r/Xb57tbO0BwXl+C0nmKriFMKperPxCivaeyNlD80F5BrlDhHF2EtdZ3BVBfRlYCyzm/5N2f6XQqlpMBlsUuyGVNkPIxstptlHRGmQ+VTneNXFQQyVSuUIutv0c1psloMJNFKUaXqVpqqa9OC9LNk91xKRNo+zoV+5XucFT2uvu8xRjNPM4+HR7ZbV50d1/GKRTSS1oGXREX6irIUNUrBe19BZWnFjjkRTyNaWwwKax0pi2FBa1Vd24tFNsBoKYDO00Tf9cuYD8O/mvD+P/yP/vq/ks85P3bbaqRTJ/nOwc9++i8BhL0c2HQd3ghNpCW3WUtr05DqnK4Jb84FlTJFmUUcWilFNDsUoqO6aLSyskMWveAz1teyHp3fb6jaWZmQ2t5S1+bWxtpAfmPwmx5tHM7v6ly4XJNy0zhURgqetVVuXVPV5UNCFeY3K8OqJaU5RUos61pUxdWVquzbOFcCV2NSw+qPtxa0Yvt7zhj74Vw7X+8L0hQna26jsj2zHyguWkE/djQ8f/18mUsFKfose0jVgfvYXtH+3Z7dBoZdAIrnYCRnjtBP9o1lD64g5fXNngdgu+kI44zrerQy7LdbrDU8HgaGcSTMsQJSB755845S4PF4ZL/b8eL6FqjO7taw3W25vr6i8160dLtO5qlztUvD47te8g7r8Z1fik3ngu5y3wsPDw+8ffcO5x2PD4fl9846vBWH8FZYYiksSe3g6e1RFFKZoXgKpQLSUlgoOYhTfRENWs70Ws8/4ZkwazlfU4uHqmq5aqPRzgt7rs2/IgYmcU6tvlE/c93PjNE4quMq50W75+O8dm7nF/zs63LLex0hRO4fDjhn2HYduVR9v1xjaOPwLjOHwLlRy/dM+e8/tHRTtfX0eDoQqkHD8Tjy1bev+Tf+23+f8fGeh/s7xmlGeSMMvSpFIPItGcKE853MG+cxKRI+cLAUgFyRUIpaPFMLXmiMXgHxvDouT/OMd5bdbivGfLXAZorl4TDy//h//qf86ldf8d133zEMJ8Y5MYXI3XFgCnGR2tBKs/WOUUkekFKgaMip6jMXiyqG3nxcJ/P8+J0GwkSLwksvuqsTISamIqLapYAuUuHpvGOz63Bei8h3yZzGSGdFb6sFflCDpuVLGjBlcJ0EHs57WXiLVCEtkng770gpVqvcAii0dzjrmOdCShM5R1lEcsJ7i3PSpmUU6I1ZKjgoSQQaZdM4BUWcMHMsBB3JoSzWt6U3GKeIqYjemDGYrgZnWpGNIqEg1YqG1WyuYRgkYZymSVo0KhOuBNmvjJPF3faaTmkKmlQy127P427i2+/e83g6UbIIeodDkEqbkaDfeU3fOTYbzynNkKWF9eYGvO1IJXFzs+X4eMQZjzWG4XFGacX2SlocU46UIi1v1mjuDwPOW3bXex6PR4rqGYYj2lYdgEmsms/vle860W5KVZ9LW5zPeG+qvlchhIEXVy/oOsc8RcZRHlrRCchsdluMF1bS9e2OlDPjEDg+DIQ50XnH48MR2xtubrdVJ8wRU+Hqds/plJmGE5TCdr9H1fMKRRDzVPUEfOfpqvDucJyIMYv44s7jrOX25TW283z71XtspxmmCVCoouX6qhD2NM1MU0Rbw+7aMY0B7z3bbc9cneeMKwynURgqxuCtgywVQr8RVolzmjCK7pXVhU8+6eg8GKuJQSZrv/NM40y8H8mxcHyYmYPoS1mbSSFjdKHzBhMzqIw2ogXX9R7vOu7vHjHGcjoG2DpurjvmKXD/MHIaZnzXYa3BK8fhcGJ33TPMMxSLMpHN1knLbm5txlXnSUGsjE1j5LnNubC77tBWQJ2S4OHhkd5bIGCNxnvLNIpb2Gbv0TPc3R3Z9JkwW65f7Di8O9F3HspEiKI1Yq2S82hxcQtstQBfVjXhdchKMc6SSErrkTzvWsnz2tqcGkMipijJUWV5OOfYbDaMkwjobjc7QpiYxpFSNNc3e6yzDGOQyrPVKJXYbCw5KRHLrC1DThfu3h2xzhDixERgtDMdfnG3LEUq62MQ4WZre5R2bMyBEBOd9yhVdRCVuLiVSuVQCAjW9J5KqeCQVlJhjoo5FaxWOFPNqmvgYo3BoyWgUAZjO6k4zwIeLEW6GrPlkklJESg4W1kpRdrZzwG7eZ7XKmEVUD6PRs7bCc+BmpbMtED7Yl8qInqvn7RiqZasKNFY2Gz2AkIC11fXfPbpZzjnOBwPpDhhVCKWSJhHYkj0u46r3Y7dVkTWpzlyGqfK1Fm/SGtpW3S1nSfltNDwtTIY40Srpoh5QymZzDOBjiqLFkQpIqIeQkBpoffrKrA6VRHp8+s/b8drgFSR7IpFy6ONyzOJnzayD8r7LpPPy7O8/NlzbZDP/b6UsjKg6+U+9x5dW1KffudSjX3KDigs8x1Ynt2n7aBtPimUtMF7z/XVFVprdrvdAtau4FWpoFypc1sEvw+HB652HaYlKIULUOfcqKGBva2qX1CiE3cW48dYmS5nlWfR7qQ+V4WSQOVUC4QiFv/cuH3sPrTvWlp0C8xhptQ4JEVhqqQKACqE0SWAWa4mD7meowC11iiskiQ2xkJImVRkzVNKkYzGFrAFlBKdJ1VBd0XhnNCojb3QvGuMPpRi0/dcX+1x3pNzYr/bUkpkt90tbL9EXkGwZQDkwjNJgvaCiBIrtbQ6xcbUmaMYIzWNtaIrmCoJ6HliZ+sYNk3cECOmVvlfvpp5cTvx/q7D+/gv1Xr4r/rwXS1AAKquF9+9uf4rf57mHb3/Ee4c+CmFmZk5pWowEBfHYq2KAJIVUEmpYKwlFo2tC496+hxxCXq1YusFCH/GIJ1DYgrCoG5sqFYQWY4CRlkoUhgrZ3YJa2sjdX2q60wRnceVzLhULT4YlwZ6h1g19JTkEC13WV5XTQH0PINSFQhua2VbQ54BCurPW3u4rNVnDLnlEF4vSNastIEsOr9LMe3p8q6QTola4CqpVBbd2UsUi66T92Kak2sBQCnRoVWoZzG3diwMztSMAeRKnlMXkvVkZcetH2IlYTo7+t7zi58/cK81hweJ+43VS0u31lSQW8ZBTHFmXr16yRdXn/Ppp5+w20iBY7+/YrvZcHNzXbWLa3urMcIKq9cgLveaYlZHWeggRbkvZ+uSBrabLVdXAqydj6mMg6q3JS8/b3uyVqv5x/J5SpFLxCjphFEoUpFc2ztHjhNKmQ8cFqljWWf98zdJtTZbjXYO4wUAa+zIpR0YVXXBNHHKzwJLxlhQzXW4fnvd2/Jzb0ByilI1yS7iBrU+p61gpZU4HTq/odtsGaYJZ40YBQAUAah3uxeMc+D+/nH5Hqj36ZmjkWCWf1cWdCmASdgqORLDzIvbG8IUBB9QmvfvHyi58Hs/+xl/9k//KXMIeGtIRmJnRa6ad9ImrJQW4zWa5ubHtbYaq6xRxqX4KNI11DXDGsvmuhfjPWC73eCdlZZfpZmS4pvX7/jqm+/45a++5nB4XODXVO/rcq2AyoppKgSVyVGMBJWmFoasONEajdEfdno8d/xXZ2f8KxzOanJKxLngvYGs0bq2JhlDCok0JbreoimEKeKs5vEQUQnCXCAlqailUhd1qnObHAokMeuEKUVFdh+PwhZogYitgqepajg01zTnthQrbX0KTUkGrXJ1moQUlmhfJpy2hJAxSJVmGEec8XSdo+stVnumIkiv7QzzHCtl1oqjYqtWSOELtGzy8xQxWsRVjVF0G5m88zQKvd4Kg81bi8YQRwketBYgbZ4iOQnAst305LlwOs04rXGuZzpFiIpCJmVFVqBNJidFmKJUAeqcVF4zDpHtlQB1wzFwOg68fNEviaU1hlLZHVJE1RgnraKyf4shgcIQYsF1G0qOgCHnkRQT1jpQiuPxRMmRbS+i+1pp+t4wB7nLXS9RcIgz3759jbWaEODx8cR+vxFNuSmJxthcGE4StO/2HSlGSaadZxgTpo9snYAo1lms04Rg8INmUBKk9xtxBO06aQ9TtbI7h4BVtUqtJKNRWgKeOWTGKTHOUTb5YSKVguktN1cdN5/eoNG8e/3A/bujGERg2O86XHU/7LcCSE3zzIsXN+QcxXkwKrreQ8nkWHg4Hcklsr92whqbJnIOGCOJjzGW/XZHSIlxDtJGkhPDqfD47iTPQmMD5SRtwhSyBucMm60AM9ZaDo8T1zdbwhyZppmUi7DbvGFOBW0Mty+2pCTgSs6FcZo53An113RSvbfe1jYiSDHAYnFuoChOx6Po0t1eLwFEQVpLetdxPJ2kz94Ztlc7SpH2WNm0hF3Zbx2b/QbnqphrkkfMOMMGR49aAIEYE1L0bRt1bV+p2n6mttyhwFVdjcaqOE/WcxG9CYOVOCYXEd8tRZLQTsDKdAz0GxHgDvNY9dNspexnthtP7gq7raPrDKlEfGeWPnrvxSCg30o1LyZFSOKYpGtA06rLwzTXRHoml1nWONPhKwhWSsQ7IyAKlQJfq61W20VUOGah4WcFobT2vmqlTssdC+SC0VXLQWU0gRknYFiKKHXmVlmt6WlAYw34XdV0NFWzYmmDcm4Zb60M+ZkN/xwAe9r2+AHQgoR0pSYpWjUWgcI7T+cEzHbGYK3Hd+ISKMFoxzAeSWGg84oUMmGeqpi+ZrPtubraYaxhmAPHYSSkD4MmawydtXTGMFctkfM51a51jTmLsABSEoa9VqS6idjqjHWeAIaQiDlizVaCbb0KNLfX6ZosnIeVGlW1cgoqrxV4awSUayDSMqTn+NJHSqUaYX78UH2vdlywyoow91JlNsm81R++tgJJqaQFYJHf66qH8eRz1coaeLbtt/4RU8LVn5sml3CWdEpCU8haNIJKETA320icDrBxi7OjRtFpS4hBwBgF2ug10M81xtFaEpmy5kZKCfPvgslRw5OL3L1Iq3HOEaWlQEW76nLZujpOIuLfxksv7dRqAezK8iWr5IN1rsYCRa49iEZWSnlh+J2Pa84F2xIUVUHDM2dJsGidCaVp06zPsyyB9e/WL23L7UgpEdoz2PcSxHsnosNOnDmv9lds+l5iqvKxpEEWBdl3J2mHrc9mbiBY04JEWtdUZXvlXBfFXF0nTaE3Gu/cwu6Awly11TabDUrB//Tf+kv+9/+nP+Fv/a33/ON//OlHzuvDw5hISnJfb27uub+/+cHv/SHHOLgVua1D8+WXf/XvsKa291CBDRS5OlKGlMlhFBCsYdRqmXygCqEK15OlpVUE7tc5cM4aaoy80gDVthYomSuiAShzRpw9VyOD5XOadpiSFqGu7xnm2vp6vqdoKsvkuUOkIEpi0bC8BJzl3+eOxKWOVQOA23PQWCm5zt2S89JCvwhoP4dRKAG4ZGwkHqd2x1ys/4oL0IACpTLKS4ltkVs/to2prfqC54wU9SFIOY6VxcLakrq0pLfY65mCy3JP676eKyjVlpjF6bW2Zst9fDIQWlPdyi5+/Pr1O37xy68YhhmtFF0V248pScspoHRht/V8/tkrvHdcXW348Y9/xO3NNdZYrmtcYJ2tOaOp8SQLOGSegnBK8i+Z5140ruK8GEW01uFpmjkejzW+LzhnBThUQEmUErBWEeN6H0tDJ1gfX4XsMVLIFQOSBtKAAJNusyEheltlAb3OimHLz57XdTLWor0T/TTvpTXyyf1s8639rMnxnId0y57NU/ZZOfeCkHkJUNt4SxYzJgUYXdcudQmiCrurEOYB7z0Ph0ceHx9EzkBr9rsNV1dbUAJi3r56xd3do2g6QwW5Ph7HiAZXY7UKDjGMM/MsIJDvOm6ub/jTP/xDHg4PjIeBN8Md4zjx+s17/vLX36CNYbvdMp2OMuJKihElZ0qkahZmUgjy/OfVHfRjh5gZFZpxjoLqFit7sVJwdbUTl2VzU4vIUhDQWop7aCeF6KrLaQzSEVSLX+cxgreGHDVTSpAndJ4xWkz/nHN47+m84zg/UtIP0wn7nQbCUhbmgFaiqWS1RfuC6xN2TsxtA9EKZQ3j41zbjYTxokNzdRQhVecMRkcBIepRYzZSlMqPdUZ0r7zBGouz8j4RVI21BVJ6aiVYhFJEhwt0RTcFmbdakbUmxSjnVRe3vpMg8DSM0p7Vy3dQCoYECHintSKWhCuWKSZsEjaXt2IYXSZZcHNOFFVwTqN6j+0czjtyXFkrm62IrWoDWok+yJBrC5Y6T0wBXXDG8dntjn9xf6xtN40Kqdbg2sjyNgdBDJSSdq+UU2VoKOY5Mo5BHFmUJpeIdeKMV3KhKOi2ju2+q7bMNWDFkEpmjvIZ0hboa/VKGH7zNJ8xOhQosXrWKuM7TcoKYxU5FZyXjSSnhHUaBsU0ZbSOlI2q1euC1kmqOyAaccNMysIqdE7azeKU6Iwlh0wown4SwHZGa7h90bO/kYfVOHHDG0MkaS/M1pxIU0aVgvWWKSRCguMQULos1bxpTnRby/52i3WO+7ePvH/9wHgSzTttwXojralFdOEeHo6kCMMwCrCVLWGWc9x0Ql0O01QXsox1Ms+1EgeWkhLWduy3Ww6nI3PUS+IWwoFxCHQZARxNqXNMznkOIjpps4gOp1iYxsijHrEGfG0F3Ow6YWD2rtJcIcyJeJwhFY6PI6kkpnGmU4UhTPRbz+2LPdpqVF37YhSQuBRJlKTF2JGisLx0S/qL9JSTpPalnRaHzDmSQkQhml/WGW5ebnn79h7f9YSYsV1HeDxiNFglrK5pEo26xuxSxq2MIiWb2ZoQ1iS+CPtGabUEvjGIGHUL7JTS8nxaTZpnuk7je4M2GetFF2McA9aWxRFJqYI1CAOsFKxFQE1bQ1UF83QihyrOWqDzHd44WfMWC+2ma5QvKsmiETSToqd3Hd55tHK06mNWUvkXJzaFUQaLZUoza3BdFsAKKnhVx6C1x6WUBQRTck0YcWKVm92SbBGsNVZ+J0Fbc7+xq1ZDhqJWZ7qUEkVVYED8MpcAWfaA9vxfVsTP9WHaeRdlVvZM/ZlSVECpFipyqe3bAejYbDdsN1tKyYzjkRQHVEnMQezuY0xsdz373aay9QLDnAghLMl+O4zRbHpfWYplKSy0NrmkM96vwtoLyFGfkVwDjlbIUdqjtAUExPBe7u00icvYwrjJaQGBL8DCJc+tXyLReV3/a6tqMyoo7Wlo417f+wwIds76aInv8j2qjf/H9SHOW18WIKLS9zWFTF5+TlkT2FzEJa5d5wLwtGSrgn3nc6QNdKlZg6rFKq318tqShcUtP1NrVE8NLGl7tWoxuCS/NWkLKZDijFGQfVcZjnMF36WoRJU0EKeshHHSfteSmyd53MVYre2lLKCarOmBkgvWaiiKrNJZgqKqCPUKCura1gKQwlSD/wqA14Rb2hZnkXnI64mlJnL85FzbfbRaM+cLa6M29BXAYBHMbx1frUVSSPRm0fAzVlrXYkxMFYzufI91wvCX1raCw1ZW7nbVn3sul6njRcnMs7i4vXn7HrK4q9nOopr2UhJdGUpBNyv7dLnWUOePO2vJ1EZXNl0tGljHH/y+tDvd37nnb+5HjgaCAf/KQTCAGOWZbQyHUjQh/HbneH64ClyFFPGq6i+yPt8fTTKzPHu5ths7Uw0U5J000GNpZywsLZILuIJadG1TNb5KpbEuL1vuS6kAWGX3NUZ6rgYkSyJ/jrdcrAVqAZXW9bKt45cg9Pl30j6XqvdTX2eUlnXhadlCnV29qqYr6uyXF2MpJ9S+VmKbVYS+VE3Q9r5l7S0CMizMHFUESFOXH62a82P7d/vr2evataWU1j0nlwtx/I8dK8AJVLCjwBkY1lpE13ZUKf6sJ/lcq5xWiqurDe/eP4igd5jXe0XVp83QuQ2fvnrBfr9lu9tye3PNH/ze70uOWEXzG7tOW72Arm08CqXqx+bFFVQDsRQOxwdOh0emSYDgYRiZQ2CeJk7HgcPxyLv3d7z+9g0lJ3ovhdI5yDn2zjLkTIh5nXNn+9JyFEBpvN2w7a+4Cw/Lr1pBwxjHPI/kJLnNxT2o92iYJsmBNx2d7+RZrLqu240UvZUuaCNxpa575urwqJijE9F9Lfqwikgp4YIBtpx2KZVpVZ/XnBbW6PJ8lfWi1VkRJudCCIFpjoxzYA6BFAMxRDabDcfTkceHjj/545/h+w2ff/EjfvTjH3F1+wLrHTEEum+/YziNvHn9+nwkPjjPdq4tkoK2tqTK0leSQ9f3p5S4vrridJjIKXM8jrx9+8Cf/skf4cwt9ykIDtEADvkC0RxXVfc0RqC2oKqmE3Z28xsYSyuCruB7m+PNwdN7V02i5H+lWvHKiq4ZhjfvHnj3/o6YIjGKwH4oFezP8jkaRU4Sf+gyYVSUZ+IMCMsl8/5wTyaeFem+//idBsJEr0JXZ59ELhJEaitudxsl1MmUYQ5gfA/FkDKkSfR/SnXkoS7c1ujFshdYFpqYEjFEuYGI6Lqq7VO9F3AnxsYEKEvck+vGl1HyvSljVKWdFnFRMNYsiLi1hr53TFPgeIQk+oIoMkoVUokUJNiRfkpFSCKKF5JDL9VERPA2yYLrN+LwlXOiJMf9/UBOmeE4MceqlWANxmSsFlcTEWGWqb/ddLiuw6VEOMxcb3rG1JIRyUlLVhfPcCkSVGhn0UraG7TTdBj6TvQThpO4Z7nOrq039YGKMdUxzKI51DZvY0g6o40WTamYCClJ1UBTRW4zY4ioaabrHf2mI2fZnJrjSNcZci7MY8QYR+97kkkUFMMx8zCeGMdIyVu6XhZcrTLTJJXp+V6Qa99bul7Rbx3WGmndSGWp9gp4CMoU9lcbrq4tu63BOmEidq4mN2F13JmmxDRGpjESggRdU0gUEle7PTnOdFthKTkvDkDzFJinTM6a1oNvrMJ5kW/NKeO8YRqlGv3Z5zcM00msh/OM7xzkwqmyFSV+yzgvyXXOiXkKTKeJh4eZXArjGLFVeDHUduRpilWfb62kKRoAIW2KSokjQyqacR64edHRbXtc5ypIGcgII4WiyLVycHw48fBuxHkjFPNTJCH6SaWIPoDSTYRcnsUwR1SBq82GnKUih0GefwSssU6cTmPIzFOiRPkzJQk+QhStoD4nUoiMLUkrUhXuN56+s5BlUZ5CoMW/qlbuoLIyKGfB9vqa1gLQjpRSbVM6c2IxSlhc2WAtGAsvX12BztXFKOG9WZ7JnLMIvGpQuaBUJpeIt762vTrS4BA9PnFCtdqIvpS15AgzBa0EeBaA6jKgnUOsCWUi5YizDmcNGdGlykJjkOvVmYI4djbKfVZrQNIO0SyoyXTKpJgJJAwGpRJKR7RzNcgWGrdWGm2FsahNtYLOCaN0TYBreiOLyrJ2paJWMVBt0MjG3xKo58SoV+erdRxiEqBBPsa0G4uurYNWa9GRKLLBKz2w3e7ou46u6zgd7xhPd6QgAP40CrPPecv11Z79fodS4vo7h1TZO2dziIJ3mk0vAWSMYpAQQmA4DcQYpK02CWjlvIBlLbRaxn/Z+gQAlqRG1Tb9TAzimBdious7pvBh8qUXV7uVRVGWSbAMTS1M6CXopEAqT+js5WPYQrXqPktElNIC7nDWDriiHh+8v/1ZKrqiamW9ifBrpQUUY/23qQzYc4H6xAoAmZbMlfU7zqLXFRAr8n9zOFQg+idnie7HjlKAXPfzUghhFHOHivL42qbXgEc5USkSiGxfXpynSypLzOOsJBXq7N6BErZVS6Rzc5uSvbbkiNbCOl6nQQUOq8yEKiwt2KJxGgnTVLVexL1OWB9y0TEmcnM8bfu+XkXQnx4t+G5Fhed+L+wvYe9lXRaQui26iiq8XN28GwQ5zzM5ZsxGyz6hz+QzlOh4nZswPHuz6jmJw97M6TTwcBxwOhNiYO+MMJKNXlhv0p7ia1U8XayPMg8lSRFQVUHRKMuFhs7v//4dAL/6cv/x8/veo7YV/JaHtZEYP55exKhpewjAz3/xgg8e0B94/Hf+wb8vCWyWokfTnYzjXJ9T/dGPLjXRQhVSgt5WpjYFpe2ydjWDipILsbY2LAATDWASoLYl3K0lSNZBWGGrNh2qfIhxlLgCLecg2NJe+AQMa5dTnqyNTxmZ54D/Oauttb6hNbLcSrtYexa0sctaKO5x+rIw0ZLiAufzwxhhBMly2sDwLLmBLpVddg6ErWdfnlmjKWfgg2rXfglqCpNzlS4olJqDlbVF+3wt/uhx/pnyp8xSkan4KOu4XktjZbXvmcaZGALXVz291wxDrLIFusZNga7z3NxcVckOIGU+//QzvJOcMsR5cbS0zuK1XxxMS2ltoJGU1m6kVAohTNy9f+Cbb99wOh6ZZon57+4eGMeJuf57GEfGUcy7Ot/RvbiuLHlZz2KU1lVVGoD6/Ki1+E1rV/9c50TKmTnMWGuI+Ww+fjCMhbDoTfbSUVMLyM5oemeqO7qwfoy1UAuPIUZiSMSkIHXEWgA3BskVG9775E4vOXrN0y+AsGcPdfG3EBOH08hxqEYDOVJqu2uMkRRF9uDv/O2/wc3NLfvbF+yr4/c8TYQQ2Wx/DUSUkkLpBzr/NPirPcfyM611LUxKYbHzfjFF6ruOewXbrbjCn04D7+/uOQ4jW1+LEDV/4XytqLqaqIwKEetcLSDB4rze1oGLUVFLoVk3rbE2wPVcc8nk8kQ7LGeG08jjceKb1+958/aOOUTRai9iehOygLwWKYzn0vZHWTAyClUUIUGZI0UlYgj4jb0gNX3f8TsNhImTVSLGkTlmQkpoKyLCrtPYTi9osbaGftujXdVwCBUNXR7alUJ8EdMrSZJizJwOM10nLBnnNFkXtLbCzEpnQV/tW262wqm2dIWYCSFiRL9QFgyj6TYd8zgt3x+icDm9N4TaDiCVE9EB0gqsU3hl2Wz9Yk0+TwFKbmY0kuRVXSTnLNZBzprpUJhCIpVVeHceI35Tkx9U3fwUc0zMMaFIGFPEWSdmHoaj6FeljNIO22WKEWH1lvQbq2twJ+0exqgaiBeMgdNp5H1K7K42wmyxottiba1U1bLUNAfu72ecF3t2VJQHv7LoBJlPjMNckwLRFJOAJKOwOFvbd4zoLi0ChbUVMYaEs3KuuRSMC7LATmKooK1UgFKWYHYYkgBE20p73ffiXjlLe2FKmTIDWoAIY4UJZrTh6spL66Q1HA4jGo3TmXEOTGNgnosIm0+JMIttu24iMEgbbszQbXu6jSSSwsrLhFnaL7WqLmEtmDEK62pC66DfOJQWJlybv8MUMUpE410Tg0aq/ZttXxNwGMeZ0xjrRiSbwTSE+rhIVTRVtmFuipStathiUlXQtmra5cL+xqO9xm06Sp4rTV0SJm2tBGxKhN9jTHI/UExzwbjKXGzfwVqhledaYWyAIqB4TKVqbwn7Sp9RuUVvAsgCkKQizLCc5ZmbB81+5zidokyGUtj2nqurjbS6JmlljGOpG6paAoWluqTWDa2acC/g7/nRkvgFTK13xOiC29j1M2ogeLPtuDs9Yu0G442cRwroUtDWoLTGO4upWnwlF4ZjwBmL9xJUxBSxRtoX5yiArMXQGSsQuza1chQlTawVH2ctKSVxwikJhVtYq0AVHJf1NhUx0QhVM2FMwkSNQVrbcxFwzKq1zTvXKKyUVIsCCV0SKAnaafoRRoAwRW0vVtKGetGiVmpVn1LbMNfyamvfclbA5KcukOfsIckFSo1fZR1NVRRWm9YqIfPMVLFahawfMSWcCzhr6JxjOD5weHjLPA2EWejuISa0Uux2e168uGW33ZKLJsxBmJYLfCJ0ea0ECHNWk2OqbR6ZcRy5v79jmqa6bnb0m44X/qXMn9Lmojyq56Lu4tTp8M7jnCFPkZhTBdMjV7s9IYgDcWP9tip8G/Nzdsa6ra6/u2BvfBT1euZH9ZlKJaGKqtpza2D+HAh1+ZErEHbO+mvnrpUwtnTRCxAGApI1cGyZU/U9pZSlJWu92HUszq9HKVHNccZUHY6a9Cm1AoPtAz64fgFpG5NBwFOJD0IMK1tFrRm0qvuHsfIzrcvZx6+MqZRUTdhMne/nMVFrrVStRFz33IRmBcIagJarC5yt1WCtJTEWUF/YC8YYcg5nyYm0otQK4HI0FuFzlX1Ka6H48Ffq8mXSNV/HHnU2yhVAilXDSyldk9EAStpzrJVkpWkv5aKIRRE/ktytZ7ACYcM0cTwNNKa6UnZhHBll0CpVPRyLsZ6Qm/Mgy31sz2h7To01mOYqvhReCj/6/F7A6+8Bpb7/+O1BMIDPXt3x1beffPT3X3zx7gI8//VXN3+l7wH4+3/3H+LMbR0HS0GRlSIGcSpr6/oC7C4oUv0jizJXUSyavFSgSNXcYBGWJ8v6Vir7qH1M3ddaAUeX2h6uRFN3KWRpaT/SRizcjbE457HWiPlWSeuQt2mzJJ5nBYcnOYqcQrlYN85Zze33ba1b9zQoWqGKrjGTXK+qml8rOP8ECINFY28B6BTVnXVdt+TfatVfKi0ShEL7ztp+hn52nW8s2+Xaa1v9Kpe0rt2mgepn133BoHrmWAsiz/xSyTqgTVl04p47VC4UvYIK7c2dd2w/uSWEWdZNtbYgWlPo+w5FYRqliOFrN8z7u/cYK/HYPAcxEkoChon+Vpu8zblUgPI5ZsYpMJxO/OUvvuTnv/yax8Mgrtgl8fB4JISZXISpm5K0fL+8vcVZu+RFupqbhCimFs5p5nDJtr1cV8vSwh1TXDog2tg21tL3YZH6bB7ragLSpIe80/Sdp+87NpsN3ntQ6kIXMRlT9dZgrPtB22clp5WT/sBRsuJBFzHDR47zX7fizGK2FFd9r1gdulPOfPbpK37vx5+jjaMopO1Qa5z37PZ7rq/2bDaeYZgFhAwfGje1EZdnYC1USR5p655gKGSGcaCx1He7DTGKGcObt+959/Yd+598JgSakNBR46ySrjnU0rJrtACrztm6Fn6wHF3OBS2MbGsM88X+fP6OintImxzDOPHweOTbN+95+/7A+/sTp6k5lVYCRCUgtTVaJB9Y1ugWNUq8Ulu/bcF7J/HqR2UKLo/fbSBMK4YYGcfINGdOp4DvLN1G9LSMXduTrPNYL0wxRdUTiJESM6brBKipVW+5AXlZuEsSna0xRlIsdD14X6BEkjckIdIQU0EpQ2MbD0NgGiW5nubAvOhlnG1KpWCdIWdLGAPjGChDwFXxf2vjsgDHlBfWmgQ7hbDp5KErMJ7mCjRIZdfWhEwqv2LdfTokbAqif+QSvjc4b6sOV0HlLO1LrtINo8YEWXadM8RQOI0Dr4cj4VgNBzqH90AuHA/SFtb0lwSsOrNFV4huVBYARRbXgvWOfmfolZWqUq1wUoBj5nBIqFRwWRKAWKvKKRXCnBinWHXMxGK178U1pWRxtcgps917EdRTEpCnOWCdMIhiEEH6lgibhQ5amOYER6mMHA6BnBIhZq5vepyF7dZx+2pPjBDiIBoASYJZ2fQL3iq6vQcFzquazBsKUoHIqTANgbv3R6axAOI0WgqYzqCMVDqtNaBzZU51qAYqjBMpRFKdC9rWanFtEctZmEspR7b7jt2+Z55n+s6T5khMinfv33NzvauAmV8qccYaitIUDKXIfbHGEpeWUg060e9E+DvMwvhJoZCTUFnbglUdlKU1L0kFImZxLYspi1ZPSnTV6CEladsU4wMn190X6f8fxY630cWNvnTGaVThGBJoI9WioiowndE7JUKLCkqWCp5WBmXEYRRtiDkRphmKwpiOeUx0ncFZaYOMYWLTueraCcVClxTbvWcoEMJZkFoPrbQAjmcAzRrfrjuOBHBqYR8pVA0+UzW8END6dBykr95K+7N1GuO9sBJnuVanRVeo60RYNddkdDxN3OwsWqfa6mbY9htKLjzcT6RJ4TxgagJWgeIU46Kl6J2twuyid0RdWzGaUoSB0UCxlpgrVar7pibnukZXN8kYRN+lyryhyxKBVxaHvJacqoW2FB50E5BVUFKCBey+TKjbvcjLxq+W/URrEQw1tXX7HLA5f/8SPLfPK6CUjLWthQRUTRYKHwT4agEHNClOPNzdEcMg7oDTJG3dpbDZ7vnk1UtevniBcx2nIQqAWJDnTsn6YlXBOnFIbi3zuTL4huHE4XSowTbkvGUcTqT9Va0ogilyf1JuxgCNDaBwrrpTGcusZrQS9585BK52N+w2I+N0Ejq90miHrBNLytMumg+OBh6VBpCelZ0v2jfP7ttzfxaKuI2V1lp71r6onvni+sFGGwG2msj1ku1Rk6AnTMCSn72Oi/OtSW8D4s8Za0/ZGcASTLeiXEsuU9Uvle9dAbv1C6UQl4hrAqNWJzhrLAZbx+JyTGl4W6k6Ry1JadXxohaji6JaArAmjM3Yo4H0rVIrIJnoBOWqq0IF6mVP1WSjsHi0cUBrNWoU5AqEPrlnF0DG09vYnueaPGil6rN4iYGmnFFJHPeWT69thOdjM4d59d4owpJt7J7W3hzr71LWsn/VBP8DXtiZdo8kiwibcp7Z94aNlxbLolpqq6S1qUo9aC0uwEpR54K8SmKU1m6vlsS1Hc1c4P/+H/41vhcF+P/TkfLHAbQvfvQrvvjRf8Y0fbqwt//ZP3v1V/6u3c6w2WxEN6iOQ0mpFgMymSAFlAaI1Od6bVsudS9eCzdN1+s5gfjmQkyNK5f1v6zzU0A0JcWWIDGa1Rqrm9SEpWSDtsJu0abGhGd2fB+AWPW/dg3PbCuXQN/5z9pnlFUPq601go/L+coytMoNNCAI1uejDYemYNS6JrTkfNHmO1s/C03+gAW8lzES5naujEcFzz7j54WEXL9veZVSFVismk1aLRqU7by/dx9YxkauijbOIEA+LFpw9WTWzzvfJ6AC6wL83dzu+QN+jLOWeZoqoyqjaguzFDDFta/rHLtdz/XtFa+/+1r0gr24sMeYCdPENAzQ4olavpPzkplQjCYpyzBH3n73nl/+4i/5+uu33D0MYupmqnxPCZwLZ1kr3Tilp7JRNeqsyNE0V3VKVern/L7U8UNyjBhTbTGX+dVcuc9bCp87BNhvt1Mtbd+dF5DYO8PV1Y7dbst+L+zWEKQdsd33nDM6ajFKSZkyhyppJEQAbev6XtJHtN8bY/H7jsu5qbQwII0qhCdSDMscLfDtt6+5vrnB9VuMmzHWYpRit7/isy9+zPu33zEMX11IRVw+B8/PX3lGhWRTMuy05XA8opB2cdfcjY9H3r674+37e37209+j32wYh4GxmmNY7arOoEJlau7bTCckpv4IBtzOrmIThnGaVtRMAmMaOzPnzFiBuff3j3z7+i1v393zeJoZ5zUWLwDKME8z8zwvXXYxZWK6PBUFOKcxncY6sIaKeazg6m86fqeBMKgLb8w12AtAj+/FFavr1gXQWNnUTO0nLbGJQ0JBKmqu82yLEWBtmBcupVIQc4Giq3uQxg0B7zVpo5hCqei6LE8l1QUnxqWXfJ4Dc4iSLMPKcogR40SsvGQYh1A3ThHB3vS+BrxrpQpqIIQspDlrYpBWRmtlYdRa4bXGWCNVy2ggFh4fZhSFNGd2+8y+81jniC0gpqB1xjgwTuGVpk8GbRzX1xvu3k8cTxPf3c3Mx0AMhk9uLS9edViref3dkfu7mZjK8jCUGnDnXJjnJEBQNnQbcVxKtc/ZF431BmfBeY1RlhSlguycQfRNItaKy99wmpgmceE8jVLF1QrEgt6y33dAkfbPOXLjN8SY6DYe6y1qCoCurCvwTiotthO6aax6D/OcGYYRDdzdT3gvLYcpFo5zYrff4fuOPGW0mSk6gBZNrRZcaKWxVgT/cxbb3FKam5CMi2xnmnEcSVEWBW0UThWUlZY+ac3QdFvRK4nHhNKJOEvQt90aSWatqUGNbJipsqus1QsQFidLGCOn00hB9AN22w5jumo0AFIJN+LEFcrC9AqTMAVzsTin2F3L/e82ljAHpilwegiUyprKlSGgtAh5mmoCYHRB1ZbhOCdiEvadrolTDNWt0mr63kubrYkLC4FYgSXTmBx6CWJcdT0pWc47RE3JiTBntKnAYMwUMt5YoUVrBVhhNdWWpVwySltS1hwOkeEYRGfPidW4d0YsnBEGaN9rNBtKRD6zsKwj0iIsjKOlAvYEDGsVJmKlbXOZ5AmYkeitIyXZvEvJTGXi9pXYEmcl6F4JqVKLwWwU3hSKjhxPiY1T3FzvIcnzIYAsbHdbVFGMY6TDVzbYekj7kEOVBrAJPb0liaaCXQ3A00pD1V5pIaYkzAqUZddXm20NMQkoKlW6GrDLTayOeWVhvDYL+hoSLkUPSkKplZmq9JNkRrLKC3dgRdPcERAsRBFx0YrnA2i1skKW5KcWKeTZk+daVRo3anVxstbQec/Vfk/XiVHD4fERVaMzYRGL2cf11TWvXr7iardnnBNzpfzLkRFtzIIzwvRyzoIqklhUo4thHAghCBusBkdxnokxsNk4UtWCNNVK+3xvlfO1eOeXxFv0ACPDMMFNqjpFlRVXMra0yu8KhrV78EGlvo5fSlGYE1mcj/RF4FyWP56CkOdHqm2CUpmWsVzYac8FkVTWF+vz1ZhMqgVy6vn3aC0SCk/HCsXFGILoWhhtLp9jXfUDFWtbXR1bFqBG2tLWanW96rPswzpPmMflOxsTtlXBja5CtiUtLSAX11OfSaVre2o5Y14t3/lkDCTjQ1MW/RwB0cREgOoYlitbQRm7FGMaa0LYYJBTrCYFwpLJ1aDj6cA3cPD7jvZrrRtSsKw2UvhMSCKqzhlVFdSAZdzbWpDqPj1PM9Y6YdOet1rVE2tA5wfARE0sBJlXtQCYUWQ2TtE7jzVSPIg51wS/LCwa47wAaUoAZmcNKrEkl4vzqP6Ab4gxjp//heZ/+7/7+98/aMupZkp5Drx65iF49mfr8e/8W/8x/7d/+K9/9Pf/rf/m/4p//mc3aP03uLm9wWjNP/+zFz/oPJ87rDV0nb8AA6XVtrbex1l+qNTS8iz/XIXSlaqFM9V0cdyzINgKRMrvIlAqs1najeQlbZpM87y0e4lBjsbWNqFUMkZ5KViryhZTLCDEB9piCBNV197JAh8804WyrGnPHZfrb31HafupAIAprUxDpc4B77P3Ul+v1Lou1XOW1mp1Ec+gREY/B86KDnphm+WSIUTKE5OStQ3z/FA1aWdZ5873EqMNypy5QBr9/a3LZ2MnFyxMhgumOOpi3nwAhNU9w2jBWGJS7K92dH3HxnmRInAe42wFhlrRLjPPEyHMbDY9Xd/z+qtf4TvHNBxrW3ZCxYDKtbjXdPU4GxqlyNoQtOE4BH7966/55ps3TKNog4ksj9wva0xtba/PR0qchhO7bS/3qzrsGq0JCPigVF6Ws2fX4VKL2lHYOO25KqVgrcU5ewlE17+0mEjYsJVNqaXtu+s6Nl2HqRJE+6srNpue7W4nbYc5Y+ozYqrWnBRpKjhlJcZTWrph0NL5ocO5U3IrP6zg5297CJvxQxAMpGnkz3/xK07jxJ/8yR/z0vcVIZMXdJsNNy9fsL+6xrx+Q4qBgpW1ZDmjdo4tV2gFkXWMQ8zL+lNqhxhKjP62245hHjmdBt68ec8wBXZXNxwPB4bTSToYrF3mcGEFtlMS2aCngNJzcUE7yVxEpgWlqjRKy/+lfX2cJt7dPfLNd2958/Y9p2GsALnlfF9pJkwppuogXQjP4JTy3BYhAlTMpwFh+YcRwn63gTCthVEjDgQ1EWlC60XaGU0VbNdGLLL1WbXbOIfVhhQkYTPaoHtDThBnoTnKhCrkkGpwB6eDLE7Xt1vmWHh8e8RYzek418S0iesL26sA8xxrS4AkeEqppZqktMIoh+9WseySCsYLwqp0fbj15QZnqgB+SpoUKg35LHGbY5JKvzVMMzgHRRXevx/wxrLbCRvs5mVPnDLOKYrKKFewnaXrRXiuTFVo38gY+b7jYbiHKdG5Hdu+47PPrtheOWKC05gIp8gcam+7Xe9JyhlTFFr3bDeWlKWPnlo5M1pcKo3SuM5LpUqNdM7UVqdS23t6whRRRUCkRTZAyyI7z+Kw2HcWv3FMY+DwOOGcYb+XB6XrHMMwk5O0KIhgu62gpgSb3jtyLhweRzrvZZ4YW3XLCjnBHALjJEmq0lVQWsEURBOg68U9UvQTgNrGgxI3QqUkgNhsHeOYeLyfpEpppLLbOUPvxY0qJU1WijRHLBnfG2IMEAPbjcN8dsVwCrJwFNEsqnrEWKfZmY5+27O72QCKd1/dcfdwwprM7fUtCkVobcN1/jrnyBlyBcNCiIzTjLIapQspR653e6zRdA5SUsTkKHEgjqMAcUU+01or7b26ARegiOSYyUEYIdbb6lQnAXpIkRgyGsM8iBtaSYWcSm0tkiTOGENOtcXHmUUovAU3OQpgmGLG70zVrZK2AFJ7biQpFw0dYaHlAiWLg1+KEWsUrnfSgmQN1IqaNoZ5Tmy30gosSfOy82NMbTmyeqnYwwIVLFuArtXpmEE3tsMCk1aNCRQbbxmHQIgB20HfGW5f9uQIKMNEZlRU7QMB37WSde+QE/PxyBdfvOJ0SJAjd+9njLYMpxFjBCAxVlgQsQJyLZDqrSPHWMPWtiuWysq7BB5yzoTK/vO+zvdSixilrlHGgFYCwmthKKKlLa9oaQ/QCJOs6Q06K8/QOAtbs+SI0qVqFazC7Y2ZU84QyRYEtYCoJSpG1XbdVMNgXSVbLnC02lZ7lhwoYyowUV0Hlbzf1GJE0y0zxrDre66vr7l59Snd7or3b96Ss5IgqLW7Kc12d81uf4P3G3JRhJgu2sJUBVWtVvSbnq4XkfSUIiEGQkgMw8BU2+6dNaLHaAzTdKJpPjRzBtMC5JwXYBmk3cj34grKCWISBtL9wz2fvXxRn3tLTJJwNo2dNifamLc2o7oJApVJlFMVcKcKHF8m2i0olE9rn1e/p6zVxlIqyzCXi/d87FgZZ2eJZGvB1Vr2m3Yq5fJ9DWDT6kwP4+y6ljNXZ+1GsLAwVhe5CqrVMdKC7IJS9L6rIunlArSt0SZNf7GcRXta6co4Na0YK+BuTQxjTQ7PT1US0dZCJuuPiH6n5TPOx+v8UkOIhJRQpeD0OaivFzBSIfvpOEWpzMvCDlSNmxix3QZjLWHKcg/reKxjXu/Us8Dc80wxU10kG6iXcxKwSyEMNAVidW8B2U/OwRHvHFNlZnbe0XcOrZtDI+vUPnMF1FSnuYU1tAweBWnl0aqw7Qy2Jn2lgomqVF2U+h5r/ZOnaE3MW7L4MaaL1pqHhx/mmAXgXGSe/Qc/v7k5cX+/q58p+qNKCWPwY8e/+W/8f/gP/q//w2d/5/0D213PV19/A8Cnn36Cs46vv7n9wef69FAo0bI5mwflbJ5D1e+q60ITvb/4DKXovCVFWXufMvmWhaCIjpBsH6uxjVJiBGO0SA4Yo8VU4ym7S4nCVSricKmsFOG9d6hhlo6UM9dDkPVpaXtURfakM3Dq+Taqy2t77u/NDbJKJNepas5AsMv/09mYtiU+1bUpnWk/ScglwJ7SrTggrpVpMX2QcWzBqbRDi0tca/VqrL0P2DEKAQPVyoA9H+OVKSkutM8Z3QiQfbbun90fqtY0+XKSLA6hF8m6/F2rZjRWYfUCIYMzihxmcaxWmevrPV2/qSCrMBFFYkTG9/BwVwFZtXx2jAEbJpbV9eyZX9v/C6TINAW+/NVrfv7zL3n3/kE6bpTklZqCNQVjmit4VaZu6AeILpe1kgt5xzjNaxFG0q+LR2dhP9f7l7MjhLD+XKmL+SmO7ZVpia5ElFILvEq6XKhsJmvo+46sFP22p99sRNe0Pp9aG4xJQEEX6SJIVQOytfKJwZkmKyfrVhaihzVFWPM0F0Zp/8MoStEff6YqMLwy5kU65sNSxOp+PgVZB7p+g/c91jjpPKnriTOaq/2O3f6Ww8MdJSeMNiJtsXxtK7ZIoexcTFjGSsAq9XRhA3FrtAYovHn7jtdv3vKnf/RTrq6umcexPmOpPv8ryA5Vp5hVGuF8uj3ZBsXoBcnPc5JxEfMX6WBIVdM2l+pYejoxzfNSfHyuwNJY5XN4CjWu3ywxvDDFXDFLfGWsIvxGhp8cv9NAmOsM3axR2EotloHMGXGGCwljpQIfVRYwp2iUUeiaRDnnSWmS5NiLMJxSBe0yIWhiLAstzxgtVsWpkMbE+28eOd3PZDK+1wxjXG6lBFIr6yOn6sjQWhCUUIiNqhtSkclvrSZWPSqywnd2QVklQFsTN0Hbhf20iKzWHaqUukmcaY/MQdw/jDVVD8kynTKf/+09m9FyP448xhntRADeOs08n618qjAME7e3Gza9YwoG11X9LyuLaajMJq1FhDfnsm5kSvScYiyMTMzTgd1+w2bbQ0kMx5nNzuCKJcxC6UwxoIDt1ks7ltH13mlOp0k22CgBbslVX6huYCkm5goW7q8cIRRQonG1221QaI6PA+Mwsdn23N5usN5KIKOg801rSJOy5vg4CfvsFNlcaSEM6kjf7YRRowSACSFyOIrgdd8bXKdxncF2ir4zHO6CiPCrwmbb1556yNkQgyShuq96AV70m/re0BvhgKiUOB5O2GvH5mrHdJj5/5H3J7G2rVt+J/T7qlmstXZxzrnVKyLei3ARdjjIwk47AqxMjGgkdBIiUaZkgQQCkUgIWXQgG9CABhId3KKRDRqW6JKFAVspGZCMM5zGJmSHw3bamY6Xjvfufbc45d57FXPOr6IxxjfX2uece9+1W/nEfDr37bPPKmbxFWP8x3/8/94WXF8ZxsDuyrM/LNQMzgei9lnvth0OqZQ0B5AlZqyR8TKdTpTsGTYDp5MI0m+3HX3nmOfCNC28ebmnGoPrpD0QRIvPeYt3oolw3Ms47TqP65yUooqMkWEbdFGGmgX1XybLcopy3fcznfc8HI+yeTvDdIwc91FaLucEua4tr87BMPZ0WhWeTjMOuediC62AtJd5nZNoW4kTSWu3gUNMWN9hqJS0qNiwsOFsTExLIcWCtxU/DjhvqNbiNNnZ7w9cXV2zvd5JQDKJK6LoyTSxZ2ESSmuzhDWrYHMV7wvTTk6WiDXQq1WE/J23UqUZPHbw+BhJiCts1zlhK26ciNwfRbsraKA9Dh0pV5bDwth5fD/y/IvnfPf7H5Pjwovnd2yudxyPkb4zfPLRNb4EfHX4iurgqFNvrczqCCULkq4RtazVWnQdpKIgRRFWrJGVuplhVFMwRcCivuso2WrFL4uCmgJiKJAnrbUSKKVcsKYIk6RWipFrXjW9QH5fG3ulWcY3Or5dHSpbEcEZwLlV/LhVx0CKL9Y6HVdWneyU+l+rjCnEbdM7MSDxKuDvvWfoOnZXVzz56BN2t0+5e/2a0+EIiENjyZMwJbuezfaK3dU11nliKqQLcfxmmy5GAZZhECCsksmLACQpKrt41e4yF/tRYZ6OxKFfkz7nnehTXsRSjarfqUCtNZaUItM8Yd4YjseP2O22bMaOKUYZx/bt5FyByMvN2whLp6oEQQOuLgPKdt+NNZgqLXotAWrP6rL9BcOaiBbVd2u6Oi2QbG2Db7cZOuPWhLP9f2lGCfVCdP9iXAcvhbQpzhdJ6+U1n1+7thU1oGi9vxf3pRV69R9b0thIEa1lUZLI8hbb9gzQrYmgvmdlVVK13UE/pyqjyDlKOT2aFwlYogTI3jmRKnjrqFRtQ6l4e/7tWWxYPrDkJOuC9YC2r1W5hqTgr7NgvSdpK3nT62pJWAPY3gY3WzGlalK+Pk8tHFbUjfJRPGzaqekTMetNd8awLAtxXtY5Pww9m91GZB7Wc2j3XOUKzMVzre1hvgUc0tp2pcLtG5hqLb6KBmPOcX2X82EdUNYIX7TN/ybfcMm8uTxyzvxf/t3vv/sPX3M0EOwXvv+Kn3z6dP39L/3wC/7O7/wBAEqRLwohsyzvZx198PQNc+zfufZ2/Pqvf86f+TN/hr/9t/82r1+94s39j0hRBe3/GQ/vvbBSVb+yXhhZtKO55lpr8ZyF4OG8z+ZSKMZjebw+1FqUZdHY1w2A0vXYnIHtoe+IOiBjbvvJmfkCEIvqGbvAMIx0w7ACB1IgravG0HlfPV/LuRVfx9xbQPDba9ulZtZ5LaqaUMt+qlNBCp7lrHXmLsZoA8LO7svNdbletEO2eyZxvrF1XbtSk5uhCjuyZkpi7Zq5PNd2Teu9bjHRWwWSt+/B5d+9dkU0g4zLo3KZ1/D40JjF2ktjgXOnwaVJSmNIW9cExdHcS+QKcpyl8wArbdNloSQBXawRw6/KSK4wzRO1REIfiFHay6wWPau1WggU8zFj7WoIsLa8YghO7vVPP38h52iV7egqtSxa6JL11BhHNSrhoKw9Y4VZXkqR/d4e13yq7Q9G4zmJrQq1RGpJGreGNZ7y3mNtIaWsDHdP1wsDUsDPc34ovm+V4lTv2EDKkUwldL0AZNZhfXc2NxKkFWMay/rscChM36KYmaEmp2NMCm3GyxwtRUybjKAnqhdcKO+jHq3P3GGNzFNn0ELnu+tda83fH44cjidKadcyyrwqYGri6W5H/cEv8tlnn3O0AWykCwPL6QEIVMK6/33T8S4EptueM/gucH+/54svnvPj3/+UH/zi90Qrtg9g5D6ci3YX4FYRRhYqd1C1oNAULAyIbE6ta05pjSXVyFko4PGZ1SI4SGOPwjlCbGtFex2YC5bced6uYZKOG+eEHLGcquiNa7zys4oE7fi5BsK63tHNnlKcuJUNjm5wKyWyFAPFEE8Rdp6+15uYCniLN1Y2uHLBEPAwdB4/Qope2F25kpZeNo7iyUvicDyRYiKlRDc6ut5inBf3xqXohlKl9aotVgiYVoB5KXSnhWHTgUcdl6RSssyRbDPeWW0JC8yaiFdTtKWitR5UnO8EQdbqjMATVnvyz9ViAeIgeCNtAqhdeO+4NgNfng5kKrU4craEYKUlxgSmqfDiiwMY2B8iu2GA04lu45jzwpu7E7vUYRwMgxNmxSyTw4CInjuhLBsnLKLjcWbse7praUXM2eBCwHjP/njE1MrYD3hXobM4K+L4LnhOp0gInmmaZXHP512tFjEc2ISO65sN3hl8Zzg8HJlmWRyd88CMcXIfN5te323wnSUXcUSMCQGjPCzOyjMolWA8tSa8N8xLYtxVTjERguX6kx05C4us5IQV3I4+OFKS53j36gFw2FzYbHuurgaOx8j1zkMOqs0jzKhSK69fnYg58fTDLfNpYTlG6lXgsD9wfRUo2XLcT2xGz2Y34l4euHszkVJhWTKzumduth3dIAKI+4eJh/s9m23PfDqx3W0IndD0xVFQnCjjIq5gxlr86JmzCIObTtoJJUapFGMZuo6rG8vxlKnmRD+KOHtKhWHb0/WOftuBboBxLlw/G/EhAJZpn3jx03sRxAcJKLXX33tH5wxzqqRU2j4o43QISoeV6vo8zZJgObHq9TZiykwpiX7wwoyylvuHI1bn5LhxWO+lEpMbgKBOrqOlv+1xDkKQgCSmROh6AaBdYF4yplTiKXK8X5gOCzFK20/neqF7e8c4eKDIWEhnEObRocFUaT7rtSowJxpqHY6H+9eMXeBm1wtIq+5vrlNtkpyZjpJ0mSvLbqMGEgZ6H7QDYOZ0OAgzIVnSyZFT5brbEQgUJJB0VtcTjZ+XeSanqK1Mjw9rpMrpLivvtRUDMqW51a06FFLVK7VS1dhDWCmyduWS8EZaV4JrW5aBEghUip+Y4klc7LK2WXdd+1qyaleUqgEozd3GENSppzHABFyVRJmiyRHS3iaBtQYKK7gnZg9FixnGeg3EHD6E1SzEO48PgWHcsLm+pd/siIuwYXNqelaBWiPWWcZxx7jZ4pzXaruyWsR+T1t3ZND40GF9wDhDmrOap1SWZeZ0OkGB3nd03p51hqr6YNX8KCm0Rhi5j56ntatOmHMSUJZSmE4Tr1+/pus84xDYLr06Z77N0DEiWm3qWuluuZgx5kz0F6Rrvb+PsTR9z1vz5BGY5Z0CklIEacmvs48ZAblpXzRwRc9VCkfn38nck++8BMkAXb8g1khFwCpjG5inCcNb7IH3Het4MlDrBPXs7pdzIV22Vl/AMOizAxSMZQUTc84Uo/byGqS2hE2AQmEetfvamEtn/SBDHxxLzJzmTMqF4JSd3sAjw8qcbtdhmpBIbe3Pes8VyL8EkGg/XSS95YJBY7TiLwBXIa/xbBsE5+RM9Akrc8rr+azj5/FXrp9wfs1jwFb0cWAzSCtwSqI92nuHd4YmLmOMtF0Yd753Z31K37paHyXbLalorZA2VXoFl0stxLQoXCzxo/NBikOluWS1sVpVDsCtyfgj8EOB348/fnjPiPvm41f/6JfcXCf+3j/4CIDdbn7nzn3/+6/40Y8+fu/7/1f/87/AP/nxD7728//aX/sV/tyfO/Gv/jc+5uWLF7x584bf/3Gl1vBPfa7t8LrWytA02m57jntb61XrwGhz9LzGCFNvPsz4cUOo4gZ+fr9VADnRhJ5bPC8FszOjB4OIz2cBJjrvadCmMZY55xWTtQDWirmLERZ4NeBDICpQsAIw5jy/19ZsFOS2Z3b5ZeJ3+ft2H9oYaQycdkihzVC5cMOtRtltjmYQI+u3XdfZVsgopa7Jp0x5w7JIrlJyWYsjRouuxpxB3dbC2s5GnOMvDArKhUi9aQWBczbsnFsBu/P1yjqkOuBUbRlZv7O9X39+O2G+BNRWcE5PoCqY3c7RunavH99P0oK1VYHNBSjc39e1WOF0TR2GjPUd0/GepKL6DeC2zuI7jy3C6LK2MavBOEM1lmKsSPJYC6eZmydnIHtzu2F//0BOZv3cdh8NBad7nDGOrvOUKgDWvCxUlPF8Iahlrdw3kTFI1JyQFgSJS0DiZa/mSVnn3DzPa/y02Y4MfU/JmUVNAEAA7CmL7qt3MtZTTnR6zdImFynWkmMUg5icHo3xJjfgH2kmXuwX1uD6DpMeG1l9E2By3iPMqvsM0PUdpkTqoawxzWXY0z7xxYtX3Oy23N3f8d3v/2Dd83U0YWvGm4JzcLe/o5ZITsc2klbAt2m4PgqtLo5qVmz74hyaCY48k59+8ZxPP/uCL798wc0oOuLpsnB1ec9U0iOVvO7lxjSmfNG4RBm2FslRVI/Xe/+O3ASw3u+Hw5Fpjitw/PgpoblFJudIqZkxdGpamEgN2Feg3hqJlUzTNTV1vZRqv+ZmvXX8fANh3jFug4YOIoYfOtFIiUtiPs2kKA4W1jv6PtAPohsFGbxXQMxx240rQplSxkVD33thJBShbsZomWc4PpyoB1mkjIVCZl5UxFnbENohAbVQpUuulFjZbANd55iXgvFx3ZhzEd2jYdNdDBvAIE4jOVIqxHzZ+GoxSa1XW5mz7RFGBFUlEUxgjIqUy+tMcEwT/Pj3Iz/KM/MEXRBAoUZYQiGnzP5h5v5+4XCI3L+ZKbVyf7fwve/eMk2ZLnR88MGWLni++vLI2HuCrZxqYpkyJcM4Bqy34lSh1bfrzSDJxLwIq8gGanaQPeOwJcWFeVkIznF1tRMB7/sHHu4nwHDYi/1sLUZXHUlgY8zYICK3OWeurzeUolXYzq1VvGHoOJxOBO+JizjkDWNhULOFvhcr4Fl123ZXHf1gMbUwzwlvLZvtjn7omabIdidtlaZKu561lXlJzLMhBKkiLLmSsmV7dcv9w5FSDQ8PE3a3xdbCaUr4YImLLPDFVaY5kkpmu+tJc2a7c/irjhKl4vZwd2TcDDSSr7dC82/AaN95pmnidFrYboV6bGql6zyn08Jm3NH1W3KuDKMI8Btn1WlTAIwcxcEy5oItcPPBLZhzK5J1wkyJuWJVoNl7S8rCQry+3Qi7sYIpsLu+whhpxzXWscRKnBLz3ZH96wfmOUm1pdHrgZgTw2bAuUrnBB+SmoFo7OWSOR6OhD7Qj/26wbXAJRW5X0UX9tNp4nScSNby9Han8guRiwhJXVkC93cTx4cjz242HE8CFHrXKaBjSROkGjnEzOEuKjBrMa7DOWmFdNri3HeeeYl0nYCpKyPpYs3W9BSLbGa2gyvfUUym6wNX2w27a8/hcMfYVdgYXLDYCmMX8CZhSmU+SWtP3Q6AiK+aIAGzI7IZBvaHiSe3Vwx2y8PrxHee3jK4Tqo2VhKNBkCVUpliUtAtX5Rmzoe0AAkgGZzXzenseibV4xaYODW1kGCqBZgtsSuqfwZmbQuR2E2o3sYYejuQ3CQVRK36y//L2hdzc1CUtbgBO9KipTpSta5RhGzWrC1cayJiLrRB9HC1QirEIsBSE1gOCoJ5H7TVwNOHns24Y9xe4Xwgpcg8z2uVS+zMF65vrrm6vmUYRkotIhYK2iYn+4TVbMJ7jw+iwZSWKC7DSyanzDxPlJwJLuBtoAsFLx1zArIWYfRd7FayT5XHAZ20DfX0w0AInqEfcM6xzBNffvUc4wwff/IRHz7bMUfUrntSUNGfK4jk9f45b8UApIpG4KXelnznYyBM8Jq2t9VHc6X9uzCrJVgV4wezMirXFhqrQGg9JzhFGSAWbSnUa/YXzrnr9z46IU2IdZ0tCYxH9eGE0WTfGi+Pr+/SYROM9Y/mUtM8A4SF64swr3RNjrGSjRQFapUkWhyy5b6mlNYksc0niQcKOWZNGJyCUeJQJudVH91/24JdVAu1tGRIzi140Qk8i7nXRy28aAB9yVJriZ5RXcFaCikuyti9rEy/HcgqSN1ulJFWs5JF59Mpo4AqDMoGHl4eRZBcGmO03XKnzJGYE71zjKMwozdqhIIaJRi5CHKpGNQYpBRwjnSRh5NZiWG1it7KEiPzEpnmheIsnQ8i6L4UKvJMUlnETdAFTCmUlASEUWZd0zZbjRRKxbhzoi7pVeEP/cEXwK+8M/Yuj+9+9zmHQ88f/IOf8du//Ue5uxv5c/+zv8G/9T/91wCI8d32yl/6wUu+/PKGw2F4599KMfyl/8ef/Mbv/I/+I8uf/tMLH3zwAT/84Q+Z50++8fU/6whdEHBKM9GS8rlduO8xC7gKJpzbkWUINAdUmTeXOjssURi29cxIyimtCRqIzIoNnbT8lbKOtFjae87mLnJvCqt4mBGDg67rMNYzx8IUIzY4EpYuXACDF0P4EdOr6d2tzMkLLWE9nNF2/4v3yrospyIxT0Om5LvWtm0rrNe2H6/tv9ruL7IuBWMzGJEn6IKA5VnlRow19J38LuUiLzNS9BAmSdNyOwPbcN5nVzBPz83oBDwDevad82uvt00vpcocKsrmfhscb/vEoxb3i0O6JM8FiDWp1/gyUTHJ4N0ZDHmEq1QoKTOnzDRFipqJgXSd3F5fsdluyensvN6O5tpXaxFAzDvSaSbHqC22UsSLOVNL4bSf+Z2//Tvy7HvLaX+StcdoMc/K2Kq14kNgHAdyLczzwv5w4tmzp8wxklKm64I6V2bWpBKADDnKn/r4QtueVatIqCzLzBIXDIbN2LPZ9XTBsd1uqCWzf9izNObPW4FkilIobEBpfQSsfD3A4aylqsbwzxK/b3siFSl8ved4pMeoRYaKtPdlRP8vlyzAZNsAzHnazkta99LHpgGKAqm+mQD1hVwNTZXXoDUVI/Ho1/uWfv1RQXSXrejf7g9Hvnr+gttf/kV219cc7t5QjLjYnsc2awAgkgIWa0R7uF3L5XlcMk2tsVQj2s7VivPjamahoLToBzeW8eWf9fYpsAYlR6YSMbUTtrbG+MYYcB4bPM5YqIVckswtDUUyiW9z/FwDYc4attuREMSxMSMg1jwl0pKESRIzLsiGdJoWbAfjRrSajC7avnPEuRCXwnxaSFGSsi54tpuecewoOXJ3NzHPSQQIa6bzPTUkac9xsrmIGL/qBTgneked57SfWObM4eHEMonDw7AJzHMlxaiW5tBCP+cELNo/nKCKbW6wXtsJpM3IKD2+Zt3EqI9Q2Kq/E3e2uiYI2QmVOeVKMYEXX0ws08KyRAqV0Dk2G0Ea5ilxOix88dmBeRZWBQa2G8eXXzzw9HZknmeuNyMv7w7EWEhJWlOLCr73o+fqZiB0ThgltVJSwVgBxoyxuGI4He+pfcdyLOxudoQQOMUITtofMlCKJXSGwyGR5krXd8yL0ojxFw5gntB5XDBSZbGWvuvACivLdHK/p3nBFWld2l31lFr58vM7nn914M3dTIqVvvc8/bBjGDum48J+P/P0esM0zdzebLneBWxfmedIs3a2Bq6vRjabTlDspZCWQlkM1gauNjD2FRsCxYkWG9YxDJ7TcWGz66TtZhLR9ic3I9vrwGbbC7uieg73M3PMVJsYrza4XlhtKQmgG5dESpVx27PZDNL6tEw4I5bsMRZub3fUEjGm0HcdyzRxdb1ltx3IOXM4TqJDpeNlPs302xGowu6zkrQsy0LNmpRjcDaoVpLRgEqcEksuhN7iamLcDZQsbJ2aE/NpolTRAMOKIOr2esM4Bp2TorVnauX6eiutsRTVZJPxff30+pzgpoIJZm3tcnYhxcwwSCBwd3cQxpOKaHZdT0oLBg1IfCcAc80MvaM40SPsrfSiL7FweHUizglSYclgg12TQGeNAmbypwmSW2u4vh4VpLcscyLHfG5xaiuBkTTOW0uxwrb0eDrXEbJj6C3Pbj8AY3hVj3gjSe68RHUqlED7tMy8fHXPtCxsdj3XV4GlFq6uPMPQ8XA/8fzhxHeefMjVd0fVGkDZDtJG1Vh/oLGPJsNrgG7Xnf5iU7Sk3LY4oyy8BoTJYV0T6pRnkvJMmuc1yUtJAGGvguzVVLSfXNY9pRAN3Yb96Q5ogr1ZNUmkHbaxZ6iVooGNiBTLeY99WKtTxoheYGPPVUXGmkh1W1/Xa6BK24IyjwQEC2u1PrhAF3rGzZbr2yeM44aHuzuO+/0aqM3zxOGwZ7O7Yre74fb2lr6XFqNSCzHDFCuxCBKYUsJ1neqfOGIsLDmBshamk2g/NB0K0WyRc7bGQMnMxwPlasvYiztdTNKunWsbhZfPyTL0Yl1+Ok1Ya0kxcjydePHiFV3f8d3vfMwujJRcefH6Nad55tntEwGM8zlxaIO8uR9X8/VVTqN9O0afQdVn2Pa29mGX2Ii067JWJ9fE6eL/fe8pMa+tGaDyA7muTKp3zqWBom+P+WpEbsFa1SA9A28N8Drvx48BvnU8wdrqtv6bUedilBUlOt4EX6WthoJT8HhhoEcQzHmJkuQjVuLBVy6NDlrQiDGqPZa5FPhfnd0MDJ2IxAdl27ViYVbtsi54BfEu1zmjbLHzmlbfCnRXgE+TplwEZKil4EK3mitYDNiiyXp778Uzufi70XWrmfOgumqCoSotm7ZsVWWZnc/JqyNu0fWmnZ9pYMaj9wNYZXa4M5Dw9tGYYVSWuHA87tkfHrh7uJM1EUOHW9ObM1hh8T7oc4+kZRYWdhG36XbWMUZceIuNUhLTMfKP//H7WVuXx//kf/yXefbsBb/113+N3/7tP8rzF1d8+ulm/ff/z998F0j7jV//KQ/7nr/5t/7AO//26eef8A//8fe+8Tv/33/17/C7f/cv4L1jHDf8zt/9t3/meX7dsRnfaLFaxnNJCXEhvGBGOU9JTZZE5qGAmDI6Wgty07SrVrRrWxwRl7juKZesxZyNOLYaAbicNSs7E3Pu2Hh0XIBhznq6bsRYz+F0ZM5F9s8mcMQZ+Hm72ATnufM26+vRzxdtkWJcYzDVkKPqjq5J7Tn2WAFrncON3XEJtFXdI6yTToGCtnIj27O1YL06sD9K/qXwaaiiw1gK1WZqLvgwSDPVxcsv2yRBwb/61jW+/XNtKHRdE2oZE+3ZPV7bV9AN+27bvAIVVlVay9v965yBr6xGDG8/8nZY1YosVfbgvvMMfUewFZOm9Rob86aNR4whFyjzQjpkBZgWDkcp5MaYOM4Ld3ciru9D4OmHT7l/eAMYhmHggyc3xJi4utrSdx05Z0IXVPdYzLW64CVXrLKet3GsAwTRBSrYWmTPNo/X4vbohB3oGPqO0+nIPC185+MP1UG7kpYjsKMLHcFblqWN0Yt4YwX5FSitVXOaWdf8x+P+8mfR58ur9AWmxXH1nRNuTocgQybXxvi9ZEhfxrRGX5pXk7fTNEn7veLJ4oQrRAjpoii8fHPHvJzXlHZTc8m8evmaH//kc4Y+sN2M1FpZpsPFWcpeddnd9f7jPYuEHs0xPsXIi+cv+ewnn/O973zCk00n+q7Vija3Mxda5ud5kOKiaJxbi2RtnDY3yKo5gdQbLdla0rxQLfiuxTZnHMJe3E8pClqWlhvo/U55kbjIwrLMGOnLXbtFUkpMMzhv6EfL1TCuMUMpRY27fvbxcw2ELSlzczuw2VhKNby5n5imWbWlxOoVIyhnKgmPI9cEBH1YysWqlarB3TRF5mmR6uJOWhO9NxSrwul5pusDh+PEkhZJwIOg1bvtBozFek9QkfHQe9KyEJ2hdoYPPt5dBNBI4O2lWqJrLiKcjGpzwOv7SV00Ale7jmQKSy5QLcYFahX3O9Bq2HuyClmDJYgaOsfYezCOYjwxg994jqeFNEdx71scm41nczWA8Xg/MU2JloceTpng4XSK/JFf/Zjf+d3PePZ0q5uekeSZ8wJVEMr3EJqujcN7w+l44p/86HPAs91IK2boOqlYY7i52eFN5f7NSbTNMvzoRy/45JMbrJd2reubHafTTPABF5B2PnU122y9AhKwuR6Zjgtf/vQNH3x0g3eOjz94gvUQbGA6JZYl8/qFtBWWpaxtYRRL33n6wdP1nmXJDCbw1fPXPH3yMUYF8FPJpJQxem6tOjXNkWCEwu+sY1nu6PqOcdPx5v64JoZd54COJ8+umU6R1y9fssTE5ioQgoCtKRme3HSkRUTraylMc8R70TUqCF382bMNuRhNbKS6MlFJybC72YDNXD3ZkqZELpUwdhSSBHA4htFjLJymxOHhRPAjm64npkhNlW7bEQiqa1K56gNLlqrX4bhwOs6AiIfnWDE1E4IjF8ucK2MunB4mQh8k0S2V0HWELpHSQq2GZUlsdz1Pb284HSaWmNhtB66uRcB3XkRbjKoMTWNIKRGnSJyVdt21yo8lzpkXB2kZ8cGyu+mFPg8shwN+7Kh4ci5siiVgiMmwdQPj2DEvmV+8vuWrVwfKaaFD2gCXHPGmsiznADx4x/W2E8dTqiSKQSqpJWaCEVvozlhqL2zQlDIxXohkGnBYQpFJ5LyhR5hovfN87/sf8vlPXzAOjhot8yGxfzixGXt66xl8Ty2OWjLpmFgsxGB58lTaPOclSxK7KWw2gT4Emhvi5cavOIRoVakt/Vo9dxLcrmtNS+aESwK6zpbmyqaJrXVeAmkMyzytmx9ogp6FIdF13QostYUzl0WZdAZr/Ko7B5rkKLMsa2L06KjKIFGjivN5y1kbIyLgq9kCF1VyYx4lyatuigINjf3XAqg+9Az9yLjZsL2+phsGjqcDh4d7Jm2vb9/x7KMPubq5YRy3uNArUAFLqsxJAAq5P27VQOo7seHOVRN165mOD7x88YLTNFGrw1hHjAu1pJXNJQWVpCzkWZhbWYwkUmLV8VjHoFMXp2HEu3uWUvDW8nA88urHb6gGNpuRJ7eb1RSggTKm99r+w3rfwKgcgHmMDLF+7eOfJUNDeF6GxtCSX58Tm1KbgzQ67hQQsRegWmMTBIcpUs2/BGbeF082EKl9KhffUKpKEpgLhlebA/byAi6r6qjWDlArSzmyNTsF0OTfrZOE09XW2AOlGualkpdZ2IiI9s76DVXWkWURMN+7RLOyd60QVioxia5GKSqGXIqCT6yBsMEI28udXTzdRWtIrWpNr0rbZ8aXporWrmYf7d7mnFWQ/KzfJ22ReZ2nOS74/jI0FTDAafuJaOWdK+/vIFDvTUTPQFZL9hswAqJnGYJXgMTifa8tYSd5bO+MUYsLHn/hpvq1IbcsUxR1bk5LgooyMwBv4K0cp+sGAZsvWn/auGti0DIeVOS45HX9Aoix8Bf+z//c153RehyOgWfP4Ld+658H4Cef3vC7f//Db3xP5x3bzfsr7f/Jf/YD3juBAGsTpXg+/fQKw2t2Vzu6rufTTy/PsyXE304z7Nf/+F9mGDpq1rhlbY29WPP1+VyCYA0ofttM0BRp9aoI8BWXi9Z/oxxtUyWvaONpTcovgRhlKOXHD3bdUY0jhJF+2EhRMoNwmHRtKw18/fprb/Pp6w5TqxQftYBgjTg3OqOAX3VQhQGclDnRijdru/KFHhYIO2M+RS3Cq15mbQUriNWQSitMmEctau3aG+QmtTKHQJJZOkJqknVdvz+tsgFnsKq1qX/9hT8GpRsAIteTMZoHvR9dfPvvKk2hh0XcJI2aksjSJPFKwaweCwYUNGjrvoyPWqHzEkOMg2jb5lI4TjO1FB4OR2JKpJR58eo1p2UhLYnnL19BhZevXvPq9R3ztPDk9pouBD7//Cu89zx99ox+GNnttnzwwQcY90vcXu+4eXKrBY2O7W5DFwQIm+Z5ZeDv93u++vIFMSUBykrmKHQcAcAu3CplnAjYcwlIGSOsr67vudqMlJQgbnl2fSUAJkr6sAGTCy5oofY0kVvHjgrpYx1d3wnIoqz4OB2lsyeLscs49mzGAW+FzZxSEnatdla1QoyM6UpeFrLqmErBQwHwi73EYFYGWIyRXAQIdtar83NlyWkdg0tcmBfRGG/yPAbY7baiJz0tLDFymiKn08R/9Nf+qs5DASJD8EyHB16/fE4pibHvuLt78/Vj+5/x8F6Mv0Lnef7iJZ/99At+8ulPCT/8PuPVU+x8UIY+yjA/tzCDrKclR5rZjzPKrH4ECAujzSCtsyVnMRRr2rQa23t7QQxYC+gtZzizL5trdSlZSA3YVU7l8pCitsEY1VSVqine1LNM2c+6P/9st/W/GEdLmkTHRaqQJWVyTNRqZJE2FuOthswSuPkg4qC+ZoLz0sIXF5ZYWFJijkmCoTmyP850faMEGzabjuPDXr4fcXGrCYqHzTByfT0yxcjxFPEOtqPj9VQJnWfYdmtF1WhgJE4LEjAv87ltcD4l5pP0MYfeyUQ8Fb56cSSlzM3TLc4ZOk0CQ4C4aM+t6qO0gWytoRYRbw59s4X2a4KJS5RcCcPAm+d7rDFsb0YRedTG464P9HOiqsZBiz/3DzM//fwNy1L58qsDJUuCZryhdJVaowSX7izQbqg4C8Mw8ubVHZ989yl3d0fR60IDaNUX2u9nlmVh7Dpurq447F/zycc3zLO0InkD223HJ9+5lUlTxYXseJrAQIwV50SUcp6kPfTph1dYYzgcZ7xzeOu4v5+oBeY5s7+fSU0s0UAIhnHrKCWzGTeMQ8dxf+BhLwj/Z1+8ZLfdaCWv0HWid6ZvFzBt7FiKiMIeUyTOlRhPTNMs7oDOYYxjv1+I88zLFw8Kfjp2Vxuudz2bIUjLERVjmgZSBSMmDlTYXm8Yhg3H4wPTFOk6x9XVRjeHxOGY6LqFq9srukEAn854nn91TxccPhiWmMRVLhumWVpGc654X7A+0KUiCfOU2ex6htGQGNhPM8Y5pmUWcUiTCKMg/6kU8mKwXUAsCLTyYC0lFg77hYc70Z2yRhbLnCXVneZEinuoAr7EnJnmRbRWcgIr4Fc/9hxPR/Zv9qSYCF1gs9sQQiBNR0yp3N5seXiYpOrvLMEGae00VVycEGbC1vVsncNWw82248n1htvNyGlJPBwjV1cd251nnhOTMkhtKrii7WVVtAafXA9st9Lq3AW3btQC2BWGIdB1npwKx2kRfbuYOR4XYXZY0RlxumFbC5shsHED+YXhq/6OSuV4OrHbXjMtme24wxnL/UmqZ09uNLCZDNt+4Oluh7HL6s60vXUQI2/SHcUaBhNALZil0i4AS8qZOUp1XBJgBxaK1fXVyJoo4/5SLNqs/2c0IZe1SUSLY5xJacFa0WjTQrYGRm7VxGjAVEsALn/u+55SPdZpS6UmE6Wew+/LBL4UaZc0zl0AbHKklJg1SKy1invoxTm0vWdtaeWsHyb23/Jz3/X0fU/XB4bNyDAMxCjg9t2rV5ScxSBgGNjdXrO92hG6wDBssM6SSmWOhXgmIeh3ix6W78LqMHUWknIcTxN39/fM88Kw2RGMIZeIvdROqAKAlRTx2w3zLFpAPnSyDl/kkaYWAbG9uBsd9lve3N0BkqikJFXNL6+v6bprttstt9c3eBdUF07W+8sqa62cbb51/7sMcsylFspbIISpbaydf7+2xxgRFZfnVNbXlFpXUGYVrG/JlTuz/Boj4BHLgre+r64QG8aK63NJWVsiH59rm+umJUz1rCFmlfkhvxNpgEfjsOlvNZBJEzprLdV13N/d4b0jNuDKNMD64twvnndWrZ2irarnollLFCPJClDmnDACUirEmNTwwajYu7LCirieDb0A+us1v5UcXd6LdqztkWvbprZeapKTFCQVgweQQpEwbEMVAL+BGW9X+d/XPNJEp99+NktM9AqKOU0ERHfE4Vwv+V+1GGR/luRPQMPOC+vc+p8N2tRSpSCqhavOBzbDSNcFcSZOmTRHmrOh70Zae117/q0lR8asJGXG+vW6Um3r79safV9/HA8dy+L58U+kPXFZPP/+X/znv/E9/8d/50/y/MXuvf/2H/6/fuNr3xdCZZ5hv/8X+OQ73+Ff/lf+Fb773T/O//0vPf6s66uJ+4fN13zK42O7OzAER+c8S1qIaRHw0Ch4KKi+JHmNKa7tvdZC49blrCZFubGR1RFScYyUku4HMmatArmlFGGwZ3C2FzYMrI7K3tmLeSxGLt73VDcwbG7ZbG+oxpBVz9RezNf2/ysb5YwinXH1R3PdPHpvg3oaw9tK9X89rBV4PZbEtETRrtK963JPbHIDDSDLOVOXhDGyNxrr1yLN2vpuLcZKBwhFmOCYywvQizDyLJaU6d27a307von59vZr5HVOvpjWsqpg1AqISo4I5hHwt2pBVslTTD0Dje3sVwb4W0Ucec85sR+3G5Z5IU3zureknLWtfU+MAkbdP+w5HSfePOxZ5oX7/YGXL18h62Dml/7AD3nx/AWlJj54+ozvf+/73N4+4enTJ2w3Anw9e/YBPni+//3vMWy23N+95ub2qYRuzjGfJpwxxFn+X9ylBahYloUvvvgS4xyH/X4FH733bDYj8+n4CAQ7jx97BmONoes7rq92OGf55KNbOu+I6RlRWy1FB1EcJafpsILVIXhqLYw+sNuGVauzjaW4LOxzpvdy3kljP+8spQvg7Ho9jbnZYjdp3/VSfIXVYKa2ByoP7h0A1ClCvsTlUTE0pvRoDHe+Y+gGpuOyjkvvAle7DbIOy/nc7kY+++zHHI/71VWzamu2FDQD280gjvDfau1uC8DlXy//8u6rvROJEzdseLjb8/lnX/L0yS3DB1cE7yhA0theDDBWOrMWx0SmyDhLpsUSScEqYVw2AwdjDD54egYtJtQ1jnLOETpH3znRYa+oeZ/MuTZGljjhPGt8VnIheGkHvjTGyVm6poJ15/gnZil+flMl4eL4uQfCDseZlKo4EZ4icRK2iohYSgVUXO3AuIoLKgZcJ+Ji1VlLgamioo4qNN/wTkMVPakHqWZWKj4YYThbqdJaa4k5c5hlYHSdI+fCmzcnnYzigGeDI+BYpsRxv7C9luBXqNuKhqu2RVDtlzgVssvUqeK8MDKef/mGcew5HSP9EFYx1VZprQVSlPagENTZKFicC6vbmFS5lY7tLZvrwNNPCvNx1iTEYq2g4cO4EE+RuWlxwDoPP//JPd3Q0XWFvg90fcCPls2uJ6asbm2FlBO+iFaSKYXTwwMhBHKatXJuSanQG9m4lmUmLpFlThxfH3j9/J7Q9SxLxtlK5y0pR2KM3L1+oB8CLlgO+1lEJp3huD9xuC9cX28Yr3p85wg2cHiz8PrNAaoE16eDBKElnqmr3ju6IdCp3o+YLcyMm44QRkJn+ezTOw77I3dD4uZ2ZNw4+sFgnWpE5KrtogVTLfNxIuWMqYb9w8zH37vhcJRWFkqhHyw5OW5uery6Fg6bXnQWqFxtR+7v9wzdOfGQVpdKMeLY9/BwJC4L49iRS+V0mOiDx15tKbXSecdpf+D29obaj7x4+ZKrqw0myDXjCtlBNgJYOR9wHqaTbGQxLdxuKsyFWCOTixgvAXtQsHW7GTAb6LcDvvfKAHKkLEEiVN7cLzhj8aZiihVAOQv4UfugjJXI/iHRzOxq02JykkC54Bi6XnU+Msu0rJXEru+oZOaYwVeunw4sc2b3ROyL37w44XtJbHY3wxrTbOwNJls+3m24GdREwWhh3ztcyNzebqQdgMISM9NxoWRpy+6CZTotUArb0XE1dlRgGIK0gRbwXlooh77DWAl4dlcDlMrDfpaNSNuf+07o1TElAbVzprhItYHjfeHHnx7wYWSYPB+OO27KwGYY+MM/9HhvWHLi7nTk7jhxTDPeCkOGCktMTHOk7z2RmSf9jrgkYk6rzorreozrmONxrbi7EDDKWLjULZCUXvSW3j6sFR2NUgrBB4LvyBXmSQTjm4YLbcP0AYwhZmmdkoDlUifiLA6cUqILRkRjW8VvFRY16zrejhYkFa2IgjJbNLlorK+s612rKFck8LPGrdfonNM2Rt75fO894zjS9x3Uyulw4O7VK+ZpXu/j1e0N/Tis2mXeOXKBaak087DVGMUahs4zdJ6xDxIAKustxoVlnpmmkxgqhI5aZhKTgPGqhaFLN0uM5JTxPqyJXhc6kgIE53ZYCWyC9+w2G26urzgcHjiUzGbTS+tccLx89YZx+wpjDDfX19RamE7p4jnZlYVjGhp0ec/M+nVi7HLBMnp0mPcHOA1gcyqyXt8CXnLKkDgH2VbahB61QWDJNb/zvZffV7UFZi111HOw1oK9NSEr8nqrTrFmFVBXoE9BNWsczpxZeO2c5UMtpiX2CEhcjcNvb9RZSg7pwGvsAzliEua2bXplyDzsgnLrTNMmlf0vqaNhrVZjIXkoOSdqlRbAqo1CKZ9FdNtXi1U8ayzSQEC9ovN9tm5tI23XagzEOsvpt2QFadeQ2LaQSsVb0a9sjprvSBWu+UBr3XDa6mPWKvPlPS6qFyYgqqXrBpYY8aEnxYT3gdD1WOspWeaGtZXBenwFV0QmgEdP7/FRVQNmWUQ/su/EPMUqC893jo3frMLgoetJVZxuMYY+BNEyTQnn/JqoWWcffWm7Z18jd/TOYcl8+dk3M8DePv7lP/2f8+/9xf/Sz3jVY7YAwB/6A/9X/t4/+E1O0y/xp/7Uv8Z/7c/8C/wv/pffffQaYyLH07cXzr/e7R+x+0QLNskcNJWaosbGRlt2DcbIOuqcMB5BHcKNYZombCdMlMs2aOuEmSJxXCUb2VdLrfQ+SFKekujhGC3oapIrwHMF48ANVDcS+oHtVtg5h+m4tmY670WbFbOO0/eBQG2daW1Jj+aRvs439oaOM2sNqBNyyxdkrSqUmqXd3jo6FwB/BuBg/Q7ZW1EKgGgVmpJXQLudX11xO0PSOZrLY4i6UlXM2zCYx/tnO5ro+rvgwONPEhzgAgDWdao9wvdjC1IYOrcjn1d1Yae+y7Y7YydZYlrrVzb8Y/0nOR72J+7v7pmmheMk5kkn1etdloVlmZmXhHeBECzPX7zi9ukH/JHvfg9rHR8+veXZsw95crsjdD23t9fcXF8xDD0hdBKHXRR0QhBdr81u82gPO8cn13r+IhnR5UyfEsV7HpaFLz//kl/8he9wd/cgoExO0onzloti+2znnBYZZF3cHw9cX23XwoJzHUPfscTI4SjFaGMMJUWidbggZIxmXvP05oYnt1d89sVzBUcKp+ORPnj63QbvLdZ2lFpXU6V2PdLKq8zQyxZE0/7zNSDr28+4FdXs2WymlEzKRhi4+kmlFGGNZdVTc0XXdWkzvb7esZz2jKGn1kxcFoL3UvTISUvFRoF2MRZwncOYcBHjWHXpvDQskH2tFbfO1yoFJXuxJ6/XWAUI67xnfzzx5RfPub2+5he//10+uB5FeqgIttC+I2e57pargACDHd0aZ7RYW2+cnrdqjFrRbBcjNIm3vPPYraPvOvrOk6Jct8mQaiGXSDWV0zwzdIbDw3Khe2jIc3pcpG1j31qckfFggTolijf//yGWP0+ZtESWKEliytpyYwVx7AZHGIXaHzYea6uKBNe1JUXaWry4GlqL8x5spkRpE5mXyOHoWGZxopqiJKehU50NnVzWGap1FAy5QpzVmcqoFoqWZ5qrBRQ2W3EYi7GIA5HyavsuiKsbKLuhsuk6SsrsTwsxJdXgqPhimPYzNoueh1P7WI8jeEOiUJ3BeqdsDC9WtMaQU6azMxlP1oE2Xm3ESSIlqQiXKiKGFlxwlAlQYC+Vqna9Us1fFnFNtFaAuaSaAW0DTalQggTZ85LENS1nrIPdVoKPeclYU1km6X3vgqPvPLVYhnFkmbMkzd5x2h+ptTI3cwELPnvRVkEYgt77NSCIp0hNBR8cp30iRieV50k0vIwKnhoLPjg1XgBMZjN6Con7Nwe6zjGMHW/ezHSDZ3qz8MF1pwKhauXtgFKIcxWHRwNdZ0lJRET7PrDdyAJRMsQ4Y53h6rpn6Lww+ILYGNeccEGE5nPOXF+NUiEPjhILJkgi04We02nCBxH5z0kEYGMsdIFVWJsKQ+948fwV05yl7cPCslS6UFb2QauaiCBwJpdKP4wcXx84HU8cjpFh8IxXjr53dGMPObHUyt3rB8DwNDi6nQR3wVemY+RwisQZ9vcHxmGgZqkyHo8njKl8/PE10yRU5xRFWJiKCI8PHXE+sCyJpSx88PQJuMoyRV6/eE3Xdzjv6Lc9YQwY54jTwjIt9NtehI8dzMfI7hc9P/3inn7wzEdxcE0x88Xda/7odz/heuglwEZAsFhVbN1JRUJNVXDeEEaHqY46ytivu4EQHFfbkc3Yn4Hyw4TvBJjuQhB9AgNv7o5sN9KWOE0LoTPchAFMVa0DYSB12s7njGXsxdji9oc7uuCxFUrMKs7ulHllGPuBm6stGcOr04Hnx1eUnCju3FbVItcpTrjioZpWQGUYd9gwcjwdaM41BmUlvKNbUDFai74ED6yyO1YASoUts7ZQt2QVIKdEs3O2zmtOZbGmrt/3Pn0UEJC1GvdIp+N9IdCaOCBzqvOdMJhKQaSF89rydGavGGUCVXJNWBvUAcq+87kAMYng8rMPnpFz5ssvv2T/cKALPcOwEcD4asd2d4XXFokQOtGDyGaN3ksRAKBV9QatHvZ9UN2a8z159fI5b16/ousCV1dPeLN/RSlxBflKKWsSbYyYNsSY8a4j51lBkHNwud4/rSK74HEhaHBThVHr5HnPceGf/PifcDrcc7XbYa3TNgwFJWX2vDdhkMDzbfDp3eObKnwtAX2fFkh7NsbIUK9UapLvrGsy9O2YNG+fQ2PpXIKGDTkXMWjR9xC2oFlZHy3ZPp6ObDbjxdgx7YO16np2Lau09k9BfwqG4CtzlK9Ug9lHR2MuOk2GG+jTWLExZSiWYmQ9iAVSzgxdY6iYhk9ircMbKdhFBdHneaHT1puV/WKNaoZdXI8+A6sOqs4r4FErcRFgWAocRsG/M6AGRuZ/vWgFNfViHbhIaBRtbPpdwlo5P7VSRO8yN9arPgtjDF030G2uGIYNMS6cDnuurq9FT1AZAbWqfhuadCgk/vUjE03SJHEBg7dioHFuP3/sAOj9wJSEgWsA5/2qTtQMONpzfN/3/gf/t1/8hrM5H0O/8NVzAcKGITJNDYQ6swHePv713/w7/PF/8T/lf/2/+e98q+/QO8DN7Z9ns/k1jsdf4f/w5/8H/NZf/3v87u++Bs7nau1EStff+lNvbw5yLxpke5n8FnlOAcNU1cHcsJoAgSRxYqwhR2PGDoMaAeia4Y1f94N5XqRlrRQGdassyjCjqjlL2zOQ+L+YgA8brAuSn4SOrhuoRmK3om3GjQUpzBcxfHjnTq4IWTtF82g/NMYQLsaFQUCxBhi1ZcZoodMYQ696dI0J5XStPn/CmQ297gu17cNJRfMd5u1eU873+VLEusWXbe3sOtlPqGdWbvuuyzW5ajHMILnco+8AHo9Z0Zmt6//emqOatJ+dk426dCqFrUpOVstjDcW3ngYNgHgbfDgdZd/9/IsXfPr5C+73oiXVGLXGSJtxCA5nC6Eb+GN/7Ffx1vHsgyeM48h2t+H66oYPnj3h6vqKrutkLdJC5Mq+8X6VBrkEMC9unF7z+ffOiyS7yZm4JL787HPG7YZPP/0SMbJy7HY7Ipb9w4HgdA0uAug7Z+mDl9bFnMVsxlmWOTJNM33w63mUUhi6jqqisaUUSpxxeu6tSOGdtETmcmZ1lVIo7hyH9Z12QXmZk1JgWJhmkU5pbOXLfbDtvbltot/iaPexFCEA5HIh0l4lBt90A4PvqFcVrGWeZ652Wz768CPuH+4YB5GiGLcKTFaJIzdbKXqUVHDGC4HhmLHHKKY573t2XzP8ainkWjBWzunrID9vrbZ5WqZp4sWLl3z26ec8vb3hww+uYW5FNblJ5/ZIjZuqSIpkl7Ut+ryHthixffcj9rJ2ufnOs9tuWeaFPghAmmIhxoyzhc7DOASKgS9fJmWEiWOtbEc9mKwx2yXoZta1zFkvzhBBg4evMUB45958q1f9F/TIS+V0SsQmdpnlJvne0Y+B7dXAdtdjHOJi0NgEUZgvy9JabDKr/oKzDIMnGtGi2B8TSzzSdx2bvmezC+SlJecXi5C6kciYrRhbyVEWBOct46bDlQ7fdZSYCENPSSdhs0URdQ5e6PYYgx9agiHPM0Zp2cyuMG4DcS5kdUs0xkIwFIOyBiSItEbaZ0yvSKmKX+cUiUvE2cRsBDU1roLx+OCwpsclWWCkvagIm0dUHoXmGkUsURIhu4qiS84qgzS39iNdPLzXCQbiTDJFjDfc3mzWTVjYPJkUC0MvNO39JOyE48OB0yRuFOc2TwPZcPPBlvu7A7Uu4iJpIHSGza5n3AxQM8u8yL3KZQXt0rKwpCoAme6hw9jR9UE1TStBTRU2Q89xP1FK5eFhYrfr2T8shJA5nUS7qu89x8NEGCQ5zLmCqaQlEYKjG9U5URHyvEDN0vYx9EILPt7Pguw7GT/GZHamAyMmDF3wzLOnZNjuOnyn7RGmcH21xXmPM5WHKtphJVfMYDgtM/PdA9/77kfcPUzcvTxyPIkteDNvyEuvCekszzwmlikCkvykHHny7CkpLnQBYVlqoiEP31GNJQwdaKUxzpG4CPic5szYbzAlc3O9xRiPxfLm7oF5iQyd5zQt9F1gswmk5HEHYaOBsByD75jnqO2zVdohYqIfenzw2sbj8DruvXV0Xbe2S3hnSM5z2O/ZjEHb56DmyrNxyy/ffMDN2D+yFzc6uatqTASvbTwVchV3JusEfHXGMozS8tL3AR/cmoTmXiyqnbpyphKJKeF9UkMA6XfvOwkwuuBl47eWnGTT6bz8ToI4dENAxpUV951SDbGsjwRjHZsQ6PueD3ZXHOKeQ5pxg2XrN/S+k2AuG5aSiDiJdI3S2JdZQDkrlSNjnDLi3tqkq6FZqZdWfdZ7Y60haUARc6LzHdWIzkhGQE+TVexYAS/vi/SyV1m7Ljf4tvbWWuX56voRi0ccCuvKaqnlHFy71g7ZkD7dQBtDxlqLKWZ97QoCqVPWKqhqm57EeRsNPtD1HV3Xsdvt+OCDD6i18vr1aw77B9Cqnw+Bfhjo+oFxsyXnjPOVWgwpo5oZ5+sMToCFzdCx2Qyii1OyCIxXSbJfv3rBm9cv5LqDodYopjDm7F64st+swzqZa9MU8S4grqJQycKULgrCmsYksnRdz9V2w1cX7Qg69KRwkhN39w9QK1dXO54+fYr3gbuHA/eHo5g1O7eyFC6f5dvH+nhoCdB53bw8DJf6VMKosd5RtQ1ZPl//NDYYj12izmmZVDMrPG7VfM/5vf1v9hIQxVwwwc6J6uMLlNd579SB+v3fsbqZGdU1NZXqpPhmDPTB0bFgqMIieksTr9SKN+2+PQal2mENCkRLW3Fz0DtfT/vveRx5J0FqXKKwES6iyVIqxVSy0bYo/V3l3IrUPrEaIy25xuJK0wo7t5TC2aGy/V0KgeURGJa1LSM4mZOSLLm1mFgra1tcUQdIa+wZyDYis9E01eIijq4hnEGQBoidq+6t7fWbj4oII8dFKtquD/q572v/NdjQscQLgXJNep0XSYsuBP1/f5F8rGk5/+5/8Es/44zkGPrIl189BeBP/os/5q/9x00A//0g2Pe/d48zmR/+4M3P+OR378iyLHznk/+U3/vRr/DwMPBX/sq/9K3O8ZuOTz58iTG3sgdePIiWZPahV8CZNZFGf86liAi5tuBba1iWha4T2YmYBDDtg9zZtUXKGIK1a3yQ1ZzDqYLhcZHCXfAeb4MUTFyHsWFNLPu+xwfH4XTgOM2rvpkL57VMxv/jhL4dDSDIypAH1msspTCq6+QKoOtiWrUgYhURM5h1jtQor7EtwaS1goqRzeXnt8KFpVJyhGJxrkmgRCCsel4GI2utguqKMGl4YXRfjxfx/89IXo0R4fXL+wHYmpFt+2IdVmBvBd8uxkB7f63terSA1yZS04Czbi1qXJyEtvBZBYZO9Jvt+tza0XUd19dX+K9ei+TIkhTok2cgsYvnw4+e8St/5A/w0UfPGLoeHzquthuGcaTvR4ZxICiBoXX9nIkcZ3mHd5hARQx0qBWcpyDryDLPAsCWwul44NWLryQuNobD4UgIlhBGhs3AVanMxyO5JMbtTnKx0xve3O/PRRprpMW7Fq53O+73B8ZB1ikBr0SXLIZzW2DKlTzNxCLOisEH7h727A8HptOJlJK0L6tzaS7CWgzetrCNXKR1f14iMYnG7hwzsVSR9WkAqJF4xxhLNY+rRcJgrKxCnBeDqjkut6LU+k8XIFHbz6y1dFtPioXDw55aYBw3Unyyhmk+re9dYsTUVkKRcWpriz/MxXe8J264OO+m1daYxLUWigFTH+thNvBu6DvY7cg5M8+Ru/s9x9OEtberxnTV8WnMWf6jAWExLuScGMfNeeLpFzUwuMVXcG5xdQR2my1D15NTZrsZ6buO2Wecyq6kKHNj6ANj76k4anYkIwzfxrwMphCrV02+eo4JspA/jBciiDMGF94PzL99/FwDYSkVlpRZ1HHNUul6EYTzncMFCzoIaxGxtRQrtRqscVoZhpzE4nN/d2JZlOGgSeRcoKZKPE1MLlKiopNSZ8GqkKxV4CfGRW2DWVkPtvoVpbbG4MeOZc7i2pgry1wJwXA8TtjNyO1uQz/2mOAoOXM8zVQDtnOMQRgIPhh181b6rzIGrP5cW2UWda4LbbJW4jLpJldYogEymEi1HmOl3Sb0HbWKFlRJGR9EIySXIppIOlGcswy9MFxiE+40Uv3PWexzrbX0wygAi4NEZFoWTqeZ693IsmRSEXODcfCEXnSqpLVJxDwPx5nDw4wPjnEIdJueLTtscBwfTuzfzJwOiX47CJOst3LO1uKcIc7CMCm5sMRINwRyzOxjltaKKpq1XefZXQ1stoHQW3IuLFPkcJgxpqPrAqeTaMDtdhuurgeG0ZNywnmLrZbtuOX1mz3THMWdM2a2O6+CvNIye3935Hq7YUmR4C3WDfSd53hMTHOi6z2drYyjxzqxB3fOUnLl9csj4yjMuc22x3nH8biQkiWoKLWzIgxfqrQnYqXVNsXEm/ujBDjGU7Kw4ZwDcuZ4mEWfKUvgLk5q4G3g+nbDMAZxTO1F/yD0jn5Q1kcWtt049sTdwJuX97x68UB3nKW6dN0Tek8wjqUsuGCJU2LYbtnfn9TRSGZW1wmr02VNYkrk/uFENQbnOqmk9NB1QYMz2GwHaqnqcGYp2hpsnFRClmkhlsy4CQRvmE4zYejpvQS+BsPTzZYxdISgmiLUlU0gOK7FaaBUUCCgyn121tN3AWc6nAXnDFiwwdL3og/l8yKOhsvCUUGMZoMuulYZa8W5NWbAFoytDIO4DzYdMdYNs64gcqlVWX0waJJdlEGRc6GGisNo5XZktAMgLnLOBHEjSkkSaWOoRkT+Y4oU4hpIyvUKC3dlxa67kYIAtQmSAlbaIkh51XWTcxczktaSkHKEdG6dalXakjOmlnNGzTngc5qMN9FXay0WYbQ5W1dL81LK+mdlXiBGEpobyHppLM46ilblVtaFgvtGwej2hvJWQBV8YDNsuLq94mp3hXOOh/sH7t7cMR0nOu+wZKjt3lViFH00bwNLbO1pjxMgZ6X6OvRhNV+Q65EK6P7hyJvXr7BW2DjCyJ0wtawJW7s/ABWr5jATp9PMditJQIwL6Poh2HYF1ZRqVXXX9Xz8ne+xu7ldr22eJ5zumdNpovPiSJrSRK0LhpngxPG4VksqGVMkOQrer2zAdjQtj7a3rQnMexAHCQbPgJG1TpKWtxJJAbeU8WpF4L3onnx+hvqfqvvY+2LQlihd/P0yeQWNs+u5KMQjWEmOXDLWGQVZ3sMpsg3WqOvXrgmdqQpsCch1WenOpQjTGWViXojlA+dWLcSAocgjpl26swZ8Y2S1c7pscYTmjtqYLw1seHSbzJmFhiaapSoIoe3x7kJw2ntHxUlirYluO08BtKvuW4A2VUnrmQp9G7lbTcg7aAGi6Dhqt6+Uui5bwlpTPZhloVjYUfEeco5i0mHOQLqsBSKUbmxz+PtZMJhqSamYM8ZgrKcYK4uPMVRdU2upON+JkUhO631tBiZWJT9WzaZVEqORbWRNe3Jz4vPPtz/zvHbbE18oEPbLv/TyAgh7/yGuXby39f2bD8MPfvADPvwo8Hs/+vpX1frtU5I/+2/8+dXdN2cFBWzbk2V5fQS2WwFQcgND9X3JVIqvBOe4uX6GWFMIQ7ZWWKLoDZaciDFpwsZjEX4gxbTOl+Mc6bIllwVDwbpMFyLGGba7HS54Ed3OmdAH4kE1htDE1Xq8KWp09H5gqOraICC2mqlgEL3Bi+djzAr5G4y6r8vvvTcEI90yMt+kmGOQsWisxTi3jsFLnT9rjRi10GQI5B4ZnZs1OEw1awHy8nzawnrmrygK8U3sF703imzQJrUwdhJd1wkYJjMFEUq4kFL4xnnahPQvhb0vDusQlnwDBsSEpmLItWLD+1s7cyn0fce0LLQd9HI/Mkbacp8+ueGXf/hDPvjwCeNmg7UeS9Nrc4Shk0KLghTiZInsY7WqQYzRGE2KGDlO0iq4nDhNC/cPB6Ypcppm7u4eOB6OnKaZ/f5AKZGHhz3iXO8IwYoZXDGMXWA7jry+e8kXX34hTN4qmmDLsnA8nliWhdB7TrP87JzhZrelU0DWyIKKNSqnoW14uUohuVRpu3v98sQ8T9gga+zQe1zNxDhxOkTi5IhpYLPZ4GsPVeR05lxYUiUmyMi+lEqbmzrKjMP5IN0QIv543rtafLHWnATACX23zvHjfFgLIG1/X8ekjjFnxYxuWRYhkOh6De8yGw2PuybeDiu+7njUabHGc5VU08X4auP08TrdhYDdwLRMHE5HvvjyK37y2U/ZbjxPb0b9TNGINUbysHMccG5rzXGmqpRDKxpK8ctRHWtQ4bTAUEs9O2lbkVzy3qsjLRqLlfX+O+voQ8cyzdTqKISLwpMQEoRpj0hdYTSPD2A8mKTYz7e4ofycA2GnOXFSTS6M6ClVe66PGFMpFEpq6K2lIvorVRMxjKdW0f6Kc5Q2tiqV3K4XV485zuRZmCgGSNoeiU40Yy2uEzRVGBFQKfhgCcmvLKdljmx3A9Z7fDX0m4HD3ZH93Us+eHLL9Xbkardh7ALKsqZaCRQrFe/div7XKi0PtoKrYIshWyttmSmpRKQWAkrFeQkaayksk4jQOWd1c9OWTVuoplBCR+iCanhYERFX1LxyDqKbW041htB7fHUYp4k952RNjiJAkTMSTMzCJZmXRL5LWG+ZpoWHO9HLMMCyJGKaKRmmZSHWjHeeWApbB7/4Sx+xLInnFA73C90QSIu2vKLaDEWYO1mTS09lGHtcZ3j+xR05Q4paNVsTFg1McyHFyjwlUiz0nWdZKsahAtiBYQy8erVn7AdyLKRaIYmWxOkUiUvRxFQquYZMqlVEf3vPuBUH05TFdWSaouhQmEToLH3nGAfPOHZUCod94v5hLwmcl8V0ibLgDF3Hw8OeUgzLvDDPGYtn6How0oe+3W01QQyUuhemyyhacaUU5mMEErk4NpsNFcPDwwSuYBwUK4ve6ThRKvgWbBq3Ji/eWba7DafDREyJoQ+44DBY5mVhM0IqidNDZDduMKYyjj3DGKhZKoK5ZDorgVTJlbgknZcG5w3UxpCq9N1AnA/cvzlgLATXY2wnzMWSCb3HhZ6u99hqGV3PfnrDdgwkY9iOPakWfuH6im3npJ3HyHNexS6QOeLdWXfCOmkXcJqQuFAxJqq7mYgrG0S/6lSPCsKIy2GuZ+q3U5FtcbCRCq9zwoKQZFKYTVbzJqpUXhstfE6LjNoKwRt9bxKnHyAVy5QMdRHqtDB8JOE0FJIppCrVypQ1iFXwCCnY6gbbxKxlPpcSJYqxTjZOpCVZwCdDfdTeV9X8QOaYbGhnQMlYC6nqM3Z0w7hWw4SV9LbU9bmdyaleXAt2rYOhH8lxRgxSzGoB34AwSQ40TC6FOUbGrpM0orE9alVAyK4ogbN2fV5JnY5KkXZngNAFxnHkanvF0A887A/cvbmXDV3EnSQxqpGSkzCzsFCtBHK5XNyndp0G5+0aODjVhWm6XssSOR4feLi/p+sMvrWcURm6YU2UjbEqNCqAK6bgS2V/2DMMPcM4YHILHs+uYbHkVTMTY/EhsN3txECl76lUpqO07ldYA5Z5mtnv77m62rIde0IITHNmSUUTp7pmA+8wrqwVcLNwfu4KTqHBXkwRDIzdsAaZRsF00eRpya/upe07EcY2tVVdzdqWeT6Pymohv3657g8asZ7jDAVJrT2bFpyH+RpIt18Bem/rRTDuHiVf4sh4jrYbCFaNJDoNpE9xQcMffT5nYADQNqvWEqltgbonG33GtSiLTFke4uj0PhDwMZgnYFPQYtO7RgFyP1tsYSWXbAB5KZQk24a15xTAAMab87MqCrwYXYrXHFUiXGtU11IB/wb8OXcBBrz9SIwsalb1VJp5h7DpItIqVZinSdt0KseTtDX1XbcCraVd4Lc4iq73GIRBapwwkRVYqxd6M5swgHFYIwBfzpkMNDezNaG4yNdN+081HA+Wf/APP/jG8/nv/dm/ydMnP2WznfjiyycAPHm6/MzrsLatn9/qstfjN3/zH/Cbv/mb/M7vfMhf/stf/7pSvp1IPlS++8lnMoZL1dYoMZhZYlnBz5xFy8k0l2MUlNTCdM5ldZBL2bLpB4lxtRAh7I1EKYmUZkpSd3dj1iSzWmGFZV27X90f+enzezb9wMNBuhBubq7ZjR3jGPBdz5IyJko73M2Ta3JOzNOkEgFuXUPdanBiFOfQVaeyrmuZiq0N9JZ9q9RydnPVt7MCyedW55bIWmuUCSfAl6wNAoa1zzDOicanMldsa8OyrX2wtUJJ3vD+pt318ekfg7kAyr7VdGpgmB6lSGtc34kWq9W5aThvHmu7/Nd8gdxWfe66hjz+SskXzwUPS7WWary21p5Bt8tDNMEWnLUEbYPMuUiMsNtiKXhTGfuOZV64vn5CqYV+2LBMcX1G0+lEnGfiMrMs81m79GKfXmJkWuQ14zgQnLii1px0DBtOp5mcI2OfccZKx4EfeNhn4mB4OJwYh5HTaWKaJtFTPpzIqbA/nDidFjZbywdPn7AZBo7HEz/94ksOhyNLSrgpsd2MzPOMUxBMmIuFuzf3HPd7ks7JamSs4by06pdKzZkYpTPEqjlK30scXXLSrqeien1CGjidJuIipAN5Cp6YLo2S9BliBDgslqb/dllQbetrUVD9shUyXbRpnsfL22PoHIO2c1zX56p5JWfWl8E8Wket5ZH+1eXYa8zKFk88iimswVbp5mgf+F5ArZ2LbTEz7A8nXr2+4+Ew8+T2mpyn9Tofy2jI2mKNI9dMSRHjxMSvlMrSCs21FWNk/XVIS2brHJG1xjEOA7vtKGZjk2gTBu/JORFjpA+eWpt8AFQ6oIhsU1zOV6gFj2oE+u5CwDiLDQ7rvp5N9/bx8w2EHRM5C9pqnQxys5bH1AnISEWnJEmIjCuYlECd3VqFMqVKWrIKeetCFwtTWoixcDhGgq8MvWN/iDgvCZ8zVVgfVoIr440sdiWzLIuIY1ekDU9b/qyv+H4gpAr3J0LXk6thCJ4wBNGDyoUUowywRr1uVH8LZSn4CkNwiqAPeN9RgL4GTtPCsiTxTclnMb2SpTIpWlVSTaiIVogPci05mrXi2IL5UpIEXhftG22IlZwZNh3O25Xt0QJsWfDqylIAcaYQYb7CMc+UvSwywp5a+OR7T+iCZzpFliVSq9zT4APWWbabDudkYex7qV7IGueYl5nQe4axE0tVpJprjbAQrBWmmA1Sge57r0LB5ypZPwSG0WIspBSZFYTpB2lrC84Sgsd7Sy6Jrg8sc1TXqbIuZnEunCYVIo+ZlIpID1RpLxUDBYfrgblyOsk9KdWwxIw9Jbw9bwYpKSMjGHznUSVmSq3EbKhTIUWxexcRwooPFqsUYW/FrOE0RZYpUaqh6yxBmYfTNOsCplGKJo+AOJcGCxa60HE6nHBdh3Me68RFKcdMiQZnYbfbUEvh8HAQ44JejB9KgTkuSsMVhl+pkXETtJWWVW/uEvx1znF9uyF0jrJUam+YDgvHw0I/BPre4X3VACFL62KS4JXQ0/se10m75qbreHpzxfbDp8wxsw0DuRSebbdaTTsn1Y9iuSptKs6fq8B11nlpq1YfKtYmQIw3nJUWrahJEAbRh7F+dbdp39Wuc1kWvM1UK2tMp7p/IlgrApQheDrfkVLSyp3S051UEKsp5KrXUCrzLBXPLnR0TsH5RnsGbRPJj3RzCqp9Yc/uQI1146wTTAKllGjY6+xZZPes+XQOvI0Rwc5qRA/osqomAqCZJgSKVuukTePdo23Yl1U9mXtVGBUG0jKdA3RdzwpFQUaP0YR6yRGXLL0PF5+dz2AKBlOFDRa8tACgz0OSKxmrm82GJ0+eYJ3j/nDk/uGBmBa8M6DaNKUUvEFdugLeBZZcVmbz5dbdWLfBB2n7daLr0cZOKZVpOjJPB01Sz0y2nAudc/I7rZpVLoK4WslkTqcjuTzR8ePPml5631Kuqs1mVlAxFGFJbLeGFG95Xd5oa28DfgpLTGLs0feM16MazCTsnFhiFtD1a+IUY1W4XtkdK4ChRLFcC5WMM7Ju1ItxdBn8tKTv0Rc1UEyv0WI1sX183y/j1Mu3r+uCVuCkyqkf3Dpuq8x9VvCmwjvXKr8QbRWnH1nWBFxAtkcvhSr7eVwWUlxYTkfSPNN8Js4GEZrzmTObUbSxmvusBNdUOTer13RmxwnTgzWBXH+9rgUNyL+cf4+urm0lVJ17wkKs+txzba09ssa05aK1t1Yqlxcj5IezzpHTmMsZrWAXaWMUhuElsPk40bZaqFjZaiuoZLE+CKPfSBtIrWIoYl2kC4GKFK1SrZgQ6I2hWistWV8zlqsRVm3KEvB779exZRRcn5asgslJGDhVGPviuHZ2cWsyBK3lZL2udYwYhuFdke/L49d+9Tn/zX/17/Nwf8/p6Pnyq1sA/uE/+hiAq6uJh4fhve/98IODsOSc5V//b/1d/r2/+M9943fpHeC//Bv/QBiE5cfAn/iG1369NtnlYW0mBGUo5EI2eQWiFhX27vw5aa45U3ScrOub0LooxRCTJRkIXp5RGz85Z3X6K2vnQLvPNUusJkBaZVoi+8PCT7+847Ov7rDWcVpEBHx3f6TvPNtNz+v9wptj5snTp3zyyXfwIbDZ7vCh0/l4yXzm7LhLA5I5xx9Fk1arQJgxUNXJsunzrcPk3NYs0130adsiszIuUNY4lnIhGN/G68pk0WKRzH1/Ztm8NTb1hGU+6+9XkE1B7n9qgqE+hvYta8F9BdjqZQ1T/l6/Lo44nyZoG3YRUH19z1qs0fM3DmwQ5pYBZT+8c3jvuLra8ou/8F3mRYDmFJPoRo2DFE1L5fZqR3Bw9/I50zzjrFdWUaULcm9rFsmCeZlFJ7ntxUFabpO2QNqUKAtkH6hZTAMMTo17LIaeeZll3G0gboXBlXLCh44URU4lpcTru3vRfoxZTMqcxxrRDntycw28xhjR1l5SJlgnUizG4nzA+kAtRvWgCydd5zBKNjCFSlqfnVUmd3swK9u/SvTirZgBiEmE6OvN06xOjFBxIg1yUZAq2kEhxSXbNkZWKPgCWGo/53Qe962N2qLGFEis2gpL7WgtgevnlYsx12JxNFJ+FI7Uc5xycawtjXoOjf1lzZnZ3dh/qynMCo++/4glUU3B956u9iwl8fL1HW/u93zy8VMx2EtZCwnnYsC6bjhHyYYlzpjqcaGjbbEt9silrsAhtIL1ec4H57jejky3V8yTyNokqkonGaZYZG/G0rmOGDxpkTnoQyCnyOXdkgI9UMVUxnnJkY0966P+rOPnGgjDGkyShdeuic559WvtgoazLXewUGLFEgTRr9oeoOKpuYjWR8qFeT5RqlH9FPnQGDMgvahOxW6rKbigNHWLAAaprJuV9w1VdSwx4bqA66T9UFwBdxRrqNaQbaUEI3bPsVKztjcaoTH7YKgtMcmVYgW5rsbROaeimKKXlmJcg904JUznhHrvLPf3x1WnqFV8fKgYRJ8np7xqnjRxx4aRXCYbKSkAYA3dEDDLGRkvVRD+uiLR8m/LJInQdEqqcyPGBN5ZbNB2CtfALSuMIufou8BpiuIqqAng1fWGzWbg8LBgnBGWwuAZ1Ekzp8zp1CrF0iNunQENapyzauMqlc6cYVkylYLoIy2cThHnRSPNGiNC+sGJ004R7a9pmui8OFU2YdyUCjlVks1M08KyDPS9fEcpwtDyzmK8Ie6lDVWSIdnil1hZotQCchYHtpIrXSdMtGWOnI6R0yLj9jRJlSgn2Ti6TtoxW/uddQJaHg8T80k0jzajx1DouoGXL6FOi0gKZDgeJgFLrDD+Qh8UmLKyGXmH7xQIq9JucDwcGceA8wLY9L04oDgrBglohdU7xzgKyp+LuCiOXeBwWJhOC8tDpAuOcSOU834M9JvAOAbiFClUgi9YJxoHzlk2m0CtnmHwAoolacUSHiiMLtB7Lwvx05HgnNwrFaQ1nNkKzjhN+nQtQQBMiYEV9K7CCrOuajt0I/prBceuUfMaPIpmmQqzKtjcgrimd1VqJWRhhgVnZYwg7WneiQD5anPurCRoLSF1ZzHPpt2AEfo+KWNNwjXHmSztCEU3rlLO+h+yrikLwTSLYwWSnQpHR3HobUCFQGfS4nymbDf4Re+M4ayp1SrqNa8bfVWNgpySGJdoYWNt3aIBCudzbbo9xhiKBg4xJcY+YIyyZqoA8pksFS0qtmrigCQzS4oEFX5vc0Z6zrIy6WR85FKllfsiT0f1s66vr3HB83A48vrNHfvjgRwXTM5YXT9yNfh+IyL5WsGqKZGytk9UMCbIvVZR2KBsMGNlLUgpkVJkOp3Y378mxYm+71ZmGmgSaIoGBDIW32bu1CqtmWlZgO1a+RPGX7u0iwqk7rPe+xUUvb6+Zp4W5nkmp6zj2ZBT4rAsPEeC9O12S/CilxNi4jTlr9WDkfEsj7+1/q77e02UmnEqP5Dy2S1J7t/bIWVr6jyDWI+0NxrWYu35L299xPvZThdAxFv/nNT99vLb1/8qUcEbYYEJi9JrwCxfXEt5b3LYANpSpKoeYyQvkTBo9V0z9aTjt3NmLfpVZS/q9Fl1swTANmfgysi1WaPMpxRFG9FawK1A2DzPwl7o+nUutsPqZ5RSKdZg6zn1aM+i1sqSCq4UaXG/CPpXRpjGG60FsCqIaS7zJQTcrgjj1jn76Nk0PcCm69LW8lbtbszx0Hv6zYYQAlREp6YYbm6EzRiCzMmV0dgutHUh6Fe2z80KpLdE6swIU3DfSPJc8CxpkTgO0bejCgtpnoX9USmk4kSHsgoD8pIlWxqgUA3L8nVpkBw+nJ3Gfv/H3yNnx2Yz8x/+lT8EwPX11wNh3/lkT9dJ3Ppn/83/TN0jv/n7wPCP/tFv8ZOfRH7v9z4EfvNnvP5nH0MvejtUTbq4eL46DM/adHK9GSuSD7mBxborGzFoaHtcrZVgpdhxmk56BYBprM0zMNwA9VgK++PCi9cHXrzeC7O/RJrW/RwjBcM4dOynTDaBmyfP2GxHMIZhu6HfbKBWshYUzqCvWYE5IW5eLE5G51NR4NpWnKkX7YEy41ri2HStVny9hShrG3hZ9YreWdTQdcnIJ0qMUdZ5vZa7tIWwktpMp+lwgQrY6zx++3jPV37N8fiF55zEUGs7N4nTRD3mPSgV53vZdGLbkUtVF2OJqa2V9tDWVm+sB+uRLSOBeT8QFrzn6e0Nm3Eg5axu3MKmC86LnqExbIeeYOHV8y9JaoZWimj8WmfUbOjcBlkbW6nv5TOsxOReYyYD4Dq9+3IsMYprYcmUanEu0HeBMgw4Hwi9GDzN08wSI8+fvyDO8u75cMQgQISzluNpwnnPnLLEcdbKvdZn2/e9uCD6DoolxkzFSutcA5lrJcZzQc8aCLrFT1OkGa4tS8I7S+cNPkh8Mc9CkDiTPKDFbU0j88yeLKo7ibaz23UveXsMgewX1dZVJzblc4G4lLLG3mvMq+POmMfglTX2rCd7CYJdHKU2pmp959/a+1YG2apvanXulIvXnQGy9XfvDkfV7S1CTgiOeUm8fHPH85ev+P53P+B6s6Ec96qVYFcCy7keJecQc8LUhHVlxV/Q0dYYt5cxVtc5bWeUTpVt73iyGznuBpZl4TQVlihj1RpDqpWaK50PMEiRfokiVTBPQkAq9Ty2WzHCIGYoxjbTt/fchPccP9dAWOgt4iJglUbpdCEV/aycCiUXQvDStpbKKjiNosp5kWpyiuruVFvlNJFToVMW0sYL+JBzoes9US20q5XNB4tokdVzkG0QUcy+7yilMm5GJPGXARyCVPmT1/ZOKwnrUiWgo3Oiu7IkRcHBdYU6ixvkUhLHQ6Yai3cJYx3ew8o0roWcIku1nE6VvhcWk7GyGZVaz8G/OVuaS4XaQMmKuC+kdGaEtVakFQUGDoeZEIJWs6oG6k2zpbFFYImF6SFyvF+IS1YWSsKr7s1m05FzImdw3tID2zHggwAdfQ93d1E24FRYpplhcPS9IXQe60Tk3Knla06ZaUl4b9nueiQZFBlPHyze93S6IJRciSlz2E9aKZb2zPlUGXfS/mVDWxFQ1pIstI1qmlJhmTNxEdHdEETUPM6ZZSpY40gJrPUsS2K77VXbBN0gDX0vAVcDZ+dJtCnmScbJMHTEOZJi5f7+yDQXnPcaDFuWKI5fIYhLZEpSWTZWNtE0ixNV33uefrghxchm0zMvUq2PFaqFmKQqLUCDIdeCK2Zty0OBmAZzlFyYjzMhGJgV6Ov8qnOSl8x8zISttHdtN+dgu+sF9IpLZjpUlkX0GkKS+9gNnq4TB9Gxk7GStx5rmj4I7MZA54UdlkvF9IaN7+lCR+96Nn5gqz3/nbNinqBaaE7BagkU5dk3oKPFio83TtmgfOcpZcH6TjdHDcJ0jLQqlABKMq+cOVeBjLEKUtgVzPHeE63FFWGVGU08K1YYhMrAa4LPoVMdhstEsp6p1GgLg2h4ZJKJ5CKOuMYI0L3EeN4zWnYM4FSsGbtWyodukIBM20jafRMh/ESuhVJV90gDal2W5TyUSdXuddVgcwW+qgTOpTR9K2WLIa0dUFbmLsj5Oye0+HYNKUXM2NP34sa3xIlUErmejVEKSSnrmhDXypIVyLFOBeYVkHeqU2QkgJPWQQWYKuy2G26urwk+8Pr1G/bHI/v9nofjgZQSHkNvPb13hG7g6uYJN0+esaQiWpW1UGujfAsdXEBPfwbCnGgsxSUyTyeW6cD+/g2n4173k7MwqDx/vc4iLk8YGDfvth6VnFnm+YyC8DghaYL5eR1TIkbulEEYusDN7Q2n6cT+fs8yL5pUFqZ5YX88cjid+OijD7l9ckvfDzjvMS6zLGXVWmqBSymJeZml2qqGDTRgzDYWoADN07wIS7ralaV4KYK/Vl8v5u7aknl+0cqSWAd+i6Haf74poHor4pTPKaygUdNavFhAxDDArcGra7bS57N8/3doEtoq8+fkv64AkjHCUsoFilaas2qG0VqjqsZHktIKs70KY6wa8L6TNoiiwbi2Tl7ew5SSsAjcmQW6BvyaG7XX5iyArCSVdq0el5qp2dCB6nmJTki9jHI1tpJNRu+FaUlO+44Cqkua7PlcmpmFvQDOJWk1en7tuUu7eT/0hNCtrcdLEpbZOPSE4PX1BuedAPr2MZMQWFunyRDTwjSfmE8HUoqKoVScyRiEwVRsUNMLZds6T6lZWGRJ1upCJtdICJ6SZV+2SAC/YhnA85eB/+3/7tfeGaKXx49/cr0WX/6Tf/QDAI7Hs8bR9dXCZ4/eUfnooyNffbXl1//kZ/z23/kef/NvfYd/63/4d7CmvgMivH188PQzSnrJy+czp+Mvf+Nrvy016OmzL2QfLVld1O1jcBvWeYEmiSKMf36Nafuw/rcdre0qJmHfNEMFw3l/uUxaqzL4H/YzL98cOJwWKfi0GAItfFaYlAl7tdvxve9/l9sn15JsqkB/13WcHmSsrMNf44LKWheS9c+gjuh1BbrXow1KBf5bzIGKH6+tWXAxgOSHWqXl39hWJD9/1tqWrYjjZcv32TBJNUsbC36933ryVcGqi+e0nvYKq/1THMZo/JFxLrz12WZlazX2eF3jEbmerEKhj/WUquqzZZH8r0XAMJUykLhAinZU6SgxLejT97fr8t6x9SOxJKLq/vVdzyb09M5hSiLFhTifxB3atIKhuO1F7WaScQwOefalXujD6rWtHQaaE8s4lOstKllRKnRq1NE0vLqu4+p6B1VeP80zV5sd2/GGf/yjHzEtCYwU4WJMvHjxmjf3e1CphZRkBVpi4jQJOyvltD4b1rmjYwBpibVWihDGqGuq7hHTorqPmrsFb1mcIeZKzA02krxi0bbIFpMVUhuRuidmqEX2AStdLdVZLlty1yGnY8cZcW8toG3Gsqc2ws1Zd9XqXNT3aXy+gnDfYiyfmdmP19G2n2MuCsuSKL5TePqnPoy0L6aUOZ0mXr56w34/8Z1PPsaSWJQVaKyh67yQQzQWMsZKSySSXzvvHumsUrVDTpOmkkVCpRaHkRY1grPsxsDTmy1Q2R8D++PEaVpWsDc4JyZkZHIPlowlCAhtlnfATNG8XfB9h/MigZTiN7Oj2/FzDYT5ThJkSdCgDX7RohK9rJQLQxfohwBzIqWM7QLGXwgeF5jnM/VZ2sokwBv6Xvv2hfHkvCTQoYgoZ0oJY9Ue1Ph1HWwbrnee4Dusd2x2W5b5IIKpyMC3TpwNcsy6yEg3rVUmSNMSkeBVnrx1FeshT4U5FYqpBDNJ65MGsDEKgnqcTuuEmWbPMPSEznF1vZEWCYwIXBqpKDgfJMnxjhQzp3liOZ1EB8dD6Jwm7gZTjGgbzIVyN+OMY7sbVpptyfWsa+EkmM4xsZwS8z5KouNQdy2D02SvMWc2Y68Mg0TJlpykRXDoK9MycdwvLFOm7wPOwdg7hmHAWGH6LDGy1EqJM7k6anFAh6ESBsfTZyPWGJY5scTCw8NESkWMFlSzJReL91IROk2ZrXM83M1rdbcLnhgLeTHUBC8ejqspwjj0dGv1tXB4iMRksEYqvFHb/3ISDTfvJeC6vupX7R+DMLhkw5PBtdmNvHi+BwzHo2wCcVHGRM3EXPHWrzpxLdE1GFJJogsweMCxuxlJUSrdw+g5PkANjmHbCUAyx9WtYz5Fko0MfYcLHttcr6whL0nBNtWEMVXZaKKJkGOhRkOZK2arCYr28xgqphemRNd5+sEJyBRETL3vAr4XN9fOiYNiCJKceysuihbEodFacpUFvnjoXWAIXltS3ApKiTD8Qo553WS8l+Ww1iqaHyVrMm4fiXk/TmgDibSOc4MyCqs6Flox0pA2SauaUxpYmSpioUXYl6L7cxFK6fq1JrpUXCj0PRjVApEqndfXSMB3SWVu51upGgyLFbS01C1rYC1U5vPa2ipRtYK1VRh+Xu5D1/XruTYdMe8c0wQ5zpSSsFSsDXhvV1TQwBrAmVZ51rElzjoW6zxZE8aqNvRWQdd2U0oVJkxrKzJG2r0y5824Iom6cdL+WKuwfqsGYg0MkCBHAxdbxc22ZAFrNCoLptBZuUZj5VxS1daFZBn6jpvrW25vrjgdj7x+9VLzCmWiYgjG4a3DBU83jGy3O/pu4LQcKbrfnEVdhfHnnbRh9p0wMcV1MzFPswjdHt5wPDzw9lGriJGnmKCINpPcLyglX1QOZbSVnFhSJOaMN8LiyY9aPc737Ny6abE2YIywLre7DaHzpCVqRVuaagpwmmdSzlgfKMaz3UmyX43B90HMX7wAO5KELqSSKHHRVgSZW15NaKiQsmpqUPS5l3N7DC0S0Pa/9wSjlwGqwShIrHNGgRR7MX/OiMs5cL38rreP0LuVddwcndrhrGVU5z+A5qp8+fzemwyaFjN4nLEKBpv1s5vwf/CO3vaEUoBMiSIIjjmvQY3VtbKzlJmaclGgR+3mY5VnrYzXcwKjhhNJ5lnTr5PzUOcpbdeuVXXJSl2TCFkXBfSt1DPjoVTSW5ffEvFH4NjFQmk02TIYlnQWKW7MVWvPSZjg8meXrwayN42alhAvWYqPJsV1fDbNOGccxjXdy68/vPPEZWY6HLh785JlPmG1cOoUtpdW/mUFwQBcCOSciTGtyQfUlcEnd0TYrP4CsL1/8Py3/83/6jeckRyvXo3s9wIO/t2//644/m4X3/ndn//f/1V+//c9f/gPv+bf+O/+1wH47b/9jFJ/NnDV9SO/9sd+VVtpf/Vnvv7bHH/wl/8+fSdSAFQuWnnkSXtvgbRqZTnrVKfmMQN1xb7fmm4CQqpGW8krGxqEZ2VhBVVKLUxz4n4/cb+fVskBHi2zFm/EmOH29ppf+IXv8+EHH17IB8iRc6bfjOSHtno24xjd113DtgzZylz3VcANWSuLgjaXzqyteK3/Zs5zubGyZF5c3gTTkMQz+qb7QC3NMfttNq9Z/7QEHmWwSbdMK5TLrbk0mlnf/7aw/jce8uAaCJdLwb5nONYqJlNpWajOnddbYygKpFrrVlmBFRbV8ZSpGJLEGs5jSsXWrHuRkC3Qy5W4yTwaiwUoBjKSM5RaSHEhGYPHQ4rEtMh6fqEPJ8/8LI1T67mN1BrZN0QP8qxltTqbOo/zGWtUtsMYAfgp2Chr8jJHyS1yMxgwxGXGGTidJvpuy+3tU4bhCwp3lBpJy8K8ZNE1PEyibZjSeVmucPdwYL+fqBWmacHhWGLEOg/G6lonY8IbT9NctIimGbVQtI20MePmRdZAe5zw98czqIZqbdJaeq2u7xcDoRaCd1AlXxHmsOw5j5hYgnrJXMFSi+O4SAcSDiEBvIW+yHiz65z0WiAR6ZHmEHoJvr9/x3hfayRcMMZqFeMJykVb98UlvvdTv/647NiIKfHm/oFXd/csMSvbv7JkIUx4b4mxxVeCVnZ9T4yWUjKmnItOpRQl7UiB26qkkjMVZwrOVIzmBMKW3LEZB07Twv40M82R12/uuXvomMeFaZqli85HhiGwaHx+miZ8Lvo9FWqR/M87Oh8IznAzXtGZ7lvdj59rIOzmyRbjlEExt+pDS6oQBkwRoGHcjgwbw7REytrmIoNXAWNdaET2sI31xpiqtLZISSalc85SkqUbJIFpwWFcEtNJ9MGcFVHvEIK0JuSy6mkYI0lsnKPoFyiwVquI9Vd/pnDWdq7FElzE9wa7OJiSOONZqc7Os1SwSpFq+TRNGGMYxxHnvDAkbMEqWJhiUrRc7olVW/ZapLpqrbQClrhIC6izbDbSM16zAbxUA2ziYX/CWBhGTy3SOmpCEBe2AtMxyj2slTA65n3CVhi3Ayk1wUKPc51UmS3UIDVPQ9tMDVe7jnwfmbIw8mLMmsy3ClDFB6lSx2khOrsyh1yz3qVqEl3Z7Do2tRKcWVmBKVdhbgXP7okwokKAmuHNq5OC3Ya+rxz3YvNrjeXh7kQInu31wDD2Aj7FJNXlJVFKxHuhipZSWVLCFNGu6HpLLo55jnhvcNaTUxLdEBOY58KyZN7cPXC4n5nnqHRoB7VglVFjadUhAYRA2imNtTBbhm0nbVSdTP9lWhg2A4VCKhnfBbabDuOE0rwsom2n5tI8PJy4uh7xXc+gItiHhz2lZLy3mvw33TxJUEpEvtML3Xk+RRVZhn6QMXU6Zpwz9L3HGHH8G3rLdhvYbIMAYUGAUmMkEeitJ1gHuWlFOTww+B6qVEz7IABrrVIFyTUTc2QpIk7cWUlIG425VdiSihc7H/D2XDFvAcc6jowT0WYryVRU0XkLBGfwrmKNBOTedrqazGsGI0K8Ue+VsiI0oI0JUnM+ouCrpQy9gHr2nCCKK5lqWqGJpiYJOQkwV620gUu1sjLNCSz0nQA+l5vr2laJzIWCMCm9DeAC3qvAtwIplXPSC7KGhM6ucz/nem5V10Wt5kQ2qKOv/B1zbhfNUsLHaTX2XME9a6sVYzDWkUoRa/iLOOPhcMRXcFWiR08vbC4j60NSoDMrZBxTBjIhdBKP6zMN1iio6bQi6NaW9X7T852PP+T6egu18vrNa1m/jaGzlk0IxGrW9ttU4fXDAf/iNfXlA8YFhs2o87Tj7LCnrBOd3+IYm8nLQs36R9S6uUQHBHjJ5Bw5ThPWRoZh1BaOSo7L2j7a3hcXeP7yJW4YuL19os8fGg0fI+2/WAHVS5L1iuowJugzz3Rdz06tuQ/1hMmqE+Ic0zLz/Plz9scj47ih73tcCAzDKIybccs4jljr6LuB4DyHw17BPHkYdmVdGxWGPcsOwGMm2DpX259HAahZK+yrq1kxYo7xnmNlMrS/NzDwAqT4pz0etxGek9aV2fW1H6kuk9YxRwlU1/jAipam8YGaLNM8Y3S+NAaq9Z6iCdYlOCdFPWGrd52AJOg4qqXQd07biAVUt1aKV1VCc92v7PpZIqBb8Q48wiYsCoQF51ZBe2FZyZGUjSktTYp4VoTBoQCWJNciR9FaUuAMzOVyXsPlbpkViFwFjDm3pa8sXqR1KBfR/0q6xngv9wznpHWzgYlNr+vroDAFEMZxy+GwJ6dCzrPEV8aIdo8+uBSn9flb60VMfamqL6tMNlM0WT+7lLek/3h0/LXf+pAf/f7u24w8wPDpZzfcXk98/sWzR/+63Z749NObd8bcs6cL4/CG3/ndj9bffvHlt/k++B/99/+feB/YbjY4d/2t3vOzjj/9X/nr7LY9m05cnGW/zmoOIXozOWU13ekwVVqQJb5/fFgjRZS2n4OMYat70QqIqe6NNQKMOk1epyVzv5/YHyQmA4XbrCTdbRWyxnC17fnF73+X737ve3R9B8jr27xPCmpgrHZsKHBD0ws0KxuMenZ3xKDGLercaFrbb9FCtLDoW3t7ayUsRmVhUsaZtk7qmNcEU09QxpvqEBmQvKmWtWgghTNVrqbirKeZrsh3CsPM6WttFaCjzSBdXt6HS37jYYzBqzud1Zapt8sTogtXFDQyK/DQpDAyCWsTFNlFzkUQ9L6JdAtmohpkX7NepF8a8NkArItWMlC5Bm8xysiiFHKMHE4njua8glTausfKCku5NdZrflgq0WgsdqGxGi7kIaTjB4hH3DCC8YI8GtlraoXD8cSXX77k9et7lmUBhHlGydS68OrlG0K35YMPP2Ezbil4crWkoujmRYG21HwB6Mr6KNp6heNeyAXzciIq61XGpCV0Aec9tUihruSEd03n9XyUohq2NWOzFQ3AKiBRA5ou1/T12dfzXO66gDPCbqqc44Gm+bUyvIrherfVuVHpQ5D7byQmraU8AnDtCryZNTakzaMMKxvanL8THv/cRmvV3XT9+Kr7dDXrPnC+J00bzKyvfXRozagB6I+/SwtCCqQuJXE4HPj9n3zG9dWOH3zvyVpIb6PT2gsWp7VgnOStuUr87qRwG1GWsjLCqrZ5u9Y+qXhGUYb60HX03cDVleGDKs9+f9jz5n7P3cOR+/s9KWWO08Q0JwqVw+lGzCOWhb4T9nSKM1e7LdfXWz7+8ClLihgM19+94t/nL/Gzjp9rIOz2yQ7feaH3mYWU85pkSTKQFW025KSDLVlwVUUuz+hqVpM1g4Am60aRszhblMI8RabDrLR/q+DIW1XBytofK4uXJm6lqBXoxUsV8Aq9l9YVK0h5VSvhiyK0VFZspSKsLUwiTJnnp3kVUHVe+tglwROmRt/3dJ0k8dZYgvekOJGXTAlSWui7oELGqGaY6ltlAVH6vsN6g3OJPkAt4pi2TIXllFeheOPgNIlTW9c5hu2wIvPCQEnEJakQoVZLsvTjd0GcQyiWHCsL0koRgmMYeowF7zJdZ5nJkCRgB6mw+2FUsEdBiioLY9d3VNUECp2T1lAk0RyGwGmaqbOw8U7HSN8s140V0T3dm4wRUfTNznOaEndvJkLw3L8R7ZTNGMRVauhWUMR7ETD0wTFPZnV563t/fq56dL0jK5grAYHB2A6ctkJkWGLleKzMJ2Hh5QjRFHyA0HtskmClDx3eOXHDNDD0gc2uxxi0xVF02jZX4ibp9T567wi9lY0pw2bs6UaDO85MJ6E7O2cZhqA/A6UyHxam04lSCv04goGUJfk3CrBYA9tNYJ4r+9PMYY54Z9iOHZ0Xd8ghGIabjnrdYUzVtmbHZjOogymSRGny4qxl1/eQYanLCkBI7FKURWLxVtoR55QFMKl11QJZgwed7+3PGlSWgquVoADT2RLZsSS55mCl2luTBOMW0ebxVpgK3ijT0RgowsyzBAyw5JmKZ0kHreSKHqExiO7YRZ5t1LS+pILpRK+hlkIsUYwKcjMEMa0+Jm1FzlJSYU75XCWuwoqsFKqCLCK2Kpu0U8dYcYApoq1VCgVLN1R86GTjT0nAKW3haZtuCGENztr8T7EIWK3lzZwWSBHjWvByZrJVDDkJrTrnC7DAvBUQVAkgC/bROizaV/Jzq/61bT3Xqu5fdS1IVGQdEh2OgmiDGHofCFaTD2vxLuBcoJjK9XVHPwx873ufEOeJz7/6gmmaxE2v61G3c4wV/bH7w4m7r17x5mFPCD0Yy7NnT/lDv/Ir3NzcUFLWqqhfRb9by7UwvGbScqLEWQCpUjHGUUqiATJFVEOxzjKOHSmJ6HdwAkCUOD/aQ2sVl7MXP/qMX3j1wL/0G39KQFa0MERdW/hSEX0TbAMgDMFDzRXhvFeubq4wzmCDxxwcnCb6NJBz5ng6cjwdcN4TfABj2G13DJsNoev48IOP2Ww3BOfxFTrjFBQ3656IPifvi4iPc3aIqwjwXS4qsDIAzqttS2xWzLe2l2jIVytNZflnth6Ydo++6WibeF3/1lje6+ldsEJaMtlAqrdhlpwTMWWs82uC3saxtQacoZgBR8HFSM3nFlmqtokYdX5eMzD5ucLqttjOadtfhIg1gzKhKwXrIfQiHeG9IVg1bbm4bymL1tyqL2oF4A94gjnr1TXwT6b2BaBtZA5l1JSkExv1eZ5Z5kleYlDdHospjUVzdnstrZWkjQHOreMt0M+1sKgwemNA90NPyYgbnbVEJNYQSQsRbb5kCp/vUz23X9WGJwj4hRVxs2od6LMxWELYyP7sPN53xLiQs8zrJU5UUxndRmUKWtJv+Bt/6xl/7t/+k++ew9cecr2ffn7Lm/t3QbzDYeRw0BO/GH2Nsfbv/J9+42s/+eb6gbv7q3d+/09+/3f4z3//R2y3G97cvctAW8/MFOq3YJg9e/ZTbm9GbrY9wUjhOEsVVCQ9lkTOszB9GutDARhnDNlcjFGjyayXGJMiY6oxHFNJKwAGsvYsNROwjL0jpczD4aQtkbPsI0ACduNIPByEGW0NmyHwve98xC/+4Be4vT2DjaVKMrkskZhFw3MzDMzTEe87sBcNsLUISG0kXvN+lKWlqmNeRVsX1ZQCkQkoLStWQDilRE5SwK21MC9HeiNtwUYlUko8MwPXmMBaMolanTrbS2G5gR9t/2mvl+IVGkQLGGfXWEp2bvcWC6yBAo/HxrtmHJfn5n1Qsyq03a590vmotTHgzoZAl4dob8l+4uzZLU/eq2BjFZaVLVDSshbkHp+QgvjWr8CWFGpVRyvG1bzBXBRBZEv4+lauOEdO0yQFDoO6Aatxl3Pi5jxuuLoahPm92YC19Bu/Ou7KNcEyR169fMNPPv2c6TThg7hq//CXvs/pELm/v+fu4Use9nuurm4Q5oehUCglrfmtAG9o94d8vveBXC21GlwIfPHiOafDAWqSYl4pdLsNNzdXbDdbUi68eXPH4eHAOQZct8zzM3YSUxrMI7mBtYCrCGrMy/mZAcuUpPvBKptxFZhnXeasFaOg3ThKBq770XYzkI4JZ0UWKS7zCkw29pm92C9b3HDJAmvxqhTqzRoTnwemtL2XWkXLt8UKFV0PzcVYPENm8nVtD2uN8vqRALWQ8mN2rw9SRCtL4nBamFPhZjfSB8dXL17w2ec3fP87H2JLpFMyCVXuTykXhgJV3NmrUVArC4lGX36eB2+h2lLw1eKUFqKt8/TDwDj2eGd49nTDB8drPv3iJZtNT1xknZoX0cvb7/fs9w8s84JzjpQip9PEOAx88PSW733nI3a7Dd4H5uVddvP7jp9rIMwGg+8cr17eqWaDCgkvmZQjzlWGXtg8JSVC8KQ4sxyEnTHNCec88ykzL9JSZlRU3DmLqZZUK7b1Yc8RMOIAGeXz+sHRb4JyVQEFTHrT430Q7bFchRUUAZOwXU/OUVqmHGAq3dCqJ2VN2kBYFi7I6DKq75FNL5a4cyEMQUCB4EhLwjvVQ8iJGBestWJxXzXo0kpTXBKd83RdwPtKp21qTsVfcxYRfKGJVgKBbttpUNCQb8t0WLh/cyLlTPCeSiHVQjxkSpKqsSwShsODJGEVKCqyr5I/2CDi6gA5VQxSZRBhb4O3AcsCxfKgIu5Otaoa88i7sCYaOWUFwgLWyeIXOu3tLpEaM8YFaoHjw0JQ/SmM9KHnIlUs5xzVIL39wZOLpx89x9PMYToyeI/vPf3ocAp+USVIsQoCVUTvzHcNidcBXERnbNx2mFSJsTLNGWpPJZCzsMniMpHiwuEQ1Sa4bUBKby0QZ2kQ6vqOYexwVkIy1ypxVYDDlAppjiKOXJpoohc3vE5Bu2NhmRP9UPAhEIZuZVYaDK5zUuGOkfkg89D5QE2RtYUXSfZKjOQYVWyycrUZ2T7Z4kVuhRCsBmMioB9sINggrX++gtOgSRmYV5th1U5YpoXqxcTBYlBtyzXQC1XnggVTxLlrSWdX09bOeG6DLY82scvKT2NVNLHMoK0yRqnUxlptbxYWqPeOPnh6DdDWoEwTu6oJfEGYRlI0dbRWLmct1lstyD7e9ppYaDPusN6uiWzVhK8a3Sx1DIpLa16FpCvgO4dBaNyxNPagtACeGTB1reAUY7Aur0mRsaIhdH844VR/DowCkG69z2swiSGpIYQ4XMlvrXXY4IVZpq0GMcFSPAWLrQVbk/oByd14K8SFlu5ffF+MhVOEbWfYdOvVkPIFe86YR9VS05ZxUwScd50CP3KezgWqcQxjoBsGxnHg/ngkzZFXb+7Z9KIVJ+PAaYu8COS/ut/z4s2e6ydPAMPxeOQf/d7vkWrhT//GnwAihl6AtNCtot3zEil5ocaJtEzM08QyL6oTmFU/qVDrhciyrl05l4ui/tvJhdyn26uRcehJy0RMBR8GrSaexwANEAuW7DIxFmUqWkIfKDnp84fdbkfoB4bxxP3DPc0EoZQk7aTLQtTWh+NhjzGWfhjY398z9APXV6K1tt3s6EMQl1RdL3K15NwSvoQzhf00K5sPAdVNYyDJmL8ETts8aQNovSclC8vMtDHkVFS7rmNkxWY0IG2tyF+LhDkRBlKuxCoAn0phxkiBB1SLR/dFgabf+7G1iqbWMotUQVqiJBZVEnRrDTEXTsuB4xyBiqcVnSTxTMqmasE/ivvlUjHOkFNZizHvb7+QYH1eIikXNn1QkOvx+glnAf7WTpuRAJosLNgK9OGybVEAytZV9VbRXBIDrABVLjNfSExsdzeQIul4L0Us48i14tqKcZFYva1nVoq4+gp4JYyfos+97z2maRfSkhkVp7bnRP/yXFPJ4u6qXzj0I971pIiwD50lV2mh6erC2G8xrlsTpZQy49hT32QKwso3TWLDhhWoMMbyd//+k68ZfN98/PSnT+m6cf37206R3mdS0kKjkza9ea589fzrWWDf/fjVe4Gwv/H//TX+xB//x3zx5Ve8ePn8n+l8L49f/1P/MV0QIxR0b8o5qxGUow89xRdSsnijrFa0qCRoF6yjDjBVizHntbONjbEfpXhbElVbEFMSZ+rZGuYlcbefuH84/f/I+7NfW7I7zw/7rCki9nCmO+bNTDKTSSaZJIssVok1dPWgnl4kuN0ypFfDgm3AgGH4wTAgQH7pJwP+C2w07BfZDbVsCZbaMGC3JPTgquqhemBVkUwWk8yRefOOZ9pTRKzJD7+1Yu9zM8kme4BAKKqSmffec8/ZO/aKtX6/7+87sB08HoQ5mDNrQRS5fTLj7PiIO3fv8qUvfYnPvfo5CRzQki6/220Y+h0xZk5Ojrh96xZaGzbr9QF6UXYDJex/CAVErU1z9WJ68coE74ufqzCYQvQMw0C/E4uB4D1D309poNUTcDrnlUIZgzIyEInVhKCcl7oAF0odyHtLYEQ9+avMU2ldfE+BlAp5LN94vaqixwefkQz3Di9F9fasCPrkkaZKk57Up848ymco4QCfBtbqHU11qJplmOsaYfo0qp1A9rpGDoHSiRVm3MGvgZjQMRSgoAIk1RurAhx8etM7uGKMXF6u+ejhI/pRfJuNsZydHrPd7cgZvv2tX+Hzr7/G5fkT2sUJIXh0BldukwzDpV6t9W0icb26YtbNGYeB5fKY+WLJ9aonx8D5s0c0jCiriB62o9R50jsKCGTK2sgofJT7uN30oB3KagkK2O0Ivqhdlh2LWcPdO2fElNitrxmKb1cqEtdDjLFKDtumFdneMGC1DApTAcVCFAZoJcOIcqOci2Okax2fPDsX0glipeJKQJWzjqPFjORk+HDZ94w+4S+ueO2VO6yut7KL5FCAaPnMtJaBtbAfD3woywoFVerpumrLfx6svZwDIW2JRY20vxRwIO17Ybmqg+8oYU7VZzSXMqbaH+y/gaS1K0JWNE1L2wr4dLXtMX3PH373Byzmc770udsczWfTgEoXtcuhUuTwhVXZ5A2Lh/r03xj8ya6VshalSQRXPkdrNUZDCJBjorWW3hpCUabdv3/GdjcAwjT3Q0/wHjOz3L91RGMdd26d8tLdO8wWcpZttz0/z/VLDYTVD9qXNI62cwLCh4SKZfKgxMfJOSfNXMr4cZTEwgx9L8W8GFInUsgIE97IoQBy2Faj/ZRRiGRF7GKkAOy6Dq2lcHJOPGe22wHvBSTymwHnLN1yRgqZ4AeUTjRtK8wPMnH0KFs3KXmPh/ui0omUI6vLHRmRhDZtI5LBDEwR7MUrpKTJDYWl0LatTAqqwavs+BjjCpIt0akZCRaotOGq+7VWM1+0U4LkfDnn2uzYrgeG3jO/0+JDpN/2+DESvHhXeS/fy1l5UNpGYawseKWEQZdiQKuDVEJTJamKSvPWRgIDTo46dtstOTHRnAUwNEWyKcBX0gljYTZvMEbAtRh7Mob58ZL11qMyzOcNOWfW65HRl4QyUxIRZaWV1CdJ1Awhis9HlmmIRg7eo+OueEdIcTCOGT/6InPKksqp7DTJ0aYYpY+R3Zi4XI1st6nEK3thrylB2vGCoOQszDaHZuiDxN36iHEaY5syHVKlCandVSz31uHHXtawURCjSFOcod+KUffx2ZK4zESfkNRDmfa1XSPyrAIyGqfpNzvSOGBbK6wyVThLGZJPxWRbi2Fz3nvdNcaQTWLRapxVpCB/z7hyXxRl2rIHZGx5jlsnoFHuR1ofUTrSWCeyTh8Iw0iIgjYKkCp6f1+kz6nIlFtraIybmtNUihlVG1yEbi7PoJpkV9W0WSnNzB2hOli2Lf3g2fmBbjbbs64UJFEe3wjz2AWRElbJQGMtu9SJ6Xd94A1TIIYvCYVGCdOQMrHSRjGOkab4tCWd6fudGJv3aSrWRLpZEnZKl5kKXVvAHT0dsrbsE/qAWbMH1hIoS86JxjkpokNAYdj2AxlD2zRYI02ivL16XIu1qcoiD1RomllD1xgwjhAjJKH+p5QYYy3UFEn4LUQkHFsTqAIXqUcEuM45Y62mcYa+96gcSAl2XgDP1ghAEidkSIpRo0BZU9L7qvRI4WyDT4mrfocic9TN0EYSbBfLBbOFJMw9fvREGnw9xzpHY2H0YylOJTVvPYxcb3qOz874H/yV/yEvv/wyP/rRj/gv/ov/nI8/+ojhG6/jQ6Sb3WZmF6XR0wzjSD8ORD+gwkAcd/S7HX3fE7yAuqMMa7Fl6UhiobBRQ8rF0xGyKcyYlMVbpjR/Wilmjdzj66cPcQ9ewzrHtChULeo4eEaYppvGKEJYAJU9AY0Fd7pgvjji6GjN9fWSq8sLVtdXbLebaZIuhVZkt92IV6QyXFxeobEcHR3RdTPm8znz+Zy2aQU4N2UmqhQ+C/vQh0DnLMfzubBhCwi26QcGP06pT4fQXn1vWvD20oDJOahRuEVHnuqCVHxxMllX2V7eA2uf6qnquk/YuCPHwOAj19uRwcPRyTFHx0fyfBhNQhFJ+FzBt1ow778XCGNKZGCB3WZNDJLEW73vnq9WNLZBMdZ3NH121UeIEtqxf5mKHUVyYxUuJXyI1MzL/VuS7xdCZDuMDD6w2kLXNrTNQsD9VPxflLDlJXhI6i5nNE3X4Vwj52nwrHaRmBTpQHoOcOSG6Rxuu45QGvZ+s5HXkJIMEIoU0rZzQlgJUKANAUktjW1Jiy6fl8qlcdd2usEVgKsNhZmaI4tr2mnav29YZXjx05pWhTSt1TR5HMV4OCXDmMFqqRFF1duStSIbSzc/QpEZ22P82DM7voPaeczoBeSxDq0bjGvAWjYJvv6t5/CffOkzX8fPut599z6z2b5J8H6vC7bWTyAYQIyGnCPb3We/31dfecxPPr7P2++89pl//sU3Wn7jN36D7373u7z99vanvqafQvj51PX65x6KHDImfAyFLSuAb73nMrA7JtOQ0xaVS4I6FcQ+2NtyktpKacaYaQ4k0tpousUSP/TkLLVD9dMMMXF13XN5vaMPQeAhoyffXRCP0lm75O7te3z9a1/nra++xenpiYDfObG6Hvjog5/wx//8j/jNP/PbhORRtuHVV7/A6a0du82GKqGFPTRUXebkMa7BMp+6o9JKOzc9xZGMUQpnLdFZ8Y5EGHAphJIWmdltZGhtnZYhrrUTS6rWdOUOybOUq3TzwC/14PlQcjNB1QTo4hGVM3HcMu2nJFS2Qj4tz3Yi0+oZh2mX5VCS/1Iie62aOqVAuwZlOsJuN30W9a/VICyxDimm7NpMDMLJC1NVubekTTe6KaEmN4dNE+CQKR6ihmmplc9N57AHzafPUZiAuYK1LwCZE9BR3mdKkdV6xfnFBc8ursWbq3ywWivOTo5oO8dyueTlV15BK8Vmu+FytRbfYCPnmy91w+npETF6nl8odo+uePz4OUol3vzSF3n1wcv024Hjozk5J9TVmlnX8ux5JJafW/JVCohh0SFxetTRNpbzrSfEzO3jI770ygNW6zXnl8+4OH/GZrMjpcDl8ydsr5/Je8ya0zsnbFeXDOOANYrWiiF7LoMUHzzXqw1d46b9eTlvWSyWJGC92bLa7jDG0L3gczCMnuvNtpBMhI00bAcqP966okxZdAzjyK2jBaqEqo0hcH59ybwVAktK4hpnjDA9DYqYfLEoOdzHFPNiKSAKkyIjLEqrrPagkFKn07BvqlHyQd1FIoWBCr5N6a8TIKdorQTS7Tbb+miCNYwJfPH1y2HE73bolHn1dMH9O8fMZw3X654PP37O9fMN3/v+jzg7dpwu5yLNzXX9FcVJeeYoEu2scvENlB6kbjaiysgYg7BV0aAsKWoJySlfWhmAwshUjKOfkkLns4aQAs4ausYxDiMxePFhs47WGGatEHrmszm3b91Go/C9xzZuz/z/F1y/1ECYLXpfabBr/KpGO4OmxHhk2eSdtYQcCm02EXwuU9Uo3kyh0CXJMnCxGm2lkIt+KPt02b5SbQLE72hmGzHdbiwxiJm9NUoYRosWOkpiZSRFMFaM5EhKvtYZjIJYpqsxRCnYSupHDPIg55TFZHEMxFC0x2Z/OGityDHTDyLZahqRL/nSeLfZkrOnaYS9FIP87DBGfC3qU8Q0kuJlJiDQ4JpGkstcZrMdRZoTM7ZUDe3MEUZ5GBSK4CU5MWVK+oro3SHTlnSzCoalKAdIShnXWNqZGNoPu4EUk0gz0SQyYxCAMSYBaKT+F1noTbNk+Qzmc8dsZiSidTfivacr6W7KjAK+WBiHTDtviOuRYQwMfsSlxMwonLPM21bAhqwYxsjJ0YJYigilpMDOKdN0ppjMR4Y+MAweZRWLZUNXIu7Fj00VZl7ifBhQWbFZRWIQENLOLKaCJ9VkVGnaIPI1WU8yoVmedHKwnS1kw+gaYUeW+2GNxO32u2H6vaqJj1Gar5ijGMTHWAIeTGFFitSvawSUSwn6kLl8vsYA3a0ZKmfC4MUTCjBJzNVr0Snyw1EmkyqhbcLpBhWlWHJa1u7RfI5SBh9jSYFhev3OiP9D7QujUczcnEotN84RqqwmhemQ0KoAc0mo6YeG+GWhTH9eixNTzDvlmdKTEbPRpvh3FYP7IqhaDwM6KxpnbxTzIabi+aFKoMPeIyOUQsoqBSGwaIVddbhv61q0pQwpCL1dN/tiDiZ5sMh/4mSEbc2+EAjZFyNZTWMF9CVl0fdHSF6maF3bUv3PDp+lXRoZcmDWNMysZttf4rdrdFakECENOC0sl4hi0c5pnBNvNiVNwTAO9HFAu0Ao79NpI1PcNAgQoRQ+CvugcXlKRAORxDrjyFETkxYGR94POxSD7FnKkn3EKYVuM7NGGFNaR0k9zNCWYW3Ome3Y41RLpzWNUzjr0EaeN6si88ZwNl+ilCUlWcu3b91iNl9gjGF1fcVwfcl8ccSdow5jtZi9j5I69vDRUx49uWC1Gwgp81LTYY3ht37rt7h79y5/+J3v8A9+//f5g3/2Y+7cuc3tW5Y7t2/RNcJ0dWQ6EkNObAbP0G+J4xanwbWyBloUUZ2K3GpcYbScVyHB3CaSiuQccVoGHuvtimwtdrFgHIQ1bK2FNLK5vuallwYadeCTgi7+awXgJONsYhyLNEQpjNNkH8lxwJdmqNGOWddxOptxa7Hkcr7gaj7nen3FduxZrVdseknzlIUGTdMK44nE5eax7JdKpJTGSDNmtAxMnNW0zuFzZLFcElJgvjhhOZ8zny3pnKPtZEtonKNruxdYE3WQJoDu6EeCD6Qk5zqb3fSVKYSbqWwHV2XylMcKU4YdSpVkJt1hGkMzg9O57N/OODbXwhjJCQkTOZDvpZwZAG2tDIDqeeE1KYnEdXt1zXa1pWlblLJgHA/uvsS425CCEQZY1qQs0meVpYhPJKwxdG0jhWzOmHGcprYqZ3L0jMXiQWthDbtiohuHkRyjAK9agMNhXIt1iFKUWYhIULTGZiWy9CDgtAp13zcI3prIaY1IQst+7OU/kofQH4AnxoHrMI3D5UCOgRwG+ucPMbbhZLYgU5oR15J8QoVY/H2knjHVSyiJlHMM0riKEsCQxi2UvbQmYecMSVlCcsRgSFrT4JhZN3mjyaAqotRAjExSy2Ecy73ItCisUeicMD6gVcI1LbPGsHv6HvN7rzPXmuebLaREkzxGJ3yKWOXoGk1rxbfQGc2XvnBT6vzzXh98eJeu2wMEfe/2az29mGAKWWmenXd81vUf/6//j/wv/6O/9lN/1l/9977Kb/3W67z55S/z/Pw2P/zRT/vKf7EsEuCl20/IweCDNGk5G9AKlRObndwPpRQmb7FmwMfALgRGLynoORfGdTnbjTVoPKHInnY+AbHYdWgal2lcy26IjKO8zBgil6s1D5+seHKxZd0fSHBsB1hOG8MwRr78xTf4ylde5/6Dl2nK4aOLd/D11TUXzy/4nX/7z3Dr1h262ZzXvvC6sF7HnuSFOdvYTBh30lDrjpDE6L3aDxjrePGKZR1ba+WZzlnCFcqZGUmYID6oM9ugjUYXYOjW3NKHxHq14vR4iRn2e59TWnxZ9SHYoIAWig3LxKBMpcAnE2KP62TIVsZi7IbMoBf7b5MzKgacSlglli+uEzl09PskemUMtu0wbUNlpOy2m+nbGA0mDxgHeTLvLmysYuBvtUj7pQEPkMMEYE3KAG2wrkUHKzWTTjcfjQymhLlkMjlmTJHip3Dgw6goibgRozPm4HvklIU4EGSiVb2U2vlRUZfJAKJtLGfHCxqraUxG5Tx50t06PeO3f/PXxAqn7Xj29BFnt+5z+9597tx/ifc/eJ9hHFldr9isN/jRY1A0CpbOcrY8ZeaOmbUN6+s1r7/6gGHoCQWteOXVz7Pb9OTgyOmc1XYrgHBIpBwIY8Q5w3bwbIdETIrNpsf7QD96fMqse89170lKejW/3mJVeRayBnYM466AI5CoYIkA1zFEdpuei4s1XddwdjzHGsvZ6W1Oz86wznJ1fckf/+H3bgy9QHou74OwllUJX8pSF5HBx8Tzy2v80KMfP+PBKw/40huf487tU5SC22fH/OjH7xYbCjlfhjHRe49Wwm7WCMA8zZiKX11MAnblDGhLKh7OOQvIG2LCx1zYZZQzeQ+WTpdtpl+mlFFJhp9agU4yqHbG4Ms+Wt9/RAbum6Fn1w+y96UsLHoFXWPxrZO9rrU8f37Ju+894s3Xv4DRAuBZozk5WUyg7xA8ygvDEbNnWGfgarNmLAEKtpHzMwHPr7d47/HjwOnxMbdOj6dAG2stISb6Yce237Hb7Qg+kGPibLEg5sxiNuf6esWm+PAabSQd2xlm8xPObt1mcXxSPp+M9wHSp/fFz7p+qYEwXzwwopc4dZOYihFjyiRQKc4vrthu5JALY2bs5d99Lw33OIyFOSHUxBglkXEchKJpKit5PwTZ/9og5ocZjk87odAiC1lbRTMTYERFQ1gnVtc93dzRKUdrFUpnOgOC+QpjxLr9AZOLJG23DmzWwrRyjWG38cxmjqZRIo0qZpBaKU6OlrStUCr7YcCvQzH9NszmclBl5Sle1yijCEOaUplmzk4T4yrrUihhpJVzQClNvxvJWaZGm/UgTJQoDAStFE0hFXRyhpSYXRhDhCgDEF0m0iF4rGtxTZWyxso+xXthi0nCH6w3PQldzO4FzbclgSt4TwwB5zSzmeXoqME52PVhMg4FGHygnRtGb8hBJHzjIE2d0FsrA62yJvTEJtRa4ZSinc0kdAGR4JpycKdRPLj6XUBbRTezpBwwRrE8EjkMSSKCMxCjYrcTaZofYwEjhIqvtBX/sl0PSbzAunnD2AcWxx2+F6lZ9EyhAd57UiqSUTJDaVhjDFhnip5fvN9CQiYaIaKtockCppKZmDEpSYKpUpoheIzKNI2wD4ddSRx1clwf3WroZk6SLIckgQMK2oXDKCdWQh4WR21Z5xkVI61raHUjspK8LxRqk+EHSaSsjKaMok+BmWmKp4ui7QxxK02TDOP2E7+9F5Q87ynnKbVNfo4hJKERV0Clfu7VGyxlKVRGL+w5H714YTlH14g5/zCM08QxR4VK7A+JXAslRU4Kq4VxGFOmsQYfEv6g1xZvk4RWiUSiiqzqVCaFUCK0pcmcWG0vMBUUCqft9IxUpkUsRcCECf4UhkOnDI02IlMeioeaSSVUpEhyrWXuJG3W6IzVqdDWNWOM+CjPf0RP+9sYxsLGkJAGVe63TwGxbz18DxlXXp+pk7Ak+371MRDadqYxLZFIUHmaXEpnrkg+oxvQjcg0nbWcHi1pnMNqK4A8Av5Y14LWYtpPwtqG45NTbt+9z9D3PHr4Eev1Sp7XGNjtBkJJswwx8eOPPub8asOXvvIWv/qtX2N5dMzF+Tnvvfcef/tv/226ruPf/w/+A0II/KN/+A9o2ob7d+9Cjnztrbdom4ZUvFzGYcewvSKO/QTm1rUt/IAezJxkNGWQXvwNC3sJipdTw+2um9h+LguLok7wQ7/m2aOHnNy6zXy+EJNldTjFrmtF41yD1rF4MmZm8xnaGLLfCagx3XxF13Xcb+9z+9YZo+8ZxpHr65UY6m43bHY7+n5HiIGYIsM4TGB1zIHYBzkzsvjBdN2M4BQ75cnAerVCacvV8xXONcxnwiBom5amaQBVzNlLAqfSJejDMissztGP4tXjMz6kwvwoDC1niD6UJL+bY0YxYa77bKJtStK0qqLIVJobsRSYtY0MYkqBP2tbcpbGFJjSAhOQg59+XgiBvu9JfsDmwLDbSRFZ00zLUEgMwYUNost+Jr6RTbFLSyLRU0wyh6Zp6Pt+2ncOP2yRShV7h5SIOckeyT5Kfu/Heui5l0rSZ7EMKLhLpoBRWoy6yw9BFc8wbcr6HvoXVh2QAjoOWBVQZU/2dcHniIiADq/9niZvNU9M1vpzjW4LWF6N/GUw6RqROVe5eo4BjC7DCGEOh+xRScBAigzVIIzsaiYeRs9ut6Pf9rQOGjtgiheQQqGjxrVzRtegyaQwYvH0YyyvWxho2hp0Md2uDmdnJyPLpWe9/vkK/uk2Jst2azEmEqN54c9uAlJHRyMhav7bv/PlT32f3/z1733qeTi8bt9+zK/8ynOGXrNcLDg6eukXep2fdc1dT2uOsIW5F0IghXECdauEp3WSahbKYE1YipLImUowgy71YE0GHwrzqw6aJpkvhkaBazRDSFxdb3j09JIn5yvWwwEYWYD2WWOZHx3xa196jS9+8fPce3Cf2aIlpJHBa1xuuL665v0PPuKTh5/wxpff5Atf+iLalKCrzXVhne8ZGdrNUUkGYzGO+LJfHaZe12dvfXXO448/IqumCBkVwzgWpYh83TD09LsdXStBBq+8+irX19fcPjum7ToeP3rK6tEzQjYsj2bsdv3eXoECICEscpHhI+nBBrRtxSdSORmixIAfRnJQdE4G7RND/WddZU+jglg3rp/xdzOyX42F8WUUujDuE3vajtYWrW0ZBFOGibbsm5I8C1J3JpXL6FMd/Jiyj6ryLCs97akaPZ0fwJ79m28arucM2RgEq1eTPLW0P/U2QE6k5Dldzph3DW3biSLIaLb9wA/eeZezsxOury/RWnF8fEJjHf2wRgEX55dcPLvg0aOn9MPI46dXPH9+xdlxy7LrMDqw2XoWM48zmn7nCSTOTm7x5NFT2maGYuRobmibOdveM4weXz7HmBVosby5dXZMjJnL6xX9KMM2HwIxl1RNFBFhmtooyc9BHXyiFYysjKiU6Xeyfm2R18q9F1/U7XbDrTt3ef7sEqhM6P212e5YbQS8268tsfepYTwpJ7Z9Tzefs9luOb+85sFLd7DWCOnDNqUWzNjSF8QsP02Xn5rieKNuDeXcn/h9xftYFbBT/O00mHjj9X7WlnrwbWQN5r2jXMoQfKT3kRcHCqEMqE27YGYk8V2TCVnx3k8u+FF8jgJWqy39GGlax+Vqw7OL59y/c38q/kIBt8aShqmUgCU5ZXxMeB8loGtauQXKywmrNU3nUPMGWECGzXrNofzaFk9cnRTXqzWzrsOHgA8BazWXl1doMsujJbvtTpRNSiS6i8Wc+WIv9VdKPJRHH/h5rl9qIGwYRpnmWMOw2XGVPG1jJ1mjGPT2pJTZ9Z4cNFpZUqBMP2+uNqU0xuSJjSJTTWHB2Op/qGWkYsqBRcxgMm1TJIpqWqkCjCjIOTD0nhAiXedQEUHSjWMIoE1JpQG6rqVxhnGMjF7MvbebkavzLcNW9Mv9yqO0ojsVY+3OObCwGkZ8TCijmOniDaUkNleou5IE2bYtSUV2VyNN206sLl/kot5HDHoqLEAazJhkA5LpTsaU++dax2wWiUGQ5xgSfkwv3Fsp7LUpD3lJh+4aA1YLgJgr8CbSAu+9HPJZDn5rFH0vG6+kjlgU4JwUpikm+p1E+rqS9uGDGOEHX43qhdn1/GotkjHjSGUzso1lvd2w670AP+xBhZSK51JMzLq2gI4Zjy7SWyMRvRFyEmlr22kJbDGZo7OZAHwlPc970VSDKmmQRWPN3gRz8o6pySZO028HmtZycntBTg4/RHarHq0lXEAbw+AjjIGaLiWTCUH2+21Pzg3Hx0u2W1lHCVU2egPG4HdhKlJCFgP4cZTPdRwDTWM4u9WVYj/hR2HbFKsqrNV0M01oItlnLHJf/BgYs6drWualEdwOa7qmpbFOAB3vGYOH2qDrptx/kSd5H1BWTx4OM9ehtXgqpWKA75yb0lcl+UuMb1NKeO/ph0GK6Lo2S5OcSsNvjMQ9qyxTd12epZCKBA9NjiO7vqdxjqZpSDHSuQbXWKw1EsKQs0hVi6xYivaqpdeFNScGySYnUholsTQlMfNHTM873RKtK8lpEroQQsBaSz/2+/tTqMvmgA2Wc568e0KR65TtCdeINDSFdBN1evFSJQU0FZAUxLtN1/hr2Svm85ZQTOhjjAzDiFKOlAqDMWWcbXFGdP8xC+ircpmC5v1rFq+k/RVzJCZTGG+lOSybcgUAtTEYZQg5FH8oT8pJ5Ay5+Ja4zG4YaJUAmPO2o7GOWZ1km1ZYPcaIH0VMKOOYz+ccHZ0wmy/YrFZcXj5jvbqmbTvGcaDvd5KWuN6glGI1eK7WPd/89W/za7/261hrubi44MmTJ/zu7/4uf+fv/l1eeukl/r2/+lf5n/yH/yFf+tKXuLi84P333uOPvvs2r778gFunZ6QQ6LcbNqsrgh9pXDNN0La77R4MUxGTPbFZCLMoDFPhNPkaHQD7lYFXfcig2gFYVldXMgy4BbP5QhjEB3YsOSuSEr/J+v1CCHgybSvDjFikhDeaADSu7XCzjgVweuvO5KmxXq/px4FxHMVUf7sRHzTvGb14I+bC6jRKk1UiJUvKIzFk+n4re5iTJKpN09J0s2l6lYp0p94DsQpo6DrxYuvargBnDdoUA3hdJFRJLBMiktYl/j71XEiT/57SxWOrFKKjHyVRq4CMSokv2PHxksY1UtMqGdhJw9QIKBwkcUuKQF/StnKRB46oyhwre52xVmoPbYRJbp3IL7KwKq0R77QKdk7m8UrkSVppVCPDkGEcGP0oUvUCTMUCGpgCimqlJsapKutrOrdTlr1TwaJrb4Dr4gFSz3fZIwT4MgUoFDlv3QOU1pP0cb+fJcLYE0ZurGf5nhG0DGb2PmO1IJfPP6WI9yP90BOifO3paSsNsdG0nYCjwzDihwHbttQwED+OGNvRGosziq5JZeDy2dumLn/o/cjQD/u9Odd0X4BM8Dv6q2cY1wkjRgyOyBnGJIwCayUkSZnSvFXGjYKTk18cCKvX8fGWi4tP+3odXqtVw7vvHfFf/7df/dSfbbcdip9yA4C+f8Lf+7t/h/Pzcz755BN+93f/V8Ab/1Kvdf89PfO51HJGG6yxbFPC+71Jdl2PWlG8HmsYQ/XLlHpwYk2kyHx+xK6wD2v6s3UGpxq0MnTO4kPgYrvmyflznlxcsXvRjFkLiHp2suD2yYIvvvEqn//C57l15xbOWWIS+d1uu+bhw4cMw8i3f/u3+cKbX6LtOnZ9j1GBfrvDOc04ymcckiossMzoR4ZhEHaFDzSN2L5kevEdi4H3f/xj3n7nfZ5ejigNd06P6LqWmBKzrgOtePL0OdfXa1575SW+/MXPcef+PX7zz/85YvRcPn3Kjz74hM1qzRtf+SLff/vHPHr8lKfPrul3MpRsGyM2MGQWi477d2/zK3fe5K2vfY3RDyyPT/jo/Q949PHHLOZzfvXXv8nV5RXXF+eMwyAprWFERb8HxPKejQUKnS1hGEWRYqwEhpWHW5FQxRdT55sFTN5TauRSN/2L5LeqWkGjc1EOZPGArc+q+C1HYgpCpXsBYZn8BguQ/qKTWYrieTqpiaYhww3YQ35VQDBdaO7aaLTZox9HRzMUdziad5L+rYVVZ53FOEfKitu3TwhBasJ33vljbt++z/ryGcl2XF9vePf9h3z88CnPzleMo+dobshJsxsUjTXcP1uSUuLiasWsm9H3I48/ecrJ2TG3ji27lWa7k+FcSnECQFAKW1jjElomve96I0b8rdFidq401aRAlbRuuRuJnG7eu8MPUGnF0fFcgFglSimtYLfd8pOHD+mHkcH/cZHv7j8nRbESiInR76Wkdf/MCZHsJXnmnUslUC7QWMdm26O0ksFcYWBOdh81FeNgLR2+5irp/Cwm+bQ+yzDqADb4qefJ4fotrSFa6Ym5P/3MdNP/ThsJojPGkJwVtqRCFDYZdIhsVjtW25FhHLHjyMcfP+XJ00u+8uWv4FrpEy6eX3C9XpHKmaym53Tv6yfKk9p/1NeVD2Sc8slnxCtVhtnc6Fm01rzy0kvknHn/4SO2uw23jmfcuXWLEDvIcG1XjONI6ywnJ0vmixat65r57IH+z7p+qYGwuEsEnQn9KMl02lG9MoRyJ4yafgi0bUPSirH3VCNs+UD3G01KexDsEI5PAnxizX7RpgzZg50DSuOKdEz+7sGCNQaTM9p4UJkwjhgcMWRyUxazMQXskaZuV5rGGCJ+8JCFdbUNVa4lwM2wC7jW4MeAc4bZvCuSSIdpBMXO9WBhb1yddUZnhXHSoLpWJEohJXTI5BGUL0WuLoVv4wiFweFHmTerEl0/Wwhba+g9Qy9m+rnIMaj3su4RdU9IYoDYzTpSTjStw/vI6nqLcwatBHHOOZCjxzYNOeWSfFdYaqUITzmInPUA28wIRVkrCoovCZr10FhSit3tgG5bKOmdXdcwlklsSjAOsuGrLKbkNUJeKzF6n7cSayyMAAGc0BY3a0hEjMnMFob5QqRx69WAHwVQ8T6Lz1dAKM4519GSAKllMtQPnuurDTll2qZFRYPvE83M0nSWcefFLyhDsmKkm5MAn1lRWAOSrjqOnrQdhB2jFGgBAK2TJiWGVNhsnsZpmkaO9hgSwyAsNT9Glss5y6Ww1YYeVtcbcuogS4R5pxW6sSinJGY3QNAGcse8a2jakiioxNPHFDZBppoXe0wS34aUkvgSlOCBrDUnJ0cYrdj5niPjpsmCSFnk+avJMlHiYMV7ahwn5iSIX0vrpAFVSRbpGANDMfhP5XkW83dDRjzOlLZYI03wOHoa24ivns5lAn1I7SrsjDLVH3wUpoTwu9DWyiTSWEwODDGgS4FfX7fRefL8qqacANZYkXRFkQ1YaydvwJpGVUEy51yRZAiTzDUN2iiSTvj+M9JVFJMviOw7pZGdmrB9ZLU0mXvQw/vqFSJ+AFVSOn19KXq0ElDC4crgIZX0ypvVwOFktfp4hOBvFBlKK3yQ/bIyi6pXWcp5mpMppSFpOjOXdEbnoEz4tDY01hY/QPFwnM+PODm9Rde2rNcrnj97QhhHlkcnkDPD0DNfLNluNiyWC9puxsc/ep/TW7d56623ePLkCb/3e7/H0ydP6GYzTk5OePDgJYZh5G/9rb/FX/rLf5m/8Bf+An/ywz/h3XfekX0vIXLS63P6zbUwzVCEGEg+YaOVxr/s71qDVRlUJDdzYk7kkhiki8xdHxQj9bNoXHPjHrumxXvP6uqyAF1G7s800Swff2ZifdUSvzYPTjckGzlMJ6sg7eH+vI87h7Ozs+nz7UdPSomhMHdiEIDc+0AInjgKG8KPAyFI4rJzhZFUZCrGWrRxZbDRT34ztRSrRXJTppCzrsNYQ9e2AjYW0KgyuyStqq7XhtmsxWhLTJntbsdiISbi4zASgoRm2CDsYkFE5DOYdx2L2VyGDkghrgqgI02PWB5Uj7PBh4nBNPZDKXwT5BF71RxIPZX4nBYJp2tnAhoNfdl79p+/VXs5NQphhyF75+hHnHHTxHn6e7qyWsGoF9aR2rOpQhhLEIbUYOLPJcDXOEaSFm8XDpK5y4KAuk9oUxp7dThYJiPgWTwIQJgCTwpIJyEYMrRSKhcmswwvlCqs8RgYg5hNO9swDD1No+hmR8Uf0ZBixDYNzrXFCFmLDYW2xVMqEgM0jfk0QzDGvZw1CgPt4CkRpveNPjjjxx26mYGy+JSJNERE0q60wjWNMLh9R04OVzQ0u53m44/n/Mtex0f9vxAI+8t/6SOWi8+WYJ6dXPP+Ry//1L+7mD/kn/zBH9DOZjx69IhHjx/8jJ/08zUxl1c9bdfRdZ1IpY1hPpvTa11YiQM5Zay2bLdbKWLL95Whlnw2UeuDfSmz3VzTWmF8gZxn4xAwjZ32gfVuxyfPnvPo+SWbwd/M+CtAwLx1OG04Oz3m81/4Aq994QscHy1pG8s4Djx5+pQPf/IR73/4EbPZknsvPeDVV15lMZ/TDwOb1TUX54+JY09jMvEABAshMIwyIFBFumuNIyBs0agl2e5y1fPeJ1fshoizRlIqtUWpzLaErISQMFozeM/OR5anp8KcMg12NkNZjT094uGzc7qjOfPtkna9ZgiB4DPb654+JJzTPDCGy8srrraeW3fuo60VlYepdiCG3XbHYrkk58xmdc1uu+X82TORM5RGOlN7LIO1jradkbOm07aoExIhD3IupAHjNSmXZ0pLsBZIfa1uWKVQ9pv0Qm2xr0MqW9B9hswUyl8r9fQNptcBAeJFsE0XQLYOfJR8g6lerX+nDr1VOWCVVtj2JlNTZTg+mnG07AQ8sI52NqediUWIa9tP/fznz5+AaSBKzQ5is6NIzFqF0RLYRWMIMbHp5TN7+Og5u+3Arq+DkZ65PSIlkbeTApqEypICKdLcwuqxhaGM1BTHiwWX11eMXtjbe0AEKj/s5udR60iAwupXYn9jiv1ICGJfsxqH6fzRmMnDrdx90JrR94WEcdOBX+xOJFDDKHBW0ViNyhUMi1xfr5kvOm7fOuP583N8SVLde2XtX7XUpXqqdauVyqGB/qcXVSFZHGANct8++8vLViVAoFbT/neAOQnJJu2Da8T2RfZGYwwSCFPTWgvjvfhyC1kgs1pvefzsOT4Glu2SEARw5+C9JEnJufHR5ZR5MfhX1fRIdRMmVkpC6Or9lBQxuYeV6Xs877BqYPRb+vGYo+NT2uue+TzROstyOePs1inzeSdq1xzIuZit/QLXLzUQZkxls4jXQibRdB1tU2QuqpiypcR81jJqT9M4Nusd+DgVThVYqYkIN4uz/X8mhcTm6iL/A7JXZZIg5DAxY5W/U2nK9UPxIUKRoetRE2zEtHaS+CWYGCMxCfvFe5HL+eFgqlDNt12dxifarmHRtlCaZDGg3yfjKZ0KMCCHmDYG0yjGPjA/shinUUGx3QwYb+TXBXU3Vhd2ihjgDr0YPxpNmYJYtiUdMlMTfG5ovD6VCuwaw3zWcnpyhOsUIXmGfmQcRX6iiSgEILNWGH673cBulCZeGmxBtlNOYlCaMvNFW6ZkpjBuyvShHKLOOVQSrxttNE3XkKgsLCU+EuNeTmd6YYYZowqgJFRMZSlSxxn9dgAvDJ7eB5pWHsQcM8rKaw0+0e8CRMV2FdhsB7QxjEPC2mKqO0hMrDMGpWG3FTnvOAjQJ+aMDePgC5tHDINNYRullGEMuFYOIwrrUZmSIBfK1EUrzp+uOL13TNc10+GUUjWTV2glPlnV/0Y8yXzx6dFT8x1DJCfPvXsLUIqmgZkymCQ7tlFmYl+5wnCa/LKoTbokrsQS5NC1HS7ZicUUiy5fGlyDcfLehzGSi5F113ST3nwyzI3CfogxMo5jSeD0U8FRDy9pLvX0GoZxZDP0DCGUpoSy3sWT6KiZiTeMkYmWM05CAlAT8DzFKZfnX6NxxhJLWpEMUvKU/CnMPHme5k0nyVOHexIChJkigUop4YOfgLDDAymEsGehwJRwWUGHCljUV6iNxjhD9PuHVFsJc9DoYgJaDvcqv8j7dK3Kutgnw8gVo0zgcjXQlieRKiGYGnNtyxRWE6InRI8OnuraJs8i+BgFwDMGV15zLg1CTpnkJcSiXtbYG2wnaww+JRrrpsQha50wMZT4SBnjJuDUWsvJyRnHJ2eA4vLinOurC8Z+h3OtMHQKW6fve0zTcnZ8C2Nb/A/e5cFL97hz5y6PHz/h+vqa+y+9xG/8xm/wta9/ncViwTAM/P2/9/f4f/xn/xlfeOMNLi8u2KxX/MavfYumcWx3G/l5uw2Na6b036SEIXpYjOcy2HFGgbESUIFCqVxSjUTG6r3EdKviF1fXw+F91trg/ch6dUXTtnRdK2zXOkXNBWjQTN6ICpHI1GVYGa1aa6IxBcAIU5H4WTLc+nvzrgVlWCpVDHlzofOniikRQ2Tb94yjTDH7vifGzK7fFb8vT0rymYo8qvg8lUKuylN2w0AcRq4Ky8BoScG0rgzSyjNktKFpWmazjtVmRtt2GONwTiQqgw8l7CKjdZRBSU2W1Zah+Gm0rZu+L4jPqXh8gU+SSp3JRUrQ0iQJXAnes1ESG2+M7Ktt094AhMLY44ceY0TaIymsZY85mMbWPTIVZllIgYQwvlrbkk2e1pYxButkL67JfNYYbJFIWlPZYBkfRhSZ2RS7nm8Md2KK+CDrRViywvDUlITeCpSWsyzXgddBEbZnaAvIWpkYwmY0oEKRHRUQrGmnAl/sAeLEcJP7pgD5Xm3XTp9lCAllW6ydTcAIKHQB1eVXTOyUw6vK7RQZVZ+5ScJmioggoFWlBEgda9oj1PyMcRzwWc6uDFDvuW35n/8v/gqbTcP/77/5r1HAX/53/+KnnqNf5Oq6+DP/XOvI//Z/8x1++CefDQ607cD/62//5Z/697/4xn/Ca6+/zq984xv80R/9Eb/3e7d+xk/7Fzcv1mwZ/Uym/4qpXjdGYYj4JGwYVQaJ1jl8+fxkWC6/H9ATI/HwqqmzPiaMkrVtdAIC15uBR88ueHS+4mobCLE0bQWwNdrQtpb5rOXu7Vu8/PIDXn3t8xydnMhwV8M4jjz8+BFvv/0n7HYD3/jGN3nt9de4dXYm57JS5KEnjgN9P0DbcL1aC0u8gMDyuYg8sa6taV9LkTCOuG7O2aIlhzXLecfxYkZXQn1EjBAZfWC92XLn1jGL2Xx6vnLOhGGkHzx377/EV7/+Ve7eusOzp095/PQT/ul3/jlvv/0OQxA3omHwPHn6nDu3v8zY9zx//pR7L31eBrlNx/nVJdY1vPLqF1gsJTTl4U8+4PmzZ6y2A9dX1yyOjnj29DnLxZy2sdy9f48/+t473L93l1u3TrGzJMPcmFksj8n9wPvvfcQHH33Mbrfj+HhOTJ7TxYKX7tzmzoMHbKvljdHSv8XE8viY7XpD3/c0bYO1dloHRpkbg79pVRamFhPrR0D5CozJdvBpSwpZh5XZVf5eHVDmw9pGCBAUQGxfU908J8WeRoLdDn/PVWuYF3++2QeQVD/VW2dLYrzHZrNjHEaGYcfQ98R+TwpZzC3WWW7dmfHujz/kV77+Om++dkq/WTH0ay6vZG9rDKhO1A4hiRzfOkuMsNn2tC5x+/YpwziWIUYo8nsJJWqMkqFFmXdIfd0Rc5rW9fSWlKhVKK/SIp5cTZa9PJX6+PC+16ldhokJqcuQFsQOQJIjjaTLlgFHipF+c80nTxzPr65oG8dy2U4178HNn4Cp2jtUNuHh61Din4MSSUdhbB18TpkC4B7wyV5EwtSnf6uiZxOYr5DQprJOKzusbRzKHqZPZnLsESsBpr97uP2uVlv++Pvv8dabP+K3f/vbZVBXQiBimt64qgBX+S2mev+Fl1pnHKr8/JzQ7H2CdYpCZpGFAMged7SYM5tZYg7T/Y9ZvN6atuHoaMl8PjvobfZs0l/k+qUGwryPhCBR5zmLcXjO1QvFonUDKpGylubHWJqmYRwDw24s/hTyoQg1Tzyu2KsbJgZTjd8WkzqRQChTOgENWZVI9xdeo3zuInNQKpOUeJ4Y2zIOI9YaYlK4tkHnNDERJkpt2pv61+l/VOIbprU81NY2RftvyqGYJwo4lIJAa0xJXvZj0SWiUDZzfSVx7L6AgxT6sQ/ybtpWfrvRxcDZ7QtrkPvinGHY+X3jUv4sFsPYyYem/h0FUSUw0M4daszkFEmDMACU0Zgyme/HwLYvG2PKxCBFSgoJ0xgqIdkajfeR2cxirEw6xlHkoLFGFyd9I7JZKTBxJKuWprUsFg1+9Iz9SA6RaOQ+GwUxjKQgBshda+i3cHSc6AwoawpbyUmSUZT4aaU1KWSwilZbrjYDY59pXMP1epBDOmfazrHdiJxJmzgBKqm836ZpsKrBGQdR/Fr0OGKcNFY5ZcIokkatS9xwY6Y1ZDrD8byjnbUM/cDYB8be08xa5kcd4yiJQdooWV/F0HFqNLQS4/yDwq+GVNy+PScmxbjztKnhtDkmE0tjV/Y2p8ukSO9BosI4CDGQQy7Amxa/pizR4intHeRLj0ROiV3fTwBN7qThDRFUkiIixigNZBBm0CEgEqrGHVWkTXKApZjYjgPrfmDnvSS4QfHhyoTCYnK6ADFK45T+lM9FDZrQSmR/1e0hFPPUnIWlaI3GkEWik9N+aplEFi3F9R54Ckled2WG1d9vnRQ8hwb3h5IhAeb2sqScZD/SxkzJmMbK+0/V/6cRoJgEycvrlmdY2BwxxL3sUFHeY5Fhpr3ZfjUX1WXiVAMuKksxFdZirMldSJOvCMU8vJyOBXyp/mDyOYPEscv7DBUkrxOoek8OetV6z8TfSoBVuZfQNEK7drbIJhcLFssTgvdcX12yKSl9Wlv6fkdK+4baNi137t7j5Qd3eXZ5jTGa6+srlNb8zu/8Dm+88cbUrH/w/vtcXV3y1a99nd/+U3+Kf/D7v8cP3v4er736Kv/Wr36TN7/4BjF51ptrhmGALACydRaFYhyHG14XssdWjj5YnfG5go9qagZkAFhixr1H5YxRWZiKJdHL+xEyGGPx48B6dcVsNseWe7K/kfJAKq3KhFHuofd5us/yLOjp50crsp2U99PKSSKQpf7Zy+zKrLgAwhIgm6d/cvHmywX0rv/0g6RphhDZ7Xq22y3DODJ6X9KI9rKiIXiSD2St0SVyU2WKxFpTH6ecM0MYWK/W6BK40XYdTdPhrKNpWgFlcx1q7AEnpRXKOJxtODleToEU03NaBjD1xJRGV4ywGwSMbawlM6ObdcyXc4IfGLdrXNsw9sLUcY0j+IhDYawt5viabnFEM5+jU0KVVLQq4ZFBYe3mhBXRNI3su7EOQfRUVEviJBMgH4JIX72PImEs+7kt77GCZ8LojfKJqhrsoUhlP41JgdZTE5piLoM3IxPow6kxTK8l5QQReRZCAhUFjCWCSihELl+BRx883os5uBgDN8y6GYvZnDFqXNOSsuJ6tWXMhmU7o20X2CJTrN5ouQwtDn1+Xrzq+085Mg49Q98L6G+MyLuUDHSUsQQvCZ/GzVBKCwMwCpiqqKw3Tcax2UhD88++c0bX/fSf//NeN+Y1n3Hdv7fjv/x/fpG//n/5tCwS4L/5+7/NyfH1T/37b7wB3/72t0k5s15vCeHkX+XlEuKc6/UJ47CS88eZMmgc5eE9vJSA+il7yFLbp6xKEy1DsPgZn2G1Q9ATgyGzG0eeXq355HzFxcpTFZHiJ1rADhTz1rLoGr761lf4yltf5Padu9jCDry8vOS9997nB3/yDlZbfv1bb/HKqy9z9/YturJe+mFgu7qiaRrmiwUxRNaPnnK1Wk0DZmMsXduKz2cSiWj1pnKlxtqsN1ysR5puyWyxQDdLXGvFKHwYSkKi7M2Xl9f0w24Ca4Byzis26y2z2QLXdTx49VUuV2u0maPMnJQ8EMQCIUc+/uQxZycnfPDhY+7df4DWjsvLDa2bYZxjtbri7Ow2bdex3e149vyCp88uePz4GU37lM16w9HRMacnxxzfusef/0t/kS+8/jmsMWx2PZ88esJmXHH35DZvff0VfvO3foerq0uePnlEJtH3O5QWKwbtZvT5nJgTv/nr3+TJ40dyTo4D6/WaXd9zb36XO7dPUKTC+BM28q7f3VgP25143eacSQVEydP/gFICpLm2kfT0gyuFyCEPJpbebM/YgbGwfrUxtE6CrpzT5JjQB+w0Z7p9MEe5cgLf75gdSPbI0JcwBeMKsDuKn+3Xv/4W5+cr3vnhD7k6f8ZR1zHOLcMYi41MxjWOk9unfO87P8CHwKJJfO0L9/gnf3SJ1Ya2ETuFMURijjRGQsRCTGw2W4YAWWuWszlnm63UMEoGAuMoqqJRaTYpQ044K8x022Rs03I0P2K7kyFXSBlrRfbpD1QWE7AYmQCwdHCfa90DGWsVi3mHtYahEfWI+MMaZrOO5mBwE/zIuNsSY+B6dc0szrFmxvX1MNV6h4y2F69Df83qcGaMEi+K8jdi6e325xk3QLzac3zqO+ebAFrK8cbw+vBS8kILaBFQaRC8QitUyihEPWKNQdtEMwZc43CtEwZ+FBunZ88u2O4GGmMPGN5+8hNXRcablCbV/8sJhZ6244kl9gI5QBQHBRiuN+IAQamYQWdnss9rSXSOKWGdY7mciS9tqTEFnzGkfJOt9/Ncv9RAWAySnLGYd+J5l5KkVylIWSJ1rbUs5poUM8ezhs16R9daBmeKn40U3LnKIutKq+iklv/OUJnP8rNTRpsEuUoQpQl0Ey9QlXQiCU3pWkf0iT4FmXEmimFkpB/UXvtermmhVeT1oFg2k3YcmtbhSjFQm2OtVaEtliaiyDmFwSPveb3aEoIwLEIQ8CSmTNe5Iv9DimelyMkVuqEAWXvd+r5JVVoxWzbFezAzxDTRPOt6FInXgadHyuz8wJFpsM4Qg4HeI+lRcrNTVow+lSJbqKCdE4aNyoKAGyveKGRmmx0AAQAASURBVLE0h+PgycP+sDFGYcuBkEuxPg5BGu+csVbje/GaSTGi4YYEUkANwBqG7YBrHF0nD6bfDUKrdZoQZTPud1spwI3FmIZ+E9leB4Yhcn6+w4fMyUlLztK0WCNrtW0swxDYbQeGinCjJsN252wBVRM2CL06BpHcalPAqRjRyhVATcCM2tRYawk20HYN+UQOZGs0KkUaLROzSJ6kVPVeWWOgkcZTGuhE9AGTO5xVtEaSgOa3Z+QkTTZGns96f43RzGxLOKTsRgGjfBwnKaHRhmRFFqiUwmupOMXPQ8DhzTbQNUyMBW30ZKRfP/MYIsMwFGP7vQY95EBWYnRvYpFk+j1DxEfPEMMEgtX1a+p0KQtLLYQIWtILb5Ym0lQaZWgKQ0bSI0tjqeqzqIq0rbIUUnkW5XunFEsUu7yKymzLMQsDTZXPtTwT1liiKp5M5XVWI+sEBUjaywpF4jxOQJi8SRi9pzUHfoda9kCNAABN2+DDKJHJOU/rs457ck70XiaxzkrIwuTDUSjPsYKTShp/XyZ6MfhCzR7wyBQvFXB0DJkU4WQxKwXJTXlWfQ/msKEuVGu5hfJvayzKSENamSTWyqRL0oQDt27fYnm0RAHD9prNesN2uyVn+f6+MMHqZYzh7v17nN26jSkeU3du3+HH73/I3/97f4+vfe1rOOf4+OFD3nv3Xd57710Ajo9P+Oav/ipN0/Dg3l2+/Wvf5PT4mK5tePr8EavVlcjCc5W4xrKeJHgDDN7vgaUQ9oEgk/SifISGArooS1bQpxFSJMdYiKPFk6n4F2ktRZIfe1bXFyI/WhwJGLcf0woDSqkiwVYyTKl/qpADM2dIMs3WmCKpKCyNwhoKMYn1gFLTWq0+WBItDxQgpRa4zhmSvlnCTLLgmIjHiRTi1HikXHwPQ2Dbb9n1WzHoH0UmF6Kn3+0mT72h+EpOwEtMxBwnRh1ZMfQ9KV3h/TiZR1fPrxgjb7zxBoujGc5J89o2zY1p/yFzNITA+bNzri6uODk7prlzl6Y0pDFnotYl8CISjKZbzKhsOaUUTduRrOy/MXi0EUZa9JIIqWVDF7NtsYwWCZHSKJXK8FBj0k2PwZT2QTognl5OaUKS9EgZlphSA8mvbbkHeyaWJFdrbacmO6YCYimFMZKmLT9T7rWeCi75vKfXUu6/1Y4Q8x44q6xUBbkyBdJN0LUybJ0SSZnCEWNhVVjHejuw2fakLMC4MFZlv405gc7FQFtNw0ZTWEkpyVlXe6GUk0h6i7/MOA74YcN87nBHc4xt0OaQkSIsWj/KWgLpHayVIdJstq8P/29/83X+4J/c4V/1evtPfrZ5/SePlvyf/s9f+5lfc3V9/FP/7OVXvkKIkX/6T/4Jf/CPv8YvOqn/rMt7Ix6BZXCitJYG7aC2NNrgrGMcpd5OCEg9sQ5LXae0yHZTSuxSpi11dQXBBEBNXKx3PD5f8/y6py9+ruX/ccagjXzTplG8/Mptvv71r/LNXxXmbwZ2w5aPP/6Et99+h4cfP+Lu7Vt87uWXef3VlzlbLsvAPPP0k4c8efqYxfExt+7cFRChafjgxz8Wn8S83zumf5fauHGWlALjrqcfPMYo5rNO/JFGiZ9JORPLOe39QL/bcrScYWzD4uiE+qwp69isNmQUq+sVi8UCBXSzGTk7trvIzgdU8uyxH8WYFffunnF5vRH21mLO7Tt3MFaCCC6vzoW53LTEDKvNlsvrjYBRBsLVFQ9eustiOWPcrnCN+HMKYPwxg/dcnF/y0p07PHjtJZbLBd5vOX/+jJdfeQWtJRX74mqFUQGjNX2/495LD7BtS7/bshsjF5eXNPMF7ckps/mMxjUk7/noJw+x3ZxxvSPmJCqYwryNKcHE5tmv4wmcyHy6JqmLBHh2fsH19ZrdbqAfRnyx+0hA20j65dGiYzGfM5vPaE3mwcv36YcyCCh11CErVuxzBgbX0M7meAyXF5d4n2jnIvdPOeOs4+pqJbL7IJ6+Ponf7Gq9ZfJEM4r79+8C8Pobn+dHP3qf9z/4CX9HRbpWs5i33D5dcrXa0vjIci5Kp83O04csvqzJQFZoIsMg3thZi1WGc42co1EYQCllxrTlOlywzAvOFvc5PT5iPp/z6Olz0hjQRnpSYzPD6KcaV87g0isX0KmyoSZQN0q4Q9c1WGtonKQT5izKghowUWvixnR0ncN7UY/J+ZMZhnEaAlV7klxkfEpVppra/1vtf52z2NSIS4IAhk2xcAmhDDwO9i5p3T/DtDfnm9vnC8DYjS89WJhZGlNUlB6mwhqqGqCDKJ2cYV7C9GZtQ78befz0Ge+++yFfev1zGC3AYSgDpaTEuzDmEoRV6hTpC0rIROkRKsalS22qABWrL7bag2ClHjx8jqyxdCXQqEo0jc00sw6MK8CXhLrlXIeo9Sb8fNcvNRA27jzWyVTfOYN1oF1hx6RATnWBF+lhTGgt9Oj5UnyhQhB5VQy5yCSZwLAJVdSViYIAVsgDbDLkWBZ7kgj0ZBPGikdTjGCdom0MObvp+9YUK9c0NE7SVurPlu+Vi1xLmkbv0w3PoVSa3BgzjdXTxLA2CUoJCKdsmbBnXSjhAk74MbJZDyLVRGGsbLCmsDZUzpClSRK8S1GFv4eHQEoiK60MGIBu1hB8Kob59c8/fUAoXYCtYtRfp86KLIdNKb5ffNCtkc5csS9WUpYpsh+FOh6CGOIqZFIukrki0cuV+TfQb3tca8FaKZWyKqCNIhWmlqRbqSJtkM233/aMQ4+1hosLSUA8OVmgXUNO4ttGLizFENmGyvST9EoprjKzubDQrNE4MqtrgzUCmvgxToeFRpIeST2uMfgx0nRGmF5WGoimK4bLSSKBZe2L/CtpaZRSYT7mlJgvmgIMKCieWZUpp5XGSqDj3gTZCwsvpESOGp0gjHDn5ISjtpGCvRT1sjYS/SCH1lw1KCtpLzFJs1SbpjpB2evOC5tIV0+qPdW4Sg7nbYPrBJw0SjydrBZGXoh77xmZwIvsEsXkFyaGsiKXpDzvWWeZNqhEKqOMajBZo9ZNMepujRjnWqPlBEj7jXuSW1SGIPv9uDIlxZ8slcmUNFOVvZmKjDAXcOLw/lRvsEAQNlVKGISR5YzEFFcD+mn/0lqepYnRoYo/YvUOExaFL59bjWO/8awWQEwX89gKqk5/BoUZJGEjN5/zQqmm+OeVz6JOeySJphzwWgmTUunC4owTK0VZhbLyvVQJ7DisChSKxjY3/IsMBmdE0irG2sJotcbirCs+UuU5L1Kzk5MTjo6PyDmxW2/YrdfiJWQ0WltCjPgUSvFimC+WHJ2cslwu+PjRJwy9x4fE8fEJZ6en/Oidd3j48ccYayU5riTzPXjwgNu3b/Puu+8SxpHXPvcqL9+/z3Z9xeX5BdcXTxnGUfwllRJZYfRoo4WRi9yCbDQx6skPL6c8NYgVyp0GJKV4bEva2iFzroJOKSVh7miRBsYQWK+uEZAzszg6Fq856n6hpjMRwNrqfDe9RFISg1ydQeksXh46Uz9FClisDp6YnKVBSCkfFJhVKrFPJnzxOkz5tZrPrHByzpzEY0LwjMOOcXdFQhNTYhgGYlZEGjbbDX4cGceBYbeb2EQxhDLJH4s8NpJSmGR3usgOG9fQ73pOT884Oz5ieTC93D9buvaeiDQ4yKQ3yt44fWnOqJxoVaa1BjPrcHdvsVvMyRlsCdOQJLgNqsoBw0gK5XPK8swYW4CdVI1q1dSIA5OpfmXWyt4jzDYl6S9iTq0SeWJcMa09a+2nZCq5vFfnHK4k7E4yoQIoVdlXnbyLHNyALowzlAC0jcFSpuajp1gpCqCmxROsss0OJUhSF1mylnpGKwOleO4Kw8/7KIblhS2rlYQkQPGdtbqkjgIq7U1dyDKMCyJnNOUZ8+NA328Z+q2Y7RuQ8k8Jm7t4JILCahiDBCIIACzns4S9mBumyP86QLB/01fTPOPu3RnjOPL06Tk/fvev/QJ/++b+fng525e6OOxZGlXmrs2nnrFU1tp8eQw54cdeTJ1VBYEzIWmUdpB2+++pJRDrejvy6HzNo+crVpuREA/WlFby/Og6FE585ctf4fU3Ps/J8TFKKUbvef78OT/4wY9498cfMOta3vrKl3nzS1/iztktnJX94vr6mvc/+ID1bsMX3vwyy5NbzFJAWccnP3nIMIgn5mKxZLFYyHNH2bsRLzA/jvTbnq4xdM4wjgMxZrbrFaFtyz4v7GuVIzF4QmHpyN4pQLsPQYZeXoCTjz78mKvrDf04shszY9SMQZrptth5+JjJ2rEeEtefPIMSMGQbR/CyL23WV3LuagHC19tBakIfsa3m9q0jzm7d5vhkSescjx895uj4GGsdTdNx93bDcj5ju9txfn7ObC4gXtvOcK5Fa2FQnZ0oPnjvHY6Wx6UGkaGc0Wb6tYSMGLI2JKVI2rDe9RwdL3nj629yfXXJ4viIi2fPZGikYLtaFaC6JnWHMnSST2IvgZZr6LfMujlXqw2Pnlzw9PkFu34U9lUZWJDztF/MWjH/XixPePXeCVop5l0zDXKjj1NPFOqAIRsuLi45zoYxwrOnl1xfXTNfzvHRE3xiGAeu1xt8Ybydn18xDOKXu+tFmWKNAB27XU/e7bh39x4//JN3ePR0xWbX8+YXP8fVasduN3K8nHN2umAx7+j7kQ8/fsYnz64Zs8JkSGQkUTwyn3fsxkjjGhonXs8phskyI+aWTMBZYWsNw0DIijFkKAPYrpVh++X1imEc94V13lcHQggoXo7UVElhsmQVBSOwmlBr9lKzQsGYlAAqXaOYd4YxuTI8EYslsp/8NMvTPw14PyVlrWxSpdhsd3gvKiGUonGO5WLO0XJJLCy6sZx9Ob/omXa4H/7LX7nYhxx+86DEe1nedy52Qi1NY2kbkYxeXFzz5Mlzvvj5V9FaSaDHbkfwoQx7Sgs0VW9Sg6oXBpTSy0dQtty3co8KMaACi/v3erB/FxuEjAQwzWZinVFxlJgq6Khv/L1MJuafLf2v1y81ELbrPR3FAFMb2k5SRcY+FgqmGAxPrBYl00bnpKgbQyoSHzGjjxGUTsUPKU9gDVkYNynmCRwzuvgDJNmcfC8JfI3TuJIGl3IkBAGJuraaRorvzhgTrpEHE0DlIvejLA6t0DrvH2hdFrGapNLymgqq7ou5t8gxErYczDnvDSRzhn43st0MDEMgJWlMTAHTus7hGi0meko2lFylTmWy7kOdkIukJkYx+W5ai/exMM4Ks25CuuXn63LztNpTW42RjakmUJTytZzV8vCqMqVLuTAbSuFdWXB+lPSnELIkHA4yUa0Jfq5xdCXNTGSEUgBoLWBe8GUi7ffAlwBzskEKKJUm5oVSQMy4Wvh3hjFBazTaWrpGpjApJPrNSL8bsE6M1tvi3+Uay2whUwqtFcmXRFGtUaMnRl+o3KlE3iuCj/hgJ8ppCIl21qB1Js8lhSwGNbEWtRa2nFVSwNcC0Q9DaXblfWtVWHVA1CLZy7r4qxV2VRgj0SusbVnOZ8xdx8I2HLUzTmZNaZoSHl2SzwLkWJpr8ZaJxQi9Jt1prSdvmgrO1GKiyu4mtlNZdzkL+NvYhq6VhtwqAXKzlgY5VHaZFbq7j35ieeQKyByAS5SDM+UoU38SqCwShMaJUX7OGDSNsXSuYTkTP76+96CLOfsQpyLITP5CU7tPbfDl3wKESSJRmhrFDMQsUd0UJsthUwnF50gfeCLkKldCiovpOdr/7MocSTA1t/UrrNHgbLlHBmX05DEmEcXy2ioLtX52L17Vo62toECKEEZy3jNkFHuDz081qdZORZ5OGa1zmfCZElZQKdDC+Dl8HdWLTqtD5qwpTI99Y14N4m0xP/fBY5xhOV9yenaKaxwxBDbrNbv1mhSCNO+tNO8xjGiV6dqG+WLJ4viMISb+8Htv8/6HD4tRukQ8Hx+J+fbz8wuurq+5fecO3/6Nb3Pr1i26VgqKf/yP/iEnx8e8/NI9co6s15fstmvC2BcpOGStyCmQk3g5ivxLvCqN0cIEywcFQN6bilurmWLCy6Syet3l4utwI9GnAroSrTyxe+vEWCKul8I2yiDG5AfrwhgpWMqzlbOiGnupXMGNIoOsq7M0YalsuLqSyMjU2q0+NyKvK6BdmYhKU8v0TE9rqhZcL15KJMeNlWYxOKCEKsSUyMqSaBi8pFh6PzIOAzGEAp6N0z42DENpiARkVyjatiXmxHw25/at25ydnnJ0tCzsywNJqJbnvf7aaM1xmYbXIYB8ZqXMK+efsQZNi6Y+m62s+5RRxmC6GSl6KKBKLs97CIFxDIQYSVles9GaEIW9mWKYGjlTpLIxQVbCoky57gPyPlq1QBOm87gm9e4bA0k7TElhkxhaWyvMq3pNrIYSCFDXXz2r6pkLMnDTgsnLfSuDTaWyDIrKZbQiZUmzcwfgiFYaIU6X+q4Aa03XMpvPsM7Sj5Gr9Zp7t26XoYCcJ5FYfAXreyurPlcWmtyDlPO0uFNO7PodMXr5PBBZW2X0K13lIXKvu8bQ95I0Wp9FMTiuQL7ipZc2PHq0+IxF/d/N9fqrH/P+T175zD/7nd/+n3F19Q1e/dyrnJ79FXa7XwS8++x2EGC5uC7Afnney3lnrBVwo3xdTHFiTNWG1zViNO7HnqTEi1ejsFrRom7YC6SUGELiycWajx9fc7nqJ7+x/avMhCIltkbxla98jd/8zd/i7p39e728uuKdH73HH//x98kp8/WvfpmvfPlN7t+7R9MIg6nvez748AOu1mvmiznz5RHaWjSWpu1AKa6vV7Rtx+35nLNbZ2glklCR/5a9xzlW640kMqZE770MyFJiHHtySUUkSZ1njfhBaqOKHKvW6xo/CuD/yccPub5e8/xyQ9SOi6stIZQ+KULUiqg0eRt4crHhn373x6QwcnxyzDCMZL9l5iJ3+54jP1KhuxATu2GUPas26mhs0zCfz+jXax7+5CFoy3Y3stuN3Do75ZNxADJf+9pX+do3vs7y6JhxGNEHNhJaa7bbDcfHx6KmSXmSKYq9hCpsIGHWj0kCp2JJmT+5dYt2PqNpWp4/eUoYA8e3TmjaVsKxSniJ9yNaQdPOcG0nya5K8fyTD1DGMivgY4yR6/WO63Vf0gvl9UQvctfcR5TK9DtZY4v5CfP5DJD9rG0cSVtUA2HoSSGQFazWW64uLzAqcPv2FRnN5nrL6uqSTx6N7AbPrvds+55hlPc4DIOsAyshE6++/IDTszMWyznLxYKXXrorP7Pr+Kd/8I/ZbhJNCHz8yXM26w1awZ3bx7z+uXvcu3XC42dXvP/wAsqgWJee1SjpcdvWEJNlrM+WZvKBEj2WQyl5hkNInF9cC9OoAEdGa46PFmit6UtQRIgHdW4dtGg1gWBkxC9LKk4giuesKoomrW4oqeXYkf3YRwn8ClHqjXr+WF2kxXmaXE2EFQlksfUb3djBRh8wCnZlaGaPDF3XcHw0Zxw9/dBDOARs/tVAr5955cP/zGXYLvVW10qvs1x0bMaEc9API48ePeHxs3Pu37kl4RzOQRnoQnnLufxHHfKnOFlFSdtfB1O19zqoPXPptVGEJKT1QxVljJG+31Jz5JtWUnzruVmQDnkvuXoXCyiXXjQn/ynXLzUQ5kPARk2DQcugskygRe7HRCOOU4KhTOsUprCwxiFMJtyuAZsVNurie5GnqawxMjk1RhhU2sqHpxBvppwjtrGk5CArtKHomqXptVbTNpYcxd9LprHlwSyLpy5SlYveNeai25ZphChEBFhLxQxfGgLwPmBMlNfn5GEXEE8RgwAkKUZ225HtdiD4KGCXYnoQoDQ7RqFM3QSK11WRNY1jYNY1bLZiPg7QzfaG7QMFvCoMhKxryhST9KVK5WIQP7PNqsfq4ntlxKw4pb0ZtCqbl5qeKtn0rJMGz4dQwLxK+fZYp8Vo31maxhXTfZEW9v04TW5zkp/rnBUGgTyR0nSjhAHii8QCAXOaxmGtQluF0xnjmvL0QtO2gCLHQNaRHGQtGiNb/nzZyiasJIRAmzJ5B+bLDrULwuJBCSsmyIafyJBEemSMALApSlOpTGHnkImxNH9aoUvKilaqALm+fNipeCuJdC5n4dgpJUy4GrwSQiJ4SQF1rsHZhuWs4exogTOarnHMnCkGsxpP2ntCKS2Hd/FoijFNE9wXtfbVOD2VxjvEUtiV5tvZRnx/UpiAWas0rXHFbJnybCtQVVpYWDFlfSf2/jbVsLsCtdpqImLmmcpzaSqDBkQ+FhPaSLpm1zjaxhZZj6yhvh/o+x1TSlqKpNQVVoGq3Xxp7OIk46zSoZwzylh8Et+Fel7FFEWGyF6KqJSemDKH7YIuwJsACDL5zZM0qfIaoDLrMrKnNc5MU+mcs/gdlmIiq0wqja0u/l612HzxEhmRoW06YdGMw/7rsoCFtUg5bDj2f1+kXxlwSkFJ3ZtSgZQuH2Ykpr1xrawji1J2aqC1FrC96zpa1wjzhjz5INUbLF5gc05OTmi7ltVqxXq9JgwDmkzTttjCoAmxMBxncxZHxxydnDLGzD/753/Mw8dPOLt9l+OjI65XK549fYYfA/fu3KFxjXiAaMXR8ojjo2POLy748Hvf5fmTx/zqV7/I0aLj6uIp/U4KzbZpaOTBEe++YstY0x+FuSVNvYCuBUzOwlTyXp51YzqUkpRTyuSPnLFK/BwydRJ6CCLJsCDFKNHiKjH0PSt1KQ1+inSzhaSOan2zZdWyz+my1iNKfPJKjZSnec4eiJU/lCRj8l46TM4Hz3Z9wnMxGRegQdVg4vJ81eFF9S2b/nau7dfBegO0tRi9nH5PfoKkT866lphCkQbuvTtDYSuG4Kd7HWPxzKspmwq6tmO5PGLWdgL81ueS/eRXJF5MYOBisZR9OKUpWbK+hVpQ6vKcERMqZkIaREZcAJmum9HYBYYsIFgSr6rgA+M4yj9+nJhtKQWs0YzRyzqqXx8kuVEYmrmY04u8RViWko6nVNk3dGWtyk5jjMNoC7n4tVIGLvpAul2e4RvgvJKCOSeRS+eU9uEfterOtZaQgIIKWqUsQQMpC9BujBEpedk/kir7uZK9WxlN07bMSurUMIrnWtc2hRmH7KOAUkI9k9NYGGDV6LlW9kopdAnpSSng/VCGr6Ja6DpHN2sLyzwWNn8JVUD80OTcs8U/TqSkWmuG0fEX/vzH/Kd/88uf2jv/TV/WBkL4dLtw/+7FZwJhd25fcu9uy/sfvM+rn3uVvv9T/1pex9HiCbNuCxxNdQMAKQljW+tpLVVJ/sRqD6MAitZhcyaGUcDekNBZ0eabZ1LMicvtlo+fXXJ+vWH0+3NZUfZkrUoKKTy4f4uvff3rfOmLX5y8ANfrDR98+BHf++4P+PjhI95843XeeO01Xn7pAW0rMqQYI0+fPuV73/8eu37gpZdfZjaThL86YAwhsttIOu2tO3e4e+8ucfCs1ythscYo6hClWC7mhJjFciDH4suZmRITlZneR9M0HB8fcbSck9LB/qk0m9WaxXLB1dUV58+veHa1ZRc1l9drYkwysEsSJrQZEl57Hj4+JyqLJXJ8vKYfpYm9f6vjtdc9m76ny7Db9azXm+lc1CV9dSzy/hQCcdix2+14/vySJ0+fo5Tm/OmC68tr2bti4s79exyfHGOnM16uEAJ9v2P042QNUhtkW7xOtZGhX91vx1HWx9iPxHHEaU0KHj+ObNYr5sfLSaKlEmzNhs16LUnQp2dYJ7YIKMXqyUdkpbBdx3Y3MBZ5dO0vpP6jsI2AXAax0dMWy5oauhGTMPgk4MyJJcfQM+4GLq83PH7yDJN2RL/DuoYxZILf8vDhExKG9c4zjPJP9WzUGtrGceus49VXXubOvfscnxxxfHLE6597GWsMV+sVTWvZDZaYNevNTgZhGqyzLLqOxawtNTWgLZWhJQPWAjjHTmqU8kypOtwpQ0tdhmNaSX+2WvUid3OiJMhIPZQpigU05HAD1FFQGP/SG0ufI3+mlSn9ayqGAJSapHhlaoV18tqrGkdwqcJMVuLvrZUDZW+gNIqEVqLmqkCbDP3kMwNojISs7XoBlpZLeQ7bxpCr768p8sG09wc7rF+yqvmaB2+6SEMn3GCqqeo5WgBgKa9u1HoC4O3ZdAbAZDmfjSMzknxmCJHnz59zfnHJ3dtnGGNoSvp8ve/7e1HALqRGLPCEECuymn7+VGcqUEaASpXkbuecb4RBVEVMDGH6YfUsP2T9SuURSUkVjERgsM9oMz7z+qUGwqJP5FYYQ7p42ahczOEbKRjJMA6RYSwVs5bGL6kilSzpi0qrMj0HkzLaiNl6qS1LIkb1lBFgp3qKidY5FY2qsFp0kTzUGHRKExu9pM0En1AqgZIUoZQiIWdA6PrBRzbbgc1a9OQxVrmYFFoa8S4wOuOSNDnaiM6+emukrCfvsxjlPmw3vUxpsimHY7lPiPF+2xm0sWiDyFi0gCjSf+Yix5MF6L0UbcEHMf2PYuwOpZiVTlpYWU7TtpYQokwIQiQEGIdA7HuclQe/m3c4LdMokYNmkRO0hWVXJke66NnRBlfZEKVJE1+hYq5nRMogyVECkvTbET9GMom2c+VgNLSNYqP89HmLL4CAKdX3RCeJ1m1mFmOg6wyuqw2hmlL1VElD0YsW29jJx2X0SZIpC3uumuUbq+V9R6j+aHJoiTeS/Jae9uDgE1onhl2gaQR4da2hUfXwzJPEJeVEDoEYC6XYMDEcd6sR40Tq6JwYv7oi/0hRfrbIjCydtcwbYUnVjbV1n5bS1QVQY6irmfeQ1A1D1lilt0pkbMoU8DNlwujRyPdw1jGaZtLYqzJ1SnHPoqxMi31YQy7rQCZ/OsuhIal5hfVgrYCjBsZxb4bZWEPS4ttG3ANVtgC6KBjGUExOA8ELaDCOnpSG4gMQCD4w61rRtBePv8nYPJVjrawxgERkDAHYJzKmlAoQRun/VAn5iISU6KzFakX9vyK7P5A+7oEwhZhvi8GvTFNqsp+CaUqXMvh4kBSpSgKg2gNPtfGvD55Wqpwm+0TIw5jx+vrIyH5YrlzRuWnZKJqmJYfir8b+AKwAikZAkgrOaW1QyRAyONPgSrGmNLgig9SFZqSKTJIssunlcllkUQ390HN9dc12u6Vzjrab4Zqyhoufh2vES6Vp52wHz9OLS7779g/5xq9+i1/91rewxuCahu9997v84HvfZ7XecPfObTKZZ+fP+f73/pjZbM5msyGMPW9+4RW++qVXGPzA+cVzjMrMZh3zTqS34zCQgsjPxKtwf09TjCQfceVzG0vAivfi4TABANqAMlSqlVK5BF/U+6+mvXUa1XHAikX21V0xkR2HgePjU45OTmna7sbzn5QURBpVQOIKFuyLuEnUWECE2gjUMBdZF/uWs34dUArmMnHO5gZAS332c2GOlXVSWSO1qLqx9kDuy8HPTFmYWjK4tvvXwf775yKzjsWLas+wLMV9WWfOSqJs3Y8OAWRdnumCcE3PJ+XfNxltqYBDktaYoviOhGFgs+vpR88YM9o4To4CdjYT5pjSaKdQykEJEUs5FeaDgHnSlJWpawbvR0KM5FJ3iK+an4Cw6kPXOAsm46YwqeJBFISp6Kx4ZCplsSkVKYoiZtkD6/S2Mg1D8PJ5lvUWUyYV9jCFWT41tGV9JqOo6cYijy8s+lRYdhisPjijVJpA5br0rbNTCvP1esXx8oiukyTZmkBZWW8HH9j0Lzl7mKRqSsnZ1A+9PL8p0swaGd50jrZtynMsgJo+eP9WZQk/0ntWrjBaDP/j/+m/y2732emN/6avEGwBPG+e9X/y489/5tcfHe2Yz+e8+/57/KN/+I/4/vd/41/L63hw74dy/pdBntNG+B4xQpImey/nlSFqZWJCxvtBWDtGzgydozzvZXBU0XqlFNth5JOrK55erhh82HveKtAqCwNbK4zSnCyO+eY3vskXXn+d7gDg+snHD3n7B+/w3nsf0jrLKw/u88qrL3NyejKd79vtlvfff5+3336b11//AkcnJ9M+kHNivVpxfn5O3/e4puHk9JST01uMm+20v11db7FOFnXXNlJv1EG7AakpyiCreAiLp53h7PREvAuRZ0lqBlHBGGOYdS0hZYak2A2B0UdqyIYc+4mh3H/vR7a7kUXXcr2ShMCPH50z6+7TB9gMI7tBvIcur64AeQ2dlXT4riToxhg4PT1hPSiePruYLHD6XlIOh37g8eMnPH36FF0kjodXLv584zCIp6Pa798CkErtdePsqgNaxBJgOiC0LmFYxZO2sOMzmb7fStCZ1qI0QUDstusY/V4dE2Nk0TVsuoaUBoYgw1X5kdK4alWPscT1ai2AVohYawgx4WKQvsZZoMW2A4ujBXfSXYb1uQAPITCOkXGM7HYDtpujkBouFj/QmBL96AkxM3phCI/es+sH5vOZsGiLdHSxXOBDYIwekzVnRwvICR8ynzy74uJ6y5NnK8rCmu5Ztevp+w27voWqdogica8etBN4ogCjyVpqT50zmMLwUvKaJx/h8hmkA+Ba9n85c8bsieEATMkHssACNlXih7aGpnHM5h3BR/p+ICgmAoYq4Jb0hAdb/uFam+Ck8kxoUTTUkJdFa+l9KPuPnHGVeJlKXUAFrcowr74nXYC1pPbDwBd++P4/MmgShur7ZVlvh8I+roE3JQm62pywHy6lnAk5M+6ChNJF4VPtdgPbbQ85l2TcFmutAPApCX6RhWwgLkriyX6oxJThpEahi7x0P8HURuqjPA0yX3iPn3EJueSmMiVnGSrGKIP0nCWY4Oe5fqmBMN8H8rIpEkIBTJRStBiMg1zSHePWs+ujyP50mXhCkatRGAcyleAAAFFafE3qlVIiaSUSylKMp5gxZTHlMjFOKWPZszcooFuOiXGM+CQfUlaZwtqcdLACmDWMY2S7GdjtBgE9AG0NrlHMZhaFJacil/MR6ywmy2aQgTCWCPKsShJWmqa6YtJdDo7DB6lWh6UxAUFsXSPgzjhEtM70Oy8SqM7Kgi+Sqhjk/Y1DwI8C4qBVMfRWdJ0jI/4amzHgnGYo6YwpJmazBuOs/Dyt8IMvzLZqpCuJnX4U6VpMezP7oZeiXdL4jEhWDyZBKWVJIfGx3FNPN7MlbEAklH2fywGgSUOQ4ifl8hqEr9m6lm5umR85jFF0c1emjhUN3yeooYRB2FIYGSnjjOjTxyHgBy9m4laKOquQ6UiRNDZtUxpbYe+Jl4usuRCiSDZiYrZIzI5kguysEUP7UrinlMjRg/LkwgFRJhNIDNvIuI4cHbeYBJ1t0NbQtZZ529G5hsZaWuOwWiS93sv3QQloZo0ATLE2muWwkWZJFwkcAgATaMw+xrcCEgolkwG9n8x5H4hEnHZoZbCmxeoGq4vBfwFuQzHcr4eiLl2OdXZqtOoVU2QMY0kwtJP3SizdfspihDxzDQqNzkXuWTbVCqwPw8i6HJokipy2Aj/SINd0nJQTIQUBPJHPzRdQqqkABAqjncgXShHfWCMNYS5eSQWjGGNi58UEdoyBZePorBHAR1vZ+HMurbeAJVUWqgvzVQ52ORzl4EjFe09+RvEenbaGCUyZ4CyND16a2fK7jds3aIf+bLEwUlDFBzAJKF/3nOrRcnheuaYh5syo9gCfTLFEHqaFMlR8xjQqW5SSg71tO9qmLayhKttS0yRKlXXXtC2LxZxZJ4bjm82G3W5HCiJFrY1IlWsprWm6Dts0ZG1596Of8PEnj1kVf4c/++f+HOfn53z04Yf8zp/+0/zmb/4mnzx8yNMnj7lz+4y33nyT88vbXFxcEIYdx/OOV954jS+8coazcLXekbNivpgxawyNazFa0WvxGcwFHK2G+TFG4himgi0WYFWVNaxykaC+6JlT/q2UQh00tUopki4+g+VMjKkwiio2RsYPA9dFIhhz4vhYwDBjDKEU8qb8HJWLfEnnSfou72MP9CoFOR78TCoYVV/YwcKgTE1VATvUnk16uPZqJVk/83xYMOf6ffJUcOWUCmi3nxbX5+gQMZmKuvKgGMwLniGfviYfrLyXZssrqCEo+2dhet6UhMEcvveJQRo8PnqqrGEYdvT9wG4Y2QwBnxS77ZbrxsqQonhLNY2jbVuapplSUWezGTFGCRgon21ICT8OgGIYR/EDiUmkViXRevReUim1sCQFzHLE5ImRKTwoN2pi5h42PUz7y15eWOUUYkdhSMViAbV/fgUMNtTAD8iEIK8hpiSm5RV0LEzkF+Psc5koaCWMfWNsMd+1DP3Abrfj9q27NI2TAI8k0/ia7lnfgC4AlQSJqL2HqwJiZhwH1qsVm+0GlKQ4W62xuqZca4wyhfVRQL0Y0TnRNAtUed2pyPtibP47A8Fu39rw/HyB1od7t1yXP8Uo39oLLq4usNbw5MkTHj70n/l1v+i1XFzinICJXdvitEYVALY+94U/vZfqGoPaC2pJqahDSl1Y+66YJaGOGIgkHq9WPHx+JT5WEwHFoFUug3fZe2bdjDff/DJ/7s/+Wd588yvyvXNmtV7zgz/5EW+//Ses1yte//yrfONXvs6rr7wiQCswjiMPP/mEn3z8MavVitdef407d+4UnFUCbT7++GMeffyQsR8kPdzYaRjcti2jL0wm77FKM45jYVIWUEJN6vTpLFAIcCsBApJWWevk4IX5bI1BaWi6hsEHAhaslvs2zTIq+1yV9D9DVOpguJLY7HalD5K1vt1t8T5wenrKSw/usrm6prOWtm1YHC0xRmEby737r/Ds4kfTGWytBL3oYqsgMn3LZr2eGIGVRRtLUr2EBMhZUEFAORf2bGh5H/IMeu9ZLBbTWooxEryfBt1i4VAYLCkyhmGSnIIi+UGsE7qOlIei1NHcOj0pLBzNM3XNRUj4MUzrWmslIRrKsh0Tu93A6CPr9Zb5YiYgf4ro5MlKYazi7p1Tzk6WrK5PWV2dst2s2W3WZCWhJCllVEw4FBhd/FeL1DvJeTOMgdVmy/Gpn3xZQyiJ5cbx0oMHxDhy2Qd2fc/gZ7SN43LT8+h8xThIwvlujBTxClqBawzdrGWxWDKMXrzYsqg9UjpIJFZ6r/QJO3keDeQIBFGuWGunZM2UhLyirSb7eobLs59SRCVho49xLy+vPf1U0ebpf7DWMJ+JL1YuLGz5rKX/33tzK3JxwpJjqfZ7SnrpQj6RpZ8FOC2p4sZoUkgYq5jNGlwhZlyv1qy3u0J40OV83dcBKaUi9ayvYP9c1eumUqTWdfKwG2MYfKbRBlvWfAjikazQN87kjBKfPLKkSh5QqcYxcnF1zTCOzLpOJOjGkHISn9Qs4Fcmi92DyiQfJ0ZbDbySLXqf7bmvnPb1+YvX4budBsAJxlHsEJxVdXZBjJlxLMQCVWyQ/vsAhIknh8i3FK54T5V5s9bEIMyZEKWZFBmUwvtELhOP7XnP8mRGN2/RRja+oR/RxdsrHHgCyLQ0kkymbW3ZPPfoNuQChCViPEguKBTGFCMhqWJ2L19vmoIdaAs5E6OeVkiNFW2KyV/XWZrG0M00Yy8/s9+Kof44KPyYibPCDhgiKck0zDnxf3JO03aNGHTHAnGbWmRnnDVFasAeoCiLVFgu4n8ThkC37CTFMCYx8w+xTFrVFBE83beU8KN8zb2Xjjl/vioPbGYcPE1rIYVS9JZGtSnG+eWfEMQHRmmFcwKujGOckoD8GKZpGJ2ALWKOKAfjMIz4MeBH0WmLf45sgKn4IAVfAJ5S9NZDoVEO04qfQjszzOaFEea00OyteC6kIGBnLtMxyNO6iEVeabViPnNcXW2J3kgqimpkKKREqiaG7+CcRS062ljTOwW0SDpNU32lMtpqZkcW5yyaPNGPdd1cUiqUV4OPQvMlg54pFk2DSorOWGbGcXI8o3WWzja0pim+T7Kh+CDAgla2sCIVg/cTnXffu+aJCs3EzsiTJKYCJV3bSWpjmZjVpkm6UmGoxBLo0FhL6wytk/U5joHRezIlya+wy5qmEWNUZfcsjTJ5HUvaoTamGDoWCXKIaGSyO7OOZTujM24qFPrR783sc2L0id1uZHW9oWsbFjMpatu2JXgxvEbJNCuS2fqRPKZp2hELIBMLwJQVNFm8RoboyQVoN1oxJpm2+pTwUajKw0E3MkZP5yxL17JwhX6ecg272Tf8WoORNVB9D0wBzcfKzMtZpoqYqQGdwILyGVUw8NDgH5B9a9on99LXyoytBXgM4rdTt0Y5vfdsHVVAx9ro10uVYt6UAso2AmDLPmKxyuGKGWvXtqQ4EqP8fFOKm5w0XduyPD4pjUhiu93I3lCKLGMMczMjRs9msyHGwGzWcXx6SjdfsO09P37vfb779jsopTm/vODk9BZvvfUWf/Nv/qesVmsuLy9Zr1ZkEFPfywu+8uYbvPXmG2w2G8ZxRCmYzVp0XLFabVFkMVRfNmjJ9UIhbBU4lJKWgz/tgZwYa+BCJudI13QkKyBjZQDWz1A8nPbG+Xt/KjNJ2qGAMUoAVVUl1GR8SIxjYB2uCYNn7HuOT05ZLI7ZNYYOJdnCtSgjY3IWVmNZY7UhqcCWORzm16nttDb4hS5VmjC1/w2qP9Ah2jo5yZX/yRPwBSpV1uEe9CqTDcg1eCKXZvAmy4uDfXB/z6tUo/5JlsJZH74/NTVTE3Oj7oXk6XMKMRL9UIYvTnxxtEcrhVOZPkSuVp4tEWfkDNFa5MCz2WzyzDLGYF0ZBri9pBigaVratmOeIvP5XFaitshUXzGOI0MvSW8pJbabNc4YlLJTIlgNb4g+fkoKv2fGyQQ61sTNJBNlkZdXf7BE4c5hC3NqMgnPkLP8rByFsVnZZeI0kackzInJRzmXdUmgnnW4RuqF3XrDsuno2laSx1MZtmkjjRxqMlkWtoyA+JCl+dBM0pz1esV2vUalRGM0IUlNkJPUnlkLq8+1El6QU2boe4L3mPkMlC2sYs/v/oOv83/9G3/6F3sQyrVcetZrx//hf/+P+I/+49/6l/oez88XdYX+XF//5S895ujou/R9z2//qT/FvXv3+O73Pvcv9bNfvF556YfC4Og6GuvQ7JtrkDXW2IaQpNbzwU9KD0U9Zyq3ozSyCNjYGDsFfzx5/pwPn17w/PkOP1SwrIAmxT5CGUPXdnz+c6/xrW/9Gm9+5assj4+AyG63470PPuQ7f/jHfPj+BxyfHPONb/4KX3nryxwfC3iYUuJ6teIHf/JDVpsNr7/2Ovfv3xMD8mGEnLh4/owffP8HrDdbMdg+Pi72GxQfYV1AWsNms+Jk2QmbiX3PnGFi5ea6pylVwETHYjHDFq9JchamVIbry2sWiyXtfInHEinATS4AcRYSeQw1jdKKt1DKDAnmRgzdu7ZlNwZ8zIDh7NZtTk5OefDyA95554f843/4j7k+v0bvel753APpUWLi5c+/wY/f/YjaKCul8ONALEDdZr1hs1nz8quv8MlHPyEGz9HRApShH3YslkeM4yhnnVETC6faC+yl1mKjYK0VqWZhXYP0g94XEFd9uqZJOTEMfRkGADmQgtRWjbP4ogroWsdi3rFczulKf5JSYhj81CvlrAlazourqw0/fvcnrO6ccHJ8xIP7t+hipp2BdqIAkiG9ppuL19RiccT5+XP8xTXLk46YQIeEjYnN0AuQoyU8qg4TYlEsjeNAv1OM45JdP6C99DbHx6c8cR9jdpqoFE8ur3GmYSgEjBQR5loGq2Uo7FzDbD7n9OyMs9Mzrtdr+r6fhqNJSRiDeFQeDCpUnMKukgEd9sxuGTAnofikPbBZEyNTjgw7z3Z3c7+ofpcaU7wXKxgmfbuwlvXkDZdSns5HpTIhbA8GKVJfqQLo1kVR64j6ZXJvM1hLGANKJVGGFJN8rSzn51eknErvafYyxYP6JyN1tpJvemP/PQTL6gDPKE1SmlCslUKOdPOuvnKUUeJjfTCQqmKqCITyXVVKN/zTYkxcXl1zeX0tjE32aoEYAhHIlVhTXn8iobMQi3xMdK4QkGL9DA5re/Wp+3mjhqIqXDK7fmQcI9qI1UIqqjEZ6Au2A7I3to377wcQlhP4IeEbYYb4IeGcJsSygJSWgiYmZjPLdj1iBj2lEQafmC06kc5ZjWuliM4l9hUlPk4pJm7WugJUdJ2TBWoKsKVVMaUcSaFENU8PeZGeGIXfRlxbafyUiaFGtQ1hhBBgtxtJOXHr1pyUE7PO0hZzfWsMegmDl9TMzdoTwiA+AjtwjZ0ecFQmpzAVg0pJc5WjoO7KyoTDFLZGBW+mSYnax4T3vefqsuf0pBOpYNNA8NNEaBgSY+8LyFDqjQIINfOWpjUYo4q/Eaw3AyiYH82KzKUivqlMq3RJFlTEmMtmgGxiWdqb4D2jF/+TpnXopplkiK6RA2OY2DkFZlFM0+06AcgZ0EkOzNKMS5PgcM4wmzXMZlako01JsVOqNDSW0O/IKeI3mWTUQdokU4qm1qCtpnWG22dzARB9xChhaWVL8e2KGA26s3RakNIcBGSNPjDsRFeeCiPMh8B242msJVFTQPS+Wc4ytZ41DTE7+nEgpUy3dNxZLumc5XQ2KwwFjdNWpHMIiJly3VisyIrTPpnQaQMFNBLmkTRChCC6dq0lcaeAXFVGFJJIc5qmleKrNDyTaTYVmxHq/LwTLzJrxB/LewHI9qyvTEgJW0z2b+wTtQAuDXiMAZWLz16hEbdGJExz1zErzaIqoE+ISaRCSGGnlJq83VKSSOe2aWhLso3JbvKeAAHse+8Zg59khlkpdikxd2DQbMIg8tE4QtaooNEWNj6w82HafxQaeyC7HmPGR4+PkpjZFmluLNKpmBMUJkVWSoxA2W9LxhhCSuiQBcBDwNhp7yrjlpQSPouRc2W6HQKNU2NRfm+SVVpT7mVhy3GTzl7NtWMKxBgAJdO/KP/Ur6s/owik6IzDGYe1joxD5WrkXiXUcf/zjaFpWrpuznyxpJvNSSlyef6U9fUV4+iLibWsmxACDx894uPHj7HW8dW3vsKd+RFPLi/53ts/4vHT59y5/xJ/+s/8GX7/936f58+fsVwu+bVv/RrPz8/5oz/6Qx5+/JCXX34ZoxXDbku/XXPn9A1Olx3jGOjHgc16JcbGY+Ro2ZbnNk0gWP18cs5QJMqmeLkNu2GaeqdcBw+ZjHisWNNBnfqVSi0WU2cBBqt0UIDLUCQLlM9EgAJ9wBQUEEyYzQKu79Yb/DDQb7Ycne44OjlFtR1UNmYB49MBuCav5CbWdYh2WSvsGjOtPabXxfS395P0n3Xtgfn6M/MeZJ3+TEFlX9VC9sb2oQ7+VxjWe3lklTwWKVbKhW09lalU64Sy/VB/ulJ5AgO12ie5GmPZv5h0MEyQoZ/WmmybaUC1WB5jmo7tbofZrkH3rIfq6wnz+ZzlclkSuYQVPZa0sMpqr4wtUwKFNIq27Qpz1ojBfWPp5gvariPlyDjMIYm8NsXb5Ciyj1Am98Mw0A8iYappprHs+ZQ6JMYAOYmhf9034l72mQq4ZZ0udg1mamJBMYy+gJFqWh7WWrpGiv8YxeBeaVU8G/c+aq6xtPMFJ2fHtG3DOIzstjuapqVxlhBEtiRA7R60zWXNKK2mGkcZjS3nPUj9lrwnh8CscRBb+pwL0HDIYhTGT9POwSBDuhjI4w7liowoR37/H3zpxqDh5720Tmy3UuJ/4bXVL/z3X7xC/Pnahb/2v/v/8P/+//5trjctR0dHvPTSS5yf/+tJuXz9lbdpm1M5a63sfSFIcMUULFMG2tXTD5NKaFOG7BF5pzzkxiiSD+XXco/Xu5H3Hj7jkydrtteRnKXpqpfWCuc01jru3bnHv/Xtb/NX/kf/PpAxWvamTx495Z/98z/iBz98h2G35bd+57f5xje+yb1797FWEp+3ux2fPHzEhx9+RFaJz3/h85zcOaH32zIITLz33nu886N3WF9ecnT0Orb68yhVmFnlHM6Z5EdUdPR9T640iXLlXKymc5XGK7q24ehowasvv8Sd26cSgBIjTWFyn96+hTGW3kOfLZLKp0ovIx5hFAmVNkXi23YkbRizwmXISvZzDYSQqaywtm2ZzTqcsRwfnfD44RPa1nF266RYFbQyfPMCaBoMOu2tAUIslYTS+GEo8jJLyhGtDF03k8FkkXNXxYHSquzXaWLQVPB8t5Fk4LZrqaEhKSWMtcIKq4Ez5X5WYCylWKxEBKBLXozEG2cYDkII5vOW2ayhcYbGGbrW8ez5NetNT4iJzTagm0S/63Em8OHHj3j09IKucTy4d4vbd0544/WXOTpZliCoAoZpzcnZGUoZmtmCMT5ks7rGOEfSijB6SQG1MvSUAbrsaVVmHMJIDJqcA9ttj3aWttUMg6ROpqTYDZ4QBRQ0NDjdikVNzqjgsSbhmpbF0Qknt2/RLWacnt3l/PKyrkK0EkLHrqfU8NMKLf1BLvttJtky+Mww9KPcRx8Jw8jgx4n1e8jufvGqYKX8iMOpWhmYlWFUDGn6B9SBfUdRjRXiSj13D0ZtVBZ99SWV40mRkwZtGMeEhJ44mlJqhCKL3adOymvSWTz35PGVeiXmjD3UGZZVOPlT1nWsiicixSe91OAV9Ex5L/WPOZGFdy6hIXVlp3SDDQYiQ7y+Wk1nuYDJsn+mIln1yZe6RnAQYfnLvYgxElUgGqmtqn2ILcwyjRAVYoig1OTdJ6tC6oTdZU8KkU8eXbDaDdy7fUaadcXzdMAYx3yxPGCMy89gu/3MdfHi9UsNhIEslvnC0cwc2ViGKAipyuJvFLykm4ToGfpAJuMcGNswjmEqQnOOQkc3CtsYuoUAIDHlGw9J1dZXFL9pDNopUg3ZrshuFnqg9wlfFmAIGWsLAHfk2GuAq2kvgJjxuk6hi1dEypGmFTaYMQpiph8F/Gs7O3l8XV/uRJKYRQKnxbMXrSW5o3EGdeeY5+dbMl6SNDM0zspEp/gJ2bLJqoN7HFMi+cisk0mycZJipKp5cxTAwlpN01ph3oVI8pnkM9vrnhCkuW2ahs1mpGkdIUaazsE4Yqwum1P1YItT42KUIaGEYgrFcwk2m55+HIvnUSrJlw5bmEM+FDaPEsTcNYYYLUqVqdrUnKnJE4ussMaQihKhaRxHRy0nJ2KEmYCxAhNKCmvt7CQiT4VanJQ0k8uZTLEp06SUE8tFyzgmrlc9MYr+emd08VmpWniNa2WziD6I7CNnXCOo+LAb0VqzW3s21wHfe87OWmkcnCOExNiPGAXzmcNqQ1MkmmTQSXFveULnDJ3tpGmY7sce7JjkPIVBFf3+93RW4qFgLCoGQhAqug/CWnCumXR9h2wwjWL0oxwQByBtzrJxu7JJis+OobWy9mNKXG8GFAlnzcQKQivaygY5AHHre6lAmC1T38l4HVkXVotXnC26+XrZEruNEilobVFjjmAo6UxyaDonCaXEOlvZH5KgRO4XPcpKOmhjNAEYwjhpwYw2+JzxOhaJVmWeQGsNOmtyFvBKxVw80mA9enlWhkEkDQAqImoGzUyJtFWeBYUta9FoI8/WgXws1mLHlBQmBCzJOU/m4KlIC6okVOwhyvABpka7TtdSloJ5n7yqmM1mDMHTdR2Xq0uCHwklHdQXsLQmQdbSQ6aKhuV8zqxt0doSk7BQKwMpJ/Es1MbSdR2L5YLZfEnbzlBKs15dsr46Z7O6kgmVEtp7Ug0hRN774AO+9857JC2mum7+CVe95/HjJ6y3A3/23/6L/Mo3foVvfOObvPLyK/yNv/E3+P73v8/Xvv51/qv/6r/kD7/zHV5++RXeeustdrstj1bXEvZQmS/R43fX7FbnxBBoG/HkiCU997Dg0UUaUAGxGCN+lPsvybRRpFvWAIkcLCGOxDhgTItKmRxkmDB554XIUOVB5XO01mFdMz2n9apgZYiJXT8yjKFIlaUQ8j5wdXVB73t8Stw6u4VC/Kny5NDKjWeqXvmn/OKG52CurOQKaGVimvhcP/V6caJY/53yzb83FZOHv5dv/u1pP8ki36vPs1iulQmrliFX0B5SKsCLSN0r+DUNvoCsyllXfq0QUMXYOq/N7N0PgRJFb6xF2b28fN7M6NLIbOyZbWfMtjuW/cDYe1pruX/3NkdHRyitGIaB66trhn6QBEk/lASuvVylSlaqv2TjWmzjsMZi22Y6WysjWAHOOFrX0jYtx0fH8vx6P/kkhqIrizEyDJK0FmNgGHrGsZ/kXZSzPkZpXo21ck6VdDcfEjFJzeVcI9YVJFRMZLWPnx/DuJeqUy0iMkkpYd4rjZvNOLtzi+PjJeMwsFmtGfqBO6fHYrQ7LYEClB6sBa0ypFjQ1Yy2rux7BZAozIMUZWBlncOW9Nm2bXGN1H45SaJYlxEQol2gVEtIgJdz1BjDD9958LOW+k+9UpLTytnE//0//zyzbhC/nl/g0jqSkvkXf+GNK/Dg5Qes3lnz1//6V3n69DdYr//1yDpPThyzTli/MqSqHn0CbFhrSFkxjpBCkqRPrW80xDkEUhwP9rqMFG+WnA1PLzZ8/PiK7Sp8CgQDmX2iFbOu4wuvf45f/dY394B+Ek/P997/gO9857tcXF7xuVfu87WvvcXLr7xC0zQiF9xs+fDDn/BP//kf8v4HH/Hv/Dt/ibO7ZzRtM+0/l1dXvPf++5xfXEAZxFkrgHCtc5TVxBxYXV2wWl1xvOjIZLwPk5cm7DGxnCHpsqILq7RpZsw6SbVdFLZZ0zQMvWezecaRPQJtMS6ThwGFWGI4FQGR21V2SAUmIrBLioZCHLAOaxzOdhgN47BjHAa6WUvXNQUoF/Dp9PSYxeKIEEdhrWoBKRtlGaNIyWLOzJdLmsbxwQcfcHZ2QrfoqPzRWTcn5ywKAb1n8LjGTd6I4gttp+TOFBN9308J5SC7cNvOCf4abcSQXyRqwj5tiy2A1obgJWhjHIQtq1QUMMzfHNzMZi2vPrjNrHU0zvDk2TXrbS92IIPCNI7/P3n/+Wtbet95Yp8nrbV2OOHmypGkWGQxSWISSakljXt6ulttCN3taQMDzADGtIExDL8z4PEb/wfjBHhsDCYZGKOnDbXGCqOWoZZEtSQqUhRZLFaRleNN5560915rPckvfs+z9j63qkQqvSC8uq9Y99xzzt57hef5/b6/b4ghcbw+IxwdMZ915Ow5X58TY+TGjStcvnLIfN6xZQZrING2Mz7+7Id46+1bfDpG3nz9bd48O2cTEiFJYJG1dmdfjwzek1Kk36zpNxtWmw1Xl9cAWCyXrPuRlBRt0+KynTx2W2todAtZ4aNhGKUuB2FXDZsN33vlZbqSxG2UDGvHsjfuStbLk4U1WxWCSUnsWFbD9AT2fpT3G7f+a0rXEBZNKjY7sj8LcHkRKNu+Zj0HtZeXwcdF8DhnZA1RAmTuKp6kVFNTXcbUkyg8ltCvUVnRuO1+PYF92mCNhVxVMKl4UQsk75wRj/KUMPedpqZtpmF3fe/aVElnJQeI8mRS5qAwugBkMRRVmqStTztcIUxkdVGmGKPIeNf9hhBC8d420/qZyr+nnLcDywyoKP1WzvgYsBFs0iwv7/H0xz/N1Ycex7Yz/uIjc350m69/9Tc4PrrDbD7jZD1O1jb3Tk65dfeIWdfy6HzOpUuXmc/mdF1L8iObs9X3+f1y/NADYf0gBdDiYI42itVZMRdGAKx+PbJZ9SJX03LJx5g5vDanbbX4gsVUEualkbKNZq6bIs3K+CEybgJjDhPTACigmQYLsbJn1ZZhFWJmDInVKrA6H+lXsvheulaSRxS4cgc2RqaQrgPlLKZt6dcIeJdE7hRiYr0JGA2r9UDXNNhGs7jUsV7Lxp5CIkTQiAG6agy6Ee+wphNfKx8jVlcJpZhK+uBLcIB4eVVz+nrEIOmKzayhXbQ0XVMkc1X2KRPtduYYfTH9LgsFCqH+rwI5b1geJJb7LcEnfJSEGOeElSfG/sVfygr7yIdIzpIoWRtzYxQ+J5RJxDgSgaadS/HeiM+XHwPDMApzwoqHTdNYunmD1g2NUzKhKg1bysLIms0alDKYdZCpRWaSgRWwX1D3QlTQJjMGYdoYI3RlrcR8vmkUs87QuEYCG7JmDLHIVRSnZz0nxxtylhCCmGUC7pysitHrCQAQ1N+w3JdUzXt3T/GDmLgaq0kB7t055/L1JaYRw/l+M6KVALCqeMjpqLi8t8SPiWUzp3Nu2hR2F0Bd9N7ikxAmz4m87RIuHLWBqqyvuibK1K34oJUGum4eq9W5bArFuB4oSULbpMKJBl02pn4MzJywA7qSJqONoS+U+Zzz5D+AEkZWSOIXIgvzzhQpCkuvJqHI+8oTGcoYw6JrJY0qJShpJSEllJXJR8yJpHLxlClppOU8jjGwGQf64PEFFGgoMj+txeS1AGeJLDHkbOWTWkFjq2m5MAeJhTmRwWS5Jw3gUyTsGEw3VtFpAxqGFPGIZNYoxVI7aXZRpHRxXZMLBDkJowJKAlWMjH5kGITJ6ZwkGIE854MfZSOuyTxlUw5BmuHqTzh6Yag+cvUxVusVl69cZb1Zce7Fp0IAmyrJLs+YUpN/26JtmXUde/M5m0GAf1urheyx1jKfLwUAW8pkOCfo12v69Yah3+DLey03IzGMxDAyZMs7d49pFnv8/X/4j7h9+zbf+LOv8+LLr3D9+g2+8BNf4hOf+CR/+Ad/wCuvvMLf//v/gC988Qv89//iX/Af//P/mK985Sd59tlnMdrw0ssv8fZbb7E36zjcX4pUxw9s1ucCHq3Pmc8bjPGEUQxoO+sKILAt1JRSWxP8Uf7sGkKDLhM0gzHVH8ejkiIbRy6TUPGeglTMyqd9TGsZMqStfFcrhbJS7MSU2QwjZ2uJYLfGsD9f7ADN0G823LlzixgC169dx8bK4KlJe4VLc19RN0FDtWerMa/yJaxhGhYBU3hNxQtNYQhs89w++KjpuTu3ePm87/3eLXy9vUdy3oJpMYpEOgQZrM1aK95sMgXDZmG55iQyAQlsk4Y9pUwsTIKkakqSXOt+GER+sIPQ5bRlX6bK8rzvM81nHbOuZW9PPFmGwbM+W8swpnghCgPaYqw0LSlnTGmsq59S9Sqt91ff98LCQPY1W0DbTJ7WD2MNnetwztHYhrZraVxD0zRTEMXuIT5jI6MfxC4i+gKQCZt8HAdyFjuDlCSEZBjFi0ySn2EcvSS+zuecxQjZTlN0kIFHZdlFFEk5slZoZ3CNpetarBVweXW+YrPesHewXxpnqUPIMgzQZbCgyFgFTm0bB7k1tjdsHSimpNhsNqxXq0myWQHelEQmLNxPTVIO7ZaQB3QeYZCGWmvNn/7ZR7/vff3Bh9xAMcH/+1/91ZIm//IgGHjfc3B4QNM0vPLK//Sv9LofdNy59wjXr6+K2kG8/GK1e1Cyb0vIhZrudVfqGx+8DLC0gJA55gvrkdKRd08Cxydn9H0gfQDxNOWMc5aHH36IT37qE1y/fojTIylGjo7uMA4jf/7N53jlldd45KEH+PwXP8fHPv4x9g/2CTHRjz0nJye8+trrvPTyazzx+GOMMfDwow9NrxFS5I033+L573x38gecLRcslntTCJFxjpmdc7Y6YfQ989lMBmnDwPn5uogxts2+1qUAoax7Serftp1x5fLlC3XgZr0horl3vkKdb6B4+9jGgYaUBNjIqtThSpjnfhxoxhHXtIScscg+Ng6+2MgYrHHM25bDvT2M0bzw/Hdl4KM1XTcrA9QWyHRNS2sb8Tks0kVjHdbJ2rRerXjyQ09OA9h6GGM4Ozvlxo0HireuPKfDMNBvNmLlMoX6SJ9hnKHruoltBaCNWC5o47CmQalG1pUcxU9JaRrXiHKlbCbjsMJqXeSRmsFv14hYGFxt23D1yj5d57h+7YA7R2fcO1lxfLyiHxXJBjnHrWPwgc1mQz8G7hyvWbx6kxs3rvAjH36SJx57WOw1cmIc13g/oLXmxvXLBO/px4GDq5d5481bvP7Gm4ybvnhKO/FCU6pIIwOq0Zydb9hfrbl6TdbpJ556iuf+/I8JKdLaGT57XNaQxIbmwcuHPPTQDdylq7z06mu8/L2XGNanvHO2oh97rl7e54zM5cN9lC6KksyFwWu9H4027B/MuXtyhokRlWEIgZQ3NIW0sRmHC1JokH4k68Iec5ZshZ1d6094L2OsXl/vEymPU69QbVTkm5gGQjmLBYW2ojLLaiu1r09V7Xk8wqgch5H5fF7fpTyLpbjb7hmmvJ9ai8j7TTs2FZWBVpnb1f5FguME9DNGT9YzMQo4JT6vF89zqXqK5c2OR2x5ZgyKqCRYLsXtsHQcRu4dndA/sGJv71DAVGOl/lfFNqb4qdWBkMGTU9mH0aQEKTd89NnP8FX7BP/lt1u+fS4/vlvj1XeZslhd/a8euc5/8lM/y2//j7/Epr+3c00FRFxvBoYx8OjDmbZteeiRRwj9ivVxX/CV73/8UANh1hmadkujq5ThEDOhD/RrT7+SBj7EjFVigNe1M1SKNMtONkKNTBetxmhwnfilRJ/woUSjptLw5iqBkBtbW80Yir+MFm+pECAqyKVBcY2YSA7aAxlnRToXRlmMG9PQ98LoqPI9MRqvN3+hUuZM11rGPmJyg0piemeLZ0Uzcwx9KL9DPo9zYjzbq8AQAsaK2XwouKAxFXxxaC2SIj8GZs7RzCxBScrhOBYT71lDN++wjRVPLCU+asMQxAcrpFIky0aA1USfCaN4gIyrwLGPtLOG2aLBNRbjHEXFOE2OZaIap4KULNd7f78tqR+Z4WTNOHogldhsT4yGXPzi5AH2rFYDKcFs3qD2pJJ1SuOxOGRi2PcbcnnwGm1kwSOT+4QtwNrgRVZkGolCt85iG4MfM/2mZzGzbHqRIGoHGNFlKyUR7rNlJ+cqynUeBknG7FdjYQsqloczkdySSEmMOsnFp8RI02q1JaiBg/2W1blG64gt51tpaQjG9YBRcHDQklOmc45LiwVOaa7s7xFHyI00krC7Uadpgp5VXZTj5PVSqeTbhXyH1VCmU8ZY2qZDphDCsgRVTMhFohNTIvqRfiPGzN18Nm06IPdAnerXNEOgbHAQfKQrkxEFOK2JxjBW0KUs4pUqu9snKwQUjKEYjO8ANjFGcvHJ09ruMMJg3Y/T+3NG7oFY5NA1+SQUQCmmNAFgIcOYNT5lmtKIT5McpAAYUmDMsk6lnCUKHaZNtnoIODRZZ6JRDKGkg2qFpXicUL0XhAFmSnpqJhNJksSp7ARAVKZXvQd2eKASyhA9PkSGYcvWykkMdF01yM9i+rvZbMgpM5/Np2K9nveaODmMA8M40jYzzs5O+eSzn+Hs9BhXjfUL8NMWEEVCJOTvrXO0Toy+BTTdmlRbY6UxXogUbDYTAMx7z/nxGevViqHfFENUSYgz1hU5Zr1/FYu9Ay5fu87qrZvs7+/z8Y8/yzAM/P7v/R6Hly7zsY99jJPjY37xF3+Ry5cvc+3qNX7mZ36WF194kf/7f/6f8+lPf4amaXjjjTf47osvsOwaPv4jT3P5cI+zs2M263M2mzXj0INSjGOkUWB0ptEK33th25qa8iOU8QqCBR/uKwITkAorUlg0OReEtPghbR9VMf1WWRMT5FSlp6ZMGNMEiE7px1oK5X4YOTlfcb7eMGsarDEsutn2gUJk6kd3b9Ovz5jPF8xmM7rZjKadYQq7ecvsgt3WZQs4bb+Wy/8RUJAL312TAuvnapS+4FMoUqC88xPv+fVlwEApRrf/knY9hMqXY5bBmuyFgX4MDKME0BzsORpXpfIwySeUUC8K9L8DXEL9qkKJTCEmfPD06xXNlWsYbXaAlu0zqlUZG188S9N5aJtGhhFoDtoWUmK1EQ86SXw2LJYL5ot5Obd5GkpsNmL6vN7Ic1LBMXld8SKyRtbzzWZT9un6abafZzabsVwsp+FGNek3zkyJX5lMU9hRW7ajsBVikLCRmEUmFHyQhKoY8T7gh60B9mq1EoDPuckQPGfwJZTEWEfSFmWEPdy1jvmspeuExbU+W7E533B2csb+YwcyZe/XYGZynhXCsMwah8HtSN7rfTYMHlUYIrVuWa02wqAchqkuTSj8ENBBCcvNaAkqUCLXN2V4UxuUtm35v/zf/g5/3SOlv7ys8q96PPTAbd559w2e+9YrHB0d0XVv0fcP/439fpU3iOmzAKFi0WEgB3Z7PtfIYFntdFjWWnQSD88cE0lTBlxbY22H1Pw+ZEmg83D/qhFDIsXM1atX+PSnnuXypUtoIpt+xRuvv8bX/uDrfOtb38aHyEef+Sif+/xneeChB3CtI3rPZhh4/Y23eO7bL3Dr9h2e/tDjPPnUY8C2Djs5PeFPv/4NXn31NUII7C2XtK5h29zL0a8Hbr99kzAG+jgg9Vpi3jq0Es8cbcSio9yGsv4qkXsZI/VB0zS01m0/qYL1+py9y1fwQ1/ky0CKmBxpNXitKOIHQCTPpjxnquzjfvTC1jaGUGr5hCqM2GL3UfxGJZkz03VtIROI56AC5k7YWOSIdQ2H846HH7nOAw8+IGvcasVisR3OnJ2dEEIoz57sDQqpKzfrNX0/lOCHUv+mTI5ZGK0FrKr3xDAMxYKhwuERlMjkYxIwth8229o1pamuNiXAaigJ4ylV43bxaGsby+H+ggevX+L0bMPN2ye8c/OIo5Nzchjo/QhacevknFnbkdKK89WazWbDZjNwerbmqccfYW9vDqjJz0xrw40bl3ngxlWsafnNr/4+KQVefvV1hnE79Oj7gfP1huvqEomGs7MV56cnvP3WWzRtyzB6xmFktR5QKYIyDDmiEY9mP0bMfI8PP7LP0Z1jYgCdA1ZFDuea1kSu3HiI/b0ludjr+DFwvspsxovgZc5FvWQdMUSGCCqO0IKPgXH07wG0pp8twwfjrNzfKU9hQu//M3ItY7n/hL2ey/1W6oqJVUa5rlX6KHVUjFEY+SEI0QbYrCK4IOEtjbvwamhoXMPh4R7nZyvWm77cY9uB3NZmRPpBrSftDQo9WQMEX8gUbTP5ZlZ2XE2ETlHIIKOPE4kg5YSz7j1sPPGE1YVsodBJy1C+WAqcn51z5/Zdjo+vMusWGFPIA6YtdkLh4nnOgJJRT70+1Tv48PAy/+PbLc+dwTML+GcPws/dgIc6AaTWCV48h//za/A/3IT/65vwnz59na5tOFjO8TEyjJ69RcP1K3u0rWEYPKv1muO7d1gf36O14mu7Wyv/RccPNRBWy8qhjxwfrVgsW0gZPyTOT0b61cg4puK9IRr1rlMkPFo7oIyVy70ea5xtLndmlKmJaw22MbRe0gj7lUej6BaOlBLOGU5Pz5l1LW23pZ4rrSWRSEuimzFaUkSc3IRGq+Lro+g6keWkECFlwpgIg0i4kioG/EnSOObLhubQ0HWO1rYFKQ+TdFOVCRBZmGFKK7xRpNHTZEXbOlJJB970IyiYzxuGweND4uR0gw+ZZpTmxTkLNrJ3eZ+2GD1GLxRU6RlK4a/15C1T76zgc0mN2z54yWc2ccCPgXbeAJn54axspBqtwVlo5g1atwIaFXPG9SawWAjgp61muWzRekbwJamP6lMlmuisFJCmIjWGBCpweHipJHIo1uuBk5M12YNxVjblMQiooeU+G2MkDRmHyAzFfF4VHxVJsLh58y4Hy4WwxkyD05ZsrQA0sTrbaISkkzk/D6icGELEaY1xpshOJAwgF5lvDIFcomJzzqw3a+adxXWWmTMMgwRCtJ1htieg6KJrWDQtC9eyN+uYNy1tMSFWKNRCwKEq881ZgF5Jo4wFSMqTOblCTVK5ypeQRjUXU5Q8sbasbahpKbYsujFEot9ufNXI34eAtW4CSirQFqdpRN4xBleonLm016C1UNqVogDdEYNEEIvsRzwFqjl03BnvGm3E4L9sfsIAkNfzpXgyKeFK8ZRzRgNt46ZNxWhNa6zII0PadtrIJM3HyJASI+IHppTEjIecUTFidPHOMKDQDEkSIcmlYC3nNyYBpBqtcFqXZk/hjMbZxBgSOos5py/pUbE+j2Vz0+jJoF4rAcdiygzjSNK7aWhl3cqyFtb7YLrW9d/VxQKB8u9930uAiVLQURgy8rtDCPSbXtIZhw0+BB7vnuT87ESe+8IWVMoy7+ZorWidsE+sESmUa4R1Yo2VyXessj47eSHN53NmsxkpJ9abNevVms16RRiHwihxMljw4wT6aGNp2pbDy9doFgveuXWH577zIl/96m/zj//JP+VLX/4yJycnrNcbvA8slkuUUty5fZtf+IVf4Kmnn+Yf/5N/wv/p//if8Yv/6hfYWy5pnOXRhx7k2Y9+iIduXCWHkePjI9arc3lNraa1TooUJUlUhbWn0SREYrYLgtWjyhuCDxeuDYCxDm2Eyaczkz9fFfYKa9mJhwUCYJf/KD8n5b6wl+T7D/dm7Bcgv6bx1sd/ctPIARWhPxsY12esnBi0t7MlbTfHNS3OOYwrEvOatKR5T2G2e1/t/kuVScprb5+7+yWP9Wf0zs/V37e9m+V8pAs/ARozrXBKbW0Nzs9HzteS5uUnjw/xTvIhTAypDz7K86hKinB5JzmLSbxG0c3m+HEkakvrKNPoBPkHK+iAKY0yg4CtQGssVssabZ2w16y1U1EckkhkQgz0m02554ZJzpyKaXSI4tmTS9Mr63Mik6b7yxnH0A/0CJuspruaYlyvSlqd+Hi6AqqXuqIC242js5aDA2EWee9Zna/K/iJ119D3W0CuAMZDL2yy9WZd0m8lgde1DV0nf2ZdQ9fI71idrYWlf+USm/UasmK+t4DsiUrYuq5psFoAy5gV1cWtHn4MpBjEW05lzk5PObp7h8FHMC0Raba00qRhxI9rjHUs9pZ08/kOrrkFdq21tCVZ8Ifp+D/87/4LXnzpiJs33+Wzn/8Cb77lePHFD/ru+5/u73/cuHFKzi2gcM6RsidF9R6WunOG1DVTbdM4GZr5Kt1ogGRQMU6AfAiRvk8cn6wkldlHZHWrz54DxPR51s64cnhARuqycRw4PTnh5Vde47d++/e4efMOn/rRT/C5L36Wpz/8NG2RHI7e8/Jrr/MHf/wn3Lx1i4999CM8/uijHB4cTu99HEdefuVVvvFn35zqknnXslgumc26yZ+nMlSrWb6l5Xy1YTUEep8IaRpRToB+DffKSaG1pW1nzGYLtK5Az9TDcrxRXDt0KCUszJkzos5QiljYJjklrIZIIoWRHDykjFMKlMInUcXMZ11Jg5ebPUTQzjBfLFku9kgpcrh3gFKalKVufP2V16iptjFnVJK1KYSR5d6SBx68zmOPPMLRvSPWZ2u6tpvCZaxt8OPIbL4QMDukUocmYXjqIlrPlamipvc2HUqVAYiwzoP3pKbBmFw+QygeZDPGIn2uxdJuTdVYzejzNFVR5dyURA+M0cyMrEuHB3MevH7Iu7dPeP2dO7x794icEquzDcdnx2Lw3jjGceR8teadd2/xvZde5ZMf/wgPPXgV5zq874Xdncz0nPzE5z/Lj33qE/zyr/8m3/z2i/jinTaMgZu3j7DasLeYcXiwYLM64fjkhMXMsh4Nl68/wDu3v8voAznXGqTAM2drsnuXw2vXuXLpQGSpszknxyc0jQUci9mMphGAylrD2elf7NuUAqAtVgkYPQ2fnZu8AL/vMQUQvD8QlsueJuhTGZwV32XYWn6Qt7WJmNunLfMqRJKP5JgurGJ59Aybc7Q2xNIDOWv42Mc+zGozcPnKJd588136YQuE3S/IkDOcdogGMtg0hXXeNJIIba1lMZ+xt5jJnjgGNsPA6nyFNZqohPDii/+WNe+FfDT3J1hXwoUmRU0aBzabnts3j3jnrdtcu3oDDRPjVnn1vvXb7mCyXov6heq/+Y+uwT9/BJqdR2+h4DN78J/9iABhMW4rtkv7c5aLToZGJoMydF0jgGbMEEe0dgx9mtaCH+T4oQbCanKf7SzWiSzy+O6Gfj0SxsiwCcWoTspCpYQKOW+1SMV2OXk7hT2I2bu1hhbR8RorrKAQYbMaCGOk7YQmvNn0gHhinZ9vMFbMlxvnsEZhbKI7NISgaRoxjSZkzs9GAbaaYpS8M7FBQ9aZMAobS2uNs5KY2M0cs9ZgNQxxxKBoOsPeYcfYB8Y+CKiWpMFEF9Nynej7IDdMQUubVm6Bxhkxud2Ixrsyn8RwO0BrwApTQYXMED1OGUIWJhiUyGKr0UbhvcSc5iQPlUq703qh66cxoqwX/XiZwgefOLg0R1tLVsKKI2VZgAtYPgyBbibG+OOQyaGXmHgt12C97nFO0iCd0SwWMwGtCsKQsxicbzYDWmnGECQ1rRUQQFlNFWYrrbBFhlc10MYZAfyMLtMjWSSNMWw2A86K10T0xZzSaNRMUv2cE0Du9Gzg3tEZJ6cbUB6fLDqqsi5LkSKGpHEqdoxr8GuPbWsAu9wn85lhHDKzuUHpzF4zY25bFqZhaRrabFExXQBD5q1Qdo9PzyXBJQvz0WqNVpLWEqKkwUCcAFHZ3BL9eoPWinVfznUWXwqgyD5b2uKFMpakTr3jQi3pWTu+VDs7wa5HjVyELcuiceLnEFUqf7eEIPLZEKJELmeF0Vbsb8sCb5R4YVljBRjSaYoB3pVruiKR1EauRV9TRqOAWD6IcX1dtyfpLLEk81BcEhQevd3MCtijEdmDKZIoU4vZpHBosNtWXT5XgiTluNO1Mc5Yo7BalaSXksSSgSJ/9Uk255gyNkmhGonMrJvee++DMFZKYeasm6amvrCzQoxQ0weNlrTdGOX7duWy5ekexmECwKpB9+DFOHscR3xhz/bDhrt3b5NiKNdHcbh3KOl2XQeFiSgJpJLOtVju0cznbDYbfEw4bdjfnzGbzVgsFsznC0IIUzLjOI5F0iuFcQXwcmHADr0ES+wfXObw6lW6+Zybd+7yne+9xBNPPMUXvvgTfPjDH2GxWLDZbPit3/otvvFnf8Y/+If/kJ//+Z/nV3/1V+gHKTqvXLnC3/13/13+n//Nf82jD3+YZz78YR68cY2DRcewOef09B5Dvy186tyv0u5zrMEpAgSnmAijJ/HeCmkyNodp6phTlmj0XAGcAnoxiRLLxE+TlUaTy5Cg/s7pvyZW3sV/k/WmcQbc9jkOIYAPFwqslGFY92zSGatTg2tnAoS1HU3X0bYttm1RtpE/FbRFQlBqozB9TZcirbwljcaWxS9dMMC9cJZK+ibTmn/xc1I2+8zFEpDChK3fkiWNWknBHBP4mIm5To3hfOUZRk1jhTHsSq0w6wxGC/u7QnG6fKYqJwDZ55VWzLTbvi2Kj4qRxrvY9BbPsd1GYJdltr1e86652ADkjFWGtmm366sWb8BIRmUtjEtgvliSooRXpOInEmMoxriFrRWi+KUVya5WsNkMjGNgvVmLD0lMdF0n+4FrMCFMwIQ2VZYk0koBCYtEyQrbmgztrMU2dpIWmiIDMlazd7DH/uEBYz+QYy4s1EzfDyK1LGuN1mIM3s0aahL4+boXOZAxLPaWhRWpUUqaC59lKDafzcogSAvr1IpHmFJlfY3Q9yMpBsZxw/G9I1IO3Llza0qjjWWg1jQNB3tLDg5mZDRd1zFfLpDkyepuJDL/5d4e4a8gS/ybOf7yAFU9uvkcax0xRc7Pz+m68fv/0F/iSHlF3weGYUPKS5xrJ2+mi4fUBj4kNMLEFnN5Q9QRlVRJGtuC5DEE9jrHEw9fIavE7XtrVv0u08wDnpwVp2fnPPft5zlYdjz11JN87U++wac/9Sleevk1bGe5/vB1vvJTX+KnfvIr03A858zR8THf+Oa3+Po3vknXdFy/dpXHH3sUZxw+C8B8fHLCyy+9ytHRvekZ7joZ8NSk3+2AKbKZhisG51rSepR7MqXCNil+RnUdzMX6oQDS1loUkjaXCsPrbL3icNnQuYbeyzqw8iONVRglrB+dAwnxMLJapJpGK6za2oiMowetGX0g+Oq9pWQdDaJ02NvbE0Cua5gv5uQMznXMXIvmHWGBG10GUSOJHmPn2MKaVsB81qFyotVCGIDMY48/WdatTH2SYoh07UzUAMqQsxY/uURhB9X9tiSKFy9D8Z4L1LU3hMDYj1Ngza5NgN71mc0ZszPYhAqsZCZTqDqeyeJpdv3GjPn+knbesVjOuX37HmEI9MUTauxHgh/ZbM7ZbFpS8lgDIXquXDosihI9AZubzVoAS2f57Gc+ycHBgjfeeofj0zX9mBlHz83bd+nXMzarc06PT3j71j1ceeNGZ949WjH6gLOisJAEd41rHJtNz7e/9SJow2q1JufA1csL9g8vS8iJzsy6Fms1IUSGXmx46g5amdQpJU5P11J7a4tVE3ZYhnealPQHA2G59IrIZfqLhlJisZNLGJvUzrv7pQSrpGm4VT25dNSTNUkdwFxIcyzAWypBMuMwsreQZ5eCf967d0LfD9s6UFEVksQLH+2idLva8qQYRQqZpLawZW9snKPrWjjNjIOkq8q+WmyYioIj5bxdEyign3ofb+UsARhN1zHmTNKWd26f8PDRPZadBSV7a60tL75zpv6hsjK3oOT2fDUG/pu34X9/37BkaeDFn7zv8gJt2xTfQThfrVBaSCitdbhWSA/1+lXm3A9y/FADYeMmECPcu71isbTEkAV5SUXioRPWSSKjtpqhl0U5S+dVfsv7b/qis420TtO14iuhjIII1otfFQhA4RrLbNYyek8/jCifaBsxoZ/PW2adxcee1aliHKSQimPEdeAH8bGSYlCWrxQi6/OB1flApkifrKRt7C0FrbFKMYg/sqS+WcN8ryGEOSe315PsC6TJYpCmIEWZ5O4ftDLZ9qOYb2YBrrTNwszQFENJcK2j60Snn4AmaxoaHIa312e4roEx0ihFHIQREmLEjwmFQVHMPa1ITqu/UUzQRIlXXZ0PMjkuSUBZgy8bt63TLGuELqMVYxTJYdMqVv0opuLags6MY5Ait9BYTTH31TXpEcVmEGnUet1LAWzkPrEN6FEx9DtFA5J0oZ1c63rNjdk+aEopFvMZGnBuCyaBJLuMPtBGAUGP763kGha/ErUZyQRCEDlMPf/gUElN0c4pJaLK6KTks5Tq5u6J59KexWKwg2bWtFxqFnRFLlL9lWQyVlg+qUdrzbofhM2g5dSOKTF4Tz+OtK7FamHIOWtxzgoFmcS637C3WLCcz4tnhinNuSoU/O0zZQvYFIKYB8cqu7nvmasynd1NyFpbGAdltyg/FEPGh4HGif+NHhXBC1VbGbDaTKln4m1cac1metbqYlljs6u3mfwbDKWZC8UfK+aS/KXqwi+gwRiEKp8UaGvR1pakzSppLMyTLD5/sgHJRiZJV4rWaVSCvrgdxSTeTCGJFNFqcd6aWqNybzqdLy5jKWKMJSl5vSEEATiNodOOVlucMvgCsPosstJQnktTvC2qv0Au7zmWCaKp96wW349YzpHsqNCWtKdhHKbp3VBMuXd9IayxHO7v4/1Iv9lgjObS4SVhDBldRmTCNtGFIQGUNbnBtoa9+YLFbEbbCJv2/OyUTb/h7GwlrApjIWdiEHlSN1uIV+DoUcowX+6zt3/I/uWrzBdL+nHgG899h/XG80///X9IN5vxi//qX3H5yhWeeuopPv/5L/Anf/zHPP/tb/PzP//z/NiP/zjjMHDz5rvcOzriE89+gsY1zGcdjzz8IPPWsl6dcXpyl6HfCO2/7chJPG0kwUpYW7vPiy9ed370ROLk21QLwHou6roDoIrJrMkQyxpnjIXi5TJNOJX4EildgdP3Tksn1mcdCgkS/Z6pn7BzhOVTJ6lKqeKfkSa/N6VlfaZfY84tzjXYtsU1M2zXYZ0rqZ0SOKKVmZhDSYE1pZjTW8lhbTbiBxa7eYcNVlcX+dsO5lcem/vOQc4XvgcEAFzOxY9QrTSbIUAuMgkFfsysNx5tpDZonKZxcxprBGjeObdydncqXoXcAxeYmQI8xhBIMcqe4GQPSNUgvHyu97YFakr7vP96oQ3GzkhTqIUvQ6ad86I1RtUEVjf9rPxJIgNJIrM2SuQ4SilW6w2jFwmLD7HIosr+WCTkfd8TY6DtHClJetusXYoHaUn/m9YyzeTXo4vs1zmRQMt/Oxrr6LpOhhEh4hrHbDbDOluCf4T9NowDZ6s1q/UG7yPOWmazToY12pDvA1SdEVq6cw2uMNCsEWmk0Qmtijl7BL2/JATPyYk0xfdu3xaPUGvISfz4Yky0SmG1gKOuaVnu7dOaDu8HlBoxuiNYi1HCnPn6nz7ynmv4/Q6t5Xz/Vby96rG37Dk7/34mxu9/GDfnkcee4qm7Z7zwne/w7rvfAz7oc/zlwTbvPaPObDYr/HjAfLFgo2Wdkyj08o2FqZjKfp20grKvVd9RGcjmncYv0TrN5YMO5y7x4NWOu8c9x2cjJyvPMIaJZdgPAy+8/Cpv37zJk48+gveR4WzFK6++zp2je3zusz/O5z/341MwAsBms+G7332J555/gfWm5yNPP82HP/wUly8fggKfPeM48uKL3+Nb3/z2VIs4a+Wese6CrKmu05vVevqadS39eCQgutYkH6XWSpGULNaqsgfUK1DWU+MKu1cGdLO2451bt5kv5rSuLQx+YTAJoG9BWZTa1r/zrsUaTauEuW6AtmlwxnCwN2c+E6/VemhtMVqAlBgDy+VS/Fm1YRw8l65dxo8j2mhmbcv5ajWx8WsoltICaGzOz2m6hkZnNkmGebduvctHP/qxC0yvap7/3l2PC2tZvTtT8KgsbBNdB0vlPEzXpyZ5AlbJrajcdn9VQGM0Y2GYTfd+xcPKn5AFnJ05wyMPXePBB67wzs17vPHWTW7fWXLn6C537pyxOh+FZBAim82meHyNxJh44rGHuX7tCl3XiZLnvuPBB69z9+QeZ2vPEE5ZDyfEGDldrdn0G9zxVkmQYpKhJoEHrx2wf3BI03aECH0/kJKEk3WNYdV7ZrOGbr5kM47sKy3hOwBqSyxJCdpy7ZyvNUO9PtXHTs6PLl5+McbJG1QZhYoX5cG1VphWk2KdM30O0oXvh4ug1wfJLaH0CFUOn8APfotq5kyZj02HUmKvs3e4Tw4Jk2ORQCrefONtfExyf+8kwUeBLORni/lkHRiBMLbk34z0c6aEBynBKKSnb8gkkfGWgLEwShqzpNxufTq12hria5hUJvcf23pP084X9EPg5q17vHvrLlcvL4VYoYWsUa1odo8YS73eVvudRPWhvXCOM4VwsT3u/zuIJ7f0NYCCvf0FOUexfFA1nb58Ll09pt/3sr7n+KEGwlJOZB/p14r1uadpLV1nSMGIGbCwAelTRI2xgO8J48Ts2qYtS2j3EImkAFCoYn5vFH0AlMI6iy/m22NJa5vPWpbLefl5KWMbJwydmCIxgGsN5/0JHR2uU3TzTtIoUyKOSRLoxsTQe0yEWeMY0kjbWGazhtmsFT+zVjHc957rZFWVJMfsA6t1z+iDpAhaUywv5N9DztjGEKIprJ1CeVUa7QQ0co2mbY3orutUPmZSiXE/HleyqeqMcQrrHF4pGm9pgyUlid41mLJ4yAZcQgRBwdAntBLftLZztDOHcbqABsLE6VMiG5FcKunqplpZKY91mjCUAFhjSVnhhwHKFKRpbJkyC8NMa41dHHJy5y4pZfb2HM6Jf40vevEQiuyqsL/kVxcZWaY0CQgQ6QNNa9kMXgC3+53/yIQQOT0r/hZRUi/6QXwX6pRam+rjUD6rVcyblm7REGOmX40ie0sidQlEWmd5+Jpjv2vpGpngzRrxULJaAEDnNMZQGmkpEPud9B9jGlIKslDljI9RGnQjMdRVnhhjKmwCxdXDQwFQEQaF1u+lx+6a47eNI/jIMI6cb3p8BI/D2DRtLGPxfqmym6b43YgvrtCUU074GLh3uqJpHLO2mV4DBHxGK0IOQJGbxSSMm5LINiWKlRW5gmCws/jnXHwBczlPDkIQf4ucZboVpYg0ukQea0XWpgBl4JR4jdVUzN57fNyeKzGNjoU1orGATRlfKPNQPIG0zCGr+fOUwJjCe/YvUxtoBNSMqX5OYTU4JcmhKssaODcNrTW0Kr/HwFRu70zMhZ1SvDwk1VVAFe0sylaIIWPLliJy0zI1y0oa6zKAmHdLQkqcr89pnGPWdbRNJwbWxqLYJuaBAJjWNTSzGc2sK+me4iURfODk5IzNMBCjR5FYzKSxjUkkh03TFZafwboGrTSL/QPme0syhm9+53ucnJ1x++49Xnr5Zfb2D3jyySf5wz/6I37nd34HYw0/+7P/Ds888wy3b93iV375V3j1lVd55NFH6PueV199maee/hDr9XoCV2MMHB8d0a/PZaBQWHXWGoKXPaPS9+W5kojtKtPNBfDwQbySyFno6juhEkpG/HKrlGpal3VWGfFAUoVtVL8/pURIEjFfmVI1cr6a7uYyTJryEXcbpx1Qbbfo2JXK5rAjnaRAUOVZC8EL2NFvUOYMbRuZMhtb1qkO18wmBpDV4rFirZlec/rsSnzy0IXtplVh9UjDUiew5eZ837b7fVvx9/mi1YpZKw2pLRLlcZRp5KV9kbCFGBmjWBQI+Czv//3b/d1WFFDvHchppQk5lAGRndggqfh25BjLUOmiq3dl8L3/q0Z8GtF2KddF7YAH08+r8vPb3yEFcxHtGsvOaaUtZvhdN5N9Uyl8kPV3Mt8PnhA8w9DT9xtSjpJqiiLGjK9JybrI4jOEUbzBZHIva3EuoLE1mq51tE2L0or5TIJyZt3Wa7LeQxmRvG+GkYxiPl+wv1wwL9LDMQSG8eI5dNaiXVOaiioXViiVZDKfVblkcg8YTbG3EC8g8XiVP8pofPBic1DYtKr4M9VzPY4DqEi2LY1rIWe+/IWb/M/+8UucnHX861//wXy2BAD74MbuBzn+qiDYYj6Cajg9Hzg+PmO+WJDz03+t93L/4WPCxVw87LyEnihFUkYQiB0bBaPE39BHCW+yxmBtIw0TiqQSGKbGOhcqSdtoGrfHwXLO1cORm0fn3Lq75ua9Devi5ZujSHFPz8751gvfhQQvv/waIUUODg740R/9FE89/eSFdfHm7Vu8/uYbrM5XPHjjBp989hkeevCBnZoD3njtDZ5/7rucnZ7L8LAA+s45Dg4v0XbtxTpLbfdabTR7h3vot94FxL5E1vctZzTGDKStXYmSwJ5d9kwCzs5W7LcGU2xZJGdMaiLvA+M4EMNw4X0oJZYNTZ1XKvGC3d9blD1vixoYIwFSo22wFeBPGWcblOpkABc8PgRao2msKdzXjDGwt7dgf3+PlMSratWP7CVNKvXHOA7s7e/Tj/2FGknqp1TsKrbXRhUwYBiGIn1LpZHOdLOWvh9w1qCQoaAfPVppuqYT9tEOeNYPgXm387uBtjHELPdvBb5yziQtJISQIiqmyf5CK+kPn3zsBstFx/5+h2kzqol0Z4r1KtCvIyFCTJ5075QYXmO1WnN+vuHhh29wsL831Z9lu0SrzGOPPMzoFeerwPlqw6bvqSbrenunyEBzGHnq8Qf58EeeYrUJvPLaW/Rj8cRWCeIGv1FY13F8coTWDmsVY9CSEokMKM5Oe3onSqmUZBAqy6+amFFSKcRSQ21repcNoy8SfZ2JqtiTVDbjTu+htABWofQsSr1XNg2VBSU1A5mS8vze+nfXP1duaTUtr+o+dlO92kommyhnICnO7p0TU2A9nqO0ouv2iEkL+1Kxcz/s3Iu777WC3NaIrFdtv8+VYL5x9EU5sWCdVtiiWFouFhKec7+/2s6wT1iV+X3BMHkd+frte2eklHno5hE3rh1KCMUmEaKXpOb7ao6UM3EYS9It5R577zn+Dx6Cn7t+32d+33eCrDMFY45JPKitU+i8ZWHW96s1vI8S9H2PH2ogTBtBmCUdMpSFTSY9RSU1FU61oco2M3pPWicWyxmmmiWWOlSQZIq/kQBI1Gl0uTrGGnLMnK82OGdkwuiENVUnTQqFsQpIhCCNha5UU2PQdvu+qlmtVpqgMv0m4zexeFBZvE9YlznoOjBSaI8xlKmLnoy0rRUQyzSGfghsNp42ZQ5m8zLXN2hrmM0d2mr8GMkrz/n5IN4aOmOtwTWGprPypxF0JuWMD4I+a8QM8rxfy0mz5ZxkUEYXIEsM/kHtLCalmd99Hkvih1K6gJN1494yJoZhJPrIcn9ZZjKQY19YfdI2ayPx2EZprFVYC2EUKnFI0JQ1SyF07HEYyDnTtJJkYowiK2i7hoyAqkoX8EtJKIIg60bkIBthwvhBFpg0SlKp1tv3lLIwkYRd6IlJGIpKR2xKtJ3BtZY2NDLJzeILH6PQdbXRoC0piqSutQ7GkUZrrDYsnWM5Fy+yvYWYiWoszjZ0TStSEZXIeEIUmZgfvchVjaIvRvx1ap4Lsl+BuJrmSN6CRQpYTkko5TAlmTFGAXULY6GamlsrbDGr4pZurC3aRDo7m8iZu2b8F1Mj5d9DSqQggE3jxMh+GEeCNsUYtaQ5ZqbnWmWRe6LZNibq4oK562OltZ6Ksmoeb7QEFNjCWpEGMqO0NE9d0whLMUSi3vE6m5pmhY+B6jvkjLBSoxK2VWWXTdIwSvJirtMapqJSZ41BiZ/Y7lo4vU+N0lpADCXyycpCqZuuAhoMjTLMXMNyIWzW6qsWszSeQwiM0ZcppvxwjAmVFNY2wtSxJRUw7ezkULyQkjQmifL8aIwpLAvnmLUts66lsQ3WiKF2BSw657CmGHRbR9t0tN0M7SxD6EljYLVas1r3kyG1ViKZmtaa5DkfA6CZdzNhY7iGvYNL2Kblzr0T/uhPv87Lr77OtevXWW8G3nn3Zpn8J5ZLkVq+8847fP1P/5Tr16/z45/9LK+++ir/+tf/NR/+8If4yZ/8KT71qU8zm835l//9v8Baw5XDS6zPT4j9OTkGnHVY60q1J/LxXOO3tRiN5xjKNLqeS2SyWe4NY1Q5HzsyjMLS2T3viq3an0Ktn1wmsoQfjCV5qxqYqqzIKiKLkxIGEmpaa+W23aYVVhaYeO/JJNAau5NEqUAbqUKUmAnrvL3PZRgQSR4SvbznAq60XUfbzgooqCbg2poyzDC2eE5VaZ80cwIU7aR9kYk6FQYZ0zM5SUYLpf/9vC3u/7qY3Ev8eNeIMa3RivNNoHGO5aKh1N+kFEhRrktrS9rgfa9RG3Vh29X//IAiVAvzWYuZIKrsdVlnkhGPHpUsMYkBeGXVvu/vqvdN8kR/AmiUnSFlZ7r/m4XxRt4BwbbQmLrwrVu5tjEWjKUtdXXKhQGeIjmFks4ap58ZveyLm76E6QQvDOphxI/jxE4eiqyynrcQke8fBAhZna/YW+4Vj7BcWFiR+XwuXlsatHHMuzmzWSfDvxBkfX6fsbE2RvaN0rBaDYrCBKssyXKvZAqbzY80TTcNCUCal5luaZKVoYkp9SSaED2MwoaRgatFOUc1Pgb45/+LF/l//Jcff9/r+cHH+99Lf9vHat2w6kdeevllAH7mp3+GX/u1B//Gfn/jNojfupxHqyGniM7i8VRvYVvWAamJhf0TiuelS/JMiYcS5FzWh9oYqjQxJpZNWzwRlXhuhTjtnzVtMCN1jwQurdnf2+MTz36Mz3/+c1NaJcCdu3f55ree42tf+0PW6zWf+cSzPP3Uk8zns+keUknx2iuvcvOtt4jjSNc4NA6F4uqVq3Sz+0CwAqZqI1JDMfAupvMpoqY9+b1sGDUN+KWR3jbFTPvSXtcyL76oVkGs3kgp4aOEMGidpnXBWUtrNVZlIpGcRQlwtlrTODv5wlpjWM5nzLuWcbOS/Qe4evVyqQHk766VIUl/viL5ICmzOWOspm0d2mh8CMXsXPoPzwwYsbZhudyjbTqp4crzFYzZDhTLH63NtMYFHy6AgqaE8MQYcSVFuQIsbdOSQvkdlS+WM+tNT+vAWfl7/eytM1PITyhs/9qTNFkMwGWvEy/ppnVYa7h25YBZZ1kuGt65ecjNW8fcvnPGsVqx6Yfiies5PjmlH0fOVhvOVysODxY89NADNI2DHJnPmrKnJoyGtqTnhliM/CtomiRxPoQg500p7h2dst54LIGrB3PatpUe2Umokdaa/f19yIrlYkHKnhA2ZC1yyBgC42BouxatDY2zpHj/PiV9kpAMLoK9zjoBUawqAQvFvseZ+38Fu15Udc/f3ROlNjcTQ57yPCSVyl6fL4BiU3iCuv+lKrt7CypNfqdlTUFrZrMO7cJUc4xjmj7f+23VUrtmpDEu1haqJN2qLGQYxO/u3K85PV2jlJZaunHM24ar+3ucuGYKjXm/Y+rL68CTD66JQJ7vdT9w6/Y9zs/XLPYctjxbOcvQvFRX07WomEqOiVTCOHY/sk/wa3fg2yv43zwGCwOvrOE/fQn+i4+99z1MpVLe/Uo5L3n72qqAYDb/YBDXDzUQJuivNBSrc884RpTSIgvUmq4zAuSQpRjXGT+OeB8mVkadGOa8veGs1Rc8LELKiHqg+qeA0lo8b0ZZtJtGCpg65bNO45wqvlsBYxzdzGBPRYanlMIX3bxMQgzjmCSJI3qG6CGBVWXyORNj0JwS3ieRHSqYN2rLxqmFrs5iBK8TPmY2Y2Qx76QgSJnRJ/zKC7NtTGzWHj9E3NxMwQC2MdJUKpliDOOAQaagY07MbcvQB9qZk43BiEl7bqGJjqa1DBtPTAWYDEIvluRDhSrSQTmXxclGAUaRtVCI84RkapSSxa+zhpgkfXPa0BvH6AUYdM5KgZQto40MgxTWPsjP26DRdhCjy3FkuZyJDxmQleitXauYLxMpigecpG3pCxTZ6o90+90jyIq2a6dEKZlmybQ+ZsXoxe/H+4B1im6mmc/AB8t80WKMxZewg/XGE5KiaR3OQUoj/Woglntl0TZ0RtPkzIOX9tlbzEpyXN7SYI3CGjA6FSlinBY9aaJUoeKKYXsIYghbqataKdQOGKW0otXic+GMfs/qXRfPXPwLRi9JDCorghE6r+jIpYlzzjBDFc8B+X1VDlYZL3UDiyEQycTyO+r+JKCKLsCbyIlTyjtpk+qCDKKC20oVjz55CCdGS00s3PQ9McRKZZEisWmEJVk9asqjNoSIc7L4pyzBAuTq2FVBUZn2+RjwMRFSxhRZWm4oHnqGWdNyPg5QYqMpe/nkZZAFAIxZPE/GEIuvm8bU+1ZrXAEJXBZGWNbCZrFaT0lGpFoYaqw1xHIvOGvJCgbvWQ+B3scCgu2mSdYNNBdZaW2uFTnuTGOUBi0yBpnISWfcOAkUmXcdXdfQugajrWz6CHvPWitFbNuI0WjTTKELgx/pNz39aj1dJynmFSGO+BKLDhI+kLIw8fqYWWTFgeuYu5aQFN/41nO8+c5NvvJTf4enn36arpvx/PM/ztf+4A944YUXeeKJJ/mxH/9xfv/3fo/Ves16LSavs9mMu3fv0DSOO3fu0HUtL7zwe7z03e/yxc/9GLO2oV+vsCWko94Hch5L3Hal8uciN8tZWCOliHNKngF5ZtQFFla9BiHGiX1U04xqYZdikXhUYwmETSkBCMLWmW4yChswqonleaGgQZh1uazlkSxMAV3Sv8jEqMhJmHiZCMaU1NMC/054XZ68pnyIjEECTOpzuFzIcxiDJ3hhwwkQZCepdOOaLShmHdq4MhlsUFWereQ5EymB2U5/KyjGVmZZ7025bwurbPuN5RPI2lGnsMuFMMO1kSGK+JkhkeKuFJb3FZTSaJcaovz37uvoC99fgDKlCwhWmWPbfzbIkEplg0maZFK5llvguu4LlfGSp69FUooMQ8JahbP3F7/ymUwut9DuZ3ifY8uIKNdbsX09LXJXZRRNaSbrPlklnhvvJclUyf0gwFJgM/RsNj1D8WoUWagwJlEiZxLwt7LlChCoVPGhswUwsDRtV3xSJKQopkjU6T2fqg5itAKjEgZf5Cm1cbgILgtbOjCsV/hxwLpGlHplmKF0wuJk30GBshjbiPzeC5PdWCtSovr8KSX2HgqG4YenTF+vTnn33Xf58Ec+zO/9/k/j/f3vvYKZf/nj8cdeICUFSPPdWINVmVD2J6Utpq6v5ZWcNdSE5nLFiEnYBCmpC9LjrJBhCkaGTlqxt5gzn22k7tndAxPkyORVoJVif3+fj3zoaX7ii5/jkUcenp6JcRz57ovf40/+5OsMfc8DD1zjgQevc3C4P4GwKSZu3brNW2++ydnJPcgBq10BYBWzWcd8vpjYwNpobAHlnbM0TmTDpmlQKjOGUPaViOK9LEEB89TWuuG+taoOZc7uHYOypKQZoiNFXzwLNQGHjgGtMklphtEXH11QOUp8Rk4sFzMJDTNaVBpa0TZ2CsywruHypSsc7O9hnZuIASkFQsrcu3OXxeHBdB1zzjJYM3oaMEYfyEpT3cAWiwV+GAneT32GMK20+PbFWADRPMmnQgg0bTMBAyDNf4xRvGW1nv5NAEgZvtc+pJR/9IPn1p2eWWdYLmaSoqnEj62pw5sQyUHqE60yJGjcjky3MMK1UlgFe7OO7sEHuLJ/iRuXTnl9eZPvvvIWwxgwRjHGzCZCf3qCj37yVz1brznc3+P6tSs4Z8WzLUeclTq86xpySgxmFEm796QwiD9pTLjWcnp6Rt97jOu4evWQw8sHdN0cU1jaxliapmW5XNDNFjgMX/va77Pc62hMIqPxgycoGU4opS8E7mzvyYyxipDuNysogK0BE4VuGFP1ntoCOfeDYNNP11CX8qemI9Y9NZdewygByGMZyE8ssJ2hx/0PUZXUy56TsTs1Rn2m2s6BMoTY44wrn/QDjlwZ/vXvMkhUiuJ/XN+/7J3eizdyJrNZr+m6Fn24x6zbp+1azu+evC8YeH8Pl3IdvBf/6fs8vwDxPjWao+Mz3r15lwfSPmSxaZq+W25lCcPQilTq0Zw1YJnM0MoRMzw5g0MHcyPP6LUWfu6q2LZ8vyNlIT5opckqY6ZkzYxzVoZNP8Dxw7PDvs+hdUlUDJn1yYC24h9lrGwSs7ljvmywRXo2DAMn3otPVZYT1XaOvrB70AplhN3k3FZvmu4rBnOGYfD0m5EMzOfbdB+lFM4pmhaUznhfGV8Czi2X+2gjRf/Yj6jiJ6S1MEJ0kum/spSpeZm4O5H+iGdGxpS0rRCjTC5BdMcaTGPo5oqmE92/MYaMyB+9j/SbkXEQtH+zGhiHgLYyIWo7i2tlkc8IMl2Lilrs5wSjjzRtAYrqgqHFu8q1hm7uGDYjfchF1lUihyviLF2gfG6rmS068eBy0jhmmCYGSgmDLqdMSrKYxjp1b2fo4qGmrcJZTVPAmpzFzDzGyOhlY+jziNYZZYQxZZyY8qdCFVdGJJSzRUfwUiRlZOOdiv3MlGSojOHsfMAWiU8ldVYZoveZ9UreQ0yRzZBJyTJrDW3XCLupUcRgycmzXkcxEM+2xNhuF+95Y9lrOlqtaJXhcLmgbZwU4cMAOYsfkJIqrcro8oXNeruYWy1pgsJAk+QvYPJxMEbYTMbaSX8NIk3cPVSWyGg/eMZBAD8BQMQQP9Ypa5mk2dKs7m6Gu/9bG/7qGaOVKiad0ozGaZqnpyJm22RfNJhUagsUy/+W5ypu5zh1+qP1pEG8UDzXDVQhQHcgiZTHSIBAzrm4XBYj1bJgpCI1DSkxFqCtTk9yealRgyGz8p4+eEKVaMp8UQCwCifksmGVewkEKJfCP08Sy846lBb5c0DOsVOaRllaJUwHO8nNasSwKuupPAchSTog990z05F3rxmlqCxJkeW8GqNQuKlIlLVRzPC7rqUxUsh7nyBrXLnu1ln29g/ouk5AxiRA8jh61v2Gs/UJ43pT7lVTmEACfsYYJXlRG2JWHJ+ueef2XdabAecauq7jYP+AeTfnxe+9zMef/SSf+9zn+cM//EMODw/50pe/zOUrV3juuec4ODjgK1/5Ck8//XSJJc/829/5Km+99SYP3LhGYw3f/OY3sMZyfHSXj37kaa5fvUIYe/oQmTVWJLVATlF8+BRIMlaahvU1veg9xQpl3S0yrF2afggCau0WeEZv5R61eKrR2go1TXy3v/m+S5oTOV0s96YSUJV1oVz3HCVllmLwXmI4pp+qskx23nN9zlKReoYQuH37HI2iaaWRG5yni+Jr0w8lEVBbtHZoLQXxRslaN0kfymd2bSuAgpVEWWstzolBvLNlGq6SLFhcBKpqQ6qm9KS6R6n6DYihejnHStE0W3By+k0VjKxnONdJ5fbv6gKidfFQO+BYRMBktctayrKv1OltygmTM1o5sqlATRafqTLdrgBRlX9UEPX09ITnX3yJ0Y90s46ubWnblsVcTLy995zdu4fOicWsY2+5oGvb933fme0dlVIkT5DY7o0k525yhCngJ0A2RnxBFMUTUmqPeWlaQ5B7orLLYqjDHUnVNeU6CDC6Tf3UhYHaNDJwqsBzff1wHytBKan/tNHCcFMZUz7Nexqh+jlSInjZg/044LoZKjvI8oyMQ1880JIwO92MpluCcYyxBAe4VkDUcu/EqNisLd1c8cKLy/d93Q8+/upg01/32KzXHN27wp/+6X/AV7/6qb/R372/PEZj0FqAb1dSd7dwvSZlYaWb8sxYYxgIaKULO0wYr5V1EWMkBk8ks/GjAGI5T6C00RpnHPNZy3zmCWko8kJDzqZ4uEYJxmoc1jk+8qGnxbS6HOv1mtdee51XX3kNYxQPPfQA165fmVLN6vP45htv8+Zrb+C9SMg2mxHdWPb29ui6mha5fV+Nlj2za6ykWDsLzkx1Vypps0ZdyIPcuT22Ndf9DFgZLCY26zXJLumTZcwCqIWkZfiYFAmLzonGGvHIVcWkPckgmDhiUsQUU30Jx8kTI8cYI6ERc0nEbAvDZxy9eEdaS9/3XJo9wDp5YZ1omHUdzhnGYT3VakZv29kMrNYrLl25Mq15MVT/vFIn1mEIFcDPzGfzAtaUwYjWrFYr2laYU9VmwBYmvPd+R64qq04IgXtnJyxnDuccbYfsX6rsFzlTLcTq/wk5lbWwfhZQBewHEb+YpsHZlsVszqxrMVaArDv3zjg+HxiGALnhvM+kWzexxpFyprWaJ598jOvXrtA4Q07iS61U9XUz6JWQNhJSysYoe7TVWti5IbJ/2HD12lWuXLtK13UTo865Zmd4LfXMnbt3yfmQa9f2xSuyyPjHcZT7bmLNXijWSy9rJJk01b5FT9dqOvdllif3W6mBlOwnlZm+Hc6oKQCn9kFTk1D37rzdrcQ2pdb9XBhAXjxUAcOkrpJaRIy7d6EuY7QMCHOaXq/WA/eVe9uaof7++vUsfoakEtSipOciK2FRIuCgpIEqybpNcs/X+377uz6YNZ4mhQAFPN6VD8t7X6023L59j8vLjtm8xVldPKDj5EustSVjUE6IB8o0oNx7wo3e6AXwuuHg9+6V86XgCwfwhyfv8wZ3C43do5zQrIrXt1XvWdf+ouOHGgiTAlHkOsGXZlSBbYQurI1mtmhwVmiYSmf6jZgvBi9paJT43OiFrbTLFNtKF+X16vQvxSQNfynGUlmwlAJtsihCdLliKpMpfj5J07YzMkFuamOwjStRvgqdFV3rGL1o41V5yGJKrM56WEmR1s2s3HzOMISAUVrMOsdAiAlloJmZkqAgWuSYhBk0emGaqSwslqEXQ3zjbDGLN9OkJhYZmm0sjdNUYkPMiT4MYCp8koqJiCw6tjU0nfhToQKQd5qiPDUuKFAFTJjNO0wjaVtqF1wrjAhVJGaZVJr3el1kSm9duebl50lbKdzoIzFIeguU7Sor8T4zemo4dLkOSoNrLKhM8EWmWdgVOe40YFkmc9oajAKFJpUTobPIq8IQGTe+JNJkks44G/E+cf2qYzmPaJOIEfyouXRgOD0JLLqWRdeK1BMxMJ9bR2skFCKTaZummCILk0oYVUJH10aVKXkkhx0T+uJ/p0oDKxtHLGbU5kL57Io3TU0BzDug2u6Ro0zwx1HQd2u2Bseq3DRpB1yS15WvBy+hBhMjkLqxSBpZiJHGSvFrtRSy1ZgxhFgAa8hKPnv195ONh1IE7UiilHhchJhLat72WXfWkZvMqLa+AkrLdQ/FLD8hfjYxJ2IBtnT5k3NJ8lMwJE9GNsiYBAiXiYtskREYa3kaI9p7xujl+SmmmErnCXCtLW6sjW25BjonKM4OukxflILWGDqtJ1mjVZpGm8IYE/q9saYUM7KOKS3Pdi1Aqiw1V08Rav2gJp8ykGZEAFhVgDD5xsaJaadMaNQEZLSuxTlb7k9JJbK2YTafScFvDd1shgL6fk2/2TCOIymI5Gkcenwx4Fda0zYts2aOyWYq8E/ON7x1+4h3bh2hXcuNBx9hf2+f0Y/cvHmLd956nn4c+cyP/igAv/Ebv8HlS5dYLBZ85jOf4dvf/ja//du/zceeeYZLly/jvec7z3+HV195icP9JR95+nPklFive8LomV29wgPXrrI+PyP5gdZkdJbpvLNua15etoWcwMdteigwNfNqp27JOz1tLj5JdWq5C2rE4j0ia7eeCjORzFRYNROTAqwwKyrGU++uMglV6J1kobx92xVMl/pL3vcEdKXpZ5JENl0wqq0Tx0l6kKVRG4eRtmmmKW1KwhSLkcLizUK/dw5nG5mCjiMheElvsnprCmvM9EckaMLgdK6RtKGm7HGT5Lb4kNkqe76P+7Q9RSK9UVGmpVpPxTlZnt9adG3XGSl8c0zUIXFlxf4gh5JFbWI3qQJCyjvbWUfV9uvTPUMWBlaFosqeraKZGAzjuOHNt2/yx1//Bg88+GBhZkmhrQ08+fhjpJR4+623SWHkcG+Pjzz1BI8/8hBtTSqdXk9uA2miiuHx+2Pn05+6RtSv692pcv26kfsZKpAq+8+ubJ2sSlhHWQO1kSFAGEVyCEWK3aC1ldCT8N4p8ZY1bATUsLYMQbbhJvefY1Vob6Mf2WzW9MMoIIxxpYHIqBgZ/YiPwkLvzIJ2vqTp5viUUTlhXZVOb0/af/Xffopf/tWP8LM//Tbfe2nxPnfIBx+XL284Opp/wL/Kmv23cfwn/8vfJYTA8fGHef75H/uA7/qrA3R/8o2/w0//xH+H0a6c47LfycIizXMsNXN9JitSluXeuLCulX20MlCHMnRTStE4kSQKJCs9QrXQrAmjZIXKYtHQNA1Xr1zhE88+w7DZXGjAXn/jTZ5//nlOTo557NFHePCBG1y+dDj5zIqcbs2tm7c5PjmjxnyMPkLKzGYi8a0JrCBrr4YJCNNK44zUchSfRxls1tTbLUZfQ3ymYJz7Gv265pydnbJcHnKeLD4bGfOlTE7xQrOeSt0rzXkmKGkrY+hhXAlrM6cSNFHWxZ06UtZ9AVCccSR58IrJvRiCL/YWnA0rfE5YJUytpnFFDlqiLtV27fY+sl6vsdYJsGgNulgSOOewRrzetoCXwjnHfD6fhj3yGSL9IGnP/dDTtjupu6iJmVT3xlyGE7fvHNEvWpb7+8yXYHeoFPLzGZt0qbfqPpvqRiFDvSQkh0x9PwL4z2ctN65dxjrDwf6S19++w+vv3OW1t++CcuQUWW1G5p3lztEprtS89+6dsLeYSdCRF4uOxazFGcPp6VmpNRTsmI7HlAgp0FrDvJOhWtfNaNuOfrPGDyOkjLOaFBJiRGHRRrFZ9/iwtwWddz24tADXSu0M6HOtT4Tpq019Xrc/ppTaMrxgkttWCeH3swWo5xFVh/DlGdz9vgK+Vcy4svFTTlPvV54UaglU956MgF5aCbm39kwKsGaGVm66DxRSR+WtJfD2+bv//e9M/FMq9VMSuwlTAsCaxrGYycBn9IH1pqcfxtLzvZ/1wXtfRz6LMMZFIr4FwECsVsiJk+NTzs8vMZ+3dI2jaxznBQjrB8985qS/UuLX1kx+bGUwWE7hd1bw63fkXPxJAb46Az9zBf78TP4+DTsqpLJzvWqfN51QxAfRlECBH/T4oQbCtCrUO7iwv6YQiV5Lg1cupLWatmvZ25Otre8lBtn7IFBOlA1D/Jzy9Psn1JfK7BI64lCMvcm5yBtL8a9z8RKr5aos+jEmFKIPz0pYGMZZrLOYMl0gJ5zVzBct2srUJYTK4JJJV9spjM74PqKNNEBhSALKUUzes7DinBMwLMSMHyM2G5osn08BoQ8iaSz+Z9qoyZ9GIYwdUsa4jFIZlBZTcKMZfC/RwdaIPl4Xs/4kaHXbWprWYoxMApTOE5NKEchKjIcVAmJ185amlZADnwI6C/JvjMT1yh6RIdWCVU2FRIolxlXQKDHjL4ysmrCRU56kj1obstqmqFEljwpSSBPwVRfc2nDmVP7EPE0NrNYc7M1xWkCjyjoiKyTqV6aPQqVPdK3IuFLMOJvpZpYYAlnBqBVOdSwcHCz2WLadyN60wWDkNYwW37GUaYqfCIBq5P1L6p6ZNudc4jdSEHNXYX8xgYLGiCeWNRpnLxZE1hXwKQt7Q7xMZMPWO1MVXeSjGZH4VmCrMsrq38vTNG1eWmvGME6brjxOO5MbrTDKbE352YJpldK+nfDUVJoaYJHLBgw1oS+XJNixyCgzcq90XScAThYgJ6a0jWcsBVZIAp6NSc6fKtc/KnmqG2OnKWfKiXOf6aMX8LO8FgUEywW4qxKpnDMqBSmqkGTWVEAvkUTubp1MNvIgAHcFOmRgFLEh0BiLVUrumQqAVclolUQoCttC2E7WGiKylqRcAWOkdyrXy9VgAiXAvUG+ppWAhDVNTWtL6yzz2UzYOcaWzVyhVXlOtBZQrGmYzxYigXS2eFaMDEPPZr1iHHq53lI9TW1cTaI0WqOc+EwZ1XDvbMXLb9zk6HzN4ZUbPP2hD/HAAw8UXwvL0dERv/1bv8Vbb7/N4eEhWmtu3brJenXGV7/6VZ599lluXL/Or//6r/P2W2/x8EMP4r3n/OyUK5cOePZjP8IDD9wgxcTZ6SknR8esz89YnR4LA0VnlBHg3RYJnzD5cpkV5uJTIqDBVL4rYQXvAjD1McsIeyXEspiUZ6FKDIXRqsUXhi21P2aPinXyXcEas7225fLW14s+ostXYmUFQim41E4RUjoqVc1/LzY2ximRf+YtM6gCGFKwaqx2HB7s0RQvGMpe7X0sZs6u7KdGgJ1SxMYs7CCL3e7LIUgoAWoaLIXqw6aKfKgCYUVW46rXmTU0tsE1bvJFnDwKTWUuiARTaT15GapcfPAogDkCYlYGV85p2pu01iU9shgX8/7H1FCVfbosHNO/X2CfySv+BdjCVk6pUhnwKQG/+3Hkzbff4Wy94R998Uucnp5yenLCZrPh9u2bfP3Pn5N9wTrmsxkvv/EOxliuX73CbNZNDUoFwXwMvHP7DkdH9yZG3sH+3gT8Gy0eJl3TsIvdlbt1Avqnm5669G4/3NRYlH/VykCWdTjtnCd5tiSRUs5pKiybNL3KhXOomMD66j8n3pgCJuyyLqcGvRbdKbLerDg5PWHwY3n9CjqoqbE1xuBcy2Jvn24mhv4xJ5wT0/D7J9f/+v8rJvO/8ZsPfdDF/cDji1+4y6/86gcBYX9bINhX+cmvvMZrrzf0/WN/K6/xo5/4Y9kD0ChtyeyY3Kupa5V6CrkHhJlamljK/ZMqULQF8km5DI5LyE9JFrQoLu3PGbzsibN1iw8wBhh8uX+jZuwD6/XArdt3efmVN3jw0cd4/Y032Nvb4w/+4I94+eVXcNbwyMMP8NCD1yVYq6zrPgTeevttXn31NVIKWGMZgzCu+ijex1evX2exWBZWGNOaRwp0rrJ+EZXJxO6v7PICLGhVTO8pjXpd3y42jUrJsDEDUTuCamRImmIBbS5gtsheoVhvetxsj6gqUN6jcwQ0VpcACqUuPE/jOLA+XzEOG0mttha3EwwSYmRUhmbWgdaEHHFG03Yd3WwhwRKcll6g+mZYQlwzDCNaa4ZxwDVues6cbbDW75J3xcOrbadapR7VaqOymurAtg50qkSyaF0ACCmy7jeMoefGGNi1c015OzTUutSxBMheLDWmYQrTvbmF95jAma51HCwX9MPIMIqP6+npmk2/xg+BgPhn+xDBaPph4NbNO9zRGts0xYtN6rFQ6ocJFLSWbC1xHPEh4X1gf2/B/rIh+J6z0xN6t5bgG+8JYUQrkYc71xBC5urVS2Ihk4pzVOnlKjNvDLGE9qjt4JwkzLjCjtNWY2NkNLYEkEgdINd6GxhUwaaUEoE07S0fdMgQQ/pBvXOGp51l5+ZWUPzBlXi5lphIxfY+ln21WBiUn8qIf66ogUXmaowrtRfTYHmqs8s72P7ZPXZAPKXIMU4D8liIDq1u2F/OWc47QkysQ8/5+QrvA+93KFX9X7evdf+7iFlIPLoO8LKoDnKInJ6ec/feCQeHc7quYTGP9KMnDuk9AFua4rs0KE3fb3i6C3yjtby6gV+6BUMSdhhI8uqbPZyJdSY/tg/9ejV95ouLz/a/q09fiAnl5fbebP7/QBr5QYhfyhSWWMQPXppAZaQQPlwyDCOudSijpoQiVJXiZYKJjFrjXN4u3FBohplh7en7URbs0oDnJI3PFPmaxSR/6KP4Y4VcppuZVEb+YrpbjHBzEtAO6FopyoNPrNcjm3NPGKUgMzODTrIwrPoNCThNGzEkL4bU1pppU0dlmlYLyOQzfrT4MRLGSH8+0nbNFpKuQGCSAsAY0d3GmElK0lpykg00s00j00ZfSEFSKFwjExujPUH7aZNQKUKOoPUUC+ucZj5vJM1z7cuER+iWbdsIaDeKJ1KO5ZZVCbRE/AYfMFXKqsSPLPlE9JUlYan+HqZMmOviNk2fi4wwlrSUqd0o4N3EzMmZFBJiniLTGfEws1idiywxCcswASjaVhOtMC1co1A6M+8s63UvliBJmqdGOea2Y3F1xv58j6Yk6GmlIErqn0ysJSmlRg1PgKHRU5RzznkyuK8TgeqDtfvgbL2H2Emx2v5bKizCfhiIUbz1ssoTEKYUtE6MwJ2VafxUXJT7QxpkOd86S/EQUxJfPK+mtMLCnRSAMjOlCeVMYcDkEsAgzY74AwrYRgF5rNXEqItuXk3+PQLmxYm+Wy6tNOeFJh9CwEdPTQxCVeBAipvBi2mz0mKgKninbIKNk5hwlFDjW2MJKeFJ29QmpUhKAC6FEqNfxLNNFQDXZ5m41oKrMNTRpXiV5lPuBaofSnnm6sYYirTMapmCCshZCwj55ElOamFWjRMtPythWFTQX5HRBTE0WtFaV4Cu7Voj61oq61qRbFqhy7euZd4tijdP8WNEWDht17K32BOAShuRFg2ezWZNioEQ/cT+yQWc1yictiTnaJpGjN+1w7qWputQ1vHCG7d4/Z3bPPPsJ/jSl7+MtZZXXnmF05NTHnzoIT76zDNcuXKFX/iFX+DVV1/l7/z0T/PMM8/w9ltvcvfuHVarFbPZTIqrMDJsVhijeeLRh3j88Ud58IEbWGMZBk/XNAxtQ/QN67NM6yyNUYCXhrqyKZPIHyqQlMklfe7i81gHd7ugccoZnyCELPHbiK9ICJEYg7C7tAQ5FNRyWqtijhOwX6eHF9lLFUSQdS7EUOjrAoT5EORZ1CIVq8BtmZHI+815uidUBVtTCaYon6SC0nmixsved3jYoAtzt65RFex2dhv5Lf8WJjlGKmbMYQwXhhWyNZS9oay/0nB5vB+ogQq1oayHLabIu4MEkekWiWXT0DSdSO+0+O1praX4UjsFOSWRrMhUxeNNWCOpMjCU8PNqQY3antft5DmRknhbbQdyW/Dyr3NkYBhH7p0cc+3adX723/mf8MJ3nufNN99kNp+Tc+YXf+EXePfmLb70pS/x5FNP8bu/81XeuX2HW/dOaGZzmrYRNnVZT9+5fYc/+vqfc3q2pmkbyJnLh/ty/5bglOtXr/DIgze4dLA3FeJb0dbWguED33eGrUmFImX576l9yFuGTy4yegGMBRSYgBGgSoiVQozxrZ28+KSWUZDFz6fuY0luYHn+tLDrNv2G45NjTk5OxGszZ7I1E96kyn3uFi2L+T7LvX2sFWBckr6b6e85w81bM57/ztVpHfirHJv+r5b6+Nc5vvKll8jZcOnwgBg//LfyGj/3d3+J9aqyTg0haYyK0zVXCrEaiaMMoGLClYFp7c0qEKZybdi2zW9XpIp1GCbDUMvVwz0OlguuXVpyfDZwvvYcnw/cOxsZfaQfA+Nmw+p0zdtv3eTLP7nmfL3mW899m0cfe5w//qM/5vTkjCeeeLhI1K7SNI6MDDKOj4957rnnefmlVyTwQktdIwNzRTebc+nSZZrGiW8ciqQl4bBfr2gbO20huQ+QxS9Xnq4KLhdwtsx+J0aY2WG3sj1H3gdm8yVZyffY4vgYqM17ndDU3y9rVztbbhUftpFQJJWEYaeYQiwqeOHHcdrvU5aBrHGFMJBlcORNh7byvGmjadqW2WwhRvjFbxiKJ6uSvXD0HmslQCrFNKX91c+utSiG6kBQaVEE+BBwxacMKNYlLf1mM90nmcwYBPTuum4rHyvnPKbEweGBDGaMmda0OshJ5b4zOqOMgJaRQM6KhDAdjRHZq9ZFql9qvITeMmPLoMVoxZX9BQ9c2uP2UeBk3GCQukElhSfTNC0pZfp+xIYkgUCpKoW2So9aE5imIXlPKMSPtnW0TjNs1rz1xuuoIjuu/3t+KuufcY579465dvWQtpsxekkstG0jdXwIjINn048MXvydnJU1V8R0mab6JDrNAjBNy7rfgHLkMniLMZb9WmqEWivqUiRXIPX+HaWy0RWgM2SVyvBRXRgOls2ZygCv108VP+l6zavcUVtZY3xRxVRJp20aqe1jRBfPx5xVGUALY3x341Pk6TNOIkq1fffc95zKkA2sUbSNYwyR0QcG79lsRt7veA/7c+fX33/Gqp2GopQfWcgU682Go5MzHhqusr8/Z9Yl2nbEjwLMS0209dCTQUREac2bb77Gl6/P6W5c4h1vp/rz8+/zXr+oMz852/Dq9747+UhPPWy5PvLeLoKZ/TBK0NWtO+97Du4/friBMJDFjUqP3P5bjJlh4+lXA20nxassohbbGmKQaXcY5WZ2TjFuxHtqEwJDH3GN2aHyQvAiTB5WwkRYzme4YvrorCkpkRBDZhwj6/XA2Be9ssk4jUjwKrNhAg0kwj5reUhyFsBJNL6ZFDVhEMP2HIGi0e83Y2GiKWhlA59o/Uq8EGIOdK6h62RK432S87JWWCcyupRSMV7OFxZtYw0xZsaYxXTbalqrySliG2lyU06TLG+alFfkGiaZjHzM4hyilIBhGYxraFqzZfewbdK0lql9TpmRQMgCAVA24hjCVpaaUgEXhKHnN74YSatJLgMl9TEXhpqShSf6wOglmdKobXx7bfa3/ixM0lhVighrLSkGrNNYAgpJMIoxMY6SdNV1Dm0UrtX0qxGItI1hdS6eFPuLjkZ17M3nXJrvlcJmuzrKhFnAp8YZutaJRCj66f1tqdnFVD1GfPCTMWimjKnLwq6MKbp98VQCLb5CO8tgDJ6cRoZxpO/7iX1krGb0QSK7taJr2kLJrdG+tSrbyoZlB1BCBY8JX1l85VPWBTOqSMzVy0Ekl+SMsiJV8FHOsdJ6apqN3nqDpNL0V6BHJEUipb1/OrILGocQGLwk8NSGtLJBUDJdDsHLFFaJCbpRYv48c462eEH5UFhKaGxNyUMCILJSpOLdVp1yIlFAA6XxCXwEoYvLY10BVZ1lUlL9osBQfWvqplwNo+s9WtfEVCardfIre18qXnthAhGEAWLLxiJ+c0oxUYbq+RKGrZmM4CXljGmdVFphmwbrXAFGCyigtYACrmE+X0xMvBQTd+7e5dbNm9hyXzaN0L1HPzD0fZlQS2MybxyNbdBzQ5cSbTNjttxnttxDNw1Zv0TM8LGPfZxPfOKT/MHXvsZv/eZvcvfOXR548EFOT074e3/v3+Pu3bt87Wtf4wtf/CL/5J/8U/7Nv/kNbty4gQ+ed955m8uXDvjcj32axx99BHKiaxra2QxS5ny9ZnW+ZnV+TyahbcPDjz8m00wSOY40dfKKeKPIfb419BYwJE/U74z4JagCc+oszE+fUgGeqtdTRuVITpGYJNlKm+pTIsl8WclzlvIW/DZK0gaVVpPpcl3XJhAqZ/FqQlL1dtNidyulXICI6GNhFxSn0yLHtdpM0d7bCffO3l33ai3FusvbgIzqhZMKc6N+f/WB233jdYAhsm75nKoUXlrtyurEONoYaJSjfR8WjlYC7KxWqyI/3TJKjLE0rqNpO1rXSGptSQObmHJlulvBaescrmlxzpHKoMJoOSfsSEIqYLb7fmIMKNMWT9CdoUz5zNN5rAX7B00Fd75vkn0gDcl63XPjgYc4ODjgW9/6Ft/65p/zI898jH/2z/7nfO+73+XW7Vs89aEP8cTjT/Anf/RH3HznTZ777kscnZ5z4/o1Zl3H+WpFzpk/+9a3eevdO3zs2U+CUrz68kt841vfYW9/X1LXQuCtd28RYmS5/AiZVEzwxykx2zpL24mM9T2fJ1fwawt8kWXPT1nOfZJFqBTWGmNlyBdjKGteZcUVMExv1zFjbWGFVcmrQHMxyfOiy74pnlIBVCR4z8nJCXdv3+X8bEX1Be32t/5QlYHStDPmiyVNI/+WchJz92l4qPkX//Kj/Hf/4i+bEPne49/8m6t/7d/xlz6UNHcHB/v0/RN/47/+mY+8Stt61ufyjCcUY8q0pu47Yn5unMVEiwrbYZIMarbDoloTmpjwZWVTlOFvYfVvhoHGtdP+tjdvaJxhfzGw3gROVyO3T9a8e2clKY1KfBmTD/zB1/6Ab3zjz1Facev2Ea+88irXrl3lqaee5LFHH2Vvb09Cd1JmPWx44403eeGF77JabwBLSKHUv4qUTfGnLNLOVBJXMYRxYLM6kQGXklo7jD05epyTwBBKLSEN+46sq9TXlSV+oXdKojQZY2Yx19g0YpLU0EMZKCYUGAcpAAllNLPZTFKk6y1hG4IydFakoylFrJFnO5bBRii+x7NZN0mZ614jipMtkzxnSWBsnMMYSQkWoDvi/YjZ2Ru8D1y5cg2FonWtsLwKgJLyNmDGlJpIQQElT7hy5cp0n0itY4VjV1iEChkWCtPYTfdZHXZqa7jx0IM461gs9iZSguxlMuTQBfQxKhEVJKUwBRy3xuKMwer62UuPqxQkSEmCQ7SC2axhPrTEkDjcXzCMA2erMwlGKgMZYzT9ENhfLrh0aS4DVx9YrVesNxtGH/HFuoVSP2MstmnwwyDkAaXpfeL85B7rzTgNEqpNiSugWFaK23fvcunwkyzsAh+2g1U/BkIUhdNm3TMM4gEMYDUYrehay6Kk+mqjyfMlTdswi900aIoh4EtKfNs2U30bYqBrHX7UF2WYO0ee/h8FO5BhdqnSi5eYKv3fdu+9fz+q/WnOGjQYZwrQV/eH7ee21tFYw7xIlyOUYImR2r5PeFQpJKSGKG8SXfoyNV0fYw0qSu3YNBKWEWMkpMwwevqSnvx9D6Wm16uvduF85R31gip1pxLl2Wq9YRhGYpb+pm0d/drQ2Cz9TrlvxUdcBg85w8vf/S5Po/iPHnqIbm82LT27rOv6d4Dbt+/wzW98HT/2U8KthNfVILaCl+RYFHue9XrNetPz4qsvf/9zwA85EDYhYTtXUaT7BXkPkbGPhNGjnJgphhjEP6og2UYLzdD7BAlOjnvRZltpnoOPVGmVsxrttBg5WmGYzWYttrECUilFLE33MATWq5Fh7THasDhshRmoIMdcptLC6ohxlEmPyeQovl6xULm1MoQByEXagirF2DYJkDrlYkfCUgrslBOxRPxaZ2kmaZSm70aGjZ+moDlngk+EFKEMzGIQhphRoJ2gz9lq5lao91YJUOWDn/TyFTjSBozJhFBklyGjyhSmGi5IQ5YlaRBp4m1NbdIy/fAhEJVQdmPOYsBegJ6UMs5p+dogGm4/RDZnAzEkmSQlicpumoacG5rWYYp0SZcPGn1gvVrjdEPyImc01mAbi2u2MdiVXaFK2uEwjMxm4HSPsw6tDD4IGzEWJuBsblnsNVirmXWGMHju3R3oWsveYsZ+u+Ty3j57i/kEal04ssAejdEYqxjCIB4YSNMoaXBBzm/YNkaxMouKVLduXq5pQDvikBhHz+i9MHbyxckgcUSRxffOKYhSFLQlpTPE4j+WRFbclrjnyo4YfED5wo5AkzIMIbDa+EmOWb2CQk0DA9nkSmHtg6Tf6ShJM6bQ65XaGrprrcg+CzW3pC5OFvOlgaobyMQa0Vp8Ywpb1Htf5J9xAhNtVcCkCtSlqdkO3uOahv22EZNaIISy8JddVtdzbmRLyJPJfyqTzHJPpSSx8FmKabMzIar7Qi5gVC4sF4WRNEhVktOUMFEdBr0z/RawK5KKN5gUi4VGXlIKdZF75SzPsc4Kq+oGpgq4KCBY2wqwU70UGycNZMoZ7wWAdE2Lsa5487hiWt7Qth3dbEbTSIR2P/ScD+eEGDg/P+fmrZvMuhnz+RzrNCptU+JSjmJEWjZT1za0xtG2M5SxzOd7tIsFxjieeOxRnnvhu7z44os8++yzXLp0ieVyj7feeJPjoyN+93d/lyeeeJIvfvGL/NIv/RK//Ev/H/7+P/gH3LhxHe8D3/nOd3j5pe/x0AM3ePyxR3jgxnWy94RhYLNesxlGhqGYY/uhbkR03YzGgCGh1XxqciUNMqGSGInH0jCThAWss/gvSsEhIEksF9+XND1Kwx9TManPSoxTsSjTMknGsshaxjBIPbElAYokV8cygCmJo8VjJSYB/3MWOYWq90gMEzhc791MRmtL0yzI1ojReXluSdIoNaY+02kakOzGlW+9sgQ4FIsAKaaXtqVrZ3jvGcMgAENKKLVlEtS1GCQkprKLqzeoVWbrURECfgykEIRF1AortZpV71Z/3osh+6ZfMxYQUJpGi9YNjWuYdx2tEwbRJMErgJk8E2La37YdznmsFUZm4+Tn4443UGXRmapZQp6fnHMJX9ndBoqs6744dKPNNKn+oEMVBkj9qDFGVpsNz964gfeeF77zHV74zguMo+c//A//I65eu0bTNFy6dIn1es2m79kMgdfeusWrb7zDYt4x61o2w0gMgePTcz77uS/w9/69v8/zz3+bk+Njju4d89kv/AQHBwe88cbrfO/FF3j31h2efOJxzs/P+e7Lr3L36Jh+GHDWsr+34KEHb/DE449MkkpnRCqFUrIWVdZX+SQKYc28p+9RInlVeWt8rZSZWCAaGQQ2dW9XO/5tZZDiYyzDE0fTyL7jx5H1ei1snE3P2ekppyenjONQ1nVNR216FdWDbj6b46yYV2utaZoWpS2+LvzAL//q03/hNfxBj8uXR46Omu//jR94XGQefL+jafzENgnRcXT0Nw/E+SDhA0qLZ2zMid5LsmCigJ1UmbNDFTl6SlsJW84STGCxUwiRGrb1AYDRwrrqh5GuEWbd5KmpW1prOZgnDpfCurp1dIbRiZw1Q3kuV5tR7iejeeH552nalqc/9DQf+ZGPcO3q1cIAFDD63skJb7/zLnduH0njWxphAfczfhxQWjObz5nN5lOdIsBQJIYRXSTDKSb6fk2KI86aqbnWMsGdGk2l1DT8rl5DdYhahOuklNgExVwb8D25D9hugVWFsW8b0BbCAFkM0FfrnkX0W4mYMuh2TsaXZHI4PDigaVvImfPzM87PTkgpstybM+u6C7YPgLBLy7mMKYtvGpq2m9M0HcMwCCDVOFAZaxW+xM0tl+JPNZvNJnJAlZRKImPGKGHVpJTph5Gz1WbyupVrb2iapigudoYS5VpVaf62Pyjvu2lYLpYs9/ZwFhSJnAI5h6mYMyUNWH6dDHBICWXEUsAnhO1dBlmV3xej1HVVHVFZxpcOl/gYOTo9oetmbDaD7KtGArn292c8/PCjGGO5decO6zc3IiNOYnWia6KvloGQWcwxWrFczASwwbFaj6zWGwE9lWboPcMwTmwdFMyXHeMYuXfvlPWqp+9HlNGcn63w3pefKX9Kza4VNM4wnzk2Y0/bOjo6ZnNwPjDvJJAupoTXAREyJcZhzWYYODo+p2ssB8t9fNuwKUCQ3rHPkWdBoXQhQ1DnerLepYqMTf8rF7kCUtPzVIkR5VskKCwUX9LCHKYGPliWyznLWcvBrOXe0THKNWRW+BBKcF+a7pxqIpOn9wBiRVP/VRVbB0dMAyEOpOTxUXG+ySiMeKzetyHu9pT3Sz//IhAMmPbbrCSFXpUgvfW659adY5Z7c7pFx2LesTrfSC+/u4WoIlour9tvNjz3zT/nheefo22chLbFXELMApQ+MJb1dBgjiYw1gtnEEGgaR9e1khKeYRgHTs/XjMPAvZMTTs9O2fQ9r7/9Jj/I8UMNhKWMIF/VXVhtz79WNVZY43uhUYp5uUcrkazIBqmLt5QXUMY0rM83UhCnwBgG/OhRSjNfzDHREEKmdXJRXS3gbWFApUwYE5vNyDiGYmJnJ3Q5jInNec/B1YXQ75FmXkz4tp8t+EgK0kznFAVIiAIcxdIc1kMpJUbSQ8SbIMWelgdXa8NEsaROqjVq4bDO4DrLsJLmt/fD1OgopYihFHPWsNgvrCM0rmnIpGlSlZIkBhprcI2bmgdjJMErE2kaR38+iq+K1eSQQCusk4X+/HRdUF5Ju5TpuWjvBx/KhF/YeSkKCwClJFTAQBrLBh4zYRS/hhjS9DBqpRmGAa0OZHNwGk3CIKh61za0TgCe3DpSSPjRM6wHcsw0XYNxRfLgZALQn/c0TqbZYtSvaBqDHjWbzShMLiOhBrMiQXXa0bRzkREGzcG8Y951NNZijZGIYx+mxbReM60MSquJ7QUwX8xRSrGpZuIpvccCpHpjiMwplimWsAKsc+RC+YbtwndRHikafmM0q3UvQQ5e5qjVNDmlxOlqje2FrWaMYSxG99YYulYaQIUWaW2RBAPEkAjZTxN/SqESM5M5JQqyoTRDeZqSGWOIMdCPApalmAghysTAqAteaXXCmnPhURXKes6ZkMM2Ua1si4lEjqFEqst7E0NaJU1Woa5vr9G2uY9JJmxZyWfVBbSYJh5sm3irVMFE5HNqhAVWMhBQSqZlOoPJClX84DWqTA3BKSN08lIgmcI8mXzisgArIQQwW6ZdbcTrNZd1RT6P1VoYP+W5E9+cbQjCdpMTmZkGiS9PmaaZYZ1jNl9y6eCQ5XyPxjXyfhT0/cBqteJ8fQ5J3tdsNmMxX9C0DXv7e4zDSliaBZh01tG6jlk3ZzZf0LYtrmmLn4VBIRKPlBI3rl3nycce47lvfpOHH36Yn/iJn+CnfuqnuHP7Nqvzc6y1/Nt/+zt84Quf5+rVq/zar/0a3/3ud3n0kUc4PTvlrbfe5MqlAz7zqWe5dHhILiyQod9wfnrKar2amIhWCQNFjJo9TdMUP6vtM2i0QTmR3sYkmsKUJD0rIoBizLAZRpQyEwsolWc2l30uTqwXuX+iMuSYGYs5c73/UhYzXLLCzRp0NbKNEKNGF3aZVpGmFRlxLIOUmOtrliIobk35K+AeYsDajHNM/n0gHjA5ZxmY7Kxdtvi+5JxYD+MFYEwYdLKe9X1PN59L3W+sMN58JqQoTcQQmbzIchUGSxNRCz+dQbkC+paQNUkqtHi9wziu0niYrGWstttBjBJZeE1UTVEBnhzFvF/FJH1gCgzjMM3jUtI0zoHSMgl24pXXOhmouJJqaKz8cdZNZv21Ks2pyMdtALWVstY1usq2prUnbwMXPugQ77Sy1iDs9s1m4PqNGzRNw2c/9zkef/xxHnrkEUIIPPetb5Fj4mD/gNu3b5NS4uOf+AQPP/QQf/LHf8xzz7/I1atX+chHP8pbb73FAw89zE986Utk4Gu///scHR3xyU9+kq/85E/x0kvfYxxHCXuIiZu37/DC917mtTfeZv/gEvOFyIheffMmb7z9LveOT4QxkzNXL1/m0YcfYD6flwHFFgTbXUen+qb8H42AUUprnG4nPyTxrdTT0NA1dpp67x4pUQY8W/BwHEbOz1cc37vH6ekpKUbOz87o+810J3azfRnmxEBb1ryu7URCJSlKWCvm+MJc2+7zp2cdfxPH8fFft6z/wUEwgHF0GKMJKfGtb5wRwvu9/l8OXLv/iFGhDXSdE/uDHOiDDPtUFEZ/Q0PwAlDNnSPmxOA9MeZiQ+KwJjOMA+MwynNT6UDlIqekAMOiW0qAAVVCaEoVLdYGFHbPcm65cyJDXF32giFl0noDxcvwoYcf5JmPf5RHHnmUdjYnZqmD+iFw7+SU4+MTWUMU6C7SDYYhiMUBKbFcLkua65yz1ZohJKnJCntNQLEkfppjjzOKtoYI1ZoOxFvovrUkeGHXSLOa8H4kp8Rm6JnNWkKxjZBfEPDDipQDSsyPZH3NkvQs7Jd221jLxEqS24c1OSWxQbCWs7Mzju7e4u7RXSByeLjH3aPjqbZV1a+t7C+rzQZfZJVN29G2F58VVWq0rrOM40AIkdPjU65cuSQ2FjufeRzG6XVSTmjMNDQ0zrG7FFhr6YdRbAfy9jauzNJ6civIphC5JEqJNFIhgGUcUBfWrYuDkJjF9mO9WRMYiMULeYgCkGlri8dkKvejEgZdRgzwyzkYfOTxhx4SRnjOtG3HCy+/xOX9OT4G3nrnTW7ceEDeV4oohfgUNu30vo02xKJssOoSt969xSMPPcjesuFs1WGcQyld+uKSpF48hFVhtB3dOyelM5FmhsDp2SlnZ2eFYV7CEcof6TdleJ1yoAmGxiynOn8YPOuSYuq93Ktd12K0LufJsr9coJXn9OSIvUsPEVPAB4r9TTnnSSaDIqXVZCp5RHH/9llJA1CVQ+Cj1Pg1/VPunzwRDmqdVIIjpX4JgVljefqpRxlXG27fvM2snVNl+7tLolaF+6Wr6mO6vcp7KutPHAlqnAaCKUsapy5KFSmFtvvibt+xqzSqv7QyxXfBsqn+K3RrVQJwlBYrF5Ri7QPHp2s2/cje/oLcKLaWE/KgyKsVmwddz/30IvK762cr5B1VGGS5DOgbp6fvgcRqs4LUlmGkPLvHp+e88NLrDH3P3Xv3GMeR0a8n253vd/xQA2FGK7LR6DmTLxcF3GqdyBp9HzGuwfuE06lMvEeCj1KAOkPOgbZzIudpeiCzWY8kZ9DWsGFDCIHVeQ8YrFV0804eSg2qSCJTFPrnsBnp+5EYIq5xZZosm2nSGZLFj4l2VthRZDarAdea4gOU2Vsu8L3n5vE9yLFi02LnlYWpBmKOHmNN7KKusOQkD4B1GtfJ57xw7qxivtfQnwfauYOocJ1m04/0K2mSRcOcaTpH2zWEkLDaEH0kpkDeoVrr4geTUwYtm2rbKa5cmYltZ86FthoxWiQHrpE0zxQzaYyEIdIurDC5jMh4fBJGghTAaTLzN0aarVnrCmgYS2JgYhiqHJALnjjOuqmJUsrKtSgL3Xw5R2vDOHphbcSEHwO+OqJqhS1myv3Qk4UHL9I2bbFWinzXWiBijWzKxhoWi5ZZ15BCZtk6Lu8vsEWC4UxTUgL1NKF776JcvOTUFtionymUqUJtVFXeFjoAIUoxOFFTqRI4NQElWusJ1KwsCdngNG7yR8nT1EwXWWhtvIUhVqY7KdE2jmEUfbrEkQu6r5LQwRdNi9KGcewZEjjt0M5MfnzJi7G/AFOAFlafVgldJCnyHivA6QVYRAC/Goigdja4usiG6v+VL6bYTNPRnc1pOtfl2bXGCvMxjljdYoskqqYskpVMp40mFYq1JYvhZ0qTXxOUzV9nDFqSIJENwWiRR25NVcvnRFiBppxzoxWzxtAZg8OSY2LMXsxHnSvrji4bkRTuMYXS4F1klMj7UWS0eHWkhLESlEABLJxzkjIJzNpZYZBCTIFVP2CUxbkO1zlm8zn7B4dcOjhgf7FHYxv8OHK+OhM6fi9T1xCCTGqzYrPecPnKZZnsUiZ5UQrhrpsx6+YsZktm3RzbthKtbgwYCUwZhsDp+ZoQJUL6wx96mps3b/F7//Z3eeDBB/nkpz7Fq6++yq/+yq9greXWrVvyWBdvwxQ8L33vRYzRPPPhp/joj3yY69euknOm73tUkeFqrZl1M2L0xHEjfmA5C6MvDILYKn3hGZ7YVAXEDyGgEKZxRuFDQmtDCCLZrlNmeW5ExkGG6q+VEL8x74OsfTFPQEeV/6RSQCsXMBiO7l3hv/p//a+5d3KVpx9/juvX3ub27QcYfYv3lnduP8asvcO//4/+Wx568GWUKutuigUkLr4kBRiSZ8ZjlSNTQdRU1txS3Kcd49SJsSZrlzWmJGJpyBrTtjLxs5akFfdWxyiE9VnPHzv3bSbTey/DA2sYxu33yfKQ0ULUEulbZ7CpNGsyop/WPvGvg67pJn+YYRxom5Zt6qxBYSbAODthOVplp3U0hMCt28eyzkTZQ1vnWM475t2sMJsQs2qtadsO42RdaZqGtsgoTd9LWu96I6zKtpXnWWmxO4hxKjin653u2zR2Dkl/ylP9G0LgfLUCpbh27Tqr1Yr1as1jjz/Bpz/zae4dHfH8t5/DWsts1nFycgLAM888w6OPPcp3XniexXLBxz7+LP/w536OX/6lX+ITn/wkn/jkpzg6OuLJp55ib3+fL335yxzs7/P6a6/y8ksvocnMZh03b93h7Zt3+MyPf5Yf+/HPslqtsMZwdnbGV3/7t/jt3/2jEqBg2VvO+dFPPcvHn/kIi8UeIUmAyIX04gQUnyORipc1s+5T1exY76aBUxI9ywAz5/JzRfJTJGjWbv3b6j6gxbWf1dk5q/V6ug7BSg0Ri1+sgOKKxVyYqkmpqbkTA3/Lq2/s89QTp6zXfx0G18Ujpb8dQ/y/6NDasF6t+Pbzr37Ad/zVQTAoQJjOtJ3FNYZUG12j0aFIZCtjVSl8Shi1TeKVJDHpUHMq4T9BEhZ3F+sKqMy6jkpgVTANngXMzZyuBt69e8690zXVn6zR0MfKVpV91jnDhz78FE888Sh7+3sovfXE6fsNN999l+OTY5RNGFfu6RjI4yjBJxk2m2LZUB7gKukLqoJgwjY/Oz3h+N4Rzigu73W88W4u/raxcEm2V0EUMXryHg1BZIrr/hyVNXfv3ONsiDy0ZxhHqUnHAClrVE6oLKEqRiVU4+i6Gcaa0pwXdQxwuvF0OaCtZT6fc3p2ji314t2jezz/7e/wykuv8plPf4rbN99mdXbCfL6Hcy1kGEOkD57j83NJvEfRtd3kDVWBzHEY5RkMW6XJYjmXawxTzRyjpEDGGEViXgeTpUZtXcMwjBfBwhAxRvaOKo2cAFTFTvO/lWc3ztE1FuJYmMkX1+dJoldA+NUQeO3tI24drfAxMgyetmm5d7Zm1raEAjIZrYs81JT7soIhZYgKKGsJMbJ/6YD1es2HH38CnQIqJYb1mhe+/bwoOkKic2JLs5g79vcXzOYLmsax3JvhnOGbX38OpRX3zs548skHObh0gDpbs1n3xDJYl6GTAK+LxRKV4fT0nKZrISU+8clP85u/8W8k9G0U37G4OxTOleWd0TlweLDHOO84LNd4IjNoTVMTi1MilAdJlF1q8oJbzB0+tKhx6ylaw2zkEVLl/5eBCCKJTNMWWc0ptoeEyW2vXf3fKpethzUa21iaEtyVEvhh4Ftf/yZx9GSlGM9O2AxjAZnqulNqUTQmK8YylK/p39N9kzPoKmOd3p30N1DSZMV/Nubtz+RiI8B9oN9uL6k1F37vNCBSO16DBWMQawzFaj1w6/Yxs3nHjQeucnK64fR0TVV8VTxDIV52zuhpf1Y5EkOpw1QJxTNGfNMooBh16JcndvWVK1cAJpavgKsBpeDtd+8wa5vtYDy+f1jA/ccPNRBmGytSPWQRs1qkA41raBqDUhG0+IEpbVivArOZZTNEUvQ4l2ljYjYXPbQxBtcIeOGKB4h4dCXUIFtJinVCnFAaVicD+1eErbNZDfSbAT8GYkjiB+IMzUxMq7XRNI1mYzQ5QAqZri0Q157QT3OUzWu96jHKcLC/x+lRj/cRYxTDxouvCkqmIhUUy7mkeGhcY+jmhYFRgMH75XY5Z5q5pWkNm40neYgDktiViweSVuJNExJh9EAnMjEfOTk/Yf9wvyRmxmnCP9Gu/UjKgdnc4JwjJFibgXEUqaZBFbNYoZ47a1htRtZnI/GsxzWaphHZZMrQtoJ0h9HTLVqsKr5LpSAOPk5m6ELTpUzkHdY5msbhnEHbwt4xBpRhQ0+XRQ40X3S0JEZfNpbiK5fL1OJ8tS6MKrEOtUYRIkU+kZnN5fO3rWOxaHFGM2sbLu0vuLK/4NrBkq6VoIO7x2sSAiyK3FU+h3OWrm1RUHTvZUJWEPPq5aNQ+NFPi/GupHH3Wgv7J5aGsPhSxYgp31NTdWqhtetJUxusaYqgimn9zlTeVcldNBhd6PaDxPo6Wzy2kN9jEJagmVL0AipLf5uzBDJsfcFAprF11SwJl6Xh9iFM77NrG2KIkkimZJImxUn5fYWJUKnkepJPQ/B+atjfL29GElOkYEzFsyrnhA8jqG6i1Y8+4KPER2M1XTtDa82m3zD4UWR+qQQxGIWyikgiZb1TEMjGUQL0LhSuxV0CqxTWSIyxUdAYCZ1IWdO1bXmWLEZLCmjrLDGmIufz8gxc+IQKGWGJzCKEEWNdAY4ledI6W1ig8iy6pp2uYQhiStt1c5bzPWazOfPlkoNLh7TWkkbP6ck9zs/POD0/YdNvZINWmkW3YL5YlE1cIuu10qw2KwHVXEPTOGazBfPZkrbppNEkCdjnHCGHkgImwGY/etbDGuUUTz39BH/+rW/z1d/+ba5eucJP/8zP8Oabb/L2W2/z5a98hbfffpu33nyLZz7yYf7uz/wUQz8QcmA+65jNOvq+p1+tCMOA1XoK2oCSOpS3iY+iTPOcbc5wVjxMTGGohRDErH0ci7l4nCZjEoUNiVGm7wE0vhTapjx/cgckJFE0Io3cMIzbgUV5Xoq1LjnDyelVvvG7X+HbL36O8/VWrvTSax/npdfe60W0GR7gv/6X/9v7virv0+gzFvO7PP7Y1/nYh36Hy5dukukZQ0JRWJda1qgKRk6+VxkGHyaGjjGGkPKUGmVKmpBxzQRuxlGA6W3herGRTimzHkb25/PipZNLgVbkg6MA50pRzPiFgWULAwsohbMEwtQBB1AYbG5aU2ugjXzOWjzK2XZu60Mm63fL3aO7DOOAUjBrW/HRyVIPhBQmputm3NC2rSSmOieAWNswn88Ly1ICJWoAinOOrutwTUMIQYY8WqOli/v/sffnsbZl930f+FnTHs650xtrJKuKxXnQRGu0JMqyFKeTOEbHLbcaRhqxgXSCALaRTmLESCOdAd2x3W0kSNxGAwk6bXTaUOJWPEjyKMuWIkUjKdEcimSRRdb0Xr353nuGPayp//itvc+5r16RlE0qpqQtlIp17z3D3nvttX7r+/sOBWic7tquAzx7AZXz6fqes/NzXOW4cvUKr77yCj/xE3+Dy5evcPfuHf7gH/yXeeyxx+Uzq4rTs1O0MRwcHDIMI2en5xwsD3j++ed57PHHeeONm1hn+YP/8h/iU5/8JJvNhsViwVNPv43DoyPe9ra38+LnXiT6DqVgvd1ydHKJ7/iO72T0nr/3d/8O165d5/u//yP84O//Yb74xS/yzne/h6tXr/HRX/sVPv/Syzz1xBMcHQqbO+bJZy9NGYKlMKcENEzhECUsRav5v6dGvAyr0ijIwqrV++ueUTMrZVoHxddLlQ1/LkxAkY0rt8AWsFblisrVtE1D5SqaphVzd6bQiEwOkf/8v/oO/tH/9Az/+h/7OJ9/6eRNz+PX+nBuxPuLgNvBwYb1evlP/d4xZbbbDdvtV+fJ8ps9xtFycHyMcZdKvSd+nVFXxMQ8H4M871FJbaiUNI8mvywK+BCDeApNh9JGGHvzf8MM+KeAT1CEVWyHkQfnWx6cb9h0MgZKgcbC1fjUY42iPVhQ1zXPPf92rlw+ueDLmHNm9J7b9+7wyo2XcdYQO5EADX1X6ln5CikJ8D0MAzkFnBVvu8mHJ+fM2G2IY08YxbD6fDuQQpyB81TYP9Msqo0uzTKxhbh37w7PXr+K1obPfupzYvtSaQa/a95hK6ytcFpRpwHygNgsWCpXcXh4TBxXUB1JUpzSnPYjT9WJpm3wfmCzTjSLBcaKF9rp+QPOz1Z87Nd+nQ9+4J3EkKjqmsVyCQmqqsZTNrsxzsyrVAz3lRIPsKPjY1KCrpN7mmLi5Zdf4fLlS9JEnRg8Sebemb2zv64oAUDrpp5/7gtzdrFo3gRITM2ffSBMKcXlS8cs2lrUEE0l8/2Yycmzz8eZ1sDN4Lm7Gbn9YMOdB2vun64A5kbtm6xSKOyhaX0th6ucKGKKt9rtm28I2K8VSiVsCQPJFHBPGy4fXeH45JB2UbPervHjltPTnjt3xWvKLRoOjluM1fzSxz7F0eGSrh+wxtK0wv5bHhxy+dJVcspcufbYfILaaC5fucQv/vwv8cSTT3N6+jlGLw0+X9bB/UNpaJsW52raqqGqqtLauAhUu8oKEDbVPQpAGPqHB0fEMGAU1FYxBGGfCXMyTySkuV5CQcgXZcFqDmShzNfTIy5/n5D1PGdKjSLPv7NidZNiZFE7umHA6Mx2tcKV+5RyZuj60uBjR16R4TcnKM+MsRyZGJk5ZxIPpyCqUvXpGQxL85uKNUyM016Pi43JqTmpdud6Ye9Y6ik9JWWW75CT4FwxJc5WW87XPdpWNMsjrl7L3Lx1n/PTBxy2FtsUwDpbjMpz6vz8HEx1m8oXfz5vgErTdPYj1hefWWR+7PueGEauXz1ktd4whh5nLX3f89Uc39BAmKhM5NI1rWWz7XFFk2usBZ3QJrNZ94R7a5RS9BuRZvgxcHDUEosRoFLM0qh2UVNVDaDoO+kMGy2FdLftZMOqLf0m0OfNzLgKY0RlPbOcqsrSNI6qdSQf0UlMJSfUNYVIKjHzVotJccjQnQd8n9B2JCSPUlMUtKHfjujiYq2Kp8jU2ZwoswqKUR+gMnGMZCMb8EnWlArghqJE3WfymIvhv9CAlZFCMo6Rbj1ycimhnXz25UtXMM5wuloJsGUUplVkL2aGoQ/0fU8HHBwsWRwsqduK4CN95yVRsxPDw6Z1tG3F8qChHyLr844weM7PN7Pk0jiDdZqkIk1bYSp5oLzPO8DKh1nf75wtEhcBU6pKgxKvMFe7UuhE2CpSs//w52IWGgm+aLiBoRNqc1VXaAWOhKlqkcpG8cgQo/6AVprWWR47WHL9+IijxYLGOQG5nOXO+hyDeNusxjWUAlmhWC5a2roWya3R2CRAmS6AybR4CPNN/BFyYaoYjBimxp20MkaRdyiZU2Uii5GqmbpdgbGwt6aO2cRezFGuR+Ws0KG1GMv7YpQ/saCGwV/o7sSYi9wYAZhS2SQXM+JMFvPwYs4dYyKy69xlhLUx+TrELPIUrRL7S6d0iAT8mgwzl3Vd/lYWlN6PJalo98q0B5zkPRDRaWGMTaPBFn+IylVz927/PUIMjEFYVv3gGQpLs17W877daE1tHf0Q6KMnqV1YBsAQA+Yhj5uJCYZSM9MjZ0hKOlfiJVF898hEQimy95KgkFV2CiFQcsF2LLEUBQArhuLayMZB5ENCla8akSC4Snw6pnE1se2aqqE5PmG5XLJYHtAeHLI8OKDvevzQszp9wNht6bcb+m6D96NUO7aa/bNySvI5xT9JZJwiS62c+Gy07XI2u0UpghID5BAj3egLA1TmwMlHIKfEU089yYMHp3z+xc/xsz/3c/zhP/yH+RN/8k/yuc99jueff57/31/9H9isV3zXh7+VJ65fJ+fMtt/Qjz2r1Tl937Ner4jBc3J0zGFTE7qOruuIfiRFKWynxFxTkq26oZek4Jhkno2iAUhTZ76AuzHuCrOg9rqkWSTxZjZ7Q/y9lEhL5SibtBgZgydHzac+87188rM/wJ17T5Pz1yo5Tj4npiPO10d84tPP8YlP/ytMX0ypgNaJGGusGfiWD/1Nrpx8iYPlbXI+QZuKq5duUFf3ZrB9ZhEX2ZgypeHhAwnZ5Gk9EcDKOpWzjJ3SOVZKGhHD6ItcAVLpdk5rnDbi49h1UgzVdYVzO2l5KubAKe42RhMYMgFdxglbyxknxeYe0JRVLj5i8sMYJZBDvNfknNASTNKPIjkyxqCMYTtsSSnRapFF5pTxSWTnfd9TV7WwFIqHizTV7AyGNYsFbdvS1i1V26CUeGXEJNKZHS+lSFC1mtPStl3P6ZkAtleuXOVTn/okN15/nTu37/D8O9/J4dER165dE7lM3XB+dkZd11RVxemDU05PH3B4eMjVa9cYh4FXX3kVVWLRf/5/+jk+/elPcvnKVbbbDZ/65Bv8yq/8Cm/cvMHbnnycumlYbweauqFdLLj7yit84h9/ghgD4zDwrd/2bXzkB34f3/3d30Pd1Lxx8wZ3br3Bq6+9zpXLlzg+ORGpuUR+yf2Y2RnTw7E718nLcK6wp03H3t5yap7s/7fFFD8yqaP6YWC72XD24AGnp6dsNhsJj9GaSk+m4UD0aHtYpPkOVzXFFN8h/n2Jj/3GNf7BP3qOn/v5ZwD48b/xbu7f//onPT5iP80wfG2YaDnDetOxXE5+N+orveQ3dYRYo5Vjc3ZKiNIomKS+lbPkGDBWgOR5sxQu2ksIq0CVpET5eVU5tHNk5PmZplxVNtfzNVNqrj2ss1y9ckhX0tkerLr57yIih0MpjpYtz77rnbz3Pe/h+Ph4ZjCANOC2mw1nmzNevvtFjswxNZYcRJ7oY2nAoUWq2HWs17KHMdYWALZ8Zgxs1itWpw9Y1hX3Vc+1y8dYWzGMIz5mmkYCPmJJbp4aKSBNtlfeuMPdszXXH3uMxx57nM9/4SW6zVYMua1DVS3aOXy/JnZnmNSTSRIUVldoIkZ5/PY+ursD9hDVXObpK5cJ3Rnkyc7FELoH+Azdak237dC14W1PP8GD+ytOzzY8Z5SEexWw21WOe/dO2Ww7aQSHJJv7DOPgWW+2WFehjWW3SY70262syQ/bjGjxiXN2l7A+kYW2XfemOi/verHzMYdmcTF4xijFohEmqLG61I3ihDmxdyU0yRCzYt0PrLY9dWW5fvWYW3dXJdhIPFkfDniaDh/EJ3ofLJsAvhSKcgZZMl3prFaVBLVM7Nas4Gyz5my7YRhHQkr02y0K6PqBoVuhtKFqWjabDh8jd+6fsmhr2rrIKK1Gm4o78ZymqVj2IoEfwogxhoODlne99528/73P8/KXXqXrevG/fmguUkgzAi3/jKEkjaJQ1pCIMyE8pvgwkRNbOY6WBxwdWNr2kFdev03OiUVl8Ebhx7CDuvKs6i0AE4hlypvhkL0l5cIASClK00MqGlJUaGt54voVNpstldGMfkRpGFMikKkKKy0VEIy8k/pPhDVp0kz7ewH3JvA+czEFctozlgkHsrClJdhBnh1RV8sekKzm95oUChNPdDfNqQs1kC4EiHkuLJYBKEBDyInVtueNO/dplgdcunqNg+ObPHhwl5z3Wu4lJCzP85aaT0L2ImoG/OTn05Je9mbu0VBVjJ6+71Bkrl85IaUjIHP/9IzXb97Gh/TI1z18fEMDYeMYiEGBisQobK6Dw5blQU1dizH++Uqo695L2pw2hmZZk6JMqBklsqJ+KN0XkeWkCH6IpJBwxuGMI6bIol2AkphU8f+q8L34vijEV8RokWI0jRizaxQUkMoYRV1ptpvAg3s9dSOT96J8Z62FPVYtZJM+bAqbx4q3Rd8VRLgMJqUUyjpcDVUtzCeZgGGSEvpNpKotYx+xylAvHVll+iFQVYblYY2iAFKbWnwDxliMgyPalUK/DKqcMmlM9N3I9nwgJaGsTylywYtnGEl8qIw2WDRNXZEq0Hog+MjRkabrPFUl/kMhROrGEWJicx6ZfKOCl9jVLgwoI5rxZiFgg06iJROwRdO2TdnQ6ALoWNkQKekioRQZYfPl4NEV+JSozNQpSYydx49lAdKK6COhMPJyykJxrYTtZJKhWdT4UKiuSnF+b83jh4c8ffkyh20ri6LSWAxxyLS2Yps7ckoMw86XqaocIcR5UpoKujn9LQhINx0z2FW8bKT7aRgL+CM3Sz47xkSYumpGU4UwG6XWVT371Wgjn2mNJWVFCp7gJZCgrRsJAyiG0hMzayxBCUCZuAGyMDHLRGu0gFOpbEK1NlhXk7th90CrsinJFDPrwk5LSABBMbNXSlFV1VyATJPlGCMuSbofCJtR0jYDcQ9Cm0AYm4tJwfSNszAtJzmWs466lsShnDMhBrTWcq4KRh8Z/JacpWuhClvLSNtIgGRlqDBUSqOSEkAE2diKdVgSMD/JojYDaNbM482HRIiZMclYPXJiZq/UbgETgKykDZaNyCQDNkYo5TEKOGOtRmkLylwo+pp2CUpRVcJSaWoxmRWT9UyjGyYadVVVHB4ecnJ8zKJdooth+vmDU1anD+i7LeuzM2IYp2b5fI+NMSzbpVzrEGiAaqbBT1LMpgCcSWjP1mFsRVaKIQT6PjAMPf0w0g+y+dAlHKRylTB3neL5d72Dbd/x8d/4dZ54/HF++Id/mKHv+Yv/1X/JF196iQ++770cHh1z5959YvTcvnOLbb/h1hu3ODw8EOaNNWhrGaOkU226DbkfxRRfi9xJG/H8kzTTRD+IBGBfsjZLXQvAUwYdY4h0oSvPdC7336K1lRj0YpCf2RUqMSY+/8Vn+Ye/8KPcu/8M/8ss5YqcHZN3e4g1v/YbP/KIv4scHd6jcsLUHQZDzgI0BN/w/vf8Bt/+zR/j5NLAU0/1LNuWyia69ZboIxRQISF+Nj4EYvZEBvpO5pu6qTk6ucTR8QltuxTDVm3YnJ8R7t1lHDy9V/Q+AnsSy1yY1CEQg6epanKMLJuWqrHU9bIwASXE5kI1nGVOHUYxDN5ut6A0db2gqoQpVFeOummo66p4FMo8cuhqfBhwVV1Q772rlTPbocdmyGGUz0mp7MYMZ7qk4GmDqyphWBhL3SxoWwmiuHLtBCg+iSpLQlsGjWUzjpxu1mhraJqGb/7mb+HP/Af/JzLwgQ98gBdf/Bwvv/wlvvO7vhuU4uz8TMC3puHGjdc5PT3l2rXrHJ+ccHZ+Tj/0XLt2jaEfuH37FhrYrDfCLvnsZ3n5pS/wjmee4sPf+s1UlWOz7Xj15h0+/+KLfPjDv4c/8Sf/FL/wCz/PJz75CV6/cUMCLi5f4vjomOeeewd3bt3ifC3mwkbtGBX7102VGkshEo+3xGH2wLAvO7KVSNFjSAxjwIcothHDMMvoVQHe97szGkXbLqRZVh/gU8aPUr8oY8lK89d/8n38+m88Pr/G6K+uWP+nPUJ4M+jlvePd7/win/v8c1/h1V8e3MqZUm+//8v+3T/pMY4OZytSSGzXwphp2xbd1OisSKpGG3uRMaC0dP/2zkHWFkPTOmxVPKICDBf3mASf53pE/Jh35zSGyP2zFfce3CePPVUORBRRSRag4oDDNnLl8iW++UMf4onHH9+BJTlBCpzdv89nPvkZPv/C51lyQM4DmzCgh0xMEPd429o6aealiDW2rHWyGQ9JQotCtxbJolK8/bFjHr92wmrMrIfI6nyFa5b4CPdON/SjF4bues1LX/oiv/rRXy3EAcWiblitV1y7ehlD4t7dB1y9dr2EnwwcLBuGw6PSUA3Few0qOtR4H2MddbXg9s3XePa9l7h380UuHbT0Q8/q7C76sKE+OObW3VM+8+IL3Ll3m8YccHp6ztHygLPTe6zWa5KKnByc0Cxarl464fKllqFfE2Pg6OiYxWJRlCdemt9qmp/lODw4vAA8zvc1hAvesdORUmIcBuqmpq52z0mMschkBeiYxtaUsO0qd4ERlsmk4EnaSrJjAeJTiqKCMbKWCBgZiT4RfOJ8HNj4wHJZs95WNHWNtYa790/f8pl4eBrbt0aYG9NRmq3WKsaCLiSkuS/N4F0Ijh8DefDFJmUsw7WQAkqTJxQf2X6IEghwsCRmTcqGnC1NXbHebLl+9RLbruPqpSN+9Ef+BTIK5/4Ef+kv/je88tob1M1i9jkbxqHcx4jSU3OxjH0lTR1lJplducpq73bPTWfDydEJ2yFcaGxYrcAZUtLkEno1AWl5b1pLGcoWcV5a8t77X7z4spDEEBi9kFTsQrzafs8H381Lr9zgdLUGFeb3GVLGqCKNzkmUAEUeOZ1vvvARE3A18FbHBOwx3dMJ6JrOjVI2PMRmTCkxZaBeGEc5k+bzn8CvMhfCDLDKZRFQb7XacOPGHU6Oj/ngB9/Hrcev8/IXX7rwfAlQm8gxSdDc/P2LdDvnOcSAvU8AYXr3fk8aXmoa4kjwPcO4IaZA29SkkHhwfsrtu2cXVEBf6fiGBsKGTS9MFWPFTNAhRvAOAgmfkxicj4Ek3GbpGBWJ2Dh4qjYyRIcOPWEYSme/IQXF2I+EUSRYxpnZGyeFSf+q56jh1GdJoVPCbpH30aVzbVDWYM20uE6MnsjQB9mYKvEhcS6htUxQIYinjDGaui6pdJYCMJTur9Es2watc0HnBTDLCcIYZcM4BmJhDaWcOPQ1x0cLFq0VzXUJL2lNBRlW5+ILE5Mn5IAyatbkjyHgKjN7dcWYsM7QbT0hiD5ZaVmQF01N2zYCzhXT9QmhnTzL2kWF956qNrjKMI56BkKqpoB6WbovVjlC9pKCGVNZhET62bTVzFCCwiYo4ILEviacVcSksFZTKc9mHOiHSF1ZbJNJ3osBpNHUy3pm7gQXcU7YMCpn0pDpI4wbT7Mw2AoOlgtCDLTJ0J4ccGW5pJ6AmvLPhMJ3fV/YSDsPi7lpnbP8Pu66VSkmKIEK80SkEJ+yUoDmnAUcquyc4HlBg58ktjkj7ZDRj3OSinWWw4NDkZqFgA/CSsgxEYtx/yyxMVrYapVDaV3+VjYHFycx5o2CtUaM3Y1mGEdyRiKtlxXNMOIqhw8elIynGAS0jiHNi3WMEZ/8/L7NngHqhTlh9GQ0WpvCWNY4UxUwMc2dZKMUTVUR4i5NSa6VUNYzQsufPOYmcNVow5g9MWfOuw6lDI2tRDpXqLsiSSiU3JBQPmGSwiZF7wugYXa0dqcUsZyKNRpjpVjXSgBAHzKhSOishjFnarV7fWUk0WxKw3VFurNftIncWQmLAll4m7bG+1C6jgrjKpq6ZdEuqFw933NlFVVbsTxYUlUVbd3inKOuCliVErduvMEwjty7cwcFEqigMns1Yjk/J15fi+Vs9HvB7yNnFnUrwG/OUujnRKUVSWXGECRtyHu6ofjaWUtKwghcd1symco6losFV05OqI3lVz/26/ytn/pJXnjh07z4uc/ROMNHfu938va3PUUMI7dv3eeNmzc5Oztl9APn5+ecnZ1SN4arV6+w3VxlsTwQYDBkxiEzDD1NZVnUjuDF11AXtoEPJbFs7xn0eSp0xCdBSJM7JtDekwPFnDmSiTkyeHj51ffz0d/4QV5+9Zt4UyrGP9OH4Xx1/S1/+/FPfz8f//T3c7EMlCJQqcxj1+/TNB2VG3jisTc4Pj7lysl9Ll++x1NvTxwsBw4OG6y1wn7VmqwaUso0LhKGc1axJyZfAHzx7hC527QREHbs+TjSuoq+20pHNQjTRCktQEtBdXXxZIhJpPhd15NzxlqDtbZ4TWZSjjufqul5txalNUe2lbHyUArkoq4ZvBdPRSsbvMmrZvSe3otnqXMVSmnUakPfD6Asm/UWyFy/fsK73/sunnj8MdCaEDzjOOJj4Pz8PuPQ8+orr/AX/m9/nstXLtO2LYeHR/zMP/hpPvbRj3Lr1i2WBwecn5+zPl/LWmsN73r3e/jhf+4P8Oyzz/Lcc8/xyU98EmMM168/xrbbcvfOHa5dvYQyIg08Pzvj6OiAb/rA+3n6ySf49Gdf5DMvvsTNN26xWq+5desW3/qt38aP/JE/wsd/4zf4yZ/8CV566QucnZ3x2muv8cILL0DOXD45ZtE2hQUkICNMBb6am+LT2FG7IST//CaxJqWkITKUlMjNZkvXdfSjx/sRnROXDhf4EPFjnIOMlkdLnD7k1u3HuXZtBdnPLOechRHzwfff2QPCEnfu/tNLEwGOjwfOzurf1GsOD9b88f/9j/Ef/2f/Nl335cz63xrc0lqaUzFc4xd/8d/9TX3+V3sMo7DqrGuoqgVGa9qmoq0ddSXz/9Qo2H3l/c3f5HPqgSjWKT4x+ITZm0r3GxephM9orbC1sAtRko59/doJzlmuHm85X21Zb3u2Q2LdB556rME1LQdtg4mBoeuE3U7m9ddfZ7vd8Prrr/Mrv/qr3LlzH61Fwu3HiAqJMea5aMw5s1wKsDqGQdY2pwnDls36nNF7zk4fsOrGWWmiteKd1w558d7AEAeuPnaVo8NDhlFCq3zIDF6YVEYbHn/8cWJY82sffYFLJ0fcu7/mlVfuou0CbazI2ZTi+Kjh3p079GNgcXAkbEgLR63l0tGCdnHEZr0hxMB3ftv76LYbrj17jcevX+Ntb7+MYWBztuWzL3yam3fvc35+RlMvaV1D6xrxqg2Zrt9Q1VI7G21YLFthOeWpIR8ZB89mteH0wRmrM2FvXzo6RldWQMkQefKpJy/s9wC6rczro/dsu+3uxueMc471ZrMLUUE8mDVZnm9TYUwt9hzRz02yhx+NFIL4RquShheiECe0pl3UTJjo1HA+WLSiiGkbxl7IG9tueBOIt388isWaszCITF2RYp6VHgAhZMbi64x8tdJIneYmaU73YZKS7T47eo85MFxeXqZ29S7opXJUtainKmto6prj40Pe+97n2ax7rl07ZnV2Ksw5o3nm7U/wTR96D/dOV2y3W+qq4ehwgVGwXm9Yd2KbkbHCwFbyRWcu5l5Gky7k8Bns0WCc5ej4mO3te9MKMF0drNFkPfknFnl0nBJTpxNlEkjMP1NKGKcxlRThEEsy/ZS8HksoXsJWslfY9CPbvqd2jiEEnFPkZGjqFtCETUdIAbIw2bNJM/s/7t1yuf+PlvbJsrajT8meZa/eBFTZC2tleNNeSU0suEe8d2GWqQJSTdeePXBtujYK8efbbgZSVpyv1tRFzTQx1iYVwKTC0XnvRqLnc1GFDTefl6L4PUbS4FmvN1SuqGRylHCGJIqme6dbzlYDKWa6fktTV9x9cMpXiYN9YwNhGSlU29ZR15q6lUJ4HAO6xAeLwfGOIp+zAAgToLXTjBeTaVejlCWFYqRailFbPMO00SIzzKr4HBUE2WRS9jgnG0qhMO8SwBTgtGEMAWsNKU1yHsgx0a0HyIqqlpjoMIzFb0wYZnVTE0Jite4I4eIGK/jAYlFhy+ehxMMshWLArRRjiIxZHvocJaGsqS11Vc2bZqUU21R0/yVJzxQ5nNFaWHQpo/qEroQpFUNiddbvALvGYoyibQ1N20jEaXkItl1H5qLGV+WIHwfOzkZi1BhtMVYMBy9u5sUHTGPou56hb9FK4s/9KP0zbS2TfMYoLWbfyEZHG0VIeZYkDiGijcUtxMB4HD1hGORB10JLt0bGk7HCo5VEHdisB6qk2Q4eVI2rA6NS1JWTBI1FRV05TLnvwuKQ8/ZepEwhBpHeOQd73jMhRlbrjQA4xUjZKIXaB8HKMYNdeScHql2Nt54xjPMYUUqSK20lRbIwkWShHIaBw6PDWS7U9SL98t6Xa2jnRUWSA7V4qRX2mouCzocYH7lwC5iiShjAZIIIfuzFh6IV3yeJA44MaSBmismpMN1iViQ1mQwj3QP2qQGAUgQfCGli2Kn582c5Vtn0+t5TOUtb2wvfERDD8nI99f7ioaTjJh1nXQDdDASGwj4zZY6ZPku8uyQNKOWMRXOgHX2OhFHCOlSQtNGCY83fR2jOzMaiSgkIZjQkBVFNXgASEpKyKtHQap7zJskoTH4SMham8VgZS1NVjCGSssK5BXXdSJLl3jJbW8fJ4pDjo0ssFgdzd3u9Puf8/JSzU0lRa5qFmIQGX6RLoJJ0cOS5tihbE1RLoqFuGmG9xYTPCmer3dJewAm0oQ+WftXPoEVm559BLvfPKHwYsdbQ1g0HyyWLtqWqHJeOj7HG8Osf/wS3b97gfe98B9/yTR/i8PCAbrvl9P591qtz+rFDGTBRc7BYsmhrYhTp3Tj0aK2o6obsZZeSUQw+YSsBSWJMJB9EGl6kmtO9V2WMGm3QZvJfkGZK1ppm0WAnc2al2MbAjZsf4K//5B/h9GzHHvntfTy82RYj6Ddu7fzNPvf5dz7ylVXleeZt93jmmXs8/tiKpvHcun3Ed3/ni1y6csQTT63IWRo8IUq4ypScmkJk9JLQ5sdAGAdUSngfCWHLOMqzGEs9EQu4Yo0rYTWB1XpVwBlTuuzi9yhG6btCdP43kqYVSzEt52DL/KGpXUWefNbKRGdtxtiEtpFxHGdpd04JVzeMg2cYBrZdR9s67t26S7/udg0yrYjBM6xXXD1e8vjlIz77yY+j5gQ6S4henuEY+Nl/+DP8xq9/jJde+gLWOX75l36ZD37wg3zoQ99EXdfcvHmTW7feoHIVjz32GN224/T0lKuXT7h6/TIpJc7PzzhcLjg6OmT0njdu3UEbx3d913dzvlrxEz/xN/n0pz7Fd333d/ORH/gBbty4wRs3b6KU4nOf/Syrs1M+9IH38K53voPFYnHxGqoip9B7wBf8E4Nf0xGCZxh6Nl1H33cMw1j8R0eyH6mNxjoJUhCWhCTPGWdol1f4d/7D/w237hzwHR++yb/7J38R6zZMJtuZxL/4L3yW/89f+VD5tK8FoJ35i//lP+T//B9992/6lX/q3/rLVJUi+H/yrYCz0mD6yb/1RxHm5Nf+0CqVkAhHXbUoMtZYnDU4Z5h83C4cSuboSaK++7WeQa0QPKOPaOUwVYvf7tgXsz+jkvUoF8aNUsXCom25eiWy2fSsVtuSthsZxgEfRh688TovfsLyuU+9wJVr17n62HWuP3GNFAOb83OmL5SzFjC1AKZjTMRYmvJGau+7d+5wcHyIMZbTswesH9zh9PbrnJ/eJ4wjcYgXvvcYIrakovfrLfVyyfFBS2sdm8HTD57DRfHBHAaUqnnHc8+QsqJpD4kJVquRxXJB6zR17Ri3a3Qc0UV2ZY3G6YQziUQgp5Hlclksayx3791Aa8OHPvh+VDa8+OLLYsrvB1TSLOoly7Zj6D23799juVxSHyy4eeMNcobopXF3fHTIevWApmnJOXN0fMJ2teHF0xcYh4Gz0zOMUvjtCtc4Fq4itg3PPvMsTdWQYyYpkTFra1geHrDMsGgXc806jCN3790nxjQ3sEFAxbap6LoBpQxaV1iD+P6lyOhHScTNwjRzk49oSmD0bNswSeFi8eyamsptW+GSYQgebTRXLh9xttowjA/Ydg/RFB86pnVlWj+medFYMQkvZeRuXOSdty97rPQJqA9Jgg9STOSkAGn8YxzGWppW5OxVXRXFhnjDNa6hsi3aGvoh8OTTT9K2CyqTWd2RPccwDGw3a65dv8bTTz3OjRtvyOfnwlDLcl2srambGuvqh8CsC7h2aSZfBMZSTDw43WC0veA/pva6IsbsOiZKS2J2TsWoX+/+fmKLTVYb1kiTORWGsNRpQlYJIQo5oOz3+mEEio9fl/FW0/nAatOJx21KxSsZYdIVblZOkRzD/F3hy9z/vDsPWe6K1ct0zgVYAvXm2qPUGGrPBubie5d33Cc2THat0/VmckyU+Wa1WvOlL77KpUtHLA4OePbtT/Pg7m20kX307q0LoK3K9KeFAESpcualO0nTL6bIvbsP6LY9m+2W5bJlGAZh4oVIRsLgzleCldSVYhw9Q/Cs+yjMoa/i+IYGwuQQemJdSyqTRpFHichNZLRRVI3DVpJG6BpHvagZukE2VjGRc8QoR7NocZUTry9V0gqm8Vb+SVHYSFZbtAFldpscNdOy1R6IIw97VjCGRI5grcYPUeiHBcgQlFNkhSlG4hjRSrM8qDBaDGJdpaQjOYZZ0eUqS91UKGNxtZNiNwpoJIljYi5onBTowUe221FMfmthc0zxwuM4Yq2iri3QYJ2YNRslG9nRS7KNtZo4iPFxzjD2ApqRYRgCi6XDWvkeMzBQTjUVjxdnM5N6zxrDZiMFe+e9JEmkLICUuNtDFm+r7OUahTFSn9RUtYBV227LMA7EGKgaR7WoWCwsxlSEAN3Wk3q/5xcgUsrpvUM/Qs6SdEImhSSIs1FoMgurSMowjpFLjx0wDgNPLg7wecBHz8mypXFV8SkyVG4n3UtZmCwAPoi/xWG7LKbkhhATvnT7Y4zCasoZZ8U4v64cTmm0ubg0xBQZhqEYMytO9CWM6Wf20uSoJZdfl82O/DwkuRZVVVG7ihAj26341milWbQLrJbAhMmAXRtN09QsWlncxhKfXDmHtW9dACukexPEJX0eC8MQ0MWQePI6e9NrC/siJkktms6nDXFeGZWS58cP4pUVSprN9HpVAAhTPLUozA3v5Vo3jaOyln70pNKSke+c9saLjElrLLWrQcc5rTUmeVZVEtYbhYkmE3rpVKOoJ1Azw5ghx5KigsI6idCe5Pc+JnyM4iOFAGB6+kcVw/SUMHstD60UPgZCUPN1qyrH4XJBM8lui8JKa8NyeQQKqgxKO6wVholQlSPOOZbtgpOTY46ODmWOGDq260DXd8KaKfPbcrnEVZVEk6tM3dbFm8jMLBqlDNo16GpB0zZzIaetmdlhqEJ9TqXZkDKDD7Ofk1J6ZonuDW5J01RQWcfRwQFHx0fYkiRqtOb5dzzLpeMjun6griRE496dO5yfn7PZbuj6jkzClrmyaivxsUuheKZVhYGjOF+t5jSqtmnJRTKXURgr6bqidhWfSK0n7yoJHpCUpeJTozJQcefuJf78X/rT+EfIl373+MrHODpe/MLjvPiFi6DhT/zUNwOgtTDHlsuBb/vWL/Lcs2/wrnfe5PpjqxkgTzGhUialQA5inTCFk6QpcCOI3+AEYPkQ8KMCvWQcIt6LpcCUJOtDYLPtxO/RmMLYhpgFWJkaCG3dlPMYOY/ij2IQk+Np0t9tY0Ty6EuastZRUlyB5cFC2FsqcXp2yvlqVUyHJckwp0C3XWNjz7OPnTBGhXXVDBJoo2iblstHh5yuVty5sebxq5fwIfKxX/tVPvOZF+bmmTGW9XqF957Pvfg5zlfnEgrhPYeHR5yenvLg/j1Olg2Lpp7L+4PDQ77pm78FVzlef+01PvWpT3Hp8iV+8Pf/ENeuXePs7IxFu+D09JSDZctzz7yNK5cvyfP8UGc7k8UzTOWCLk+/fxhU/XJH8epLgdGPxOjZdh3r9UYAxxBEmha8NCKS1GESfGJo6gWLdsny4IDlQcv3fOcN/tpPvptf+egT/B//zA/xZ/69n+WpJ1fldZHTVaKuPMPofhPf8a0PpTLPv2NFPzy6nL985TPcv/feN/38nc+/yrXrHXfvX8KHt94KVG5k9G89L/kga/i9eye/uS/+mzgWC09MoTT/SsLangxSJIy7e56iJ8ZQ/JL2tbLTOqNL6Tc1SpOkQiNA2MQSF2aDlz1B0CK/NBZjHVXtaJeGw+MlV/2JbMD6gc1mjfcjp0axWZ9z+eo1jpaWw9YwrM4IKdJ3a1bnpzODW2M4H9aEnMEqhq1smo8ODqmdol7IeplJVI0wsoduy9BJyj3akMNuI3nnvIeYudw4zkLAxECl4drJIU+27ZyUi5LE5W3xdlpvxai/Hzru3l9LymLXQcp0m8iiOmLTjxKGoqWGXm23nK9WWPeAECKXji6z6XouHR+Rc+LXP/6peZ2W2ljWRAPCvt0ObLed+AaPnlu3b9O2LR/6wDfTto7gB1559XXWq3Oee+Ypcky8/toNIJX5rOfJp58CIi9+4XPcP1txcnKMdY47d+/y8ssv07Y1m23HdruhXSxoapFrnp2fE0KYvVGdtRekjlPgkbZuHjOUIChjxI8u+MgwBoZ+YLl0pWFsGdOuqZliIozFy7mkdYJg9TErchYrlytXjhi8xznL6dmaTGboJS1ToRi9L4ntEyNWfEJ9kehLuJN4r1rbsN3uGEVqf3pkYkjuWIRSi1myTuRkxMYjg06+pHxHqlrkkNbZubYuqAig6DrP6nzLtceukmLiySefpq4b3rh1m9MHp7ztyes88fgVbt++yzCMxTdOmkYoha3ERiCmwG4053ntmM/loflBKVXq1Yb7p2fl+S2Nc7VrMF58TS7N4uLRrHfN3+k1U8iCUgpnDSfHB5ycHOBHz+n5mpTGwgI3ZR+fuH96TogRBdRoxpyLbDXhfZ4BPl2k/DEXgAgh1/h+wFXNQ2e8Oy6ywdT8/01pfGfEU3rfc+thaSR5yomf5JE7YK380Vt+vvylmv8NYj21Xm8wWvPMM0/zxs0b3H79VVJdod1eUnMWv/OchHEdkxfvW4TI4L3YEEyBd8GP+BC5f3rG6nzFrVuxWBDJTQrAdgz03Ugu5IS2dpxvelASmPfVHN/QQJguFzD5RPQJ55gn3BwpaXmKunWYWlMvNK6yQocsDCehRkoakDb6QszqNCxmA0IrpWhKkayLBBBgHhTMPllMP1fCXEspoJJl6D3bzUi3HXFWEOnkDLkgy4YyWMoDbK2ZjXN7P1DXFj9axkE6CHXtaNuaprW0jfgHDH3AF6aE0SLrVNYx9gMjMmjHwdMsqpmtlcvAV1romlVlcZUtm2eFQgyovQ9U0wYWJTG+Kk9pqWJkGTK+pEPqIrtMORO9dGWsFm/ZCUCsKkdKiX4IeJ8Ifooq1zNYpWKAHKkaRyKireL+vXOatsJVsjk2STafqqQDaatoFoaxz3RduvCcU66zUWCJbDYrrHU4kwVFzga0mFbWlcYqTYyWxhrqqsIdHBbpmmVpG44WLU3lJNkwZ2rboJWb55MJEFDWlq6SlQ7nxK7pusJoKjJGhPUyjqNIFI0kAWpd4pOrit57rK1B2SLRFV+unDK1rcXXLk5eJlaku1qTyKy7iFUJWzsOmlq6VXU1j9mJNWQm/yO18yRTqYyZQo1wyl6gk+8fYjicS0KiJ6Ys8j8zyYzEy08icNMFMGwaAzGD9/teXuLR9zABbaKGWytee1N4hHTgkIjkKKwQpYU+LwCeKkkoO6rwtAGmACwxCYNkivDNQNZmNqVMKQnrqQQNTF5p3ocZBDVKEVHYlFExMSASTRDjb5MVXYiMIYph/MQa0tNCJ//blG5UzJEQC9tVnl5CjrIIZnlutC6+g9pQTcC2MZLIWDeAJmQlSbt1hdWm+FOIkblxFoWYyG43KzbbtUhXtaaqalwxuO+7HlC4uha6fC1A2G7rLuNI2wZt6xKEMLE65BnxwWOsRdwOZHxk0i6pNGdi8IRtoG0qQOSopoCpB+2CqnIsFu0MgonUdwSVWR4sUAo26zX37mzYbDZl4yteK1I3FOawEkm1LqBDZcXrMEUZlzGNxa9FQfF+opQUTVOJJL8kNTlti5dYkdSh2HSH/Bf/z3+V128++cjn5nePr+2RkuZ81XK+avmpv/2t88+1jly9suaDH3iN7/nOz/O+97zBwSJcrAFzCZ8pUsqcZEzKuJmSiqWAE+aQzNsCyEPwUthFVQI8xkFkFlE2NdVUrCUwSuiCUqMYSavLU56VNBPWm56z03PQmn4caZYHuLoRRppxVI2BPDL2vTTnENDAhxHve4IfZeNlHAdtQ8qqsMmtNDysbPSvXr3MOHoW7QI/etZdJ9IQ3+F9YOsFCLx+7QovfOpTvPi5z3Ht2jW0Mrzwwqc5PT3j9ddv8NiH3i/zkLIcLBaE8RavvvoK3/t938cf++N/nNdef51nnnkG7z23b91iuVyWYKIN56s1t+/c5W1PP0nTPCz7K1dl1shkZEf21k0ZmVOnHrpsCHTp1MQU6LsNfdcx9j1dtxU/zJRmg+Y0e+VkrKn4tX/83RwcaH7oB16hbluMtfyxf/WTfN/vvcX/9f/+YV67ccSf/g/+AP/On/plPvih17l/qvhzf/6HvmYgmJyTrCHj8Gh22WNPvPBIIKyuPL/wi9/C3/o7b2aSnZysOT09AOAP/Yu/xF/969//lp+fkuJv/uT7uX//ayPxfNSxXMjaG4Kw3StrRSolReTM4gh+IMcgNfqcOjuBeFONolGYeV2EQIoB77u9c5pMnXPZrKey+UsQPVkVNYimMLccVWVZtBWHBy0+eLSt6cuGrKkt280GZSuGsWdzdkYOwlhwxqDRM8NwqsdjlHloCoGJwZONJmbPsBWQNkUvTJIUyHusjX6MgDTaFq1l9D2619gk4zzXDXXbUlc1h4vFXFtOlh2Dj4QM69WGruslPXGzkec/S+M2eF9qEAluQinGfqDvPYvWonNi1QdOT89KurA0iVebDZW1HCwaNmuRdWcNm+2W89U5V66c8P53PY1OD7h/dwtp4J3Pv43KOeqqEiC+1Mm1qzi6foBRmTh2nBy2NLVlSIrgPTdu3OSNW/c4PT1js90yDiNaa05OjmgXC2JMVHXF5atXaGoBH6bALZAggr7vuXL1cK7pTPEibiqHVrBdn6NypFKBNDI3wKcQq+DDzNoKPuCDI2RFiOIHJ3OSLmCu5trVY44OF4QgXrJCuigKFb1Lfp+k7orMMEoqeE6R1aZjteq4f++MV/aBMNS8lgj4n+dxPgFG5VeS7DzL7Mxcs6dSq0+KJ4UixcAYO5xbMAwjr7zyGnVtuHTpEkcnR7z22s15H7vaDhweLHjm6Wtst92893tw/5S2nZIPBRiLUYJ4UhLSiCoSPwFS8oU1WsMFBcfUKPV+ArhyaaTs7S+UgIZpIrxcqOMubhen4C5bCAGxFiXFOEoaduWEhDIUOWrOGeUDxMw2xnlPop0i+cwTj11jvem4d3p6UXaoDMY0ZU53CHUvPoRRvRkEy+V8jCoEFPZCYth/7eQhtseYK3VrRjH5kn05OvWMe+69eYyJ9XrL3Xv3ebYfaOqadrGg6zq00XMQ1tR4CEFSv7thZBgDYxC/6WEQ4EvmXLnXwXtyjHNK+nwYjY+pNN8CcQwEnwmjeKI3jS2Kq698fEMDYU3rGL10VM9PN+Scadqy2U+ZcfCkLNIVY4UZNQE/tjK0NNP4F2rllOagmIExea/iVVS6tymKj5ct1MOcM2gpYnVWYorN7n0UYLCknOk6z/l5z9B7krVyw6Whw9APOOdK6psgSBnIKpUNsaR0tK0TYCJmnDPUrWN5YLElpWSOdE+TCWRAxVzOVYAnpXQxXRbNM0kWXkNmuaiL0VwmVhJPnaJETk9/L54HStLRZpKVPFJjHwhjxDnDwWFDXRlUVjhjwRrQGj+Ms1G5Kab2mUAu4RbCnswoAqr4W7nKoq3QYrxPWJXotpmcrSRfTsi/LimFuhS9WszxY4ykKL8zGnSMVEY2+k0tbBhJRYQcBqwFYx0G2SAs24Y4ZqpaYtHJGd8JONa6StLqMlRGo7NcG/KExqcCDCi0MpCFnqrLAuiMpFx2fV8YQBo7dQxSJmeRUjolQJspbDwfM0YLsGGMFIriVWNRSRFzLJNkMeomo5JQ5rXKNJWjLsBO1PKdXEkgnBYKoNx3eQ6GJF4VfpSOjjV2Rt5zSYSZgCitZIZPFI8ty7xoKAV9KAXnDMYWcEQrVAHLVFYXFjAQyeCue1PYT7XDWivFg7VUTgI0dOmaTZr+LFQtAYqMGNzGLNc87Pn1xBiL7FA2vrp8TlPL8yV691w86wIog7aOxjmhUec8p5eFFAVsTBEVREadyzW2WlFbwzgGko8Es+vgqLIuKSVj1qpi2y1YkYB0MWJNkQHnqXumaauKtimMQmfLYitAninsL6U0lTYsFi1tU4v5dlVjnJjphxDoNuesz+6zXp/RD1JYHR0cY627EGOulcY4g3GVdAynuZEiNTUGpS26+D9MHXkxmI2oKQUzRpLEwe1kBdMUg4CLi8YUwL6msjUhBXI2HB0ezCa5IXj6rmPbbem2IvndrDeszlf0XS/3ohQLb4ryzjIuK1djjfj1qSyNhbatsVZRGUtdVywWrrANd8WkNlI0WeuwxnF2fsK//e//G3xjeXv99j9SMty+c8zP/KNjfuYffYAJXKnrwPWr53z7t32Rj3zf53n6iVMx7C2vs1lSI6c5QeoAofT7GAmj0Pq3W2FtiKzGSkpvGAFdUjTBKNlEG22kIE0JkAJv9BeLv5SFwaW15bXXb9Msaky1lJq57AwMCp0jOgdUMpACGVPA/WLGnaAfA75bY52wRa1zIlN35btohTNi1eCc4Ug3JXBDALBYUn+V0nTDQGUMTz/3DLZuuXH7Nndv3eL6lctcvXyNGEW+/Phjj3H33n0++8Kn6fuex594grZuuHf3Lj/x2b/BJz/xCZ57xzvQSvOud7+HN27e4N79B3Rdx8nx0V6nP5e67eGCPe/9++LGaPLCkX8LuBW9JwRP9ANj37PdbIkhEGMgemGCpWmOT/DKa9f4hV/9MIs28MnPfIAbt65ysBz4yEf+JgeVByzWZt77njv8hT/7D/hzf+G7+PRnrvGf/tnv5X/3v/3HoDe89vpVvraH4rXXFzMz6+HjcPHoRMpPvfAOPvXCOx75u49834v8jZ/4Vh67dsr3fc/nvywQBoq/9tc/wJt5Gl+7o677wqCUe2I0pOgIMdM0FlXM0sd+ix87YRvPr448vNWRWk82SuPoheHpB1KSGmin6JgsEJjrZ2H5JFLwZQMJFFDNGIXRDldZLl/OnDuLtop7p/cElNYyDxgFjRFQPETZPLfWMPqAUwK0PP7447icgEj2I+vT+9iTyxwsD0ghsD2/T/TjDOgC5d+JjNhhZCX7hpgj/dCT+gFtHG27YBkjRkuIVb3nuZqRvVXIsGwbKaQRWXUsjcRQWBuhsFJDSbfNk6SpNAX6MZLJrNYCoo+jZ7PpCsiXsFZxEFtCCBwtW5yFRdPw+JVDrDMcHlzi2pXLrLuO882WRdPKJruuWdS11LxZ0UUJOXPFk7aJmb7forOnUiNHjaY2DWPrSCljDcQw4mMiEzk7e8Dxk0+yXCxYVAaVAqZq5nNsmuaCdC6VZoi1lqZyjKszuu25NHz9yOGlx/BnZ6TosU4xDLHUO6YkPmZRIKSIs66wxDQQqatKvJuzonY1zWRpkjOusqURK/u1XJIL9xnKm03HgwcrGme5fed09qsseD9Jpd1Q2fv35Pc6HdNed2JeBu9Zn28YB0/bNJJub40w5WzCuZq+H1ifP+D0fkvoTnn5C57bN18nZMUwDDw4PaPrO556+qliyzGy2XYcnRwXy4LArVt3xZcrLubavnzD+f8eZivpApCt1ps5dXMcpdZPQeo760qIXhC2qEKeDUlf34HpMxu0JC1PEmUQ2akxGpM1B8t2Rw5xokyaAhJICTVIA3wMCes01lUorRmT5/498ffbv9axKMaULsjYHM4j8w0qFaDqzfPsbPuUhfaXsnjWyt5p9/dTMML8uunzgckx7i2IYHKd2bHAHv4W223H5z77Bd72tqd5x/PvYHv+gC9+8SVJhl3qGSAOIbLeDpxttmy6gX7wdMMorMO4s5LJM74CKkV8trvVPWfiGPFRrEhyjkJyiJl+jGyHxHZrSBfCUt76+IYGwlxJlYtxki1MxnWmpLHJfjdTmCDTJjdPJoiSIgFlQ5yzoI9JNjKuEq1xCMIYmx4QKVYzyQswNXVTUhQpxFg0xFXjMJIhJ52D3gvkP9loAAEAAElEQVTjacyQNd6HYvQJIQ64Sh4AlQuApgRYkQ6FoPdN7aSDpA0xTEmGqRh1Ayiilk6QKhr1YRgZNx7nHLZMurYSw95YYngL8oSz0n0aMqTRQ5FXARjTMHajyMdKOrzQtU3ZP2RIRWtuFN3Wc/pgS+UkzVIkGpCVxP6qqeMQM74U6AJYiZeZUQKkKK3K50jaZYgBbTXGGmJIBC8pAgpdPJzkJk9F++QtNA7SbWtrgwqeuhWTR2FMTTJQGMJIGj0xa4KRSS3HhMFw5fAySmn66CGmwhSTRc0EocNWlcMjxpQzSBB1uac7OnGKCZ+FiWK0njteukj7dkXXbrGaTJp3vgBgjKS1aA0xTN3QHfoOkK290A3QSlNXNZV1F1H20imaWUblPXzxNZMUwyLhHMTQ0+tAVRdDxPJ8WdSFwmoC2KwWavwEPFgdmMheWk3hAeLbNnc0kjCmkhVTeK0UOufCxpaNmC7JiEYZ8TYzukjvmNMx/RgY+tLNVfKdhDEhy4DRmqpcJ58iIYdi2E+Jw65mOZ+LieyDAHRKEQrlVymKp4CZQTWFAFcpZ3RSM7CWciYAtRHgPmRhyzlxUb+QxpmV0OclGVJAbKsNTlsqLZR+VRhNWomEo6ktzmly8VdpXEPbLjHGFqalXCNX1zSLlnbRCGAfI323pSusiG6zYug2BD8WGUkp2koBTAZXVZhKgMiqaWZwYBpPTGNZBF+QmVk14g9hMIgElswM4O42roW9oTN1ZXHOUVUNdd1QNwtOH9wtTQRhrnZDz3q1Yn1+znq1Zr1e0223ImXz/mIxMLEZ91Z2rTOVledKCiE9AxDLZS1dQFuVEJUabdWOgaA09+9f5u/+9Af5qb//vV/dYva7xz8jhxSaw1Dx6utXefX1q/yPP/Ht7AMs1gaWi55rV1c8/9wdnnv2AdevbXE2c3yy5erlc5pGpNFt0xTWuSanzOhHYT4ah0YYpaQMZi/xqzDCzs4e4D1izpwmhqiRZ0Rbji8dkxFvUzOxE0t3VwD6UdI2Q2BaonXZjCfEXmGz7TFG5Jt+DLSLRpoqhYltjJKaw+r5/XOmMDHF17F2FUcHC44WS9q2RdkFi9riR0/T1JgcuX/3jniGOsvTj12j26z5wmdf4NWXv0hd1eLXMvQ0leHG66/xM//gH3C+OhMmXUolMGVKOROw0hkuGJ1P92cu68sEMoNgiJflMA70XcfQd6xXK0gJM7HCCjiZk/jI5Sx1Q4iJs7ND/tJf/tdYrY/mT7M28kd/5B9z5XLGWEfwZW6LiZOjnv/kP/w5/uv/9tv4u3//Of7Kj30zV6+cf11G7b/+b/zwW/wmUVdX3vRT5zzeP7pbrlTCWpkf3/mOWxwdjDwMLD589P3XV9Jd130BXeX5FEsCCb2ISZrV3XbNerVC4Tk6WOxRXCKgZzuRqQGktXjMutGSBo+x0A8iQ8tZ6u80S7QojbTAlEypmMCNDCqijEEVCYRGcbBoMFXFGAJj9JIWrCTFu6k0T1y7xDAKWyiUQKvDRYvRFmUtTd2gcuLKpSNe/uJLHB2dMPaB7mDDdrsGKLWYqCCc2d/07oKBNBnvR6IfGZOswfJcSXJ4jIlFKyxqZx3D0IvnqHXiGVgvcM6RnexPqtLk8kUmHqKYwascSyBPaYgmCFm8FYdB1ADeB0YfGMeBYRjo+4G+3+LHHnLiYGE5WR5SOyPehXVDU1UcHS645o+pXIUx0ph2VuR0QRmWtkaPHSqVGtwqdFNz9fIhOge67VDuj+zXXFUY8Magi5RxuWg5Xa3RaWS7CmizYoiZJ596krapCKOwadfBs14brBbgdew2DH2HD1IPaq3Zrs/IJPzgMVYVsBZsJTWsAFYruq6nrmtyztS1pS2sV1t8uTJq9rCS+l2DRprPzkIWG4tpnktlDNXOMfSj2OJozbbrheeUKczBCWgoo2X2q9v9ezdvQk6ZoR9ESeQbDAqnzdwsqNsGa6T+e+GFz/Dii59h2TYkZbE5iPpAZ7Z9L5YRteXocImzx6ScGQbParuFDJcvX0YZzdHBkqq2pBjYbrbFi60wMyfJ4tSw19JIPl+tqWtZv1KpnSebAq0My+WS9WaDj1JfUoDiSYEFk1xyAr6n8LmMMtKYrWuZN5u6IviIYiiWRLGwPytWZ2tUlKz6QxQhU1QUwmbsz0dpjhvZB0YfJbxsvifqoX9rco4T7M5bzcUKvSMNlCl79qfMex5xb3rd7qNFpPnoT3lYErl/eO+5c/cet964zfJgyfXr17lz+47MNWEnw005M4wD5+sVq+3AMGb63hdLIAVKE7KMufmbFIum6VtmmOeuJKaExcLAA5oHZ2vapqHrHx028PDxDQ2ESUKGIYSEL4CINrtNjbWaVGRcySeCCYWZoGfj+zAGYsgze3qWfxlJoASLUgKgSLqagCJkDcaIVMmaovdNO8M6VVD6LhUwRAy2x0Gkf86Kya4xlWwugZwS0xgu673c7LCbnA6WLakSbzA/yiQE8t1SntKlUkkUzHMnQGUxtxfmUEG4s5oR4pzESHBKY0pRzIKVydSNeHEZY8RsfusZupHz845xKGaDMjLnL69QMjGddTR1ZHmgyURsgpQDIfkZFEoxMfpIypJ0Kaao8rAZq0uqpiEkoU8C2KpccyXRqzkllMqFRaWJYQK+lCSmDAE/+jIwNMuFKxOaPNLaFMvClMhBEhWTUcVrLaJQNAcVThXPstCTC9CRc6brxwJKyQbCYsQwvHxCTLF4Jmn26c3ei8S1so7aVcQmoYYCOOwZtqss8sbKFaAmCnV0MrCvnMVohVcyjvbprxPwMKcmImyVpV7O7BkffRkDhqjizIQMMZSQhDgzIqfvPRmWxyDx4bYABiCT72xoXrotkx+GUQJAp5QwBURSZQGSbksBwKZJUCWiBqylshZbtIKqnKNSCmXk+lg1Ac/S3glegNNQqPzi35SQmnRiB4r+X7qjdZHxDoRxYIwBjaa21XzvcmF6yVhD6M5l7BtDYXTOjGeS2usma6G4u5TIMVJpTWM1Q5T3bGopXERylYkTUykr8cxDY1BYbWmcdHLrEjYgY08Wb0maNRirhGFZFkNnrIBWVthrrq6oF2IqH1Oi77ZsN1s2mw3bbss4DuTgUUkKEFM+y1o3+7sZZ9DWop10Mif/kakmTwX0kw2GJkb5mY8C9JkiT2Vi6vFmYrZWClQW8K+tWR4cClursFhkY67otlu2mw0PHjzg/r17nJ+dsd12jP0g8fPOlc/bHaqsFVO6n9EapwWUrAqbzjlH3SwkTEVrUo5obWXuGo742V94F//D//jtbLYH/O7x2/HYlYYhVJydV5ydH/H5l556i7/PGBO5fGnDu56/zcuvnPD6zcu849nbWBN56qkHfPibb/Ku529z5WRN1rLZSWWjknIis6R2lEJSir6YNSGK9+nRySGDjxISo00JYMjoHCFK0ai1bPS0MZAgTWtuFvsBXeTdXT8wdBIWc3RUMU3BIhkvQS16N48JoKawWRocTVNRtwustdSHhzRtQwgjOkVy9KzPT+mHClc5Dg9a3vn2J7l7/z6brifmgLMVx5eu8LbHr/LSl17l4x/9VUKKOGO4cukyWlv6wc+NFmkUgU3IA1zwRMEVpWETQmAcxPPJe48PgRAC227LanXOdrPBjyPHx4c0lUOVWkgKbJGYZ6VAydrwsU9+O6v1EY9fv8u3fugmw7jkI9/7Et/zXXepKidzW+nq5MI4rhz8iX/z13n2mQf8N//tt3D33tEjR8vX63j2mTPW68fe9PMJBGuanr6/mBaZs+bH/9qHAbh8aUPKukiUvh5G+F8eYJuO5cLTLlqUUvRVR45S28WYRBJGph88D07PUSpQV466mlhOEzi6kzyKNYOEEVWVY/S+MPong+rCZt7bVE61DwigHKNsTKWOLaz3yesnJRKKRbMAr2bfVwCVE23tqK5fLs3aJMEYZHySGgjrSF4sHCodObtzg/P7d7h/+waLpkHlkaH3jF5Ac0NEFSneZLcxbVqtNaQgYVEqSyKcH3v6TjLbcoz4YQBtcM6JUfV2hTFWQItmQVU3xdrAoGipq6Y0NiOV0QStyNHPcrnpSEDKmnRQvJiYAEVP8APei4l61w+MfUdTGQ4XS9mHKYVyErJTV04UJUq/iSHurKFuG8axu7DNt9Zx7fIV6qZhs+1LvSJqCas1zgowMdl/iAwSzlb3CVESr2M2NNYwDhuGYQMZ+kF8eI1SpOBJMRCD1MbOGOq6IgRRsoQQSeWeWiu1nzKGNI6cnp5z4407OGtYLhccLBe0tbDpn3jicdnDjAE3NYUpdj9mMmvXu1VJTYCQjO3DgxalhbW0Wm1k7i4N3bjXWJ+vY94BYzlHct6x+TOZ7eDReLTSws5br3BmsmQJaK2o64amrlmvV2itOLl8hbpuefLaJQ60WO3kTJE4i2VFXTka11BXUsvFmFgsF/gSJmatwThbQvGauQZXZRwNw8A4DDMgBoqu91jjqCtF15e9VCEfhCTeu2HPC3j/mBRjOgsrQ2tR7YQQyFE8Xl2RSY5jYA7iQwA3U4gjXT9ydrYmpkRdGShkDnKSUL5WUGIfUlFaPeRGf+GYdhKZt5Qs5gnMKiqeUvM/fIIKtSfFfMQHqmkM7HPFZl7amySRex9PztD3A6+9doO6qXjfu5/j5ht3uHfnHqnsw6tKXu19SbEeA34EHySZVZU9Ugwyj87fMQtRYtqvq/l75oJ5BFbbNd04oLSQEFKONPXvAGmk1lokPHi58TkVPWmhBWowRhF9iUjtkZ+bHd1RaUn2CiEzxRgrpSTJgkzIibGAAcEnqmpKmJukEGUzjsI5jUXYFj4E/BAKUJTLxALbjRcPLKUldcpWJHLpro4zaivvSTGCLcVoFvqvtRrlZdhLWkxmHCMqCKocwy5hMEVZHJdLSUhxTiSaKQi1UFlKBzpDhjEL0DSMQjM0ZWKtyoCqK0MaM6PvOX2wKSh2uvB8TsVyKkWKMWY2Gk5RvJYiAeMmZkkZ0MA4iMGpYEXFA8gYstKIOeZ0bzXGOUxdE/0IMQjDLCviCGEUT7LQpAKKCXBUFfp00zgBD0NhP2UB0lKppitrqIuEz2jNsmo5qBfSeUmJyYo+KyWATNqtLpOnyITlCKtLkWJERRlnkx/D4L1MrkX/74rZe2BiFk1kVCWFhzECTpXJfepwKSUm41UBuiaAiIlRI/+DKV1Sq4k9V+SxBYDcDzcQzwq/kwSXcx/LhmI6Uobkp0LPzkDQzntu56FH3kmMJ1p9jKEwLScW2MWJ1ijRvmct16C2dmZoThuXjDApp88GNRtc+5IQJyC1PNexdMWIGWfNzNazyOcorcumS8AyyvmQBSQWKUCeTVbbRjYTzloBoKdznztrF8/HKVM8v2RDF60wOKfvkcYp6KDQs7Wm0lYYYErjTNl8OkdjbJGnmjkqXBJ4ys+0FmaqUsQUqE1Ls2ipFy22qkCJt8HqbMV6LbLBYRxKql7CokoCK6WLXpegBwFqq6YRqaW1NG1VTFj3E2nKs5shllhvScOMGCsMlX0cff9QyHxrzQS0Kqx1LNoDdGHB+LFHacVms+b8wRn3793j3r37nJ2d0XWdbGoRM9V9s3ozNURsMSy2zJ1mW/y8rNGzxNFVFS+/9nZ+9uffxZdeOeaTn34bvyt1/M0c+zf4K29+3/r1/ySv/a0+FDFa7tw95s7d4/mnL33pCQA+94Wn+Yc/NyUHSoH71BOnfN/3vMj733eD55+VrupyWc+MsJkRFWV9FxmByL7HII2rGBOkEZ2O0DniXIOrWyjPSQ6BmCAEaYG7yhGi+DyJT42maZrZw7GuJPhGqWKtsBeeIqbN0jyzVrPpA7l1XDq6hPcDabOmMYrke9n4eJnvnVFcvXzC5eODkromc7NG1qLHr1zidL3FKMPlK1e4dHKJGBLbTTezNxXgDURXgomyWAiICkDqhHEcOD87K9dOfNtijIx+4OzsjPV6TVVVLA+XIscII75IuYyWlOWqaqiNSDK0k/v4zR+8xZ/4Nz8u/jY5YW1F3kt+hlIX6J21wB/4oZe4fPke/9mf/yF+K8fvj/7Ix/h//eXveOTvnnziHk88do+P/sa7H/n7ynl+4Ps+xS/92ju+TiAYfLXXonKGg4Mj2nZB3/X02y05jiili5+e1MkhioH6puuwZlfjKBVhYmDmRJ78T7Ukp0vSW543wqWVt7fBlmNmypT7HMOuZko6lVRgCZyJQRqKJoMhE0szSiuFdZIwmDMoMk5nKg2hpE8HjKhZciYOWyodOV+tWD24Q+XsbIUhqbIJ4gg+YpwrALeeWTPGWlxdo1PCZCnVldIYlSGNpHGDTyMhazotAOGwOS31rMJUNdrWmKrGNRWbzUYab0r8oYSZr1G5JLE7O3uRSmCZgMS5MNWtNVidSMaQrMWpFudq9HIhjURtpo8GKywjYcoXhlTZdc91VfG20VoXM/jdPWrbFuUsVUmInGpcYiCHiB9HYjHB74ctRM+9+3ekKWsdWomdg9LFT6Wcc4qiOCKL2igU3yyK2b7WmnG7gRSIyZBiLvK6si/qR+6frnj19VtUxvD2tz1J4xpund6nriueeOIxAdMeqoVTEtYqFD/qgms89Ge4QvSoa8e9B2EOGVSAegSWsj93QSAnPV/DlBLbYcQoRVUsOPquo+s7YWmlhA9j8Z51tHVN2y6oF4fio3V8IHuf7Iq3V5oDSWJIWNtJ472QTUJKpSEkdjxOxwK0VXPg13QtJrWPtZamaWibmn4YOVi0dP3A/bMNp6fnJdgts95sGcZQak15zlWp10VGWH5e9kpGmbmp34VAq4ThaIs1zZTKnqfvW8LOfIzcuH9OjJFr1w5Z5orNekXTtly53GK1ou8zaRsYJ88z4K3mwx0378scuUDfe41veceJUFAsZ7ISv+R0cSDMFftMRBDcYnJO3u2sHj1+EuLJe+PGGxyfHOE++B6uX7vK2elawOLiKR1ipC8hNHIPdKnzpf7I5bs+jNbKGBWykHi171iQkxJvHCN1ZTg6WNA0NZX7HZAaOTFIoikG7Ili4OixlWx6pHAqKYohzowxXbTk2hpy0gz42c8LJQl23kf6QeKVU0jUpdtxcNzgvbCusiq+P0ZB8QiwGIbO0208wxDwgxitxgB+lA2hUgJKucqVLlORQjL51aRZEmityPYSCW0Vxiq8lwFgCpAUQ/G9iMXYH2YwQgGuMlS1dMjW50JDHlMiOUnPA4mYjjlO8wBKaZwysz8OOqGN+Ku5ZDHWMA5hburpom0WLzM1p/T5IElSIIVDylH8VqYUP6TAlvOQ+6Rm3bbIxrISxNwYMwOZskG1YhaaEznsUebZqcljyuQEy9Zx0FqsAR8j4xAY+yTyj2J0H0KgrRuWVU3buMLK0hwtFlRaIm+HIRYTbZFFKq0w5TzMdB5SxewYYKoARimQfUHZtSbEhLEyhlAlVady6KBmZo8qdPpJ6ida/jAnNU6gGiFitEhlQDZL0cbCGtx1jaZJ1UwG/gibajKIn4pBkQWHGbjKpZs4hiDMvImtpkQmR9Hm25KINxvOl/lMBAO7yS3GyBBC8e+6OOk9XABoJawtW+jtE8hojIGIsL4IApIpxZSIEwvwOiWsTdO61hBLhHSIApDFIKCZNkrGqBIGlC6T81QsCAtonM9/ShWc46wn49qUCUlkwBPdWEIGEgYp+MjC9qucKewDJIY9CUOstpJw2FiH00ZANGRcOCdg2HG7FMCsFMaxMDSFySRdb6cr8ZtoFhweH9IsF2X8RVbnK87PztlutnR9N8sxp3trjcGVsaKNoa6bUoQJkORchXEOyga5H8YZDJN/8vzvEGH0mawEmHKlcL94r3cS52k8OSeSUa2mIJGpQxo4Pz/j7PQBd27d4v7d+5ydnrHebvDRoxW4ylFXNU3T0LQ1VWWpapFq100t84kWOa4zlhQr/vpPfQ+375zw4MEBn/vC7xraf22Of1oA4Cu9/hsJKNs/FGB4/eYVfuzHJxnbtJ5EHn/8lO/77s/wrufvcPnShkXjOTzqcW7yPRTpYCissYnFm6OwFrWxUhegUVGRPcQ8khSgAyTIWSjxtmoxrppZM65pcFYXs+LClnQib3e2gO5K5tRuNdJHaA8P6e9uQWnak8swbBi2a/wk85ZKV55/a6hdYL1ec/bglMEHDhbynKIMy0NJq91sNvhxEG9MJgPzjLOqNM5EHqOKZDuT6bst6/U53gecdSVRqyR4TSlpSjP2o5im5VRM8C2uaqjaJXZxjC5psU0rXlvGNdiqLc0mS0xarmGaTPulvpQNya4zf3gQ+K0em3/vp9/F7TuHD/0080d/9Of5nu/6Aj/2V7/zka/7jg+/xL/0z/8aly9tODtbfJ2+3VSlfuXjytWBqqoAJ4l5ORODoaqkLlDAeVxzfHyJYVjT9yPWGJrJb4lMyrE0rpFaW4vnamUdy7Zl6KUpOSUCX/hqhVi2bzcxjaFpE6uz1OK6NE9iiIzbDdpaaqVIhbWpETY7qvjagliAqJ3c16lMSJpUAF6jC8OtzAs+BHwQBpAmY7OX1qzSaJvYpXEDU2I44PTkZVkAbaPR2aOSeJPlBKMHlaRmTxkYe3zSmLqlWrTCIo2RHMSjakKtrNVYK+sqSlFXNSmLDQ1lk1s3C6rKolQqgIjUlgKuV1I/T4cpfqNaGsLWGGZ5XwErE5mshJFO00hTvjTMp3tVaTFEF3m5WD8k5Pc5ZQLib7bdSADB3MDWmoOlpE8KEFaY75RGaWF8RS/1tatq6qZlYgVYY2gaQ0y2MBEFjBmGgdV6w2q1ZrvtULV4MpvKkjaKlGC12qLQHBwsuMAyKM1dMdWQ1Nqs3vwkGWNYtsXred8GYgJD4pthlbwHDskcO3mJCVtZaQPGsGhbtn0mbmNJVJbaTjyZNSEpMULfbqnrivVmw8mJ+DumEMkkkgr0KTH0QxmjBXBW8mxq7UBLQyErmTf7fiQzzpCQLvdUWSdAr3WgDe1iwWFb0TQVGXBG8eB8RYieHLgIAOUdmAK5AMuTn3axPMqJrOQ5HH1g0404ayTUKubJbpiUIn0/Mox+plBpW5qtGrquF0CvBCjlZElR/vEqXggEe+jOsO9V+Mhf76gGlKu59+tCRlCwM8O/uMcS7CvPoXfTu8jjVnZN5XMeHmsTCBYz6JQ4Oztns97y6us3eez6ZV6/cZv1+boAVzAWX06x6CmMOrWvRovs4LfdOaYCOu8TTnKi+BXKfq2tKo4ODmiWDdbZMna/8vENDYQZLZfLFJ+fnNXslWGdLUCYxjrNtmhwtTHUTsAVTSrMC0U3SKchREmUVGq6wCVZMoEqwE/d1qA9YfRAIiWRvsWkSUoK06EPDF1kGBPr8x7xbJsWJ1Xkfqps1AUkspUt/jvCvNBFstU0lciijCRAAlgXCaMq5zx5fRVz9uJ9ljNzUtmEuFqrBYBKCV8kgxPDyHtPSEG6oUY2i8ZoYeOkRIpCM6WAUVVl8KMUgQpVBt4OCJNxLR4CXdcTfCClkgiSEtXMyBf0V5ELxXjiQJUUi4RQS5XB1AZtpy6fIifx6lK5ADaAqy22ls5B8uIMXDvDotEcHTi6bsRHoTGPWVFby8lygTOGbhi5fLiksSJDdCXd0RlNbRV+KoKygCTKiKzVuAm0mroDibQHOgkApUl5B3S4avf4xTKbWq1pqgqv9Mzq0oX1ZbT4EAlDSMnCVK5fCOI3pjVlg1HGUiogXEokBCRNxShYTPoF7JtSPUY/CrAUAg+HRGQgZlmCuxDmFB2rKeb9cq4TeJgJ5PJa+ZoGHacOioB/Q0noyTDLScxDwMhk2qxLaoyYTE/Fht3bGDF3YXOGkCTNrR9HvB8FuCkhAtrp8uwybyYzha1VGZTeyUsvdIVzSezx0o02xqD3gBnxU4uzZ2GIsQQFCKNJZURaDTPobpWY9k6JTTmnAnbVOGdZFGNSoxWqMA9VAQErYzk5Op6fIR+CmHAqJZTzRgCg5WLJYnGAsxV10xBT5N7de2y2a84enBG8R2tzYeGYGIq1q6hdVcaUvZA6KZuTspDu3becstCevfjrTFr+lBVJGZq2kdCOh0EwNFYb6toJLb7IbeXPih9GgnHsxHRzvRYA7M5d7t65Tdd1hOhxTtMuFrRtzXKxoGlb6qYRj0SrqZxQ7rVxKGCMDf/dX/l+/uHPfoDfPb5Rj99OQJl8x5gsr9+4yo/9+MNec5mmHrh27Zznn7nDt3zoBu977x2uXO7QJpeQj9KfSGITgHXoqkbZhoijCpFtPzBse+q6wdmGdrGEkhzpKosuMuraueLPI80YrTJmTs2WY7mATUj0fcd2veHg6IijS1dhXLLKETVsZwa1D5E+iFm0NloaV9aRQ2SxbImxJ6eAy1vGYcM6ByqjZ1lzShlSJGexRnB1TV3V4v2qNeSE932RqleYkp6bkDXu8PAQZ0qqcwKSpqob2lZqH2OEsaOdQxWGh50l1WLOLmsHEuYDTMYyU62VcuYznz3h8MBzcNDzn/xffv/XdcQ86vjYb7z9kT//jm//PItF4AsvXX/k73/fRz7D2566D0Db+Ef+zW/lcflyP19b5yxVXTNCqTPF1zZky6Wrj3N6/w26zQNW6y15QUlsS0XBkRCD1kzKYqmglGXZLNB4UpaUv9mbM+8aOg//t7W2vF7AsKnJKNYeOwZdjlFUFVqM3UVyeXE2UjnNG+GoNUZnlDJU2hFVwsdE4wxWV4UBkRhCmOwFqY1C2Uo4bDHj3MUtqy6s66yYm6mSSKhRKRZmevG0NZmkDDl6QhTpW/Yyp0Sdyc4SxsDY9+Kpl4TlMTcmFSzqBcZaxI9NFQsDCQFYHiyoavGmnSRSIWYwhlSabUbr0hRuBPhkgoMmWhNQAAtlDHVlUb4qP9ul7OWcqWOiLl5WU9hXCo4cBTCb9j6L5QHWDfR9x9B1BO9x2jEOUndmpVDGEifgU0vNpVES2lPVMscUG4m6aqjrlpQy262k55Ez4zCy2Wzoth0pBJKz9MOA1pp3PP8si7YlJS+1qFXknfhCzqk0VqPayeCUnthMO5DTWjtfp+kQgEcR1YUfl9ft/rdWZr7ildWEKBc9ZRi8pxsGAT6sQ+VcmifFf7LMjX3fYTSsN9sCmE2BW2Lwrx5BTRNpb1WYx1nkuXn3LIUUSDk+TBYipgEzeDblmvQbS1M7coy8/anrnK1OxZtb7wCj6Xzj3nulnNAF+plIDCmK8qOtazKZzVbYpsPgGcYg+9UMKmS2BezKZK5fPcZYAcZD9GithEk3jJjCHGzbFmst3Xbg7GzLo5oDqjRSJIzuoROfQLC3MNEHdsoUtc/6Y56v9t5od13yxeGRlZLGWTnX/WMCwXL5rGEcuf/glDt37vPE+9/BpSsnF4CwUCTlYmJU5iOtMIVVHZPUFTt2rvxRKkmx+z52KYnKJESxpZKQPDMzIkP4HQCE1W1VHvpMSAZFJOlcKJRCgzZGFjaywhcj/UvXD+i2A64y4juRoOs8QxcYxkjVSOrLJHdLUdhSD+5vODwSSZCxCj/uBpFCJJaxD3Qbz+a8l+JTCUjS+4RWknQkQInE347jgNZgncLpShhlzhRARSiZY/AcHC2ommqmhYYQqRcOG8T7YwyeMJZFfgKQVBLjcKuF/hki2UgXadv1s4fTtImPIZbnSSZXkVeZma4o3akkflC1oV1WpJhmMGLqeGgJEpFFVckk1g+DJGoUjb9CQMfKCPVU/LnkelonIGCOmRwh6+LdYzWmMgV+jxA9WgVIkbGX9AilNLYqQQpG40uhbLTCAMlnlrVj6CWF0uTEu56+ilaGw0XNoqp24M10vqmk0BVfigmEm4oJZ4r3VWEbCvtQTHc1RfqJ+LroPbBs8paY0PuJdeWsKxPGQysg02sE7Ap7M3hMkWHoyDlJzHzd7nk1qRnk8sEXWWWhzS+MpJ1O4FUWyaLXfq/zNg3znR47lsQhKH42CUzOpGhKB89I11bH2e+BsrhMxWSIAR/EIyqViWyS3sBuoXLFV2EYPHHq4ES/B06VwqSwoXIWJlY/evphJHjZcElaojAZsxbQcRil2AsFnMpGY9m73wm0lWtEKaTDxHIr986HiDIaPUlwvLDcfElYQoEtjCpXPA+0UrKgKJF91lh8SfysleOoqebFwBlHpRwa8S2cAFcAbRxWNUjKLITUYbKmrmuODo44Pjrm8PCQxXJBznB6+oDTB7fpthu6bsO2X+FHkWRXVT2DfkYbqrqirSVivXKOum6o6npm5Cml57VX5mErSbNFEj0MI97HmT6ulLDYTN2Kz8Lc/ZUxrZHiTStFXdfFqH6azxIp+QKoRc7Pb3NafMC6zSBpjgtH3WhcpTk+OsI68X+p6xpjK15/4zq/+hvP8clPv52bb1zin/vBT/CJTz/Fxz/x7Jues989fjse3wgA2Fd7KPqh4dXXGl597Tr/6BcmAHfapCUunWx433vf4H/1Bz7J88/epaos3lcsFhWHh7Wwe73n1s17Re4dOb58JMWkkTS5pqnRORdQevK4FLa302UziKwTpxtPVVXcvn2b44NjFoslVVXRb++jiFgtjG3x4ApzKmbd1CKbspambcVnSFcEP4gE3neENKCsIUcnUiWlqQx4HwkhsVgu6ccBHzwHywOUku8vrDULE8ARPVprFs2CylRzo0PMspcCbkzr+2S/UADA1UqYUUdHpXkzFebTzoGddxrAdlPx7/2ZH/wtHBNf3WFt5HA5oHVF8I/eAvydv/9B3vvOVwBYLIbfyq/3yOP1G0eU3WBhJVeA+P2sAzQ6kLJhHWuq9giSJ4aRmGLxW5WN/WQp4XTGqojKspYqo2hqCEXSN47iE4va1WVTiMX+oSemPgpjzax+mJgyUOr4UFjvWViLk+uPvIdU7ePssSt1r1JxrhN1TtjiQ4bK1E6sX/qxgD7KoG1FVqpInWXvYsumPOUdp0TlXR25s6QAa2XfoJWapV5d16EN1NZgDGgGchQ/s5gD49iJ4qKs4SF4yJk+JGFq6cnuQWOspt8ouo006EASoIcxMIaMq4wEPzUtbS2MUKUHYbXqXfP7glqgNE5riwRbZam651+TsbU0hqfGrjR3pSkck3gcxxjx8RCUAJndVoCqMIp3boqRbbdlve3pe/EqbBrHwXLBcnkAVAIYEiHlwlCVeUpbQ1IryGpu5srASqQg86BIJy3vfM+7WLQN9954lW61wg8dRruZNSX/X82Mv5iSkAQesbYdHS2ERFHqp/maFKLBPqgyXdPpu+08oqCtDznfjqK2yZBCxNiK5dLOdfssF54Gkwx8zldrLp0cs1qv0fpwZo9NYQ7TXZrGotaQiCiVMMngyGh2QFgqY3nf04zMbFVCGc+j1WytKIfOVytUAp0CefJ93FOV7J7EfIFXNZExpLES530JOZf61s9Klgz4mGEMEsBmFG3jposNgG0tCkPfR4qtZ1EVibzb6LK3yQ8RAYotAUrJM5wfgsNmRtjFYx8w2v3dm4+JrLGHOc1wXCGuyt8piKqcUi4W2GVe2Z8VY4zcuXuP09MV/RC4fu0yr798Y08hImMgpjTv5+avWMaQUUIaSHvvrMrYynuvmUgzzlicq+mKzDvlWvbeX2XJ9w0NhMmCWKO0otuOWB3ZbgY25wPWiSn+ZEaZyMSw27geXWoIMWIr6bA0C00IFcEnxlFkc36IhDilU8qAXK96Tu+vOTqqiD5j3CQ3g+gjp3d7tutB5ImT6W2WicLHQFVpTOmSTDzENKc7J4w1VHVdGBAy4nIKZaDKaEkpYaxCGwE6uvORGBJdN8hkUGiGtjIYJ5+VUuL8bEMmMxYa4XQIYFU8kor0TBtTKJ2F4q+kABmmuGYFdWsZNgpbSbfUlS6PUrtEh+mzt90WnyKNqzGlIxVCpG4qcoa6dox9mBPpZEOeC4PN4kMEo4ijbKyrKuOUoPdaZ6KP+DHiGmFO2eK55EehPVfW0NYGZ+W8Dw4qnjq5jLUVT5xcnaVYXdcXhlyQ7sNDhY90VDS1q/d+loUiXVibOYqO3xVWojGmyDLkr10xthfTyMiua7fztJDUEzWDCPv36VGHADcCFqihLHQ5z0XazFiKaT6vnDNN1WAqsysyUCVxdV9cujtmuSO7CXaMheFmRYqAUnOCH8jEiJZuocXOXTkQQC9TYolhZr7J9ZDnKhR5YyrGyJMMMIQAQfT6dmYWSedy8J513zMGX0xCmcctZmJbpNlH7OI9VoDBKvGIs9rNIKGfCtwixRn8NB7lPIbRy1iVCyTfFTG5nzoii0VL7arSlU70281stjr5YUxjQXxMzCwdVmq/cycLgMLM9/fqlatFAtiwXC5xrqLbbrl54ybbruP87IxhlI1N0xQZQ+nMZqQYa1wtxqdNQ9MusFWDMlLUxT0Gl/iPyZgPITGuBsYxEHwsXoB5fiaMMTSNpFMqo3fjWDHLt4wxVIXNqBSEpPY8PyAnQx8M5+drHty7QQwDxgROLtXklLly9TFhQ1aOpq4x2vAf/bk/xMc/+bZHPjP/3X//ex/5898ZxzcSO+p3j6/+KPN8Mty7f8TP/89H/Pz/PHlASeVaVSNPPn6LH/7BX+bZZ78AKbNoRIZ49folQqxZrw+4dOmcyqk5LEYri1Z7LE21kwIOw0jlLAdHx9iqEpPvqsZZSxdHdCnyx2GcC9lJCgOFfVpYI3VVkzEkZ8taqArjWDY8WklDLSIm2il5NtutrCNaM7qxNKXKmyfI2ZMYiTGIFYTSc2NRqxJwMzdKLMaI7YJqW2Fe58yNN5YAPPHY5qKf4f6OTMNma/nljz3ON33w9tfxPv+TH8dH3dy9X63rR/7N3Xsip8xk3v72r9d5fPVzz8/9/Nv4t/4PHy3NUmEYKWPwUdbw07MV0VbURnP02HPE7RGr05vkcSvnUZpvutQhRiusmuoCRSgMm8luwxq785csNVnaBxP05AGnZzDMaINxhhFpOL7pyOU1ejJ+LhVhzsW3S8a5MSKPAy6AaaIGSGV91JiYcMaQoNSTBcCa/j5FYcwpkXUFH8iFcaXLhlZ89TIuMTc2x1K+GCN7qJTSbEWys9ZIVAaodKnN5H18TBzUDTknxpjo5yalKAe8hm5zXs6tbPwxbEYYYsfR4aE8e0YS1F1VUVdSj9R1XfwLS+PWiB+byZm+E7sXkSA+BPCo3b3KZfOuVSabycdVvks3SiM9Ro/C0TaHpBQZh4Gh78AotDO0i6ISykkkpENHThHdbWmXCwkYKt7MxlhsLWx67weUdrhKGGzW7Oq2yom3bL/taSrH+vSBNAezALj7wNTs/VSaj9YaNJkiO5qPo8MFh4cLjFbFBqTIyRD1zaPYRwBGN3tj3XC2kQCJjCLmzFHbzqnofvSzemTb90zyNruH5axWG555+9sYg7CUU87kALtScq+hHyX0QTzaShhTYY7pIovf9+h7+PtPPw/BE4OEV43j9HNhI6sJSCm+gvug4L4gb1KEjMFLaFUBdBUKP/q5Zt+NNWabFgzg9r8XgEbrir4PGBOxToLOYCKcMJ9vzhIyMY3l2UIIYSbO1+ECdPfm48v5is0AmNoDFffPhf29xt7r1BSCIf8dyzAyWkMUPt163fHKqzf5vu/5Vp5//h185tOfZ7PZFhLDlIKdZA9UWF35AvHiEWOzkHOmuTEWUsIwerZ9z+hHNJpNt8U5y9HxAfar88r/xgbC1Oxlk2lbx+g1rtDtg4+EzjP0IyGICb5xinwknjCh3MWJVm2sxrpMqhJVbYhtJkVFCDB0nr4bgIypLKH39M4iKUFlUEawymBVRVtropWkp5RzSSCRxWIchRm2WJS48+nmK2jqBle5OSlxniiUA0q0d9757UzdWD8Ghl4ezBByAbEE1Y8x45V0trQxnK/WM1NI3puZHeTqipSFuWRrS9U66sYJQ80WjX1pfuYsSZ31ssYa6Z4uloaqspCVMOx6L95ISnN4eEDfDfJ6qwSkM5aqEWlVt+nLfbTkpMqAz/TdSLsQmUK/HYXhFxPLxtA4JdYeU5LPZJRe2DYqZhzgKk3jdImAh6Y2PHV0TG0bltVBMUqVhT95oYKHGC4UPuVtBdjQ7sIEGMLIMIhZZAjSJXAaqkomc2MMcRgZxjgbmZrKireF2pl/hiAzt9WGqpiuj8FPF/zLTGmloCkdTJRMxrGLFyZCayxt09INHWMaSTnNBZv4jMWp6co4jlg7SdcUk9R2ThBDACqrDY2rimmyAGeS2DG1F+SfGSxOER+8RC67moSYYypkw2NNAcJKc8+HSIq76F07JZ5iwYkuP6VYzCuLJChJwAXFh8/sfbesdktdDKn4g8nhzI6RJM0HO/v0yf3f0aWbpi2svVzuXZH4TPNKhmry/CtjZ9LC79aujO87cvToqi4Fk6FuJNZbNp9SZNvyHcLe4qu0xlWNsMac4/DwkOVySdu2xBg5Pz+n6zq2my3b7bYkruYig3JkPCkHqlqixJ2rQEmAR103Qtt2FVhHLsxOFLM8KqbMMJSAjjgls4YS9y1/LMWggPtNUwsbryzurpqMfV3p+irqqsKaIgvOstiGIKy+nCMheqyNHB3UxOiwJyekXDaxxjL6hh/91/74l3lSfice+0XFjjX8u8fvtEMmnnFs+NIrz/Bf/7+f2ftdBgKHh+eQFav1JQCMiTgbeOc7bvIH//mP800fvIE1RoAtpNnVD4Fb9xQpGY5PjolA7aSO0XoXTOQq8ekSZlaca4+JTaO1ZluK5bZdENNkCm1LA3PEj7K+qlwkb8YImyNEAbOMZexHYgrzep1znLvcZPFida7COWkEOOsw1mGMFQml0YXtOjHCZbvx4FRqlUuXtwJQPNQkA7jxesu//x9/hFu3lxwffXXR7b/Vx+Fhx9Rc6PrqkX/zfd/zBfFRIlPV4yP/5rfysDaSS+iKAkxJLlY5E7uO5eGSg8MDmrrFWcOwTaSxL0E4cj+VKoxzBaqM3ZAnFkaGUkMopWjbdq6hpDYxJJXm389Ny9LQnJgOk82EKeNyYqQBpcn7EKOJHQ9lTrxnD1tl1/xMxfsThDnTWklRVHpqLGUmb1RhZ0VCYbFMQJjWIkeyatpUa1CGmAQsmxpbwgQR8CuEUFiaIgGVc8pFLuykeVpSxZWODMMKUNT1EcTMGBOoVMKWductDCPFkBR9P4CNdP0WskjMVJAmZN001G1pzDV1Sa0uTWZry/MsfsvWGUmYrOvdNdlLoJv2XMzlqSo1jZixp/KsJ5tlfmgc3WZNSseiBkhJzPKDeL9O/sQpq/nzhtN79H2Hs466PSAXixhUJquID4Gz8y3rdU9OCecMl04OOFjU3L97h81qxe3bD6hrx8kJpLizQDHWocwOZRKfJE02u3Oa/rZuaq5cPma5aIjrTQkLSRevwUzeEkAwJ8gaamdLzZULCCwvsMayaNvSeI+zZDwEsEZfkBnGMIISj+v1dstisRC2bJqa0Fx4FnbNUVkbciGuJJVnZUDaB8LUTg46sXOncxGSVEYrR9dtLgA9uYy9h32J949MJqRAHCJhurBpulYwDn6+ljvQSO18r+0OsMzTdc2InF9nUtIlKExsnd7skbwDAMv2sNzV4smZp2sx/fQ3d0z7wod3lfvX6S04F/OR9sAyZw3OKHwv39n7xKuv3uD1G7d5/8kJT7/tSV76wstsu4F+GMWHMSMew1nRlfV6fm/yI8KzyvxfyDUTmWPaNzS1KNSMVaw3Hdo4Ll35HWCWX+nJWM2QU8JqQdbDGOm7ga7zFyaHqrH4MYn5fc4sFg6tywOYp0VEui5jBu8z4+gFvDHiRWatpR8CXX9eboClqRyNrkgZFktNai3BWwHjgjDMUKF0esRUcPSJpp6olyKHzDmiE9Q6Y+x4YZAaNAduydnQMwxeWFdREX2GbEghFzZbollMyRqywGaE2tn1A3W96wBOXR6QARm8pAFKVKywxrSd21dMho/BR2IO2FoRkMLCOE3lipFp+e9aO2xhpAWfWJ3Jonl4dDBPZqf3NoQkXYUQA0FFXFVJCp5x1LUUrLmwbiRBbpi1xdZomnq61pMJroBgy9pQH7bFB2DyaVI8fXjCYXVEbUQuFnMkjglsibKe0XcjVOa9jkHKaiZrjkVSBohnkqvQbSuMHiWFz6JtJFSgH/FjL8l1tsFpC0l00agpDUzSs6IGslzX2kpM97YrCS1ZNgauqliUOHGAAyO+R7FQ0/fvr9Fm3oykLFLWmARQkSImsd1u6XuJhZa0mVoYaykScmYYgzArc0ajqY0U0MJ40jPYFFMqXXc/dxhjiqgsxu86K8YsY7tyFSGLpFImfrmuGVk4xFOqnIdzuy69KteeSaqgmUldGTHzjxI9bkqXNSP+ZlEVwJCdkT3I4iKMJCNjX0/dWTOb4McYiYVlp0vnVetEPwg9XMz4weQd1pWmp7AEH2TEH6euFN12TZqASKOoa0fbyHi3xqCLW8H0PWShV3Pqk7WOxWLJ8fExhweHLBYLMY9fnbM6X7Far+Z7Kia2jr7vGcdBup4qoZQ85yIjrGgXhzT1AmtdWV+lba6MmedHiQSXeW363zlTWLAXjVldVdE0TfFpYfZsRKldEIQxBQATpokfB6IXkA6VyTkCYo5tdCYbjVkcgNJoZQnR8usfv8r/97//PXz+pce+4rrxtTse3ZX8Z+H44Pte4+XXLhc51/73ezPtfr/b/KhD61T2/LvXvv3pNzg9P+T8fDn/7NlnbvC//pd+iV/56Hv46K+/i3549Cb7yx//7F7T396HAhyr1ZULP43REqPlky88xydfeK78NHPp0ornn7vHMFg+8akd4/LJJ854//vPefyxW7z7XQMf/nDAVYY4alC2PPdmDjHZ91KaWMl9L6zstlhfxChp0+M4Fga12COM0aOUgGXSnU8MDGxVARa0nhtP1tk5AbaqavE3rGuatqWqagEj8s6mQM4SyJFUEr+HQX5njS9AwG6DOv39X/nx93HrtjwTZ+ezCepv6eFswAfL0eGG89XyTb9/6knx/vrVX3uOR6XeKpW4e/+A//TP/mGG0XLn7tHX+yt/xWO1qslRAFBXV9imwQMu7+SKy0bCDOL9L2Fz4PjosLCGSyI3VqS0MROKDcHksSTBU4n1AIetmgNw/CgyR1vS6qbN1xS0sL+RT1kCtJJK87pmjNlrNk6b5t0ct7/BzaXOjL6ko5exO23sRUFQJGBl6OlSA4tVhniiaqME6EuJbTcUJo0ABDFmujgyeFWSkGtpIEUY1gHyrik5BXHNjLgoaoAQg8CRyopHlNbEwgrSxhKTJHCOfkXtDpnW7ocPraS2sCQqlWmaZqdMCIHeD/h+JI4dhUQ2e/cZY1DaSF2iLEob2sbgrGWxkNRC56ShJ2oVOU8ZC0X1oiagYm/NKSCnmRK4817gFVChZ4RA7BqE/T4lnwO0i2cBLfNWSHvKEpHXLZeGK5cWnBy1rFY1rqoZIgyDZ7FMrNYblkfHnN67x/HxAVMwgFjPxBLSZskYEgJCaWWL1Uapn5VYvj/1xDXuPfuE+DbdP6frezabnk0/luTLidkAyccyjkX+6KwrjWZfmsOapqlZLpaMvsgCnaTzxhAEdI4JRaaxE5gqygGFQucsPtthwKcgPsvKlNT7PaByuhvlZ4koXs0hShN1ZoTl3b0owIi8RiB8jVgGjSXMoAh493HQhw41EwEmlDDmyZp/d0iYhpj+54IGaaUkeK+QWvaJEsJ4kvGikTVv2v9OoLWAgrrUug9/KwlzetPvvkLdNr32rSgUs0Jm/2fTfPTVll/znm1ip+2OYRh59bWbPPPs27hy5RI3btzi9KwjpJ3yLUQwNtMuLDllRl/uacyELE2PCaSdvthOvSRBCKapSbVYOKQM63WHVpXY7pivrgb9hgbCNmNAh4i2UBWqqdEJpbPsRgVAnAg1jH3E1pPWP9NtA3WrWS5roc0m8ZxIKaBCKmZ9kjjnisRtuvOy4c8YDV4rYlqTVcLaQ+rK0jYJP2a220y7qBhjlIkAqGu7G0A542pNXTkOD5ZUqiL5EptrRB4HMIRMH9YoBeuzXiaDBJvzjpQyw8RqKovEtOjKwybdmrqphfavJ+mVmTejKYvPljVSrLrKYgoIo6IihYKCh8z5acfYB4wRWmSzsFS1JSkxZBfjfD3LU0Guq3GSNtN1nbCWhlFkb/1ABhaLivawbNyUQlsFuqT9RKGG973HGXClflMK2lb0/30XCLH0DUNEO0PlNBnNonEcLRborDmsD6iNFKkhehRQFcAup2lxmL6GrCwpFomr0qDtfO8AFu2C4+NjTk5OWC6XaAVdv2K9Phdw0YeZ2p5SnFF9ciaGgA9+l5Q3tWUoVNli5Cl+cgHrKoyrQZsLi8ZkbJ5jmIumylW0TUtVUq9CDGw76bhbI7HhGdhsNvR9zzCIZK6qql2Rp/YKoSRTqtFmZrNNxzRhKeRapQKIrbdrxnEUmYyrcUZkByknxuixRl2YfEPMhLRLPbWFAp+VKeDLBIDFck/y/DymJJ4P627YM2/VxBJrbowFdnLT6XPk+qmSdqlQ1jK1LvdlPNP5TkXRVFwaI90daxRVZcl+l4Y0bTNSSgxDkvRVp+iVF3+vSRJoHVVhgaUYGWMiZ01dNyjtSuGpMc5yuFiwPDjAWkfbtmil2fQbHpw9oB8GtpstYz8UHzdhi1lnMFae0Vzuoyod3aquaOqGtllQ1UuaWrxwpqTNFJkloSJrnRIg99I+M2I+uzceqrqiadsieSrXzmrqtp7vWwb8OFBZjTKxpMIE0ALGi7dKLF376WIG7t1f8Kf+9I9wvvp6JZo96phhzb2z/K06vjqA6O1P3+X0bMEnX3j6y/7d44894Fs+9CX+zk9/61f4TEVKMoqff+4Nvus7PsuHv+WzXLm85nzV8gu/+H5+7Mc/AsCXXn6S//z/8a+86fVf6VAq8W3f9BLf/72f4H3v/xLGSKfz9RuPcXr/hNFbXn3tMi996TpfeOkxhtGV7/S7YNn/MofiwYMjfu3BmwGSGzePuXHzGBBwzJjE7/3OZ/l9v/dTvP89N0nKEMgcXVoXMEwsK1KWe161x/IJWhW2R1l/U8ItZDxpY2cWjIIiNZsK5LIpmZsYRc6liueXNrPP2eSHM8k89MOYUKkbU5nvxnFKaY6yARLTJFDw0z/zND/1t5/hC1+89HW65rvj8GDkfe+5z6989PFH/v7DH36dX/rlZ+j7R+tCvvd7PotC8bf/3oce+fucFT/9M+/9mn3fr82h+Wt/47386B/5AmOKbLcddVOTUpIGZBaQarj7GirLprxVS0LYsbkhoZOaJXkgzJBpao0ZDhfTlijPQNZOVrkDRPb9d6b6KIQwW0pIWJB8jtGmbEan18Dejrt8GhMeMTeT0t7m3jlHduLFuw/A5YlhWRiRsrfdbXAzzCE8ch0o7y0sdqXFz3T6PHKePb1m3yg0OYjUMhVQJ0bxCJufQ61xldyP3fmCTwPWVQTvL5xveWO0ytQ64SojCYrTMww0TpEM7Ev+jBE/ZWs1ikgk0ftAN2bwipHM9lTP0mjnBPx2VY2tKuq2paobrK2wtsK4Cm0MShlpCKnduWu1W+t3pt37pyHzCBPLH2mIG+N2FzqLcmIcesZxJdJuDcdHSx6/fpmUMu3BIW9/+1M8/fQTnJ2ek1PgF37h13jnc0+yaGpSzqw3ndSy40BKGWsMdVOLNFZr9OHhDtjbWxeffOoxmtpwdr7h3r0HnJ6tufHGPW7cusd6KyqnXDrPqQRonbSOsyFTV47aaIYQJbnUOWrniDFKuFOMrM7P6LuNPAM5YZRMpFbvQKq79+5zeHyJ2hnCGIrXsjwIIQViVEVqr4uqRxUiRNlnqUzvhV1rsnhWT1YlO9BK6nIfPTOknGGxqDk7F7WUdXZ+JvJb1SaqeNqVvxGm8c4LM6XJ708YfpJ+Jc+I/AxiHNHZoq00bFIC4SdEtErznKGNQc/gnUJpSSSdEpHf9NVUmZtylDNUBebKb/7b6XgUCJb3/g924NeFt/kypdujPs6HRPBxXw1KznDj1j1eeeUG73n3O/jil17j7PwBzjmOnJX9jrb0PjGUoJBt7+n7wGbTEc82cwAeKaOL31rMCV/UcQfLmpPDFucqRh8YfcAPxzw4Wwto6r+6GvEbGgizzpJiwI/io2UWqnhnqcLeUoSQ5/2LrTWu3mlxRx8xDWibcVVZfDZgvCpRsLL4LdoFOYuPjg+eKZVo9CO2fFZVFQmQTVgrk4Cylci3tCHkTGUV4yDxvErvOqDOWZrGkXNkM66l67TJpVCULk/w4m2RokTOalMXwKMiETEmyjOZFePoJWmvMrsuxbItflXiveVjwNUaK7gXfizjPivapqZqikSg+AQM25FhCIy9p9uOdJtIXRvaVqOMGNnPRwEgLlC6ERN8nGHoB1ZnK3JIM0324LCRONyY5L20IuQE2WOtgA15kCneB0m8rCqoK5lomsZR1bZ4kUj3WKuKxy8dctA0GFXhlEMh0k2ZMN98KF0YTtkAwjhJMQgIltPsn+a937t/jmEYMM5yculECoH7gfOzU/q+LwwkAZgm+vTUJRSGTaCua4nufsggP2cxFSRnjBMm2FTcTxc7FMPNEMYZwLHlPsiGwqCyYhiH2Z9rAkIn6r54fLkLn6uYXi/nrHScZZHAztS+/H2IsnDkDM6NoERjP3WpRl8CHmqLchO9tdCeMyWNpzysOe8o/wWgDEGYgzlnfPIlRp25U+mj0M6343DBW81aw2HraF3FEAI+T4b6U0wycwc3A2FKIE2SbGKLNHHft2u69v7/z96fx92W3XWd+HtNe+8zPc8dax6TVGUeGEIgEAgEwmAUhe60oq32D7uxRWwaaH7y4tW/H/ijQbAVaURtHCCCIK2CEGVIQIFAgJBKIFYqlaTGVNWd733GM+y9pt8f37X3Oc+tW0MwI9aCyq26z3nO2WcPa33X5/sZvIC6mIx2BbizVjqBxTRf5YxKmVi6PlVdMxo11G4mtGKjS7cIYQXGPlnFgDIoJT4QxlmaUcN0NmV7awuFYrFYsL+/T9d59nZ38V5YsKZIKlF6ACV1JSCUmPavZUGVK39WNWRHjH0B7NBkWt+x9FKA9Qy6/h7Z9GsYkpmVYjQeFWmlO2J0q8u9tFrNsUZhDdQjjVErkaF3vsif4sBAy8Wzruvgn/2Lz+d3fvcuVqtPBNsiYbSEZchFfjJ74hM3nt2C/pHHTz3lz8ajlte+5kN85isf5gd+6E/xy+efvGk/yhBT3HbLJT7vcz7Ea1/zQU6fOuDBh67jF37xtfz6O172X3zMN1y3yxe/7l6+4HPfz/bWvGwoSoGnFHc//zLq+TuQ1ZCAWEgEYhTdGnZ2J1y+MmVnR/48e/YY93/wZs5d3HrGz39ufPxHjJrffOft/OY7b3/Sz172kjN8/mse4eUvPcMtt+zjoyF4ePChk7zjnc9DqcxnvvIjvOjuj6DKvNMnOG4OpcST5sGHTvOC510cNi1oC9qhjR2aWr18RWtFisLEzkmMi4PnKjlGLkCY1ILe9/430iAwwI/9xAv5f/7tJxY0+pv/2/u5/Zbz/IWv/4pr/vzcOfH36vyTgbDZdMmL7j5HRvPCu8/z8COnr/EOVz83zw7Q/niPn//FF/Df/dlHGDUy96eUyAXECHHBhYffj86Juq6I1spchsJokfwpNMlIEzxKhBpQlu9C9OmrwpUP1K7CbBnatpVE9RISNDTfCksxpSRraa+IQJqFvfVELgjXoCroZYSUgJmNki/nSE7hiF8sIB6rG4E9OWXUESmlSMNiyqWhxjNeMtWDOCDfz4s8yRotlgjlPaQmkoNIyhKTpyvnAzaAZ2vEz7RaszDCqiP4a0hrn3SLlUZXr2bQCls5jK6e9PIhRTKLVHTkLLNaiVl5PppG2LWRrgXTLofnPyTow+Sss9TVCGsrqpIs3TQjtLbrPYxaA2FaG4x1SApn8Tli3SjVPQi4AZQqlXGVRuux2PaEwGRcc+tNJ7j+1DbNeMrW8S0m4xHtfMH77vsQIXRszSZYLV5c+3uHtO2CvcM9jh07TtOMaGLi+MmT1FNhfcYcn1ShWGs4fmyLSePYnjU88PA5HjtzUWR9/YtSghAgiIfcziE0TU1VGU4em3L7HXcwny+4cHmHEDLHtmY4Z5gvNOORgXycK1d22NvbHzBBrQ1JK+pKZKzJR3b3Dod7RCnQhZ0n8g9h/6eYNtRMzzyELSkqns1wsZyRPZ4ey7NWat6kJKDh6hltEyDOKmOUJhIHoCsG+Y3c75c2AaaMNIdVpqmF2RRbL41hbUjooaZKOZMKE1oXRuoAOCtd/HM1KQU2Aw6ODj2c557D/HRg2DXP21UAWV7fsuWEPMPvP8uPe+KJC+zcfcBsOuH5z7uNnZ1L5EXCOrHpMcbR+sSy9XQhoEwLrAjBMnKGLvQscMR/MUjYidEKXzyXtRY5dOUMSjVoNE1Vsbt/QPTPLvH40xoIS0n4R52XDTClM1hXmtiIwXrPDBHDbC0mzjGhk3hhGaskSQ+RlqFBmaLX1xlTGSpbsVgscM4NjJpRLUawPW25n8OzSmAtFGlTXQnDRFlF7TTzfaF7NrWTFLyYMEbjKis6d2PpfKBtW1arjuWqlY5GU5OyhACslitSjGQ9wXUrkhPE2pVOqXUlwVBlYo5CsPCKymWMUqSSJGmMpD95n+iWnmqsUbZs9xQDjXS56JgftPg2kEk0lWY57/CdJL2kZAaixGbXDKD3wIop0adKGmuomgq/8uSQqKwdEvFm2yNhBgFJrYGHGBM5JnSXB5aZApwTT6mm1kAkRY9Whhtvvo5joxlOO8b1CK0qtHIDO6uPx04bzB95T4XVPdCkIa9ZeYBERYe12Xwvm5tOpqwWSz7wgQ8g4TWxUIb71KJiAnzVDGK0YdSMiseRWe/2+ns8FysStQ5ZSMXLa9UmUhR0PISAiGCFapu1HphZfeG0GQO+/kLitdJLZrWRrrnSa+aU1grnDDEauq4sNqXSMkYNC0HvJdB6j1kq6lq6OkOykiqyAauwZeppW48yugBsInPspcoxSWw4WZJ4egZYf81iELNO0drH/uvgjBEvhyJXBCEyL31HyJmV7+iKi/uQNBMUXQwizUuRNngpLJQ8VyNXMXIWZwwgRe7O/s66QAoalSpcM2ZUj0gu4Z0kSHWhQ6VMZSyj0YjxqOHE9jbjphEmFKp0DVs6L4W1y4qsNc7VwqxqmgFYUkpx4eJF5oeHHOwfsFgshoKtqRsaV8t94T0hRKrKUel6zT5zFePReGALppxpuxWdb5FgBUMvEZLQi1gAzjU7bk3tLuEJSqOMpPWOxyNGTUXlaqyT7mgIHu9bnFLYlKldn8gFIbasSthF23YSSV1CPxZLzT/58S/lPX/wQp5tcfRfMrSOMp/JfxHTJxP8Wo+/8Obf5nm3X+Bv/Z0/86SfPVkCtS7zlMq8/CWP8SWv+wCv+eyHGY8iv/Hbdx/5faWEfQjSSLnhuj1e95oHeN4dF/nAh26iXU34mX/9Ot713jsI8WNRMiS++ivv5a/+5XfKJlUpjJ5Ahi5mfMwF8CoJu6p4/OieEi+Gt0wjNx1fEG+fE3qZAbKJWixr7vvQdVy4NGE6adnaWrE1bblwYcY9f3gLf3DvzVy8tIUP5gjw99z4xI1777uJe++76Wlf88tvfyn9/fzGN/xn3vw1f8jWVius7SQpZmS474M38V3f95WcPjXH2sTnfPYZvvqrPsz2sYCtNtY8+TWRsG14T6aStBdiZm+v5p4/vIG3/OQrBnnj3/5b/5HlUuaFb/vON6zf7BN8z9x6y5zP/9wLfPt3vvIpX3P+wvQpf/bmr3mXSFNTGr7PM49Pjedib2/Ev/ipl/A//KUPF7mrI/iOeLiD04rpdJv9KxdoV8viSSeqhrq2g0LCGEXOktqYUlqDYAAo/EZ51hb2TjNqpC7yZmgk9qDYIN/KiZhjAdTkvPbrYy9BWnsGZXrToJQDKpfkuCx1FgZQeR3kMKgf1MBqCTERQhIJ48Zl1Fpx0HXMajt8HkjIBKqXPK5ZTyklfCd1ipyPRNIQY8AW2SRF7pVSJHQtvutofSgG11J7GSPscudsseM4ypzrR0SsMowq6eAJCPLdmuro/VhXrqSDrkfvL7j2S4N+fpCwAY4oFVI5ebmw/zMQsyry2IBqFV0labc+rJjvp4ExGKMGtVbPVE0tNg6jMa4ST9WqgH7KgLOWtmsL2G4GhpZcO4N1GfLajqZqRLZZu4roA2G+y8H+HocH+2gFDz38OC+44yauXNnj3PkrLNsD6saxdfw4L33pK7nhhpvJOXP5ykUuXb4ASLjQUYCn+IrpFZNRzdZ0RFVCSGIBVa0WpcHSB8i5BJDJu0wnFS+463aWS8+F3/49QifN9pMnTvLCu+5gPK45ODjk/g8+yIfbh1iuJLRAlTq+sgZtDKjM+QuXiopApHG1czhnqJ1l1NRicD4ZkRCfeSO3hvhNFpmuD6lc635vKQzPPl1wUEClQE5BSCPlGoYQ6PJaCaJVL3G+en6TvXPuwcIyzeck++eslMjlBwpnuQtzInSr4Y6MIZG1Lp5gR1Ul/T3cS7P7QDNhitnS/I+FHXb14Unh3AeArb2sjwLjm39uPimbMJ4aXr8Gt550Op7lUH0jfGPs7e5z6dIVLl66jHOOyWRMRuEqh3MOpTToSFaaKlUlZK2E8mRF2h6zXLbEkFBa0RQGXVtsnCqnaEYjRpNGCBjWkjOiCrqSmYz+K5BGOqtYtFEMlbtI1ShsLXK/GDNta4il4LFO08wczdjiRgYT5AZtVxFrpDsiGIHcYMYo8QsKwog5dnybdtVyOD8srJ08TPartmWxXNE0Dm01AoFppFOQMUZYYslH6qr35DJFhimMGGskQSLGRFh6Qa1zHtJgQECmxWFJwcFCFlDCWsP2senA1pFJQhNiwPtOTCStwTm9kXwhE0mM4oOWsvgipZhRBkKK5LaAEV2kXYingnMZ12iWLuNDoKlrlNFDkks/NqnbIqlbzxjGGEajBmctldOkEIVWazWxdFPalUcZQz2WQtQazXjL0dVi0B1Cwhgr7JmQ0CpSW8VoPKHWFbu7Ipu97bpjGFVhdS3mpwXRr1y1LmBiPDKhaKUxGKTBlEqHQ5OSIPq+mEj2I4bA/v5e8fCKhS2WqV1J2ilXTCi3ZYEok0Dvl9Kfr56K33te9TT6nPu0FY/CAwqcY9V2xfdL/BH0xnkOMdB27XCsIa7DFkBADqUUdVUPXTZttHiIxcjKd4McUplechsH2YnIAAw5J2K5fjpLEmYbOlKOwz2hlFD6Y0gYty6SMiKbBQHTQumsxMKUCzFKx17O3LBBzoUmG0LAd50AmNbgjMFlQyixzv05RSmWIQitNpWfpbWxfs4Z7YV2HclEPFZrnLZFtrNeyGLp6JLB6WroSsnCBp0vx1O8SXp/kaqqmEwmTMYTMWjeYE1aq7FmwihPpNhqRky3tqjrmrppqKqatl1x+cplrlzZYXdnZ2Cp9ua+PVPQOYu2UkAoJXLN0XjCaDJlNBoNZvk+eJbtUu6FJMlEObcboIj8jy/Ab89etNYe6YzLMwOjxjEZT2hqxwMPOn7m334md9y5z9f92fswBqHNEwZWbP8ZMUTalbAafRd49PFt/s4P/VkWiyf723zsR8KaRIjC+lqDYJ/4cfLEAf/LX/0VbrvlEmfPHee2Wy5jrdzDB4cNP/JPv5QX3/0EO3sj/vRXvpfzl2b80q++4ho+QIobr9/jy17/Qb7s9R/i+usOyBkeeOgkD+5NePDhGxiPWhZLAb9z1hzfPuQzX/EYd9y6w2+/63n867d+1sfpW2ZuvmGPb/xLvy1HWqwLYtks6gy12gAfoyKrCCqikjAYBpBMS+PKIYydfk1TwKSKvO6zzxyJ9tZK8ZK7D/jiLzhTjkSK25wTB3PN7/z+bfzuu2/nzLljnL+4xcHhiE8VEOC/7iHX4G2/9nLe9msv5yjQuwZxAS5ekmfh5//9C/n5f/9CtrcXvP51T3DHbbs0TeTUySXvuud6/uB913Hx4pjFwhLi1c/9k8Hvv/n/+ZKn/fnHZjwz8+qxxyf8p18/xbvefeNTvma57Iv/JzO7Pv/zH0YbSuryJ2+u+6OOX/qlm/nzX3c/1kLuPKwOCzsiM9napl0dsLe7Q+c72k4zHo+FTa1F+mq0BqvIWpGjKkFLvY3Ikz8vJUjKgwGrLSYZYfivZDPbhzzIaxMY8MELCKVUCV6KG5YlsuZHhBkCoEhYk8kK6qaisqMNU/GIT35ovEKp20Oi7RKVURIU1G/qtWJqa3xMmLQ283ZWmEq6AGFai48YKWNUJsl2hRQCIaTBzDrbNDQgchIrj+B7zyvZxGujSRlWrWfVejHk35CX9cnXPds3Ky2s/CBhS3L+c2kyru/aft+zCWwNP7zq1lZaU4/GtPPDAipQmut2YPf3v6iUxhpKEm1JEYyRFEPx8JV6+3DhCb4rioO+CZvLa2zxG6yKSkPLn5WjqRqq2okvoe0N/aHHTXpLClFOiL1FCIH9vQXRd6xa8dw6ffoE97zvA6SkOH/pPLt7l7nx5huYTrel1ldgXH0ULLnGFKKLRDxmz2QypqqrIQQrZbnvNnXhlTWc3B5zw+ktTmyPefWrP4MHPvwozllWS/Gc9THTRbh+ts321hYfvP/BYi+UiyLBkFGlkazpuhXTyUgS6YutRs5ZSB9dYLHq0Epz9sKVAfQ4sT0r10gxKooZ69yQDN4rUnQBycqWm6wN1506xZd9yefyUz/91uH5jEUF0t8JKSMNtQKEi09gCam7ChTq+QlZQe7TzPP6H61l/5FDN5BiUnnPXPaXSvWS/DUInQrI3INga+mzLvtqXfao+cjxDOtfCRbrSoiMMesm9rVYYhJQkXvy/fr5ufp5eopl6EnMsat+dvUIMfL4mQucO3eJl7z4Bezu7fL+938QMsN56OctpTRjIwDp1nTCwXRCFwLaGLpliw+R5XJFDIFRsWjRKlNXlew7mobOdywXC04en7KcrwjpvwJGmNKSFrZcLGRDFeVpqCphqXSdpIUkEilmfBuwTk66V4ncJZzr44/XM1U/l2i0xCpH8XVy1jBqRMK3XK4wRosZfqE/G2eIZbJU5WaTNIuAzhFle58iGXXtxMDd2jIxMUghY6EDUh4YFZPE5GqNMJWyMGWMJKvMtmb41pfkOulY+SIZUx58ZwmVxjZuA5UWOvXqoENpeWjJoMbCGEtZUhuFnSFSuHpSEdols62GmLJ0MjTM8xLrDK52Gwa46wCCfoJUqi9IDNaAc4YcLW27xFV2OPk+CLXUNjXayII9X3oqJ50ko6HrMs5mZo1jXI9pnEVnjaXi9OmG2lSENqEdpJKcKeybwGgsxqo5i+a7TzKEYnpa2EIp9qwoofRKFyXju65cr8AyLdFKlTjXgFYwrkUDLewwAVK0EbQ/xwg5iXdCCMPPN9mFDGdQfkeZTA6BUECjHkwbj+oyOa1n5YHNUzy1pNMnzMeuHHdKidVqNbC1mqYZuh59YmaIibbIKFFKZLLOoo10k3wMxOBRORcDU1n4dUpi1O79oPN3NmGMI5OxGJQuqY1BQM1+hBjpYqDzAgYP3Y7CvnPaDgVTfx5CCsKW6+nsuSxKZdIPCboYWQVP6D3aECPMmFLpEGUqDG3OZePsqJTInhWqdHFlkUqkcq+oIRyid6/NKVPVGmddoTj3197gKglUqKtajkGpIwubsRZXjajrmulsytbWNkppDg4PuHTpEgcHB+zs7FCVSHFgzTIc6NVy9W0lnmNVVRcT/AmjyQyUwtn1HJSzdEZ79ljKunS7htNOzBCKp4jIcLsB3JNnQzOdTDBG8a7fv5F/+TOfzbnzM3JW/N7vw1e/6QGObbdklYZCOqc4ABFdG/mt372Ff/LjX0EIDR9/8GHT60sT4ieX9fUX3vxbfOWXvm8AvYyBF77gEjHCv3/bq3jLT3/Bkdf/mT/xXn76Zz+Pvf2j/mhN43nd5z7Ml3/R/bz8RWc5d2nGr/76XfzKr7+Ic+e3n/S549GK227e4f4HbmRnb8qvvePFH78vWeam/+Pbf47PfMU5YtiUBKy7iSmonoAga1LeSL4tBaMxhqyFrQtCj+9K40gVcN/0fiNKDcUimTKfF5NsTZHCG45vR77ySx/iK9/w0HDEZ85v88u/9kIu74x54uw2f3jvTdx68xUm444nzm5zcPiJuFefG08em53vp3929/bG/Py/v+vjfUAfo7H+XsZEYrw2UPW3/94r/ojvn/mZf/Nq3vSV72a2teLxM8f/iO/zyRv7+zXv+YOal75oH5cDlVWDQqAaTTh+8jQpBg7294dmTd9E1MgmVykIWfXQ+ZH3tyTCVX+vE6R+DlGldk12UBUMTA5VPIRixpp1cygmK8nYG5s+AYTKem0E1NdGDNojkZV3jIyAJkSGOVDM6jNtK/YgqlLUzpb3XJuNG63wEfBBzPStHiSMPUilSm0qoJAtCfeGUGrGGIPUhGFdU+aUOUKgzT1QJQ2FvuZJqXiKFX8vayTlMeVMKkmXQYsvs6UwaK6KiYtdOFIbCpGueJWmIlNFYYwjpoxf7ZNiKHO/+CRXeQ0g9tfKlrTNoeYeQoD6lFqDNgJg6b7WzHINYkykEPFdy2q5KGEFskfMSjyPtDLUdcXs2DGOnTjGdDrDVm6o91JJE6UQFmR7pUoz29AuF0zGI1E2KEUKHVpXZCyVbQQ8m4xomhFKGcajCVd2LveH+aQVSSmFHU3QIRDiHt6HwoRUxFT8ncr9pbTGVI6tyYjt2RhlKo4dO0Zdny0sRAlCcK7GuIrFqiMHz2Q8kmTzAW8sIKmCUS2BcmzUi32AVS7+dUI4yKQYaX1EK83hYgkpMZ1WnN/ZIcZEXTmMNlRVQ+0a2U9ri3IVxlq2R8LGq6oG4yoiYtBPKizyqyhLAlrJ/W30uh6/WpaoEOAsJglMU1hyLqmhSQgvudc4FxDMp8L4LKxRCUsQZcwRxmS5t4b7UeeBxeacYVTXLNtQyDFyMHJLy/MeS2Mw5l4Z1Nu8HP2uqWATR/4ufWzYYMPvXgMM29nZ5czZc9x9951YV5VzuUEuYJhKCslC5pCuFgsCpQ1bx7Y43N2hVRntJCCvPz9NUzOdjqnrmhgDKie80dxw4wma6tl9oU9rIGx/f0nVNPjOUzW1UAq1JRtFUpGYpR9slCbmiKsN9cgBClspkVOEjA+JptffFwZZv7fUiqLMKgZ8KWGtYzIa0VONkyoFtbVobYlBE4M85ClGvO/oFh1aG6ytREZmhOOinbDIslKsushy2dF2gmLWdUXT1AQf6HxPw4b1ZctoV9FMKpl4Z1OUlnS7xXwhPlQJQhfw1rMyGpsy2pnCThJaqbFaki0RyaAOmtlUOhbzecRa8URTCpIXI1I3qwtwlvE+0i5WBCvIbZ/S5Gonkcs5Y40whXKGyhmssagsLLV2GclZaOzWyQNc1RUxCdMvoQb6unOauhZJXl1pbpidYNY4RpWhMg6rKzQWlRXBe0LwOFsPMe1D4sQGY00bjU5ScPR/1/tXrTvPamg6qKsn03KzVNZSWUtKEWt0mVg3TdatMI6yAEjamCMoekqpRBKbI78nqXpKunrl9VprTp7YBsQjbLFcFUPSo2P9XdYG7ikmVnk1vE/f3do8J1BkkphhsUAJHbjtwvrvgBCkCxhTIoeeddbTgUUW2gPVKQW6LrC3XOFDZHvSDDp5HyKrrmO+WhGKBMGHIPJeLWDbrJ5itMaHjspVw6qfVTnm8qz3SYZdSnSFAeZTJCTxUXBlNZEOSfGf0Rpbkhq1AquLDEtOynB9KIuWPeLVJqN2jknTFLCpyK4TaCvebs5KImTOxfwRGI0nWFtTNyNcNUZrizWKvZ09Dg72C9tQ0q+2JlOcq4fr2ftk9EOVKOHJaFy64ZK4mpDCWBtNDnKvLdvE3oEvhaBsKrvU22j230sYsmrjeu/tH2NrBtOp56FHbuC33vkKvv4vvou/+D/+xSPn4sUvvMhXfvmHmIz3WSwDwfshevx9997KW3/pVXzgg7cPT9XHblyrHNz8u08s8HVs+4DdvdmRv3v1ZzzIN/zFX+fY1lIOp0g6jIYHHrqO7/r+P8nh/Mk+aFonfu4/fMaRv3vpi87yhi/8EC++6wKPPXGMf/3vX8H//v1fwXL19LTwxbLh/geemlnysRkZ8Pzo3/033HnLvBRaEtIht39J+tXC+MRkVNk0ojRReAvrOWmQDuheDEHOmUrZITmq3zbmInvoi631EeXCBOuL4ARaS6GsSrGs4Ibr9vkfvu7d4il1jSJvuTI88vhxHnt8m3/5b17Fw4+uExedC2xNl1zemfIcWPbc+GjHU4FgAG17bRP8Z2aUKX7l7S/lnb9zJ695zQd59NFr+YN9qg/Fd/1/v5R//A/eQu0Uk7FlPLYlVMfSTGacOp1AKeaHh0UBUJ511hta2dQWf8vUMyQUtmwyC8SFzhFNQif571jkSk5lVGWkGZykqWW1bKBtsRyR8CMNqp+pZD+B0qiqEnBEi2qgt3fIFCuRnCStOzkiCpM7VOyIIdD6hI+U4Iejm9deIoZSOGOIGJRa20b0zO/eF3WoMxUYFMo4saEozcHYs9b61xbmRj8ZDtLQJEmccix6APystmtJuxIGXk5R5lujQYnVxGZ90Y+MhF71I4SEUrn8I55P8oEWnwzLxb7I7owunqeWdNXcDwLmofPAHMu63A9Bwnmcc9iqP+Z1rWBK+mEPmsUQyvfxAm55j4+enGG50MznCxbzA44dO8Z0NqUZNTgnpIfKVuWGVLRtRKuMtmLdc/LEcZSC48e3WC1WPLF7yKVLl5kvWrJymMoxGjVUdUXX+iN2J/19Tk/gUKWJrTRKO0nJdZV4aBtNTJkQS5iCMQNYFTMoZamcBJGNxyO0UmUPlyWsQElwibObxvWslUn9eSseuKYciyZJHWzdAIrEKNYu1khXLGVQSZQmzmimk0ZAqP5YlUaZLP/oCHmJzQqjR2xNGny74Of+3S9LU9ium9TWSLqwz3kIRUtZ2GKksrdTUG9MvzEhNma594tc75NiFDWTLuEM/WmIae03eUQ9FKOAZqVh1+9J++PrSRhJJXTuk48ts0lF5zUh5sEvNZeOoS4y6Z5l1/ul9c/p4NXdk3QGsO/aQNgfhQ32VCAYZPb3D3ngwY/wGa96OXfccTsXzl9kd29vOH8p5/Wbl0laA+PG0dSyF84pkRrHfL5PRjGZjGhGDVVV0dQ1dS3exyla/HiKNyucEQ/lZzM+KiDs+77v+/jZn/1Z7r//fkajEa997Wv5/u//fl74whdunKzMd3/3d/OjP/qj7Ozs8JrXvIYf+ZEf4aUvfenwmrZt+bZv+zZ++qd/muVyyRve8Ab+4T/8h9xyy9MnXT1pKAg+UtW1UFGHhCCZ3LQRmV+OEWcV0Uf2d+Ys5itGk5rxtMZoMZbuViLt6lOMcuy7zyBKSImQr4xsvp21GFcMqSW2qEw46xQ8KamVgDIhkZLCVpHlosPWMlHXlUUZVUACWYC8D1hraJoKawxt51Gqw8e4NoKVr4+txVtMa0VdV2uEuzxkPWtjsWzxIVHVlmbWSCfGloWajCnHoLR0UuTh1bhKl9jxPlUxF8PISr5hyni/JOdMu5QuRzNyuEaQq5Sk+15VFrKHnKmdILk6R7TRdKuA0oqqrqhqh/cBZyPZZ3KgdKCEBZaTSFYrZ5jYhutm20xqRyZQ6QatK0DSLikSxj7yuV+MKydaZIDlcknbtk/yzjqCpitVkmUE0Mk6De+rtaa2jspaTDlvMSWMijI5KDFENVaMIWMMUmSVTtT6Sq6N860T4LFPD1JaU1UWpRyxsPwq58gIS7FPFuo9JVJcsyhyEp+4foJdG74buq6j9e0QY78J6uSMAMXl+29S86/uKsiEuvaM6tlTKSWiWsfYU+7NrJD0UqtxTq7VwbKj80E886xGW4XvGLw4AIyq8dGLkWrp1BlTWJpaD1JEp6DzIoEMBZBLuTc2ZQC2tMpURpMxpCxd0drYwYxRFT4piGl+fxw9o8poU16rqasKZy2T0ajIXvs4aIrpv1ybylVFAy+d3Ho8Zjbbom7GEoTRdswP9+jaFYeHeyzmh/JsN2MqW1FVAvj3XcxBLqGlMOxp+845YYvB0CWKWSjUZDGJblvPqt30F1DirbY5xZbjD8ny/g/cwe/87su47wPPYzxaceedV3h/8fh5z3ufd+Se+Pb/5T/x+Z/3ID4kLl3U/OZv38lbfvINfGLGtVbyTywY4VzHl37RvbzhC+/ljtuucN/9t/B797yAP/Mn3sPp44sN0FlkIXsHDf/4La/nt9/1gmu/nw34YOkTHMejltd/wX0cP7bivvtv4R/809cNP/vUGJG/9W2/wGd+1iWcrXFWY7QwIftL0XtQyn8oWTCtwignHXul0dJRGrqlUnw7ksqSwrxR5Hnv0Xo9N6mNOXBd3a0j1KXmzSgMa3OVfv5KQyGrYkYr2YShyu8oaJrMi++6xEvuusQbv/gByHD2/JSc4YbTh0OxmpLi0ceO874P3MCFSxMuXprw6OMnOHt+i/mi4jmPsufGsx9PB3apZ/FzODgc86u/9qqP+ZGtxzMBcs/0uzzj769aj8LQxF5aJwiWso7xdMZpLazQxWIhjI2NdxSfV2G8kxlsDpRSjCqL7ZPgtLDBlBIFxsC81pZEwiGp8ZkCNORIiAprN3yHVLE3UZqUJMEcxJesP+6cxQvRWAlTisnjckfOYFXC6Iz3iRAhZU3WSjy2yh4na/E8CjFAkMaVVgrrHMYqhK2eh7RnEEaKWLIwNAqyKknyVYVOieC7ApKp4fwoBXVtsDYNFhFiFC517nrTnwtjYx0goJQi6yx4Sw/QyCm69h76qpFSbzWz9iLWyhCzJnk91FsMDQ6GICY5olzOv3yfTackW5rS/ToTQ0QrW/Zw/ef3AI5IIlNKRN/iV3KNrU244iEcQ0fsWg535nTzK+yPRoynMybTbUaTKXXTSHo6RXKq5D7b2ppw883Xk1OSlmzOHBwcMp97YtYEH+lWAZC9Z4gr2q5dPz05s1i2nJpNSdrSpUjYqBG7tqPruuIJF48+ZWUvKzJKRRsyJ6cznHV03mOtAL9ojbYGY8VXuzYW5ypUOa+bF9Mazda4Qts4AMKgqIyjdqWpRSZni0LUNB4jzO2cJMldKCgDaJKyLoE6vbWI+AjnlJgvRAWDyiyXvtT1ZgiJUzmiUqLWCmUUSmvxjCtgeQ+OixVO2XdoabrFsE5Fl/2bSBtVSoSchn1OQhOf5oYWDzMB6KzpQeD19ctR6owuRDovrPjJqC6qGznWfi8qipmINYZgzMBqlPda+6Zligx24ziO4E+bJdI1xtOBYP0QximE2EOx8qdvF3zkI49z5twFnv/8O6mbmu5Cr06StcKUPQsFJEQp6sqU+6Oc+0nDqp2QlWI6nUqj39khCRpkjpnOZjCpyb5m91mq/z8qIOw3fuM3+MZv/EZe/epXE0LgO7/zO3njG9/Ifffdx2Qi3gw/8AM/wN/7e3+PH//xH+fuu+/me77ne/iyL/syPvjBDzKbSVf8m7/5m3nrW9/Kv/pX/4qTJ0/yrd/6rbzpTW/innvu2ZDVPYuDtwalNWPbiJ62MGZWy47VqiUmSYvpgsiYQpepKsPi0AvFUilcJSfQ+0QMCb+C1GmI4gWwaj3LRYv3JcnFKOrGgpYSOpcUQdNHpcZNczthkfXGeKtVQHUJ34o5XE5CT82J4gkg8qMYo/gaWENVVUWXnPDLIKszaxM/7cRoXylB1XvZnvd++FzpgMPSe5GLak1VG5aHnvGkxlYGnTJpxQBj51ykkE6+cy5/GXyfnKgH9FlbCz6Dks9KpfWlrEYl+WxB4wtinhKVE2ae78SbbDxuqGsB/roSIkDqvbHEFHEybdhbtIxNxaiqOdaMGVcVtXX4YMm5JuUKrYQJKN01AUFCCGupTFa0q5aY4rAoAEPnCvoJRg++S0qLcSY5Y3KR1hiD0ZJQ0VSOnCSNE0UxMe0p2oVH1hdTZaToJdmqfF6IoYBroWy4ZIKw1kn3LPdgkyRB9mkaKRfvh0o6LG2SztawcdxI7RtYZtagvCqLdhzM+nPOg5dYSIDRGOf62kE+ryz2IQrV12pZjPrPAwZgzTqHs1bAIyUFoCnA6tLH4Xu3XUfro5hn1pU8BzqVBUmRosI0Vrp8CSrrhnMrPmxq7fGGUK9dBlQuj4zEmKsUS1qLPJ2aTGMtVhlsKXKM1hIq0YNnhbZNuXdjTBJMYYSlVzkn6TjGYDcmZBRUrha6vCmMMCcpjc1oxGg0Zrq1XajAidXykN2dK+zuXsF3HX1SqTVSNJliJKmUltABpaiqagC+XElo7M1dxSDUDwthCIG27YaCOMQjkBexDxhg3QFOUfNd3/tX2NnZOjL3LpbNAIIBR9hH//jv/xR1veBHfvSzedt/fNVTT+Cf1qMs4FdJmF76wsf50i96P5/72Q9QVX3Xz/KKF53hlS96AgVopNngveZtv/EifuTHX3/NT5iMVyyWNTkrfJCCsa4Dt918mRAMv/Srr9oAUT41xqtf+Sj/x3e8g7qJtCESkiYhcgdFLsnFG2mwWdiIvlP8yn+8E2PgxLGOP7z3eg7nFbfetM9tN+1x2837XH/qAK2lkB1YYhtsxTj4/agB7Mq5TwYsry2v7zd1a7PcYsyfjRTbKa7lCykRVe57XT3fTJgkZY3vd2DXnz6QY8gU+aVCGbjrebs8744d2ZTrNdCeShMhZnjs8W3ued9N/OH7b+KDD5zi0pVZ8a761LrGz41P5nime+GZft6DVJ+a99R0umQ+Hz3jpqttLdtTLZulHnPSmpwt2kTGk6mEBUWRwQ/e6htsCiGWyKY7BElMHNVyZqIP8owWEGsI9ImpeKtqMBUqi59WZY00iVNm56Bla1LhTO/FS5nrNL2U90jTMa3nD/nwiAodva9Q34CW76Dp3Rh0YUelLN8zSuIDkEgKyGlQqSik+dnXaYksDJiCRClkgy57UFG3iHqg38+sLU5k02oxSROUgtyRIoPtS0qi/Ogbs/0mNZOH8zn4CW8AJ1eblvfzdz82SQCUn6XS5IUKZ9dKClOkkf25Fp9YSBjyNe7/XrnSA2R9/dYrAnJphGatsU4PdWmXNEEVOaU22JyxVhG8gGQpeFahJYWOdrlivr9gPJ0x3dpiNB6jjSMqM1zXremEm2+6jm7VETpfEuNF+q+1ASxWO3K2+CCMvc02yshaqhqMUmhVoIikCKXp01uo5NJo789EVmsih7Ei0dXaMBqNiUmYZbKnDOsLVh4oYwxNXQ97942eE1YrnNMotQaRrDE4A85qbCX+aTkVClUOhFTC6hLD3kXW8SCyZG1Qxq6vSSqULSj2HSUl0jk6H4vdkHiK6yiprGLtgewLsoBdSml8SGSlaVxd7uXi45UpXrKxkBHW37G3F9FGY6uqFBlXo7tSb8SUBI9QuXg1yj0bfJmgCqAvli0CavkSVuWsoars4NGslR6a9sbIn3Eg4xzda0IeGtzXArWeDgR75tFz5ASczOqoZ13Kif39fc6cOc/Jkyc4dfoUjz/2BIcHB/ShJ7VS6BKMkbIQL3TxHi/vzGjccFKfIKOpqvqIPcv6e4hHstGaauSKZ/Yzj48KCPvlX/7lI//9Yz/2Y1x33XXcc889fOEXfiE5Z/7+3//7fOd3fidf8zVfA8Bb3vIWrr/+en7qp36Kb/iGb2Bvb49/9s/+GT/xEz/Bl37plwLwkz/5k9x666386q/+Kl/+5V/+rI/HVv3mXR7nTBr8nrwvBnVGUzUi80MhLCsvflviZifyixyzmGj7jE5yg5EzvgssVyv2DxcSZ5s1LotcLJaFsWe7iJ9Q0cfniCYCIo+Uzkkgh4i2jm7ZokYV7SpTuWKgmdYPsS3ARyigmLdCL3WVoV3lAiwJKFZ8KMk54EOgXa1kIz1QVGVBDyERVp6qcYzGDu0U9UgACt9FtIas8mBc1yfWKMR/oN9zDQtzMZGU9Vthq7WXlEhFFWRFKiCjPGwZXWSWMWZWrYAu29tTnHGoXsrZBcBiCvJPUjTa0cxqTm9N2ZrUzEY1GiOTUpYFrp9/epZl78XQq6FSTsyXc8LB0YjqnDMprPM0+kQPXQAtVYCRlBIqR8gRjaJyJX3TFjZWJ4i++Ne5EqPdJ5lEUowCJPYTVpmBVJmMs5VoYaOFhSYAR0VWSvyVyHLNNeQcIUu3r5+MFH1HUIq8q+nvfQHQdz02gedety1U5YQPEZIpkfVSDmTW36XzLY1u6LkXOSf5zAKiGqMHgMZqjcmFPKlB5YzV688VqrumqRy1c8XzRxaKylUoJYCT1obFynNiItJDpfsCONOVmG7Z3GqsVhgl3l8hG7rCDBw6JaUwMEpTa1s6RwJeWq3xMTIw87N0z4zWOGNonMVoKxJYI50a6XxKQaG1gKTaWKyr5R/rip59xmQ6kysZI4cHeywO91kuDlktF7TLBTklKTiNwZnyXbT49uUkDC/rHE3TUNdCEe6LnB4Iy33io/eErOhCFiBs8GUQI9KUcllsPShJ1XnfvS/jX//rP/00s++Tu/7f+k1v5Yf/7y/nr37z1z3N7316j5tuuMy3fuMvctstl9FKce99t/P3/vEb+ZIvuJ8ve9193HjDnmwslBKmEQB5UNxl4P6HT/P9P/JVXLwyu+ZnjJqO5apivrhaGqloW8eHH7rh4/gNP5ohc+XrXv0Ib3rjE3zR555DkYgY2gSJOMwLIs8W6a0xcjJSljXgl952F//xN1/Ahx98eqmWtZEbrjvgphv3uPH6XZqmI0bNZOwZNR2T0UoSImct80XD+95/I9pkzl/YYjrtePELz3HqxILZpGN7q2Uy9mUTnQv4C95rjJWHvrK9obJINQbQrTAZdNlAKsUgUVKsWacDSFbmGR9zSU9G5FOl8aKVSJWed9s+z7t9nz/zJ+4HRKZ0MK+5/8On2N93fOjBU9x3/2k+/NBJuu6p5HHPjefG041PBAD2R/+MN3/te/nnb/n8Z3zdD/7Qm/jb/79flPVa9WuuImcBCzSZ8WSK7zpWq4XYkfhULBwAJZtppQ0qGWIXyxxdjMC9sFNiWXurqkJrXTbepSjQFq3c0ARHG7QRKVceAJdN0KD3ILrG+cnrupOcUBlS7D2BFDplnDalMSy/YoovWZ9M3nskZqQm977D5oxyBlXqEQkmz4P3YgJUFkPzFAPBd/TNBPFvKil9qNJU7H3OejZOJkVNMNLgASTqD6RZ2Ne39Az5dT1aVOxSrwBDckrfnFAixesBOK37c5dJkQI2yDqidaR2pkf2ZP/RN6D786qQZvbQBNloEOt1XZyzNE1j6i1x1gmDVmecEl+1rMEkjRlVRXUge6KQpP4OuXiBlbXftx1dF1ktVywODxlPZzSTGW40wVQ1Bqmbj23N6OrA4f4Bly7vslq1qJxo6pqmrvBdx87lK8wPDlkuDgmxE2lwSlRaU9WV7IVzRCtwsk0k9dd12OXIKTFKpJA9DiMNPo22EvBEzoPyJIaN9S33jaA1YNXf5/3/aq2orMb3CYyIisUZvd5bFTJIDgpiKs8x68RSGPYlRgkJwZqS3JjW1iabo5fmOmcIKhWvOZGfquzQWm0A5eUZ01r280qRkEAD0yc45kyN+BGvupZkwOpMMpCSIkddgjgsylp0TCUEbA1TKqWI2dPFgFaqsNvk3g7Fx1kXf96Y1mFU3id2w0KOobKMRzVN5Upggh6A2957TZXzF0M4cp17yGjzbG3CRJtgmOqbfuXeVb0t+VMyw8r8dRX41/99iJHz5y9y0003MBk3nD59kv29Pdq2KxjOWrF0LS83pSUxd2KczN0bkuWrJdU98F0pRVM/2V7kWuO/yCNsb28PgBMnTgDw8MMPc+7cOd74xjcOr6nrmi/6oi/ine98J9/wDd/APffcg/f+yGtuuukmXvayl/HOd77zmkBY27a07Zr+ub+/LwdfNq0hyOQVOtnkSVqdQjkzbPZVn2SiNaOxxlhFCFKki4ZYEYNUu8rJxKdJoEpUcjF7z7nXKRf6ZEwkLf+UqRRFhBzQJJRJGC0yxKoqCYEm0S0D1iraEEhV343OpNibW5aEGRikiv1D209mesh9LkuaSoTg6XxX4pLBVQZtFCkpQpRkiRQTVhvsRFOPKjofyQgCS+aafiiw+QDkddy4FzBMaWEZaSsMMm3W4IsAhcKwEoBROk8hZLouYrSirhwqG1YLTw6aSot80RmHTpraGrZHI05uT5iNRjS1Ez05fdonKJUEfByeI0UqYFMP+OQoEpr5fC4m4qNR6e6kI8b1AMrIsVotJqsxJqJKoDOmnPfGGbTJoJHE0FTkZVkm2nUbkrLGF6lkofyGck8JjdxinSkLbynuEAmfxDEbYpJOVC7U3KgCMYUBnJJDkQQe63rD9ljkef19FGVhUoq6ls5HLJ5osuHT/cFKFy0nyH3RUACv0tFwTqOIBXwpDEcAVeRMRMAUYFXesgcUK62ICC29qYXNVlXiKdGfMmvFQ6Nylrp2pJSpynMBQkkHWQx789reD07DRkEEwSR8MoTiPdD7/jljMVlYYHL/msIIE0CQ0vGzRqKe68pRW4dWazmpyqCNdF+ttTR1U7zXHFXd0IzE3HQ8GlHVEnCwv7/H/GCf1WrB4cE+wXe4Am6JX5SAiU3VUDUNKFf8AXJJGxKDSGukGO+6Tq43JRY9BFadp+s8Xcy0vviQbHSxOh9pu8D+fElOmXvv+zzuec9rubJz3ZMngCNjs5iXZ/vv/vCffIbf+XQbmeuv2+V//n/9J15y93mMSUPSkFEGoxWf+bIzvOWH/gVGx9JVp8dC6eUZSsHO/pS3/JvP5Vff8ZJrftLWbMH+gZjfP5O31yd/ZE4eP+Sf/8BbOXaiw2dLRnPYybwVM6ySIiaNEfEHWmtar3n00Rnb2yu2p56YMrt7jp9960u5eEkYh6dP7QMZaxN333WGxaLhzNljPHHmOCEYHj9zjMfPHANu/6iP+j+87WVH/lupxHjccfutF/mMVz7Mi1/4GN/3d7+WY9tz7rzjPDecPuTEsSWf81mPMJm25AwhaQ7nDbNpR+0YEtj6PzUaVboxvQegHtZoaWKknPABYqlONSC+N/Lnqo2FlaEYjzKf+conUErxJV/0qEzLuQcSM2fOTfm3v/Byfvk/voC2/VS/b54bz42nH7fc9ADwzEDYufOn6Hxk1UrSn8l5vVFLCp3FfmE62yLmxOLwEO/T4EuVsqyTOUiSXOHLsPRp8M0RW4VILOo6Y3TZoBZwKEtdZZwr8kqN1patiWykhYGkGQTgWtQIT8d2WwMRBrKEy+QUMQiDpmeQZkSGpMqGXn65nxvKyKIS0SaRieI7pPRQEw29UaRG16ln6KaBZZdzHthOSktdVX4i9WkugGLZyANoa4c5f5P5plBDbdaz1HuJn1IUsCYNLH8JQegkGT6LhxRZDdenPz5QaJ2G0IT++EwBB6Qp3vtChrWsbmDP69K0UqWpoamdFTAhyf2gQJrdgNXgigRfO43RbgDCQgjoAL5IZU2KDCwMJaBGG1ZiS9K2TLxnCjRGYTNgbJG0ShZydWmHmBJNZRnVGpU9O1cu85FHpDYMMeCcQZGojKZV4LQePHPLbUdllLCzN7yC+/tNixPLAIaFmOhNy+vRiP39A7piM9MXNKq8r1brvciR+5geTBFSh++xYy1BVsYIICli1b6LVAIkUMIkM6b4l61tEQT06QXGCZUCujekZwMk7q1TtEI5LXvFAnCKhY34GavMQOpIIQ5gYGRFil5Yfq4SkFtrnHIEE8g6YbWmGo9o6kYUUqWZ7DP4kJkv+2Cyfo+n8CkU9pnck96v6/HeF1Xu3qOThPdxYIZpLedUmmi9Z1oezi1K5oTI0WE2Ht1hi7wBbPWPag+C9dexv24Cwucjz98mUJDJTwq8kL8X9vv58xe5cOEyd95xMydPnuDxx59guVoNc84QFlDm8qtRN8FvDOJ3VYgZ5Z7M6+2qNBqLB/qzHX9kICznzLd8y7fwBV/wBbzsZVJgnjt3DoDrr7/+yGuvv/56Hn300eE1VVVx/PjxJ72m//2rx/d93/fx3d/93U93NIQgDJZBrmcQipw15cEzg3QSBNTwXcCjqOuMdUKik5tJNu3BS+fE+4BRiuWipRlVxFBo0AayVrJYRjF2lD13b8ArF8JVhqlpaFcBpTKHhyu0iqzmYizfroRO65xFzP17NFtQae8F6NBas1x1hbYqk4exuiQ+puIv5vHBi+m9Busc1oopYtcKABULCKLKAp+LtlnpjNqQRmYoMPK62zF0V/oFORdTdC3HYqqeVbMGXpSmgGx9lycXqUxhuaRE8BGDgQDbowlGa8a1JN/lmJmNKrYmI0ZNNfhx0U/MMIA0R1FtQZf7/4spDQmJq9Vq8AUb/ASUImx0F3Lq6cPShcjl4TLGQmHVVM6AMSQSne/oYifJkWi6XBhE1ggwZfqJnPW56Vl7SiGAEdhyTnwIQ9pQXRIZq1xJFyRK+l7btgKDFpqz3jgXpiQRxSipl6jSJehN3/N6upUuxIbvlFLoPvoIBjDJpOIhh6QP9l1Ja2UB16ZvHSRi9MJaI2H0SLqvrCnouoCBulJDZ1cpRRfEUFIP59tQV1bOdc6MUQNjSikkJCAlicDOmazKvYaAYhKJrKgwpGzxMeBTxJfrXxk7TJr9a1WW+8GWDktTSfKNdQKIGcmgKr4YxYDWWIytcc4xnm7R1A2uqqibhqZpqCqH0ZrVcsHB/j77+7t0bTvIGK21VLUAwKaY6FrjqKpaWIFIF0xpLTJi69DaApqYFDHL+ep8oPVe7p/gC0s203Z9UmfikY+c5vff8xJe/rKfZ75Y8Xu//9U88cQXkdK1lwRrAyE81XLxqeRN9bEZx7bn/NMf+rGSJrwuZlRGTN37vYfOOL0uoLRBNjwKVp3l13/rbn74n33xNT9je7bAB8NiWQ8g2KfukNLprjsu8/w7rxCS4gd//DWsOkvXGdryT/AGYzMhKrrO0tQeMswXFTs74yLxhLr2TCctu3ujDWlp5uKl2fDvZ88dK//+7Auaj+obZc183nDf/bdy3/23Dn8/nzc8cWZtfP+jb/kiBJzzhLAGm+684zx33nGRy5enXNmZ8eIXnuHuF1zk7hdc5PrTc6zZAMmU5id+5lX8zM+9AoDbbtnhi7/gQU6cmJMzTMcd41HH1mzBdafOyvxtpaGhrdg+GKNLR7xfr+D2mw75377xXbzhCz7C3/jOr/i4nKfnxnPjEzMSs9mFZ/3qmDKHC49zmqYSI2tp0iasAmMUrhlR+cB80dKulqQulSadSPikqV0sFVRmfx7FDkSJ7CopVQzxO3meVc/i7GvwRMyy1UsRMBqfhTWUc286LinZRSg51MyDXPsa81tvLaG0HsAwYSQp0H0YCLIHKJYWPRNsTQMpjeIsPkYpp5ISLvW5MGvM0Ez0ud9QitRKyjQ1EA6ULs3ksoPOpdlsbaKNAZUL402bAag48p30unE42FgMQBTkAi6Zsl9ThTEEmZz0YNnRrwf958v/5qGm7ocucrdeIil1b4CYRSkSIWmNNg5TFnBVmp5ayT4wZTPIE8VcPq03/IWlRDlfYrlhC5CSgRrXM+9ChCiNVfndRAyedjXHHGoUAdPUqGomxIGcacYjTl9/kuvOn6CuLSkHrJEApiu7V0rDWPZ8OSVOnNhilCKTppZzp3oygsJqaUmFIIn1egMooz+N5d5JSYCwurI04wk7u/u0rTRUIReFDOUXCgDVQzeqvFHhaPRJjLr8vS0NZXl2KEBMASkLIG2MplZQW00wYhDvFfh4taw2YRAPPWcNKcveIatNxqLU8Vn13ltFVUEJtzNG9nkxDvtZ2VOLAsd7L8SaqimAiyQ6+hQgiwT7xhtvZlRZDncv49uWeevxMVMZ2ZHFopwSTlpEq1ruqdJsl+etB5mLPLXsV4Vwo6iKD7gx5Xks5zP1oJF0yNbPV9rwM7t6bilb51Se0H6vvwaX16CSoPlKCBq6qNZiIsYNwgj56Su0Qi27fOky586d5/kvuI3ZbMr2sS2Wy9UanE1FXVesaJTcjJDzwGgdDqzHJ/qxxpqHa0689tx6rfFHBsL++l//67zvfe/jt37rt67xvY9++KZ30FONp3vNd3zHd/At3/Itw3/v7+9z6623ykKmClJZJqc0nDhV4ogNprA4XCUof9d5fBdoV15uOltAnLKgDIaMZg2MSbSwMJjqOqFyoVqqsjDFjpyjSCu1MKJyWRiaxmGspq08daNJKdAtPb6NRGUkKaskrVROPAsViZwCKYpxIzlTN45V68vkovGdRpdj7QmvIQhAkpJ0cqrK4CpJhRQqsKRixhTRyYqpnxE5ozbCarDGSOcqZrQtzJiQSvT8eiEcrh0FQLBauiZmvfj0iLM2wtHJOZNdzcoHRpWwfOaLlnbZMatq7ji1XQzMFZUR6VnOisbZEoigh0KCFKT7pDaknEeOimHC7qLHh8ikbnCVsG7ErI8CXLGm6W48Yf0tOSRcpExTVxhVk8k4a0lKZHS9+XyMkdrW0jHRUmxUzqEQ5lKmSEqvMfpJMUaRyfaTtnEOpyucdSSXmC/mLJaLwSjfGENVaLxH309jrJi3pxI9HUKk7fwAbMoZyiUZRS6YAFOSnqRUHzmthu+skkJFmbSrqll7VCkBlF1VkTthn4XgSa5GG/Gw6gsyZxzGGFZxNVzXEGVhly5n6bqV81hWWikqe1lnFu8hTabSCl8Ws14ObEr3pAfaMmCCxoSIzkGASVkfCxgswJnVFmcy1gS0gXFTFZamGgoGYyyTyXS4HxNgXC3Mr/GU6dYWddMIzT5GDg7mzA/3WcwPCV2LSJ3FW8E68SxwTqTK1lgqW2GLt5i1rlxHDUaud4xCqaY8VyErgo8supbFalU8wOS6Bp+ZzyO/f88LeOsv/rfD/fGeP7hW931dbDbNklGzYmf3+DVe98dvOBt4xcs+wue9+iGcBdlYMQCjujB4ctrwLNlYgNGa93/4Rv7BP/0iHnvi2uesqT2r1rH3KQ9+bQ4p0j78yGk+/Mh/edpc27prpN+pp/j3T4WhjoBgAA8/cj0PP7Ju+j32+Ene9mvy76NRy513XOBFLzzLXc+/wJ23X+Stv7IOFfrI48d5y7/67Gt+0v/7b/wyn/WqhwffUhPAOIVziO+16pOfpMwLMfKSFz7Bv3vLv6TrHG1nCa3iYF5xeWfMxctjHjs75cMPHefhx07Qts9OLvDceG58IsfW1g4exXd++6/wg//g9SwW9dO+3lpN2wYODkBNHZURL68EhKwwSur/qklMthIYx3KxoF0tJcG4MMh7sEShJHADM9RgKGksGaOZ1A5t1dC0ssaKx6lfkbIGNCko2uywxhdJX0Rb+VkvKxRmRSIS6R1wNrhZAzPEaI2xlqA9IXQCGpmSXJhTMeRWG2CaAlwBzTSqvHYAJygAVBIQTVhlikrbgWkeYiqWKwzAm/gZpkJ3Xvs7UurulCxaxQKUSTGlyKiNGtdsNPuUUuKHG1Kp29eySQHqzJGkyb7Wy1mCn0zZW/UBY/3oE8OfdhQ27VDkJ0AlUm/kXk5Vp/UgVwOpj4MXIkHPZesLwU0mSv/XISZQhsrKO7RRVBTGaqEtKYVxsh/z7YJF7jB5hqs0lXFlX2rZ2ppx5523EFJkvliyfeIUzWhEFzr2dvY43D8k5cyoadjeGuNbT2gaUohMKgk0E1DVomIaPN90AahSlnth8I8iF2N5VZI3K46dOMXu7j7Be0KIEvak1x7R6up7d/ivspcsrDAQWaRWShrmhbXVS18p59VqhY4eW+xNQgF0u/5eKIAsOQlzTItMMGVRcfkMqvj49VCNRpO1gFghBQEEVRZlVAkJ0IVMoo0aGvvRB2HKKbn3xF9v7RtcNw3b29tUJLpd0NpSNSIj3aqt4BJRQK9lK+qw4KQZn3IaCBiqqGNiaeD34XU9A9UiwQTOinrmiF9eFollLP7FOV2bmbU5lGKd1a7WFf/ADMzi56ySnHurLdXIkZLsHdsuFFukteT1SeDUVWO+WHD23HnOnj3PS1/0Au5+wfNZLVsuXryMjrrsZeUaapVlbhykuKqQOQrBZvjQHrA/+skxJsy1t9jXHH8kIOybvumb+IVf+AV+8zd/80jS4w03iHfJuXPnuPHGdSz7hQsXBpbYDTfcQNd17OzsHGGFXbhwgde+9rXX/Ly6xGM+eZRNb+lopJTpVoEUI022VC6jXGHI0FPl1pNnj3z2AE9v5BhipmsD0YsZuHNi0B2RG64q2aopRqyO5J4pFYXZJClvFlcZjDa4yjAaW8zxGqXEp2d5uMKvYpExKVDiO2asoXKQc2S5WJSOiPhQZSRVxHeBEFVZcKBrPeOmJgUhYov5Z5LPdo5m7Mi5w7lA8MXsLyS0EQp0VApdGUGhu9gDuDIp5L4LdPRGG24+LQ+tNmrwherZYP16k2Imh/WikREQYdFFxrWljolKGa6bjbjpxLaAIlE6Npme1aPACFXZBzFsNMljlUjSNo3gN5+JfoFSZCpn8NGDUriqFlZU/3rVL/ybEsAezBY6aI/s65HCWdkUyaJe4pRTRGVVQBRLVYziaydG6hkxhExZD0b3WkkCSq+RzikPQQc906vtOlLOVHUYuiHeB9qupfczGBaHIxvIXOjsJakkBGLwYk7f+iIj3jQ6XHdvtNHFPLVPpBSGUk6JuqoxMRC0GEoL69AJaFMM64w2xCYU/4oolPhyjayyRxY0o8zARIsh4jtfuj3FD0ArDAZd5JmuckN0eF/39FJCXT6//1amFFHWiu/XsFiUzk7lKnyQolUVBkdd1dTFLHPVrlDAyI3EV4CSyLnRRhlPphhtyNowmkwZT6bUdSOLc0wcHBywv7fD/PBAwNcYsVoxmkzWkdzagtEo6wihw2nRwmvrqOuRpPKUpJgu9KalUjr0XZq2ExZYGzydDwL4+8CZJ47znve+gv/8/ldyePhsAC3F9tZ59vavZ7UasVqNnsXvfPqO6WTF53/OA7z6Mx7hZS96nNEoDLJrYNho9PNLTlcvu3D2wjZv/dVX8vO//PJrfsZsuuTgUM7j6kkA0KfjyGidsSZhbMLagHMRayNaZxaLhuXS4f0f1ex9DcZ+Oo7lsua+D9zKfR/omWYZrT3WeEJ86ut/5+2XuPGGA5RxpK7Dp0zMGVvWTY3GWrUG75WiK5v6ra0lznQoMgbp3qOk6vERlj6xWHmu7MLjZ49z9txJ7n/AcfbM9Vy6cgNtNyZEg1KyUw7B4IMh580Ao0/fa/Lc+NQed7/gEXLOPP/OR/ie//0/8S3f8fQMx+nYsesT82WgqS11LUnUilKvWrlv67GmasZsHTvBwf4ueztXWC4WxBDWYJjWdK0nxYg2DRSeSwiRw/mCra0Zyjq0lc25s8J+j75PB48okyEapsWrzNq1L2os9UIuxzZYcCgGZo+QkkReKT+Xpr5I5czA1lJKiWl/z94vQyuNa0ZDLWmMk/1Nkk1y8sKEU70cu+yAUwGHBklS/356I/1yGHnjD0k11Got1RJjDkWOYQCbeuPyHtRaM3ri8HayMddkk9c2JpvfzWhs2a6KlUkmlnS9/rUh9g0C6DfIm+9zddr5MDa/Y5YU0c6rjWslZvUhigd1aRuLHFCxbrb20rSMmJs7K15TWtQV0XtJ5jTrWpjCfMkxyH7PGlw1g5ImOB433HrrjewdLGgmnpAzV3b3uHh5h8cfP8/e3gHXnT7JZ77yJWwfP850OsM5x8H+nlh3GAQEUxajQyFD9CqJJL6V66tawEoBXZTWTLa2OH3daf7wvX9IionK2iK/k5Olh7PB5mZr2OdVlchkez9MUwC0/v6SmranIMmmKwdP61uUYgiganREjxwx6zWTimIbo9eAWkpJekXJo7UjK11YmWrw06Ics/yrBmVLcymiVfEA7I81ZbIy698pZaH8oajrhroyqOWCUyeOsWpbgo8s/YoQEjEFuuDFz0tLwuakMmhVoclYxDPbp8xBVCzL3iQqQ10ZAbiizDHCLtcDUNnf2ylnfIh0XsDlXGycNsPfrnnb95dLr/8lxAKqBfl9Ux6wmARPqJzDGotWHctVe4TQIZ7LCa2uDjyU9wghsLu7y2OPPsGdt90soHw5n8NetNxX5LUcFiCnSMpm7UP4NCPnTFcCTJ6BfzWMjwoIyznzTd/0Tfzcz/0cv/7rv86dd9555Od33nknN9xwA29/+9v5jM/4DAC6ruM3fuM3+P7v/34APuuzPgvnHG9/+9t585vfDMDZs2e59957+YEf+IGP5nDEeDYFlFlPWmLyCO0iYLUWSt/wYObhISXnohWG6CPL+arcYBrfBlKQjXKKibq2NE1VaJMlZYZIZTOuMswP24F1YYweHrXKCXrbjAx14wozKzCb1eyMnEgVlaZrJe1iNB4x22qwOrGcr1h2nqqyVJVjPK5wlSXFzOHBip3dFdZZVqtIu1oSu0AzaehaD6wppNqIntY5h7OelQ4YBaoUtyoji5lWRA2mLl4nuZdOPjXMmwo90hSz/03zQzkDAuwkn4g+DYlZSiuSkQuRjEIbx/XHt3n+jadwStP5SJeFStoDKP05jTHSlpTHWmVMgqw3AgrKxNpPthkKBV02Vqp0F7SxNOMtQrsQNo5ioGgfAdV6+g8iXXVOihVrjACv3uNjhJSx2pYUFIUrnYZePgh5iK8VVlahhlsnxomFyRRTYuW9ALBVBV1gvlwyXy7FuBIBhlPKOOukg2cdkkZUZrVy6CmJbDBmicL2XYv3HV2IhFRYfMifMpH6wv4ymBInvI4ozhsLmGjlTUnNrIylthXGuOG6ayP+blQC8qUYhkmpTxPqh1UWnz055kGK6pCOjdaGShsq5WQSLJOlNg5NGHTw/bFZawfvh4GplUo3zxS2phbza2fleJVS1K5GFQ8QlYWmHKMAm5WrqKsJ1tiSTCdedDknqqpma2uL0WSKrUeMRlO6tmW5XLAzn7NcLlitlrSrlYBXOUNORAVhL5QUPYsdz0Bpks+Mmhmj8ZimHolMUknhkUv6aSysPfGkyLQ+0Xq5fqtO4rEvX/G8+567+cP3vZpLl1/wjHPp1WNv//pnftGnzchonfhv/9R7qGzgJ/7N5wHwtW96N5/3OR/meXdcoDLroIPNzX7PLDxCsdZyv83nFe/4vRfwE//2NezuP5ndNRmvBsP7HgT7VB1V5Xn5Sx7jM171MLfecpmm8dSjxM7uhHvueT6XLk25eGnKpUsz9vbHUBo4XdLgAY6ypcbjltOn95lNl0ynK7ZmS5ROvPe9z6OqA1UVGI9WnD69z8WL2/igeeihGzfe4Y8b4KJIqeKZmpSPfOQ4//LfvorXfPajfNbLP4yzmdQVmXllsUr8j9b7vUwMgLKkoOmiApXxrRdWRpnv+iI3ZhiNOm6/9QluvvExXvD8Oft7+2zNtjh93SlpGJTk3l72rpXYICxXive9/wZ+/hdfxgc/fAPLpSQ///G7Vs+NT8a4/fZHUQpCTuzvPXM7fzKqiDGzWEWUdbi6EcAIikm5gFnGWDAMydjOClCwWMzpNryHnXP4hWc824YUSDEQQ2A6nUqzr4AdRsszFlMsS4ZGqYhQEBRVVUNZN2KIaBUwxY5CTPRLRVl+19iKvs6UPUzvgSp7l5x6kKr30ZEyz6ij6XBK9bWr1PbWWqoSstV2HpLUl72XUF/jxlQAhaHWA9lDrJuj1xprL580pGVTNsMpi6RMvogdGpJ9/Z1VEsn48G5FYqfW8sZNoE+V5qxVsgfqN816Y2+g1JrgQGHi9K9JiScBh9f6PiAsqeVixcFiJWFpbcdyJU3FgWhTpK8okavVlS32HZbaGSqj0NTs+Q5rDDEm9haerVGNswWG3DixOWV81zI/UNTNIfV4igQuwaRxKDWmvbzHgw88xsOPnuHyzj6dDzRNg9YWV485fvJ6jh/bgpxZ7R+QU8LZioQES8UYSqJnBC1ex/mI35PU5hlJjqyrihwlUb7fnygN1plCFxKm4JDI2m+0NxowpuwFU0qiKqGkivqAIQ4yRFVYfjlDDJ2w6LqOUMKiUJnKaLQWRlYbwNOnqkqDWHx/i+m8VlRaQmi6nPExyXOW5VxHFY8ALXJP9gEasQTcyV56XRf2lz6XhpRlMp1y8uRxqjQqG66OECLLdsnBfMH+4pA4g8PDjspAXRk6L0QVJScItMIBx2Ji0i0IKbC38Gg0Pq1hSlesYPr7pWcvxpgkHTNGjNKEPrUVLT7XzzB6kM05SaQX78WOYthWPlAerDUbVj4rZy0EjyMfc7SJuflfi/mCS1d2OTycU9c1p0+doF21HM4XhXTRX8945Pck5TSCseVsPP33EnA1sbHNfNrxUQFh3/iN38hP/dRP8fM///PMZrPB02t7e5vRaIRSim/+5m/me7/3e7nrrru46667+N7v/V7G4zFf93VfN7z267/+6/nWb/1WTp48yYkTJ/i2b/s2Xv7ylw8pks92xCgoZbuMpLJ4xCg3hEIRomiSnTYDOOO7SPJxoGAe7ncwMphsWRx2hJAKoGNQVlNVDmtN+VMQZe89dWNBJRaHK+YHS1LK1HVN1VTysCZPCArd2IH2qbWiqixN4xiPa5bzQM6aLkdylIQLkInGOkPXSTTuaORwTYUxhsuX91ktPSonvG/JSSSHsc4sD5cYZ3HOYC3UI4dzBqMsmCTyT9WndGh8m9jfWRJToq4rshYplc+RrCV7R4JZjuTfDEMm74ApyYmKRPbdukujtJiSFqZciiU1xogc1Trpcp3YHmO1LHCxgFqxGLenAogIOi839riuBGQrmm+QaN/e2HM4vpwh9oufLb4IIn8LqpNuYOlo5SyytL6zFQtbzPVR0T2wknNhY3W0nXgWWLOObu67BX3RJOh0idHRUiR4HzhcrgBo6nREzy6lmxYTxU6kmCgxYe/fJgQxRT82O87hfIWPvkhxhUE0xFXnzKJdslwuabuWEAMhhALgKSaTSbkeFpIklIo3mXTcXOUKI1GV1NM4+KoppaitwxnNyDXMmgkpJtrQirSxl2wWJhnGEbJ8gX6x6mf1ZbsU0Ll4slXGQDIi31XidXD1fReDR1u1AdT17CjRwPdpQ6CorKOqHD4GVm0n84NSgxeFy9LdNdoM3RSRpooJZ1VVJZmxJmcBuFMMTCZjZttbTGYz6mrEsvMsDg442N9jf3+Xw/nhcB8NBVjOBN8SvPgDTsYzYdNZh6sqxk3DbDxhPBqBFhPyvtj1MbPsFIt2nS4VOzHEb738ee+9hne9+7U89PDnEGMPznx6s2v+KOOWm67w37zpPXzhax6kqct9V4q+P/NV78VV4Qi9OpGLh8ua6q/RXN1Ri1Fxz/tu5e2/8ULe8XtPDzA+OfXxU21kbrnpCne94By33HiZSMdymXno4RnOJnb3jzOfj9marbjppZeZzPbQquNgf5tzF05w8fI2V67M2N8bsX84ousMIRhy1iwW9TNKm5RKfPBDwiifTBY8u/v0o72Xh53LVf99zSP6KN734zNyNvz+PXfx+/fcBbwByDjnuf22S7zipY/xWZ/xKLfcdEjl0rAeQWHx6r6wz8SBdSZ3c8yJZevZP5yzWK3IKbJcLIkhcHB4yPGTp0hZybxKixs5dJELGcAZqCaJL3j1E3z+q58gpcy8DRyuMnt7J9ndu5sPP7jNf37/lIcfOs7h3JaI+RK8Uo7l6J/PjefGetz9witMt45R0TE/7J72tZULVJXhxPEp21mJbYazxYYgFCOcBEcYCwpbVWydOEk9nrC/u8Pe7g6r5ZyUcrF/6NklMGoa6sodqSmhpL0lD6FD60zlKglaIoMBpRNGV8Oz2fm1OXnIUt+hNUo7kjZkW6HCEihJ9CpJna4YwBap6QozJa09lXLP5CqV4/ow1cDO6UsPbcRsuk9BV/RNSQFlmrqirtyQHp5LnXaU/7wGvnsp5dU2H/37rhNzA6vlHuPxGG0FPLc6Hdl89uBgKLVrjJG44fk8hBKxBsqkQcXQ8NwEuXJWtKuOYMVfqZ8Xrzk2wbcYOVi0XNydc/HyPjll9g6XrEradq8myOXzte7tVER9kVOkrh0xdtS1hewZj2usUcyONcwmN2CNI2U17DO1MVBSAr3vONzfkZ81Iyh717r3s1KaZSvSNGFcVWxvzaiqCluNCFlhk+wbgw8FuICEhFHlJA1pqy21k/3s0q/TBWOMVFYPaffNRJpe3bIlRVGA1FXNbDqlMVoAo5yGYKfSpS7XXZjI/XPQ28sAqByJ2aPLflt8L/vAoSxKpZyJOaAQllrP+NJaPIAzoqahACcxCTPKFQ8yPewLEm3oyCoxqhqUtmRSSXBe38uJhNUWlIVcvsNVraucc9GTln1qkbzWFQXAqalSpoqO8WzEybCNNQImey/7ubaL0sDuAm0XWHWR+aJluepQzpJ9h2n32Z8f4IN4IBprCV0ejsv7hLGyl/Y+klNmVFcYo0nB4L0ct2AWEkzXP5ehhCX0xI9UiDC1s4xGDfNFi9Va9uxlv5dSJoRYgu+K3DNCiSQT9uoAST+plTz813LZcrB3yM7OHrfeegPHjh/j3PlLa7KL0ihjSRuKF3oCSYxoHVD2mRUVxhqUfrpa7+j4qICwf/SP/hEAr3/964/8/Y/92I/xl//yXwbg27/921kul/y1v/bX2NnZ4TWveQ1ve9vbmM3WUfE/+IM/iLWWN7/5zSyXS97whjfw4z/+41ctOM88tFYiP3QCEiiidA1MMUmPibTKmEqTrQBnKSVyiJIyAzS1wRpN23qZaHxitfIoFWiaRFWPGY0alIrUjaaqNSE6louO5byjGVXMD5coBa4SrVbwkuSnSNSVRamKblWkg1YLo0MhaGrSnDxV4VcUtlEmJ1VM3SumWw3Hjo9JSrNaBU6cGLOa76O1YjqxjMcVoBhNRkLhLRv9mCLWQFUVEFApRqOaro0sFivOnbnEeFoxP+hAZ0aTSnTbCerGDea8tk9KqQzGHb0+SiuCT7RLTzOq0Bl0I3rrXo6aY17TNVMuYQ+ZmBS3nDhO9InlfuKWm7YhZVa+I6Q+/WPtE7C5jPUstd5ccXP0KL/3EhignmLjJMwnTQyy8G5NZ4zqET4sgVQ2FrpQWtXmB5BzpvWB1gsQlqKicgpb2aHroZ+m97/pa3D1yAV4DCEK9fupX0nrPV2QrkXlHE1VsWkY6oMfALBe82+NIyVFVYvcsWma4iVX0RT5cZ+g2cdyi3SvT+BZH1Moxp+NyRzMD4kx4IMAkq74kg3nu7AUY4pDYWOySBjHzViSTtswFJSVWzNMrkXvNYUFSkkR0RqqYgjaL5Z9QRdiJHeyyK+6gDWGrdmUuq6H7xRikBjjgjZaZakaAVzrumE8mdKMGirnGI/HOGuYzqa4yjGfH3Jl5zKLhTC/unYlHmAhDYuJGN+KhLhydWFbaKqqYTrb5tix42xtbVEXCQFKl+cgl8WzY75sWflIF+R7dG3Hwf6cCxd2+eW3vYmHH3n9U9wrf/w3nlonbr/1Mt/wF9/BK154Rv6yzCGbUsZsEtZeuyQWv7jNOWd93h569AS/+o67+aVfe8mnQarjsx2Kx8+c5PENY/hP5BAWq4z5/Nn6pT3TvZzQWrZVEvxw9es/nZ4F2XR6X/PAgzfzwIM387O/8LnlZ/Id63rFbbdc4GUveYIXv+gst96yy2gUj7Cac874kNk7WPHEuR0uXdklBM9yuSKnxLipuLwT0CZiUsuojowakW1rvTbX7Y8IZMMeIhidufHGOa981RN8yRefAwWjZiQNyvk+oVsRu5acRb59uIB3/v6NvON3ns97//Bmlqtm410/na7Nc+NjPU6cdpx99ENs3XaaF73g4ad97Q/9n7+FqzfuHSW+WRpdpHNxaJL2ZviApHmjcKMpx1yDdrUkNy/n+G5FNZ7SLueErqVdKMbjEVtbW/ThVCkrotJkrSU+MKxQKuGsk+TqGIixLXI5h9EV08mUg8PdobbYpODkFOm6do0ElY1lRJPaeTEtr9g0iR9k+htsh96uIa/fCBB/s74pKAz/DSbSBuNLbfx3/7axbxgWJlcsQMTaoLt8lJb9Fj1bTYmnLVn8TnummTYIG2k4us36UM5LisIE8d06pbCvafv6TMzr13NbLFYwWUW0thi9Nu+OAVQlByp1vBkaiwJm9cCb+NLGEJjPF1y8tM+5S7ss22sDsjlnoo+EIp1LUepWrTN6IezCtmsZ11Ya7QYWq47LB3tUxx2TekQfhmD0Rj2SE7Fd0K1qVPI045n4IFstsjRXleQ8BRm6kJgvl6A0o/E2xiRUt2Y5hhAkgMnAahEEQEqZXCxcRk6YSYsulCyz4pGtM1VVM53OsFpx+coVKqNZRVkMFD3OWhoxWny1jLVEEiGK4mo0qui62NuBPbktVa5fJGN1AcBSySFXiO90acb3T4CP0qyPWaG0BVeLZ3dMJFblnMoHRsRawIeAs5aseuufo/5vWkv41fqGlPrvSZbz/b4zQzMaMZ3N0Lai8y2VlW+mjaIy1aDgAfFGGzeVpNEnAe1yEUemrOlC5OBgyflLu5y9cJmcYX8xR6NJrSK1Ec8SFCzayKr11JVjazqmqRyjGpHq5kzSmXpiS2hFph41hJCK161m2bas2pbpZMRkPCKEwHyxovWSkumKj5/WGu9lHxh85HB/iatEjeU7IVT0llOZwubrAztUecKVgGUKO0Dojz12hgcefJTZbITRivF4zGrlh+dSaV0aEjLfrkHaTCDQmA1m3BHwO69rd7V5tz3z+Kilkc80lFJ813d9F9/1Xd/1lK9pmoYf/uEf5od/+Ic/mo+/xvtMCgoN9UiSIWLM655FzkSf2Ntd4Iylix3KJEFJMzincc6Q0JhKLqY2hlHOdF1HTJGUAiFBU1kEiExlwhQTzMWipRnVxUcsoYtvR8oyCS1X7XA5TDHzdM4ynTXsXwmMJxU5wWgkBtkWkV6ORg2zLSVpkrVhNHN0K8vZM3u0PmIqy2QiSXQohlhVbTTETibXmLh84YDOZ7aPj4hJvntVaQ67OXtXgiTdKUu3yiizBJUJ0RXmlNQS1hi2tyfC4BouNMLIKfesRtOtEtoYXG1QhZNodGY6tsyc0L8lDhdu3J4RYuTGU9ucPj4V76zeyyCt2UKbhpmquDqGFAgxiOQyRIxbM/6IT344QuiAhM2gK+kWNHVD27WgSkpMuY+cGxNjxJggHfZr3HcipRMatHyIhqzJMeNTkRcaNdCCy4v6/5eFnKMAzyZjyId1KocpwQO9xG/9emjbsPYGW9/0AHShY9WupKAonUOJTYaqarC2RhUD06oSE34fPN57AaNyxnee0EZiSNQIQ0wrNej9+7Fsl9L3z5uS1KNzRUa0531B44yTZyRlKrPxBXJ/Xp5+U9SD2iAecRiLUdIRCjERfIAsQNIqiseaVopRXTOqG0ZNg3WOXBI6YxIAe0hrUgLQOeeomxHjyYTxbMpsa4u6cugc6dqWi+fOcnhwQBdC+X7SufC+lX+6dRGujaaqJ0ymU0ZVxXjUMB6NGY8nTCezIxKE1ie6EIWmvOrYP5izd7Bgf75g/3DO7sEh+7uHPPoRePc9b+GPY3IjQFV1dN21gaeX3H2G17/2AV73OQ9x8sQSrUu3sdw7MUonLIOkBql8zdsql/8Rx4s4yHav7I74m9/zJ/nIEyc+9l/skzaEOfDaz3mA2cyzf9BIsZF7mY3Ce0PXWba3F2xvLdg/GLG7N2F3d0yMhu2tJVuzlul0RdN0jEae667bYzppsTbibMK6iNHCyIwR/tb3fjVPlS2klKSufmyAEE166h7EUw6lArPZktl0QVUF2tZx6dIxYjLEONjK8uRS/pM15Hy17ZgPP3gHH37wDn7urf3P1rvUpu64844LvP6L38WJE+e5fGWfM2cucXA4Rys4fUIaQEpZujYLMyF4RpOSLKbAGYXR6wSwhGLeRg7mB8SkSMBqucJaS90X/woMgZRalE7CxjGGyiW+6kvO8FVfcoaUEvuHC373Pffxe+/9EF/73/wIb3/7bbzznYZLlxwpXT2nfbLP+XPj4zcy100WXHf79SUlMfP61/4Bv/7OV13z1c9//kq4u1c3yQSJWTOZtCGFsi4fITZlnKs4cep6JtNtDg/26dolq/keB5fODC9LOaG0ZTKdYKyVlLViGxGzIZqxlC0pUxtDWlwS75uccFqeldl0xqH3GLVAJUm3H9LilCYWEGXjVCAyJKnt2s6DdihlsDqtm6xXbcfWkkoZISQOuzgAF6bUpf0v9yyplCXR8upTaYwRZkUBokzhTJtymrMxIt3OWQChwl7r3yf1wF+5LjH2ielILX+N4Ts/fK1NtpXYhhSGyub3zuVYEKbdcrmQYDRthwb6cumpa4d16/ulZ6BktCRxIymBKUaauub0yRkPP/H0CaailMligJ7Bh+KJpSTFEAydR1JEdfESThFdJHKmeFblnEoifQERVSZ2nZjDdysqPabLWlLckQQ9pTU5RoyGum4YjUZMpls0k5q9x3eHY0xR9qtGiQWKkCTWJ1ArJbYQ1hCVpPY5a1Fa0jKb8YhxU/a3Ia73SwoBP8voQT0BI0TeWI1GwiAbjfFownqTgjUiU+5vFmPEBzhHhYgexbTdaEvSBk3sn2hZc3JPZrCDZYnSjrqZldcVgBMIKdHUFTFF5stFkcmK77NCCALGmSP7xk1CwaY8tzdtTwWYTr4ltQtShjZC7UrQhvhFbLwfhanWP0HrkVKiMRmbLaulhZNb6BwhBQ4Wi+E1AF0nrKjKGEKI7O0dcCkEutARUyAnxWxUc+vpGYfLlqZyxG6B1ZpkKjoMIQTGo4abrj/FiePbHM4XnD13iS4IM9CaklKtI8Zo8SQvSqJ2dfR7Dd8PRUyKZRtw1tFUbphfQIghG7tdLly8zGNPnOPUqeOcOL6NXy3pfIf3RY6qewmknOdhV1lUSRKesT5/PWjfq6EE7Pw4AWGfaqMLAatEaig+SIlcgDBTvKgk9TCxXIn0IoVM18JoUgmDp2rACKsqA6Hr6NoVxgmzzGpNColgEhKDLOCUMGXg2PGpXPBc2CQpE4KSxRdZJFJOhJzZm69IlBtlbLjxtqnEvkZBvwUFEJPLpqmx1uBD5HCZ2TtsSTmwtd3QtoGuhaoW+l9G9PwiJ8w0owbnRB+dYmK58Oxd3ufwMNE0hq7NKCr5xj3+EgEt5UOMni6qkjonvzOd1WgtjKGY11ua6VbNaukxVh5SH0qyjZXzf2I64dZjx9A5c2p7RibTrTy3nzrO0rcsYyBp8XRIOQ3pNaAY0lLLTS3JGIVhUxbSnj4t2nb5P0mt7A05ZaEJ3g8dIGOsAENlcsl5Y7JDgD8wLNsVKXumoydvxIVyLFaCPghavd5/ZJyxJdI3l8VHwJkuCK0ZGIz5QdD8GDxdCLRdJCZZpPpuyLXQbWuPbhQ67wFh37VdK0BY8AMDq3IVo3pEVY1QfQIhsrClDWCpZ4iF0g0g5RIzLkVmhkGyGIcO4dNH6MoCb0p3UIDoNgQOF4HtiUx6rqqEAhxFPjp0cpXGCtGwYGVCB/aFqj0aVahMKSjlXIYQ11vWwoYb1zVb0wmjqhLadhCvhJQKsK01o3o07LdM5ZhuHWMymzGeTKibihg9+3uHtPM5frUi+IBvW1a+lRhuiXAVsDyuF1BjLU3TcGz7GKdOn2ZrNqN21cBe7Lx0HjPQdoHFqmW58qxWnsW8ZWf3gAuXr3Dpyi4Xruzx4COv4dyZP4/3d/DHa4OYuf76Hf7G//QfedVLL/A3v/ur+c8fuHn46V13nuMb/vvf5CV3XyxAtBmi2KWluVHMFDVJehpkJJffS1QSle7hf/6Or+XM+eMfl2/3yRuZ6XTJX/srv8HnfvZHyErkckfSha4qHFKfIksfWLL2lYGemZBRWqTs/Y+0UmvWQIYQFV/z1e+h7SxVFdmazdnemnPi+JznP+882pYNWVLsH9Q8/sQJdq7M+NADN7CzM2U26zh/fsb5C1Pm85rOGyaTjvn8Yyc9zdmyvz9jf3+KMYHRaEXnrwXAfjo8a2uG1apt+MAHb+MDH7wN+Nry9xlomUw/yAvv+iluvG6JUkoK4dBRNcL2NWV9ClmY3FHJRqQLmSuHLRcv7xGi4rbbZhwcBupaMZtOEMeBRLdayrqWjh5ZCRBDK03jDNOm4sL5J/gPb/1mTp06xdf92RNsbW+TU+Lc+XM8/thHiCFi9at5331/ijNnX05KUzZyr54bn3ZjzXCSEVF4okqkLEB0VYen+mW07pkHG++RpcloS6odgNKSJpfCpiV4T8DKpXFbM2GGdRWjyZYwX5ZzYfnkjE+wCoqtUYMhs1quaJcrvG9BJUmYVwpb19h6MnxGqS65dPkcvU+vACcB78PwqiOMoHJcKRxdswwBo/PwHVNOR9Y1YwyOo5KhTKmn5UxQ8qqwwt8QZLB4QmWljj5JirWnU0yDpA1KPVM2yxIuFvG+K99JgSqNcC1svJz7b7VeE2RpvurZ1ZqmqZ90LvpzZa0pjKFMkthL2S+pfKQGzUgoktW9tyol3TMPieM9w2/4TuW1XUx0PnHu4h7WmHWg1lVjQyFXPOMstrak5DHWQPFLJitS1HRLqGpNF4J4CtMzqtTAeuuBMK0Uq7ZFJzCmIlWZLiasNZw+tc2xY1vsLzra1QpnHdPJGG2sNPBypuvWYIUC/Gopc3eE47Mp0/GYvf3F4FO8+aU0mRA8MQRG4yk6B/7wD+7licfP0XYeXZILxfd4nbTZy0SttXSrJavsmU1npdluIJujN7lan39VTPNLhOfRW8I6orblJxGVgrCpcgFqN4zyY1EIJRSrqEhKgVak5EugTCo1i9yfPVMx5YQPHmvWcIhWerByWZ+ejFGWbDSrtmOsDbU1mMJyzAhbzWiNUWv/4ZC7a4RObJwKJXu5UWOYTSpy6JjefILrj424cjjncLHicLVivmg5s79DVTkm40aaUjEXlmYiRLFH6Xxg1yt0PaLTFT4prDK4rGhXB1ilCe2CRx7Z4ZFH5BiaeszxY9fhY2TcNDirmS87Oi9NieWqJYQ42AGt2VflWUhrosFRs/xr713Pn7/MZDLi5LEp152URsTq0pIQAvaZpI+ltowxsljMxcImK0IIjMaj4bmqJ88+lOrTGwhrw2CCqLWma+MakCIXzy0lhVkxfnUWrBMTfYlZRjyJKHK6kCTy1UoizHLZkUPG1YaUwDlF7G8AVJEPSvKbMZrQBVJMYnLtNPWooh7VGKvRMbJ7GJiOFVVtiAFCBGUVzdgSYkdKmcpljM2s2sDeXkfXRpzTjCaGZddx/Dox/VstGcwOc4ZKO7pWkiEzmdHIUtcOjEFbw2gUWS082WlyrAjFEyyFKAkR2oINUOJLrVHi8ZUUq6Vna+aFmpsyxoFB4yqHOlYPPltaaSpjODmesTUaYTCMbc11W9PiC6hQM82qXbLsWnw+Sj5NiDcTWWGMRVEKGRD5Wmn/aKVJFHNEpbDODgvK0YXFSfdCCZJvjBEQLCdWbVc6DHHQn29u9KpKOharYh44GtmyORRQR5YN8ewKG90vhXQ4EuJl5UMolPlYWHkVVfFqSNFDiqQgjKQUCnMNAUdNTvLvWuSJm6OuXAHiJAk05AR9xG8BB1QpFp1x1FVNVVelCFgnaqSUadsVXbeSxdA6nHOMRjIh9p0X55wYwBpF13qRB5TuiipgbL+YW22HyOw+nUhrLbHd5RoGL/LhWPwdtDJUtXhrBBcHzzKlpNjQfboJmhgzpjDmyJBSoG07MX7Viqap0KqY4xpD7RyVc4xqAZgXyxWrQr+31mKVoRo1jCdjxuMxVV0znkzEBN9VxBg4PDjAty3L5bwkxlrImYSi61ZMpsIyA1fSWYVSOZ0Ik2wymXDs2DHpWFpJhjpYzLHGEqKY3S+WLYvlioPFgit7B1y8tMfFCwdcunLAld19Hnz4f2R/7899bCbQT6Hxxa+7j6/+qvdx5+1XMAasyhgUf+XPv5PfvecOPvuVj/CiF5wtkhMDHPWf6lLEalBJWKgxF4NceMq9cs6SrxeS413vvoMf+L++7OP9NT8JI/ElX/gB/pdv/J2NvzOyQYkyRw3z79XFmip+aYVNafQ61h760xpKmpF0hHsQrOvEi0RpRW3gz7353UBJx01xPU8j60bIYEzm+PaKE8fOoLXmS17/AL0HYL9BAEi5GPqazHJpOXN2i4cePs7BfsOZc1s89PBJLl+eYGxkf78hhI+mzFHE6Dg8fOoiqq4XnDxxwIkTe9xw3cUC7IunT1VFtIksVzUHB2MOD0ccHE44OBhzcDD+KI7laqDgYzHUxp8j5oev4j3vfRXvee9mJzywvXXAXc8/x+s+736uu+6A604uqF0mJY2xiZWPUpwftFhX07YJV00I0UvqpDaoDDu7geC7cl+Iil0bYVBIpousNXffdTtf+yfewIVLOxzs7/PQh86x6jyTyYhR7XjR827kjltvYdzcxNe86df4g3v/IQ88co5XfeZn8bov/ErOn7+VX/u1LX7rtxrOntWFQfqckf+n5niq+9ryf/3fX8aL73qEF73gQ/zm77yat/2nzwbgebef56FHj4a3pOgJGZxxJQxC3rOfI8xmGI9xpT7NQ9MzpsRqOWdxsI/vWprxlMX8gBQjqh6z1YyomjGHezu0UbGMFpaR2chijGa5WnJweIBzmrpyVNYSzZNBE6XEe3ZzNjFamuypmNdnpYYQqX60y/YII6Vn0kspddQPq2evRB3Fij/39g7DK9avLSBYbzYSYyRkzTKJMbvVGafFE1BF8WztvWF7AOla1gF9WFbKGZWThHUVVlTK0khNpTYlZ7JWZCPMo/6uSEk8hq9uXFXWELwnBAEUjCtpgLGoK1KGlNBJwJXKNpA7ergTwHuR3Ynpcd+cdBhXDYba1lVMrOX48ZqDVeBgvmRnf/6ka0o54uL2IuBkTKAjlZPGkNIKrRyozKpN1FVpeqvMqlvRhXGR9q7Pn90wNrc5EKM04xugmsxYhYgP0IzGuHpMGxRuNBaFAon9/StM8piuNNq1Ell7H98WgihpTh3fZv9wwc7uYQlckrRBudfAGdnn7O3ucv78RbbGY1IKVFVVrmmp3XVGqQrbB4M5SW01OqIyOCuhZNpoTNbXtnrpa46hh7kGV7S1qF5TqSBnIzJUFUg5SHBMUXQMe8PNuUU5nHW0nSfnwLLrcMZSWXukqacLKNbvm1JKJJPE21mJlDRGwQW0XeMN41FNU1lhUZePjBhWfh0MVllDbWtIcDgPTMYWc5WBvULUbNZqtrZGdG3HctlS1xV2ucRZw7HZBN8GtFKcv3wwqGu0gnHtGI8cpIRC87IX30FIpuzxFM5Yovd0qw6jFW3bsuoySVUkDMu24/zunPN7j3P65BaJsHlwzKYTbr/1JO2q4/LeXCyBkJovIzJJ74Uxtlp1zJcr2qXsrY7Npjx5vlfMD5d0bcfu3iEZRd3UxBgIqxY9KiF/BTjv57sUI0pp2q4jp5bFYsHh4SGLxaKwxKx4OTsrwW1phFZP3UzZHJ/WQFhKmeWiGxhZOUtKS05RaLBk2Ywrg3YO6wyVM2hTpFUAKeD9Cq0NOcq2IMay8e5jSp3I8ZZLRdcxLErGWmLMWFsWAiMAm8i2QCtDbSum0wqtE6tVxBop/HMSsKTrcpHgZerKkbMAeCkIDXG1XLJaelzt0LZCW+i83FrOaVJpwkBFSmCsputiAdcV1mnqpkEdG7E87HBOs3N5yaULC7xPdJ0wevpNiU5i9m8rkY3aqrDOVMBY0DrSWEVVF+12LokdxeD++u0p46ri9HTG8fGYnICkCNGvzfKVou1WLLuOsLHA9jpta2yZ1DIpBnxUhQK9ZthsJtyoYjpp7JM95rTWQxoGCIrcrlYsu1aM031gMmkIRR63mWYoenlB6ye2QSGLy8p3QmlPZWOWIjGUuPpyfK3X+CjGrdF72QAC2hjpbPWdjBLh3dPtyVLAqGKwqFTpcpmrkuvK54AAYd6HcryFglrAQmvEPN84M7DmYuqvhR4KE9+1hHYFCiqt0bYaghZM6epY6zDW0nYL5m0gD+dbJMVrDzGF1hZrhG4cYyoLmej1Yx9DrRSTkS3U1lRSLCXRqLKWEAJdkHTGnhkIYu6vVUBlqJwd5JwxCTDmrMW6CldV1M4JsJ0Rj4kSptHLE9rOM7EV0+mY6XTKsePHmG3NMM6JLHG5pN3doVutWC1XElRAeV5UiWwuIKixriRnZraPn2L7hKJpxmxtbTMZTySNUxUdf6H6h5hEYhQT3kcWqxUxRVrfcbhY8dAjhvPnr/DQw29mZ/e/54+LBPKG63f57/707/O61z7AqClASoYULclnjI1onXnZ3ed56V3ny28dfTYpQQJaybzRlc6QdGj7LZciB8c9f3gb7/vAzewfNmxvLbjphn0ODsf8u198CfsH00/GKfg4DokC/0t/7p286SvuxVUWtdmly+tz0wNX1xqDtFtptDIY0z/npYgs85YwV6UZlMn4FOUzS1ErcoCSCpYpXhbQe91kMlZpUmjpP7JnMvSdfl1YCzIbSuMmJqgbz/PuuMLzb79SjhXe/d6b+Z6//UcBNZ8d+NS2Y86cHXPm7PXc+/67j/xs1Bxy5x1n+Kov/y2Obc9pmo6dvSkhGE6ePGC1atg/mLK/P2W+HDNfjFjMRxzOR+ztTnnizEl2d2fP6jg+dmP9WTk7dvdO8PvvOcHvv+clG6/pz03kutOXuO70OU6dfJC77rrI3S+aMho17O2uuLy7i3OVMAO6hFFKUqpLmHEM0EZh5/Rzel1PeOVLXyQSjOiLh0rEWMOqbbC24f/5d6/nl371JbzuNQ/x9X/+JyFn/uCed3Hvf34fs9kUYwwvedEud9xiuHjpf2W5mnLTTT/KV//pN7K393n8nf/zNrruo/OgfW58PIa66s/1ePd7X8y73/tijm2/lptuuDj8/Xf+r/+Sr//mbzny2pSKh2rOkrpc2Et9A5QNhpMpNdfmRje0HQeHK86du8jO3gHbx7eJIdJ1nso5JhWMugCqHpRMy05qBpMC1mrqyuJ9YBk6cp0GwGH4pkoNaYm6gF1aa/m7qhrUAlmpAWDoxwB+lb1GCmkAyq7lmSrnROqsoSpTcKyB1sfB0F5nRcpm4FJmxJ7i4GDJ5UtX2NqaoJVia1wzcsXwXmW6EBmPaqp+CT4CyG2AcsOVXRvcawoRIfek4w2ZVP9dsoBy11qLel8spZV4iCk1JIM7BAwzWos8ikSmxWrLph9Zzrkk6Knh1kspkLqE1gZtLJVzokxwFSe2pxzbnrLqPMvVtXzCNuZMBZTrF5Omsutr1Nt89Enpy67jYLXg+GTGZAMIkzRSPax/MWVCSuQkyaXM9xnVE44f2+LkYUDbmvliVWodxWq1Yn64Q86tKKWKt+Pm0cbg8Z14SPf+2slnQrsRKJESy5Unxcjp666nHk/Z2d3hwrkLzFct21tjVBbbFGVFdVQ5w3Q64rpTx7l44SKhADDGuvJZerCsSYU5vukPevVwzuBDHkDS4RvI8iM+gEoa4DnlgdF15OqURtuqXaHQWO2Y1HpIAM8FDF57Sqm1dQviGazKfRNjou0irnEoFCHEYjgv9UnwXpp7WmNcfeS7KZVFzYLc6vNFYFQ3WOtQyoOKw95bacVkXBNPTJmGMd2qYxk6zl/aZ3f/kJ39OfNVx8oHOh/KvseTg6exilPHpsyOn2A0npESTItv+GQ05uLFKxzsH9C2HYdzCU9DOzA1XUgsVx0hJppqxWwyYjVfMK5rQorsXbnEwf4usaiBjJF7dTqdiYInxMFHLKfMYtXRtUIA6dU5Em4gglUN2Jx44vFznDx1jOtvvBFlLBfOXxSvsrYrQW0FDAuRxarlcC5eeKvO430kxEDbedq2Y9V6QhAwbDquaZoRNkc5v89ifFoDYUYjiZE50TRFZpQi0XtSlBvLjmUj7Bq7lrNpJfGxKQpq3ps4KqHfYrRstFKmaiyJzKptSycBQDbQqe2IsUJRUVWOxomeOUXIyWCU6MCtEYlhSplR5WiXnsNFh2saSWuwllFjsaWF44shttKKqrbF1FYW1HYliYHWKUIHo1EjMrCUcEYxrhzbhRIoqYkC+mmtmUwr6UL5LIt4K5t6rbQEfZDFR0AbRo1Gu0znhSU0mVSQA5Wp2Z41uEYxqi1jW5OSIieojKXGMa1qGuckUSSlgcYs64Xc3HFjwYvxqijbMjH0I+d8TU+Bze5UvygfMQNlvRD17+O9Z7Fc4mOkKoVM6wO+8zS2IpfkLdUjHeR1cSXvMtxra+/To8WATPhpWORV2cD1ssAUJZ4XiuF8kHujf4ve620Af1TPbDl6TjofhAEZIzFnDAxJlVBMSq0aKOxKiddYLsCTrWpS7E0KC7suK3JKZaE4stzLcSc5Xu9DkW0yFHc9EKaLV0Wv3Y4pikcTIqtNuQcoDZUx8swWkDSVyVKVLy9dB91XUHI9ckSrjO8iWnXCyjRaOjZ9NLixQ4GstZjGtl3A5L7oUEwmY+o6cvzkSU6dOsVkOsE6R4yR/f19dnf3mB8c0rUdZJlknTVkleg6kUbUzZi6HnHy1PW4qqZbLTHW0YxmTGbb1MUUFTKRRPTCuPQ+sGxXzJcrViuZxH0I7Owecubckve9/w4++MBXcPHi5/DHhdlw2y2X+Y5veTt33LqH1XJTxyTgpymFjtjtqZJY1wPLcPQcZMT9QQ/PfmUrnKpFktVpfu89t/Lzv/Qy3nffTZ+Mr/pJGBlIfOWX3ctf+5/ejcqpFJIj2RQqNbwqpySNGJIwV4ukXut+nlNH3nWxqPjbf/eNnDi+5OTJJSeOrzh5csXJ7UNOnFhy+kTLD//jz+H+D59gZ6/h5PE5OSuuO33I9dcfcstNu9x00z6zrY7xuGMy7hg3XlKP0ITUd7D7+VKKpYQanvurTWt730OgrLNrN96taccXf+ED/Pbv3sH21oq9/Yaue/pSR+vE9lbHdNphbcIHxfzQsbvXPG3RfvVYrqbcd//d3Hf/3df4qRyvs4Fjx/a48YbLnDq1w8mTV3jxiy5y/fWXcVVksag5d+40h4djRrWnqgIpGXxwtO2Iw7kwzABGI49ShosXp3z4gdPs7EwIwfCxnzMGWIELF6/nwsXrgVfy6++Af/LPZf07dWLOG7/8CT7/tWe55ZYDjBFmji7Ttw/FI5TNZ1ve15oaN6rXUKRSeK/5/h/6Svb2x1x/3T4A7/i95zGbfS1/6it+jbuf9ziPn73AweGCrgu84oU3cfHil/Abv/1GAB5+9LX89iYR8rnxKT3uvOMyZ85usbu3zamTq+Hvp9NrPbtS58gmq7A6CssKkwcmPGyCEpSGgDTTjHP4pDhzaY9Hzu8U5iuMq4qRs1gjydqTybikxpdQLqWo6hqlxdMqRJFcdbGH+/tpKyMOekEajM7R1NWwwQPxDc5DtdWPXBq3WfYjQDBBisC8fv+c01Dryd/Jk7UJgGgFVityWjPiAIKyJGXpPaqM6sQnaNVxcLjkrjtvoN4ao5Si85F5F7D1FK0qtBHje6MFkCyHfKRRvYnVCWNNxG1SCkk9lMsX6evEq/2/nLNrWWRJfhS5KiSlhoZM573UeB3owr3LyqKoSDkKkNQrJK6qoXOSvZNWkjwKQAyMnGF7XHM4HtF2qXzPjXM9/Fcp0rOAe0KeyKVRJz83RmFdUTTQq05UsWZRVFZjtRqUK/0+JoSA8YqgrXi1EZlOR9x4/XFOHJuwXLbkDDddd4JRZfDLQw79gtwuh3tg8zpYo7j5hlNUlWU2G3Hu4g5nL14REGGQayqObY3wMXP27Fn+4H33cttNp5kvlnhlaEPCd16kxoWtZbRhPGrYnk2k6VHsfyrnmG5NyWhCaIlxLaHDatRmUzeLP3TOmcm4wkdoj3hzQr9s9ESIlBJd18k93Fs8DN97cx9YgsJyf78frSVSFunAYLGxMRTCbDPaYp0ul1saf3VTy34hZZH/Z3nee4aqAmKWJMzxaK1gCDmRY2GzlHOwWC3ZO9jlebfeyLHt6ZBIuXewpGku85EPXmJnb46PmZj18MyEEMW5T2sWXeC4sWwfP8bx48eEyKKNgFI+8pHHHmf/4IDOi/zQ1iMJHPCB6WTMqZPHmU3H3HrHLVw4e57nP/8OPvyB+3ns7DnqugatueHW21jODzAKnE40FnTtUNmSUixzZCS2HV0XsCnThUSKonaKWRqlseugEl++4D1VVTOZTOVe9C3CXLAC8rYtV3YPePSJSzRNzcHhilAwDRB8o/e1tlbgttYnHksddfXsaqBPayBMF5lG6BJeh8L8oehHZcOuFEeAgP53xFgyw2DQV3y6inF39J7/P3v/HW1Zdt/3gZ+dTrjhhcrVXdUZjW7kQBIgSIJJFElJNodakmhLtqy0Fj3jseQ1HsueNQ5rxvYk2VqWZhSopWBatmiJoihSTKDBLJAgMtBooAF0rq5c9fIN55wd5o/fPufeV92NQDaIbhIbq1DV791wwj47fH/fEDLFlBiJPnLQzbBKCfgUAr7tEyhkgimsxTjL2BisbQidx3s43JPPEW8vT7PoWC4DNZ6iKigKMcjPBCO6NtIs5b3aKMpKzOuDj5LMkeWYvlstAozTmbEk3k09Sy5mGjhJkP+2FVlKYbNGOrVYA20IgKLQBqcsVaFxdaJOUs2NSCcrRx5beEajku1JTVUIS0jNDLpTqCQZET5TJaO4GkoSRGKggXul8DmdcBj8UwaL8qZY5dcSId1Jq833dfAHyxPqF0seHSjXSbwhysIJpTO/t/fSAjlepSCpO6Kh1Yq6KwAqL8Oo6AdmhTIG5YXdRrzD4DVXSbq2N6LMwQBq9V1KyZLqzm/pDQxB6PbOSgxxiMIIFLlrDgLovy4K8yiGNFzj/ryMsaSsN+dF55SE3RYjbddl5mQUY8gYUT5IsIMz4h0WPF1YA8Ly//p4XIlMVoLqd0ucrXDO5M1wnthS7jtr9Fi5j2LiuLFRCVMtM91iyospbY+Bc/3l1tmXwBaOjXGNLStGo4pyNGUyndAsl+zcus3e3h67e7vM5nNSjBhtJMjCSoUnhCVNs0BrQz2asH3iLBsbW/n65gQaI04cIaVVkEDw+HZBiJH9w0Pa1mcATPG5L9zFz/z8N3D1xhmapibG3x/JhBvTBf/9f/0T3HvhQJJYkYViinJPdY91rB4XFNKfU9IriS8aY8QwuPNzZFUUITNIO1/yGx+8yE/+/MM89tnT/H4ADr+8Fvkj3/sYf/7f+yilTZiBOWoAnZOgVp45AMmIXCLGQAwRgnhvQD/m9qlUsjg/PJry6S8JKK7YVAcHUul+9vkvHjJgracqPZNJy2TcMJ60bEyXzGYFTWs5f+6A++7Z4cEHb3Lm1IzNzbnIWGRAHJpRx8f8h193i4cfusVf+T98QI4swcFhyXPPb/PcpRPc3hnx0z/76GDGbkwkBM3uXsXu3pfyHVttcL7ylgtd3nHz1ilu3jr1os+2tmM8njOdzLhw8QXe9KYnOHPuGs6tijwmS/y1kvHNujVGTH6+hBGg2T8o2N1z/NZvn+SjH3uYazfO8srLBuWzbu1M+Sc/9gj/5Mce4dgNIrK1Neeb3/EU3/Xez3L+3C7apKHHOCNzfi9nyxgCu7sTrt3Y5NbOhNliJS77ufe/kZ97/xsB+L/8lX/CN779KVKKbE5rDHP+4Y+9Qqf19fZ71KQn3Lg54e1vvcEHP3Q3h2spshub42Ov/s1f/lkWi8SyWchGShu8F7ZGiIl6NME5h15fMymISue9tPjezZqOw1kLaPFFCnnd0yWWWlgzu4cLqtIyHdVsnthiPJlgXIlTFluMqEaAkvleazNIv/uUxhCSrIVTIhpDZyxeqcGKI/pASg2G4xIeV4zEs1cJC0prjSmEPY8XJokUlvWxsR0SXTjOYDI6iRdqylLHBClEohYGWUiRtvNMN0Y8+exzWGN58L6zdEbhNHRLKV6WORVdrDLEtzUET0gKrxJJg+8ClZXCZA8Gplx8jOvpzSDG19l7dgDRtBaLA6UoC0uRw8wSst9LSQ+pfSGEVZEnyZyWkLWWLYpcjM3Ki+A5Piatrpcwo4e6NyklKmuEAecKisKz7HowTdalSgl45mOg8w1ouRdVZcXg3ye0SThrMTairfy3UhJk5ZPPChhZ66xbDuTuijOQvKeJC0kPtY5J6ajObhKDWKmAoaoKrAHfzmlmLSYEqurF81hZFJw9dYLNjQlbm1PGmUSxfzAjdIG6LDi1PaEuHaTEM08+yXLZcvvqDeaLBqNXjErZlMkFc86wtTFhbzrCGk1ZSBK9sxqDAFyiikmkkGgTFE4N6hsFxABdK0wrW2gSJntU9q+Qr1TIHnOd3XnH7QR6Fnp+W06IdMbhk39Jz9iXBMGGjxAgEy191TiN0o7CWVR+dsQ/WaMRuW/uSsQk7L6VJ6D0LyE6rI5RG8fW1kmRu5qCumiJQQA8kmb3YM6y9aDEEzeEQAiiMHNGvPhiFHLEzZu3OHfuDHVVYoxhNAKVBDO47757abuWra0TOFdS1WNihOs3b6GN4vSZkzzyyEM88vqHQSX2d3b5whNPMF/MmEyntIsjzp07w4kTW/iuZblY0LUtbdfijPjIjqclbmtE23bMjhbQBlIqMg9USB6juma6tcn58+cIIXJwsMtoMma+WDA7PCSFQDEa0WWgbNl2HM4W7B3OCT6hWI178sxH2Vdg5Hr7yM29Q5z+8tY4r20gzGi0EW+uHhBYqzXIfyuFsT1zqGeayAOVQsBHcnVDZ123pmtbQhvoWmHuVFVB6Up0aLPcK+YNdiT4RJM66srlzXqH1omyhGilqrOcC+Pj6LChaSNg0MrStZGyFpqhbz2+k0G29YngU5ZPGkaTCVoJkp4QgzxbGMYbNWVhccZQKInpVSllpD3RhUDTdTRtS+s9vvHs7R5R6Aqft0vjqgSlqJTFFYaysOhkmY4Nk21FSELD1FYxmRRAZNk0jMcyELjSMZ8FRq0hdH3Vp08LE+N2bQ06I/n4iLZaUPQQBm8tpRQYsDntxdgVgDOg/WtNoUALqKEzWtTf2xe9dr0yqISN1LQdKaPKLgOLPag40GeHQfhlJtD8XSFFlqGj1HZgNaS1Chn5E2QAFip//1OjIeRJWAA5sDYDYmpNToRIf+U85N0xMkj8rDHCWHKKtm3xcTXgr0tGtdYYk2QB2bbYnPJlXYExgur313J9akhJACjxspJ71lOs+38rKUygjBEg2YdhwE4kMCuZglb583LKZiLkcIbVBeuvntCgtZxrDJSlpSplstV50olR6NGd71B5g6ili6C0pnAFVWkY1SOmkzGT8Yiqrmi7jraL3L51k+Wi4dq1a3S+ZbGY03ad+HkUBUprSSptAiG0aF0wGo3Z2jpNWZSiX9cK5wpcUaJ0If2/bQdGWAwtXdvSNELzDSnwzLPn+Tt//08xmx1f7L+W24/9/X/E9uZaVTIlCLLYtEYNtPK+qTue2X6TL+/tGY4KlARdoCSR5snnTvFTv/Aov/DLD7Bsfn8Ah1+8yUUrXMMf/u6n+dZ3P8frH75BWR43jl5nwZKLCb00fGi6j5P32Xvh+E2QoU+Y0Se3G/7qf/Rr7OyOVn92Rtzerbi9M2K5dLzkwPslmveWI285ehnT+8c/c/4lf765seDcuQNOnZyxudlw6uSSUyfnnDwx4+TJOSe2FpRVtxpAUmJzs+Etb77GW998HRT8hT/7seHzQlDs7VfyZ6/m4KBksSw4OCy5eXPMsrHs7NY8++w2s/lXs58pvC/Y3y/Y39/ihct388EPvgtIaO05efIW4/GC/f1NtraOeP3DT/GmNz7FqVMHAtLnT7FGUzqbNyULTp3wvPdbn+Idb/t1lsuWvb1Drl+7xd7+SXYOvo9r17+RW7dOsVoOvhIA2fpnGPb2pvz8L7+Nn//lt7F2Y3C25a679vm+73qc1z90ixNbs8xyg83tA/4f//lP83/7a9/P5avbOOexJrJYru7B//Nv/Gl+9O/+QyaTQNdY/vaPfssrcOxfb7+3TfrKbFayvbUP3M3h4eoeP31pe/j3mTNHHB4eiPl16KSoSU5rTwp0IoYjmqhRSQ/MihgTphphy0pkdcYwGo3YPrFNRDFfLpjNZFNHEBm2JKIq6lFNOaoxzklCdVYi9FJIpQ3aOqwrh+JzDOIVrGPClZnFYnLBtgfcYiTRQbZz6Z+LlBLLxWx4TGKSMmgKUYqqSZGCMPsjDIB4n7DIHQxWlZL48yVNMvKhgZ5lK0XfelwymVYkleiC53C+YHpiglZQ1nl/YSLaCKjgg7zXqCz1NJYQFR6FT6IQ6aXxSjGsrxMJ71M2Nl8t8lZ+TX1Ilsq+lBm8TIqIAEdB5XT5HjFXkHQiqEQvhEopDKwtpQ069YWzfE179plikKwOLSUqZzi9OaZpAjHCztGCJieRi3dmxLnMilNBTPgtw7EL0adjVBW0qQUc/bTc+k7SI7XKPld5v5HVEn0f0FquY4wZaImJyllcWWUgrKPpAq33aG3o2pYUBCAN3JlNuAoJMEbuWYyR/aM5N3cOWMx3cxCcYXNScrhYMp/NsLZgZ1+KttopCufExiLfuJjEfujMqRMYBY+fnHL1eoMx0LRLPv/088Ls86La6m1WnFsV+43WWSa88mheth7QaKvzXkHUFKWr1vOQju31+5+gIOHzs+/xvhMDdnV8L3nc9D2zzF4CEAPpIyl/dhfaXBi3OTQgEyiUApUGD7H+XEKMQ0DacM2CHup5CQZiR+cTbdfgrYKgOLm1KWQTbehCS6HEGy2liHEGpbJSJ4lRf9O2LJcdXdcxHgmj0xnHeDLi/PmzeO85ffokFy7ey/ap09T1mL3dfVwpPshVXbC9vY1SihACm9vbOFdgnOXM+bNcvO8e7r5wN9tbG6R2ydHubVHBaAXJi/+xczm8IDKbVDRRo7XFK8tkOmVjusF0OqWua6qyIpFYLObs7e1xdHjE4f4+OsoeIQ1pmR7vA10nQXIKscARcJzh3qw9wvgQB7+8L9Ve00CY+EIFHHZIvRNpliz+jTX54c+DTEg0sROvHqNlE50EEFrJ0TTBB+bzBcEHCmewRlNUBVAIIKHiakJDwIv5vGFUO4paTCe9gjYkmqZjsejoukiIiqYTqrIthKLdY5rCnop4bQhAsgodxWup1BqjYjY+lM19WRQUZTH4KZXG4rTFJFkAhOyzEauID4Fl23I0a6BVhCBm780iMh0XA5OqGhkKpzHJUlSauoRoOolhLR1lpZjPPbNZx2QU8CGhuohtLTqaLHFJaxvbtAIde78DlSAwDD7rhqBRRQKBYyac2ZCPPGD2n2edxbpymMQGWjESF9xTJdf9xHqTdgCrFNZYXDYuF+CwwzorMb7DIuH4I6IBnSJtEIPAREIljTNlZuuZAfzxvh/Y+76ihkkkrAG3xmoKpQg+DgBBz17sJ8cQIj6/R2uh1Buj8UEYgCZPcNqozNYKq4VU9ujq44qNtTjlSGF9kEiDqTEISNV1YvLvbJa05gmp6STUQZS8K0mVytUyAFtWmCKzyHJYQCJPEKmfrLJvheorGmv3XSkGDT+rFLo+Mt1aN8gGAKwtJAxB20wkEyaZUoqqLCmKUkCw6ZS6Kkkk2rbh4GCfzkfms7mkoiyXEkOcQxh66V3IC2plDFaPGE0mTDc3qSdbObUoYpKlLGtJuklaJMudz893IIQG3y75ez/6Xn79A2/7omPba6n9ofd+nr/yw79BUfZmuAHdy3NBhgElY45adRFgNQ4M/406trC3KkeGK02Mlo996i7++c+9jt/80F10X5EJ+muxyYWqqiV/6d/7JN/73U9TFBIj3sPU/RjXBwPE1FessxzbaAluWfPbSCnRBj/I05WGFNXqxqRediiL5VG95Du+7ZmBSW3UStoDivnCcet2zbWbBbd3xuzsjLm1M2IxLziaW45mjsPDgtmsYD53LBs3gPq/k7Z/ULN/UPO5L/IarQNV6dncbLjn4h7TSct3fvtTPPLwTZw7vni2lgymLUnsvqjuIUzhRNtpPvKxu3nmmZNcvrrBzs6I/YOK/b2K2dx9RRLKr6wpYnTcvHmem9k6aXf3JM88cy+/8L7vyufbcerUbe695wUeuP8Sr3/oBidOzFAKZrM5e/szDg5nzOcNs9mCRdfhysu88+0/wwP3fpIiB6EUhaMot3nq6bN87gun+djH7+f6ja21c3slzlENf3e+4rnnK37kfzz7kq90dsHDr7uOsZHnL52ke4n09n/v3/8LPPL6qzzxuZcGTr/ytmI3fr39XrTV9X7f+0VSvFisgLD/5Z++efj3hbuEqd2PVX3xzShJBFQxEUIjv0tqtZmKCMAVkoRtJChLzYmTGzhnmM+XzCcN7bJlNlvQNC11XbJYNiirqcY1o9FIAoPUizfLfahH6tlFKFLyGaTToppQIndTWmOAGIIUixyo5OgHnhgC7eKIzjdy7EqhlSGkDpPXsSlkuVEMhC5kUoA+Zri/3oW10qQh/GSVz9fXT8qq4OTJTV7/8H3EGBlPR2JybhVFWWCsEUKBFuVGzAV7rWT/Q0IM0rWYi/vEsJbs2U5DnTqz2eS6rfYA0M9nveRJPlTr3mdQAXp1XmsKj5jSAEyKVC6gXEFsxXPwpZ5m+V7Z8wk1vb9scg83RyXu3Baj0nFjf8Zs0TJvxWKjaTt8FxHOE7mwtBobtQGbFM4JiIdKSKxSlunlZNOeiSaKBtaKwdnzOq32SbGXcFqLspZWCUimVcTqJOtqrcTEn9VIfee5a62pyoKt6YQTG1PGVYlS4KxhYypyud7Dd7mUNFBtBgIYXQaWoffPaqmqgtG44sSJTTY3KubzJbPFgr29A5y1xATLuaQ1GqvpfEdROFRipXIy8owczRU+e4qhFNZoQhRGnlI9hpyZfPo4s0r6W8r+phGlIzZ7mQ1hDWv3/849Yk+GgDWW2FBTFCbnslkyHo0pC1HhqH5uVL2H6Z39DPwaCy150Grlk5eApBIme92JL5nGJUXpHFvTMWdObGAVhFZkrD4FAbJTz4hKdD5wOJuzs7vP/v4Bk/GYqiyzDY3j9JlTPPvM85w5U3P6zBlOn78Lax0xwXhcs7e7g3MjIaPkffWZc2e568IFplsbnL9wN/fefx/T6ZRCJVTpqHQitAtKA4bsB6cU886TEBZpGxVROXAjNjY22NjYZHO6mcdSuQp1JRYyt2/d4pa6QeiTaNuGphEfMHrgMPb6opR7ee/3thpPYg6ZCy9Bonmp9preSWitcE6osjGoPHAqVGaJWZdZXtlYN/jAsvPUZYmppYoRU0Rbg3WCLvou4FtPt+wIMUhUrFWUlTCUEkIhUwpcYSBGvE9oLWaE7TJmwCDRdoH5IrBYyLCkjZEky0Rmj4gBcZKTkR1JHuitNThtKYzFZfqj/FE4Y3ISjqbzHmJf8REzzJQiRiucFaBMI+Z/i1HH6Y0N9g4WtF3AacPmVOix47pAW01V2ixnBG0jQVtUaQkpYJNFJyidom0S7SIwCiNMNHldIp1aQIuYqy1ZngPy0KZE0kkm1sz86JMfhw2woF2D5DTl+c+oFYVYW4NzwtSx1gzGzgkBoYwxAyOqZ3j136+VZjIeC33XuQyKSPJjyOwIY4zIOcmTVAZZY4yobADYn3PhCgqk34khvTAAY5ab9u83WhZ8IaZj0cV92qLu6eNDEmMPCAlQ6r3Uu4wxWZ5//CHvPTMkMCLl5FKzRjvvAUlhLkUtG9reJHL988R/opel5XWCEvK5D0L1d1aeA6OyJDdTY421aONkMRLEYNtEkz3GxPyeGOV5UscnpiEFVNuVnBlJo9OZFtxPODGm4RiNKymLgtLFoYpgnKUeC/g1GonPh9aKpm2Zz+fs7e2yv783GIBHLwmSyYfMNhMPI5RBaUdZ1FT1iNF4wmg0FkNGV2FVHIAzrSUsoxsMNWXAjsGzuxv5a3/zT3HphXO/g9Hu1dHuuXCDP/9nPsr25pI3ve56Zt1pkXUnldmLsmJSMWVpnsiw7R0Vt17m1TM1jemZfMLi1VrRecXf+dG38VM//xC7+xV/MDaokbNn5nzLuy/xw3/xYwKeK5XHG5n4e+lwglxEyeMu/Zpexk6VPQGTWtkj91LwwaswyUKir66mlKvlKUdlR0hGNiiKSNJxmMMUilGduOdCyz0XQelbMubnRWbb+bUqd8wLGZjNHddvjnns0+d54YUtdnZG7B1UHB2WzBcFTWPxXmdw/Cu/5zEa5gvDfFFy9doGAO//lYcQ4D4xqjtOnJhz5vQR584d8fDrbnP+7CGbmw0bkyWjkSfb9MjnpYS1kXd/0yXe/a5Lx46o31Du7Iy4em2Tp586weefPMUzz21x+crGIMH8arYYHTdunOPGjXN8+CPf8BKv6JhOLnPxnp9i+8Svk9ISa2Q8XSyXLJuGwon80LkjHnpwzsMPPcfmxpwf+2ff/qJPE2lQIMTej2z4zSt6Xp2vefyz933J171yIBj8wRhjXk1tdb1jlKLkOlD+8U9eGP49ne7TNI0YnGuxA/F+xf7p14xGy5pZKQElhB7TZlKQyYBEYmuzYlQZukbWwV3TsbN7wN7+jOm0Zu9AU1aO6XSDyXgiX+Ib6I3Yc3FA5fFVqVVxot+f90Xzfh2o1tZ7ylk0GqPLPI6kHCYSUZm1o7QeChnKKEhaXtP2fq9S9FadVMqjzgFUvfyq38izAp2OPbGZhTWdjqgqASD79ztnKZ3N6+H+hFbn5fOFT1Hme5PXAf0GHSWAlnb5WEI3qHfoz3cNnBAmyvEij45q8KMFWWumzASJOXE8hjDsOeR4AoQOpRIqrgKXBtY0amCP9fuulM+tX3c7a9icGKzVTEcF86Zjb7Zk/2jJwdGCw3mgbQOa7JESxPpBPj9RWosCRkWNtuCconSGqqwzCLACdYBB0tWfI/2MnJBishM/s5RS3ptIYd1q0DqvBfr5iuOssPX73V/XsiwonASTlTnc5mjecjRvCZ2nbTva1gv7EsTqrhI2oM9qH+8Di6bNa4/ImTMnWc4PsNkrzeRCts9SYFIiho52Pic0shc2Wud+La8z2lKOpkO/kFRqsX3ovM93j+wLnPcJAyAmRStnC3zw2Qopr5lSHPwq41DsO16MVciatL9GKRft+9armJRWOJP999Ia5KjzMRAHX2txoVl9SPAhd8MVFCbgeaJrZe/ZhE7kuDEyGhXcdWYTv5xzEHNio9FijTOAeDK2zGZzrl+/ydWr19na3KAuShnrnGN7a5OdjamwY63DuQJtLJPphM2tTQ72diV0wgfKskQrzYkTJzl/1924usIax8bGJmVZoLqGpBS2qDBEbFxSlcWghDIp96uqxEVYRIutKmGO5n2gwE9yDYwRtc5kMqGqR8xnMzrvBQRrA8umo3BWgFgiktJ9fN0xMPBCICWxCXpRVfNl2msaCGtbn9OqgmwGQhSDViODl2yshB2mk4BLXU5QiXFl3mizr5QCusYTu3VjxCQPnIWgQmbjKNTEMU4OnWTwSrksMl92iH+kykivgezVBFAWRozlnaUqk0wymfmQlKJKAr1rZahsQeWcAGBOYl+lOpL9tkJi3i3wMce1WpVNyVO+BoK0K6Cymqp0kBTjuqRtA9NRwbguCSEyHYlRrXMWHwKROHwWOrHoGmpXsFV6nNWkqBilmiqUdMHTep/NH1cLEgCls4kkGfDJndUaS1mUGf0OQ6WkT1fpx4hAIiopcQQvSVLKrA0rPdMsreitygrbK+RUM6PXQDEU1goTDOSh6XxHCGEwYNRK44wjkiTFKsUBJItBNpDOGqqMaLdezOpTEvZVT7+VQSEvgFKUETFqMcgPMVce8mKCYY7OgC5gNSbvX/t+3G8we2BMvM2k6U68C2KWfBZlgSucsAN9yO8Tk3FyAhwAUQxF0x3eYPJsyHPUe8713lsqpcxKM3lR17N4dAbBIr5rZYEyLHZWPm4hSwnJ7+1BsIE5OERQa6yW5EqSJBy1IdB1iZDnH2dlM+ZsKamcRmOsoShL6tGYsqrRRtF1DbPZIUeHhzRtw3I5Z7FYgJKKRIpyvlAMXhhKW4wtsK5mNN5gPJkyGk+wxuZFsMq+dIbOe9qmzSmeYaD/f/hjD/LrH3iExz977x0j2KufeVC4GX//b/4kZ8/Mh5+lXP01meufUv88ZoarEn8qMnO21/NrLeOGSlKxM1b85NACIrsMjn/qM9v8j//0UX77o+ezFO3VfY1+9y1x4e4DfuCPPM13feclTm4vZV2dKe8x9ZsjBmBVvPwyoJWyfHqobmbwHIZk0j6BaSim9142vn8+V2N233QKefMkpq/9/ewX6DpXZKUqqwf/LmFw5jFzkKBkQCsvAKsqcs+FJfdcvJ2PS+WxLA4Jb8JscxwcbHD1+gZXr065fmPM5z9/glu3R+zs1iyXlhC+kjRARYyKo1nJ0azk+TXZ1bFz14ET2wsuXtjnwQd2uPfeHc6dPeT8uUMmk/bY8qr/9/b2nBObc974+qvDBvQLT57myadP8uRTJ3jhyia3bo/Y3y+/pHn/K98ch0f38ZnP/BXgrww/tfaAU6duoIBzZ1/g4sUb3H3XLufP7VOWcO7s83z/9/0mt29vcPv2Jrd3Ntnfn5CSJnzVGHCvltaPz6/+cfr3Vzt+rRfLevj3zVsVs/k8z8/HN0MRwTSM1jhjiM7mvamsgWXeyax3JWwnay11ZUjBQeyIvmBzajmYjXDOsLlVYwvH1uYUawuCD8RO1nLCONc5mEcKOjdvVfz4T7yBJ76wTeESt3Ym/Bf/6c9w/uwRs1lL5yOuUDk5PIMFkNddMpJY53DVGG1lHaUy6NdXk1NKGFsSCk8KssaNMWaQJJLwKJWT0pWwdlJYgSqoFXt4XVqmlWZUSbFJggeiAA3GDWwZ+gILDGtCKd6uAK2+EEke8vvCeiKiomcIFOD4nNMXwX0Q2qdJMr9EJV6rZi0cawVepLVrl4Z1foqB1AaUKXIBp2eUZYQuFzmSEoJCL20bcMPV9o9RVVI4iw+RzXHFbKPhYD5i92DO/kyCOmIMdCFg8xraaiN2NlFRuxpXC/PYac3meJOqHGcALg5EgZBiBlXUMF/23k+db3GxEr+tnK7ZW6mklHAZ5OunWRKD65yF4Ts6LxKzECOLZYMxho2NMTt7B3gfuHJjj/myQ8dE27XCQEQ+YF2dIWCGyamNiZAiisTJk9s8f7iHMbA5HbG1MZJj6RNBozCX9Bo4lJKEp7WdJ3UdXnt0Kyb0svZJ2Y9Z7rHsQWQ/XzqbJXKy37VWkQJ03ohXct9PQUBRJUTC5Pv1hR58qWNaSRp7EGzYA+cWguxBq7IYcIOeCSh9qO+LcnYpZanwHWur9aYBpyGFiO8SCodvO44O99EKqlJz7uSYmzcsu7NI1FLkJ4j/dyT1WRB479nbO+DSpSucOX2S7Y0NnLFYrdnYmHLm9ClmsyWzuQBNlXXUoxGnTp/mYHePRdNweDijrmTMLcuK7ZMnubmzR1F4SFkObQ0hapKxBKUHYKsfJno40BiLMdB6gyLStg0xCIagjRbJah5XjDFMp5tsnzzN0WxJ5xF5eu4DpbPEkAhBdhp6bezvl5bDPjOAchr1ByE1MnZRWF95AOgBAFfYzCiQTTwpo8rKQF0Qg5jGGyPMouA9Xeux1tAs2kHGppSiKARU04AnkBBadVHIjbBKU8fEfN7hY0bqk0Y84sUfIOWboZPMQDabbzvnqQuHM2pIvCt0gdEWo4T1JQOqTExlUQ6T3rJZDsiqSj2SnaOah81JHmhIJDQ2szOmY02sAqPKUlgzvBeFRDmrYgBfbAYT9TD5yLPe00eb1ueo30DnVwNP79sVYoIkCLgzBqvUAICUZTmAIncmPioUUaI8+hkT74WttW7+DiIbFOkVw/ejxERZGQFTvJfkHqUVBiNpIykJqp6lg0VRyLUwwv4L3g8AWJ9qI8Cdpy57vbsAYb43/swBAb1Utx8VFCqnosShmqKdgF49cKbNyiuAHPSg0KA1xiic0vlzM/NrRbUQWa2XCWMYzHsQGE0gDOepjWJIHBqAtZgNRdeerxSzmfmqcmKNoS5LfNbBW2NWFHVWfcSHTmKFU1/dWwUj9JNMz77rHQe0MoMWX2ffCaNFh2+UyZNxJCiR//ZsoqqqMdpQVhVlVVGPagpXYqwmJkXbBpZNw2J+wNHhLsvlkrJ0lFVBipG2EzagwmJtQVlatBVzdltUWFfiipqyGolMYM3jTfqf9I/ZYknbChswAS9cPs1/89f+zBcZwV6dm6uqOuLv/fV/wZnTjWwsjHjZpbzw8l4m+CDkvKHCrdaebeiBmTQYejunMRFUKChysUKpRFSKS9em/N//u3fy0U+c5dV6XV7p9qY3XOeH/9yneMOjN3MlUZ4dAVFjZk+uQKp+4Rt7MCpJCmu/VQepa68LQZRK6JhYj5HOS2xIeSEV04tSGc2wGB/WKQOgHaPIroNC5PtKD+9OeaORVDYzXlsU5gGYNLDb5PXDPJXHsxgSKXlmswWjUc3mRmR7+4A3Pbqa02IMgwx0sTDcuDnl9s6Exx4/x/XrUxZLl6WYBQcHFUez4iWYWS8PcMRouHV7wq3bEz7+ybuP/c5az7mzB9x1/oiLF/a5cGGP++/d5eKFPYzqiyDy94MP3OB1D96E70mwNi/OFpYrVze4dXvErVtjrt+YcOmFLS5fnnJ4VNA0Gu97Ft9X73nwfoNrmTF39dpDfPyT/W8SRbHk3nue4667bvHgA0/xbe/Z4dzZfZqu4ckvzNnZq7j77jeysbFF00S0GjGbVRweOZ6/FHnh8gl2d6YczeqvEKz8aravBNRSd/z99fa1bkeHBbP5EmPMAMgMTNi8VjVZXdHbORgjigFrpfhclAllhY2gyM+lFbNWqzXj0ZSNrQkAp/ISVIpdilgYoneZ/aNRWvwD/6v/9r088+wWL/W8/if/1x/K/1oHVvsWOXlij3d/4xd425ue4e7zO5w5aymqMV1niBJTKTYuWTqWUoIira3fyEnAAe87KiVFxBSlkOtjJ3uX1aCb139+9RmsipmgKKx4BqkkYWIr9lTvjZbH6hx41TPdYorDuJxUoif2BR/l89T61enBp6y8SD3IktfJrNayKFHC9P/dF7/JKhGNQseEUt0a6JDnGW2FuT4ct8ylJiVUJhmIysKg8nq4P0iFWI+4rKwY1wUpTWhj5GjRsH80Z7Zo6bqOWdOKJ1UXcIUl+Ja6rhmNalwhQFhd1ZzaPsOoGqFii07tcE5t6DCmPN5/8vUMnR8Y3DHGIRBNKZ3TGHP9ESCHQoRcIFMaTJKi2OFszv7hjKP5gtl8yXzZMKkrUiKHW4nstiyrzHqy2X+sy6QBCXjw3tN2PXGgB7RgPBkznY4pC2HJ9evCvn/0RfwhOInefkSWG10ukLedp+nCUFRuWi8WP42nt4vRvaoq7/NLJ97ByihmusM6g7OS/hpjyn1PDU+oimr1uA7qxjvBlZU3WP/7whWM60oS5Nf2RusG/X2xUGxV9LCWeqmWSJgs94sKglGZ6dmRdKSuLKe2R5zYHnNt/4i29QiUIKqzvmkl6pymabl27RZXr97gwrmzlMaCNlSFZVSXtK1ndnTIcjEXVYu1TKdTNre32H/hefb29tne2pLnQhtOnz7D9dv7jCfTjF+I53LIe82mm5PalcyUJGtYVPb5ToqUAvP5AW0rCa9dO8NYw3i8MTxzCphON9jcOskLl6/TdhGUzQmREkAh+96A1f3aaK2tPzYgSp8vzyLstQ2E1aNCqKQp+27VTlBGJ15JSmcgJkcsh9jL2RJd6ylri0YxnzV0rRgeLhYNqZMHXRsoCoM2sFh4qg1JbYkxUVj57KAkUVLQ6x4hlslCGyBPSCSocsxgVQqds3RjNkdTLIpJTniQylXWyGewQLJBjIAyXtJCmqbBWbd6ULnjIV5r/cOvVWbiIBP7uMrHm1/hifgUMSRsrrbFBCkKM0vR6/UFXOy/rh/c+vhbrRQYk6sTavgOOZgV80e8nmyOXBX2wGqJkCtPiuyLkKtYcR21Xz9LWWTI7U3Dfe4fzJTScB9SSjTLRgaeTMOWhVUaqgikbObuPV02Junlcn16zLLrsEa8oHzrV98hF/0YICUVu74PpoGtGIJsGgegsYe2Vfb90dn7QKksT2TYHFsrk2B/0QQkVKg8QMcUxccsb6LJtODgA4mlgIPrlYrhukmLKZC0QufJTiSLmrosabqOEMV/zuQ+r1R/34SxIv/dV2OMaPX18dFKmCkZhOxvqFIURYm1Lpvhqyx/Fo+u2imscTjrhgVMXdfi/zWq82dpFssli8MjZvM5bdvQdUuaZk4MnqIYUZSWrumwUfwaYrTU4wn1eIwrSqwrMdahTf6TN/w9a00ukqcNHcvFkvmiIaXEb/zWW/lff+IPv+Sz+OpsifHoiL/9136Cc2e7VQVV5Y2ECiiyf13SsO7PoNWd09EAjkGWqFtHURgKBxFFEQyf+/w2P/2L9/CBD5/huUtT0iviPfTaaf/pf/RrfOe3PQVA0/SeLTn9tK/s9xX2lAgJQlyBUusLs/VqY+yr5LnpPN6t3yUBtLJMoR+3gb29mh//F99EHIymtVTk8h9ro/wxAWMiroiUhacqO4qyoyo7rOkkLcslNjdnbG8dsr01w9o8tueqdw+Y9QvkoeXDN0oxm80oCkfbNkD2/lRrPjj53JxtuXB+wYXzN3n/L9/Pb37w/hddb2s8040ldeWxNrK3X3M0K1/0ui+neW954fIJXrh8gg99ZP03iaps2d5esLnRMJ02bG4sue/eXS6cP+D8+QNOn55hdKQsAvffd5P771vdxz7xuGc2o6DtNM8+u8XlK1OeeXaLZ57Z5uatEbu7BQeHjhdbIr9STdG2NV948hG+8OTxc9S6Y2vzGqfPfIqzZyacPXXI2fNHjEcVW5vbLJdLnnruC3S+zYxsR7Os2N2dMptNmM1H3Lq1wZNPneP5Sydyyujv1fP/OwG1vhLw7Ovtq9mKYknXerwOawVBYZH2yamdlxCsfp2kjZGUcGcZjyumk5qicMPmy2gtRvgpiM+NUihVYJzB5fXYwF4BUUVGxS/9ygP85E8/zOe+8MXTcVftpYBVw+2dk/zs+07ys+97d/5ZxNrA2dMH3HfPTR564Bpvf8vznD3TrGw+dD//5g1hngN0uxS2dZZVeu8xztMVfiicphhJoSN0HR/++KPcd/FptjZur9LZVSJ6USykIIXf9VNQRq5Jn3wZ8mbcOotOmqhFldDF7tjco7SWwnlOgO/BC6s1PiQWbZsLsl32r03Dk2espbAus39y4UVp0b2q/E9tqLWhaVpZxys7oEPZzRkNWKXlGhk5JmvMYLwd8ka7B2joC315H6GQsbnQitGo4MTWmBBlXSNEgMRs0aI1dKEDLXYcBE9ROra3TlAUEqqA1qh0h1H/Ha0HjXolSvBe1tb5OiijUSGDiSlbUZhCrICSyCN1FOedtvPs7B/y7OXr3Li1y8HhjMPZgsPDBYtlJ/5kEcZVxaNveoSjoxnTyQRnHJeeu8Th0Sx7DyeCDzRNOwRn9fu50XhMXY8pnB0knyoJGaJn6w2J7kqvBbsYCmsIROlfJJpMMGiajvmio+08i6aj9YH5sqPtBJhruwAhsuw8s6Yd0uILFzE2SNplVtlYs4LCnDEYJd7Wg/RXrbzBen/g9cfVGkvTtRRGizIq7wW+2D38clpc31MgO9m6KkhZgj0ZV2xMRoNEOKU0BFX0SqxeGaBV4uBwztVrt9nbO2Bai3zRKEVdlQIyNkvm8xmTyRRjLVVVceLkCfb2d5nN5sxmM7a2NrHGcOr0aU7duM1sJoEiG5OSsizQlaN1juSXdH6BqLIkHODgcElVjyizx3YMLbOjfWazQ2IIdO2C8XSTshphc99VClzhKMuS0bjm4GAmntStjCNt19H53m4Gjs3LK2w+3w9RPN3p8f1y7TUNhKXEMEBY00f6CntGGUVQimXjCaGhazvapgMUNnf4k2mKDoZRURFsZNk2eO9Zzhu0gklZESMsFwEUFK3BFoqqdEQvIFUTZMOvnSK0uRKcHySdRMPtypJaO8amwBrLZFozKirG44pJNSL4jpAEAY4p4mMUud0aMBRCoA0tCoUrHEVV4BsvYEfshtf0TBtrZXDRSmESEAKh9zjOC+1KdqYDeBOifL9ZG/ihn45Wi4Ae6xYDwtVkpZUaHuiYkjDg1jZsPbuoaRt88MIIy5KdLscoxySUc53pXc5a6tLSNQGvxKjTGivSNBjAOdl3y3GFkFlXeaEjbLKO5XIpE2RiYCcBg1+ZPGwtbdsSU6RtW5ZLAYzELFS8pIy1ObVGEWKgy6yylSfZylusn1B7zwWh+fam9CIPUz14SA8iDLAhMUk1w8csv8y+WIlECvnyrgFIxjhQiq7r6BoPqRvuOYqBsZYStG0zsLrESF/nDXh/30XGFmMk0G+65eOsMfggg1TpDK5fmJEIvgXSsLGjv1MpETLtvZ84go+SPprN7lW+TkVRDsyr/pFKRu6ntVb07VozHo9xzjEejxmPx8LMOpoxn885mh2xXC5l0rAOawUgs8YKeJ3NY30IOFMw2dxkurXNaCLx60pbYtT4rF2NqTe9F0A9xijeDb7l5i3HBz74Vv7VL7z3i45Zr56W0Cz4H/7fP8GD9x7idALlMXqUwUqBx1NK+C5kKauhrkusiWKmyqpr9R5xMUas1UMqkLVGkoaM4YUrNT/1vgv8i5+7j0uXN76mZ/97045voLe35vzFP/sh3vstT2GN+GzIs50XjD0IzsprRsD5lBfbx0EtpdQKP0gJkmIIh1QyNuZX3rHIkhZTOjbHzBcFv/yrb3zFr0JZdrzx0ctcuHsnJ/4lfv1fv54YNUXRMZk0nDl9wKmTR0wmSy69sM3hYU1ZLtjabElYfCf+ZN5rrt/cxJjAdLrg9a+7zusevMaZ04ecOnXE0eFLg1s+WPYPLPsHr/jprTXFsim5eq3k6rWXe01ke3vB3ecPeOihWzz04G0efGCH8+eOmB05inIhmzqlh7TdixdnXLwI73m3zht+M8ybi4Xh0gsTbt6sufTClA9/5CxPP7fFbFYwyGxeURBHEWPBzu497Ozew+fWEgus7Xjzm/b4I993lWr8PHU153D/AI1luVzQtUsqq5mcLLlwzvGOtygiicl4wv6hoWnO8dylDZ5//hGefOoMu7tj/KsiEOPrINiroyX+/J99P/WolOJjt0q79Z2nazuaxjNfLAlJ4VPEWYePii4mxnXJdFzSNB2jyhG9l7WWElVBWVgKpxhNphSFHmRQ1q0iWRWyvvv//Z238ZP/6vVfpfMUNujlqye5fPUkH/jtR/jRHwOF5+zZA86d2efuu/Z421te4E1vuNG7Rub5WpLsVbZ2KKsKVyL2Lf1VjJHoO/6Xf/Yu3vfL7wTg4QeexQfNe9/9IU6f3OGus7fZmEQIXpQCa/OHj3ptLSnr3t6of7CwCJJSH2MSE3QUPnaktGIDkzRaCRghioUkRZJeUZEkCTylRF3VYlliCyCPjSquZJtI4U4lhWo7jHWgV6EsIrvXdDGgraZwdvDmVZldBGoofK8X6nXSx+ZcZTJLzBrGVZEZZTYz4cTw3ifkj/egNclHdFEOewPBMjUmiYQvxtjXgI61zgesNfgQcvBUC1HAWjGWWrHuetmiv0MN1iYpiKEUy6blxq1dnrl0jYPZAt9F2laIHCoJIPDAQ/fzR3/ge7l5fYd7771As2x4/y/8KteuXmdnZ5cQPDEFQhTPrhgjJkkhp3AVrqwy41KaJUHsJNUypUG5JCqehNGBwoAiYpXCWcvG9mQ17CYGEGzZeDofaLtA00WaxrNsPV0XWDQe30W6LuTzagmLyJUbe9SF7NmEoyHA+PnTW5zYmEhIVtsOz7uw1DXWyYbZZF9vyCCekj9Z/DiQLvq/jzf1lU0f/b0cmI/y33VdcWJrg7quWDSd4ABOPD6XbVx/PPFJoX1kvmi4vXPAxfNnht8VRcl8do35zm2cs1SFY7qxiVKa6caU6cYGzzz9DNtbm0ynEyHMjEdsbE555tnn2N3d5eRWRaoNKo+N062ThLomznbwbSPsPS+WHP1qLGWFg7MOr8TjsF0uCF2HLfpXyfO2ubXNZDpmd2+f+XwuLNMo91oCD/J1z52j/zsm0Km335FxQdsvL+X71bDK+B23ZtnQedks2MLgCumg2dKXrvU0bciUX0NZKnwbKApHdnkmhUA1HrNsW5zTWK1ytUAAtRASR7OOunboaCHCYuEIcQkgKCiZphtXdXdFwMRETcV4MqIwlo26ZlLWkvoB1JONrClX+C4n1dF3mhUjQJHZRUkGz6Is8uszwymK2Xvvv9TTnQsjFa0Yg5QEBrKSdLiylA7YNR3BBzRaAAfhJcg2qq+I9A90/pNSouv16jnZxuh12nKf3GAyuCPf7b2nbVsZNAvppEmpIUFivlzSeo9NhtJa8UkrHCp5CqNR6EG6GGNguEIpDpNeCFFMmmPIrAdP2zQDs0sphQ9+ANN6P7V+Um99S0hBwCTf0bYtNmRk28k96mLEGJsN0Veb1l4WOqRD9xrzPPGtF/C7rsOVEke87rGgMgjYyyCJDEBYb6K5aJuBfddL05wrCTl5sWnyhJ4n2J5ePkzwzpEytV9bh87hAr1RKUg4gc3zdg/+iCY9g4da07ae0tms95aBuQsNBrOqkijxvEtoofumPtI8UpUVVTXCZrBE2EOVSGZjyHR6eR61M3mydYwnE8aj8QC2xRi5fPkyR7Mj2lYA4/4ZMlaANmVE7hhji287iAlrCra3J9TjLUbTKfVY0pL6KOo0AHjSHxbLOU3T4qzjytUtPvaJN/CJTz3EC1dWk82ru3n+q7/6L3nH264LUGUUpRPDVYMDWhKOEB0xU+5DkMqi67XHaRhIRJpaOsrC5AJEBqdzkfrGrRHv+5V7+Jc/fx9PPPnlVs5fK+1OpkjC2bCWZqn4xnc8z1/6cx/kypUpb3rTZZwRT6/WZ1D72LszmKXSCmjNJsvrgEZajXo5pj6uIK+cUIUQQI+xZtf9vUAANmE4yu8n4wV/8o9/UJjQBowWz8Gfed+buXnrdw5cNo3jY5+4j4994r4X/a7rLLNZzfXrW7+jz378M/fc8ZN1f89XI4Ch2d0ds7s75tOfWRm8G9MRgsGYxPb2nHvv2ePR19/g/vt3uO+eHU6cWEpBp23wjfgG9RvAixcOueei4hveAT/4A+J5UxiZF27dWvBbH2r4rQ9f5Kmn38ju7jlCWPfde+WukfeOj3/iNB//xGngLfRlWsWMre3P8MD9v8SFC4ecPNGg1AExJolFD7JTW6TfJtmGt33DPXzTewybkwmfffyb+PGf+DdfsWP8enstN8WTT72T7/1Dj6F1R9dJEXK5bFg0DYtlg02GuIgcHB0RSRhXEZKjC5GycLIJ14qyKFBlRbNc8IUna2K8Rlnscs9d9/PBj7yR69dL/uj3f5QzZ0bYyg5rmUuXJlx6vuADH7z7SxzrK98SlmvXT3Dt+gk+8Rj87PvePvzm1Ml9vuu9n+E93/Q5tjcPaRpJztTGoK07zoxQCuMsy2Y0/OjzT98HwNPPrcbT7/zWT/Pn/sQvAo34SYZICl7WiGs7b/H+FJXFuiVLjOLnU5geqoNpXQ22KqvDUZTOUthxXmuJ0XnXdSIZ9C1lUTIajQZf4bZtab0kCa6zyVWWT1bViKj04KzSdV1WQkDUBmULrNaovMlum0hED8BOX4jqfDfsf3pmmPzeoZIAQZ33UkzWMvaKMgYKrSmLXMy1mga1Nt9LsRF6H0+RwDqniEksUHpgJca0UqKkiEpB/qAojMUWst/r94N3jukJ6KIUr+u6YmM6wRUF8WgphXZEekvXoZ3BuoKNjQ2+/Tu+DaUUzz39PE2zpFkusy2PPHuF68O2BDhyThQz64FIAEXhsMqyyKyekFngsnb3pNgQI4ONEWmEiiNcX0hXwoYfG8vmRjHs57Vx4hnctoSUWCwWLJYtTRdo247dgzmzRYczY6x1lEXBsulkr5ckIMBYi3Ga/cOGWdPAMtGFjhgSk3EFCTY3xoNseHNSk6qS86c3qUszECq0AmVSDitY3eWkViqlY30+P4d3tiEgzGp0p+mN+Ou64tSZLe65+xxH8wbvl1it0LrI++ZVnHLM+7RrN3a5cXOXxbJjMpZrWTjDqTPneeqpJ7l18wYnTp6iripsUTIeTzl37i72d/e5vbPD2XNnGWXF1smT21y/eVNC9xZzunGR1R7i0YYJ+FazCMJQa7sO41dMUul7I7zrWMznwkibHdEuFhTW0ldwtQLnHK6oWCwXzGZHLJcdnY80nc8MyawkSioXhzMLLAoO0/cPAR6+PKbeaxoIazvRNCstLK8qJ190XUNMiaoumUzroRPHFAX0CRHrxJi9W3T4zqO10D2VFnmZsStfm2pSUI2cyAO1lcFIu6zXTlRG0wZN4TSmQIz8lMg1y8IxrUdMi4oiL149mumoJCyP8FmO17OJpMnAa9SaCfla1QOyKXtGP7uuE2bRwORKkiAZIkknEYjHtYdOqZxSqXLipHQW6xOlEQNriR4NDB4ua+i8Tys6bAiBHo4StFy+32fABFZsKEUaUjd6MK3/nOEYTE4SUeIBlaKiWSS0driqoFf+xLBipYBIglSmCg8Fp6Qkirpt6HrEPw+uXdcNHlOSfuIHGeO69K1fADVtQ+c7yrKkLgXAC77rb1f2p8gPs9WYaIbUnv47Iqt7BtC24iHgrGPRLoZzGSScvcxSHMhF/msti6ZhtlwyKktCjDRdJ8AqKlNjxROtPyeTKfQrA2o1JGYCA4DaM9cGZlu/986sP5/TEENKuEwH7t9jjejJdU7z6Cnkq76ridGgtcV78UUY1ZK8WNWjQQYpUb+lXDPfZomlfH5RlNSjmsl0wmg8wlnHwd4B+3v7LJYL9vf3V2Bk/t6eJWm0RvucUmgkRKKeTCjrKaONDYp6i+BbvO/wy4U8gzkd1nvPfDGn6zquXN3mox9/HR//5Ou4cvXUy4xMr7aW+GPf+xH+4r/721ijMEbAfq0FCHNOCX4QIUVJjUFHCium98suQjI5dVPjSpn4rdWUlRgT+yQLQEXiyhXHL/7KXfz0++7j80+f4dUJSPxO2p3Al/zbWk8IsmjpvEXryLe/5yn+xA88xj337BBT5OzpPXrb1eG5fqlvSJIwHGMYKO/yTSkXeFSu/pMXxjmZVvVpa4mEyJXRSFrkIINc0crXY777SvR4vOQHf+Cj1Eb8c2ISecWFi7fpOs10ukArxbXrW3zmc2coXUdddyQUH//kvbStnHsCgjfMZiUHhzUx/l76Q32x77rz/r16Wgh9eAvcujXl1q0pH/3YxbVXJIwJbG4seejBG3zjO6/wyMM3iisAmwABAABJREFUufvuPYyWJCmlNCkFkRXVFQBFEbj7rmu86xs+zZve+FPZuxScM9RlTVW+hU9/5g185jPnuXLtNMtlD5K9EtdJPicxZXf3XXx091189GOr85FzWnLhwmO84ZH3s7H5HMnDpSt7uBQx+jZVcZUf+lO/xWJxln/1M/9HUlpfssr9HI0a5nPLV08m+vX2amn/6B+/i3/nh55EmxExifG29x4fIru7BxTO8cJV2bB5DLNFQ0iaz376u/j4h//UV/RdP/4v3pb/lQsPKlIUkaZxr+xJ/a6b4tbtLf7ZT76Hf/aT74FhPR44d+Y2b37Ts7zlTTc5e3rG6dMHyDI18hf/7K/wpkef57HH7+HXf+vRF33qr/zrN/Ebv/Uof/k/+ADveNvTKH+EX8yImfHfM2JiiPjgCZ1I2UhSOL11NGcyHhO98M9JLq8/sx2J6g3y81nktbLL64z1n5VFSVVVKGC+WEiRKCW6CCF6jOqtUxJFOcJlP7WoNco55kdzjDYUqqCqKinCi6QIOjn21nd0XpOSYlyIUqAPpOpDx0xeE0rEgfhFK5UBMcTiI8TEvPVs5DEYoMG+iDEUMqClVZ8KKqqmmLTsC0OiLgXsiTn9OURhkhcxoq1F2wxG5b2IVmt+bmvN57HSZJXQ4AenM/so9f7BUmjOt4iUEgf7B5w4dYJr16/LCiav82KU/UDqgS1rMebF84bPMlcU8tkvAQCttxSF0WUHuaGiru5k9ohfcVUW+KJg0TYU1rAxaglBZJQnNiuWXeC+C9to40QqHBWkvPdVK5/Au89tY63O3s8wHo+E8VeK+qTzgbIUOfWNm7s4o/HtfBViZAyl26D1cegTWUdC6kGZ/si1OvbfIP9pnKEe1wLAdh3aVKwrLjenisn4trDFfc9AU2hl0XqFIcgaT0DgG7d2uXFzh/FIim7TzW3aZJhubBJD4Gh/n63NLVwpZISt7W3OnjvL9atX2d3doa7kfZPxmBMntrh+4wZVodmYTijLMp8rRFPQFFNYNnSdp/MdRViReYw2A4FFK8VyuaRtliwXM2GtFmVmNiqKUnPq1Dbnz57m0nxBEzuUMlhjaKMHlQRzSGkgKvTSSqWgyH38iwUU3Nle00AYWU/sjBjk+57Noi3WaIqqpKprjNUDdVoBaPERQynMRikR8j7RNpG6KnGZBjOaOsZji3Pg25am8bSNIJHGyg2t6oLaOLbLPnnEZDq1QRvxRKpKx2hsuXFjn63xGKMSbcPKjwqODQ5WC5J2HFfPp2ZEL96DUzHGzHYRyZjo59XaYKcIhMwSyJ0jJ8x471dxv5kFF0OiNA6rNK1v8cEPwFBKCR/8ACb1ZvOpB4CUeEgJiLHy/NJGBmyfAcqe/dVXfFLedPVGmc5KQqbLNOveF8xk+nVKK28vOZCMEIcIxwyRX5oZ0IOFvYS0bdvsCaeZTCYDWCWMK0G9B9DPd6TCrX8YxgpNtk9mDJ3Qr/tCVc+O6z0behbdeDweJC6jckRKiUWzwHf+uA/O2qn25pSjssSZHnxYOycfCNkuu2fcDT5CeRMc80C7/plqjZUXQmZRpgjJi/FmiDkUIBsXJkkYVYqBTtz6dujTzvR+fdInxUetQStF4UqKQoztq6qmLGusLcTAdA30tdYNzMWN6QaT0YR6VNOGlqODQxaLBTs7uxwdHUJKjKqSrhPTelIGZo1BWVnUWGMYjadUdYV1htFEKkVR1cRc6UxJo3UlUuS2o+uWPPPshA9/9O18/JMPc+36yZd4Kl+97Uf+h/+Zu8/OMTqBclgL1qYBUE4xETykTq09LgIY2sIRQ0JFR2EN44nIlKvs/5Bi4ImnnufytR2M/UZ++8Ov5+d/6T6uXn+lZY+vFgDjOPur/1kv37LW80e+5/P84B/9NGdOH64xegW8emnq/PFPlDF2Jc043gQkWw0K8pk+Zb8TpYgpELslUSHzQkpDHVqvffsxc/z8NTKs92bBAroprXjrm2/mFwZi9Dxw/zX+1t/7TrzvgYeXY2AJeHPn/ZtMFmxszDhzeg9rFPWooe0szzx9hp3dCSkpQlhVzF+59mroQ7/TpgjBsrM74UMfmfChjzyQfy4by83NOd/wjud59zdd4pHXXaOq5HdHsyU+RFxhKbOnkg/CSqzHlrtPX+HiXVf4o9+rcc4xyoxYo8Uz5dq1in/4P72bT3/6Am3reOWYZCqf04jnnnsXzz33Lo4/Gy0nT36eB+7/OBfu/jjj+hP84T/8X/KLv/hfklK19hmR+fx35vX29fbaa0pF6spRVhXzxZKu84NP6NkzJ0lRGAWbmxOaLuA7GSP/yT/6ykCwO74VgJQMTfNaAFt7RpblyrWzXLl2lve9f/Vba+acPXPEo69/lm9651P8W3/iEn/8Bz7Mk0+f4tOfvcD1G1s88fkLpKTxwfDX/+Z7gffy5//d3+C7v+MJirWUzJREFdIXzRMQfUe7WHJqvJDCaew5zZbbhzt0rahpSmfZHFdDYXl15Mf3Q4PdSg576n00Dw6OuH5rn/3ZMr8HNiY11hg2JzVVWVCVBTpI6JNPcVAatG0LgPeBxbKhWTbD5xuj2Z9nQCGHPFWFoTBCpghRE6IwUHSmviulMa4QzzENG3a1RxhtbNEdHBGJx85TKzDaSmogTnA5dGZyCzPcJEPA03aBZbcgmRpXdlR1wpJWSaF9Afgl+0NvWp9whWVjY8KpE5vMly3hcI4pIHoIQVL+JpMJ97/uvmF/V1Ulk8mYU6dPcXgww8cW68BYsVdp2pbJRCw12q4jBn+s0OZ9ZrKhsoogH9X6EmTtfieEKSx7GCvXwZhVev3qCg6fk/oKjxKPLGfFw2tKKT5yAmMK+KUUKAdKQM2epGE1iFhMAtkShjY4FrMlb33L63jh0jX2dg8EH4hRfMXzeknA+D1MUUsS4lfUhJFn9fGx5U7/17Ko2NqYcvrENstFx7JpySeM0eYYmSaESNd2XLlxm2eev8LW5pSNzQnN/IiyrphubnD96hWuXbvKdGOb8cYWIBjCdGODq1cuczST4r9zjo3plHNnz7CYy89aH8i2a5l4ZUh2hNcObQ1l4YBI2yxpm05YgzpgrMIVFhUczXzB3t4erh4zrVZzuFOa7e0NLl68CwPcvL1PtT/HWMPN23uDvdGLliBKZLXTuqClo/OJyv4B8Ag7eXIsDwHC/NE6JxAinch7ofH1aYDaaGKQzqsyC0kB2eOerVMVvg34zhBDIAVol5HFrMM6TegiRakx2ua4eiiMpTBlZlkpXGEw2R9HK0VhJSlxMW+ZjCqRe8VASKsUF2fcAC71SVv9RvXOphBTSmuPV0aFySbsjKJc+fuEEF9UKO3N7bvOYzOtuf8urbTI/ZDOZrUVEKcHHXPcacpPgdKGLptpmh4Q01qM/jMQJoqcrHdOibquWS6XLJcygYUITeclQKBwYqJZFBR2Xf9/PJFuvck1gzZEQsdARxZvnZRDBWSw6s9fGE5+YA45t7oHTdtIqmTMJohKBgiFDLi+bYbvNq7AFg7SiqEWgtzfGCW2ugfA+u8fjUYURfEiijiAMY4uyAJfqzzSkPqCigBF1lJlkKtPCU0pYbXFh0TnBbw0xgwRv6SU+3SWyRqDWzOoN5kFsm7afGf/M7o3zk45qbO/LisKuVaa4g5ddsrfHWOH0uBsyXg8oSgriqKCGDncvUm9eYrNyZSuaUlE6rpma3OL0Ugo/G3bcu3aNQ4PDzk6OqJpGpbLJc4aTmxtUDjL0WyBUYr5fIlUFwqMLSiqEdPpRk6UNCglDL0QNT56QCTEMUQ677l0ecQHP/wgH/rIw1y9tgK/lOojrl+97d/4vo/TdQUf/Mj9aAoKtxyYYNaK/1TrJeSjB1NUTrtzGeQ1RktibmGYaoNPGk1kNlvym499jg986FN8+BMLbt3+AXb3/gM6f+EVPov1me5rBWC8HMBz/GfOeb7tmz/Pv/WDv8m990rkfdf1LAKZB1KuYL34UzLDK4/Dfi1pcRUwkj9IKUzK0ow+xSzG/Do9MDhNUQxg1sudVR5VxQJA6SHAxCjDfDnHuZGMa3q94maxGIKPGBPXgLCXuz8C3tzZjo5qjo5qrlw5la9RZGNjwb333OLb3/sEb3rDCxwcVXz60/cwm5V84amzHOzXtK2VBKbXNKD1SjdFSoa9vSnv/+U38v5f7j3eciXWeM6fu853f+dvce/9nyfGIxaLNo/fIgUKOTSlKAvxCLVmkGhMpzP+T3/5F1C5ijufzYk+kqLjn/zED/KhDz/MK8sg61vJ7dtv5vbtN/Phj/zZtZ+vlwcT/WbojW/8cV544RvZ37/vFTiO368tceHu57ly9S5ifLWxmr689obXXx9sCrquO7ZEkaKc4sTWJuPRaAAy1pPVvt7AhxGXr464fPUM7//Vb/qy3/dP//k7ec+7PkHhSqDDOVkzDut8JUFMfhEpjGY0rUUm5UNOmLZsTs4To8e3S0LI0sc7vqd2BaZcsanapmHnaEZKR4inq4xZrii4+9xJ7vKRRddxuGiYLzsUkZ39A8qyYFJXOGsJWZbnQxj6TFEW1FVN8J7d/UOsNcwXSwpnc/KoorCWM+fvYnl4ewCcQhCzdtooHtDWUpeF+HDBwLDuR7O9/f0XMbBX/zq+0QtBvIfJbLmY1/HoKAb4JFRO8FYJSmNoU3xJ0kTfjAKrE0bBdFJx9vRW9m4zPHf5Brv7R9kLTVYjh4eH3Lx+mxeuXOXimTN87vEnuHLlMjdu3uBwfsh4ajlaHOJjyebGZvbstThrIEVi549V733sCHFVeNdKMR2PqIqCGBIxBYzJe14l61RSIARoWwmsG9ROa20FqK1CzvpXxJRYtPKz6WS69t4I2oE+ziC2BsbV6jNDSBzMFhzMDvJ3KUmEDyLPc9ZSulJIATFmuafGlYIFrFvMfKmmdfaou2Nboa14y/WhA8Zo7jp7mtu399nZPcgm8gzqns6vyyMTTddwcADPXrrGuTOnqDemaGOxhWP7xEkWR3NCjBzNZzRNQ1FKguT2iZOcPnOWnZ3bnDxxgpMntgHY2tjkzOnT3N7Z4ebtI4ypqaoSZwVAVa4kVZtUdcOZk5Zl29J1S3wnzMo2LhmPSrHlCR3LZYO2B2xsn2DK5tp9VUwnE06fPsXs8IikDOVoRD2q8N6ze3CUU9bJwKrBGs3IZbCaVZL6SxAUX7K9poEwpQWIMUpS5mZHS5RSjKdjyroavLPaphWZlu3lazktBmEa+ahIBKpCUYwd3huWS6FbJyKu0DRLMeJrDjzjScV4WjOtKka6GIyiXWkGk/fSGurC4bJkUQa4MGyGevAGIKo4pAn2BrkykIogBhhSBo3RlGVvuphwpcspMF7igAHfiZmeyYkqAAkx9gZJVwFwVQ1e0mP6ppNQjZXWg3TQ5AHDKy/HFoUZFkLAx0gXBTyAnMCTB/CYUmZTRXzohnMe1Stgo5crllbRdq2kIGIHeVtPkU4xoWL2uEpquJ8kaLpmAKG0saL7D5HlciHpmkYxKh2uLITpoBTkibYfYG2CQgtwFGJAOz2wt/IFxCibwat1ZFGkZDEltBNAStssL1SQVIIIpSsZmZFsMLSwrhbzhcTX9j5XSQwFDZCiIpAjqPs+oyC20j8Meri3vdEnSMqkyymcGSVGISmLdVFmuaZGGTMYd4bgRToa1yK2Aa0iOlffUv4eYxTRS++MPn93TOgkfcY5Ye5JoqPOqXT95l5ASecsRVlS1xNUihwd7pFilHunNdsnt6mriqoSZtbu3i4HBwccHR2xf3BAyD4OfTpIWThCjMzmy2HhUJQFShnGkwmbJ04w3tikqEZoY2lDIHkJzoghEaJ83jPPTvnwx+7ho594gOdfODtcB2sDd991m2vXtmnaV+MGIvKWN15ic6PlU4/fzb/6hbcPv/nQR+/n4Qc+JezRkFgukrBDgcIUOZJcNhCKhHVqAF7EtLvfeiquXt/jp37uMf7VL5xk/+CvcXj0YjnFK9dezC566Z+/Eu34Z9d1I6BLyL4KRcfFu/cAuHFryoP330SryNPPnuKP/8Cn+I5vfYzCLLGFo+kk8bDzXhiyxopPC2B6FleURFaRAiu8T9hSIszLMtJ2TZYaQ8pMUomJt0Ngg7WyarPWsljMsdqhjMV7kSpqbXLClIwBAv6noRhBFC1sjCr7R0rASIdiuVTMF0tcrdEuJxPHhE6JQsuY+Y//7o+y7Cz7RzU7t8fcuD3i5s0R129O2N2dsLc3ZndvzNFRTe/d+LJXP2n298d86rExn3rsXn78J+SeKJUoC8+ZM3t8yzc/z6OPXuau8/vMFo6nnjzHU0+fZTYvmc9Luk7TdZbF0jGblS8JwP3BanLNQ3C8cPkCP/o//8n88+NgrNYt589d521vfpx3f9PnKaoWfCSq1ULeaGG5xxhxzlHUBdZa/rP/+Le4eN8LHOweMBmLVCKEwAd/+xJ/7x98C5/89ENfhfNa3y30/Srx+ON/8qVe/PV2rCleuHzv1/ogflftrW9+geWyZdkGbt1WXHphyj0XD6lHPqsgDEmL8qMPBXr++dNf68Pmi7FmXyvA/nxR8l/9t3+au87tsbl5yOZ0zgP3Xee++66gTIsnUeHEHiU3oxX14JM1whqT2fc1wXc0zQLfZShMKcaTjVwAX41TRVmRULKez3uGPghLaU0gMGs6fEwYawiqRKvAotMo7SljGpI0h2K9MRRliTKGxfKI3b3D7FlbDBYQIQZG003O3fsg6EfY3d2jbRom0yndbIfZznVhu/mA0YHefdOaldwTV0Hbftl3eP11SoNG0/go6ouYckE/rPmYybouBElOvbNZlXA6DgBPVRacPb3NqCoZ1eWgADk8WuJjpKpLrLVcvXqNt77lUT7z+Oe4dPkKKUYefPDeDFB59vcO6Ubis3zr1i3m8xmjcc2oriD5Y/YPBrG8OXZPnaYqxGO5FXu0oawh1h1emHJWo3UGydB3gGE+/8xjaOk91BIBkyKlkj2Y8nPI+0khcTRovWTQHSaIHezNVrVKHyLzpecLV2acOzVmf3+ftlkcS74sigKX58V+jZb6PXNfqERC+15UAj1Oh3vRENAHNWAEK4hBzHoLZ9majpmOaw6O5nSdHI+1lnE9wuXi1mLZ0C08sUsij9zZ5Vx7N9vTjWwhZKimY3Zv73L1yhXG0wn1aIQxjrIsmG5Mef7SJV64fIXpZEJROKqyZDwec+X6Da7fvM1kMsEVJQQtCajaYOsxam/lp+ecoaoct28esZg1ea8qp++DZ7mQZ/rO5pyjqitcUeCXOwKcVhVKa+7Oyr75fInPHtJk7zBjGEIRYjbo/3Laa3q1WI4KDI6ma+kaiF6hEBAgLubZGmUtOl6oYhRWZxmeDCxaJboQaKMwoKrSUFcG7yWBIoSEN5q6dmzZmrI0VIWjdiUWi1UKa4Vm6dDCArP6mHl87Kmba49E/wClKBTYOxFvrcX3SlhL/U9lI9Qnh4TsowQreqnOiRZ9qljeAsnGaKAoOpQWPX7MAytJPqN0JUb1iYiSJKmNHkzcQ8gpckoe8n5QGDzLvFAh9Zqhb0qJ6D3ExOHR4XD+PZspZrlm8B2+cyxoaNsuT15CfTfWrDZ1KbFcLlksFnS+y8woC0o8IwrnKJ0ldFIhkgdSgJUuRFpSlmc2maYsAFd/P4bBLd+uHhRUPe1iaGqYAId7oBgALyFzpeG9wz1WYArR94cYJC00ePGpSxIK0F+3oeXPWr/Xx/+tsEamh54x2Kec2Gxmb4zOJYjMmsumpD73jfUW+4kl/7iPI7fGSNBAZgyWRZ/WajBGEnTEl0yAUYvJ7xHWXVmU4lGVwbHtU2dIMTKajtmYTijKguWy4fDwiNlsxv7+HoeHh1JByHLf9WviQ2Q2X+C9pJJMppucOFVSjcYSz5sp6z73WzkXWSh3bcczz23yN/7O93Hz1qoqoXXkjY8+z4W7bvOBDz7Cc8+/2szwE5sbB9x78ZDPPXmWTz2+2uCMRw3f/s3P8oe+7Wne8ZarJC+Tg9HgjCYkiax21lIXRhLIjVSeYgIfIOBIQaNU4miu+dn3neGf/8u38szzf4lXxotH7v3b3vICh4djnnrm5SSn/UbhldwsJM6d28XoxOUrJ1/02YuF0LTvv+8W3/eHPsN7v+Up6rrL75Q4+cVCU9cFVufx247RWkIoCJGyVAKCQx5HUgax4kr+GDqR27SeGHez0aoeGAypl5ykvBhKCYX0Y2Nl3lHWSIJRTn+N5EVJv7YaKLnS1sehwYelvyopoYj4xZHIBkqHUg6lLM5I4SgbvmCsZmwVo7rlzOmOh+MOPoenpBSlyISnaRWXr23y/AuneOHyST73+Qs8f+n0ADK+fFOkpFg2Bc9fOsPzl87w/l95y9rvI1oHxuMlF+7a55GHb/KGRy/z9rddwZhI02huXK+5dmOTvb0Nbt/e5ObOJvt7Iw4OK46OSuZzS9PaF93/39/t+LnGWHL5yj1cvnIPP/u+72d9fVKWSx55+Dm+9Zs/w6OPvoCxHnJSsgqKza1NuqYbmGT7B/sEHxjXN/hP/qOfpa7HaGtRWhhmt28X/PwvPsgv/+r93Lq99aJjeaXO6evt92/7Y9/7GNZVLJaJf/vP/ek7frsCRld/v1rY2y/Pml21SFk0oBRt61ilvr5amuHK1ZNcuXrnXB2ZjOfcdW6X++69zoXzu5w6sUeKHV94+iKnTu5y5tQ+Fy/sUBZzIMla0BboDIIZY6nqMWU5RqtEWmMQoaEsRb2gUDRtk+WYieWyYf9gzq2DOVoJaARzQkxsjCp2Dls264JRaUXSphRVVWXLHMNi2TJfLFlmsoSqNGVZYY3haHbEaDLl3gcf4rOf+iQH+3toEgfLfVK7gCQJ8IUzAwOoD67SRuMx6PDyG/GEMHcgywZR9BY2qzW99OW6HqGto6oFbFpPZBeBx1o/l2oXRiWKtWlWPlKseoyeoJWiaztmswVddxvvEyFptLKc3NziN3/9Q4wnNdZoTp3a4mh/l65d0rQNWmIoMVrWkkojVhppQeEsTSP3z1rNqHAUVouPW967ubz/1GisMhgl9iw2h1lYFbE2YW22AeLFFgtDr9SRqkj4VvZREtIWKW3ffWJW0/TkEk9K/hi5OEZF8pIqf3A0o3CifLrvTIUrYO/mNUI7wynx8ioKscQRME3lzwWiRxmL1lLUjwr0Hcd85z5LKyGgxAht6yWkiCifocRfO/hAjDCpHBfuPsWNW3scHi7YO5yLEY5WGCs+aDGlwU8r+MDewRHPX73JhXv3mGxsUBQFRVUwnkyZzxtSlL102y2ojYBJJ06eZDqZcunSJe4+f45Tp06ilOLkiRMs5gtu3d7l2vWbGGPY3tpa3QtjKaqa5bJXTYnnelU7uijAq8/eYSoXdZvlksViTp0JMj1mYq3l9OnTPPXEU0zHNUZpTp7coGk7dIKTJyb4LpNVotz3IcxCZ7uetuPLaa9pIEy0WZGJK3CppHM1R/MlIXY5ajYNQJgrS1zpcM7RzudATx+USlKI0PpA03omI8fGRsF47AjBkoDpVIAsqy2lqWSzr3LamlIDTdY6dUzLvG68DkIfJicE9h5ZQFaGM4B2+d29Iia/WUziGz9Ha9G334GTZCAmJwMaCxo6OokV1ooURFfetUu8Hwl44QzKSwcySovRJCsPMzEYz6BaTEPCYVIS14sSaSr06ZYag1RnXK5SaCVMoaR7Q2eRKvZG7TFvogC6piW2QVB8YyjLinpUrDzVMiC0bvDeSxhDDCSfKAqHs1YicKNcUa0UpnCktgMf6HxDk1H+QhmwQZgYxmTPNDNsZo9Tc+8YjNMK4Bw8u7TOCY93vDT158/gV9Bfz55FRpZBxhTp0osn0pddUimNNhaXDe9V7k86/ytGYVmIrl083F4OBIM8ad1h7G2tpXQFzlqcdRTOYq1GGzFr7qWm1mqczaaFQNfJ5FPXNUVRE5OiqAqquqauKgpX0HWBZbNk/2CfxXwhKTCLBV3XDdemTyLtr2UbAhFJVZlsjJiMJ9STDYqiFm86LXBbTy9OKdLlVEkfBOg9eXKHvb0xhfO8+Y3P8fDrLvHU0+f46Cce4rHH73uZq/21aAnwPHDfLs9fOsn+wSafelzAu9MnZ3zru5/nvd/8HG999DqFDfn5yOBupr2bTGOvCjck/PgYSb7vv7KOaoPmwx87y0/97L382m/e9WUAF1/e8dfVkj/zb3+a/YMR//o37+ETn7oz9a8/z5d51n4X333x4g3++B/7TX77o4/woY+8nhhfvElyzvOt3/wU3/89n+F1D93MsfAapaTSrZWm8x2jWouMPI+ZXScMzOVcPP6apsmJUpJ403Ue3wnLuOtaQp7AvZd4evE8jGhtMNYNKa2+ayWxK1e5bA6SQCm6kMdPpbBapM7GOsrRiNI52VBkAC31gDw5VCSPmSb78KEMEHGkQdZg8Tjlwchi1SoDKbNetSaRBqltSBVdWPkNqthB9IyqwMZkyUP3X6b1L+DDJ+hC5LnnT/Cpx+7jU5+6j/39MYuFw39FLC5NjJrDQ8dnPzfls5+7wM//4ttZ3wRrHRmPGu6/9zrf/O4n+cH/3Yepa5GhLucVWivq2jObFezv1xwe1hwc1tzeGXPl6gbXrk+4fGXKzm5F2/Y+I6+mjelXo63Or2lqPvnYI3zysUc4ziRLjOolb3zjAX/s+57j27/9JovFIV0rfiIqy4o636GSmB5HFNubDf/OD32Cf+dPfUIW/0bWVl0Ll6+O+e//5rfx9LOvtoLD79eW+C/+sx/nvntm/Oj/8m5+/QNfTXbvK9e2thLLpuPf+BP/Jl8aXHqtPauapq2/1gfxO2iao9mEzz814fNPHQ/4uPMeWNvxl/7Mj/GGh1+grqUQKwCQwboSY+xxEAxZexvnZAPvCo5mM+aLBct2yf6s5YWbB1zfO8BqzbLt8CFSOsNtrYkabhWGSVUwrizjuuJUUaK0rId9CCilqcuS0ahiNKrF9L/tBKQpRxwcHFKNN7AHczSKxdGcbrEUsEIpyiggjw6BLu9RytGIwqZjyp87m0j6xKJDqRVxAlK23um1QRLMpbUS65u8/tY6W/1k64LVRjEXrFQiJiuJhncUzp0zTMYVp7an3H16i9lsybKJtN7z5DPP8Y9+9J9xsL+PNZrl7BDvW0zq6NqW5bzBGYezpZBJlKRluswaapxhvmjEB3k0ZjIqKK2w3/uCnh08nw0qWaxOAuhl1pYaTufF+5I7W8+eSjFByEoxo4a39mCStTbLSu/clwuBpiwKUtIsmiV1ZTk1cmgjrznauymexZXDWCO+0Nn0PpHwckPRaUV6QAmd4VjhPqZVUF1+RlRKA7vPdx6MSDXXbYG0FiLDpAKrN7j37tPc3tlnvuxY5MKp0qIgM9Yc84Cez+bcuH6bvf0DLuT1WVWWFKdPobXi+rXrXL92lY2NCdVd5+R5qErOnDnDM09+gf39fbZPnMAaLXtqa2nbhsNDmM832ZhuyPESqAqL3drmYHd36ONKKayTfTVr190asbKaz45YLhYURXkM4K3rEUU5o21bFsu5rG+dZuRKbEiYGKEsiCRCCtnjGaxzsk42hqOj2ZfsP/AaB8K6zpOCbP6V6ugC1GVJMJq5X6zkctqQkiJGaJqOpgmDMTCqTxuJdHkX6Fox2awLR1laElrABK1FR50ErnJaiS7cy6Nk8sOtdR+zuzKZjxmlV/m7QECFHgTqH9reVF1eozBG5Ah9nK7WBmX0ENHbN90r5dIKtPF5o4SRz1Va0UeK9GmKytjMKBCQjygbJK0Utk9oUhBVGjTyK+P8Fw/yWoFyVo4zgxBt24g/VYwZINFoBVW18gHoJ4yYpTzKyIbLty3Bi3Giq0fHvstoTVEWpEZAxRBBaSOackTa5YwZjKFTyslrmZGxXMyZL2Zy3WyJTjKoDUmdRolEZBhQv/jCKsaI7/yQotInSR4zguwBr7W2PiivM85ijHTRy31XX/r7tQadWXaSioPIZmPPTJF7qI2keoaBwbE2eN9xPnENCOvB1XFdS6CBK3Js8HFqrwIKa6mqAkjCqjQGVxi0rahHU8aTCVVdUVYlKUWapuVwPmN2dMRiNqdrm4FJKcxIg8nGpcN1Uoq6rBhNJgO1tx6NidGQ0DlaV0E2dPU+COgQJQQg6URVQ1l3/OX/4Gf47Gcv8L5fejsf/cSDX/Q6/963xMntQ/YOJoTghs3iPRd2+Y73PMu3vecSr7tvJ6f/5OffFBhX5PEoZWafhChorUkq0XpPG/wQ2BAifPbzW/z0+x7g5/63B5nN70zq+Z0de1Xd4uEH/zb33ffNfPKxd/H3/9E3Hvv9i1lfr/wGRqnEbDbib/ydH3zJ33/PdzzBO956mbe95QXqcQNKo40DBSl2RB/wKZuQdoHgJTGpaz2+62ibLvsKCri8f7A/JLXemUKrlCYEKcDEzKzVSsBzRY5O7+PqM4PMGIk1t8ZlYnHAKEOz7PBdx7zrSCly8sQpysKiVUARicHjvaRN9Yw0iTePOGvEp6+ssEbSAoPOiatEQtdSFpbSKBSBzidCJBuzBimGJpXZ1Q1Eg1ZG/COFujvMic6B84kmJCpd8YZHF7zh0c/yp/+tz6GVYm/3Flevn+IzT1zkc5+7wBeevJum+Z30v1UfilFzeGT51OMP8KnHH+BH/sGdi2rZdCiVcM4znTRsbc45cWLBye0Fb37jZb7nuw7Z3l5w5sycUyeXxGg5OCy5frPi4584zyc/dY5nn9vi6KhA2CfrlfzX2kb8i7XjLOj5YsSHPzLiwx85B/9NP3dF7rvnNt/0jZ/hW775Gc6cbujluClFkQRrNRTZlOpIStje990742/99fdJUS16UBrv4bFPb/OB37qPj378bm7c2mTF8Pn9dG1/79vW1hG3bp/gv/5//W5M5H/vW1EUuKLgW7/lKr/2G1v83vSDPqTk6+0ray++N947/u6P/lmEFea56+x1vvEdj/FN7/gMVa1IdKjU5yKvxmuL7AlcWZIWDV3U+KhZ+sSs8+wcLQkhEgIENCMne4bppCJ1iaQ8ISVGo6moYZTKhWAJSZpMRlRVSVWV+C6wXC6pJ2Oq8ZTrN66znC3p2o7FfMZyfkholygF2jrmviVFDyngioLxaIwJCa2yJDGt9h/DWmBtP6gkulF8XLUmEelCOLb2DsFjo81b1lXhXMz7ZZ0QU8InTYitSMQSKB8yGeF4+E4PTkwmFSdPTDm1f8Sy8cwWHW274PNfeJK29bJOSS2lK9CEVahaEh8t5wo2NjfY2t5iOp3KXjIftg+B0jkm49EQQBezKkP2slqM7bH0WZfqZZ5nWQuJF/ad6ppe+SQBdWIZlOSC5zCoiLFaAu56EGpNXSN3wOAQGwc/8pLoSYfRYoWSjKGq64w1qMGjKqY0EMskObPITK47zmNNCbT6e/1+pOHH63/W36Tyd1SF464z21w7c5Ld/Tnd4RyfetBJjsn742Fyt2/tsru7x3IxpyzLrKCC8WTMdGPKcrFkPp+zWC4Y1TlBcmuT83ffzc7tXe574OFs++TZ2tri+s1bwijsOpqmYVRPKS0U2uPGY8aTKWl+KAoTL0WvonR0OXQwxThgDjEEFrMZ9Wh8B9NRs7W9xYlTJxhvb3Iwn7NcNGw4iw7yDCktJAyb8QKtFOO6po0GnxRl9eUF6bymgTBCYrkIpBK8DiybAFEL2qlKgm6k0q16g++EMYpqVOB9x3LRUVWSCLg5rtBZ1jiuCyajkjLTI0Mio/Yqs7Iyoo0wpJRRGKXypnMlaYvEHC0stE5nTDZhBPqBIP/pGVFhGAD7DUnCJzF1l7jc/GCGbkgKC0EWm4GUE0fy9cngSUiRZedpm47arCRzyftB09yf24romZModKQLXtgHKUBPAVXHFDeDxFH38cJJIn37gU8SAS29ZNNkKV1v6t91Huc01jjKcoRzBSlK6oT3nuA7AeRyFUfna+y0pk0J3zWEpHCuxqiBaIw1htRfhyjpjRK53WU2VCcBAIoB6AN5fc/U6sHFvvWm/YP/jpJJKfhAaP3KeLpn2/XvXWNl9H1gnYnV34O+9dTphDDqvmgk7MBAFFaJNSYP0gmT39fTkrsu0GRjxf44i6I41neH442r8+/TxHSWusQQ5drST0zytqhAKYNC6KnaaGo3YupqJtMNTp04hXWWEAJHR4cczufs7+9xtGjEBBVhVyoUUcv97mIYJrvCFownY6wrqEYjynpEUVVS8VGa2EkKaQriyRRCoG2EWWMtFIUc884hfOTjr+O3fvv1PPbp+176un5NW8zdRHN7V5IY779nh/e+5xm+81ue5aF79jBW4YNs+lUSTw5hDklohsmVsZjkNbJYjELGV1KRu3LT8aM/9iZ+8VfuZ2//lahIR4ri8/yFP/dJHnzdG/m7f1fzqcf/cz71+HrK4PqK4Ku/mUlJs7MzpapaYtRcvHuH/+Kv/gInNmf0HPkYI2hDTBqlpHji25bDg12ODg9ZNh2L+YK2DXRdJGQml/eePihiY7KB1pqmEU9EbSSNz1qLVpIEFWNEJbBGYYtSUoIzYzZk8DlGSDYBDqU0knMuc5lWef7Rjo1JTQjIAqNtKQuHU1lqkavTWil8iplBLM+EUgIMKxIpeHxR4LSTxUNeKPmuo10u0FG8QBSK0EXmnc9sZlnMhyB+e+R5q6e9S8CJzsCsEWDRFCjjMa5E5fjyrutwZcU998y4eM8T/OHv+axEqLcFB/s1e/sle7s1+4dj9vbH7O+PmS8KdnbHvHD53FfQC16qn4kEs20Lbu8U3N6Z8tQzL9uLUCoxHrXcddc+73jrC3z/H36C06ePuHjxkPHYyxioNL6Dxz97lvf/0gN87nMnuXlrshYu8HLH8lpt/dxjeOa5Mzzz3Bn+6T//DtbZecZ4XvfADb77uz7Pe77xOUalsHw9ii4kVA7LMUahNcToCTHw+ofnvOEN1/hhJXYWvu3ovOdg5vgXP/kN/G+//A1fq5N+Tbe9vSn/84+9BxAbgJdix74a23g8wbmC/+a/fIJv+543fJW/TcY3rVtOnrjGmdO3efyz7/wqf+cflKbwwfH8lQs8f+UCP/Ez67LsQF01vP6hy7zz7U/zDe/4AoUJkAIxBvYOWw4XAQmPUwNB4Gjph084ah3jMhLQJGMpbUHUhqgtyjjQhhREjbJ14oQAHEgStjEeVzjZb2lN13QcHR6xv7svqXntEeRs9sa3hNTPyYFRVbFoAoezGcl7NqcjJqMXb8Z7jzMge0xLumJHzFYJK5hGZyUOpeyxmqZlsVhmokPAdy3ed2INYwtGk5p+TPYhJ8LbFz/fWmuqumI6nbAxHTM+WNB5AdbatqX1kdB5om9ZLBqs0xSFw1phwgsLHgG7RmOqqiJ6YebUpcNoRVkWFFVFVZdCAvGe0HVyriGRCKKoSqs9EurFgFjbiITWZkaSsn3RabVfM9aij0mk0rAGU3m9y8DWOv4dOq32jBuTmlmzP+yplFLU40kOFMt7Q2RvFtaJDUqhehDs5UgLPTCaVmDa6sRFvmnuEF/cqSpTSrG1MeHucye4fvuAw6bDN+KblZTCWIN1Gt+twLDFYsnly9e45+J1isIxGo1xhXh+zUYzDg8OuX3rNtPplFE9QSnNeDLh5KlT7N/eYef2LU6fPikkh8Kxvb3J7GjO4dER9ahmMh1RWIdWAYxh6+RJfGzpfGS5FOVbURTEKP3DOovSiqYLzI4OBUCebgzkmF4eWRQF5+8+z/5ijo6BMgV8EwZ8Qqse4JV9zzHrD7788sVrGghzRmMKlT1UEl30NEtPFwPjScVkXNP4ROdj9gSKWKMonCIFGDtDbS1l4RiPKqpCjLx1lppoFIE4VL5DSBTW5Bsg1fykhWXkMhMsIX5jKU+iYhofj8vklKSr9D5OPbrvsw6YfAuVEl8sY+wgI0iZWUWSFMehuADZ1FyqCuj1TqEprZjeG9IgR7TGCNgU2jUWWmaqaUOIcZCPdWLdLuehQTtHYewqvSefQ5dinlBiZt+EXH0ocZke2afM2Jx4CFDXtVBLtc2DnaOPZo4x4kMaEl+WbUPhrIBfXjzAykLM0a11UlVJwqjTxkBmpnU+QkyETtgxKHCukMRIbTPYtCZrJUsDezaWWgFCfZxz8EGYY/nfvZ8a2Z8uhrgCOjND0RqLdqL79sGLVv4lEiTJg7fO1F8DgwR19ZJ8XGvhBoMxZY6Ntjaz6zIIsupvfjgeay1lWUJCgMcYcK7AKJtZHWaQjMaoWHgJZEjIM2HX4jm01nQu5EFKaNNVNaYab1LXJbPlgmZvwXyxYGfnNk3TMm/mYAqReGWzUTnGTkDYfA2slUl3e3ubajQG4+Qe04PCkRBSBhPypp+Es1Kd67zmtz9yL7/xWw/y2x/5apg5/25bz5CSMSABD953m+94zzO891ue5d4Lh2IKqUDFJBhOylJUo3CFwmhFUgqlIpLW2l+PNHhZLBvDj/3EI/ytf/hWfvebcgFW7r3nSe69+DdI8TGuXHsP//wn/kNu3b74Eq9/5UGAqmqZThtu3py+6HejUcu7vuEF3vOu53n7W55n57ZlOr2B7zpu3FiCkkWo7wKuLNHaMJlu4pyjaRp2bu9y8/YNlssG3yU0DqV701+RNhtjSFrGeqPFB6/LcobC2WFeIVdzk03UlUiLS7cKYJAxV8bdfjxWaHwEHxJar8xvrTNiooshBklJs0ZhjcqLtR7gg6LzNG0n4JdWIhnPrC0BriKFE0P+3m8ktC1L39Hp/vOyiWzTsGjazPaRqrRROaE2CohNijl110gXBfGKMhZlLLaoBdjTBm0K+mQGhcyjTieKquPkpiemw8xqVYPsLsbI9RsT/uXPvJPLVza5cWOD2bzkOCvrlW4Cmh3NKj7/hYrPf+Hssd9qHamrlnPnDnng/ts88vAtfuhPfoLz547kmuTWtIZf/bX7+eVfvZ9nnt1isSh4qTrwa7+twO4QCp74wgWe+MIF/taPwLGKDwnnGr7nuz7ND/3xT1KPwuClh4qElBMuW4/vWpSC8Qj+3T/zwa8DYb+LdngkDPvXCgh27uwhSVlCUsSkOXPmiBs3Jl/Fb5TnMcaKm7fu4+at+77sd25uzglBc3RUfekXf81bv2H+WveDfrywLJaWT3z6YT7x6Yf5B//4e4FEWSx5w+s/x8MPf4rzd32ewipCUizbSOvjsRElJkVImqBF0u5DgsKgXUlQjk5VpKLGKI9OiXFdyVzmW3zXQUr4mFUU0Q9WHV3nGU020VYxWyxZhgZSxGiNKysWswNmtPh2Kez8dEKAlPLFLKGQC+1ChkjZkkL2Ouutt13oLUxcUdI0Dbv7h+zs7jKbHaFIbEzG1OMNmqA5sbXqdz6EbCR+XJ2ilKhqtDaEqMQ3WKm8/siFfR9ImRTgu0jjG8rC4gIYI4oPpaCwDmccPoIrSlKzpC5lb2WdE5BKa6JUOQhRPII1kkQd44oxpbUkz3vfiZVPJg8YbXCuEpBSZ43jS+Vl9nX8GNHoLLeNKwbYmsKnB8MS4ONyWHrXoxKtzGC2bszx+5diIpAyu36tB98Jgik1+IgNXXwIYEvD3zEfhNE986s/qhXYtz5nloVle3PEie0R13YL5k03vFRphS0UMehhDRlj4oVL17h89wtMRwX16dNijaLE71krw2K+4OhoxnbbURQFo/GY02fOEDoxtZ/Nj6irksI5Tp04iUZzcHjI0dERIZzGY4jZ3240nVIeHeGP9mXdq8BaQ+Fs9gbPqrlly7xpMNaxmB0xnkwGXKS/nidPn8Rf72j2PYfzQxbLBmct0/GYylaQDDE/M0nDsumwTgrN0bwMceSO9poGwgwqp+rJwAcKbQ1RSQct84Oa8iYwxUjTeFQyFEpoc85pRnVJYcUA3xgtm6IQMErYPlpr6aBKzPwK4wZzd2BYv4YY8dHnzVCWxZERXbIxYqawpvxzlAAuUWg39MkYWpvsvWQyO2klkxkeoAw+aL1iCq3f9nXzfG01pXU07XKgmMoxB5Hz9RsihEGmtZbUTd/iUyDp1Wdq0cOhTEHM1QPvM92R3mA95euT0NZRFI7CyXVrOqEtT+p6eNadtZnaqYnB0yVhEhmjaNEcLVvKqsFZhzYiexNQylAYQwGgxOix11QrpWQXmFkKIUSJ682bKmMk0dIYh0ZAMLs24GmtUcWqKtCzxIIPwwYYQCfxyxFAKgNl9CDFCtGPGYRI+eFMmaFmlQCPKa0G1qAi2igKbYQdEhPKGtQdskqTgb4eAHOZedLmxMuUN949wj7cQ6WH/+5B0BAEaY8ZgCRJAmVRFNn7JfumZZZc71FA9GvMOXJaa5cnyki3WNB0ni5p9vZuE2JksZijlOZg75DoAy0ttiqG40k5qCEEiZQpyopqPKaoa6Ybm1T1SBJFvBguet9moEf8/rQCrcR3IHjFY4/fzQc++Dp+7QOv/4rGmN+71k968ueBe2/z3d/2FN/xLc9w8e7D/GBrlLIoXeTqR0BpKBzsHR5iVeJ0vYGzCh9VlsKlLF2LNG3iH//TR/mRH31lqtp13fEt79nhL/7Fz3PPPYqr1yb82I/9x/zsz55hudy447xe6ZY4c/qI93zzs/wb3/8ER0dj/sp/8keOveK7v+OzvOsbnuKRh58jRQnfuHZ1yXIx49q1JW0rtG5ZLAiT+K677kKlwEId0TpJaVy2LYvFXOKpkyzGrDYkrQgZtNXaZL8MebbquqaIDqMTzhlEDrkai5Rh8FwwRmcmnx6Ym232EOtZnCogYyvyXK4q4WpY5DrrBCAdiqv9851yUIaRyG3AOjt4xKWYsNmQ2FqL74LIPruOlENZehZs13lmywWt95T1CB+CmOcqTWEdxEjhDC77QSiV/SZDkLGibUgoUIdSjLFFLnCIrMC4AmMtyoJJDusKnCkwhUUsZFfX6Z6Lnv/w3/9QPq4lIJKAoyNJj9zfK/m5X3w7Tz59N0ezOm/4v3pAU4ya2bziqacrnnr6NP/bL636KiTquuP+e3d4zzc/x3Lp+KE/8TgP3L/L9nYzzOm7OwU///6H+Jc//Qbm8/VN9O8ngAyOn4+i62p+7n3fyM+9bx3YSozqBd/87i/wzrc/x/bWVapqF2cNZS399R/+yN/hL/zw//73+uB/X7SqaigLz/5BzdceBPnSzRWB2wcdznq0gv/vX/8l/v4/ejN3nT/kic+d4DNPnODwcAzAeLxgNvva+W3t7wvIeM/FXR55+AbT6Zyf+Jdv/5odzxdvL7731iwxGlr/ajDtlzVR0474+GNv5+OPvZ3jO50AzLDlk4w2fpuquoI2C1Q8wlW7FGpGMmCsJSrDrI141eX1v8yfIYFWBrRDG1k/piD7oxjE8kShKEphrqASAY0yLluuJJwtiFqSyOdxyXK2x3JZy15la0pdlXkdHocClKh5AikXn+705AVRBJB8XguDdQUhJboQ2Tucc3A4ozBQVyWmXdLs7lGaTUaTKn8f+JSLTKyYaCqzh8qywDonDPggHny+C4SuZ9gJGzcGsV9QeU3XdcJcM1oYV0YZMAlX1nRtgzWGsihWcrceJFpjWul8VOvdS+cCcK+QUUpY6s6JB6o2Rl4eAy/VLwfAKxMMlNbCAByYVf01XnHCkoIu9L5aPQv/i4MoumeZDdfzS4yhgzxS3VHzUqhs8C9FI/mdJuRitvQvtHi+kldCm9OS0ycnTK8XHM7maz7ImuhKUgg0g2k97Owe8sLla5zYHDOtClJmECoteMPu3iFFdYvReMLJk5aiKNk+cYL93T12dnZIKnL+/FmcsUzGI9q2ZdksCT4wXyxBKbQNjCqNtgVlPWF2dJALq4kUdVYf2aEwn8i+582So6NDJtMp9WiE0mYA9TY2pyxmhxzeVrRdR+tbef6SH+6RLJ+SqCNUkPWuMpgvc9h6TQNhSknKQutXP3CFABkxAxYKlTfEiUJrQlQUaEqrGVVFjgUtBrP1vhIpahSVI5nzoKEB0uC9NfhuaUVk5aE1HB/IgJWlMyGDGCEmSm0F9IgrqSFa/Me00iITzHRWASUQU8T+taiMk8tmXyLqBbxaTzFMme4r71ADQtwnQqZ03BA9ISmGxEAKkS52hB7kQMAgq/TAsoIVo01AJ597ZS+9UlmPLJu9zsfhvqQQxTswA0c9yNY1HV1ssE4GvZASs0XLxsRTFAWVLUWaY8zABuovTJ9UOQA/KevLU59MmcMTrKRcei9pMVqbzEZYDWa9T1j/WTHEwQds3ecrqRXQJOd1nMqaL2zuoirr2NePWqodPWgl7AklevsIUSdBvFOPNMkH6v78swTJGCssv7y5DRngSjoN0tXeoLMHClOuNA3mikn85IIPGN1XC/QA2BV5YtPZGL9tGggBYzRVWWGdpaoqnHM4V7BYLNjbvc1iPqfxAHHod5PxBkbJOXjvB6aHJ2Lz5GfsmKIeMd7YyAwwA0VBUpompMGTzftACh6UmHKSEk984Ry/8a9fzy/92ldbQvFKNMXJ7Rnf8+1P8j3f8QUevG8nAyyaPpFGng+LtgUSKW3Z29/jU5/5HJeuXIUUedc73sRDD1xEGzfIwf/ZTz/E//S/vpFbt0f8bhe0RTHn/Nlf5KHX/RyPPmooyzE/8c/fwMc/8a089fTDL3ler2Q7d3afP/p9n+Xb3/sc29uNJCsGj9ULvuHtz/CRj9/PX/7hH+ehB54gxgbfdbxwqRuqm8tly3yxyLLANR9FEmpjA6JElRMCXQq0QSSOPS3eKENhcw6Q1pieUp/HLqGAW4xNeC/MqD5RWCbqlVeHDwEbA7GLFNYOxvNGa0xQGG3pglDJjUkkJfNJSjI2QAbZVZ9YZTiW1Jv/X6QVOkswRH4ZskRSahpCMdf5HGL0pBDo2oYYw8AGTSmxbJY0jUSPW20Gj8GYAtGrbD6c02KNoShEhtJloF0COMSrT6eEjkC7EOmy0tiixhiFLyyhqqnqMZNpSVmW+BBZLJt8P8RbUxuDtYayXPltTiZAisS7D3nLG35VxriY6EJi/6jgxu0Nbt3c5NILp/jsE+e4cuVk9iP7ajGy5HMXi5LPPHGezzxx/o7fR+q65aEHbvHggzs8+vrb/Mjf/gW2plLpPzxyfOYzp3n8iZN8+CMXuXR5m1cmufV30kQemtL6dXolr9nxz50vxvzSr7yNX/qVt93xusDm5g4//Jc+wH/3//mn/J//6g+9gsfwB6MtlyXL5ZfnofJqaGfveprHPn+Dce2oK8vTT91FUTUcHFmSUlirOHlixu2dMd4bLl7Y5eq1Cd67L/3hX6X2/KVtnr+0/ZK/K8uOuuooy0DhArd3ahZLl5+try3w7UOFPyY+6H3SZLP+tT6+499vgU18804Obr6Tgxe9VphD1s04eeIFHnzwM1y85zIXL16VAnwo+OhHH+HM6Vs88+x9fPu3/rqYuxu7xqYXOVc1qqhHNSF46hgpy2rYGxgVKeoprdc4pygLS9QFy6C5ddAxjQ5rTS4giz2CIZEiQ+iO1jpznDKBQ0nyYA8K9OogtPgoDmnRyYvvb4rEbsHhvqUoi+ybZUEXOZsy0FtugMzTVVUyqioJM8v7QVH0RHQhhfgYA8HL3i5oTbQrFVNvuTBY7GgtoJWW4rzp1yMvZ+vS39G8N1K58OZMOSianHMY62Svs06SepnPyf84PpusH8ewl7rzgxTKFqgk+yE5npc5VoQQcvznd7xQWDqZrbXG7Erq2DGIzb1YO/X2XhYv6i6yilIl4uClFhmPHCe3JmxvjNnbn7Fs27x/y2y9UsKYfH6QQ0hcv7HH5RO32NraRtdTnJZ1U1mXhJ0Drl+/hbOWqhpRFCWj0YjxZML1a9eIBE6d2MaODNZa6lr2efPFgls3b7G1vYkaW4pqTNTyt7GOFLMdS0zDPrXznTAflZb1dkosZzPmB3uMLSxTgbMaUxRUVcV4OqGs6kHJZq3sQfn/s/ff4ZZd53kn+FthhxNuqoxCJhIBMIJikhUok0q2JcuUNZZt2X7kJHe3w1jdtsftdrvHftozbXvk7ulpezStQFnOkmVKFEVKJEVRJEWCJBhBgCCIDFSum0/Ye6X541t7n3MLBRIgEQgLi08RFc7dZ8e11/d+b+iZcwswbJl88nTHixoIi0lkj2J+rzMIluNKkwAB1mgGhRQvYu6tKI1B4anrkroSICxm83AAY1VGSdUBGa+c3EDbuF4CI0kUKlNcRTrRSxWTaJRdlvSJ7E7+m5TC5yQ8MQOXfdZGWGeyLTLbJYp/hiKDdBptsxl99KS4ANpTlrAkls0U88OzxArqEhsBDEIf7hISIxD8QuoXUuhffyYEUiwoKkuMod+eyEIRMKmXF6oepIkh4lQgpQzaJJGHRhUpdLEwqGcBzgDYzPoqiqI38VdIYqZOXaQudCBYd/IFBJDit2NidbTVjj3lwyJZQyvddyYO0Ifz/2KSF0Mn1bx0dKBb9xBe9t9ZMMb6ST91RWv3AMtmCm0JBJxKcnX6psqCyaWUFrZHId5YKNWbZ3a0694bLEpnIebnomO/dUCA957CFnQ2pdrI81KVVX/83YvOaNMXnUopRisrrKyssLq6RlWJAX4Xi+u8E3PSEPGupaqHtK2nWGLhhRTEWCyBsgZra0aDAaPRmHowoKxryroWyWXwzDMg4FoxMZcEMk1ShnNnV/nND7yC9/zmq590Db4ZR1U6vuPND/M9b7mfO159CtuzBTszUZ3ZbSINRUsSrJbJgLu/9GXe9Vu/y7XX38DpU6fZ3p0xHK+yv38t/+e/egW/94mraN1yIfDMGVqrq7v84Pc/xlu+/VGs/RK//t73c/e9W3zyU/8du7tv/4a2/XTHD//QZ/j2b/sS11/X0s5nxJTYujDFu0DTtrSN40d+8B5+4HvmtE3LY482tG1LCNlbwhisFuo2SQloaxbmqsE7RsMBdVUwHo/zHA07+7sMqhq1uo53rbBdo/hEJiUhKt3jXtgsyVaRQW0IQRo1kBspxhCCIyYBE3yExjkBtVJOXMwvnBAXnpQ9Y1hD7+KoZK70XmjmWksAiFaqTyCOef+0UiQlgHhZCFjlmxYfJTyhtCUKLQ0XtQDmtVJ53lf5OY0CgBUl2hhJ3E3ifamVwiqJkU+5cEhaut/CVLP4zE4kJVQK6CQLcmsGKKBpHcHPhJHWGnxmmqXRCil6XNOwv7PNbD7F2oLWeYqyxpYFtrA9u64wwnYzRhjCACUyt66NFddc0dCGc7hwFuc/k5sj8ms2VTz4yAZnz4356O+9kseeOEbbds/Pc1X8aWazmi988Sq+8MWreGf/98vvkUhZeg4dmvH61z3OdFpy3/1HnqLI797Wl45nY//VJSBYZDBwhKBp2245uXgnP3fDsLNzlH/y//qh5/A7XhrfTGNz9xyf+MJjIs8pa975b38Q7yom+8MnfbZpSh57/PJhG0rFzHJ6YUfTFDTNCwfSPbOhL/nvwXH1lac5c/YI7gUEHZ96KMDg3Spnz97G2bO3we/BJfoZlHKsrm5jzC5VpSmKEVqPaJrA1SfvZG3NU9XS7IVIWViUkjosBE/yDQPtCdTUI8N47VjfsJ/NGiYtmJAy4KQxJKySAJ5p46hKQ1EYkRJqzbxpcAGCC+iUMEWFLSvxiW4dSosCxGhF00bmraMaKjBI4vp0xGhlgDIWpQvBXhAKRbfOJzetisKIV2l+D9IpXHLNmLI/Gynhg6YIUlc552md75v4QJ9KLUurSEox1+RilyOgGf1aRWfChNLCUDPaYHQpqe8de0yQoKXa7OmDHE+6Gy6VL5LrM6VBd43+g3fP09vwU8wpl6kXD+5/rtjzvdANY+j9rbvgveVjKIxlfWXE0UNrXNjco23bfr0GCWMNZVWCavEhYQqLC7A3adnZn7PaBmwlyqu6rjBGsbu7wzmjOHnllWxsHMYYy/rGBlVdsr29xd7+PvWglp+pKqqqZHtnG3/eow0UxTojCpQuUEVNVY9I0YsEcjajrEoimpA0LkQSGTQ1Bt80THa22RiUQoYYSJOmKMTTbDQeURSF+HobWetdLlwhIWQj8/sFCJtNHG0TKKyiroscU6oWaGuKFMZQFZZxbdF2IIwKEtHPRd6SgQufiwBtdF+MwCWAcZIb1ccMIilQcSlOPoNp3Z9VBjV09ttSKAotC3aFpLR1bDP5JQVSDnETiabPCRs2HQRTrBUmWohE7y95rjP7LLOgQgwHjPk7U34fxKA2GSVFS34YEzlVMMgk5mPIJKSE8sLqGmkr9EVEnico/QLo65DuDjRy3gsDoqywSlFk9k9nHN9LGTMVtmdyxURpLRurVmLYM7DonMNK3mfvH4MKGSjiAIOrl0rqxUSqlcYirAatOBBz28kTFapnkPVMwSUEuqOimixf1TqDOmmJnpuPI0QBFVWSbRpr0SZiUwFkuWb34skviYTuAT1Y7nQIgy0lOa86S6JC8EK17grRDvgKoZ8uOpYIabHfSinKLF+1VlI8YkoZCCszW63z2Qu0LjG0Q7TWrKyusrG2Lp5dVY3Smtl0wtbmRba2NplOJpIamhLaDvCNo8BCgMnuPt55mmaOKSxVVTIar7C2ssFoOKaqaozNPnZNI55zChiUmeUSsCYxnxf8+rtfyS/9yovHyPYNdzzKd3/7V/j2Nz3MaBhISmeQhr4jZoymKoyEYmjxcotK94mfbev5wr0PsLm9zz/48b/EB95/Fz/38wP+87t/jJ3dtaf45qfzWo/cfvucl9/yGXZ3/g1vuMPw1u/6NiaTlv/j/3c97/vtf00Il+tyP7uFb2E9f//v/AY33/QYMQac95w53dBMp7SNYz6Z0LhA6yLz+ZyUEm3byhyqhO2ZCMKwUgUqg7sDU1JWFVZDWdrc304URc3hI4dZXVlFgHVNURZYpWnqmuAa2maejWRzNElaLFKMgpg8s9mEYT2irkqs1TRChVwwir3DWGhdoGlaCltgje/j0/vFJ/T/jUSi7mj94v9llemT+Kw1hBhoQytJPEnmdAMYYn43SeMieI/3rp9XjDJoq3vmsbUWDITcLOn9I5XC2II6s2knk11hZGXWqNGaOs/rCWG8KddircmLHS1JVkqJ3DHfMt55YbM2Da1rcS4So6dpIrPZPmbHYvZ3mc9n7O3uMJvNSGhaH7GDEcpKk8Qaw6CuSa5Fa8WgrCjLsjfYtUY8KsrCZKDMZsmoxWhpOKytRDYOTWiaTb7r2x/sU3djhHlTsLU15hf+w1s4deows1nNgh3xXIDAy9sztK3hzJmKM2fWL/PZyMkr9vibf/1jHD28Q1ltiTeMNpw5f5FTp6fceedr+fznv529vaNL+/2NDp09zp5qv18aL41nZ/i0x6OntghJ88T9f5qdrcszrb7W+Oog2PJz/Nw1dp7+WMz5L/y+PPV4rA8tCayMJ7zsutPM5gNOnT7MdFYRozTbv7nGpWBIwc7OUX7zfW+/zGe/jRtv+CI/9Ed/i7IMeNcQfYstBhglzeiQPEaJL28xGDEcVn3NsLLi+yZ6b2OTDE2ION/SNi2VDwyqkpVRhcLQ+Mh0MiVFAd20LUnK4ELARwmqCjHSZolizH6wSimC90wnUwEtdFb9aE1U4g2qySSCJE21srNK6HxkU1cPJTqrm64YTpnd7byndS5LJCMxOlKCqh4y37lAWVUE3+JbAKlznJMANaULrLYYFbGqALVIrpewr+KAOqcjVSz/OeV9y927y7C7ln70KW+B/C/Zh5JihFL+ku9+GiMTPr7+e/zy+76cNLpMwOjO1Xg04MTRQ5y7uMvu/iSDkgsAUwgkiknjsWVBPRiQ0EymDfN5Qz0cCNCWEq1rCK5hOt1nb3cX7z3WWlZWVjh67DDbX95ke2uLjY11aTyWBSsrY7Z3ttnb3WNvr2I0HhKiwhpQtqAerBDaCZCYzuaoQmSntrDi65eErGS0pm0dO3sTxmuO1dVhf220NgyHQ8YrKwISO1nPdb5tGRXJTHWWWJzpKW+JS8eLGgibNw43d1SrtXSltfiUhCiJXlaBSuI3ZFQBMQgQFj0R08sV29ahiyWgpHvgUQv2ZCKzvTJCnVHlGKNQWUMQ/W4S83yVEXWNpjIaj4A0Wqke5e78XyAzKDMlVavUa1s7gMjYBYCjl1hoKYoviurgfSUFlwAynVmgobDi8eS9oPetE7PjwhZ4xKPlUpRcQQ/KdDTTlBlFrm0laTCzq2IPMsmEeeAB7pgGSqODJJBVdUVoXT9x9+cUASOFqbGQN2otk3vKwJY1WozvAwSfJ4nkhXHAcicjyTkzGp10z8YqAWUsph71jAel1IHJpvMhM0aYFcoIO0zngtQ5SfjswNNOGonqWBwLiWIIQcwzUbSNI0UFaExmcSmkExKIeByhq60iOJ/vKyPMkaIwlGVFTInGOabTKcO6luIzF6/9uc9skmVgTiG+ZlpphlnOWBSWelD1MsUYPMYoKRB16ALhMpvFUNU1ayurrKysMshSyLZt2N/ZY2dri+2tTSaT/Sy5zP0n3xCc+BXFmIGKlKgGA0arY9YPrTNaXWM4XMfkYjuEgHeO6Bwpe9UZZbEGfv39t/Jz7/gDX2WG+OaJPVdZvraxPufn/vmvcOTQVJjRaEASClWezI0VurAtJIQgRY93gdZ7koLWRfanM3b2JrhgeeL0Hfytv/0GPvWpt/D1v4gDGxsf44aXvYc3vWnGn/rTf5y93X3+9S/ucOddd/Dvf/kP8sBDR5+ls/HkcfKKPf7w993Hd/yBL9M0CWt2cM0uk9mEhx6e0zQt3rWSHhuTdBYzw2jeLoIolEKMaYmkoouJzqBiVWNshbUFZTXAIoEORisJ2SgqrLHUVU1hDW3bYFRCEzEpB4zUA8qikHk0M7lCZopK8LmiDQnvs09BF6ISBbSHIMwtY5nO53gX0Urm59J2/oaL+VCAsCx/VNBlk4tfpcEqTWFNXsQq6dyqhIuJpByl1lgl378wTl2wOzt5qNYa5RWqUHQhGCDzvfOOxjUoY1DaSM84JawtcF7o+GR/QmuMzNMpEVLEJJFPWiPnz2QmbJEl7TpLDDpPSqsNzlpaJ15m08kus+m+vGtzIaEAH1oSBp8SeC/+k5n5evb0aUI7z53EIWVRCKBpbfYlKzBliS0qlC4pqgpTlugMmpVVSWUNITo5VrG9ZCXBkSOOf/j3fqu3Fgg5iAcUs3nJ+Qtj7vnSVXz+89fxxKnDzJuag3PQc8cqO3V6jb/1d78v/zlw7NgO3/rm+zl58h4Sp3jlq+7ktXd8gvXVAavjIV+5/yo+/8VbeOTRazh9ugPHXtghJhPwzTJvvzS+eYafS0BSExQXnnjmXp9lFbjl5j209nzuc0ee4lPqsr+vypbXvOYUb/qWh3n/B2/mi/dewfPzvHw1AOyrAXXPN6DXbd+wt7/K5+5eXfo3WciOhhOOHrlAXbdsbW9wcXMjM1pf+Hnnaw/FVx54Bf/sp17Bk0GLyLGjZ7nj1Z/l2isfYrA24dgxqOoKm60KfBD7kbZthX28LMsbVbi2xTUNMcKs8TTNPrO5Y944FIkVY2ldYHt3h8Y5Wu/Zm0zZ3Z8wm+fwMC9SOGMl1Gp/b5fV1RXqoiAFj1ZWmuvK5jpVgswKaxgMKuq6xObUwqIwxCai+pTp7M3ZrQuiqHbm84bpdIb3LSE0pARFWVJYsWjxztHMBewTBrvUJ2VlsEZSy8XOYYnthBjpd6nXAOiSdACuSET0QqnSA2PpSXWs0ZdjZF06IspojNXopyVN7kg3SYKp8t9dVo6nOpbW8t4f3FI68PeLtVeHP0ZiX18ub2lQVxw7us6VO0fY258ync9pfcI2Thj4IdI6GCD+6c4HJpMZ08mM+WzOZG+fECPTyQyVEt41bF6cceb0Ga665lpWVlYoK8vxE8e4eOECe3t77O3vUQ0rMGAKQ11X7O3usLu7y+Ejh3sQ0dgSW9bYaoSx+1RlwWTasLoypCgU1gVRViSpcWfzlsJ7DrWOtaLEFEWPCVRVzXC0Qj2omc1ndDFowsIT5V4Hgi0YjKrHA77WeFEDYaurFceOraKsdBtU1Fhle5P6rvAorKQ6RsBEnwEOsJbMeloY9HXIt0odKEYP1lxOKwyCkAvzxlNoI0b5SkAzo3Q2i1N9WmI3lAbv5SWRsjRGHqaI7rTkPaqpMn1UCoiYpYNEn+mUafEzqhP0icSlKiqMNviwkOkkEiZv63K3ilZKJgYgadUXTjElMWL3HltKJ1gmAp39usRjJmTJXfCO4H0GGeW62IGwsCIKveSD1hVosMRW6gqvKNIfk49RKcV85oRpFTtWWAdQ0gNe8pf0xvQCFBo0knSiUdmzjAz0LPYhJTIAJJ5xC+be8nybTfDzSTygQycDYlFoxZqc3pij4stiiDLC5OoZbPlVo7VCI/cSSXy9OqBWaaFjR+f6Yrn1EmXs87YWNxmL/cnnpru3B0XFeDyS5Dkt16IoxS9vPvOQAsIp0SLXNZaqHrCyus762gbDwZC6kolpa/Miuzvb7O7uMJ1MmM9nfeKKnMeEcw1KOcqyIsTAaGWF8XjMeHWV0cooeytZTFEQE3jn5HhiyOc/4XGYmPjKV45eFgQbDidMp6PuLr7Mnf38Da0jr37FWb7/bffzrW98nJVxg0pQKgjREoOw/gprqK0Serqg9wRtJBHJeaYzx2zWEmLC+cDO7oRPf36DD37ozdzzpZ8gxJqLF7+ePQxcf/09/If/cBu//Et/h9tvfwU33vj9XH31NXz8zl3+6T89ySc/+Q6km/fcjO9925f4g2+5j2uvOk3TztjfmzOdTpjsy4u6aRqca0lKWFSlLvp7HiWNgcImVoZi3L46HjIa1ISYI5ZzgqrOMgIBaBKFRZJi8zNljMEWVliHwTN1c2azfWazfWJ0fbdJa02pSwnV0It0084rKwE1dGsk8eVSQtVWJOqyYFCXuODxoSKWiem07Y1nRbIdsgQ5exMmT2KxKBTZviZYg8fgvcH7hLUhJ8bKO8fh0FHLi2ap6YKiX6zEIDJp5x1N2zCoBiLF0LpPqQoxZN9I6fh6H7LsNPRs46IoiHFMWZS5QSPPbOc52boW5fN5ThbXyfKNkTIpxn5eL4qCsvAkFPNmRtPMRc6tNTaHpVTk6AAFSVtWVlY5cewYYT6D2YQL58+xs7Mty+O6Zj6f4pzv99caiy1KbCHswLKsKMo6m/IWOeFYURYllAYyCNids97PMabeWHg8jBxa3+fmG+7lj/6he/pGVwfYxiR+X3d/8Vo+8rFbeOCBK/Oz1S0sns2C0HDu3CHe+atvBN74lJ8qijmHNvb5/u/9DN/6pnupqgl3fvImPn7nrTxx6iiLOfT5KVbTJXN2XbUkyB5uL43fz2O8+iBVoTCFgfhkOeTXGm1j+MIX1vOfhKkzGEY2DkXaRnH+3KIc0lp8hb2XgrdpS+78xHXc+Ynrno1DeZbGV3smLw/ovTAsNwUYJtNVJo+uXubfvxZo983AzFsel+6L4dz5k7z3/SeX/i4xGMy56YbH+NZvvYdbbnmcwWAgvreaJRmibM25lul0RtvKWiAlRYyGqhqIB25InD13gfGozoCUZj6TwJ9Z01JXlZj0TxvK0kKKhDawv79LVRoG1qB8JJqCqESaKQoVwZuiDwcS6a3VONex1xJaW1TREROksR2zksoHaQrFLjSLSGkNIUpjvlER7enVSCmCtZFkO3Z754K7OHcpXQpeyT53Sxhh/dB7rnahAEI2uWTdL0lDX+U6JpQuKKpS9ibZzDRb2qMnYWnizZxBg3zc4dIPCYFEaZbzAC7dVsqf6wrLkA8ydOb3aGm6qsSl8svCGo5sGG65/iRrw4pp09K2jovbu0xmLY1zzGctu5M5F3amZMkJrfNsb21z+tQZNrd3cM5x7txFNje3qauKEyevZm93l5UVSWEfr6xw7MRxHn7gIS5evMhoPOoJFOPxkJ0ty3zesL21g70p+58bgykr6vEhyr0tqqrk9BNblNZSlLYH+RKdT3VDiF4AtWPHKQdLYSdKsbq+xvrqGvv7+zjnxVbEFuKLTQeCdezFSAyhP4dfa7yogbC1cYUpSny+KUNzSZRpTo0orcFqiwuRoBJ1rXoDRBRUhaUoDPPW472AKkZpMWszIk1CLXxbesAspuzXY4je4bzDFhqjTM8M6nytCmOy9GV5B5V4OflIYTVVZfuJR5hMHegiJstERVEclM+QEkpFYpKoCQGNBMnXKvVPXyebaZqmX8STjyMGL5revFsdnbcz516Gykz3MzHStK0w8ToWXDbqF+9pOffGWJlssz5cpgpJw9K2Y37lbfosN1Wy2BG2gPxsGyOFXpjZhyDF2KWgTy+D7ECrThif/31x6vM5zIbrSokHkzJq6d/p75OAzjLWfr5a6gJEYfRcBintimyF4sBcj6KsKsjnMkaPjw4fI1HnV79RlHWFyt2eDu1uXSsJdkghecDsnqXAB6UoC+kOzZwAaaUtKFVBaQrGdX4xWyOTrNZi0I0jRC8UVlswHIwYjkYMBkMxUaxqrC3Y3d/l/LmzTKcTZpN9ppNJTuG7zAshdfHNhqKuOLqxwdrGBmvr6wzqAT5FWucI0eGbGTFJIU4KFEWitIoYYW9zj9gWrAw9r3rlI3z+C9fytj/4Gba2S+769O1LINgLM5QK3H7rOf7YH7mft7z5UQZ1Q4gQkiwGtTICgMWENZqqLhnWKnuDCYsmRJlrXEj9nBNi5PP3FLznfS/nk5++g/l85evYO/mOV796l//pf3qIn/jL38MbvuW7uOOOf8fNN/997rrrk/yTf+J5z3s3aNtrnt0TszSuvfocb/uuO3nlbfeQonQ+v/KVSAgNvp1nvw0BngqdKGuLNgKAKOTZT1oA7TJTvwdVJf+tK6pCwNyYJP0XxCNMK40PnnnbUlgt/gndmckv0dlsn7N+jkKYUPNszh5inms5OMcszz82M7qUUkSVssekQdlEG2XxWGiZYyoKBlWFD4HRQCT+8joSs32b58WmneO8LBg74MkYQwwiBwVFaQoG1TAfp6YqCwaDisqWECPO+9woSH2jAPL7McuEWieSSuccrnUH5iqtNSF3j3sALWpmswk+yNzZNjJptUauVYoQk2PezIXdmA33rbFZCppNWstqIUPIndMuZSqEkBnHFltoiqJaeEVq8MHJXKwLVscDbrv5ZvZ2tki+wWjF2toarnWSymkMWrVMZjJHNTSUpYPZDJQSuwKlJKlZa8pSwLCiKCjrmqKqKaqSajCgrAayHk0JWxT4tsTN58SYaFonHe3s8UnHys3NgEENb/mOx/mOb3uUPnk633u7e3D3PS/jU3fdwkOPnGQ6G/DcgGSL4VzN2XM17/nNI7znN++gu/DHj2/y3W/7LC+/6RS333YWxYQzZ0u+eO+t/Mf/9JZ8X7TEaJ/TfZz/vgPAvtmK/m98aB3zGukgo+OZHufLb0rYwRrTJnL4+ENcPHvrN7BX8nxOJ4bp5NLgiSRsgvhCA0jPxXimx/B8ssku/f1TfX/Hru6kaN+M10Uxmw34/N038/m7b+bg4j9Rlo71tQnHju1x28uf4IoTmwwHO9x0ww7T6ZzprKGoYu/LZZRnUFkG2TfJeY/RNer4MYb1gOAjrUts72xTlpbxoGA4GrG5uYnznhPHj0vzTvnclImoJH5lIURaH0DpTDRQ2dhcQJu+f6bN4kwrqSmbpmV/MpM06vxBUZJ0DfqAUglrVO/VDJlg8FXGk5hVsbOXOeiVdalksE+o/FpXR2m6ZEghYJCpWQql7JNILx15ZvFnDSkHxmUfNGLiycmR0uxeZn2RMa2D+9Oxmxb1f4qJkFQmPeUoU3jS7V6VmiuPr3JkfcB83uJiYHdvwv5UEtFPn9vivofOsLU3wznP3v6Eh+ZzHnzoEZz3uNbRtC1N6yiMYWUs982F8+e44uSVgKyHjh47xgP3f4XzZ88zHA7ZOLwha7i6YnVtld2dCfNZQ9u02NJK4nhZURlLPRhTTWeojKOQ5bS9ki2DnynCfD5jf3+P4Wh04PwMhkOOHD7M1vY2FzY3adqWuqxRJts6dVwP1RGaIgefu6ceL2ogrDIFSYnvCAjKrpLCGiUsMKsobGZjJUMMQ4YrErNOPnEJYdO03uPa7uIIP7RHlmNm9uSHRitF6sCWJBMCWcIyaxucDxTaUtkimxlmE3YtV6mT+ykFRmVvFkTiKACL6K21MnRsT8gPi6VP90ohkIzCxJQLx5hNx0XLEZUg8r3sL3tVhSWmTidNOTDk9PQ3FSxkhovkQWHB+U5mk39UpfyQR5GU6KRQxqJTImSmQpcisszaij4emCh7UKtD3WMEs6BKhhC73ex3WqRl6oAXWLedzpzeWNODmXIOUp8qCRIc0LHOSCIxDfnFYSKYfE5izCmXl85oy6ex26aW7aWQSEH84+pqSGFLnGsz809njy9HUhZlIWgJOyi0RNn228zMlNa1oBTT6RTvvYAnzi2CBozB6JpRWTOuLUVRUlUlGilIS1sKmq7omWgxJoiRqqwZjUYc2jjM+toGq6vr1HXNvJmzs7vL5tYpZrMpO9s7+GYuyaRLL6hlUFBrQ1VVVPWY0eoaa4c2WFldpapq8SRLkdjISzWGhoRQlAsrnVmUpL41TUvrPIOqoK5m/PX/5j/xq+96Pe969x/ghWV/Ja679iI/8kfv5a1veYSiEDp2SUtyLSmInFMZI+w7I0aixiTKUqFUFL08cp+5EGmDIqTEI4+u8L4PXsN73n8DZ89drpv6tfcNoCwf50fe/i956JEP8GN/5s/yXd/1Y9x22628/wPvZ2dnyl/7qw/wb//dm4ARz9XC8m3f+SFeffuHGZaP07ZzTj2au6LKYPRiSWu1YTgssDmxFZX9F3JAQwgRa6SjVFcSeGKzYXvvNYjIf61ZvOISCYNhNBgSU6SZNz2YFWMixDkx7dMtRDrvL+fE38NokQwUVljHHaO2Y4Mt+0qoBIUuJFBlYDPbTFhNQYnHobGaQhtUUMS2IWoyu8osulwqom0OyFCSFKv0opGTOnBOK5JL+BCJTcusaalKSd6Reb9jYOVmjJKwl8IW+OCx2vbnymfZqSRYSVgKQFGUlGVNCJ7xeJWiKGmaOS6D9ChFUYrxPlaRkpF7u21wShojJKiqSmTZw6EE2FhNbGX+N9YcAPLrsqYq6/wy6t6jci6C95ImpRyECU88+hVIqvd41EqL3MPmFpHSaD3IjSyVfUHl/VIU4pMyb1pCmOHdYuErLLWSqhpgi1JMiotSPMaKAqUM5KCXsihpQ6CuB70dQRegE1P3NHb3nCQQhyDd+GIj8G1vfpg3v/EBBB+TxkHbFtz/wHE+/JHbuPfLV+JcvfRUPdvPqmzv7NnDvO/sYd73/tflcxAYDOasrU55zasf4eQVLSdPTDh+LHHFCU1Z3Mu99xf87Dveyu7uKt+8BeoLMbp1zeXfUYX1KJ1o24InJ3K+uMfRIzv8/f/bv+Ov/3d/+ZJ/UTxT64I/8Jp1yqFh0kRuvuaD/O8/ddMl4NqzNZ57RtL/8o8+yq+9+3oeeGiNpjHs7RX48I14DD1XY7E/L0zIwOXOh2b5vjFmxmB4hhQNzq3Stqu8sOvBy42DYF/bVpw7X3Hu/CHu/uK1+W8Dt932ELffeorrrr/A+top1laBmEjBM6wLqsKgCHjf0rrQq3A6G5GyLNifzjizvc/s9CazWYv3gVfeeiNlYThyaBWjNaPhgGEtDSmUoSoLVgYlo7pEMWJ7Zx+Tm4kHMKle6SKN6da1zOczfA6E6xqFmc9B6z0xSpBQ54EqDclAyYKZvkRWz+vgg810IQrEfk3WERestb3XKf13fy3wowPB5B2l9WLN8FTDmO7Y8v4kRSCHL8Ug1yiKvPJJIx30yzeZpL8MrHVlpFIKg8nBdU8PxAGppQfDinpYkRIcObxOSommcayuDLmwPeP0BbGq2drOjc4eJ5IGfOs83gRmszlPPP4E119/Xe8TBjXDYeLw0eOcPXWK6WTK6tpq38xcWV1jf7/h/PkLnD93gWPHj4rZP6C0ph6sMKj3WFsZMBoUTGcO70VJtcwGDCGws7XNeHyBlZUVirLE2iKvrw2HNw5zYe0ie5N9Ydr3uEyHTRw8r093vKiBMJPljmW+yQKRwaCQB9wubkh5cAJVPV+c8rQwI3beL5heZNPxDBhZY7PmWmeJ28JfpbAiGZrOptksuJNOJHwKmPzAd4ygsrAZSRc2iFaK1gX291y+0N1DmYi+zwdj2TdG60SVwRyPULe11mjT3dMLNpnJD6XzjiIbChe2AN95PWXPq5RTwrTChyj+MmQ2m7aojNb2BYY2FLYzlO9+qZ4FZ3Qu3KLOpt+mLyBi8hgtgIvWi0nr0slL0PDUF3AKRQxOlk5aS2egA7TytXzSFKSyKX4uXLUR2mzKHXrIS1TVmQV6hK0rSZUdqpySxBt70pL5dJYv6kwXvNzaaYmJ1mnYlVJCKa3KDK6G3sh/4eWVcEEmVx8iRkFhFomag0HNiWPH2Z3sMxiNeOThR9jc3KR1kho3rGvxHCoKqlIM7+u6oh4MKYpSzAmVwuiClJllbQw0rsEFz8bhIwzqAWtrIoE0xtA0c85fOMfW9hbnL15gZ3cXpRQroxWSb3HRL2ipQFFUvaFhVdeMV9dZXTvEaGWVqh5QWEvjWlrX9gwerUVmVJRezPBTwrmETxIskVJkWBVsbQ/5uX/z7Xz8E7dfesWf1zGoW/7oD9zPj779bsbjNgPO8lxHF5i2DqOUSEiHtcjwjOkTH2NKTNsAubsEgRAkCfc33vcy/vFPfds3sHeJomj4qZ+6n/u//NM88dgj3H7rq9jaWuWjH/kof+7P/Ti3vPyv8Dsfej2HD4+BO56dk3LJWF/d5Pvf+q+56uRnAfEtDL7AO0k90kWNUaAzg8oaw7CqqEqbz1HMwHFNXdUkVJYOgo+BuiqEYWSFzXTQjDb17FefjV27JoAEhkhHyof8ImWRQmOtxhrde/A1c2EZjUZV9pmyDAfCwnLekbpujO7OfspdW92zQfuwkx7cR0BtpRkPa/EzyCzh6bxFFwLq66hAI0bvpSUkRUgLMIUkDYekE67xGaSXr5g38m4R6X7EaGkOaQNFPUQBBfKz3fZc592oxRfRFAW1LSjLmtFohXowYDrdRxstPoBtS0JTlBWDHFqzkJAnYCSG/F06Zv8e0bS+RReapm3ks/4giN55qRgtrC6fJKwmBN8v0mKM7G5tsXX+YpZLLDePpLMqfpjCIBTvT/Fucz6wubMHHoaDiipp2vbgPZxSom0b2rahe9sJ/GgyYJX6d4YtSyJQ1yPKqqS0pSSNZe+xuq7Q2pKiSD06v8TgWpzXoBbJiynJnBoHkde88glecevDpBTo/AZDUDx+6io++vFX8eGP3sxzWfylZJhOR0ynI06fgc9+7tJPvBpJUgscO7rH4Y0pa+tTZo3m9Kl1zp1f4UW+3PwGxle/Ls4vgfUZaNDaU1UNs9kLy3D+xkbiR374IxSFqBUOjgCYZwSuXHWFYVAO8a3n5Uc8t/7PP8f62h5ffvg4/+Cf/tizvfNL49kDp648ucXf/7sf5MSxBvPeKzlzdsRo2PJrv/xORsPIZFLw5fs3+OjHr+D+r2zw6BMjtrcqYnrhQbKnvk4JuZ7L+/j87WsIA/b3rl/aF5CXq8Naj/clMvd8s4GMB0fC8MV7buSL99x44G+19qyt7nPlyW1uuXGPl123idYz2nbOtGlwTvx8lfIYPYG0Q2W3scNt6mqKUvDY6dNccewIX7jvvFhIjEYMBzWFtaysjBlnawmlFTu7E2n257WJscXihepagpJaxlrx25y3gcl8TuNc9upEGv4ogndMpg0AZSHAW2EKymSpRwJmBbd0uEpAoW451V3ONrSE2CVmL351YFg3OoudfnNdgN6l5zotbVxp6BqmlyddYY38zKUYm+p32lweBPs6RkewWSASSzv9NVCe7l9T3k5dl5w8foTjxy7w4OMX2JvMFh9Uss0Qs3Ii18qrq0NmTcN0NmF/b4/1jY2MoWjG4zGbZcne3h6Hm0PUdUVRFhRlSQge5wJPnDrFcDhgbWNFgvy0JgZPaS3TxrH5xDY+ExoGdVai5SRRErhmzrkzZ/Dec+jIUQ4fOYrJvuiD0ZiNQ4fZ3d9nPp+jVa7T6fAElsDayzALn2K8qFcmKjeVGueobCGyRLPk5aU0mALfOM6f2+aaq9bgkkJpecQUJU0rirF9V6SIz4p8drnr30gchhRayVPaispWKMTYPQQxuBa/F41zoZfeyf6LVle2IX8nke8AmhQUwdOzsKyVbr4LDqM6fy9hQmklDBJU/rPWPSC1XIBpoylU7trLQSPxtjmlMgjjTXzOhJkg28pm+TmxThhhnR73kuuCgGG6yCb0XaqkAo3BuxaDImo5/phZDXaJzXHp9UkkPArX+sUXWUuIkn4ZU6RA970iYd+JXGlQD3qQUg45MXf52mmNrkq880ITDZ4YFDrKoxFDIPpA6vy7lEJZ3RuZKwXeg79EDZhyemOX1NnPUAaKqiDSEENDExop0r3H5SLdAj5E+TsfKLTBG2FdWGNxe/usr29w4y03E0LgzOkzxBgxWjMeDBjUdU5Ly0y0JFr+lCQcIUZP6x11afAxMJ/PKQc1x4+foBzWrKyvUVWVFJj7O+xsbbK3u8tkf4JrHfPWkXKS6M7uFs1sIky2lChsiTaGlZUjrK0fZjReYTRekWJQRXwUCZK8ONvMgGooLBQmoCpNUkHuMR/wPhIS+GT4+Cdu4v/709/DC83+evlNZ/irP/FJrr/uglx/5zF6JCCN1wQPFkVpKwa1YTiuqSpLiImLW3vc/9BjwhIhcfvLb8kpkHDmzIBfeudNvOu91zObDb72rlxm3yDxh/7Q77C5+Xd5+9t/mLe85fvZ2zvJR373w6gImg3e/e6/yGhUA3/qWT43i/HG176X17/mXdSDXQrbdXUsHfl7ra7xzsl8pBVVXVGVBYVZeCqSVPaFspRF9uXK0j4XnCzGjMwB82beG+YnBJxqXbtg3njxsog5HEUkxkL7UWqRaBWiNDDEeFWefwFiRN4efey32c2zPksPo5N5KuTkJZGoL3xAumMRFtHiXHVS6/zmpiwlTdj7SNQirdQ6UVVWWLQhoZLQ5rUyUoMoUEZhi4J23uYQl4i12WfSB6xR2UMMMLLMciChMh1LKSw8ErXVYvhrLSDnpGnndIa5CkVd1fLuCRGzxI5dNvxXiLyxKuTd2LQNxhhhT/mW2VQWZ90+d/JHnz29+u1oReeVZoxBVfIMaTTRx/6dm3mFeaGXO9qqk4zL+7gshdHVuMDO/hStFONBRVUUufEjYQDGFCQS82aGd213kTKwGfF+EbBiC8tsNiHExC6bKJSA/kWBMYbhcMzq2gbjlVXqDKKqfK68UvjYACEzJMWuQWuTwU7XN+K6YS3ccP0Z7nhNy1Unp9z/QOLx0wM2N1dpm+M8l95+lx+a1mnOnV/j3Pm1/m+VChzamLGy0lBWkUHtMTrQOs3m5oDTZ1YR04WXRjditMxmL+rlOaD46Z/5Xr73bZ/m0tLy2NFNzp0/+owYRm07R6MwSZrShw/tkRIc3Zg+6bPHj27xg993Jxtre5w8fpGzF1bY3qn58oMnefixKzh95ijTWRdk8fwBJE+c2uCv/LUulVDmy8m05Md/4ruwNlFYkc0ZozhyZMIfe+0p6oF4HJ16YsSnP3ecs+dGzOcFBxfeLyTIk+fbb4qxDMRVeF89xee+Wc7d1xqKGAu2tjfY2t7g7nue2U9rHSiLOUUxoyhmlOUcY+W/N1x3L3e85m6mkzlnzm4xGlRcf9VxNELW2NzeZWtnPyNAAUVCW4XKNaVr5uyrRNuuEUNiv2kZFwUJSYw2ugukC7JWS6ZfOwDs7O4yncCggMKoTCzQ8s5NwuxY9jzW2vSBN0qp3NxsL3/gyJrBlhZsyfI1DjH2/qeyXU1ZLiT4RoO5zC3RrdmehK1o3dfT6QCq98xGTyYBIkvdvM5q5pkmWeZRVgVHj6xz4tg64UxkOjtoKSTiTQHZEjCZNWysreDbhlOnniCEwOEjRzDGcuTIUc6fOyfhbyTqwtJ6R6E1a2vr7O7uc99993P9tVfzmbs+wW233goh0M72UUnxmpuupfFCbmgax2w2ZT6b4TsrJyNHP93fZmdnm4cfeZyjJ05y8623orQQWWxVUQ4GEqiWg7MWTde8/o+yLPa/HzzCuq6z0eIRFn0kmkhMoJQV2miSR+DQak3y6cCc17OtMpIb/JKpXq5Mei1xWoBO8s9JTHxTwMdsfm4rBlWN1ZbgHVFQLGF+ZbCjsIayLKTDne9rn7v6hkwdzYbHYkKfeupnSvQMgKSWpIpkT6+UjyknpYmqKHu6ZL6R6kAtZcVw3ypUilK8xUhIKcv/VN5H3bPXAJQ2lLlo6gCoDmQB8QdLWdKotEZrQWzbZg4povO+yQGBc4FZ26A0/XlRKUHvubUEjCFsvQ6A7IbRhkIX2MyC01ln9SRmQb5u4ilUMmtajNHSqbCG1gns37EDVf79IsWSnnHnXKDInQhj7JM6D6Ywi8kmP6TeiaG9tQsQc9o07M9npCiMhYXRY6KwmqLQkhzZONHy01LXNatra+L7o0T+aoxhNBqxMh5RLunkOxZgVVXU1QBrNDMnjIqtrYusrK5y8pqrqeoB64cOZT8rx/bWFjtbW+zv7tK2bZ/YJkX+ZTzAyDG3KyscP3k1R05cxWi8Jmw61zJpWxrfUNqSNjgUEaUCRgcaF5nPIsF58cjKCTs+BB58+Dj/73/5I+zujS/7nc/PSKyv7fOTf/VOXvfax2iaOZPJHufPRc6dPcNk5jly7AquvfpqxoMhUXusjgyHiroybO1sc/eXHuRjn/oin7n7fnyHmiYYjUZcf82P8/jpt/OxT1z1dUoPEldf/QmGw/+KX/mVf82pU4F/8k9W+dSnPsUb3vBGXvWq1/DzP381v/xrfxzx5/t6Fn4JrSNrqzO2tuVaKBVkwbI0/i9/5B9x1Ykv9YsGkyylKajrAWVZUJYmy/8sVhs0CaslVESzAGGcjyhrGQyGWGtpW0c7bw8wl2ReacVg1kuMt9I68yoXn2udz6b7Ml+5vAhyQaKmq7KWMBHnaZp5/n6PVorSWqqywJpSkmliIqnUpwaCBK0opVE57CQse2EEkakrhCIeUSSlcqqSLBiFBehIOAHOkwAnIThU9BiSdEnz+0lLLDBaKbxbXM6yKgk+UtUlIUZ53jUQPM4JqB5jAmsoc8psCg6X9y+F1Ms8q0FFVVcCdGlN41qatpHUtmaegSoJs6iqgYBE2ey/B8qUyoEpARIURph7RU7dbJfmcdOHwywY17awJLeYQ33yPWM2+JC9FSUZmcjSvJSISRhmIb8TO6l7ShIpLvOxw7e+j+/u1pnWiky0KAqsLSnqIdPpPrs7W7geDCPP64trHaKkVzo3I8WAczBpm/7f98qS/b1NVlfXWT90lPWNoxgtDMemmbOze5HJZJ/RcAVjSgb1IDc0LPVggLEG51wfGmCMZjqVUJIf+P7P8shjj/GeD3+Rrd0pBlBpRHSH0aamqIYMhieI8WXs7l7JzuZhTj2+TtsOFzfQc1QQpmTY3BqzuXW5OVzOpTUBWwSauSSbvTReyJE4fGif/f2Kpi3ROhLj13dNQrD8xm++4Ul/f+01m7z8lvP87kdu67/zq91/WkVMYYiIX6ZCS8yEgiOH9vgP//KnpEh/ik1cdcUMlOat33GaqCySfAuTqea+Lx/m7nuu4L4HTnDuwhH29oY8PwDZYvtnzx168j/fBx/+6NP7+ZfGMx1f7dxlFUrXoEJ9jc9/s43FsxSjYd6MmDdPZpYeO9Jii/twMWILYdQrDa+47XpGwwG7exMhR7RzTp+7yOaFC0znDZNJIwnmSWONoWkannj8FKuHVnsOU+tbSltmRY6wnnvvbMS2RRlDSuLLHb2w1rWG4UBhjM3vetWH8fQheM9A+5ZItI2nu4YhBEnddC1VaRnVA6yy0H0EQBVixfEUo78vopJGavddl6qa8t+FsCBv2ML2+5/tQfNRisivxxdIB++6KPZJ5nIInXy5rHflt8zjogmmlWJ1Zci1Vx6lsoYLF3fZn85pGkfwonIqjaWoCpTRHNlYZXV1zObFizzx2KO4ecPhw4cwWrO7fRGjFNddey0qBp549HF8COzu7XLq9Fm+8tCjrK2ucOrUY9x0442yzp5NiNnDumPxxQhon09Fh7X0h0LwgaaJBALNIw/jvefGl7+csiwZjFfY2DjM2dOnme7vY61Y73wj40UNhKUIw7LCEpm1c9oYKQuDdw7nGjFTthXDsmA4WhHvHZ+To1AHqIydcX5hLJUtMabIyWCZ1aSg8b4HWLpCrCt6EhL9bnTufBcFMbMSWu8lXSMDYVrLy9zNhTFGZrYJ0JUN5tGgE0pHdFKELN9pmkBZ0j+oAtrk5I3O2wqFUmlpvtCkFHpQUOUFvLYdgCMyoxSTpDlGeaB0BsC6wqRjyJncpY7Z3A6kQFMotBEAKSbVo+QxhJzGFrCAMfKQxgxKFUblOUWTUMzbufjFGOnaK0X2Cov4zADrhvhcWdkvlY8tA0SJhIsud/dt79WltaHNRWzHFum8dtJlJlm19IQmyH5CiRmeurZi+q+XHqWlTkZ3r0QfJa1RqwPpmNOmYTJvqAuL1eI30/m5oVLvkaaVINwJaNqW8xcu0DqHCw5bWNFTF4sEsk6eVJcVVVVn8G7OdNpii4L1QxsMBiM2Dh1iZXWN6XQqxd7uLvN5w872NrPJvly3FOU+biXBK0SYNy1lUdA6x/rqKqsbh1lZWWF94zDD8Ri0yN/E9LEToydQLdoklBLpmG9yYl6mUiulcc7zmc9fzT//P370mUwHz/KQ/f2RH7qXP/9jnyMxY3dvn7Nnpmxt77C9vct0Nse3nquvvT6zKhuGw0qMtm3Nw48+wYd/71Pc9dl72N7b59ix4/zon/wxXvvaOxiNVzh39iy/+mu/wy/+4l+hC5B4Zvu3KGBfdfs2Dzy0x+999CP8kR/4QdZW1/jA+4/wrnfdwWw2Xvrs1zskxeim6z9PiFOuuvLTbO8e4kMf+YvceuPH+d7v/Bmsmff3vDB+CqqqZDwcsjIeMxgNKcoiG5Iviha/PyNGzwGmn5aEoN39PQHcQ6ALpAgh9FHhKgl447yjCUFYOvlZFjaXAMWzpqF1bZaEszAeBWjmqJRBmxiYzqaZBaUk7TXLEruFjndBfO0yK8zmCHB8BKURix+V93mpk+gjIbmO+IUCSe/ZvQBAXdcUXWR0EkIzUUAqpClL0gk08jldUliYzYRR1TYtKSZcK3OCQmEKiy4LTB0pOx8FyHN3FFljEjZpyN9VVAWD0YBhNeylhz743rdMKwGdpCvrclpyQVEW1HUloJWT+c9qi1Ou34YxRlIZbSGyV6tpG2GwKa16pnN3bo0Wv4zO91HuhZilrTJvi0fnwbvVB9+z+lKUFOiOnesygCcvicDGqEIZ3XekNfKOM9oQg2eyu0njXAa9Ft1plKKqEsGnzKSW7GmtIklDVRmUsoDppRjNbM5me4HdnV22NjdBa1bWD7E/2WN7+wLb2+c47VoG9QpVNaAsBuKlWFTYDCRaW/TrDgH1It7NMMlxzYlVbrzqKFtbW2Kc687Q+sRwdY2TV8P64Tkx3A0hMigSJ46uct1113L+/Hm+cHfDr/7qW3n88Svxfhkwfy6LwLz+CAYfvhYrLGGNw5hI0xa8xCJ7robi4uYijOXrBcG+2vjkXbdQVS2vf91DfPKu68n0TZ7yXuuk81qClFKIKC9J1sL2DF+1Pu4lM7oL/JBjWluBb3ntWV572wNgRvJeUTVWOWJbcNc913H/l49w/8Mn+MoDx+F5AWmffB5uvPFu6npGXTWAZjJZYzodEYLh7LnjOPf7LVTiuRwHfaueenx18PaFG5fbp8RgMOGG657gxpedxhSKkyfPcfjoEWKItO1cmoRty3g0ZDwacuLYUWbThtNnNzmpSoy2bO3sUFQNbeto5g31oEIpxUMPPcbxK0/QzBoOrQyIfR0idU1nAdONsiwpqhLXzkmxISK1dIySSt318rXWVFV1gMjQzRRPOsK0sEHolTATj9KWZRN7rRR1VWY1z0GVVnf+wiUN3taHA4QQ4VB9jWufpE5sMste7JryPZMPYnkt2G1OKSXN1eUUSqUzI+zy35oO/O5gBmdIMKgrjh1ZxRgBxfb3ZtJ4zP6xdV32Fj0nThwieFhfH9O4ltlkn8neNocOrXHs2BHOnj3HO9/9Ph586DGaeYPWcOWVx3nda26nKktWV0YYAtvbW9SFod3bwrXzxR7qkvQU0FNKCdd65jOH85FoLCFGzjzxBNZarrrmGoqipCgrsS+CA75xX+94UQNhJEm9GA4sRUHvJ2OUABPGmGygL7ePVrIQDlnW1ZnUK4AINmXPLG0zK2tBVSQpjLYkYs/C0kpTaItPHqUVvouPVQqVdGZfZTAJeuN8laUkslANOdELnBNwoIqRsqwwWQ6iogBbMYqhvrWaqFKPjifVpVek5VOTmWKZ0aaiyPXkTCA/qiQSXpFTJjtgbSHny0qk/vPAAcN9KXAWHRRYRNn6GIguErNhojHitabpzIOlsHCuQdkiS1gEDOmCBWKGzKNC2A0pHYjH1R31VknIQdIL0A7kHHQFk1fC3NPGUJQC4kjSlxRi3dnrzBOtEhqwHBy5ApTJTXx3xF+oMPQTZP/ZsJiYxQw55pSwhGoUTrnM5grileVFcjisasoiT/ZLbIOYE0kUUrCfOnWKra0tMRfc2WEwqKnLgsIajFZLE7akTKYYqQcDDq0dZWW8ymA4oqpqyrpkMt3n/LmznD1zhu0t0W9bI6bgIvMNTGctc9dgkMQUpRTjlRXquubIkWOsrh9iMBxRVmJs3RmMpxgAT6kT5cjkuTzQNp5mPqedu/6c788q/vW/fwsf/fiNuKektD/XI3HlyYv84//xdzhxdJe9yYSz52bsT2acv7DN9u6MeeNJITEcDrjqumPccNM1HDu8Ql0gQRBJ0Taej3/yC9z34Cle+y3fytu++3t4+a23cfHiRR568AEeeHCThx76Tu688+08s4KuW3wpyjJx/fWfp53/C37oB27m535hjV/5z1v8r//bBl/84i/xbC3SxqMdDm+c5tDqKW685tNcdeJeUGCs5i3fcidKdXR2m0FPAbWLwjIc1AyHA+q6YlAPsZmCrlQiBIf3jnnwRNf281dIAiz47F2QcoCJVloWFk1L07Q450hIklAbHD4zwIIXsCRlMMVHaTi47C02rMqeTRtjJOpIqQWc10ozqAcZOHaEzCxTCHDvvFsyhl00QnSmbWtjUVpANE2isCq/cxJtSMQo8eGhjGgNczc74JkFmeFpTQ/+9JTvmMM2Sosthiil8clBCngvn5GGTgYMU2AeIkqDVQLsaMQAt/EtKTgBFUOk7BqIRgkTKqc6dt6GcDCRSSmFy9J4jcgaikpkhConBlsji8UOvOzBw056qXRmzNG/Z8WewPeg1XLoSXc7L3tVxhhQVvVS9O6zXYKnhCvkRkduaoUQCG3o38+FlVRMmW/lvSfMQSef9wHv3SINV6n+HBdWUZUa55OsN5TCB31QepGTNFV+n3Xz4myyS0QxnU2EGeglcbLUJWWCdubZ39mUxp1SmOy5aI2wyq01VGWZ/2xJYc4Vhyq2pokrrzpO07RcvLDDZNIS3Jz5ZJe0PqYoKqJyGAPRNfKuCYErj+3y137iVykLQ2lFLhy0ZTC+iro6xDv/c8XvfuQEp89cwUFA4PkqBhU+lE+yIZCR+s+8NF4co2lKPnnXdWgdMtj21GBYjIrxyKDyMx61IZoBZMWBCr5nTUC3qcweDYlZE6gKjdV5rllWCCiFLjRaRSyaNjWMihmU8B2v/xLf8S3C4g3SHcbqgosXV3jo4Q0+/plr+NRnrmZ/MnwWz8yTj/8rX3nF0p8cw8E2hw6d5cjh06S0x2y2StMOca7Gu5L4dYUILJfPL+Rz1PGKvtmZWN/M+3bpUMxmY+6+9xbuvvcW6N/pgaNHdrjllsd55e0PcO01mxza8JTZh3oybcUHqrAMBjVHJkeYTKfM53Nm8yb7sgZWxyuURnPx1FlO3nE7px1oK+vBmDQkD3TrLUWMnhCEUNGtKjqbnWVj+UvBjWVSwuVGt41EwjVOiBomM03ysKWmtBrvFY1LUCzJGZXAT/oSSV1YslSSs6ny/8tcotVinXRgf+hqt0v+vmODpa60FN/m7vhky7nx1oNglx/LyrCnGoO64orjhzm0tsK8EX/czs8thojN682isGijSEqabMElEpadc4/zid/7XUaDgtDOufr4kCPrNxKTqKWqqsLHyHXXX4k1moubW6QY2A2O2riD10vFHAbQnfLFcYsfq6dtHFFpMN3fNZw59QSHjhxm4/ARVlZWWF1dZT6dErI1yZMBzac/XtxAGPkGTDHL1FRmD+m+MOlPMNncPMrPuBgI3kNMGLou0YKYKPdfZ1SvD3hzdAvxoiik4MoAE4nes8rkh0NQVk2ZF+Z1WeKCAAGdsTF0FMqQHyrZd7LJu4BZ2etLiX9UUlBajYoKoxQ+LRVCCUBuNqMKubHTQi4UUiBpgTSEbZCIKkcSp4Q1hfiaaE1CfFtUUmhMZpMtisiwdF66rndM/ZZJUQraGCIJhVWSUNglNcoxaUiREBw6CWNLvkctbTuRCMJ0MJmRF8j+K1lfnlSO2V0CtXroXc5LIKBTBK1yByJ/Pv9AjBHnIg0tVgv112qd09ZkQdSd60IpMXWMYGMu+KJI+2KUwkomu0jUXTiDwi1d8+4+bX2Tz70UrAr6wmt5cuxptSEy2Z9QFJaN1RWGg0qSyjKlWDTcSDpkWVGVNcPRiJXVNVZWJH1wZ2eLC+cmbG6eZ2t7U6SX7RySRttCCtUYcdlfSSlLBDbWNyiriqNHjzEYDhmMVzG2JGpNk6uU6D0kj1aiJZfaUeRJ87mnmTc0s8CnP3MNk+mQ9/32HTz6+AlemMWFXMS/8zc+zne/7SHmsxmT/QlPnJ6xubnN9vaUxiWaNmKKmuPHRxw9ts7ayoCrrz5OTIH5vGE+F3Bkb2eHQ4eOUBQVhS244cabeNnLbuA33v3r/MzP3MNjj/1hLlz8QVJ6+mDfePQgs/lVhFBy5MgWIfxzfvO9f5bZfIc/+aPn+Nt/70+ytf1/5dliSZw4dorbb/kcb7zjo1TFHs610oXXCmsq6rrAWiU+RkYTMxAhz4+8aItsZKozcBBSIrRt37XzbUsz36edzzKgJDC9ULyFKt+zelIgBklwlKjnFuc9kSCy77QAUZwTgIfcAPEx4nLKbWE0Pif/Nm0jaZDWUg1LClOgkPTWaU5CMugMgAlgJHOL6sgFxJSYzQVMqKsSmxLaiO+iSpEQ5H0k9C5DUgYfPap1ksiYARMJtygpi5JAJKRLFl5Koa3G2BJbDAT0z7HdigTRM521AvIXgmp57wheRPGF0hSZ2ZwQ5qvOBqVdaIl0IlVmJAt4pUzXHNIHkpUUUJUFMQxIPlKUhTCItfh1dfMmgNEF0dg8/y1krVHF/ti66+ycw7Wu7wT3qZWRA2m+Mcs5VMjzo86NrUgvjQcBD4Ne+Ir1DZJ8vEopjBVpfcpAZ7du6AC02MWjw6JG06kHw5QCaxQUEd8EuvTIrllkjUg7umZPzyb3Aec9zWwm7HSdGJYjyIBYUZQopUWaHgMpeGIK+KgIfkqIntWVDUpr2N2VqHSrIyp4ZtOItkZ8U6008QaDEXU1JBHQKlBZWY9snj0Dbcu4LkgxkoLDJ09RVIR2xu7mA7jBWV7/2j3e/HrN7a+6lauvuZIYE2fPnuPU4w0f+nDBu37jlZw+ffxZmX+e+XgxFaUvjcUQpvHyn5+SadM9g7qzl7CZfWqohhZNDj0J9MqElMD7hLLyLPbyqn6FmCtRZYGI1WB1I3OqApNaoqoIKMq6ljVZ8hw7ts2Jo5u8+Q0PoJTNDYtI0xQ89NhRPvWZY3zkzpdx6swai3fys3WPFkxnR5k+cZTHn3jFU35KqcBwdJG62gMSTbPKcLjD2tomr3rlg6yOj3LvvTfyyU9fQ7hMYuXaypzBwHHh4gAfns9S8asBYC8B3s/OyKSGYDlz9jBnzh7mQ7/76vxv8pKrqpZjxza58WWPcdvt93PlibOsrrdSJzhP27Z4L81M7xxb57cIreOjv/17XH/d9Zy+sMfRQ4NMFjDScAoBEIVJyG02myWTncWRwmCX1FoaYTU9ye4p18rdSCqRMkkjthKQBBCVPUC5iiGBzyBUCjgXD24TesC9O1XShF1a/3TTRq7JOhWAfgrASup7qcsyDeVAfdv5fHe3teqOXNE33hbX5uB2vxYIBmI7VBSWYV0To4CNSgl2YHOC5TJGkJCAoka1kAJu6jg8lvVEVVSsDI9JKEJaNAW7sKuyrBgNalw7y8KL1B9X8IEUWtARFX22RtEUxtBkAk3M6jdTyJrXe4drG7abGZvnL7C6usp4PGRjfY3J7i77u3vSLLxMWMEybvPVxoscCMsjQWkr6TinkO+dxSIVBJixih5Yim5OyrrVpA3kIgG6mysS48IgHqX6jrPBLBbaHeNIJRrfsDvdoXFzSWkEMVrPhRcp0cwbXAi4fLEvHYrFzd0fXpaGFFYLZpQEDLNGLz0k/QpftpPN7V1oUTGiVOz9vEigrEVZgwp68fm8j1qJPFNkkl58VpI6MBElxCOsW+xfcjkWx5PTvjrA0vuYH8LFZ8qylKVPBhxFqghKmZ4VoJCJzWTpkDEKlEyYZWkEtIsJ7xIpSoHaDZ3yn5Uwt8Q3yC3O81Jx5EPAtS0+BKwx1FVJsgK+WW0gJmJ37ZUSz59IBgoVPiR8kPsndV0IRU64lMmvP2NKkkerwhJiC4g0q/UOqyVxVCuoyjJ3CMQbxmpLUZTUVUVdllS1FaqxLaRAzhIvSQ0ZsLKyxsp4laqqaOZTti6ep5lP2d6+SPCethWmVyJRGoPSFqMVrXNM53PmzmGKgo21QwyHI44eO0FV1VRllTsVChcSOgml2RoF2uPzeVRKjLfJfk17u55/+s9/iC/dd82T7p3ndyROnjjP//7P3s3KCoQQ2d6ecubMBXa2JzRzR4wKTMXKSsWJ8ZDVtRHr6yPK0qJUYn9vl9lszvmz54gxMhyNqKua8brh2utfxgOPnOLBB8/x+BND3vGOP8UTT2w8oz182XWf49WvbPjP71r4rPz8z3+RH/3Rj/Ln/8If4b77vh3nvuNZORtVOed7vus/8vKXfZbh0IlBfWFQFJSl7n2ZtFZUgxKroSikc+hwJK0oksaqhPPih6C19LV8iCi3JEd2jvlsTmwnksjn89OSa6CU56tlry/vI94F8bsKnkgUEC57RTnn8N4TY6RpG1DiySWekTkARGvxZsiLMe89g8weHo+GlLZm3jb4IAb8KYlxrMsm7ALmiBdY16XrGyVai8Q8+JyEuVhwAJAbHEpr5jkVN+X5uLAiF9RWwGYVHdKYkLnZFBZbllhbi+9ijLi2IXiXDWYVRaFp5q5//9nCEKI0JoyNYGRu7BoFAXkvKaN6aaTOC5oOCOvA+sIIMB5SQKUFo8sZB8ZgC9szxoSJLYsiVNf5TLkLujDl17m5IAsy8WjrGLTSFAJl1IF7oPt8WZZinh+FiZWW/gdSM3cLS5NZzzZf57IoaRoBjow1GGv6+tt5x9zNxRYBtajLU7dY1XIcPoIRdmwH8KUWsAtmuVHZo1QpSAEV5Z2lcwNFZcZxCgnvHcYqdGY/yn5rbFlS57lGKxYL1fyrsBJfrrWidS3OTwluxv7cMVoZogg08xkpzdnfPIuJe6jYUlkoRjV7YZV9JUCZPH45KKAopSGVJCBhPm+JITEYrrC/v8eDD36FBBw5fJTx4CxvuGObO171Jbn/icSguPuL1/Nr734jZ88d5cmSspcK2f9yx1MAWU97LBd98vuqdFgtwRhJZZuIlPjVd72C//Srr+If/r33cfstFyBpkgWlxHtSIQX0IFlZv8Y8D+W015ggRY1SRhqjpL5xB8L4T7SAIuQEXqUUUevM9ggYU/Ts1MI6brv5DLfddIY/8yOfy41xWW/u7iXuu/8Yv/nBN/Dgw1cwbyqeS2ZlSobJ/jEm+8f6v9vfP8a5c4kHH7yD8bhlOEi87LotVsYNZRmZzS3nzg05fXaVnb2anb2aqvS8/nWP8ppXnuXaq3e5/4ENfvYX78hblPTP52+8NG8890Mgnqapeeyxkzz22Ek++KE30r0IB3XLyuqUw4d2OXRoh/F4n2G9x+23f5G62sO18i4rK41LitVjV/PBD36Q73jdjZSFRWnD7v4MW0bWRjVKGRSaouj8wAyFNQf2xkcJB1qGQfUlwJM016RpmlJEG5k/WnUQWE1RMdubY5WiKg0HbXkTWgXQCwDFKCXJmQc/RsrrA5U6R6+UVU0Hz6X4ZEtdG2MilepAeJvKQNpB1liS9aU6sCmWJZmX4gRLP5n3L/VAkIBUigKba/Huu+kVa5HYB9elJH5kzsPqyhClFINBAVHmSBBQK2T7j+6bxXpkTnQu2yCZAwcmYGCLNkKQsFqBNXhvevhba0VZFXltpqWZ6x3z+ZydrU1ccwWrK4dZX19jd3sb17YHmrTdccna8/cBECZsFd9Hs8eOgaMEsUV1L7tEaiD0aWSQQoQDN9HiEVMZWBJWz+Iz3cnuJBX9T2YDZY9nmqY0vpFFtzKYpKQT3704O+pmXGha+278ATmIgCkhhFyg6Fw4SFFJEt2yYgH6dAVQQm6EGIJ0k3HZ60seDp23L0yoBevIxIjJxy8shoOouBSF8rCkJDLNGBYPGl3hsPT0dscTQyD4SAjyS2VQUhuoqryQANpmjk9J9MFJEH0pYBVaJQE6+/QQnbene0kWLHDB7tq7TqKiNbozqr9kAumK6e58xxhJWWfelVfLFE7yeRfAO084Su4vrTRJmQx8ycQhE5I+MCmkJKl3dVn1rAOtFc57lC0obUFZWEaDIYW1aAzaWIwWD7mytJS2YDQcSEiANhibGWBVlZPRBDgM3rG9tc/e7iaTyb5IfYLvgcGUpAMQjUgNfJTzPFpZZbUoGQxHrK8fYTAcUtdD8ajLGKJRCaMjOkN8WhlZAHrXewWRQUMfIu/4V299AUEwYX/99z/5Xt76ltP4EGlax9Z2Swhw4fw288ZRD4aMxpayLBgOa0ajmrquqAc1IQZ2tndo5nPOn7+Ia1uUVhw9doyjR48zHI4Yj1eo6zu4+57X8O9+6Y3Zc+fpjSNHZnz3d5/irrvu4ctf/gEefPjgv/+JP/EmptMPcPfdz84ZOXn8XfzxH/gIdXVGjLiNxZqastAUpUXrzMjK0l6Zp4TRVZZDeezzQ2czAFMYje4SfDPbNc7nC+aW8zTzKe18wrxtmXspSmT6SISOSt+DYcJMdI3DObnPBsMhZVEymU56YGMhR9M97dx0aTN53pbmhci1lS6RhbyiKq10yIyAC9aKP0EbA8m7vA7MzRBtSEiwRydHJM/x3jmSEstvkcNJCInKoFZSImfvkn21NpIkaQyh6zCmzLJjwVxSZKZoltbF4Aleki8TCVsYvI8SGpBZTTG/D2IQlp0xEpbiQqB1ntJmthIZ6MnvtT6tMYjfmzFG5JLJSCJn2x5gVAEZJNV5MaNzc0XuMZF1C4jk/CUR5yoLAVKU77FWbA6M+HjGJKzr7me6AJOuMdVJILXSRLW4B/r3YseiTVEY1MZQD2rxmFOq98lUemGFoNVS4EpeSygUSWWOdGY5h5jEs6g7mKCINqGTQiXV2wiEGFDekdCQF/5dE0trRfS5wdbJIRIYJeCr1sLS00b1+6Ty/WONlWYKpXTog6dQ+wzqCp0imkhyE7QpSH7KbGef6GfEuqRSK2z7Jts1ZIYhScJnygFzuw/K4JSACIOqZjyq0SoxnU4Yr6xSliWT3U2qwmCVZdFXSrz5Wx7iTd/yEHGpgMlXnIsXx7zz19/IXZ+5Ae+7VK+Xitz/UkZhW5z/Rn2rFoDYaNTQtomilHVUt8z82CevZmd3wN/4Oz/Ad37bA/yNn/gIo1FEJXmStJK1qenmgJgl1GkByqfoAUOKkrDrE6QQcgMhr++BlHz/cx1To6sROgm7FPJV/5xqbbEmUVrNoIwcO7TFt7/xvTkQSJ5X7z37kyFfvO96PvbJ27n/oZPM5p1h//J5eLaGIoSCnZ2CnR2ArxZElGhay8c+cQ0f+8RizaZU5NChKW//gS9y7OiEl127zWRW8Nf/1g/wLa99hPvuP8befrfmeem5/i9jyBw9m9fM5jXnLgl4eNdvvJVrr36CkycvsLG+xerKBY4e3WQ4nnDtdddxcZJ47PGHcQHm88DJ44e44ZoTjOuK9ZUxJrP167rMa4LF6IjYsACAlokrZPIKiOF+F7SWUBC6Lal+WwZh7PugCNiF5zYJEyImLGp9bSTUaRkvkNR31b/DVZ6Q+mZu3lpH2pAGbcC5FqUE6Ov2XytpAkd96Vsyr0vUYv8Dpm9EdnX48mc6KwvNUh0bJWjEKkObPKUpl97TeX7UmaiRgbGOTQfCvrXZ89c5R+sET9ApoQ4ATbLe6QKSxE98sWZZnJoknQgFxspatw/Q6+qHUq5J6GSluUm7v7fLbDpFcZjBoGa8MmZ/f5/ZbOFBdkA++9WJcotjfHof++YcwuxpKXSB07IwF+PiDOSkLt0w4tqELRJlIdK1ZVBDafGuUhmwUqrr8nayuSwDzKBRVdb9z5osZfPJ9w9k8IGQAkZpalOKdvWAzEVe0CqDDl3a1bInSu9fJkjLYl+Vyr5YIkHqsKcOLIq9dEeOPcSI626m/FlrDDoDPt026bahJLGSSx58hbDRQqT300r5fgYWiHaGo9MlD7FSB8EnOVUhy2lykmTKPiuFIqmYE9VElmeSQhtF8B5jF9sOIdC2GeTSuaTtgcxcgOfivSrFuPipRnf9xDOioDCZkUa3iDooBfUh5gk0kLzH5rjgsihAaRLik9U6L9KvBOYS+qbcs5ZBWfdgFCgBwWxBXVaMhyOGgwFWG0IE5zwpQVWUlNl42pYFtiioq5rRaIWiKDNVv2Uy2WOyv8d8NqGZT/Cu6YG9qAR489nQUWuD0gZjS8pqQD0cUw9HDEZjBoOxSGfy86BV6kEw6cLIuW5baFuXpVkhg4vwkTtfyTt+8W2kdEl35XkaJ46f4x3/4l3UtcG1LdOZ48LFXZQ2zGaOsiypygHHjh5lPBoI09BoTH4RhJjY3tnn/IVNmtaJlt0rhuN1BnXFLS+/jSOHj/Hhjx3m595xlN/7+OrT3jdrE298w6NcuPD/5E//6Wv4uZ//mzz88A2X/ex0+vVN20p5Xv7yB3nZyz7F+tqnue9L9zHb/zJ3vOqVaDUWIFZJx0gaNZrSmuwZ0PkQiuVCM531IGcHXqSQZcdK9Wl4PkRi60g0iExRGgwS/CFssNl8RpsZUjaD/XMvBqqqn1cEnHVBnqlSSXy8NEMklES8ysTrwOZuUOyYpRk46LpdMYEyBRrTH5vRGoWA0UmRGaoh+48FxKdeJtGYIj6KZN2ngFF2AZZrkQAkrYSdmWJugAj7JyLbLotSXvxWuqQ+IZ56KeFd2/uPmTyfxxBwKYdPpNS/x4BMd09YK0lMIpHvGhM54EOBMV2AR+7O6URXrnaMue6d1LFlgw/5GZD7zjlH0zTy7usaC1Ek96pYLAz7xQ0dS8wKQyp/R7cS1Er3TD6UhAb44DGFFnPrqAkq9LL/LkwkLs1FKSwSnZ9033fNrdwIWgbcegZZvo+VUpSq7IvbS7eDgqgy47ZrAtG5ecj5UiiCjqgo92zoI+C1gKdKvL66RGVrpAAPMULUSEx96u/7FFMf0S77Lami/Xoj+CxZzs0Ta9BEUI4Gj8bJojXOJLAlCZCakrAKuyWvNvKcKKNxzZTgQNuKVK6QUJR1IYmkWX5sjZUU5+keRT3E2qJ/1pYmHTzLDi1yxq68KvJf/8THCeEjKKCoaoL3nDm7xoMPHeGuT1/JPV86yXQ64CWQ7MU3Xve6hwle88m7buAbv3aKY0f20SYQokFpeTZ/58Mv494vXdF/5kMfuZEPfeQGThzb5a/9Vx/hW159FqvB6MWzqxDAuyuQpDltIQUp6lKCaElG5lyblm0zOiYmZONhlBLpfAfKd/PR4pDzOjoGKaZV9hc2wsKMSaFUydoqnDzxIG/7jgcJITBvXF7jJ06f3+CeL93IJz/zKh5+7Kql8/KNMu+e3rm/3EhJc/HimP/zHW88sD/GBL547wkGA8c1V29yaH3C0cN7rK7OOHthxCc+eT2te6bBQC+NF8PwvuCBh67jgYeuO/D3a6v7vO6Oe3nVK+5k9ZCE5gzbQFFV7M4C02bOXhNzyJRGW824toSYGNWlhKotkTJSSqQg6i/SknIgRrSKfcBb93SoQF+PQn5q8ru3C80RAojU3yZ1tbcA6EY6wQfWAz2pJaaMN3RAFAe/p29cCQurC72LKfU/E3NzeDltHKTZ+mQDeLN0LInOs7xbF+mudifk8J4o9ISU8ppeZQLJAkzsVAApH4DgCJ39h+rXT0pJg3QymzGsqqwcO1hPa6VxuOzDLmstvcR6Xa5/F/jL4v2uFAKCKQEbQwyLo42R7YubbG9tc/z4cYy1DIdDqrpmPl+kc38940UNhHV+SqRsMJy71jon73WMlRgSTSMm51p1MaR2AQBZYdmQO8Ip059iflCWNbjCLJDv7TpAki4lD6TJXfuQFqwn2S/Td41ijBQKQlLycmXxIu38WrpCxFq5cTsfLGlEZS1tBqS0gtJK0e47ujfy8PffmSeL7sY3S8XIAuwR2ZAPEVyLWe7os0RLVRm0yoheZyZN6gAvMkKmQC+8gw6O7N8QPKHxWT4pIGRhLUpFtPK41IUgGIrS9KBhT/dYOqcKSZ+MHXAZxMg/ZJljSuayBc6T7qscamCMeIQZKxp27wNuyam3R+RjxCeRJFVlKSAU2VQ7nzStLu2KL5gMKJaSLzVlWWCMxWAobElhS6qyzIh8YDZvMdmgcFCWVFVNPRrIxDAYoZSmmc/Yn+yzt7vLdLovrCXZa4wxOO/Fzyx7gClEHlBVNfVgRD0cUw1HlIMRRVlhbCFstXkj2xAhPSA+N8H5zBYkn3e5f7d3BvzP//SHOXPuhfCOkafg7/7k+3jLtz0ORFLw7O9FNi9sc3Fnn3kTWVtbZW11JbO+CtZWhpSlxZju5QXOBfb393n00Sd45NHTDEZD1jcOUVQDNg4fpiyO8q73vJJ3/KuTnDn7tYC+xQL2+LEzKP0zvOMd38Pm5iF+4if+PP/jP7iDZ09u4Ln6yk9TFb/KePQB6oHj0Qf2aY4eZX2UuPHqWzi8sYYxSbo33VlLCWs1ZWFAI8yirvuU73tjjXTL8xwmLBkBcpz3TOYtzkd8nlPEn5A+TtoHST1NMRBJeKDOc/fUzWmDE6DYmCyxjCSTBOCJMufHEJk18+z1Jali4hWQRAIZxUOrmztj6ujb8mx309ISLiMJRmSaPal/qZMLfJXIwSjiOUiCAgHlhalqxA+NLH/sbBtzty4ikdX94kWLtK971/gcbgEdliULtRQTMUhKo0gIZfGYxYP9NVPKQJ+SCCl7PHZzs3TsYl7wCMtXFkoZnGPhY5VCIpC7fCYnRTrfs6ksAm5183s04ilprMLS+c4oOZDMbioskApp2ERhVXWM3I75rJMw+iTdWVhbne8bip69S75XY05tvHR0i7iOodaNLvWy8wPrmFAdSzde4tHWMcSSTv3vtdL9+0QYKPl9mnT+PSKxWAq1lPMv4SlKG5JSvSek8/KdhdHZPy7ktQf9IlVARPGe68A7UOIzlhuBZVEQ5l5YhqlLu0pYnSgLS9QlhbXiq6pUDjQRX7OiEDN+lSQtVRlIusUlI9dNBVonXWbvPfvbFyFF5pO93lfSWEnpksChJZZ7XyzIPZr6ezIRg0SpX33VjOuve4zv/PaH+nTYGBPOJeaN4itfOcp73/d6Hn7kWGaSLSVxvTS+SYbi43fezILH8Y1em8T5C2JGH1NCJQnk+ANveoj/z09/K2277LWpOHNujb/3f//DaBX4zm97kP/mL9zJoXXXb6vbGykRpMkjD1fMHrOeol+vdwmCwtiXuTz1TSGUlaZzB4ShKIr8+z5UKfZG/il3kA+spZd+L4+JYZTBcaU1hw55XnHr/fyJH35Q9imCD7A/Nzz2xAaf/dy1fPxTN3H27CpS0j3fz0IPORCCYRYMs3nF5taYRx87/JQ/Za2nsAFjA95pmtaSkuGlZ/m/rLGzO+a3f+f1/PbvvB5IWOtYXZ1x8orzvPpV93LVycdIxUXmTaD0EWPmbO1GQkiMBhUxQVGIz2pZGLQC3zrado4Lrg9d00BVGKrC9E24hMZosTDo1zRR7HnI66mIw9qSoiyl2dfVvEtkmacaC8/Trvm3YHo93dGtnX3yB/5e2wUJ43Kjwzg69r4okRYqAqBvXnagW2FlraFzM2AZT0iqk0UulAGjYd3Xqd2sZTNBxHRe5svHooUxHzJTNsZ4wLtL1qf0QFw+Af22OwZdyhNsxwxUQIieZn+P3Z1dJpMp6xtrDEcjBoOayd7eATukZzpe3ECYFVlA9BGXi6qqqA6mTbEocEJIeA9lZQCDTlbYVMaKrCUdZC3B0kLaaKy2vRzBGNMDPFoZjEqk3Jk1nWTBFAzKirooxF9KkRlKEZPIemYIQRDa7sKLiftiEaGU1GAd46r328qssYhCVQVaId5ZMTOylMmMpZgfKEGhjZGOdEziRyJSO8SrJIhpfYwBa0VOJOeThXk1XWdNOmLdOevOX1dAARBV9m7LXbIDpzf2CV4i4zNoLYbVHWyktUYljbGFyLRyupZ3LVFFTGEz+yrhs99/zMVnD/J1KHdmyNlLWFlaZbmSVlgrfmOdMbPIN7PkyXvaEDpifpZZZYAghSylDFKsJp/BpiDFX2HJ8/Xi/C0xzjr/G62EWm+0ze6Qqu9C6sw+Uxk4GwxqVoYjhuMxurTMm4Z507C9s8N0MqGdz2jmM7x3AjAW4i9mtIBX3kca51HaMKhHjIYjxuNVhqMxZT1AVxUqG28TAyl6tPZybZSAaN55vBMJZIgd2Kp58OGj/C///IeYzlZ4foec4JXxLj/307/C6kjusdm8ZbI/ZWdrF+8Ds2mLC5HjJ06wvj7miiuOUBYGY+QZ6gDkTLrA+8B0Nmdvb8K58xc5YS1VWfL4qXV+/b1v5nc+9KqnuW8yrZfFLn/px+9hdXw3/4+f+h/4vu97Ns9B5NZbvsxrb/sMN173ebzbZmtnj9294zSuYfyya7jh2qsljEble7ZbsJO9iazFGo3VipCDOlJm5PjQSbY0TevQXgzsp5OZACTAzt6E/VmDj1FYjDn9MeXzaq2AIiE6SluIB19he+ZUyD53CfEu0JlyaozGVArlZDvTZs6saUlAoTUWAeh1linqDjAnh3jk50x8pRQ+gw8xRKZz2d82xMUCS6u+2QFZ/pcvZcgvfEioqGjbFhBZprGW4NqeRdAh4lpJcmpRFBSmyOfZEKKYnKcErpnLvK21LEqisJ20Fil4iuKX6EPKtHZ53xXGyL1Lx/SNlBlgjwvOkmwj5RTFzDJVKWYTaiuJh6Repdcxb7vF0Gw+o3VtD34ZYxbsrO4eMio3qhRGafGYDBFlRA6qyhKFdEdb53FLwTS91ChrZbWRBV6XILQsRep+H0LAJy8NBX1wAdmJ27t3effeVnphR9CBWt0CMPnFuw6ka2mUWTA+IHvZdsxrCVaQeyTlYBmVGXjQwZkpIZ4XUeBWjSzarTXSRIiSZpmiJKH2xvpLyZfd9rQ2DIdDrLVM93bz82ooC8t00hKtdMerssAaw6CuqUqL946yKNDKUFa2B7KHtSRRasDahawtxgYwWByEhojGFAXBNVw4dx7vHM1sArlDrK0w6tCWpDtfPANZBqyNFbCW3KiMEVuUuRipKEoogsXPG4IVpqUPibIOvPrVF3jF7e+STn4CtGY2nfKFL5zh05+eceH8Gzl/8e0EVlgU1N/shXUPizzNzz5Xx/Nsb3vR6f9Gt3Nxa03S55TMiQBaJ/7E2z/NL/77N132e2IyfPDDN/HBD9/IaNjwfW+7jz/5xz7LeOTkGeoaqd1vtfj3tT5QFuLLSvfuy8WaYOA5iZ2ORSJgbAiJ3b19tne2KQrLeDigyv63vc1GXiN3RtOxWzODFIRdozbpzoISyM8Pqncr0QbWh5GNm7d57a17/MU/fa8YUydp/nrvmUzgne95JR+58xbOXdigswB49sfXt03vLd6/qEvQl8YzHgrvSzY3SzY317j7izcu/kUFjh/b5JYbH+WVt32M48fOsbnXEJNmWFuq0lBXVtakwTFvGhrX5MamIgUJgBmUBYURZrPSlqQVYPDe5+aKqMJCtodBgbUFg8GIqqoxNgmLNANhneXDJYeR67bFGuSpjPK7tZteIpYcGHktmaI78DMm2mzxcXnyRtcM7NZly0mMvbe2UhSqwCzJLgO57l8OGuiJJYIzdMytoqj7NU9Mki65MhrS2VmQ6H1du/WTNbYnBslYNPW10cLk6xPLA64VhjnpYJNCKYO2Bq+N6ElyLTGdTtjf22d1dY2qqhnUA4rC0rglILHHJH4feISBvJy8D/ggRYdRkprV0/H6dqr8NwQBkTo5niajmkoR1SLRSilFoQtsuQR+aSNMMaQYCjGSQhBmlDLiyg4UxlIVJXVRMShrCmMkqTHvSEcnFCPgzjMld49iIqWFKWeH1gplIeWiRvTQkmAjh9ZtY4Gtyu9Fpysd4VwKCPCHxi51bUnS+V9+IXceKMoogg59ISkMsIX8pfdaSAI0dqkPsnjIBZiOB9dFHSCkOrZbB14uAWcswg2UFh8WYy0pRebTGdBQqWE+hrwfXr5XZC7Qs+BzsdJ6+c5+N3JXXWmF6RdYUhCiNRlby4g9coaWFi9yGJHSimdW0zhmmXWCovcBIl+zome+KYqyJCnLZGZwvl0q3lSP6ndFT/ed2mg21tep6wFr62sMB0NMUbA/2Wdze5N507C7u4PzHqsUhdaUS1LekEFKFwBTYSkZjsZsrG+wurrCcCDnMykIKhFCk2n9IZ+JgPNpIVv1nVeRMEE+eufN/OwvvP0ZP8fPzkj85H/923zP2x4hJtm/nZ2Wvd0Jk/0J08mcyf6U0XjEsePHWFkZcsXJYwxqYX/J/BAyS6gz7e5kZ7mozFHSw+Eh/upP/k3g6figLACw1dWAcw6tvswv/JtXsj9507N27Ndf/Shvfv1Hue6qz6LVNMtYNYPBgNXVld4bUJuIMVBkUCIpRZu9+7p5TsxGYe7mNC7Q5ohikgAXKUbm80Z8u0JgOm84f3Fb0oScZzKbAgKsd1Tw1osnnbGGqjQUZYEyQUzijWJtOMiSsYRHWIpa08vGjM6eA1oTTMLHyKRpaIPAPJhIhTxzqQNVsoRMYqKlw15lALoD3VofmTZz3KbLZt8CSITgxb/LFijVMdC8ADnZQtHozpsyJyElKaJszzjOXpPZE7JrqJS2lICL7NkF+fnO0vRu3/qCjdQzjFUHwJOy/DTIO8pqAfXzAinFFqOyrDeDLCHPyxnCyYszLVL9vP0O5BKGqjngG9a0Dbv7u4QYsMZSuYqqqHpAyFqLsYbgI60JDEppVnUeYB2AqvPbKOkEyeCC6ZOftdHZb2ohe1wGpWDxHurOm9JKZNh5v/rHLv83ZgARRc/eWF4bdIEH3bFeyggDWcRppfO8l/0ruyRK1xW48j1KJwExKYRpnkFnkiwyu0h1SVXV+CCMbpIlEQk+EVXqgeO8CICkUEkMaK0tqOpBbiAZylLu9dKWKKa0TYvROc3UGknaywvYLgxBqxJtFUolBlUhDTbv8T4z4OQlvpBV6JifgRJrFJPdLXwzhSR/r5Kk93nX0gZh4Xc9MNUDYhJOlFQ2IVaKejCiGg6l+E+K6BzJB1RR5qAakRz7bGOB666jNKF0ushNL9vnuhO/zBH9TsZNyGFFsO1v5N7N7+auh94KXJrU+/yBZEpFbn/5o3zXd97DvV+6hs/dfTXnL6wBipNXnOfU6aP9Z48c2ubC5vrltvJc7uFzuO1vZCQG9RzdhVoBKPjpn30jv/Fbt/G191sxmdb8p197Nf/p116FNY7XveZRfvSH7+K6a7fo59b8PvRR07pcjHXKCVTfxOgB9bRgMcSYuLi5zWe/eB9nzl5gPKp5+Y3XcsP1VzMc1GAkXXgyneNDoCgK6qqkKjrPWuQ5UYoQpUveLfu7ZgSw5H3c/SGnci/Nh+LxWVJX8Of/1Jf4cz96DyEnf1tjmM4GfOGeK3jvb9/M5+65/lm+Vs/GeC7B3pfGN+tIyXDm7FHOnD3Khz76OuS5jFx58iyvv+NurrvuNCeOncUWHqsVSdksDpD1wbTx7E5adJwxqi1lKanltiggQeta2sYRoqz5pHEZqCrbJ23H6FGlRVcFJjOmO+rUgcaY0r3KR2rIJ8sE+8/mmrtraC3q+txUS1JX6UtAGxNib2XRzUGiwpFnw0cvKoK8X511k871fMrfXRiL0YnUx7R1C59L2ahPBuoOsOLi4ju6hiOKPkQrJmkulqZEo/tmlVLlJau3hpjXy7N5y3zW4HJtsDynlkaUUc1slpvPYrsymUzY3d1j47CjLKx4N9eVqE5YNEufyXhRA2FKSqUs8ysA3wM5dABnX0nkmzkpoo+QCxCTu8fdje3xiyIggxaJhNU2y+sCIUkhGJW8QAvTxb/KjVSXFXVRUdmSKj9gvecKCyAMLQ+X1qp/mYYgx9DdlPLwQGHy9lEELw9MYXOHOUbmjbAROkmfUknUKEZTaxGp9AkPHbMrUyu7zlj+T78/HZ3Sey+ds5R9EvL3qO6FnBcSMSYxxO9NjOUq9RPI8kOmcoccQd9BOn0p76dzTs67sRgjXjopepTOyYm2WqC9KWXmmyiiU0r9z8cOMET8t2wHMGKXD10oo32SR6LI6W2tX0xOodOj+46RETBGS6Fhyuy1FTJIlBcluQDR+XzqouiLp7Io2Js2hOAz40T1CZvSoRSWTJUnZW0tq+Oa8WiF0coqZVmxvb3D1vnzXNi8QNM2vXdMVVbQg7qCjHcTrwuBQMGh9UOMRqusHzrE6miIpNwFZvOphBIYhclG6T5ks3Lne9ljSsK+Cy7xr/7dW/mdj9xxyUV+PkZiPNrjP/zsr1CUAopPpw27e1N2dydsbU3Y359TFgXHj61z4sQJDh9ZY2VlQFlYedGw3KmNhFZ8/rzPPnpK52ON/O5HXsOvvucf8uQUtIP7JOPJjITdXWGjwrc8K0d/5NBFvve7fpOrT9yJay8QAlizRllX2UuoM7+Xey7GQIitFLwh0XrpjqdunissVVHR+jnTdsrO3h7nz++yu5dZSioxnTagFJu7E2KIPfNrc2eC0YrNnX1WxyW2hMZ5SXGNiXnjQAnNXWvxAihKS11bFImzRuau4aBkOKhQWT8ojQh5Lpzr5HnC7HKtAG0mz1kdbVsuQ+oBax0lbyclKW46H4loEjpGpvN9VLtgEgs43jF8Yv8MRUT+mXzMTREA8WIwJqJaT0yJ0opXY4gxAwGL/2l0ZluJb8NiKLS1YEz/0kepfhEQQ8gv+ogxipiE0Sb7m7I8PktLZ1OS97SqweeQmB5UATlfGkJoiTGHCVidzVBbYbJ2gH1ORQvB07QNPvi+G9m0DcNKQguUUr28sGPlppjythd/3z0RKcY+8KUwmphZUSaDQ9JYkcVeDIKmKL14nyx3SRfpwqpPk7x0dPLL7vMkWUyaZPD4g4tTDoJhfSFqBMjtaf/d92bpZkwRS5dSLO90Q0HA53WEsE5lH8QfDsD4tMS89ngHKVkBvjKDsWOuSVGuc0Mr4ZpWGN5ROrZlWVBVJbQtPsHKyogutTp6Sf0MQVKsppMZRWGpK0vTNPjghHEYfM+WUyhsWYunkSpwboYpEsPRSu/TAeBa6WgrrSjKEXUS9mjMKV7eedp2SjvztC5IM6aTUmphew6HY/FuS1ANB5RFSQBhkWmT5+mOJZ8gOFYHBa965Y3s7uzj92aoxrO/N8EoRZzMOR6e4Oobf4kf/J7fYO3EcQ5feSWj1TGTqeauT2/wnt+6mfu+/NyHtxSFeLq+8vZHeM2rHuJP/HDgv/3v/wK7e6MDINjqypTX3fEgv/n+Ow78/MrKlPFwzumzhy7d9H/BI7Gxsc87fvo/5jAJsvVH4g+86aEMhD2TofCh5M67buTOu25E3tWR9dV97njtQ/zA99/NoSOOWdNQaHnWO89MYyTlzHSUYDqADJz33Hv/Q3zq8/ehdcH00TNsbu0yGI24/tqThBB44JEn+NL9j7A/mXJoY52XXXcl1151nNGwFpmR0ZTW0rqYm91LUsr8vsi9qH69Ir9iL6UX9km3LodOem+NxniZq1bGDW983QO8+Vse7AEA+VnYmQ65+76T/NYHruGuz11FjNI0f37HSyDYSwNAkZLh8SdO8vgTJwE4ecU5XnHbg9x002McObTNkY0LkpbsPGVR0qLZ3W+xhQYvjX8XpVGfoiM4Jx7IWQEGogiztiClJKFL3uG8ZxDFuL8srDDq1fKeZT+xzJz6WhJKpRbver2kLnBOrC60SpRmwdjsaucQYvcH6Gr2PJblisvf08kJYxTWrM3sNpEdX+4sdwnbTw0eHWgQLq+/FGIdpBcp4ySwpQUnIJk1OqfvLn9jBhbTQspZWIPLdhCFtRTGIiS5rnEZAcPe/h7bO9scnc0o7ApVKfXCvGkPWBc9k/HiBsKCwliNS2T6vRVRXabYdZIMq0ArLwaVKqFVkSV0iC42A0JdTHzUMXuBiV7YhxbwKBVRStK/klJYY7OUUGOzMXTKjKHuIenAmM7DpTMF7nxJMHrppZUPLL/gMn6TpVo6d44lKVOhKIss78l0z4VnWU5Gi5E2iKHgqCwltUypXGR13gdLQABdPH1OkrCmZzmxBBaovDDowDGR2tAzP3o/s3yMIUXiJfenyd5pvfQjintOoM0MP9d762hTsPACAaUN1WBAM59J8RECJiVUlq5IR9vnn80smMx2KI2hMLZnNdVViTFyHwkt3gsA4tsslxSJVRdO0MxbVM9yiZLmqKSA7Dy3ZIKTVLGisAwHFbYU/xWFYj6fY3LyZYy5O1iLgWhZVvi8rdIWrI5HrK6ssDIesbIyFnlUhHkzZ2dnl93dPWbTGU3TZFTcE2NiNt8HErUtUMn0oGFZVoxXNxitrjMcj6nrAcPBQAIYfAPJU5QK8r3WOClavI/5PnPZ+0Jx31eu4Wd/4bs5f3GDF2LxcvXJC/zs//ZuQArQ2bTl4sVdzp7bZt5GZvOWQV1x7TUnOXxohWPHVqlqizV5X1PqwYrgBOgTynQQVmMGWHf2LT/yZ36Urz1d9tAqAFXlaZqn+plLwbKnP8ajKX/ke9/HLTd8nNiexRYWoqe0A5IqGAyH4g+UC3vnRaa7YG0GmtZRWpjOZ0BiOKhpfcv2zg51VRFTYDqfce7iFg8/dp7TZ7dxzqONZu48bUh4J/LplfGQSdNgS40uDCfGqxgrpuq66jrmkUqmImKQZBhtlCzQlbTDY1LMJnOqqmLWBGL0oOUZKwvx7Ysx0fpA28rxFKZAJ82wqiisyU2JhU/gMmuo4xWltJTeqsGWBufAe4fNMdmdTNkH8b+T+W8BkEhCXyAEmZutMd2USuGcsG8Q8Ls2FaUpci9G9Zc8hEA0yxKYzDpLHYNU7hOX6e8LT0w5psJqouhhcG1Lq6AsS3mPFSWh9TSuAQdGWwGYtEFIOVIwuRiEXatLagp29vfyPOgoTMHMzUEpRtUQq0y/aOlGN8fHFLFa5PZWCRvOqJzCFgOFssIe9qGnObTO40LomwSVkYVQt5jTSpGs6QGw7nFRURFVlJCBjrXEglXcmepba5e8e9KB5ElYsMAOHEeWjaKg9W0PdnW/Oi/Kbrsxxh6k6p63oihwXljdPqT8rpPGTYg54EYvFpcg6XTdraGNxVtFioYYL23R5qNJAoBtt5uZqSgPV1UWVJXl8PoKSmcmc/9+lrWDd+J1OZu27MXAaFjjnEGlhqZpcM5RVZKaWlUVdVVjFcxmU/abwHzWMh57UjMXtnnX3OkuUT4POhm0HZFoSamlKEWK2VYt00mDm4j0c74/ISLXfWdnR9ZdiGlyQBjbRWZZmgyWmyy7Vclji5rhYMBoUOEOSxNttWlJ2csuhEjrG4I1UBnQAlCujhXf+sazvOLWBwk4fvJv/3kmk8HXmn6/7vHX/spvcMvNp0kxsLfncM7zpjfczW994I2sr8/Y3h5w4vgu/+B/eDc/87NPZgr/yA99mF/4t297zvbvm3MotreHeF9iC2k+dFD47beeI2dD8vWvPxRg2N5d47c/9Bp++0OvYfFuBojU1YzXvPJR7nj1o9x4/XmOHt2jrsRz1WhNYQ2tc5y7sMPJK6/lL/3lv8KnPvVJfu9D72NvMsX5yEMPneZjd93DuYu7+JB45NQmp89todDcevN1OTBF3iVVIWsvn61W6BgeX4PlIN7G0uiJSX4vc5oU0FWpezsLknit6eBR+Z0JcGhlxlve/AhveePDdF2aFCIpRHYnFe98z638+m/dzM7eaOmcvwRcvTSen3Hq9DFOnT7Gb33gTSjl+cE/9HvccN3jnLziHOPRnHnr0aZh2gb2p52JvieExLG1UgJ4ULQuEpI8bwmD7qT6SdZbRVow0l0IlEuJ0oCARor+7y4LhKUMlyvkeVM6g2ELlpXWihSlJo9RLbzNOrC7+wN5yZoWYNilIFi3/1L7Z9wAaUZ1jd9uX9OCakrPFbrcWPqKbk0cLwHMeg9WtbDQ0FpLXULXWFZLaoQnD9XV56VeEFuW+DO6O8cJmlnDbDJlur/PeFBTlyWroyGt8+zsTUWB8RSH81TjRQ2EkQTJLLuiLwNMJHrfC4WYu42HqUc81fKCbWljKrMPCi1SjpRSNkWWm2b5IoYQMUZegjpHhHZ6/9zIJ6aICwcX3iAFYveQmaJAZzN2hUgAkjH4JFJEksrpD/SLWYCqKij62HojhSFknxgtZs2t629MVSq0LRCUPS7d91EKvSS6aWssijJ7l1hJKsvpcHLDq/6/8t2Jtu2SdVLucstiVevcGQ8mF6CpZwV0qLU1nVdIonEO5x0uG+dqu/Any+rCvvMlKL4l5ALfe0HVxVtB565y6plxCinMOsYVqpMZLT/Ii+vrfeh941rvmM7mzGZzVIKVwTDfHxGVQb+YIm3WoMs5XBhzo4TZVZYlKcSetZGUZnVtVfzPilIKqNZBVTEajdjY2GB9dYWqLEhRPKr2d3cJPjGfN2Li3rZMZzN869hu5hhrqeqaIl/PDrEvyyFlWQrwtbLKaLxGPRhl9t0ckgMlJs4+RrwXYKjNoGIXifvgw8d57/tfxyc/fRvPf6cQIPL3/9sP8p3f+hidlPj8hQvs7s84feYiULC7N+WqK49xw8uuYX19hfX1muFAL8y1SVk2KFtsm5a2dVnGE/sX0A//mR9mNj/E117oLQAwpRKjkWN/v3wKEOwgWPZMxve99Xf5tjd+gMLsoQl4NyfVNvtEVWhtwVREbH6RRtqsv3dOfLza1jFvWrzzIs1OwvBDa8pSsbW9K+cpevYmcyZzx8WdKa2LbKwNUSaxVo/Y22l57IlNEgJMFYVlOC7xwWNToi6ssAkxOX0x0XrpnBsSVaVZWRkym86JXsCS+WxO8gm7N2U0KjOwr0iIZ5dCQKuIgJwpJUKRKLQFVfXPsZzmxKVv3ZhEZoc2YmSPSM8UUJQl7f5uzypyCpTuPMtE9hWzqXjXhdfZmN9FCCpSVZbgZB7oGK9FWWFtDShCbAQQpBapfEjMWygyyOedW9rt3EQIgaBE+hiSGJ5rtWhIGCPmyVop5k0jkrukxby9Z191C6A8pyeRiceQaGNnFi2GssIojVTlgJRC79nVhoZkC8pKgLa2bXvD/I4i3/1SemHaXhiDcwHvpvmdkCV3MdI6R+M8pZWk0uA8xPxuspakDbawaKt76aHWWthhkBsJCyuDDqRr29xlJS/G8m0Q1YIV28elX7KA7fy+undKN1dDZpRlU/5OHtVJLpVWOO+y5HYBrsUoMkqjO69JmWP6ptTSMOQ5KQmDTkVhhyzbJOTlDZDy/UhmRxlAElTLwjBYH+b34EIaDLIoblsBw0IUVhgK2rZFUzMYDGnbpl9nlLZkNBiJ3HV/R4C8aLnYenZ3d1kpPKNaGobLxxN8QOtEWdXY6hDQQmohRZzzVPUcU857qViKAmyOBhVWG1oXCEmeAu88s8lE5JnWgIp96qUxlqoaUFSSHlXYirKwWBUYrA8oBzWT6ZSyLPMCvcQaWc/5vM4oSoNJkX/0D/4tP/m3f5zn6r12+62niCnh5MCwheXVr3qE3/rAG9nfF4n9zTfvcsUVFecuPJn1df+DVxLC1xui0gFG3+jo3l/P30jJcHFzhatP7pKikgTUlEgm8Wv/8V8x2Sv4X//FG7jzrhv4xkCxbiz/vGHejPn4p27j459aZp91jLDIeDzlqivOYu2Ym255jKI8RNu2tM2c+WTO3u4+p86cQ9uKH/pjf5wrr7qaz3/2MzzywJfETzA/010ITTevG1PQKVpkTloUyTGFvsbp91lpklYUZiF1Twla57OvbWcxkCjLvP5GmiISXJKPKrhsJp5ZxHmOWxnM+DNv/zR/9o9/VhJmbUFMmkcfH/ORj13L7378ah4/NaJplw37XwLJXhrPzUjJ8qvv/o7+z+PRlGuvOcfJK89x+NAO6+ubHDq0xep4D4UQBBofs6qlZR49msCwA6zy4msyd9kmoCN9PPkeFhuixXv+KezBCDHho6Mouu0tPig1Z/Y0TUGSnlH9u7cLROrq7dRNvZesa5dZ6907OHX/pxY+hFovTPNjTJD9DbtD0UZdolCgXztB18Ttmsh5vXUZILBniuV1Uoj5U1rOh8r1uOpqpr52UkvySNme9yKv7FLcVVQk71Cuodnfxa+tMK4L1lfGclwpsbc/7deIT3e8uIEw5KSXhWhQg3eL11PKSKIWb4uiNLQ+L/wgJyktbhxrdJb+aDqJVOf9It40mU0RIk3rCCEyrEuMNZKyyOJG7OVt+d6IaaENFsPj0H+vpJ0ZFCnr/xXKagojHhrS6Va959XyiFGi17UxeBMzG0xuppileSGzekIds+ZZg7Jifp71viojw2KAK2wsXRhc8oSQC87QAVC6l5PC4iHs9seYxYPWySjl/Jr+szEtBcCmBSOv8+JKUeigOqc22gxSOZ8ZazHlf6vQLGJwvY/5muuehioFg9BahT2X8nHnAq+VZDrjhaEiSZDIBIEk3LnWSZEaBfzURlHXNdPpVLabxBy5MIgBtjHMU0uIkkRmtc2/CmxZ9D461lrZpxjl55SlHlYMhzXj8Qqj8RhjDPP5lN3dXTY3d9jc3KJtHUUhBWnIhvxFWXJo/SjD0RjvHfv7uzTzGWVZsLqyysrKCvVgwGg8RmlN2wams02ELSeFkvMR5yOhZ8WJAf7ps6v83idu5b3vfx1N89x1zJ96JG658RT/7B9/kEo1/TP0xKmzXLiwy31feRhrS44ePcKRw+vceNO1rKzWrI4HDOqCsuhkvIt71TmfZbPC2vA+ElPiHf/mFn75nd/5DPdPMRw4Wqfx3uSiZrlgWP79M1sY3nbz/fypP/ZvsXqTEBtUiFhTyFaMMFTEA0iS2gKGyTywuzthOp0zmc6YzpoMgM1pmpZZ0wgo5hzDYUmIHpTl8KEVUnIYI7LYYAOz6GlCYjprSSlw9Og6SinG9SADGtLVGgwt7bwh6chu45lMNaNRwWhYYgqLTxE8VKnMHXSPNYb19RV2dqbM2gZrDZ6ArbQk6EUBsnd2Zuzty78f2hhSlHkeM6CtysV8oi5LfJ5bjdYLH8d82rXWBAIOj74kXasoK6rBENc2XUbF/5+9/467LTvvOsHvCjuc8MYbKweVYqlsZVnBGNs4Y8A4YWMb3LTp6QE80A3DDPT0B+gmdTc0wTBtmx6gCQYaMM6WLeMgW5asrFKpkirfqrr5TSfssEL/8ay1z3nvvZKqSjYeYS376t563xP22WfvtZ71e35BuOVKJT8rEojiZV5WslYkjpgAgp2nLA2dD8wXPaUxjKwlBJWYlQFtFG3fITJOAUdEyq4GeWdODhaJX0BpsNrQaz/83hoj/mK5KaEUwRfMO5fAAjkuraT4UcmYWcUswY8MpVyUoqbrO0ZmlGSy8riqGKX1IUmsiRRVQVVWg08WMEgYjTVD51ArJX6D0dP2Pb7NwI0kH4pXHkRrWC5a2XDFiPIB5TymLDAqFZCogXUUfEoiUqDCag33yTPTpmQkYw3aCCucKHJXbXRiEa/WbFjNDVk+GciMMzX8IeZrYAXE5ef43uOjp3PdEKajM6CzVpTJ+uJRJkpcvCnTegoqzUW+9SirqEubWOXXzBoxzygxSR/k2iltnZJ75XrN3qdRqyHgxVrxYuuSsWzfC1u0LK0YDKtICCN8YuYVtqCqqjRXBow2aBWoOMK3nqaNlGbzOrZK3/fyfXULnG+T7LGmKguZs+oxo4ljNp9zcHDEqCpwrmc8qlFRSfNNGYIxsvb6FELjOjrnEgPbE4KnaRb4EFm2Acsh40KYYl1VYea1ALdNiy0KxmMLUdZyn3wkjYmoaNjcbPhf/vq/48/+v7/l2jP+OYzI2978EH/ku3+R2aKj7XvG4xFnzp5Ea8Utt3lOnFhy5Yqsq0dHJQrDbH699+ThweQlH4Wwk1+In+ULGf+pwbDIcmHJNiLSZFhtKKvdyF/+i+/D814++eAJ/t7/9+08c+6FNLA+l5GRf81stslDj24CL+cTD8KP/geA+4C/wE/8nOxIrF6ysfUUR4s5b3rTEc+fX3Dx8iWeeKqiKApOn9phXFcyXwFGyfxSFskXLbEkcyp3QEAvlCKykr6rKPnLeq3pP58vuP/Bx3jwkSc4PJqjjGZzOuaWM6e4587beNkdtwwSrwE0jysigSoiuV4WNUAganARWq84feYy3/mte3zXt310qJ/lsZ6jI8u7f/mVvPeDd/LE09vM5vVv4XfyhfE7eczmYx548E4eePDOYz83xnPixCHf970/w01nLtF3PU3XUlaF+J7GSLOUBlXfdzx/cU/YxVFR1xXex2RnsAKdB//SuAKq8iPyuquV3Ku9W7HGr10nRU2QGmuEoU7Jr+WczB9ZZSUeYRIgNaRgXgOEZd/zEIXUqVK94L3Uy8OeewC0choviST2meZNDVoS36263hdt/blxeLhKgL/EOCmlkiLBiKe7KbBGEs9zreSDZ9k0tAsJRACZD7eMzP0q9ETf4NoZwY4orWU6GjFbLJnPlwzAmn5hjaPPeyBMmFphKGAz00gjCKcxiaFkLap1Gb5J3hdrbCBth5OWE8tCDAMKmr0unPMDGywAIcmonBczbQHNZDPgQqBz/cCoqoqCqihSsppsErreg5HNmo+r7q82KY0moaRKZU1w6oqSPUz00BXqe4dTxyUX3kUWyx43DpjYs2ylO13Wq88/wMBRuvmu6/HOSXyrlrQLnxLEVhGlGTCSjbD3q641rCaFa+mbfq2DL8V6YljAwBQrixKjRQY0+LTlRZiYUG1Bz5USeUzoPK53xOgoEkNw/XhiELPurpPfW2tlQ9SHFZVzbWOjtdzwYjothqTWyPfgvKPpGqJOhs9pGrNK6O3juk58WGErlrbAYFDKUpQjTp46SdM0ABwcHmC0oSxKtja2mEwnTDemeNdzsL/P/v4+hwcHLJdN+lyajemUEDyLxZKMjm5t77C9e4KiKDk6OmA8mrC1tcPW1jZbmxtoHen7jq5fpK9nZcbqwsrvq+8kMfTy5Zpf/8Br+aVfezXPPnf2c7lBP4cR+Mt/4V186dvPE6PGdY69/UPmi4YHH3ycxx4/x+nTp/ii197HzvYm29tTJtOSojR5jk+Lh8gDfEpTEtmBeGR5H3jq3IQ/9d/+IdbTTV7YiFSlp+0si2Vxze+kA7sqmF/4mE4W/NFv/QEmxQM452iOKibTmtLqYwyVwhrqepxAfJl7Fk1kNpvx5NMX2Duc03Qdy6ZluWzpXQ/IRrlte7q+pVgoqspilKbetigdKIyiqDSFVoxiwXzpOJp5Fp1n2Xf0S8/RYcOABynxqvIhYEsoCiPzhFYUVUlVFvQhUFhhCKFgMhLGJ0quxI2NMW3bY6yh7bsEFmtc71l2HU3fMtLi11AUlqXvUDFy6eohJ7c2OJjNccFR6IKN0Sh5DKTrIKauiIlrBUuAuJonRdZeoAot6T1r84dK/mneBVxwItVOLLfhSkj/9D7S9YGjox7vWw5mDaW12CTvbrtOTPsTQCVduuSzoEQiZ4xC2wTmWZHYWy2m90XySysKi7OGQltU0MRYUhQy97ddK8wjFTEq2QZ4j/YerbvhmEMMuOgTI1h+1nd92nDqwVzeGENpDNpE0IGk+qSsaplFIpLenNZfbTSd7ymcpSwliTCEQN/1tG03rAmZwd21/bFGZwzgQk9oW7QxCbwx6GTIuu6Nkf25gFT8JSljqRnSPr0AgFFFlJXvtA/9DaVGIiV0+OiH9cdoI4EOiY2WmaW5dhiM85WhLuqU0ClrX1kanE/ppCGiUfioaduOrm8o7YjK1scSnEIEG0IqCoeea6ppBPwUmW72CpX1x2hJDpX0yQTsfRrQQmSSPtVK6bHZFyyBzFkiui4xzsMHnxhVAlqts/NArme5njo5Bi32AVVZivxYKUqrqQtDVxiUD4y0oTYGWxR0Vnzyggo4JT6pMRbEaBPYlzftCZgMAU2PgcQ8FFP85XzO4VGD8wGjlSQtb20y3dqhGonHmVKKUVlRVRUb0yV/53/+Mf70n/v9NzxvL3bccfsFTp464i/91W/lla/8GG9/+3tSrajZ3JwwGdW86Y2XedfP3QYIEGa0om2uX4vOPXfqup+90HGdxPYlj98ehs+v/Npt3HHHFcoirIKw1ocCg+a+1+zxw3//p+h7zT/7V1/Ez/z8PcxmNTHe4Dm/peN448uFKXt79/JjPw4/9uMAX8kxugURpXomo0uMJ+/j9ls/xu//2oZXv+Jm9g5nXLl6QFGWTKYT6qqirmtGo3rYhGemiSIQdSSkdeWpc8/z4+/6FR594hyT6QZnb7oJYwzPXLjEJx56go898Ahf/qVv5kve9MXMlks++JFP8gu/9H4WywVKGc6e2uVld93GV77jjWxuTIR5q6SOV6GnsmLRolSyzkj7oByWVW63fNvv/zh/6JseSKxUBargaD7mEw/t8p733sbDnzrBpSsjFsti7Xv67bnOvjD+8xveGy5e3OF/+V+/ide86mne/rYHeOUrnmV7e1WH5HVksVxSFDWPnT9iuWww6jl2tifctLuF0rC5MWJ7Y4rRSuoEl5Oy0/WqFKO6RgF9DMwWy7SOB6rq2qCW/JTkH610skwQ788YvLRYQ5Y6AkpsilZrbRzeN7+OJ6RwuSS7TPs9UTEde+fhX7IXDMNe9obHScIiYkjewvY6IGxI3c7MexWH+izXyzl8sLSRUAhLTmlAR1SybohR2O2Na+m9eAuP65oaGFlLhSe0S7pmiSvFOiWz32R/lOqeFziN/GcAhK3AFknzEsaSsVrMg22+yCSiPG+EZMhOziQAJCISnfWo8mxOGwJ0fU/TCZ3eBU/rhHJsUuyyRJLLZZR9Xbpsqq710H2vi5pBetm39J1PiZPJ48uYIQnxODVTUVolSWyp89IlaaAkueXNgWwwnPdYrdidjsRfxhqmxtD3jgtX5uxsjpmMi8SYUgQnHXWnoI8eEwJ12gxYLcyL7NAgjC85qsxgyCjsjb6bPEKadNaHUopw7OZWw2vpYYEXqmWWv6goksVs2tz1/bAhCVF8WY55xqyNvhcWmDDCukFyk49l3Wcmg3TD54liMB4TyKISi0NCAjxlMh8trFBeR5VomPOEEUJgNpvRLBuMsZzcOUk9qtne2mZUj3C9Y+/SZWazQ+azI/q+gyCvJ35kAe/74TMVRcnpm27i5ttvp20a6baPxtSjkRxXCBzNZxQmYgqdTA1lo+STf4xPTIz5rOT9H3glv/q+V/DAg7fx21WMnDl9iR/6Oz/D9rZ8xqOjhvPPX+bSpQMOj1quXNlnY2PCO9/+Vu649QzbuyPqsSSVkHzi8mbVB0+/zEloPm10I8tO8W3f/e1ENtK7vvDPaq3HOUEDRAawPl46++v7vuc/8nW/5xNcvHDA+XPP4XphTNWjCq0lQSeD/pCBg5Vn07LpWS47Lly8zGPnLnLuwh7zZYc1woqNMWILCE6+d11ENrdG7O7WWKWYTGG0UdAHR3SRQimKEqrKsLUxpvcd589fxTnoe7kr6pEkPnof6FqPLQ2jSSlebIWhqBOQEYpj92HvPd5F0AloqQ1lZbBW4VxMwAH0LtJ3ERUsoTOcf35OHwLjcYFWkb5TnJsfDDJZneTMW9MRZ09ucWp7k3FdYNa+Ch8kqUdkI3FIBm26QCRQlGntMCsvsegVoYjDPArS7eu6lfmhMZaiKJnHBcuuI3qRWFtTYYzMsVkWVyS2V+8cl4/mvOplZ4nAfrdEW4dy4HqP1oqylMAMrTQ6ajaqmumoxnvLMnYURiTvdm2D6KOsYX5NHimgkQAdeb7rXEfTNaz7XuVGzuCvRmRUlWyOx9RlhVGGnkBdbQA+sYuFdavX0pOOFnOc90xHY4yVZCaR5nX0fb8CzrRKa4ka4OMu+JQEqtCdADylNYnll9boIEViPa4p6/KGnczoIyokNleQxOeBbedXM3v+vMYYXHRYlY1tNcbKd260IaT047w+oOS5g5l9AqUBopLGTQn0vafvRAJYKsNYlRlFzrS84VjqQrN0HuVjCvQhMb1TArQ+3nDKTaUYIy4eV06oY69M+kyKUV0yIvnUebuSc66/ZmKiaxKLPa6HLRiiAZTUI8umS89LXei170LYtiLJnM+WA+NE41ExYom4haMHfOspRiVlXQogC5SlTX58gRgVBo1PzUeLpFoTRaa6Md2QZl6yKRgbw3hjg3bZ0i2XGB1QrqGbHdL3kXo8ZTweU1XCVOn7jpfd1fJHv+v9/JN//rkn+j719FmeeloaSecv/B4uXz7NV3/tj7BsW3Z2NrHWcvpUMzx+Y9pJo6Jb32DIhXbl6ktnhPX9tY2a68e3ffOvc3Q05r57n+af/ot3cuHizkt+v9/cofj3P34f3/Ytn6Aq3Gd/OFAWkf/yu+/n+77n/sRAjfzAD76OH/uZF2uu/1s5ju9FYqyYLW5ltvgWLl76Fj74kWvvXAfsUdcPcsftv8LvelvH619Xc/78BR565HG00bz8ZXfwmpffybgu2T844Jd/7UMcNoE/8f1/hi//iq9kc1Ouua7r+NAHP8i/+7f/mp//lQ+yP2u4fHWfX/61D3L77bfzlnd8Gb1zPPbYo7z71z7Ecxcv863f+BXcdPqEHK1WKO8H+w+T6ub1QBSQgFgApSTFNYZAURmm046bzpzn93zpc/i+E4ZyWHkjH/XbfPLRM/zHX76Nhx7Z5fKVmrYzhPAFoOwL46WNthvxkY+/ko98/JWsVkXPqZOHfNF9T/OWNz7OXXc+x4mdbXwILJcNvZN95d6iYWdzxFPPXeUxfxmjC6qiZDwqKUupl8pSFD5eyZ55Pl9weHhAu5xz9qZTKOWuwR9kSP1QoUwthJChTF6F6oEY/+Mbrl/RgZhrBVnxo2/BGHIAnTS4zFDzCAFGD7eRqKokTK8sbswc1ok12t/g7dc/y/q/ldYQ8nEFdIQYxH+8Hkm9oBohX4jNkNRdPnhsanqHkHxlY8QqxWg6ZbqzSWkjvjmiryxGj+ldj0kS0piY9/Gavf+nG5/XQJixmsJYyhQPDpn1sQIxhNK7YjLl+HlIRWg6wdkIWcUEuKxdIFGoUkQxm8KtnVyrTfLCgeA9OqUN+lTwd8lnxGpD76WLYpUU9fnm6b1LhvzZh0u6/iFmeWFMTBApiLReSR9BNmRN2yc2Wr4QI30niPXGtMZYjS0Lqbtj5MTGCG1IqRWrDncfw7AJ0RH6EIbNlOBTAgz1KVVMo6SeD7mAHvaONxwqnfNcULvU5fdraRSy9TquP84sMqsNGvl73nWDB5rRGqwdjIO1EpmjT/5W+ZzmkQ31u/T5M9NmPUUnH0dMAJ1zjhgDbRsoCtnYj0YjbClgqfeecjLBWsvGeEKMkUXTcDSfSwe8qgjA3sEet91yG+PRmDtuuwNjDbP5jP39PebzOe1yRt93SZq4AhzFyLjDdR3O9VTjDTa2tyjKgvn8aNBTZyNmYVLoQV7T9WKUKjJSKWKWneEjH72DX/+NV/Gxj9+F979dU0Lk27/pfv5v/8XHk3l55PLVGZcu7fHMuUtcurTHxmTKzTed4vbbznDzmVNs7YyoxxJA4L1cQwzSr5A2zEkOnbonf+mvfwkf+Mi9vDCm1jqola9NlUCwG//uxRZo977iIb7vO36EwjqquuDgssE1S6rSUJUjilIYjyYxY0AAgLYVH6quCyybJrFJ4Wi2ZNG0QyJf03vohfWhdYRW7r2yhO1xgYue2WFDWWnO3jGhqDTdfs/+QSdedEvx7mpS7PRyuVpIt7amEkEdEb+pzlO5xMQxQvkW9o74aRFXlHJJupVNjbUFG+OaoJwAM01PuxTgoGsCfQvtAjp6JlNFMHD+4hG1Tqk6WuR6MUasiYwmJaqAg+WCXvVshzGlNngX0FExX3a4IPN800rya99FqroQD60AVSHrinioAVissjjXAD55uAiLy3tFUZTUVUXvPG2bZLcxQpQ5cggaQzrqHaBLDcZyst7mymzJrSe3GNWWJi7w0YsshrUum4p0oefKwtEHN/xOEi4VY1tRIH6TIYZVQyeDeWnOFcmNeLBl5nMOcyFyTPIo3zWURuFcT69XXnvLcMBkc1cYs8HLXFOYNL+IfM1qQ2t6STjUmemcLAKCR6Hoe2GKoa140oRI03XC8kiMHa3FP9MAKq/lRkAq5xxhHiiqVUAEIHLF4DGYwei+c92QiHht5zOfp7qohQEYfUpclT8Dw1gxAHFKqYENlQHS3LzJ8QxRSby6KtUgP8jyf5DrORvmloUUqCNbUhkJRsgSQGVAqZX0NNcdwyyU2L1ZXiANJlK3OD9mJe3MLGivPDro4bvJ308+R1Fi+mSjqnK6paJAivMQJYCj9wFrNFVhUiHKqtECrKdSKbJRcDxW1wfnafuORddgjaYsC4xdHdfwXCOSZVLjLAQ1pF0WuhjAWKndA8pAPR2lZqgmEOjaBW3X0TRLunbBeFRQVQWjUc13fOtTFLblh//Jl/GbNyIPfPKLmM9v4Y9+18fYGO+hlWZ7qx8esbXV0vcR72/EYHoxa8txJqDWnhA+M+P5lpv3ePMbH0QrzQ//498sGeVLHetrKrzljU8znXSI0OYGm8lrfib1pIC3OrHf77vved73wVu5cGnzt/bQf9PGtZ+zAE7TNKd5+JEv4+FHgH+6qpnlT8NoNOdld80Y188wX1i++ms3ec29b+Infvw/8FM/+ZN0XceX/e4v5yu+8iv5xt/3B/jhH/ohfurn34MtSv7Qd3wXf/JPfT8HBwc45xiNan7mZ36af/nP/inv/uUP8OXvfCNnExg2NC7S3LCOwCslNQBpDnG+H6wG1kdWeqjoM3EFU8DpzY4zZy/y5V96ESIczYShc3A058rVI546F3j4sVM89fQd7O2dRivDcrnBYrlD123gfc1vj4ftF8bnx8jXoeXS5V1+4Rd3+YVffB2reSdQlR2nTx9y6tQBp08ecObMBU6fusLu9j5V3RB8pOk880VL6kljDJT1AmOVAGlNw+a4oGtbQl2Sr8njTbtUFxNRMa/VmWG29rAbMNhvNKSMSx6YiagTQiCm9dca2eO5fokyBdbWqS5ww7Fcf4zptT/DGrReZ+bmoAFwUpcYLcFYzms6L2B6NSoIIdIsw2C5VFWCi9R1zXgypm075vM5vusZVyUbO1tUdY1KUlPvPU3XM1s2tF2/fkQv6HzB5zkQtjkeMR5XlEWF0ZrOO7wXycP6wqi0pqrH+OWM9c1qTKa4wj5KjyWBWoNHWBz+hCidUL8GhK1HrPsY0TFJ96KkP41sOXTYfZAvzLcNO1tTrEmmuErQUuf74bilM5KN/UJKTpLNcGaI5SRD57KZPVi9Mqmv65K6FhmFD2JGrxDVXqYPZrqidz6ZHGtGhaHzUnz3wScWQZJ9quOdypj+19j0mddTLzhe+IovjhlAvi6lI+Yh/xZfoJx8GZV08ZVame9lIA7WyqV0Tswak857v5Kt5GQvxLC763sB5NY/S7qBi6IQE3knPiQxxJTKFSlswWQy4ereVZHipE29QvTI88USozSjQvyK2q7Dh8B4PObkyVNMJxtsbG6yvbVN27QcLWbMjo44ODhg2S5RMQ6mqWHN0B2EhdAs5njvKIqS0XhEPRqhrfioKKUwRYrKNipRRYOEEPQ9/RCe4Old5C//jT/KM+fOfMZ77Ld2RBSev/FXfpG3vP48o9GIplWcP3+Fc+fOc/HSHiHA1sYGt957lu2tKWdP71JWhroyOOWHuS54SYHJ0sfMciPCBz5ygr/0138fLx6oWqPYXve8z/S7zzyM6flT3/s3KdRjjCcVy2WFqmsB7H1DBOpRnYDvnEwl4RhttyAEMdIlAx5r99Dlq0dc3Z+lkI9AjAI2kOUKeLQOBKfoOkU5rsAqptsWZT19H+l7AUmb1nF02HE0WzKbLXEuolSBtQW7W1tYY5PsG6raDrK0rskeiGmj74UdJdJmYX8uF47DWYNzgdtv3ZH7JxhcC83Cc7jX0ndh+KMUFKWmdw6LYmtagofloqXvFK7vJep6bChK+dMHx6wJBCUFhu8jRMXFCzOWSyceClEIOZO6wJSGrnXcdtMOXnVUvaEsxcxe6woVDcZWOLegNAbnxKw7A38ndzZ4/uI+KPFudAqUEgBosKpO85Q0vuLQZYsqcNh0bI4LrNaEfvWdKpVZP9Lt6p2jiT2VKsR81ER0BBcdbeyosGKWH0Skp2JcY6NFsDbJZEkgjcjP+8SwJeO86U+Wr7ep8WBtAoaMwnULrNWockxR1ZQ60vXCcBFjfGlI6DSfZWmjcymYJcVuC3Ahx7lwsi4YYwYvr5gbLOu3mgMbLF3byXfQGOrJyoOma4VNa7TBGjt0PbONQgastNaUVUmf/CLlDcEqK/JIZQZGHUghqdUKEAQB5WKMeOfBMgBmClkXjdZYrQZWlXhhRlTyiPNB7rui0HRxLTHp03SVYpLeq3R9xPzYIInQuRknr7GyLciFY96A5gh3mxh7tpCkyHxuQObWEAKFWjWJpDlIYuhJHVFYWV8HWWaMw1ycGWYyJ4fBIPxGze3ee3rnENwmYKMVhjx5RknNNzTWlOl8RDrd0TRiIWCMoSyl9oox0tlOQFEj3pxaGRZd4PKsoVkuaGeablqxvTWlHk9QWvNt33KRV7zi5/hzf+Grb/gdvPgh1cuTT53gL/3Vr+C//r4P8/u/8RzTyap4b1vD1b2az43xchwEA6jrlsVi/Bmf9eBDt/LWN11k7+A0e/sTbmSwv7W14ODgM7/OSx/rx338+N/65nNDbbwKAUnPiWvbs6E2Fu/U9Zd60+sf402ve4wf/Yn7+Kc/8iXXvcfn57j2fE1YLid84pOngbuBL+OBh+B//TsArwP+NBD4lV9d8gM/0PLylyu8V1y4+H/wxjeWfOu3fTs/93M/y1/7H/9HxqMRX/v1X88f+o7v5NFHHuKBj32EZ56/xHgyOWaqHYDohSlbJBm7QhOV+HCK7YBBpWjcRR/w7QKQebG0JaY8fp15FPRyX4QQaJYNXdtjtGVne4ONjcBrXjkn+I8REls0XR1obeh9QWGn9G6b/f0ph/MphwclV/dGXL4y5eLlTeaLGmvELufgaMzhbJx89P5zuC6+MF7ayN+9oe1GPHNudMM9ktaBquy5+eZL/K53fIjdnQM2Nq6g4ozZUT/UgMsmUpeabu+I+bxhMplgCwnZM4msYIyi61pi5ynLkrK4sYTysw3BLaLUdlH2vYURHzQx5FcD8zuDYcOnVgqjLeBpO/FhzsywoihWCerOfVY87ljNkqZ0K8Vv+pFH+VU9NZ5W1KMC590xtUuoRBHSVZJiXVqLIlIWx71bnfd0TcNi0bJ3OE/El4xTvLB7+fMaCEPIRUJfTOhgCJkhtJ725FkuZ6zcMCLRZzlHMtIOQbquQyrC8MiVJ4lizYgumdbFnMQi0cSxF6ZGjBGj7XUXnFcBbZP0Lhn2a2uIyqK0eK0ospxPCtgQI8E5YpJ1GGMkAaPt6Z1Hq8RgKPTAhIoRgYwS2JO9zaRwEJqkNWIGnz9nLjS0Sl4jqfsvaLJcdHatMxsSk26Q3ax3noHswaNUTJupgEYWv9a5oaAJMYgcK4ZE41xj4iGbNeedsE8gAX7mWHdbIfLBqigpbEnXNbRtM8ibjDEUxuJcB74TScXazYmKhOjpfS9GhGlhLU2BxRBdEMlLhGbeUJkKrTXjYsR0PKUwZZJYVFRFiXOOSsGJU2epq5rJeMx0cwNjhD1weHCA61tmR4fE4HCuRzlH63q0ynG+awwa39N3HUorJpMtiqqinozp247xZMRoZClK+f6dW234fNrEuN7RdS37+xW/+r7X865feAtHs+nndPu99BF5wxc9zz/42x8FOtpmRkTxxLlnOffMefYPjqirmrvuuI2bz5zixO4mo8oIownxYXLpWglO0iz7PuCCSglkka5TfNN3fRfwQgubaxleNy7IPxf217f8vp/ki175s7KJdj0hlMLQDGLaH7pewiiMwShFSIm14unV0XVpG5g2toJvrAH+iInlYrHg4GhBn9JgRfIdCVFMdGM0oHph4ATwLnBw4HD9PG2wxSi8XQQO9nuWS5kXq9JSlaXIal0vMmClBQyjF0lSL3NC13bMdZeAHmGMBB+wVlNUBUfzjmUjTQvXey6cP6QuC+aLntmsY7no6ZpA8OKZNZpYqlpYXVVtwUPbO5TSTCYSWFJWlrKyKAyLufwuBEfXSFiHSPGg6bzMnQl4KIuSpu0wvsDayGyxRI9q8I524alKTWEauca8LMTzJSm91TGqS5zv6fvLCWzXGC0drd4j/orpmtJpvSHK/COznKS79t4BBSEk9lTyfYukpk1IUhQVaXtPYS1Bgesc1gjzWWuFUwGrFFEzmOKrKDKzdY85uWbUYCifzVyH9kBaBjMjZ5BKpiaHyAY6tC4pY090ir6cEFSfrtO1+QvxlPLBowqFxQ5gS13X9C4nKcOGsbTO0Ts/gLyf7m5zyfTd41GVGoCzbIjvvMMoM4BCed1e/3duaOSx3hGNTphhUigel4wODKW09nVdNzRcrh3HJIdqFTeulJL01r7HWkXTg/Sa5DHZDiDGiFFm8PCKMeAHMpWiMIWkf4YOQZ1X1WoGvvJ75iZbbvyUVUkMcZCrFkUhcsO185FBy5xkGhIDVWnxzsSsJAlh7fLJkk5Qa5JkeQ0XVkz09cZljLCcHxJKYfp3bbeSoubvJ03Rxqy+27ZtB5ZbXder61mKIfnsSU6rC0VVKKYVtK3MB0ZLol4fn6Osaqp6xBffB/+P//uH+Lv/8I03uPpe/IjAy192lUcf2+WH//EX8+pXzTg4XAGMs3nBU09/boyle+5+kk89fherdSwmEOx6gGx9fOz+2ynLT/DAg6fXjvb4yCBYWfZ03WeXW95oXP/cyJe983H+7J/+Dd73G7fwC790Jw89fIr9gwwIRj704Vv5+q9+cghjyvYcYhYXGC66/IoxHDv8CCkVGr7x6z/O7/36j/Mrv3o3f/8Hv4IX7w36+TryLKoJYYMrVze48n6APwD8Ac49Cz/24xF4BfDtQOTXf6PlH/xDxdkzf5Ku+1F2tloOZxPK0rC50bC9taQopX6R+SzIJlxJLaPTvS0WIgwWKMZoCmvxIdJ5jyU1q1eIJiEE2rbl8PCQ5XKJsRUqzYHZC1AVGh09EFBKE1UhRptodqYlSrcQW5S6IgzVVIfEa68XBbGyTLWhsye5dKnn8qWO3m8zm2uuXinZ35+wWJbM5/LvvrdoLWCxUhHnDF1naVtN20rgjFaB3hW0XYHrLc4ZnDd8ga32+T1C0Cybiscev5XHHr91+LnWnt/1jg9wz8se4+Yz57G24fyly3RtM3iOKwWjUcX25gbTjQnTyZiN6QSlgvi7Rob0bq1Nqhk/+15DIXv30haEVY/u2D4ZjhNU1h/jvcOHtMdGSaCALRBfbvFCdTGCMvSLDl1JGNz6AeQa49jQHFvfC11g7Gr/3rueDkehKwawLP1Oa0dZVIxG42PN2aqyGKNYth3PX7jEfNmIHZWP1HVNOa0EROt7Xsj4vAbCYmop+hAJfZ8ALdHK2pyyIA8hBp958hAjwcsJklpcy++T/MAog1IalyUBKg4ss4iwlQgcA8Nc10FiBdlhs+ExcVU8D4W31cOluO5Zks3WI0OFK+FoCWTzPqC1sDpilGSZaGSh0an7PBR7EXRUGKXwMeJZfQZFZqLJJtMnqUgeOU0zhCCoVPL18t6jbLnaECEymsLYYY3N60uElHqZeD8hdYpDpMfhEpPKak1ADP4E+0vnPMZjhUxIxazOG5LEVPBJBkkC2pp2Qdcuca7He9mQrbzjKsrRhFiPhs0FxAE4zIv0PHnbFMZSF9IdN8amFEhNkUIPisIyGU+Yjjep6xEZmS2rms3NiqquGY1G1LWYmnZ9x+HRIfPZnMVygXc9KvQpXcQLcJEYcN55hE3jiUTq8ZjJxiZFVTPZ3BRaqbVUI/FjUioBik6kwc4JmBd8oGsjH/3Ebfzyr97Lhz/2Cn77FuHAf/dnfoU/+A2X0/WmeOb88+wfzPjEo4+gtGFjssmtN53ltpvPcvLEFuO6pCg0WolRee8CXfR0XaBJIRSkWtgHz1/5G29JMecv9DPeiNWlqEp3A/8v+EwbiRuNO257nu//4/+asjxk78pVnn78GawtGU9GbG2J50uIArJWVTmwf0LMYLyA2dmLQ6X7PG/wjuZLrh4c0rQdTdNyee+Q/aMZi8WCrl8OAAMg8cPaDMEWfddzsB8YTwrp2ibmSozifXWw3zJb9ISgKKywjLq+R2tLXUpyZQyKvhegelRXtE2fLI9SsIXRhCBBFgqFsRZt5Pr0MWILxfnzh/RdoChkzsngmS0U9WZBWRmqkWE0Lgg+MjvsErsH0IbWReq6wBYa18fEYElyd6WI3uOsfGbXe3rncUGOwVjF0VFDYTWjaURFi9OBw6M5dineBhuTAjNWRBVoe8/RQqR+k3GFLhRPPHuFUVWId1FMKTlolo0jIuxMowWMK0uLtRq0gINFaYZOmNKGvWULyotpftT03h0HXpS8nnOeUEdcGyRt0wdcCFTGSkiMNXgFfn0tyXT1tD5FIiGlpVa2EE/MZJK/7hmltZE5OkKhZC4NMUJiE4XEiDXGUCCBDNoa2n5d7i6AU2EtKoBHPJySuD6Fl+QUJqgKSd8VX8qAQbyn1lOSQNbmfJuEIABsXm8zeJTvsfwzpY8DL845YURHNdxbqNQcigrvPMF7bFkMzK/Mwl73RLODjFMPINP6up+/gyw5zN/BiolssYVi2fhk35GaT4nNNhjZkxqAXr4Ta3SSRicGsZJ1SOLXc0NE0qmLoli9d4yDnDNqWfu6rsM2lk53xwrw/D2t1k2AOOBtsglOYC9igJvXZ58aiTKjqdSL0yIHTVOqBGcUGFvQzQ+HhpFLQQ4hrjavIYbVd6Yzyy1K7WUL5vMG7+S+yGE/w2Y8bbDlfBtGpcZ7PfgELhYds/kltDXsnDjBZoTf+3WP8/u+4Sl+37f+XuaLz1UyqHj0sV1On5px8dKUv/m33sDb33Zh+O3ddx7y4Y+duO454g/5Qta0yNkze3zq8btQKn8/eS35zGvX8+e3aZqSBx7MpvzXN4H+yHc/iFKOX/iPt/PMue0XcDzXD+81hfX0btW1v+uuls3tCV/zNQd8xZe9lz/2X381+wej4ffv/Y07KIr3o1clPEEHgvNpjglD7Qg3gPAySLv2o3e+8zHe+c7HaBrF9//Zb+fgYOsGn/l32lDX/HvExYtw8eJdwH/DQw/f6DkB8OxsL7jz9ou84p7nOXt2nzOnDjlzqmFny6MRb12XGuCjuqKw4v3XtN2qrlcDqQ/vHE3bcHBwSIyRsSnx3tH1LjGGNYVNKpNiJEnytqDrlQDfWQHi+9RMitJccWFopg/+xjFSa4WymvEosLU5ZzoNlPYKbTuXCjGtJXl9yIFYJkm8Mya7XMxpl03674iPqekRV+jEsql45tmz7Gwesrt9wHw54Wg25nA+oWkmLJoxi8WY+WLM7s6c0jquXh1z8fImz17Y5uBoStcWa6Da7/Tr9v8/RgiGX3rPl/BL7xF/yS99x8f5lj/ws3SphvDeDQxrYzWzhefK/lWcu4gPcGp3AyKc3Nlgc2NEXZaSkg5ABH3j71muT0DJOjsot/LDtfgnoyRdto8q+ZAHYuwRktBqbY9E8IEuruyahBAjvmL1eILRSda8hrPkWvCzjQygRSPEHms8PijWSiVcIuk45wd8wruk0FOSlhujWFZpY5jUFRFhsKHVkCD/QsbnNRBmlEj1fPaZiAmkAumwO0dmVRVWNnhKm+GCEEq1VNHZVE3i6sV7TOvkB+aFeZJf1ySUdtgsKJW64+KbRVkOxWuIAaPW2EuKZLisielCyild1w6FAg1Bx8QqUBAVMUhZaowfimlIiYxpU5/lkwHEyDImoruWSHZrVWIQmCRdsJicFMXqXGqliEnKSFRoJYkWYrQuRa6YNeenJbPMYUVbbUq8lw2ESnetJgUDEAkqd65XXfr17rlE0odUYGcPFvkdMaecpckmhiGRTDbMTr7TEKirEcYWYOSa8cETvEuJNy6BYsIsjOl7Q0GVPICUUoyqirIshQZeFMmLq6AoS8qyZDKZMJ1OxejPB5q2Zb6YcXh0yGK5pO/7IYbaEFBRJLBN39M6h9KK0ljGozEbm1uMxhPq8QRbiF9KXRfJPF3Ogk/U8JA29/m/n3xql1/5tXv51V+/l/lnkUX81o3I1uacf/OPfobdbWEG+gDnL1/hmef2uP+RJ5mONVuTbU7tbnDnrWfZ3pgwHlUUhUUhRssuRFrnaTuRdYYQZVIEPvbxHf5ff+n38lJYWuuPLwoviXXeJBDss28ePt34E3/s3/DaVz1EQBGjpu8F+BU/w5K26WErnaEEGgkbI5l0o8HopJtnYPj1rmfRdhzOGuaLJfNlw97BDFRgPm85mC3YO5wxbxqRF+XOeFo4iIrCKLrWMdM945Hh8LBltxjLZhJF10UODjvmiz75d0CQHA1JtCMybxqUTlTpBHQRUuGXIp8joLSXbrxPEcraUZRxKAQKq5jPe7wLg4dNoSL1pFyxWhPN3BpNUJGitDTznmpk6RqX5kSYz3opbBNbQCsJTRHwR5hPMbPvoiQI6sJQEGkbR5hHtO5pu56q1NS1pSw10UvqaFEaqtIwnhaU9QhjNFcuzVgsHUfzkDwaoS4qjAEfO4wVenpRCZjrlWM0rilqTQgaFQ2Lo4AuFb4P9L5HESnRBBUGLyltMyiRWIFa0XsPRtG3jqhEcqpKRWnMMA+rtVtC5YZBWi9iFDm/9wFTmYGZoyyoYf5NrjwJgPUqCns1RorCDqDQYrmQ4ibGNDeJp1cMAe9bQPzXlC5QAerSMm8b2r7HRCMNLJUkMSTDda0xZZb/pQIorBg+Pvjhs6ight/3QZpcRq1k8pGYZMQeHVeBAesSQakzVx5E2eMLIEQr66XRItcfKPyrzXeuB9ZZYcdYyzlcJTevkHPsvMhEQ1q3RpWhad3w3matK5z937TW2OR+pJNXXvYUtZqh9li3bohhBeCtA3Xr62yMEiCjTVpnE4YinmTH2YT5GkKBSu+X30srPaxxKoGVKwa2hCNkz5I8QuzRpgal2NjYQKfGV97EDnVE8rVz3g1kIO8ZWLJ974mhQWxDBVDL6aUJXiQiNgdVIU3Fznm8j/QuAaZdz5Hel2tFa8q65nu/+2P82E/ew803XWR76wrveNtHedcvvIP3vu9eYjS8mLXi4qUpZel49rkpv/GBVfX/e77qUf7R//7F1z2+LANt+0KAMMX7P3gfAFubc5wzzObjF3xs557d5oFPnhxe6/iIfNu3PMJ8HvgXP3LvDZ4d+T1f8SmaJnLn7Rf45//qnTd8X+8Na4QFisLzDV93Hh9rog/86E+8jCef3j3+yjGmJDRRNWit0BiCUhAUKoV1xLQPcL0bkuBkfb0Rv01GXQV+6O//CF1X8hf/yjfy9NOn1x79BYDhsw/xXN7b32Jvf4uPfPzl1/x+ReXQ2rG5seT22/a5/dYZZ04dsbm5z/b2jN3tGSd2FhRFAALe9TRNS9u28ipxjguKLvn+WmuoS5Ok/BFbFgRl0NoQgab3eCe2IBm09yEO/spGe6zOidvCjB9PN/BRwj+qqqAsS2ZH+wCoNSsOeb7IQI1R2GK1xzNR0oPFs1auPaMLgvcp9CNS146tjWcGAM0WR2xOj7gZ2TYZLU2W8bSWfYf3LGZH0mJLa8jgxWoNPlr2jja5sjfh4UfP8P4P3cUnH76DL1zHv73jPb/2Rbzn1+5lOllw09kD7rj9Aq99zae45ZZzaC37TnQPXY9rei5emdM7x5WDI7Y2RkTvOXVik83pCK0UmxsjrFkBn+IXKmukgFBDZ2o4BqUQ9UciH+S7USfcIhKpipobDR88Xd8N9hl5FFUFriekEJ0BDAsMqdmfbkg65kpZZrRBFQaTBGukv0yQutMaPVgs5D2Zd5GgBP8Yj8dUiEVQft1l06LwNwwnuNH4/AbCtCQaxejTF5Gp/9Idd97hgseo7CURyDTo/CWURdKmEodOofceowT0MXpFvUeJb0ieU3JRJjJIg8MP0kxMArKGLzZtzFIS0/HNSXps/s7i6vg04vklSUwGokhg5AYwoFcTvAsBHVTyNVklQqgYBDTUemAUmCSlkeJSzGalIF7JFfLfMSbfM+nLpxSHbHS7QpFzImQIyER9g2sw+7MMrx8VGEWhrMgd03myVs593lBopUCvvFoUIgEyKXFMKYUtCqIRtpik6wkCL8bGYQWyaU3Apw56GI4pSzUzY6I0BVVZUtgidZ1sSh8VMFEpRVkKQDYej5lubDCZjJPhvqJtWmbzObPZEUezIxaLhfiUWDswD0LSXffO0aeuvbGG8XjC5tYO080dRuOJ+J5YhVYOVEjd/hXo5b2wyA4OKn71/a/mPb92H0//tvl/yVT7R7/zo/zx73kYEPnb5StLDg4XXL5ywHMXLxO84uz2lNtu2eXWsyfYnFaMJxU2+cMF34vm3Qc6H+kDOC8xvF0f+do/+C1ABvhe2kJf1z2F9RzNavo+d6hvxBL77OMNX/ww3/kHf5y6OpQAiyaiTSnGzlozmUxRZ88KsNW2VCmYQYBwKGsrRY1PAEYUGV3wAd8lyePhgisHMy7tHTFbLFFa0XQ9m9MRh4uWKwczDucNXdcJjybPVwkRCRFcAK8MbR8pDYymBb6PLGeOvogsl47FQmTXGUGPfiVv6J3n0DWJYSqePihN7PzKDDwVgOSNahC/shAgRoctDcroxNySz29M8pMyiumkFJaslTASpSD6SNf0hPSa1sJoVOOjp1n0NE2SeUdhhSktrA+Tkvx0kmpk4DECXecpkz+VyDugXXT0SyVsq8LQLiJ9B+MplJWlsrKR7lrHaFIynZZcutKjlMjUQ2gpCgMqiI9WgNhHtPFUVYmpIGoBNdv5nMW8Q1tN8AIcaKOIGEw6mTECLq8VIu8Rtl0piXohoBFfqN55QhlX8+QKy5BzqAIurKS1q7RjMZ63RgJVtF6xmofiKp1b7wOdC7jQEaOiLCyVEtP7ECPWePFoSI1zkeE5rMnpihZDYGQLtBZ6OyFQJkP6zsVhjTM6WRfEdGGlW1T8zwIGMzB9sh/GAPyoeKx4kzVTDwCRQZIgUSv5oFJKGlf5/2JmUaf1aogjh+x7FRJ4IixeMMmQfV2ap7QAX/kc5tfUSg+s8CzrVCpSFUZqCdTgSTbUBElqKK8WhkaagFF+tfVJnxeTpBaswCTFSuq5DohZa1fgoFqTU6j0nGvi0lWaKwdAMIOCa/5MwV8rU4vD8cEqDELHCLGnKEoqqxLAtwLu8nNijClRqsB7acr55NdnCzNMd0YJk9UaLQ0GpfB+VasAYgFRhETukPlJRXA+Mj86whiLKSxt2/Hlv+sT/K6330/XpdRdU/J9f/S9fO93/iKPP1Hxt//B99C0LyTZUc5ZlxjHTz8jycXTqZgzG3P9RqJtX3ipnhMit7dnLBYjZvMxb33zJ3n/Bz57YuInHjzNxYuTxBS4dv0LeO949vlJWiuPN4oK6/gv/sj76dqGg8OKf/6vvvTYs9/21vM4B/sHFXt7FUrBF993ia/6yufZ3WkJDv71v7mLH/7Hr7rhsS2bXMMllkLqtWoY0toF60+1YAImgs8+mmpYb4DhusoAclUF/tZf/XFiaAVI854f/ak38O9/4h3EmM//FwCFFz9WtVQIhv2Div2DbT7+iU/3eMf29oKbTl/hzOlLbG5cZWd7n52dIzY29xlVc1AeazXRG5yOWGsoXY2xQZgipCZ3yOqKPAHpoakTQsQpSa7VGmySQ8+XS7FUSXXLctkOvsrCkE4N+AJ0UGIVoQPWKKwGXRYUhUkS8lzfaFRqrOdmnNTsYrcg85dKDDXZv0RkTuzbhtA7XO+HtYQoAJpWEhyitKbSC269qeDO287xDV/94YEJGyMsW8vRUU3TGg6Pxly+ssUjj53l/k/ewvmLO3j/4jyVvjBezDDM5hs8+tgGjz52K+/+xTcCgbpque3253nFy5/kja9/gFOnlvjUVA7R4WNktmzY6ANXnr0qYWyF5fSJTeqqoE7XWWENVWml1grXrx1aSUBTJDVCg8ggdbpPnA+gfLre158pFMf1tTfogA89o0IPa7sEkuiBnb3O2L/RiHr1+4x7GKWOAXwgzXMRpBm6Tryfwckanl7CWENdFkStUanYjTHSdv1gLfJCxuc1EJY3XCFtyJQWdDQkccrwGJW/nED0Toq3GFYFk9aEtaJVClKf6PpycnPBWNpkzop8GZ0TmY4pTUot8kN31STghihddTKbKYrUT7OaXI9/rJQWGWXTL0Sy9Ly1jWOORvUhJmlTxCZWQj5eEpMLo9Emp5Ct/Lycy4WsGrqqK7aRDHkd5HGDtj753cCwoYqKpE2Ow+PXx3o3Od+wPkmh8utaYynKgsKWw0ZCNgQS0QwqMdU0i65N/5bOb2HtwAIIweNclySS2eNFJFcxBkll7F3qYicQTEWsMWhdDcEAdVkxGY0HA16FJBJZYylL8QUbjyZMNzapqhptNF3XMZ8tmM2OmM/nNMslbUp6TLvR4TxIT1/Ar2pkGI/HlFXJZLLBeGOTsk5JVypCAlq971cgmJOi/JMP3cRP/uxbuf+Bl73Im+g3c0Smkzn/7Id+lt2tOX3vuLrXMZ817O3NuLJ3yGLZolBMRjU3nT7F7TfvsrszYTwyGK3wCH29670UGIm9I3Of5u/90Kv5t//h9bw4oOp4wV5VjhO7Sy5cHNM0BQ3FNY954cWAUj1//I/8PK9/7UdwrqXvHStZuljDWy3XdW1GTErR/kffD6A9SgIaispiC4vxKf2262gWLfPZgoPDOQdHc/aPFlw5nHM4m9P2DmM0be9o+56r+4fsHc5oOifMGqUzDePY8DEyaEyUpihKvBNT+rj0KV00eQAh82dImFhUEd97mS+CS/MtMr8k1CszQ8pC/AXwKbFSydxjrE6G9pqikIQYUyjqskg+QjCdCCVcayXXuPN0nRMJk09zo1eycmslBv9J3plZSnneikXa7HfCRlWawWcp+oAnYi3YQqGtzMbRi1Gn94HoPdo4MJo+QOdEluldYGOzZrpZcelKnxhW4l3Wdh1KB1ywFF482Ywx+OgwR5GmbVAKZodz5rOW0WiEd1CUVs6PD8kPJ8vbMigmc2tZGkLanBmrCX0kKgQ07j2l0YMh+XBlK4FNNAzFijFm6AbaJHFPkE9aA64trHKxLtLONnUUC2uFga0Y2MhqaEytralGzOej9xRKDJVbetCS1ByVSF5CAjiIef3Nx5S6jx4MsrHIjQujzdCZHJhJSYaYkzFVMqzPpv0ZKFuXU/q4YprJXRwTWzixThLCl1ll+f0G6V4IxzqeeS02wRBNHIq17Ms2qLjjWuMphQhkgArFAKRln5EobyyfKwEBRiuyviBLYXP9MnyeNUbYtQ0vY811/jn596gEiKk1v7iQke/V4/L9P6ROroF8w+sNNYgazqEcS8ROpvhunrq5Zli/8zWqjaYIhYTZOAE5gmiSV6AaEhxUl8LqKIqSSE7Jjit5ijGY4ElkMbnP4qo+WS6X9Bcvim9qVVGNJthiTFGVBO9YLlrmR/uc3LX8z//DP+Dhx+7lB37w6/nMa8gATafvQ/6uqiQbG3Wf4bmffmjtxF8wjWZZM0mv9eY3fIrnnt/hmXM3fcbXeN9v3ALAdNpydDQ69rvXffElAR1vsNkCOH16ITLiEJjNrpWQRv7in/8ARvnVZi3NFdYqgoOjWcG/+Nc3rl+MWq6xJPPGTDZQlV27h9Lo8zUTNUqFtP6kdYgwfDuZOel8qseJKGsTW0LxB3/fR/mD3/gxlFZ0zvLBD93Gz777dTz59Gmck4bn8GG+MH6ThmV/f5P9/U0efOSuG/xeGGN1NePmm85z5tQlTp444uzpOWfOzNjZOWA8ng+N75iAzlwf6NxgS/U8MUqie9pP9b00pLN3pLC4UmhYllprYWCHgZSg8QGi1pjUTMlNF5XaBXptvvUx0vUBtMNGAWutQcC9SEo9JyUDB1QRqU0h830C0ULyvPMupMa+1AHy+dRg0RNiROuOjemSzQ04eyryqpdF3vnWj6c52IA2hKDp2zHz+ZhlU3BwVPDUuR3uf+hmnnzyJJevTIaaYzW+cN2/tKFp2hGPPno3jz56Nz/101+OUoFbbrnMd377u7n5pn2MbijLClPUaAsu9Cy6yMW9hhPblqPFkqZp0CoyqiV5XanIzuYUpaFpe8Z1hdEKF1NIDrK2ubbDjIpUY8s11odrgTDAOwpbyHqphWDkY6SPcSDWCE4xrGYc63oNY23vH0Vld8wnVSVyDqv7yRgl+FxqqttUF2VAmFRDBGUIg7c7aV23FEWgKH4HeITlxDTnhbJaKEBJqqIdiuM17WuMRMIgQci6V5U2olqvkqDyl6qIQ+c2F4PSMZYrxkYrhSjiPWG9T8mIdlXggTA91rtR6X9i2njk4jRfVDGBZYOyKU2m6+wrOQfJBDSBUXqtAB/eZ6U230kAAQAASURBVL2jrVYbhQy0DY+N8olVPA6ErcZ6AZfkiFEPl77o/FfvK1RNhs2VTv5aOTUsS1Wij8N5F8bAysdmhXDLBsJojS1KOaedwmopWoyxwx/5LCaxa4rByFNeW0zI+1ZonSBFeWYrGIm3kNdSlrIoGY8mQydcK0VRllRVzdbWJpPJVDaGStF2LcvDJYv5gsViQbNY0ncdzolRvYCkBq9TIloITMYTRuOSsqqZTMeMR9VAycYWgpnFXrqaid0myYie2VzzI//2d/NL73n9p79J/hONt7/lKf7af/9LhCDGw5evNFy5esjVq0e0TU8Mkpq6OZ1w89mTnD29w87OFqNKJK+d74i9AJJ9L15MLgEel6+WfNv3fitCB3kpC6/CmMDZ03Oa1nDl6pjnnt9Iv8vX84t73fvufZxv/v2/zKmd8/S9Y7FoWBXYWaAcMXgqJYbSHga9f4yGru+JpLlKixeR0H8Vy0XLweGcvb1Druwdsn8442jRsmw7mgSq+uBpF5JEe/HqPsumxQWfdPwivsrqowH8huE2LqzGloaiqmjmC3y38s7yIRB9lqNlAF5kqvl+gkiIAi4TIgHxtZNbNW3WY7YnUChtsFZTJT+vUZL4aqOoastoIr4hXdtTV+LB1zZiai/SSVBK5I0KoUe7XujPzq38ijLTUykzFIvaCBsuhCDBIsagaimQy9LgUlImKlJWwiKJXtF3wqByXgBnOug7T98JC1kAFkVRiPwVILhI1/VEfEqWlC60NkqkHssmJb9a5rOGw4Mli3mPUpbxtKawBl+GTOKTc+4FZIypANFa0Sx6QideJ95HtJVE49Y5CmeS1D3dAUpdu1ccLv/MitVap4aNWv3y2jspFSzy/aakxFQcZXAJVaKwA3gFMTGEpODX6XyoqCBELLmTl4C6JKHzPgz+EFprYfRlw3cdMZhh/RYsRtaksigHlm9uSGV2iA8eglyfPvrB0yKv1UMwzjUjf7aQ64cYh4Kt0MUxa4MYxXtNFr1VwE6MER1X4OAgc4yr2iIz+YbXQbwRAYIKqyJRGXIKp9QQqUE2VCbHC81jX3k8bp67PrTWa43DVb2Qj4/8lbJWs4SIw2CMJUaPSuEC62DZsfdTHDsP+XfZYy3agtDI9b/uWZfPY2GKoV6LRWLEe5+ksqtqx2qGlG1jxC9MvmNZk40zqVkpfqtBKXQyY/feEAI0ywXNfoMiMh6P2dzeZbppMXaMd1KcFUXBuBxR1TW/650X+PIv+/d883d+8w3P77GTcM0wJhBiTo089o3d8PHXjnUQDGBvf8p/9ad/lqaJnL7pIs89f+rTPHM1nnhyGwDXXz9b/Jd/7EFAgOQbfYa7795Pm/SINe665yvV4dO9BysQyruI94r/7i+/k8Xi2qaUjNtvPxrA7GGkh2ltr6lrZT2KZLmydD9k/RM2RAhO9gMJ3LZaE4P8bQtL51oCCkOZ7FQUBZF3vuMp3vn2J5IMXtbZK3tHvPsXH+Hcc+DDzVy8eDvevZW9gzs4OppwY2+3LwAIL32IFLNpt3n8yW0ef/JGDEIBy8qiY2trxu7OHmdOnWc6PWQ8atjcWLK5KX+f2D1itFESUbRtL3VU7yhGtRANvKfvxLLEWDPMhV3v0LqXpri1xEITtSTiGtQAfGWWV56LAwI4BKXRRYFR0jA1RAoj+1TnU8BIjERkT5Sr1Jia4HleFdkYuKjwiELGeVINlPe0MdWEoFXAqCCEicRu08ailKaqHOPRQuZWIq991WN8/VepgUQhib9CqvDB8OGP3cpP/Ox9fPKhs7RdwRdCAF7qUMRoOHfuDP/T3/rDQMSYwGte9QRf8bs/yt13XWQ66QlRWP8eS9N5jhYO7zr04ZLNaU9dWZaNwznPuC7pnefE9hTXenqfanuXPcqk1svNK7EFCMO+WyEOQhqdvO68AGox0jSN2IOU9YAKDM2w6+qn43NdDk+y0WKtrFm5sRdSfWtSmnZMTUPrVzWJNat3iCj6kD2V07spRWGlBu36G9c5147PbyAsASo5fchoIftppbFKihyLSRRZN7AFcqdgvcgTuZs51oVVycjdaDPIKZxzKLt6nklyPgXUZTkAPqhMcQWICZiLyfBeNjJ5p+hD9vNIHighT3npfaR1luR9x/09kjoxSS4VVutktLsaMU2OWYKlVGaarZhnqyHssMxAkM8p3f31Vx06Ccg59T6gTC68V54rOWIAEshVFEOcevZ4uZaq7p2ni901rDSNMSvZYgRGZTkcSwYqYzLsValbnwGnYREKK2oyaMqioCwtRWGwRfJui8l41xRYU2FMIdeStZRVxe7ODqPRiNFYkpjmyzkHhwccHh4yn80k5cqHhGjKguRdT9/1gKEsK8rkOba1e4LpxjS9Xk1ZgAQiRHrnkneJOw6Eec/jT5zmL/2N731J981v3vD8b3/7XdzzsueJMbJ/sOTqwRHzo4aDgznzeYt3no2NCTfffIqNjTG721N2djapquRwEyOd8yx6Wdh9iMnQPPJdf/xruHDpbHqvl1I4Rk7sLtneanjiqW2evQ78enGvW5Utf+y7f5pX3PMA7XJO1zuuXJXNp9YRo0mS6nT3atABou8HwF4n36+oNE3TifdXXC1EXecIEY5mS64ezNk7nHE4WzBbtrRdJ2BZAhWc9xwtWnofWDQtSkfK0q5KEcF1hIVlZM7ReUMbI2VhKCpLCNC1nr4R+rFzfujCrM8NPvrBB2lFf9ZAwBIT4CNSxOyrRRQQTOShkaLQjEYFdV0wGhUpDbMVA3mQezD5gRGlO9t3AoqGdH3EIGycrg8pJCFcM4fIfJHnSO9FRlFVBqUN02ktXnsjmYvKomB22DCbNfRBKNVVXUBUKJ19uqTzqhNgeXSwxBaG/atQVCXaAP0KBAlJwtsMZvfCRjJG0YwKJpMiJcFGXB852l9QjyuM1TircV5ArdzoikHk0CJltFKELxSHrqV3kdLK5ypLS+cUrTPYmGVvKb0vBZ9EtWqMeHq6rqNI7L3ciNBKJ9PzNVAEKeptlpiS1o8g86qANp5ywJbVCkuLJL8wkVoaPVyGAhKldaAwReoKRnqE2beedJn/zmxrr6Rbz9pGI8/VEqSiB4+tGCO971O8OEPzKjPFrLaDufw6kCOHv5JKZmBmkBgW5jogbF2CGFR6D6+GYIzsv5XZV4NEUR8HoDKD3Ac/rHPplhu8slAQ1tdKeYHjIFhcGc5n38Bj4Nbae1772ddZ63IOBOKHIB6m3uMFQhW/uRhF5rxWrxybMxJomdllg99aEFZX1zYIeBqG746wYveJVYNOjA75DCFYvHP500tBn88fEe97dEzIsBJJR9d1A/Ao38nqctUa+q6jbZbMl/MEFks6q7UFtRYJaVFVjMZTitJSFFk21fCDP/Av+K/+5B/mxYz9/ZqoLJcubVzzmxe+Rr3srmd57IlbkASygpM7LTvbl3nXL78S7z97uZ/tAbrrgmIit9+2IHjNfH5jP5nXfdGF4f7IFhvrI1tq5M1yjBEvcR78+x9/JZ986CQ3Bv0i3/FtD9zwPeWeWAHZx2Q8IdC2Dud7gs8SSE/ftfi+S/cnmMJSjkbYosRoseRo27mA8CZJvJPKIqY0bxIYYAvLyROGt77pJk4+8RT7B/fzJW88x333XmFnd5sYIh9/4CEeePAxmrZn2bZsTEbcdOYe5ovTfPRjO1y49E4OD+9muRxx3Pj8C2DZSx8ClnW95dLlMZcun+bhR1/5aR4r1+vW1pKXv+yQu+58hpvOXuIVr3Ds7u7T91J3q6AGti+If3SIUBjLeFShKAgJVBDpuU71YBxIClEpeg+9z8wtLbIuNEpHtJaGV6GCsBKD+ENrvWpsRAsmRIgryxcXEEZbaihFpWRdjlqkdsGv9j6EVJgK6SGEiPI+NbbES1ZpqcOMEsa36mG4HpUayApvuO9x3vjFTw3NKNLcPF9UfPjjt/LeD97NJx85ydWrU16sj+Lv7KHw3nD/A/dw/wP3AJHJZMktt1zhbW95lFe/6hxbm4adnZredbi+ow8REwquXprRti03n95ktuyIyrBoRBnVdaK0sVbTOoexXVqzZB01RlZ65xwK2KhXyiznHZ6Ij4rYLtDWossRat0CgrU+6o0+1XpNmBpdRpsEDsfh8lixxKVpWhQlvXMY4weyDQig7ACuWW60tqLyMC8M4vq8BsJkwybSmEjSuiIbrnVD9fVeuEpt9gx0rUeKay2JWMQ4PC5ECEYmNwmmkUIyF4cmLZQahPGQut2ZRSCbNNkU5QI1Ua8G1lROQclHK5ISM8BgGVgDrivUsyGy+Igl2UjeYSQwLYOl6+wv58L1Baq83eCTkX6bNtJquIjXcTOVHp9T7a59vczOIIaUrpK6tcrIBsIq+gTw5IK469rh+8gpZyb5hgFDsEFpy2OJXHH4jKv3z1r8LAXNm+SqKDDaMh7VjOqaohS/tXwTF0VJUVRoXWB0QV3XbG6J/LFKANx8Pmdvf4+j+RHzxZymbWjbDu89hRbPM5kYNLYo5LWMpaprtra22NrdYrq1TVmWWCObvxA9LjGDeuckHWtIGpFz9KM//TZ+9Cd+96e5K36rR+TVr7jA3/2bv8RkLBKwy1cOuHRln6tXjpgtWowydG3P1tYGZ8/scurEFidPbDMZF4mGG+l9i06AZOfFByz4wPvev8Of/x++gXUg+IUc0/pjy9Jx5+2HzGaW585vcuXqtUEBL2Yxjrz9LQ/z7d/0U/TdZY6Olpx/rsO5DqWTGaOKKC3dZBUVpbUQFVVREEsBb8TfT6FDjhSHq3sz9vZntH2g944r+0cyZ0TFoumYNwJ+9dlDLs0TbdfLeXOeZSudd5EbCgAsG28BLHJnxRbyd0im0HnzH0LkyqV9Yd8s5XoTcIC1DeJxlsixM6l6YWmUhulEwiSMVSznPV0rnjvDV6mVGM6PS/E0SEa1IgmVtN2+lwRbHyJ962halxZvkh+QzPMKTQi52XD8uFbJiKnJUWqqkaGuC4oq/W0t9bikKDXNUvw3mmVP55PE0QesMWxu1ygFfb/yKup7z8H+EmmSKuqxSx1c8WnqnU9zvsd1Wa6ZGgpKGGUxSgBAswy4HlCKZtlS1wV9G/GVJCai8tSfPJxSZ1bpiBoVtMuWg32P0gGvAptK5EwixzRynnzAofA6pkaNpAkPMrYU8pI/n9YS211YBuBBgg509iVO370kZqEk1bjtewqTNsKJYZuTCzOI5IMXtW5IEk2kqAZh6kL2g5RruvcyX+RbdpAKsmIL+bhKFVofx5KQ9SqpMb9OltDKh1nr2F/DllpniQ3ASdoUDelM6zPGGssps9TWQSAdJSgnJyflpFRhshw/7hjjsdTqvO73oV8dp4aBWs616+8aQLwG4K0Dh9c+J3+3QGKX6hUMlqbaoER6axLYWqhI8B0qsexsVUrTpl+lnurMzPMej0+F9+r85c+Pmw/nKvuvDYED6XpUQZpeIQpYJuBnJZ6u0a8BjBAJeOdwOKmw0rzmnQCJ1lhKU8q6FPLm0kuyuBKGR+c9bdcxn88keTcq6tGEorBsbW1iDejY0/WOED0ndg3f970f4If/8Zuvuz4+3eg6y5NPbjGf3yiZ8rOzwsqy46u+8sM89o9uobCBrtc88dQJtrcu84EP3/OCjwMiPlz/XtqI9cUz57Zu+KzXvPry8F0//czOsd8plRq8UVQZkZzW7em85p/+i/vyI2/42l9078XrfpZBsHVZc258BO/puo6mWdL3HX27pGtbXC9s3ESQQRtLVY8Rk4oCrxXRwf7ekvlyOTAjrDWSxptYzdZaykIaqFobbr/1Vu64/VZCCGLRkXwpCYGX330bKgaeOfc8bV9z89kzvOyuM0QidfkeHnzon+C9Zzwa8drXvAIfAg8+8gQbW6e5dOkUVy79bpbN69jbO8XRfJKYf8eb5V8Yn8tQxGjZ39/gAx/a4AMfumXtd3k/EajrJadPXeaWm85zz8ue4M67HqOslgKI9xo9yMbXX3nVUNJKvAd7D8porNWYPoFKWpp/vVHSSEhrflSkBuMKPVDapMAVAcMIAZ0agHmWiCq3JzUxlLK/DB4VHQz+yDE1SBh8hgUwhhBFmlZXKyJDfrzgXcmDyVgBi1UC89K6UZaOd37JY3zplzyWzh4Erbl8ZcIDnzzD3/mHX0VR9Nx0Zo/zFzbp+pIvXM+faSjm8zGPPDLmkUduA2AyWXL7bVe45ebL3HLzJe666wLjySGb2wU6iofrdFzz+HP74h0bIj6F1RkttZtNYQ9KQVFq6qqgtKK6MErjyzIZx0RccII3KYsuTGqEroDhdbXbpwPDcsNRallLYYXZ7RKDvyyK5Au78i0FKAtJmP1sY6V0C4P9wQsZn9dA2LJzVFWB1p6+l2609prCGKy2idkkFHtj1rqselV8XetRIXIEAVs0ApZZrYm2QHuNCy7R9BVGi1+F2A7E4RaOiIlh7pyHxPpSIMWXWmlxVYx0zpGZY2JqnyffVVc3XnOsWfqRXmV4fkZlJaZcWllDcR/jYBbrrxEDxxjF4H8ojFcAlzGKwogpn3T+48BO0EYDfvCFyZ//2qFSGlfMcklS6VFo8exQakh18lmTv1bgkHTAxlh0inwvEOTaJ0ZgCFEAvrX3XZ0nef2qlJuvsGXyDikSQBmGDrUxho3pBpPpBlU1pq5HlEVFURT0fc+FCxdYNksuXbpE0zaSGLqWYLZ+AEqJof5oPKaqKkajMaNRzcbWhLousVWF9326aSNt3yeqczb6d0TveOSxm/iBH/4m9va3b3B2/1OMyP/z+3+Nb/qGZwh4lk3D8xdmPPP8Rdql5+lnLtK1PbfcfJJTu1tsb085dWKb6XS88lVQYqYefZSiNEVpzxaGr/tD3wHUvLSFUJ5zy82H3HrTEfd/8jSPfGp3OO6X8ppV2fH9f/xHuf2WjzNfNBzse9rW0feeo9mc2WJGYRWjsbCBjNW4PjCbdUxGJX3nGdcVO5uTBJwmhpNzLBYtPgSeeuYSzzx/ibIu6H3g4tWDIX0UoHNOpHRdR9evYsMzq7V1K/mcMYqc2KKNoTCaqjbYQoyiR5MKYwyHB3OahaN3nqN5TwiNUKX7DosV/7Dc1kkbxmxGnjfCkcTeUAxyNWMVysDmZp1AcQGssmeFNuLBVVSFgM5G0/uAD4rRpKYsLPWopOtECtlFx2LesZh3KYVSJXmteGt4J40JpZKLVUzyRy/zu7WGqjbUI0s9Et8tohpYe5khNxqXoMD1BeXMEHVJlv9t74woqwIflbDSOofrxZ/PWMVoJMmWWhvGhWbZACoSjMKpiHMMIFj+o7WsLW3jaKPI/7rOYwtNs+gkTVRHtBWfw+ylpDXJ+zFIul0XiKFiOq44uVOyd7BkMq4IKFrnKINC+RLjoW/Fcy9CkvQonPMp7VZTlZbOBZTPCVYWQ8RGk5u8ZJ8nR2pA5dsuKjEXd57OOaoyMEmAfWVKlIFlcPjMyFYioRVGlwZlEmDmB0lfLoCKohgKpLwOZCnj4DGVm1Frz3XerTXC4iAhtDp5qq0Zx2cAap01rMKq6YOSNUZYIYlhqDxe+cSaS8wkvfLPHKZ/xQAwHpMnpkKNyCD7zCMkv5j8mTKLC9Yix1m3WBDwKIOF60y0fD4GJtvaceTwiPzfUtAKYyqvpwpAV5JWrCAGJ+BQ9JTJSD+q5A+KQhkBpLrMtlljpWmtsWVN8IG2mSe/nngd6Je/0/XjF9a/E1+4FKBjovhqZvm28wKg21TS6uQjqgAfe8KK1kMGlSMCRmbGoYqJjd5JUp3rZbNXFMVQ2TdtS4iHKFOyu7NNNa7Z3Za0w2YZiLGFKP55X/M1n+IDH76Fj37s5hsvMjcYP/IvX70W2rI+PvsadvPZSzz9jMgfbeHpessTT5/gDa9TvOJlz/FQ2kB99nH9hlTrMCR37u9XN3zW9uaS5VKuix//6eMA4IndRZIkZhQ992oj7//AzWtm3dcPax3GdBDFUZXErjEJQMjKkGwb0Swblss5B0eHcl3HiIqO6FrioPjIn8sJ26BtUCnMqlt0HBwc8tz588yODii0bBCtFuWILSvKskabMgGpRgJHjKYsLdPNKUZDWRVUhWVrPOaNr30Vr7v3FakpLPek6x1vuu8V3HJqh4OjGRuTCS+75+Vip9H3PPrYU5zaOeSdbwX4Zc49d579g0PO3nwLb3rTW7C24Bfe/T6O9seMR1/HE0/fzXPndzk4mDCfl0QyYAYvra76wljr4tE0Gzz9zAZPP3MXv/4bb0u/j8PfZdFx223P86bXPcQrXvEk21tHVNXKoyhGWCx7ytJQKkPX+WGNyBJKlbr1NgFdRqXGVWJ0y7zoV5JGrVBYqft0enw6qj6KXN3a1FSL8icGN7Dclcr7SWkAhBTDGwEXBNwLXhqvEjqxssowRlGWER1E1aC0RZHWUwJGZdsaLcwKFDvThne86Qrv+McPDnOq+AQKw/LJp3f47//aN7C3/0JCR35nj/l8xIMP3cqDD92afhJ5+T3P8iVv+RRvfvOjbIwqOh8ZjTco0n6y73tiDHRtw2LRSYPIOXrXow1sb07Y3h5jtGFjPOL81QNO7WxijSGicd5jTKSsSqIC51cBVRGZa40G+2mm81wLGH3cPkprTWlMIqhkBtpnBr7WFXGwwgpc7+jaViT37neARxgg0hgfh8XNmMSOSqmNIYgpMqy+BKUUvXOoEOl6T10nE/She51eW4FJjCgdNVGFJLuUznxhCwGZXAJBhmI3p08JLVYwqswUSPKE9MgQBIkXv5kIOoFsSiWUPckUUkGZvS702gZBkWj9Mft1xCTPktCAGElySxk3AsGyV4kYiqqBTaGjGqRV1mgwK9R1ABZtMmRUyYh7bchGXSfJ5mqyV4pE410lH6o0MWeAL8cDaxRFlM+ths55IBpJOgt9BrvSJj6u3ltS48qEfOvUeSmoijrdhCodo5LuYFmyMd1gd3uXycYmxla44FnMF1y8eJHDo0OOjo5ommUyrPRi1rvGTJNNuaRaFbZgNB5T1xX1aMR4XFNXlrIUCWvj+gG5DiHQtD29E8Dj6pURf+8Hv40nnryV354R2Zgu+Vc//C5O7MrnXSxaruwdcOHiAc+dv8wTT5/nta+6kztvO8PW5pjbbzvN9kZNWYpfwKJ1tJ2nLgv6XozHu64nhsD/9A/fwE+86w18LkWatZ7X33eRCHz4Y2d49rnN4dhffIcp8pY3Psx3f+uP4bqLXN7b55MPHeJcpK7HKCV+gPuHRzx/6QoxBLa3xlRVwcbWmKZxXLm6YFQa5vOGUVVytNtgjBm8og6OFswXLbNlx8VLVzk4mg1MSlsU2LKSeHAfhIGwWLJYNgIaAR5h0hSA0uLz4EPAe4XRIisblRX1yKB0xAeH73uWs5SENu9pmi5tMNcA96IWto4VQ1Zb2CSxjgnsghjk8xMDy3m/YgopKey73hEJVJXFO0vXOGkKGIU2UjhZq4f7LtPw2yZSWE3b9lLFmUjsgahwfaDrAmoA9GXOJ93u0rQAUxrqyooUxkl36+Spmq3tmqqWeXo571jMOspCY4okgVZKgKDSM9moODXZ4HDWCNMPnfwmFUZpnDbESjMalWzvTAgxyv1cV1ijefbcJdolwlZpZZPmEG+z9WkxhCiAV1Riyt852jakdcnL3BigLErKqsQYCKEffBR16hKP65LNjRFHswbimv+V1vQx0C9aVKfwfWDWOJa9G1jDbWLeTScSDDKqDEWhmVQlpoDKWLbGNXUqTLLEvOvXN5Iq/b+wmF3yLWmqTs6rl3mf6IVWHwNWWaKSgtnoJHf1vQBhQUDclURPU5c1Td/gox/YVAo1RHav2wRkQCT/bDDPj8lPVPmVtH4NqFn/d2ZvKaUGH5b8Orl28F4ixX2Q19Nm5X0ZQkyMoRzdvQKmhhTkKDLjvO5mgG59BL9inWfQKwQxrNXxOMMsEpOZ83ozasUAy4/JYF5mTMIacKYUphyjFLjlHJVDPGgxroU8m4YMrKXNW8ILfa4HFFSVACX5mFRIoBvCnC3KYgDCsom+NmndVzkUQA1MyExPz6BmJMmPk19NPhd93wtYQ2agScHtQ/7vjO/nTeTqD4gx/qJpWCyXLNsGHwK7m5tMxyPatktNKk9sG7rlHBUdJ3c2mYzHLJfL46BqFGnlN3/T/S8KCHvgE2e5PqDihY1Ll3d4329MAXjVPRf48Mdvp/dS286Xn1upf+JEkxKue7obevlHitKzmMu5fuaZk8d++w1f+/AxRUJ+TvDwd//+Oz7je3/Pt/9H+uWcoioSw1m8YJWC4Hvmi4blssGnxlHvEutlLblUfAKtGCwjzOmYGZFR4fuOLl2PTd8QXMe4KpgfBly7oO0j3hi8NagwBWvxUdE0zQA2k5j/m20PBKzWbEynGLWa43LqJcmnOBK56cQut990ilFdU1YKPR7xNV/2Fr787W8gKnjy3Hl+/QMfZ/9ozu2338Eb3vBmTp0+w/0f/xhde563v/U1fPF9z0E8Ry5+Dw6OeN9vfIT3fvBj2KLG2nto+9fSLF/GbHY3B4e3MZ9v03UV4mH2BTbOSxsroLHrax57/C4ee/yutd+vGGXj8Zy773ya22+7wqmTB9xyy0XOnLmCMbL3GbZlEbq0f0/kaGmEpf2Y/Dw189L6Q5r7M3hGVITYo20gBDPM+TGQEvbk0dn/Liaf7RgheEfwDhtXIFbwDuf6Y+sOaY3pk7G/8pEYXWK9OYySPc10Wgpz/JqzohLbOMtJTQjccetl/sUP/XNJxNQK5+D5Cxv8H//qLZx7dpszpw/5+AO30DQ3Ys3+Th+KRz91K49+6lb+2b/83cNPz5y+ymte/Sx33nWRne2r7O7sM54eUtd9Cjfx8p0HT1SKZ54/ZL5csrUxYTIZ8fyVQzY3JuxubXA0n7MzHWErhScQddofJO9OrUQVcT0ZJg71k/zXqkEHuXa4fv45xmiPK1JD3nu4PsmCEwDbdz2HB4fMZ3O0XQ8z+czj8xoIyzKRGBDPoQy06NwxyokGGXwxhMxoQOOcp3edJCfAiu2QMa0YRcKhFYqAUSJnKa0YaGpjE727T0BKTunIC14qusishQG+HIZSSphWiKdORBqXqAjBpyIuH1DqlK4zpdJriIE1SUah8DGgkrmubDpXXYf1kQu3vu8pCospTEpizJ3iuEL1145ZqZWEw2hS8cGwGZBOh0nAVByANHkdAdL66Gn7nrZ36ftcK/ARM++6tNLIcBHXtbi+Gy7tHoaid9hsrG2ktNZYW1JVFUVRrj5DBBBdslKKsq6o64LxqGYyGlNXNWVZ0veO/aMF88Wc2dEhR0cHLJcLbCrCrFUsly3O9bjAsfct64rd3ZNsTqeMRhVlVYiZdRTjysaDa0U6IlR+WTT2jiLvevcbedcvvJnF8lpJ33+KIefze77zQ/yx7/mkrK8e9o8anr9wiWefu8LTzzzPfNHxqntu521vfDUvv+cWRqOCED3WSPKhtiXOiWG5MZJm1/aeK1cM3/JHvgOOdStfyDEdf+zJE3Pue80lHn9yhw985EZJWC+8qBuNlnzvH/4ZXnfvJzg6OmK+kCCFZec4WjR0reMwMZOU1hzOF2Ko6gLjqqT1mr2jA0yhOVw6rh7MwQeOFj17iyRj7CQlsll2tH1H2wvzYOVqIwyw+XxOHyNt5/BOOjiZoZE1zpFITyAoJ/4Ra54rWhsxV48a1/YCdimkG9SF4c28S5v4GDGFRTx1CopCS3dPSaJlSB1srRTFSObbxbwVryy/Np8l0Nn7SDWyOBcoCgFPMMcZKLIgajCS9ug9HB621M5Q1hprFU3jaJO0UuaExAq7wfxpK4PSlsmoYHOrTowhqKoSkwBwEP8xW0h31CQpZtv0TEYjRqcrTp2eEpxnZ7diuehkY5Pnk6iIOnnOZHaV1SnR0jFfCMOuKsT/TduIDobYhWEtkO8IZKpMDF133HfN+yCSCWOoR5X4rUVhb1mrCD5SVQUgkgalNT5GNqYVZWVpukjbOlmf6FkuW2y0dD5yMGtoO09RaE7tjtHWYmthfS1joO0DywDtwYJbTuyw2J9xemuDcWmTR6GEFuT1MUbQyR9LJcAlhMDRYi6+PHgmdb3qNocg8rQYiSaiYsD3SWasZHNaqhHKmOE7D95jsfT0dL7DKotVWSK/YkHJ/dMNzaFskK/WG0BKGOPXAiDrY13GaIwRU9f14Bu1YmU73PC4/Hp9L74CNrH40g0LkYF9BKC8AGrGmmPT2wDErbGi1q91AskH8/pxDBQMKxbYMamkT82y3g3gHwM4tJCGVvTp/EpQRMxNrPTYXOWa9LMQI+4akEMrRWFEFpT854nRo9L5UqhVMJFSg1G+NSUUGo9iVBiCa9FdCoLwcs9kaWNmHqiY/EbjCijLbLMMPg6AJ6uNZG4s+hBYNAsOZjMxy24XdL1jZ3ND7BgSyOd7T+8cdSVf7CJJ5+TzGrIsbz6b42KNMpGX33ORV7z8Eo88+tmN6tfO3ot4LMMXMl+MmYz3ALi6JxLp3Z0OYxSXL29+2me/kPHyl10m+pboO7r2Rse3uojFaPs4JeBrvuqpa0BnWHaK7/wj3/FZ3jnyxtc+hHOKoiywxlAXFk1kvjhgfnTI/OhQ2Htps18nqVZti6HeV9ETy3Io7pUSc/Ah1kYQABQ9Gsf2RkldTNkcGXIKa1lYqqrGFCUhKtreU40r8SLUMkeYJJckSmOr9w5TFDSdp1IGqwr6rmW5aIVdmFUdCsqywJSGtu2H9MCiKnjm6edQyvA1X/N1fNVXfS0hBt798z/Pxz/6EU6d2OG2W29ebVzS2NiY8vovfg22MFy+vM+y2We+fDez4j9QFS2bG3K/lEXBrTef5WV338Wv/voRTz3zGkJ4AyHcwnyxzXK5BUxZBRV9ASx7cWPFKFsstvjEJ+/jE59c/72AZNPpjNtuuchNN13l5Mmr7GwfcmL3gN3dA0Z1j/fgCehIIjkoCd/SDtbSIWV+lGaRjtKELAqbbAQEhM17YyElONlwap3WOZI/mCH43DgCbIFSVp6f0qXFtzRQJDXLigygUFr2LsI+E4N1hSYGldib8hwfFF5rqsIwGRdCjAgx3ZfS/Dp9suPP/amfFdXDcE7Tv5SooQ4Oaz712C4fvv9mHnz4Zp57fpv5ouK4597vzHHh4i4XLu7CL9/49xvTBXfeeZ4777jA7bc/y81nz7G7s6DrRaGwMR3zqSefo+06tNJsTsYU1rIxHXPr6RPsbG2kRHlQRgHSJCDGhDesOifr4UYeT1DimW5NIT7tN6jJQowczOaSqGzFgqT3Pc5LaFzbBtouWRxUFYUtuXDpHMooTu9uv6Bz9PkNhGnp7Pep+yqbjEDUWdecwCEE+MoJjJKSIcb4nXPMF03y9tLDIp0wsGSsKwtMac1gDDfcWmniiYAyBmUM2iticNIBza/l4nWFLTAUB9m0PkbwLhJVj4oqIfSr1I/Moghri57WFlT2PElGuKlJEJJHmYBRBlgBYlorus4dS8ostE768kTOSCyqfIEeQ3CHU5DkmKkj70JOFpGEzdxNl+dBNtAXKvtqk2hTUbo6L7JhV4kSH5JhsEoSEefdUFSvOvqiW7dFmXy+CjG7v0Y+E6OiKivGG2MmkzHjuqKy4uvVu569wwMWy5ZFI93GrmvouzbjkTSN+Jj40KVj1hS2ZDrdYGtrm53tbXa2NhjVpRhuIwaZ3kdaJwBYBsG81/zGh+7i//yxt3H+wi6/PRN3pK6W/JP/7V3ccssRIUQODmdcubLP+fNXeezxZ7hyZY9bbjrDrbec5s7bb+LU7hZbmyOKwuKD53DW4ZxC6YgN/dDFX7aa7/9zX8Yjn7r5JX62vHmJvPbei2xs9Hz0Y6f5xffcORz7i3/dyL2vfoTv/Ob/E81lfHBcvCg/7/qOzvU0bU9ZjVi2Cy5dOgDkfumco2k9xmiOlp7F4REmGZi3XUfX9aB0ksuqhGnLJs71npA8UgSPtWtdj8DCeZGREemDw8WwMpJcA8KiSuZbie1CvleUou8ti6UhB0ZESLT2ZFYeHNVohLVGgEpr0v3rqcoC5z1VbWlaT+8EECOKHFESHgu65E0WITUDUgJYjEm+KMymojQEHSGZDYtXRaQoDV5F6rpMZrSB2YHDLoSxWpSavhe/PEkc9InhalPq37Af58SJMSD+Y2JYLbLQqhJfF2GhSaGoloqu7QlLkVzJ5koxGctSuN+0VKVhPC5YNo6u7wdQxXuRBeR5pq7ESNQ5x3hUYA20HehCE8T4K0VXi8xcruEEIOnkXHnNZetdoCrLxMITOXFZaCbJ4H+56GkbMe0uCsuikSLDFBWzWUdAS5LmWGFMyXRT0y0irulRJqCNQxtLT2RkGPwuQcx2K6OJVvP481dpW8eljRkbk5JRYRgXBaW24oWnJEGrsFZAjeDpfY+PmtDIN1Ok60qkicm/xwnoH23A5sk0b0aDSCxNTD9TYk1gtLDset/Tx55AoKA4tp764I8BK/kzrYffeLwwyRJbTFs9SChBUguvBVrXx7qfllKKslqFteQGj0nmrivMSBKNVEo8PAY8rTWXjBKD/8zuuralOhyz0tcHVkSOsauO/e4GY73Luj5uBAz6IFJJkywi8rKfm4a5FTWw0zPQTaQwKdE0CNvLJyb8UGfp1botjIUSk86FC462C/RRYRSJmSpzWp6Phg7z2j0UVRzkGtnTtTLiHTbgSzGm5yQ2Q/TDfNz3DmsKyqJkOh4zrmsOj+b0XT+s17EUkEOheO7Zi+ye9Eluq+iajqtXrnIwD0y3thmNa+57zWMvEgi74bfGp1vj7r7zaY5mG1y6vIvWcg08+cwpjAl82TueS02LTy89fCHvsznt8X1H8J6muf61zp5dyLMjN3h+ZFTLfLiS4np+/Cdf/VmPZjJuOXl2hCkMRVkQvePwYI9mPmO5mNF1rZgth0BRiptNCG64NqxWyTB51RSWEUAZtKnJCgeArQ3FwVwRyworBDKiD1RVSVXX1PUIbQu0LSjKSkABcrZ8SPWoYGcqBhSBru3YqEYsFgvaZknXNvSpoSvMeZmn2rbHNS3PPncB5xzWGKbTMYeHRzz/7LP88A/+IP/wH/xDFIrpZMzdd97GzvRWrl7a4+DKnqxzaAE/rIRz3ffql6NUChfROq3DmuChS022whaYsubsmQs8+9zjnHv215kvFwQfec2r7uEV99zFiRM7hG7BM89PeeDhu3nkU7fy+OM3c3VvQteve5Z9Yby4oQDDbLbFgw9v8eDDN3iE8ozHS06d3OPWmy9wy82XOH1yn1O7B+zsHlJU1ya0ru5h5aXBqoGcOr1OYsiHIOzelWpHQuBAKZGH56+2LBOoFhEppAalV36YPrN6B9l9ie9dImqkhkQoZL0OARfBIyQJrYVV7nuNQ6FdDrmQdXRzI3kMx9XnzHu5uuq499X7vPpVj8lcv7Y/XTQV999/Bz/97lfz8KM34VzxuX5p/1mNo9mY+z9xN/d/4u5jP/8Lf+YnecXLz7FoWu6+pZKwruQf7JxjY2ODwzbw6CefoWsatqZjpuMKpeDMyS36ruOWs6e4rpgh7VmS1QHp8tLq+kY3yO+sMZRWGiAxZmIAuBRSVliDtbIm11XFy+68JQVu/Q7wCNNoSl2IjjmZ0wv1M4hpq0tm8kPsLcmgWbwAvBMvkT4l1ikV0kSgV8CaDwTvUVpTl1XqQAdilsQFT3AetJENW3DEKAar+V7Mhu1aa3RQx0AsSEbzaZIiKgaZZXq8XEey8ZUYdy9sgKGoCANyr21iYSTtUIwRFwKGlfeWFKopnjRT+ZEOr/yth+J6vWhe0Roz0SsOBTCILHL4bOnzG6MwpgBdMGiachS9zxH3IjU1mTGikj1jFOp8oaxEvRLT5t4AksSp1WqDoYzGWIsxBUVRYq1l3Q8OwCYPpqqumEynjCYj0Tt3Hc1yyWw2o+87lsmbSYzrxfzaGEsInqZZ0HWNfEylGdVjxpMpGxub7OzusLu7RT2wDCWFr/cSX9v1gb5zdJ3j4Udu4md+4fV86KP38OK7wL9542u+8mH+wn/zYbSJtH3L+QuHXLl8yJWrR1y+vI9znjtuvZXX3/dqbjq7y87WlI1JRVFIhygCutfURc286VksFhhb8JM/8wr+7g++nc+1SJpOWl7/xRe5sjfi/k+cucEjXuhrR8qi4Xu/+1288p6PcnX/MssWjAKb0tq0CnRdQ5dihp0T2rcPcDRvmCd/r4DMJW1QdH1PUVqatqXrHX1avOVeimv7r5j8AsPa2pDfl2FT3nUdbdsO1x1RvJSOfd4IMn1LRzFP+NW4oGtCrsQpbMRaiN7ju07MKgtLWWmIYrDvEqsJBUdX5xirWbR26CQ6B52LaBXQLs0RRthQRGHmhCGa2dM2PaPaEnpH26d5SudUX03XebQWqWiVCqtm2dG0Pc0ieweJn8W6l5DReljXho3LzphqNKIoxLxbaei6HluIoWxM590nEFop2ew6L+dnc3tMNqLtek/btozrCS5q2mUvjQ8rAI3rHXmjVZgCkC5Ul6TMEctiIWm3zktDRhudpA9xDbCAGB22suAzkCJgmy0MRWkH4L4oLNvbJXVt6PtAbzVtAleuXJ3jhiRLWed6LxLYwi7wMVKVqWlSeKposEUySLXQuZ7eO8YjWTuci4RCzFRd2xJc5MrRksPOszkt2ZlERjZQRsO0qimK4hiQhErJoj5QOEXvSqyRwjgktkyMEZvYEwrZNFamIq9tpAbUOr6R1xerBQTtYkeIgUIXZKZVDCtTegmXYbWGEYfrSApwP6wZ1lgKUwysL631cJwgAHI2vF9nW2UAxhgjXpkIMxq9CnAQFngG8ZNUU6nh9TJwlz+jRg8S0MzuFHmkbFwKK+fb+ZUvpnh+rHfjX9g4VoHElM5pV+mXea03Wny2Qoz0IQwhC11wLLtAYQUMzIEIg1TRaGx6E61SmIdSwgBYqy0GJuBkF90tIdkMhBgITjzJgtKgLNmnUKXjK4x4DebvPANrOMTjyzm0lQTbLGENBIJ3qCA1GmoVOBVS2FJZWE7tbIOq2Tu4yuHREd47bGEoK/EWDT5wdHiEc4GqnrBz4jRGK6qqQivFE09d4KabI2dvOsnXfs1H+Xc/9iUv6vu5fnz6NW5354jJxHHp8i6Hs5W3zjve8jRnTu2zaEuu7m19Tu+zs7uUVDrg/IXr2WVv/5Jn6doWiPT99SwMpVab85AaMr/63rs+69H893/+Z4R52/V08zm+a2ibOd47SltSTet0T3m88wMIei0obnQGu9Z88qSYH5rfw8iArlJSJ0422N7cZmNri61tSQwPSGqgSII1tqjxPjKbzSjoMMkvp/eOpm1pmp7x5pTFfE7bNgQnjfIi1evz+YKjozkHs/lwfFVVUlYFp3Z3qArLsxcuMZsvqOuak7u7nNzdQYXA+ecvyDwIicGsh68yKvmFMcKALgqLseKhWRQFxloJnXGBzc0tTp48wVvf/Hqps/PpIBK9QxG489Yj7r79AfiqB9CmwNoSiHgXuXSl4rnzUx5/8hSPPn4zz5zb5dLlKU2bPFK/AJS9pBGjYT6fMp9PefKp633+tHaMR0tO7B5x5sxl7rjtImfPXhVG2c4hZZk8LoUOkhqzaz6Q+X3yP5RBG3/Mbywmdk/fuYGkEJM/ZmF08uCW+y0gNUiuq7S15Og3EwFt0MGgYkgsY5XWY8AW+CiWRLWqIMbh/UMieoSwshTqXRjYZVl6vbNTk6kwRBhVgXe+7THe+bbH5N5OdcLRzPCxT9zEP/vX70wEhN8p44URB549v8NrXnWe6UgDI6KK+BjEE9s7OhfxvqWuDFZXzJYN86bh1S+7lV94z0fQSvHaV91KBM6e3ObMqS2y1cPQwFpvYqW9Ud7/u7U5fFyJOsL3PRE9pEHm3ZXgAwws15M7Wygii8XyBZ2Rz28gTAmLyygrfgBeTotN0eqZgqm1GDlLWsHq+VIIm6Ho9iHQO4kWHUzbdKTzPt2QUsx23TIZBEpR7ANYrcD3x8CigEhZ+t7T9z4xMMQzBVjF8Pby30VhKI0R9pPsgGWSMCJdiqkLmllT694YGQxbl3zE1O0vjEVhaLuOzAxTkEA9eY2B+WU0ysrGInTZnDufq3S8yWhZA65fdd9y2lx66TV5pcRmG2ORlhTE0MnP0AM7okiyTOfCcBNopZMM1RyzzlBo6rJcIcrJn8EWpTx27Q4T6UVBWdXUozHj6YR6XFLXJV3bc7h/wOxwn8PDPY4OD4Hso5aklqwS1SSCtqEsa8qyYjzdZDQeceLkCTa3ppRlgSLStVl/LaZ/vfO43vPUM9v8/C/dx3ve+2qWzY1jyP/TjMBf/G9/na/7qmfoe8fzz19h/+CIJ5++wMXLV1HRMx2XnD6xzS03n+bsTSfY2ppQlwWrvW8En0DcAGA4OLT8iT/3jVy5us3nWvjcfecVzpw+4qFHTvOe9+YC4KWxv26/9UG+/qv+d6bTBhc8T52LVJW0l4xWRKMwynP2RAVU7B1GiiLQuwbnFvTOo42irCz7h3NcCo1YtnORJy5BcKHj3SgJm10ZfcuCnT8Hw70lJuKOppNu8bBJHtjm13fZB3ZIhPFGzXSzYLxRURhol47x2NIuHZcuLmibbphLjDG4PmALDUETPShEehRBOi/J7TIkAMm75E+mcorbaiuttID9fefpq0C3aAWAVmCtlo+gQRklyVvGMF80VGXBZFwTjTCkytpwuO9SsEjyOVQZ7JaCSdhtcjqmO2MmGyPq8UgkZnhi31PVBcvWoXvpFFFaAeQLgy0tRWmHU+qcF7AoRJGkJEC+LDVHRgsruHPMZktc31OVyWvD9TgrjK0YArNZw+ZWxdFhJ9T+FVkneUwm5hwRFx3i4QHjiRxLNv1UStN1PV1nkkRSDPV90FR1iVKGZuFoO8di1tF1ItPUidGsjTDjlgth7vV9SEmNivG0Wnm0RZjNxVvMGINNCaKLRY81ir7t6RzYqDFFYNku6d0cqy2boxFdjExjYGs0TmATK6CIxA70XuQbQPQR5VVa0hQqCFNRZGwreVAOXxiurdwlTMuhwVDrmqADta0HI3xjzHVFVSQO3mZBZQmbrD8+hZuoqDAYOt/R9734WymGtMMMigmgaQaQCkjXHJKsiDCpfVq7U2McY5L/ZmJs5/VqkDunYVRKn44aFx2994xsSZGkfVrpYyCV+J+uFkQp/NeaVevNtgFRvGYKQRGTVxIIQ1mkxKs0S5VulMz6DonS6Hyg67sB4Mzndh0oDHWFMQIoSFLpCuAcQD6lQFfEvhvQ7eyX6YfOrwD7EYUqRsIK6+dprjIou368iqACRSwwIdUGRn6Wm2ZghcPje/CR5bLlaN7gfZRmVyy4uL9E0dC1S4pCZCC2sFhrKYoSlJGQm+DTfN1hcEw3ppw4cYJXv6qk7SW9kMLxLX/wffzbf/+5gmE3HsZonjsvnlyLxaqmOHPTEzz8xDl+6P/3e3nu/InP6T2+7msuga1o244nn9657vdvfdNzaBoMCw7m1xtd27SQ9UHCPi5dnnDu2etf59hrvvkx7r7rMsFHlvOGdnGI7xdAwNpisMHoupa+65LHaoNSAkgODVrXMxpZ1qYVjt8Uq4ljvsjXnADRVWUY1RNOnj7D9vY2vQ/M5ku6XmQ5KGFiS9MVbJKW5fcySN08no4wxZSNdkyzXBJ9YvVaaaAvFg3zecP0cM54Q3zpJOlNGkbBe171ylemACW/ChAZmmppAYlRApZS+EgAolNAjy0K9vYO8N6noKhS7kNjiaYQFpo1VKV4OtkELFsr83JZSBiAMXJMNsj7GyPA2i039Zw6cZX7XrMHPHLsHMcY2T8wfPLhm/nIx+/k4UdPc+ny5g3YZF8Ay17sCMEym28wm2/w1DM38xsfvO4RFEXPdLJkZ/eQm89c4eTuATtbR/JnW/7UdYcnBa+lICYtnc7hG+o6kSBrbVAa+qhokqpHrn2pZfLKZFRuX2TfTj38zEeSOgJ0sh3SWvbzipDUDCF/BHTwKLUSXUegTvfA+tIWvBtq2RAiofXMY0pNDDAep5CgyvGWNz7JW974JEoplssxz5zf4vzzWzx3fpsLFzdYLgsuXtng+ee26d1/Lr5kN7rHpMCqq4bbbz/Pl73j49x376e4eiiNQFuIdUFRFmgrmEKZwoLy8Gmfe/HqIbffcTPBB565eMAb7r2bhx8/x8UrRxAjJ3amnDm5TV3L+cwAWPR+AMKc9ymQQWqKdWsmyHiEBYwo2PpVArg2BrKK7gWOz2sgDFJnsLRop9LGSTTRxmgiNm3aEg0/x3e7Fu86QKUFLBWYPogOO1FEjRFvrewrElFU1RjXS+dLY+iD+FSEGNFrF1iMOcJTvL+IAq6IVMeQTeOFaaRTNzKm9wSVNsuRLL3UOB+SVCgmyZ/BOTd0RNfN6JQy0o3ORuxrxr0ZXY/OUxaW0iY2gk1JTEatHpOotEoxsNZC6iCvcVQB2ejl7rVJkiznkqxJJyDP2MTqEsPToWvvHb7pUUX2ChFnW6MKClMOwF3uCEsH2KSCKDEMROA+JE7aoqAoBAAbjydU9YjJVLqZ3jdcev4Ss9kRs8NDMcFfHAhLLRkZa6WFvZAAVwlHgI3pNlvbu0w3pmxtb0mRY1agn+uF5t51UiwdHVl+7j/ex8//x9dxdf9z8+r43Ebk1IlD/uk/eDdbWw2Xrxzw9BNzLl+dc+7cZfq+Y3Nrwj2338TGZs3Jk1ucOLHF5nRMWZoEbCYAx/WSaBZh2UV+8b1n+f/81a9i5SXx4o4rP0drzxfde4HewYMPn+XxJ68t4F/Ma7e85lX/nJMn/x3OtTzyhMVqKCvxjtmY1mI6Pqro2iXORx57SiQ5PsQEIoip/Kiq6Pol80WbFtRA4xxWp5CIoIS1dWwzLnLEGLIp+HEACSTcQ5iaPQRH79cMSSlYoY753CeIXWkMgclE/O3qkSKEjunEUNeGphLApOtkrphMNd5Jum6MAiypAF0ytJYuW0SpAh/04EXhQhBDShcTwy0dSWLtxAijccF4UmKtpneBg4WjHhUoFUBn8EG67tLFc2l+lpRUmxi6XeuPAUg+CJhukiO32JXJXGKqUgCXkOK+uxZrlfhjmcDVvRlVZdnZmVBVamCE2cJiywLvHaPJiLrO6XyRpu3Te8gxVLVlNuuZzSQivaxqmtZT1QYXI6WDeiSbhlIFgotsTh17hyITytLyHKaiiEQVMVZCPoxVdNcQeayW17TG4F2g6xzWClOsqoSt4n1kdtgOCcC9h+Bk21MYCFHklM5p0DF5o9lUTCiISoqHEHCdh6BETpkus+AjXReIymCisKky82vZtigVUVoo6tOqTtf6NQB1YlJnue56lHXfS0BIBnjk+05JkaYYgJRjZqrZlT3I9ZQ7guJPJg2qgmLFJvJh8I1CrZghx/6gBIBi5c11Lcs5/zz4MBjYD6b5TpjkaFAxd7XVWmBMMhFWKrETI33oB5BufcQY6VwnQGlwlMl4trBlus/iABCFxKgeJIDp/KwHARDXEimVbE6yqSwqNbq8w/ilrKdWzqdL3oGD1HLt3GVgMN+ghS2GqSmDUEPCpTWyPvjVNlcrJewAWwyslb7v8b4josRTNIbBM+766PMIrkEZiylHFDpQWENMwN1gf2BhMhYwJoMG4heaP6Oj7Vra1rNsW5Ztz3zRsmwczinqieLUiS0W8zn1aMz25kgsDpRYUxhboW2dJHhisTE73GdrU1iSt91+O3q0l1jlktL11b/nQ79lQBgKrlzZQmtPCCvm8BNPfpjp5BEefvTez/ktbjrrOJwZlN5muby+gffyuy/TNZ7F0vLv/sNbj/3OGD/0cTSAVtz/0GcLEIh83/e8H9c5uqbHdS0Kl6RRspYEPFqJ7yMUMkfXZQo4EZlV34uTLEDb9VzdFyPosqiYTjYpihqd0ieNFm9JYxIApAxd0MIABK7s7XF17yqzoxkKYfsG14kNipKAJKNVAgrW7ECMHlLkSWuWlLKSbA8wGgmLpd7Y4fTZ44B28GGQmvVdg+uF7ej6lrBWLwgrW2wVnAuEKCBd24ssNUSG+iMnEErwREffium/a2F24LFKJEd5KKWYbG1jy3KNUScsI6ME8LBFJZ/dlrh0XFFFisJSWk1RBL7oNZf4old/GFtUFMUIYy31eERdVjSd5v5PnOQ9v34rH/7oSS5e2kyS3nWg7KU0Qn+nD03fV+ztV+ztb/P447ff8FHW9mxtHnFiV4Cx8bhhNGrZ3JiztTnjxPYhJ3f32Zwu6FUkKFFRrZayJLs0iQmvNV1cJboODOD06GwPoFK6r0n7OVSP0hZf6ESeIHWVbOosqnRFqIFssRqR0C1WXhRIHS5Bdfkngb6XPXvwazVkaDh54oDdncA9L3NsbUo4h9Jy/y6bLT7+wFnuv/82fu39L6dpErHjP4shZ7Rpxzzy6N088ujdQKSul5w9dZ7X3vsAb3zdh6iqgC1SEFxRYK14e0l4oEX6iIrtLUk9XzYtTz+/T8DS+8jp3S0+9PFPcebUFmdPbzOqSzYmI7Y2J+gg97rLNRgJx1gbAozpAYcwBGwMWC+WMxkj8GtYxwsZn/dAGMiGrChXEea5WM3G8ML2UmJtm7qLJgNHGUAhbVpCTp9c+VgURTLWjJ5m2chGEinsvEqdyk8zN2cKYIRBvmGMWpvLRTbpnKf6v9j773Db0vyuD/y8YYW994n33FS5u6qrultSq1tSK0ELIUBCyEgmI6KNZ2DGD4bHHg1jezDDPH7swcYmeGxs8Aw2xjbJgzAIWSKjgFKr1VEdqrpy3br5xB3WWm+aP37vu/Y+995qVXVJgrZY/dyuqrvP2WHttd739/v+vqE6P3GWR2Nu4kqyYBqf11q7Np+jpCyasZCPMZGyb4gyCltbopeCFUqTWfTZWUaky/ZWZFwJEyIOP1JKyRfqJvAGUBmTATAp8wury2hDCpHgOynQjaFuJlhbE/OGDqCTkveXF0ttMoOjqmiqRsIRNjbh8v/T6Yy6qQlh4Gx+wtnZCU074eLuZS5cusjuzi5NK9Hti8Wc08NDVqsVt2/cYNWtqKsarQyNnbFwS5yX82zzdYQWJl/dzrh4+SJXr15ib39GlQvrzge6LmTml8cPMl3vOvi//0e/m+tvcxr79g4BT77j1z7Hv/eHP0L0Aydncz75mWMWp0uu3zjCKMXezhbbOwfs7W1x6fIeW9mTSBdpTFQoFTNbJRAinJw1/Kd/9uv5sZ9+irdXnCj295a84/FjXnt9l4998s2nbD3o885mL/Hkk/8Z2nyarht46VoPKaCUyIJ3tqe0RnE2qdmaNYStCVrDfNVzerbibN4xX/Yjs8eHiAtSWPoQRrZmo9W44AoAmITtuZFklmIihdLEnnub0hi7QApRwPSNxroAYNnHVMAHVcB5YZqmmOhWA957ompoKzBKs73TYLQToKvLBQjisdOYiiqzFo2RpiJGSFpYGpOpTLZDCNl36Ty7ycdMOk8KW0ta5gggUGPMgNUVwQvjzFg9JgbFJFK/tqmpa7tmEIU4skasVQxOnr8YFcrAWyZ/MUSSUqQQWZwtSUnYo9ZA8gltoWkqLl/azZ5hMkAIMafxWo2tLcMyZMm8RafEciXsKp8jwi0wDIHVaqDvI13nGFw3AuSV0Vx+aBtTCRjgnZjDm1pSKFedExbLGDgQR2ZNjBEVwQ0aXZ0vpHyIrLoeraGdSPJquRZCBlO1UVy8NOPw7orBJyqVqGvxohuGQPSOYdAoDW3bCECDIkX5rk0edNjKspo75sdLutF3LEsGazvuAUplbzQtSY+rfiApWIaB427Jla1ddqYzNCI9K+yEYtiuHrA5Fonipp+X1bI/JUTmWXzlRnCHNUMsDhHb2vue3yiDigI8KaXwwcvUMtdT5fsTYnIG23JatNZ6NFs31pzz3NoEZsqgpTxf2U9DChiVAaDxjhHgLqgwLpHn3nP+h09+fD86M5DF20WeXYYOm4Os8+8NZJ8tDXOxQYjJgJ2STIX1S4xfAoqkpeDEVOPvS2jOmgl371GAtk0wrHy+SPYmLZ8xBHwMI4hXgHPtPNqEEaATcD6IIb+x2Tftwd4eo4QtSTpqUIY+GBqr12+m/Kwunjd6rJFEjipSGpFwSypv7xKHd+ccnyyJGN75zss8/NjjHB8d4fpT8WjMdQ+ASQMmiaRTpUi3nHN2fIfd6dNM2gkuOpq2kevPB6o8qPsj3/MP+c/+1K/m7e2V9x9nZ2KM/853vM6LLz08gmHdquPZz3+Or/yKn+ETn/rqt/Uay6HDBc/HPn71gY/vbNes7A7/7h//tbz86nmZ0f5eR0ww+MCqH4jG8LOf+cJssD/w+36EaXuMH0SSnuIAmSUCZGQV6qZBoXCml6G2Uhks83gfmEyE4Wk0tLRY09ANObADRYyOrpdBx6RpiUGSj+t6St1OqZuKum3Y3dnm9PSM5XzB6fExWikmk0aM8bWE0fggKgBFqRvHuzeDdWvQQGuT5dhmHCgBrIbCKJagEHKdr5DBrrGW1hpS8qRYr2EhpcZrXP5bNk5F8dqVzzw4SSV3zuFyCmrpK4ZhwMfI0DsUieDFCsBaaVA35czAuE6sVksof680q2iJ+XknrWXaWJzvZG3TirqqadstmkY+06pz6PzYYw+/zu/+rZ/gt3znEhe92DMozZ07QiJQOD797Lv47Oee4ZVXH+L0bJvFsmUYCqi4CZr9y+OtHN5X3D28wN3DLywTtNZxYf+Uy5eOuHTxmIODEy4eHHPx4JjLF49FiulkGKKNxt2XNrk+VFTjMCwmjxirC6mlyjYRKaRzfprAKHUfVVBK1B1JCpVzL6SUMPy/0FHeXszAluyfok4gxJzmfciXv/cu73n64/wr375k6Adm04a22eXWzQPu3NnjuVce5ac/+k5u3trduB6/VA9F10156dUneenVJ/m7P/jrUSoxaVc88vA1vvoDH+P97//cmEha0sXF8qSiripm0wnTyYTpdMKq67h254SLVy6CgsOzgfnNU1545TpKJb7mK57kbL7i0oVtnnnnQ5D3z836btJMCClL30MArWiswgLLFMa1M6QCcP6SAcISbvCyqXlp+oKR5kc8Y0T+aHOBGrO8UGsx1iyT2TWYtDFJJU8xjUEjZr7Od2twK4E1SiLh9T3sqMwEEYZaoe6n0YzQh7AGt5LI57TKEstc8CmywbOC0SSW9ZS6oOwhhHHauVkskxt2BeA9urDfImiKKaL8keeXzTOqKACh0SQX6AdHSInKWuqSKqnNmk2XwTudgURp/nKDoEQSqbT4a8XgZatSIldU7SQX115YKkrJhM6K4X1dt7TNjLqqcIPjQU1V13d5cp3Y2t7m4pXL7Oztsr2zQ1XVhOA5OTri6PAuh3fuyKS3akgxSTGiNEmLv9j21jY+ePq+J/pI0044OLjA/t4OFw52mc2mNG1D8I5Vt8oG6VGM8GPMLAFhSr382uV/ziCY47/8z/8hX/ae23Srnus3Fty5c8KtW0dcu3EboxSPPnyFgwtbvOsdD7G11YrvlzEil8m+HtIgDfgh4HziY5+8wn/wH/9qumHyRbyn9URPqch7n7mN1onPPHuZj37i7QBgnocf+VtcvvyX6PpTThY93gdJrUlS0CmtaOucFGWbkV8VUqTrA/OV57QfWPpAnyLLbqDvndxGSkkyWsqefimbRJMgeJIKpBBQ2qCKL5DWmZXJuQJADLHF5DwkJ6Wy93K+s4TQGI22UtTLfaFzahrj/SaAisKRsBpmU434MqQMPAvA1DSGqhZ5sQ+KujYYDcEFhiFSt4qug60di1KR1XwgOI8LER81MZ1npSUECGoqlZkdaQ3OJZPZtJJSlFQiKvnvOvspNW0lJtpB1kjvBeyvKo13GhMSxIQy2aw4jTxEAcOSPHfXeZZLR216Lhy09KvEwUM127sVVWWFzRZKTD3iU6Zkiqi0Frq3MaQoXhPLbmB3pxllLbu7E5YrT3fYMT9zWQojvi62rXHOcXp6Kut0iJjKMttq6FY+BwCs2UehUNpUoq4ts+0JPoeFhE3ABVAp0fcDTWtpJxV1K8KirpMAism0Yn42sH8wwRrNYiENmIAnMlQZnB/N31NQJCOpmTqCcyGDOuKdGXOwhfcZ9EoRtKRRKg3OCkRTVWAq8TsLMZBc5Gy55OR0wSMXLqB1YlpNmNUVSSkWQ4+pKhpt3rAe3JzaueRQ+X9aa0kg0uu9efMeUkrhncdW95cwhSUG60J73DOjAFJFJrcpeY855EXpe9hoam3oXt5z+ft7P1cxXg8xN8RZilnqgfH5ivF8Xg43Ab+Y5SDRB/qUsk/LeabaJoCIUpiqRlmxUAgJLANaJxIO/BxCARDW50ubte1BYZVba8Z0ywL+le9DrCUUXnnxCcmhHiU6PWVPw5QSnnVIT/nalMp+YSYDi1nW7bwnaY1NCaWbHIZjhLU/+q2uT3QBxFJKhL5jNYCpDHWWWsjgcc2Sd86N/z44x3y5ZD5fsFguWfUDwcN8vuLk+JTTHp588ir7+wfMz464desMoxWTVjwxJ4140gbfZc9BQ9Qi75ovFzmF0mNti9INs6AI3gHwVV/xEl/7NS/w4Y889eCb4Ys87h5mlnm6SYyPUSYIMV6mqh7itdefeNuv4Z3jc5/d4k//2W9+4ONdt6LvVlw8OLsPCHvqnSf4LGGp65ak4GMf/cLv6Zu+4RN0yyVaG7QOKBtJUUHK4UvGUNctVdUQvaeqGta3ozCOzxtrkxN5KyZK7EVciKQURv+wEIdxjRHvKwnEmExakc53HcE7rNFM2gmzrSkxOlarM0DGxyEMmdUi/12OGM4D9mkD2N4EmZbzFYvFXNape5q4UnMrBcEPRO/yWiX+te2kxVYVTdNSZdsQAQc1ppZ7o67XcqREqSMCLq4B8NWqw/lyz6m8PwmTOwQ/1vSgwCYmk21KMrBWim1jGVzIsyyFC4FUNWii+OhNJqA0i9VAWro8WPcUt77KVpyenXEyn8tQQguYAsJSO9i7zrd8048znbbs7uyxt3eB6XRKCJG6qXnt9RU3bk156aWH+eTPPsqNG7ucnU1YdRXO2Xxa7/Us+1IGLH5xD+8rbt0+4NbtB/c2dd1z6eIxjz58m4ODIy4eHHHp0hGXLh6xtb08RxoR0EL2jRjJ4RNZXjl0DO7B34vILNf7lFJq5GaZXJmXcGVjtXjGvhFbhfUAR+c+VdLuzcgut3YNpHkXIShMisCANkve8UTP00+8xtd/w4v8zt/8wzgf6HrHy9cu8ne+/9t46eVLzBclxfJL9ZAh/HI147nnn+G555/he/9Ox8WLt3nk4WtcvXKLK1du88jVu2zNluN6VdsKazSNqbNJHChbkbRiahqefleLcz2ni4Gqqnn5+hGvXj8iBM/+7pQLe9vEGLmwt4PWC/a2ZxJ2GMXWpqkqVC1V0rwTUk3xp3uzx5c8EBazpACkYVxLHTOTIUJS0lQZZDNp2xkoxTCs8L4/twYWk8zcT2LSmvXkEVZItdEXSmJWLii1IgaRxpWpaZUZTaV4izFh0aNEKGUdrAAyAk7FMkHV8pwK8UYRrawZJz+lGR7f9z0MLTKoJCdHEzNzzWR/r8IIE+bc2nQ+oQk6EE0kmixpVConawpDzm40N0noLfL+dPZLSQmjS+IHSNJDKQa0bKhkpmsG8bRKGJuN7quKumqoTY1BGCD3LmRt29I0DVVVs7U1o24rTCWGw03TkhIcHd7l5OiI46NDTk9PMUpkcTItzxP+GCiAz+AGppMpezu7eaPdYndnm7atqeuKhKLvO4ZBJmv9MOA8SCqpfG8vvnKJ/+5/+jW89MqDp6e/sEfiA19xnT/xH/5TjBlYzjteeemMW7cPuXX7kKHrOdjf412PP8zjj17myqVdJpOKpqlHHXZI4HwQI8oozfF8XvG//O338pf+6tcw0ivewnta32SKq5dPeeqdh/z0Rx/l0597kPn9mz+q+i7vevrPo+3fZ7HquHMUzhlnSi2aAZwk3jbWWtCWZBQuJu6crCAl5quBZe84W8j3O/TFa0CkZCmvKaNsmAz6FqpXSpkFlN9cTOiox+JagOGIdyIFyu4IcnZqS9Uk6qawXNb3sqTpCWBidAEoWQPQKBbznrY2bCvF2cnAauHxQdaWprXEBCiNSYqmFeaPVRWHdztMBX3vmW1NOD1eZlAgZPlUAdTLd65yM6uoKrWWkWRjeq3MOFyIQeOHhDVgalnPTKUZhoHBy/uTpCCFy2wspaCudJb6ZfgriYwrpYixhsbWeB9xOrLqPUF1HN7yXHl0j6YR41ZUyqzMgQRYK55bCmma95oZdVuTlKQ+LlfDyJRShcFLkcStWThF/h5Twg2OWMzNMWzvWUgib6+symvfOvVIKxm0lBTL1lYEK2y1vvdUVmSUIRvCVrWiHzw+5hTBKPuBd5GqFklQXWnm84HCXtaKkfIfcoABRAldEa5VlqtnKVkST8yhL7JFecwveobgGAaZ7k+mDSEY6qRpGoVzgHcoo5mfDLzY3WI2aZk1A0Zr+uDY3ZrxmDbsTzhnG/Cg4xzzK4McxR4kqXT/Hq3XANMmo2lT+nhOQlmSnfNAqbDkik+nicLGNhkIAkmRDF72CR3XLM8CXI2sz3vH3GRm2uabTud/TqU101LeIAQVRu+y3jvqekuStXKTWaToKCV7pKny0EwaRR2zD2nw4vVSBg5JGKHS1460tLwesWbC5foCxSiPVCga26x9w9JafuCjH8+zUkqYmmmdEDp+r6xZYQUoLB5no5Q0BFyUaX4ZQnrviSH7kWphXymlSDoRc1JZYe0Zbwg+YKqaqs6BB9kkPyZhu3Rdx8npGfP5UoZyUQJ3ghP2UCKxPZX68frrr+O6FVYbfPCjp2GtNdHYEaSQ4KSIMRXLxZLtrW2auqGxWjwHq4oYAilFFInf/d0/9fMOhDkv5+vlV98DwPbWs5zN38PnX/iNfPpzv//n5TV88Dzy0HUm7YpVd/8A7PTkDoeHt9nZvgucB7m+4RtviIfkGDaiODt7Y3/Ur/yyz+OHlZwzZdAqgNYkZYk5/bGuG5q6He9DlVFluabi2Ad4H9fXXmZ2kMFbknjaTNvJeP37mH1m8howaSa0kwnBOfq+xxpL24iJd7fqBGimVBhIgMhoRvZgNqxOCeM9hCA+wmiC2OtnD64dQhCweRiGtcrFaIyKdMPAYtVLjeICwxDY2Zmhzjqg9EBinA8y7CUPqmXILAmSAjJK0r34HReWlzSZlTXUlZXAjLymVnUtLGpVQP4smc6MM5B7PkQZLISY6PqBlKIMl5OoJkJmoYUg+7TREpwTQ8AqYccPC0kFRcl9boxIsZTSOOMZFgHfW1JsObx7hnMRazRBW6bTm3zl+17mA+9XuMFhVDznV6jyvh98YDKbsVg9ys9+5lE+9olHefGlK5yctISwCZb9S6DszR7D0HDt9Stce/3+2t4ax4ULx1y9cpeLF8XMf3//mL3dY3a27zLb6pjWeYCR1kOnBx3FHqDss4V/da+YVjkwXvq+EoK3yW4c/2iNHmXcCqWEna03QLAYIyQJTSlgi1GFEAPQkZopxoIyiaefOuHf+yPfm+81zfXXr/BTH36CH/rRp3j9xi5vvZf6F+twruX69ce4fv18iIPWnqtXbrK/e8p7n3meh6/e5erlO7TNkIfSGm3NKCNvqgpSwCeFto30H0pzvHAcn91hb2fKcy/fHLGV3Z0Zly/sUlvNpKm5eGGHSVsxaWCx6nLNANa9OYjrSx4II4kvk0j8bE6yIxeOUgCWokUo/JnHEcvEZl0Yxgx+qZQ2jN7X6GK5gYq/hUyRsuxGq5EJlDL6oxTZHygXbVlOWAyzY0w5ltyMqRk+loZQ6H5lyqW0bLKleCzJOyFseHrEOMo8KZ8sT3WUMuJPg8bqDICpbOSsxRC+FMkpAUE8O6paUWQ9JQmzsjlIIDeHJZFrXH3SGlBcAxLyPQQvrDCXmxBpaoqvGFhjs+m9JHmVpiRt6MqElj5lf3+fyXQq0smmJhHpXIfvHavFUtIflyuWywXdspPCuBZT/eTDuQaAlNiaTbD1Dnu7O2xvT5m2EwGItCbGkEGvgHMe5yUSWHxaKhKJn/7Yk/zZ/+a7+OeD+gf+7X/zI/yGX/95nPccHp1y6+Zdbty4w2rVs7s9Y29ryv6jV3ji0cvMpi2z6VqiphD5h/PCbosh4ULg45++yH//V76KT/7sI7zVYqBpHH1vKNkz7333DaYTz6c+fZV/9pPveBufNXLh4Ie5+NCfYnu2YvDghsQweKK/Z+PcTLVDwKT5omMySXR9JEVhlYScItj3jr4fGHo/Xrspe/2kbNhcwDUBSsrkVor2wrSRc5qIiMGnUgm03BNh2Gzs5V+0gumsRmlN3da4wQsIRX56tTaR9k6kQTHI/b613aJ1YrmK3Ly+QBuV15BcyCmdgzpUXi/EUN0kkUzUbc1kKiyrymq8NZnNBcooQpD7OEVZA8q5THm9sFbTNjozihh9kbSS60ghS4g8R0In8EnkIjHB/OgErS0uKLwTdpka1+wiUzcMvXBlfPIC6uWQjZQSLss5KqPReXKstQBJwcfs9aBomoq6EoZc29bitZJThyYTLeeBSAiwWjnOznqGXjxgbPF+UTqbwipwFmOFiecGj+Bi+Qvb2E+UyoMNJdH2WilSSFRWiw+X10wnFcuFBLZMpxXeJ8LC5WugyP4TthJ5p62FMjfdFnZr3/vMgLaQCss3e04qUEoak5gSVS2plzEzp2HtHwPiMxZCgMYIy8gHgtb4rFrTWjGZ1ayWA8En5q6X73LVM2sbbG04XC6ZNGdMrWVaVeP+svaYUefYUEopYXKlAtmVe437lp6RTVEmuWQJnC7yoALQ2nFglfK+HuP5JyuWAgUIKgMlHddWA5tJkuX9FQZZhsTX7KkcCKM2Pm/xQNs0vC9eXsDIFitgmUZR1Q3B9bjgRGqUf1yuJQFyyh4aYxAj+5z2tgnClWdWb7AvbcoH7z2/5X/lvZXhUZF2FSBMPoOYKpdmQ8FYR/lY5JGSYiqNc8yyrzIsSwTviEpl4Htj/Uvr9xWCrH+bgQGyLnqaNqFVQzKGuYtMKkhRkvtWXUeX03glEMOMXnUXLmzz8CMXcT5Q1QbXz2Xt0RowqAQq30sFmFD5e7TWYKuaULxwsoRNDZ5SC+QSg92dEx5/7CVeefUdD/wuvpijnCfvt1CqY2/n73E2fw+Du/jz9hrHx4rnnj3Ahwe3DMenS04XjoML8/seu3K5o6SDK6X5+Cce4gvVEt/yoY+glM5WJZ7kBrRa++Kis8pAGWFSA2XwHVOAvBZWlcnXy1pJoZSwcHX+3iZa0shsZj2rZCS51PW00y2mk4bZtGV+OscPK4yOYMGHgb73eO8kUTgEYpJmui5G/uMnKkmn0jCLDYkE5MgSEIk5tKKsPcZIOmxh9a7XkkRTGYxuSdOGEBIuQFJalBshCsOXRHBiRVL8FUcfwQ1gKyWFT5oQNDkfisqaPJASE/y6tmJ7Ygy263Mye06etDbviWXAk69308hwGLDLDrRiW8uQLGSWdoye6BwxeHReC7x34lOsC5gmbKHgZVhdVdnk38i+ZIyAZ9oIu3kyneCyjD9GkawapXFuYOjFf1ArsRfQyDXphsiVhwaeetd1vv3XvsSlSwfcuv46KQzi0WkM165bnn3+YV6/foFXr13h5q09jk+26LpNls+/BMt+rsOHilu3L3Hr9qUHPq5UoGkGdrfn7O2fcfHghN3dMx595BaPPnqD/b3TkbFfWI3nfh+Zn537JkJCxXWom8xxyl6ZJe65Rlc6jnWKRjiKodglKYXKIUDWGKrZFsUPW4aoZS0KY0+rVFaVKWGmPfXkMc88dcJ3/5aPslgGXnz5gBdevMKzz13l+Rcv8/qNHb7UwTGQAIfXrz/C69cf4Wc/+95zj/2qD/0Tvv6DH2a2tcBUazA9FS8UJTYJhWwTY2TpEhiLToohRI7nHafzjocu7XN0uuJnPv0iWkO3Gjg+OuPiwS57u1sj4ebnOr70gTCkCLbGbkj1RI5TKPUlcUymsJFh6IC8acKY/Cgmlgp0EkQ3Tzh9yKDaxnQT5OeLD4aUZdL8biqhYkwEH8dCSGuR0agEtREzPq3WZWthsxRTUCBP+hUx6nMAWJEziMxADOz1xiancspVaYY1CZMnrsaMTmFk/UkuqMv7zdG2xqCVzY2UvMeRraJAhWx4yFpOUiQPeT4k57gU1kmaTk2JhlfZu8dijVDRC+06BkmOEoloEM8wa2nbCbt7O+zsXcAaSd1ZrToWyzln8xOWqwXeiyGzpOooFBajE94lQnBobQkRTFVR1xWT6YTtnS2m0wnTmUiOslOZTN2cy3InmSIW7fEwVPzVv/mr+Qf/9Cv5xQfAEpcuzvkTf/yHeeqdRxwdn/DyKytu3znm6PAYkKLm4OEDHn/kMtNJw3TasD1tZSqYv6EQE4OTaWmIiZOzih/4h0/x3/+Vr6Ifmrf0jpRKTKcDi0VD34t/0qMPH5NS4jOfe+jtfVx1ymOP/UW29/4W3gdWnaPvYdK0mMrStg3L+Wps/NfTJJkTqcyWWXU9gxsymCFpNc4F6toI08+Fc6CAXLdFTibBFfkRkQMUS5vcOEm6qxoZSDLZLusJuXktTa38e1MbZtMGrBXGTm4khd0TCS4QnB+N99cVQMIPnumsZrFyzBcOlBQIxTvBWDMWtUonKXoz2JmSNJBuGJifyvNqlX0RI0j9KYl/SQlrM3etxECWV+emX62ZeFX+7CFEJCBPZUNxJelClUgu/FAk7JBcGjX+pZX3MaIzgO5dpG0qvJP1KYU4lgy2NSgVqSpZT02e/JIUXScSkratR/DB5GrKDR7nIsZKE9I0msE7umXg8G7HcuHGfcHk722UO4aEbQyRgNUWgkg8iydaikjBla+BmM+tDwn6gFaa6dSSkGm4eMG1DENEGyOATdrwx9Iqp0JWInPMDM5mIvuIu7vAWEXwIn+PMUNyG5/Ve1DGYKsK59zIltD6nL+sMCNy0mEBYIvvZIxRmAvK0jaJwUZc55kveupaipdG1aioOVl1zKc907qitkaaxbzuK6XW0seyAQYE5FBrttY5YlVa7zGRiDXZy4xIiUlLJq3Bis3nyVfVJpsL1t8nrFll5fERFMtg0eZ7MCX5UK9/N2a577ijK2G0aVUm0rqsHOekjuOR1xGNSOqGwQnwM5LREiolgnMyVdU6+3oWIMln8/41kFVkgZuAVvnc5TtNrNcwldafs0gYiwxy87zUth7PXczJYmiZpK/3/lxlRGEaQ14Tkh8T53RKI6s+evm8KUbqtkXbCqLs4wX0K/fwZhtUvhM3DGKFYSt08szPBnrX0w89g3N45yGD2k1VsQw9Pnh292Zsb29lT9galRw+IMy7lINCjAFlZMhAyj9b5c+bGcfeC+hjtHg/BvHTLCGhfe/47t/yX/En/8x/dv7CfhuHNcP475P2OabTj+b/Cvx8NFXb20tCXPL555/BueqBP+OixVZbXL7c3/fY9RsT3vO0RowEEj/64+/8Aq+WeMej12WIoxKxH8ROI9djdVVLkq8PhDBkqKUAjYHiLRejJHdLEMx5huLo/5vBMJB1WZjHRiwOkNqprmXIeloUDUgqoxsGnHf0nTCzYgRlLNZW+CRsal1q5I3P5j0MWvanPKmWP9oDaqwrN61VzsmCkXrFmrKOKHxUdE7A6ZStSULwDCEPerPvoY5aEm6zh6EAhxIG1DmR06f8/EpJymtS5HRLi9E2ewBZjJVavMpJf1Lv2BEA1HWDMhXaSLiLyoxstJb9p9aI8j1R6UQYOjHgbmqWyyVnZwtsVXHx8uPMT0+wdZ3Z0oHp1tbowVc3NVtbW2OiPVrRDYblcok2VoJZfE+Ist6s5qtMnBDgI6IIqmVwitUA1k5omx3u3vk01qg8AB2oK8eXv+cuX/FeqXlQIs+tGlGKOOdZLGpu3bzAh3/maT792Ue5c2eHvq9IafMe/Jdg2Rc6UjJ03YSum3Dz9iU+d8/j1jouXzrk4Ydvc/XKXS5fPuTKlSOuXL5LVUmCtkCm9xzS4I9/r1UeRo69dxLmOUIIEFsDkWiW8BurFBIO4MVSqAwQU6J3SQajAKz9Psd3km/3lCIRwRWqKvKup27x9FM3+Ve+7RNopRgGw8uvHfDiSwe8eu0Cr7wm/zw82vr5OsX/3I9//KPfwj/+0W8593e/7Tf9D7zr6c8iktQarSWQyWSbGO8jTVWhK8PWpMZH6F1g5cQCZoiK4AKrzrMcAjfvnnH7zhmT6YP3q3uPL3kgrEzqCwh2bxFrynQYxsvSB7eejiYtG0Ioked5s8vT3mIYH4KwCkraWci0X59jOitrqYzEchcDSilEAwpPVde5MUtZmpLy5EWNG1KRg4ygWC74BFzzuTFaf/bNmHkKI0ypsfDVeRI+glJp7QtWTDSj2MFsPI2MX5ViZD+Yjc14hBbyfxsj5sSFBVfkFCnP9O/7eW0wVhIYm0YSscp5FbPmCqV1boiFlSZm/g22rqjrmulsxnQ2JcTIatWxWq1YLRcsl2csVqesulWe1iuMtpI6mRRD70e/kMnOhMmsZms2ZWt7ynTaMplkg3il8N7jnBgmeh/OJZ+kZPhHP/I+/vr3fgPL1Ra/+Jtb5Ff/ipf4I3/4p1H6mNPTFZ/57Ak3btxmcB4itG3FlUv7XL60z+7OlN2dmQAzeWQS8zXts1H04AIvvrrNf/EXvpFPfBHsr9lswHtN31sWi4amdly9OufGjW1ee33vbXzWxNb2x7ny0J8B9RlWvefuUQawM9OmsmY0VdWKkXYvDC6568WU1gACIvd9QBmVpWOgiPR9BppHOcUGEyJGGP8uooxQ69tJRUqOuppQVUZYnjkS3WiFc5LUKPejyj4lmdVRitmYRt8snwtomYLGEXgIXv6Mh2B7kKDrBqISGZzzngRZ5hrQOqJ9wDlNZTXWSKM6rAZJ1vIePxeQ19sytVdZRiETMBWE/q1t9lQqrLfMgvU+m/jHlOWOApopBVYbVPYSK36EIQQGHxh6LywzLUBOUAFd68zCVbLuRvmwSukM4olU0WcJn1zOElAQY6Susi9WTKNsKsZE9AFrNDEznLRRwuwc/CjZMVbM5FerwNlZz/FRx9Dn18mApSoAp84tmBYpTvl+fRjGNTTl9VDWcEXhOUl6aKCphdHSTioBAmPCVgpjA85J8yzLpty3VaVpp1akzG1ONFLiWSHsQCkaKEAT64FFCCl7aIo0FF08NeWaLKEMIs2Tdyqf87yJug2GurEoLcOa2azGDZHFosMHYdP4lFAhYpTitOs46VcczKZMrBUgbGNtUeY8UJVUGivZe4GwAsxsssFGGW4SRrdG/PZSTLn43HgtdX5NK9f5JvhVBk3FF0sCddaMtc33UUA1lffTEIMkt2XAuqwd5bNIPWLOMasesNyNm6zrV8TclMtLp5FapNCjQnrziMHnZM3154lamBPF6m/z11LKcsVRTi48jmTWTfi97/fc3p9fx+TGgpzoVxr8Is/UCWE+RkAFqlhBMlSVpP3pHJ0u+zZgxSdUmyy13gAy1u/9AUCYczRNI0xRN3B4dDSGO4QoLLRKG2KyOfxEkVLFdDqhbRuMleFh13t8FFCsyKnkHk+E6FEpYpUlhohzHboSxv6YjpZEzu2yOXlhsAUf8H5ALvI3W35vNFQPOGJB2YC9vX9EO30FY04JYedNPv8XPn79d32U03lHjA+erv/W3/wpLl65igZ6d//g7Oy0RoIKZC35/PNv7Ju6t3PCbDonxVYaTUUGVwsIKoEig/NYE/Meqjb2JTlkX/KYstki14jUCeeN31UeYPkgNadJYtFhraWuK2LM9V8M4r84OLpOgDAJqxEWSSVE0JyEqkZJIUCZfBV+pRqvKVk7hqEfFSnlMBmkOyexJo1rutybsjfXOcWP4neGQjetvOfgZcClNdaItDCRRisPrbJclCIzlTfiQw6AAlxWZyhtxrWxGGOXny9MM60NVTMBJYB0SAlrhcWFlsCrymqsFTBs2pjMmDECXG0wLpfzOX3XMYYH5b+31lLVNZPphOlsJgm4xuSU1pDZnImgwePRKpF0om0rUsy1kLX4qOlTjdi5KHTSGC22LKvVSs5+ghSlHlFANEqkulHhYqDryTXFikcfu86jj13nN3yXqAU0kboSUDfFxNmi5ebNK7z08lU+/8JVXr12mZPTGcNQjcSHfMG84T3yS/nwvuL161d4/fq9ssuEtZ7t7QVXLh3yjidu8M4nrvPEO15ja7qQeyZb7IrtR0DhpC41FmMtCcTrOQ+hxX1h3cNGEqgk+5gSvzxhtSuZwaWy36V8/QlYis8etckTc5jG+v6TZ/ex9NyBdz5+nXc8cX3ELFJSzBcNr752wMuvXeTmzV1u3pI/N27t4t6k/O9f5ONvfd9382/9m3+UphH2JoD48QozVWlZI7RKGQ8wtI2R/kAb9vf2hdC0E9jf6yQMp3dU9s3dR1/aZ7DsMUXrPkaxy4MqN1Aw1lHy39k8WZVIMrlKx0UWhCUTWfsLFEaU1nKXBCJ90cWnDIRZ8VzxOkhTFCXRLCWZHFbW4LxncF5+FplskdZNUyKNcosQCpgm0y6FmNJuSkm89w8s8MsGrxHT0OK4U7zBIDMA0vmNVj6j/Hspfo2p8sSTtYwmbXicJIHOy5S8nNYgCN/4XaWEpEDqiqZpmLRCSy8MimJqXKYt2opEsq5r6jr7htVCOx/cwNnpKXdvH9KtllJIREdSjhRzYpbSKDQ+iu+Oc3KuJtMJ+xf22N/fYWs2oWmq0R/LB8/gPcMgAFgI+VqIkVevHfAX/odv5eVXvjC1/xfmSEzanj/+7/8Yv+zrr7E4W3A277lz55iTswV3757iBsfu7owrF/e4fGmPgwP5fIXqnpIAC96nDJoElqvIX/veL+cv//UP8lYZbVpHrl5ZcOPmjMVCTFj391dMWs/r17d5+ZX9t/F5Fzz06N9gb++vsOpOmC97XPAZHJa5j8rXW/BNnvBJ6xW9kw2PAupKkRMjJMR/yWdvCufFTcfma1arNZOG8d6TGyWRCCmiVaJpa6Z1w87ehMXZgt3d7XHAqxEfLB8CIQUIKXuMyeO2yo1kBl4isi45l2RtaKzcTwWw9PH+FLcNcCDGxGrlsFm+IEVqLkpNudfTyFZyvQR1KMR7zDuXwRORV4mHiJwMleUksgZmnyG9loAOg0Tax/y1iPwvA9k6y7CtGSfYIQSGwdN1jr5z1JUlRpk62wIYVJJaCNL0xJCHET7ihkAfiy+XFCZJlZS7NF7nBd7UCpraEoqXYoIYAq4Xn7bgPSQxgCcZ5meJszNP8IrgS7OU11SNBBhYBRoiMnm3Vo3SS2mMvXjTFNN/GAsmGdbkPSgGEgZj5DrQVmO1MPhSAjeIRBNAGwk5mE4rJlNJKyupyN4NzOedNEXWYIwk7dhKroUUkxhDKwEAtYqoJA27d2EMZDGVIgU1Aq42MwmL7H8YIjEG6loAMmWyv6XVoCU0Rt5rNpxPiWU/SBJaSnkQlIdVBahS6hyggoaQTZMLgKRKE1maV53lh/csV0kJ62icv6c1iH0v86pIFVVYs4w22UaVrcZmT7NmkJRNr6ROs8nYyP/QQY9eQ0ml+4A0tfG/e8Ud59hqMYxggMr38DnvLSVs6nOQWl6zKNYFgIpy4UfuARJZn9MRtCWJTEnZdThALtrL6957rD//2g8RtREGgABhRSKstaIavQXFkFh7jS7y06qWayj7pmKqEQA89z3dc76KVFXWmIHlasXx6RmrfqBpmizdEqm+88LkVbpi0rbUtdRVsifI1N5WFU1lR0m0fP/CUofCEMvsnSzR895JShoi2RJQJKDS+e9/a3aX+eLt+WOWo3h2ab1kb+/voBTMZp/k9PSX83Vf+4/4qQ//6rf1/Hv7x3RD5NKVwwc+/oH3X2dnd4cnHnuc/+9/d3/gzdCbEcx9+eU9btzcfcPXeufj12Q9JmC1JmW/K5J8184Hhrwo6hymEXyQtPEkNgQFFEvnwFt5ElP2xnxdlvvPakMiYJJFZ0liXddUlaXvOpwbhJkdwjiUEosMAeAVGYhTKteZjEEZKt/A452jIGUQ3WQPYOc2mKRlXdT3s/kSCjZAalV6E53TUPMgQynQdS1elt4RMhtG6gORjCZd2MACyNWVJaaUFSoKH9feeTp7HsZ0XkKfyAl7ORACpB8zPjHkAJcUE5PJFJTNbBhJ8ZQ/iWmtaZqaybTNMjQBN42tODs5xodI1zuMyuCV96yWK2wl31Hd1njn0UYxOPH5Dc4TQfZiNyAcBBmU1UaRaotqp5hqSq3E/ziFyHy14OWXevrBsep6jBL5pylSXUAbO0o3/RAkSKyuJEU+ewEquWDRSN0FUqdsbTkOLtzmy957lxQ/hdYyZBgGASuVztcNmrOzKc+/9Ag//ZGn+NzzVzg7m2RG5r8EzO4/FN5XHB3tcXS0x2effXLjsYQiUDcD+3unfOWXPceXv/fTXLl8i7aRnkICHkUePEICMfe7peeFsdCNAGPIUZE6M/6wAqJWqADaRHQoCqP8G/esC+Ofzf211J1KM512PPPM67z7mdczEL7u4Q8Pt3n99V1ee32PGzcPePnVC7x67QKLxRcTZvYLdSSmkwU72wumU4dWgZu3DzibC9PtW775r2CMoW0nmZxj8qDdkdKQE2zl0CqidUCG42KbUgg/la2wW0KKUEYxDMMbvaFzx5c0EJYyxVdroayj1oyFOF7QaT1NBVCKFNeA2bnCknJ9ZS+IMr9RIRu5a7ThXBEJeTqR0xFCNqxNgPKbgFNEK5NlAZGUnTwk8ZIRDNqcXpUI0HJodV6aUIrATZP8pATAUxvT2LIpjwgzctOlJLr+csON0+Zy42cWDKqSpjzJuw4ZUBGcK1GXpiDm18lFo6WQ4fPdnmRK1tYtk6aR1LZxISjggPiltbMpWzs7zGZbtG07ssRIga7rWR0tmZ+uOD68y9D3xCSyqGYinjDJZX8ObfFePvVsa8p0OmFrb4dmOmMym1BVlpgirnP0w0A/lAmuFBu3b1/gJz7ybr7/738Ny9X0bVytX+yR+GVf9xp/7I/8OFV1xjB4rl9f8fLL11l2ThoUYzi4uMfFvS0uXdxhZ2vCdNpQVzaDQNnLLiR6F1l1iZ/8yFX+9J/75Rwdz97y+3noyoLp1PP8i3u8fn0bgIcfOmW5shwdTTl6G5/1yuVneeSRP0fvP8x86Tk+EVAzxJCBLeSCCVLo+iiJlolIUzcs4gnBC8ihtPhuJGQ6D8LiJIO6roAnRHxmYkbOMw3kXaXx/32K1BrqRrNzccLu3oRmomlbg+sltchnNkHykZQpniFGYt78bCVsK0n/VXgCXR+yf1PMBr95TcreUCkbpa9lckAGO+q6YtpanE9sb1UoLZT+cV1QUhCKebP44tjaspr3ksAoM15Zk5I0DaVg1UoRs7zExySmoFamuiqb0jvvGVYiXZ404plFnt6HkNAqEvNa5TOYNQyevg8Ev/Y/MShUjPJ5JhXG6hEI9F4k6v0Q8GFFrlwYQsSSfZ009INDaY2p1iyOuhYfE/HPUkTvWZ4thHGiFXWlSRj6TpMiLOceYwXAq2oB2wSUyaCGFkDVB8A5YbTl6YHW4tXiXJFkr/83IqG54PVewg/K96uNXBtNa7BWcXbqWC2zP5kVX7OqttlQeS3P9T6wXAxyXRlFVdtcFBiMUkQf5VrXiQpFcH6UmnrvpZHL+0+lLSk6VMwBA9ksmcQ5PyaQvWlwwuIxlUbnZOa1DxYyGIoRV+7fUvFl+7oCNm2yrQpwtcluHv8+N4ta6zFdsbyWBhxKGmgCJg+URPK/BsOK1DNmUKPs84XhNfr0pOwblkSGWoCQsn7o7OtTnrM0fYUFJhdEZkErM96LIzhkZO8dPTbvWXvuxZwKcDby/UbJ47gybvxu3tdLnaDkxJc5QhKT0o0wm/UzxBRRWZ6NXYNl46Aqr4aK82w+AR5V9oPaHO4xvnZh3+jKZIZJNts2Al6JNMvK8yqpF0wu/GNcp3vKUCesAToUgXV6dtd19MPAqu+ZL1ZybZsplanzuiR+j9ZYtBYm79nZimEYpKZpJCVSZ2Baj9en1Js6QVVXeX0RPySFYugHtF5RTcSgPKbiQSrv0RhD07Rcuvwc8xd/foCwrpM9eDL5BNCTUs321s9wevrLuXnzyS/8y2/iaCd36fvA1s7JAx9/5JFbWHPAxYuX+JF/duG+x5Uq95bm2c9/4QChp9/5EtZabAZLk7aYWLxckWEYIr0v4SbeB+Lg8uvkviD6UTq+fh9rNq7VMoAgrcH2KJIQuZs0NJMGpTXD4MawpnK16TxkNUahi4WJKl5g+ZrOlgg6T4o2JclRZiS4DM5VtpF1dhPVvvemZv1e18MV+UFrzfjakQRJEZUpHTfK+7GmKO9hPQDQeYBkxseEzdaMSpW1G0NW0IzdhdiNpHvYgn3fM191DG4QkDEl0BWlpQDpZyqTcBbq2tJ1E8hgm7EC2LXT2WiQHWPADUNO75S+SQbksu/0Q09Cs+x68VQMMliMwY/qlq1ZzbQxWKOompa63aZqp6jkSGhWyzkv3L0zstIq22CteELV1oAxRFN8Mx1D1+OSxpgtgorUNntGWTta7sjOF8e0U6VrAbuMXIvR+xxsE6gqS93U1E1F23oODl7g/e/7jLCPVKKp8u8i7NrXr+/z0U88ybOff4RXXj/g5GRGeAMfv1+6oJkiYel7y42bU27cvMrf/yfflB8TP4XdnTnveffLfOgbP84TT1zHbE7TNo/sE5weJDnf+FGFqMz63mMsWJvv2Hv3dJXD+Tb/lOfKfbuEP0l/rvOevv4hOLhwwoW9E97z9Mu0bZZ6a8Vyabl9d5vbd3a4fWeb117f59XXDnjltX3O5r/YvaxiudrKCqrE7/zNP8BTTz6Ltjc5XfSAZmtrh4sXL9K0U+q6pXc987MTFvMjkndjHRJiIqTSreV6JsSxR7JWAgorVY1Dq5/r+NIGwigTRovCIIbCYfT7ItPwtVKEvEmVKbrUT5sg09q8khz9Le1vhCRA2DqPQoCrNifEFBAMlTX+WsyotRVQyPuYJZYylbHG5MJArm9JoFPZ3F/0y2tg7nwBP4RBmmlrc4MtEi+r7Rq5zmyNNG7cuYlTEJUSUn5UoyRxjUKXCZNQeY0eIbPxj9DH16wLhVxEOkfZlumn+NhkI/ZskppSwmpLXYmuHhAzSmuomwatNbPZlLpp2NrZYWdnl8mkRWvFatVxcnLKcrFguVqxPJvTLd3o0zImjJGnbaZBVxO0qUjO0daG/b1tmqZB1Q3zHrqjFY2RaUEInq53uKjph8hP/MQH+ckPf4Br19+mr9UXdST2d5f8377nw/yyr72Gdz1nZytefuWQ07MlXee4duMuFy7s8NDVfbZ2Z1zc2+LCzkTi3UuzEoVRE0LC+cBnn9vmf/7/fQX/9Eef5K16h1gb+IavvU7XGT7ysaukpFAqcvXKnNt3Zrx+/YuXYTT1im/65T/Fe5/5Pl586TO8fO0GJ3OP82psLJVWmLThoZHSuK0PQ8dy2dG2W+uGNMsiE5JKllS+Zs+BXOlcbVBYj+ckN+RaMm9EY7GZEkPXAy17F1vmJwuSNsTkaSaGrhNfqxDiaNZbnk8rRd0Y+i6i0LhOgJPeSXCE0YqqMiPYo7WhqvXo1VNuaqMNs2nL7u6MiwcNZ6cdFy9I8R6C3P/OSbM4DIGTU2FCxCieX+J34yFVAsajRSqWyIbo+Q0nWQO0FhabraFurDDbjKZbKVZdB8qjtaWtRQInkuKcX7fRSJLXvRQTLst6gg+0TUNd6ew/YlBGyevZhPEBPcjz2VrRNMIA1is3mvyusk+VsSLB6IcwMle11rStRaWQWXAyua3biqrKhdJC07Ryvp0L1BNLO7WANN0hxlKPZB85+ee0FTlQjImmroRtpwSUSjFLRjIgIIONIF5eIdL3IqFVWmO1RVuNySbPhVIjXjaF3ZcyiLq+prwPY7qwNNsalRS1NVRW0wVJ4UoqEn1i6aXoFhAhN0qjr5kYCVvEJFln1o5S4Nw6iVIpxn/XRkAZN3gBCQuzSBthIKbAyg/4FNcAnlrfc+V15f6Te/JB/jjA2qtLISybsRnMk/QMxuQbTUhjKo1gGuSUYM/5IJsN9kilKnw2azdJpHkmmTytlzefYiRFB8oQ0tq0fWRu5nMq1gJmNJQnCZOQDIqXtboAPOUQuaY+XzirdQNb2Eibx+bP+sKAzEXG+fMoaNjo+5apdTF/BzolfPJjQuTmkG2TwVaA+s0jFklaYZMVthllLVOjeXcBha2VCe4IuJVrJCWMEharsXK/hwyGhSgBDmXiq5TKTbF4xQ5ukOvTreVsC1b0/ZDPn2XSSp23yjK31WpF3w0oBbt7O8xmE2EBqSDTfQqIKPVOXdXUTSOG3Qm8Bzc4rKloZuuBoJxxOXN107J3YZ+v+LJ/xIsvfog3d7xxAztpF6w6aWqm058ez+HW1scAePmVJ97ka7zRkTg8eh5IPP/s4w/8CWsVOzs73Lhxg2eebvnUz+6fe/yDX3V9BE5feXX/gc9Rjvc+/RJt22JUGfiu/fmKPFsbkeKDDBME9MjsI/IXlBwmSb1urBVJHllCHRNOlYAtTaXW95KximYyY9pOqOsGaw3dygmgmVEc6Tmk3q1KnZGK76RcrzFK06qNxhqT2b+M19B6+S7NscdUE6LLoPbGAHzzKP6i54gjedhn7No3Mibo3RokXtuonL+W5LmEiazUulk3So93epFGJ6Ul4V2pzAITcEpjsLbZ6FMSi/mKECTAJkZP168wNrDpeRmA6EEnSXtXxtJ3jsE52XdqCT+bbrA1h35g6AexOFGKpqmxtdzv2os9wXK1FFlaZEyzHJxIFFOUNNcuJdRyCRxhbcXu7j71ZEZSwqAWv2WLteBCZAiR3gcJmcnBHK7r6VYLYYUTWUbPnc5RNzXNZELvHFUtzNpEGr+Dtm5omyZb6SgxBrcQPFRVw2y2TVXXdKslPg0oFbCmeJTKeVJKoVPi8cfnPP74J0jp45DiuO6iFcu5oa3naFMDidOzmleuXeHTn3uEz3zuEV67doHFQkD8jSviDe7M/70ewr47Od3jJz+8x09++P2wceVb7bh46ZhHH7nFQw/d5ZGrN7l4cMzu7pxJ248/tz6kRisd89mZp6o106nGWqSW3rh/U4YpKDVTBsbK08aU/Ypz3aFRWZV23uc0eFH6WKvGwZdtHA89fJdHHjnMCbJy/NMffYb/8s+/PZbw2zsUf+VvfgfwHQD867/nz/LII7fZnjVcurDFZPsStmq5dfs6VgPZf1Q+lzxDGejJv8dMIAijzUVVVxht6If7PSsfdHxJA2Fabcj4su6XGMYmQjaUKBI9K5TSENK5TaQcZRN13su0Q5f0KQBJZRKqtWwY1ihqY3KCokwIfHC44MeGSSkxnTYme/2kNJpzlgJJK0E348YXq5QUfgaD8w6/QQuUjR5CEplKypKHYvQHmX0SnIBUyhC0wRpJVHMmNw46jWZ/iYRKKqc0iHRHJplO5KHZ+yQm8HF92xeT/5i9pkS3LwBYVYnHQtmkQZpdlaSBV3lBaJpGjOq3t5lOJsy2ZjRty3RrG6UNpycnHB4ecnp8zGq5HBuNFMUPpa7r0b9LplWagKbd2uXKw4+zvbPLcrHAuxVWK5E8NDPe9Y6Hmc/nHN69xdAv0TQkO+HywSV+6sMP871/51fwVqWCb/9IfP0Hr/Hv/KGP8tCVM/p+4MaNU+7eOebo8Ixbt46oq4rLDx/wFV/2Ti5c2ObiZZE/GquoZJCJJHNHXIg4H3nuhW3+yP/j13F6+lapsolHH57zdR+8wU//zBV+9McfHR+ZTnuWy4brN75YACzxjsde59t/zQ9w9fKn6UPArXqsgUlTMV9JemrSMs8p/MYYtTABRianFLb9asANp+eArhgCMWOkgg2rjVdPuZmObBZ8svnkSUP++1KEhNyci2dMom7EsylR9jEBHGxtqXIENGndDArbRJ6z62TKOPSR2hqGDFglFElLSqU1Vgzmo85YlPC2TL4ujTboKNOQs7OOysLZYmA6aWnqClspQqPxKWF6Q9dHutVKzseQUMqgVMJF8YMS5ubaP0RroRenLK2qas1kYkkpoJTHu8T21h5b21sszpYsl8sM4GW+qxJmjiRYZvAkJkIQaermETLjrB43uiTmmBn0SSkRdMRazaStqSrD4Dz704q7d05JGIIPzBc921s1JydznJN9wBpNUxsmbY0isgzhXDOhlab3htmsousc00mFrRoZHhgBDIZeprZaS7DCfNHjsudWueSMkdRLKBIsUXWhIHhJ8kwxinQ8/45zkV4HmsmoR0drjfeSbBdiyIbGkowaWwHJxNcso3JKsbc/xQ0hs1oC00mNtYqq0nR9ka+I7+EwuMyMFDZh21RUtRFwtxdmRZUT9aJSqEoAKAFJM4gSIjGKhHMYBBCLQPKRvve0qgKTMNbiEDmrj4FE3mfKPZqBk/V9ksbvP8aIjnINAiOYVfy5tBapjNEGl9OBVGkwcwqkGL8LQ7o878ikNnr0CAs5DENlllAireWNFC/N4ukjh/IRpRM+CuC1uS6NDYlaryciLcpsN31PEXLPfw4+UFcF2tz4MV1SSzPTNd9X43tSxfS7AHJKQnPYKJzHWy97ohXGxygBX7NJy367may5edybNhlCwA2OZNfgYxDKoTRxSeWkabGF0Bpa3QLQtu3I1gsZIHcukCxUFqwuREJhXXjWTD9TZOF5sJdIdMNA04g3awJO5wtiTNRVlT1dNVVlWK0G3BCYL5b0K4dSiraecHa2IkziODzVSuRQpMTu9pS6mYj3qzH0w0BMHq0MPjfpmnWiJsg+1DYNl69c4X3ve5bv+/63b2b/9Lte5BOf+goAdrb/cQ5VCty58xvzT7z9Gub45JTBOZrZTwH/6j2PSujHyfEJt5Z3ePGFL7/v99/5zrt54JJ44cX7GWPl2N895h2PnVJXW6h4XtIyenmptK47Y04h90HCHDbAc6VqYXz2HSZYTFVnSWAB6mU9DpkVOakNk7phyD2FUtmcv2lYLVbiL5RibsoEzDVKE3UBeOXnrc5G+Btyaq0VaDve+yMzMgPD1ugMkkVMI0xC37uN+/TehmXDloR1L7EJWt9nOHbP769lWRlYQ2qcsRFXmwNBJXV1SoTsgamAysggjKpeP3MSFlbrAnUlbMvByzXig8/PK02EsPA0IVUYI+zsECNdN6CVps7ggFKlFhISQcj3ujHi12m0Zto2TOqKmCLzvsNkGWTK3ksCQBQ4vrgXr4NChqEjpUBUFqs11XQCaQ0s+qRwKLTrSJ0oC6zS7O/sUhlhaseU+OEP/wh7Fy9g6oZXb9zl4MIuW1sThsFRAkt2t7e4uLfLdNLK/ul87ksV3dDnPR+mkwZrDG4QIAxlUBhi3AhsUuX7S4jth/y3ThrbDPRBo5Onqip29iJfsXeN933ZK3Jes52QymCud4YXXjrgJ376aT7+qSe4dXuXwVl+6XmXjbspPjbcuHmFGzcfxN6Va6ipHU3bcbB/zAe/5pNcvXyHq1fuMGk7Vn0StUdIzCaGyoK2cgduqtHI+ENEGO25FZFeXxWf2rwu5e+8sK1jStknNlHXGXCNevT9VIA2wpA1WvNNv+yzxBj4c//tt/2Cn8k3c/yl//HfJlMO+MavfZbf/ls/wvb+gPcDMazk/asCGEIBG8tQeq18EQ/OsmqFbJH0Zo4vaSAsC7+JMftkRZE6pftu1gffvGljQyipi8t+BXm6KGymYsa5LrpGECv7XJwtl3nqvE6oGTc7I9Ic72OWwKwn4OJPI9To4hkwenjEJIwIY9ZA2LjRKaKK2fcmjRObUnTFGCRyPSUqY0nUJBKVkUbakqfiJqGxqJQ9E5LcaHJqxY8sJJ9R6YBKmrpsIXkqrUk5ybGhruvsUWMytTlLWrK3gnOO46NjHnnoEbTWTKdTtnf32Nndp2laSbJU0K067t59lcViIX+WK4lBLaZmyL+WqTnkQt1WRNNgm4Ynn34vX/XVX8OVq1fpuo6jo0MW8zlbW1tcufoQ0+mUGCOHh4fcuHGDrlP8uT/3JH/tr+294fXyC3VY6/jXftcn+c3f9SKTyYrTkzNefmnJydGc4+Mz3OCZTic89dRj7OzOuHR5l739aQZV1wyKISiSh653+BD41Gcu8Sf+zIe4fWfvLb0fpQLf9i2v8vDDc/7W972L7/07T8v7NDmVJRiWy7eWJrk+Br75l/0UX/2+v0oMt1Ba062moC2nZ3O8H3KaWMRUIXvPyfcdAln2nPLmLNeC9575/Ew2lrhuqCWhVCSJKHOueERlk+EUKfLRrICjJLMlgHJP5w3FaoCERmNM4s6NORcfmuFdlKS3GNBb4rVUOGm5nlv/u1bEAEMGBhQ5ZTH7D242tWI8L7uimM1Xo1StriyTxjKd1tRNLtK1rFMhBLS1NLOKRkFIIjva9DmS01ASZzOtSolfV8wyUpFsy2JWNxXbOxOq2rCYL+hXHaRAaxJ6y1DpCdFHurO5yBPrBpNBn7I+lfUrFC3qONWR/xOlr7CpxK9EjwySGBPaGGZbknrIckVVVdnXzZFiTb/0BBezMbiWQURer41R2KolBJFySEGsWSyTMLsmhsnEYmwSREXFzOBS4jMWsvl4LsCdXwNqYhgs8i+ryeCfFSq7LQ2xx2W/kJiBwBgidVtLweMd1GXQYuiSyDq6rqfvNTvMmG41DIMfi6hh8FSVpIXN+y6f1yRSk96x7IYxHdT5gPMRF8DYmqauaNsKozRbuxOUhq4f6FY93gVWyz6/hjAUjdZgyPJWz2RaA+d9Y5QuvpsbYQWhBHPIUEUZNhgKiLn8BghW9o1y3RTW0TlfKBjlLip7cQDUxuKz7FEpha0akhdjW/Lera0en89ok60K1jK2dQOr8/eWvfxC9rpCrtNo5L8BBjdk9t8G+2osVvNz53WkADdFFjg+rlNRalDSlY0+7yNWpI5FFlrknOdYrBmsHK0RSkWd18Syj5b1JUbx0iOp0XD8vtY7Cui2yawrr19+eN3op3OssPL2C8u92CzEWGLmh/GcWyNDNBUUPvssCrgTCYq1PFbJPZhUTYxxHLqVwxrLE488xNVLfgzn6Lo+J/Km8TkA9ne2mM9FFmmUoakbqrri9HRJ3w/5nBZmb2TS1mxtTbF1A1pLWM9iLoDKZDsb5IcR3B2vBQ0YzWw64Zmnn+EdT7zASy8/zds5xvtOOSaTm+zu7LBYrhjc/V5dX+Qr0LuelBIvPf+r7nt0Mjlmuex54rFdwkSxWN3fUkTfk3J40Suv7L7hK33wfc9RWSCdl9mllNYhBMjgx+e6IGQPKB8kMd0oc84qJKLzoLQTL2FjxxRduW9krXZRTOcDgRQSrZ2SkGst5Po1hgLgZPZXVVFSbzf3VZvv7VFumV9LpSxtLnV83gshW6OkkL0ZJFEOwA06A9S5MkkFBJOaYBNQL/eGnLPCXpX1ai3tlXVxTDYe72UZ4Bgla0HivEozv4BI6UmjF+m9jF1hZlZcutCOcuxyhBhHlnjxWotRpNA2+2LGGCWts6kz0zgDc+OaldA6UNdyno2KmOiJMRCi+D1ZpZjPl2xd2CdpRgBA3m8ZLYilRt8PpEQ26Y9YG5hNdnGl1mhbjNYCVnmxtFFFqoaA47bStI2AZt/5G78VawAnLEJSZBgGVsslSakcugD96ojrt+bcuH3EtVsndEPA2Ip2ssXehT2Wq46vfO9TbE9bbt++zd7OjMEFCfTSOYHYmswmq9BWFARGGzFoJxG8xpgGFz1aV1K1KulbtckkjxQJwRHDgNaedz11i3c9eYvf97t+cryItNbYqiZEePHFXX7on72LT376YW7e3GG5qojxwWzD//0fcn33Q0M/NJye7vLiy09sPJ6wdqCuHdPpgr3dUy5fOubyxWO+7qs/y2RyBCZKMvLGMxb98L1QtrD98zPn+zaSxOA/RiaNYZUBV5tB/xDCaGlkrB1r66//4Kf52q/+WZ5/8Qqz2ZLLB6eczmf8X//o/wHv/3nAQnLt/PiHn+HHP/wMAMYEvv1bf5iv/qqPsjU5w6eSKl9UdPc8g9Zoq8Y18K0cX9JAmJgAZ90seZaZMjAwUhDvXawz1KrKpiQovYs+SxbUuPHqLGlRmSkRQpCLSesMXiVcHATBv2cyWsxV1xNiRcjNsDQI0lQZK0CUEFZk0QkhSMx3YGR6bUocRjPQGEefkJF5lSctknjpxQNFC2PMhYBOkT6K51JlK6oqN8MOUqbclvcxvobVIjsQKHs0Oi5T2KZtmEwmOUpcnWOnybmQc6W1Zm93D2MMBxcP2Nre5eDgomwMw8Dh8RnzsxOccywWZ3SrlRTzedqmWXvULFc9y3mPTOPgwsEuFy7vsXLgVcOVq1c5uHiRnZ0ddnd3uXjxIsVPbb2BKz7/+Zbv+I6HWa1+8dlfX/7e23zPH/oY73rXISdHJxwdLXn+uROOjs5wXujXk0nLI49f5eDCNlceusB0Vo8GysPgCD4vDgEIitVK8Tf/7rv5C3/pa3hrt3fi6pUFv+e3f5ZXXtvm+37wSZZLWaCryuOcxYcvdnqdeOjKLX7tt/xvPPrQP+P45BA/CNOjqZvcIEUmreHKxR3aSc3seMHt4wVni06aCiW8DmMUITjcEKkzFpdSNtgugFMSSnGIPoNPKqNcepQNlzxJuT8z60HJNabzY6WMk+slCbiB/KW2iaq2HFzZYTUfGLqARhNcoJ3WxBQyRil21mtPDQH0yn2kSWIai2IYHKbWayld9CjIm5+sVVrrMU2wytNKazVXHtrm9HiFd5Ju5Tzo2hBT9uUgMJlWdJ3H93HEwpKSzyaN3rrhUxpqK9NqlETKOxeIAXa3Z1gFC61QKdC2rdD9dwKrxQq3chBFYkjKoEVOoUwR3OBBKbQ1RJdZVeTaMq3Bw3UPmRt6BVVtME1FVVW0k4a+G5htTwk+0rSWoRdPLVNLA6SBVJlct8oqUjctJ0dnVFaxOOvpQ6K2lrbRbO9YrFf0Q8JlplNdSQEhJvhkgEKPa7x4XMl1FpzLnoSyB8QsBZHplPjUbRaMq1VgsgpMp5rBD1TOUPUDoGhbS1Vbun7AuUTfebrO5z1CZBA+M8OCl+RIazVNU7FYdQyD+ICFkLLMVeRk1lY0dc3Bhe3sJyPAWTG5VwpWiz77JnUytJgJCy/4QDsxY/KwKqDVxt0eo+xxSWtiCEybCZXVDN5Rq0jyYTxvppaUz5DtA2SaKf9ujUbHdYpZjHH009LGYLS9rxmb1g198HRDT0JAcptTZVMIpJDXCbNusI3KLG1z3qujXDHF7LgAfAmpVRWIPNNAKsEKBThmff0WsGsT0BtDblQuVsmJifl8yr0ie6nKgzopbaIwvDJglxCwuDTco09ZBr3KANUYuxEEUprzzPSTZwE0SWli9GOjJz+3ft/31jkxRYwy42OyHtlzwKasXhmIK2AY8pnC4HBuYGt7S9gkUSROch3JOXHeE1dptHIwG16JVsMQOPdaApJJLdM0zRpUjcLYDYWZSQFDEgc721za30HVlbDetcbamr53DH2P8z2r1ZzVaok2M7TW9L1MrUNuor33DEZqkmXX53TCNZxgssJAK83e3h7f/u1n/Pm/wNs6hn6SP0fi8sULvP997+Vs1XP7tuXsDH7Fr/gMP/zD7/2in79uTjOQMuX5Z++X01y4sODKlSu898vfS1VZ7mWgGSPAR0yJ45MW5984zv43/NofFQsSLRK6TSRm0+Ov1L8CvIa8u573sFsfwqGOURixIjOz2MqObJ/gA13qxG7EgCcwBMeWtSQiwfvMoo1jA6aN0BOVTuO1HsqwJoMtqfQOIDWD0aio7ktgXd9O6RwIKMqWnq7vwcxQyoy+owVjMpjM2k5Efx66sgUJM5LkW9ifm91QYbjbTV/HMrDbeB8JkVuXxvq83PL+Iy+VFMAdsjdgrakrOz5vCIkYkL0l11eTSU1TmbwigcpDDLL3m9ViTm+NHb05I3EcNugMck8ncm+EFEYfpvVhJBk0kkFWWdONmWC0EX9dramMeK8ZlUBHjE7iA2byqxb/2j6hjKbWLdHL0M8qqTOjczS5NwpaE2KkMZoUPBf2ZuzvSO802zng0sULBCxWQ985bt++yUuf+zQxs6a7bin792QKVUM9nbGzu0vUFY2x7G1NGCK0dcUsf35tDX03AGmU9MZCGkmRGDzWGJosQbVGy57ZTvNwh9ynBp5615x3PvkRYvhp2YPyddUPiVdf2+dnPvEQn/ncw1y/eYmT0ynBa/GhLRvRLymwTOF9g/cNy+UWd+5c4fPPyyP/69/9ViCyuzvnwv4J+/un7O/JPy/un7K/d8qF/VMmk25cHxKS5FqOlBJJgfNSszdjOikYJQSa8vMBAaLH4VQ+nnj0GiipU7emZ/zXf/rPEAOcns24eeuAz7/wKE++8xpKJf63v/cNfPa5J/jFOkIwfP8Pfgvf/4PfAkBdDfy7/5c/x/b2GT4ofB5SFP/CGIW5qZBV/60cX9JAWMx6wqhEdhjCetKpKAVbnrwku76gciEtm6ssoItuidVGUow2ispxBIQYN8eYMnNJZQNyQW+LZ8smHXoshCNYU2Eq6ON5zaqtapQ20uzDyJwqPigp64HVPYVpkYCZvFBL9HhpKuW8GGVQaPHJiAODUszaeqQM1lW9hpyNxIuTkMjjIIloZKNTowzW5FSwbCBb1zV1VWdArVpP4UZ/pvU0tJpUXNi7wO7OLtN2ysGFAybTCbfvHnF4dMKdu3e5dfs2y8UcoxJVmTgZizJlgZap26rrWSxXNG3NxcsX2NmesrW9Q9s2xBh4/rU7nJ0e03XdCH5Za7PPhOPaNcMf/aOGv/7X5Xv9xTy08vzrv/sz/N7f+TmU7jk5POXTn7zD4eEpN28d0fcDV69e4tKlfS4e7HHlyj67u5Mx1CCR8lQtisypl2j2l1/b4U/86W/guReu8tY2m8iv+ZWv8gd//yc5ObX8H//Qt+J9NlxUkZj024jn9Xzj136cD33D30aFV+iWC5bLmqaZrBkXG8XUpK2pa8ve/jZXruxxdLri9uEptw/nnJx2dJ1ncCmbvcec1rT+rOXaTynk1Kg0XocxF3Biom8EXL1nmimQmCp9MnUr3g7l3tz8Qd9Laslq0XN0c8FqMTCdNXR9z9mZyRG/KgM8wliJ6HF6Jl585Q4R2SHK0LYVs1ktMmJE4jq4UqzFzCQy5z734B1d56nbCXXj6ZdLUsrFY27Ya2toGkvTiAzTZ2MtrQRICz6OhWkB+8RQXG0wbKRYtcawt79DQHxbhih+ibU2+N4TK5mcF/jajBI08C6MhpYio8isKnLKrJLXo8jQVA7nCJLUpRJU0wJAifT8wsU9umXPatnJ6yrL0AnYEnXeLAtNXCliSPgh4bqEGxL9ckF7sAvJEaOwzbxPrJwTo34dMVbTNHb0fzFaWFtGG6w2xCBNbztr0Idz/OBQmBFQMFoTjKzF2hT/R7LhM0QlqY6DH9CDymm1cmKqqmLoA2dnDh/mTKf1uL8psnfk4Ef/peVyIATPMEhaamURZmWecqs8FW4aK15p+RbUWjFpGzSKFBKnakWMSZJ0jz3GaNrGMpkYjIE7d+YcXNxhOpuwWkmzmICu92OypMhXsqcVGhfye1GS1GpTwmLztFzS94oUrbBAqgL6pAIw5uCXApyxbjxDDKhscmfyfq61Qtc1KIXrOkI/iC+V0bjBjUOvSqZC50CVWFDrspvlosvksiL4MCZPioQzs5azv18kA2Tp/jV5NOyPYeP1itlllitmELA02yoKe7uAsBot104BnjbBtyTggDio5kNJsmY5j/Kc+XdVTmvOg6txGnDPMYKFG2ywkW2KNPzhnjUzpUhAUQJzRsatknt4GAYJFbDC0Atu7WEXBTUjpjBKhmV91TjvcU4A3rqkTW4Ad+W9FdmqqQ0mCYAc3KaUVTOdtigFS9eB0jQ2Yc2U7e0toh8Yhpl4ESlFCJ7lajGeVwGnHcvlksF5ZgePYKo1iCgsnPP73dNPnfKGJ/lNHEpFJpNV/qyWD33j+1ksFrzjsUs8/a4zrr0Or77yxlLEN3Ps7FyTe1CdPvDxdzxxh6atR9D53uODX/WqsP9S4od+9F1v+DrWePZ2l8JsQa57leu94MI5ICzGOHr4kWsACT14MEMJGINoVFK4JMbLts6G5uX+rytM9ubUW5p20hJ8Tv70PoOnG4Arxb8swLj+JKxeB0MU1LewFGI6L9OOyaPUgweM43qnFCku5e+oSVrWcPHSFMDX9e7culV+r1x3xEg0ZgPwyu/innvFx40hYHkMAcF8FBVKqakU3Pea5Vh1Hcpamqq672fKNyTsXBlaNZU0r1NjSDH3N+XXEvjox3VyM7CjsHprU0tad3RUxrA725Ieoa7FI66sw2r9JqxdJ+NqbVCqoqomKAVNlavBDBjV2qO1rD1NXdE0FSkFCfwJ63u6X637uzLoOE+QECBfW0XcalB6lzpbIGzvthzs73Bw+Sp1M+XlF17g+PCQp558muViRd1WwijzEgpirKJzjuOjOywWcwbv6fo+s+uEtRcxTKczQDGbzWjbCW3TYI1m0ljappI6WmkU8jtV3TCbTDDmFFuZMcxGHssscFmU0RrqumJ7t+ZdzRlPvuOQtv0cw+DZ3pqM59uHyDA4bt/VXL+5w42bu7x+/SLXrl/g+s1dTk8nrLqaGFXuP34pAGaak5MdTk52ePGlB//EQ1dv8tijN9nfO2Fne8n21pKt2ZLZ1oIrl+6OIQpbbTXOWJMSj89N0AwyC9t7xiJm3L9VJhCUe0SxNTth+6kznnzqpbGP+oP/5xfGfiXExE99+H0cHJzwnmeuMfQtf+l/+vV84lNP8Qv13Q2u5tln38+3/coP46P0ZYOPDF4sgIIuFg9lcLpmwv5cx5c0EOZCkESnUqiqjZUzSbMpsiLx3bFZHpWiJwaZhIQ8nWmqBq2EWlqMkVNu/qwx4uUV1OgVAgLEDYMfm0its2Y9e3KUplLlhmlcnHITWlWGqm4xtiJ1q7GQKIuzeGlIoaxNjvG1VpqfIH8ndGMnxWeKuGLyq6RBU0o2+qEfqGqLDTCpG6YTM5oLA3LtGiCAD2t/AplsVNjKjH4skqYm4Fdjm/uKD6PN6CnSti2zrZlo1Hd28sZsWCwWvPDiS9y6e8jRySknJyfjhjlrqnyOM/NNrZsDgL29bR557Apt2zCdbjHZmkJMeC+SQB8cfbei77uxyDk8XPGn/lTHf/KfHPw8XoFv9kg88dgJ/8G/+zN82XtusZgvuHXrlJs3jrl7eMJrr93m8ccf5rHHHubypT0efugiu7tTKpsR/swgCEHkTd4FUoTBaf7297+b//ovfpC3eivvbK34g7//I3zzh16isgISPf/CJba3Oo6Op0gD8sWAhIm9nUN+3a/5QZ5514/jhw7vZJpqqlqun2r9vM45KluhSsOar53T1Yrj+ZzDkzPOFtKQV1ZDimLaHaPc15n1kHLjWJJOzTg9LmyKlI0W02gsKNLnLF8YazUlEdkaBhdgg92YcoWokMSwybTh+NaK+Zmwb2JwrOYKPzhstZ4Il9dRURhR8n5lulg2Ftd76hpmE8vedkuMAlCtOsfJyUJCKHKTHnzC1nrth5ZgsRqYTcz4WsWUNvqAyQWwNZqmrRg8aJ/oOydeZ1rTB0fx5EypAAtkwEyq+qQStpbiq5m1wuCxhq5zKNuLUXVl19erD7S1FvldBtvOTgOmMuhhY+3Jh5RiKiOaBeTIaXGFARCB5UCsxX/KWEMN0CYWi9XYfMSgBOBJssn3vadpPTs1HN5ZMfRe1u/eoZQ07knVdENAmzTG2QPCPghR/FCUfIfdMspUWktIS9+v9wFVgJsoHkBFqjpStvNyaStDVWm2d8XPpqol0a4bHClKgqUUsC2V9ZycrDg6nHN2qphOqzENU+ciNaWEdwFroZ20tNnQce/ClL5zHN5eyLqqBKBd9QN72zOW3TAObYzW7OzM0BqO7i6gfB+qgLKe1cpyerLCR831a4fMdmZszSpia+ldYLlyLJeO2bRmOq042Npmq5qC14y1WW4O/SAJg/JXCRfiKHO0tiTerj1dxp1GrYdGm2yk5WrJMIjUrpoIIK2UIjkn97VSKLsOlqnqCpvsOYBibNySBAHEqHJScimuwCpNLImneUCRq4L1B2QjrGYDONKs5YXnHcDWhwBrFSEMo+QQ8nBCZ55pXANgm0mYdV1n5ujGQC9l4EslYc+yZlyFEEDZ8d4fzwNrRkvZt4skavM8FUCuSLhjiqgq+3WMn3Pjs228Ahu1VIp+LanMp1Hl+1d8c4QJY6IBLJVWuMyCKR5NetwTRLJYjpI8vAkUhswOrGxFXdWklFiuOiIR2ygJ+/ErohcLiaYWOXEBCoauZ9JK/WNszURpFquObuiwxhKCzw22ACXiByUMdjf0bG99mp2dr+D09OIDr4Gf62ibnjt3L+TPo+ndVd7/vsj+7jaf+ln5oDdv7X5Rz12Oi5c+g3IeUyf291/l6Oixc49/2XtfYrW03Dm8yz/7MQfsn3tcKUVlNT5E/uE/efcbvs7+7ukIbAQfMFaGUCjQOqBUHINnigJj876vq3otS85ri9QEcfyzljoj+36I2fA9EhDz92baYG2FzYzjgseEIF5k9+I+CfEOdU58nXTegM7d1RkMgxzoodZMxPH+y+eqXFzn1STr4AlReUQU9r79U9qedF89Xp5bF7A7+xyWuij/Kj4EXD6fRokHMmQmWPZaNEblwTjZiqbInDcXjoTGgxvwYb1+aFOhEMa7zrY2AjJZqvIutFon0m94Lo6V0sYXUMD6zfNUK5i2E84WS1Z9TwWkDJ6P5zT3hGoDpNIKbGaqBXdG1PW4V8oHWL++c8KgqmuNbu2YyO59RMeNHWATzGMNNJCS+LZqQ9vUkBKT6ZStnR1293eZTVtSCCy7JcEPBO+ZzmqUzgnYKjPVNNhuxTB09IPFeS9rtJaaQ9Ym6Lo5pITCE0NHv5I1/AjxyXPO0/We45M5JycLlNZ89Vc+g9KGtq4wxjDbmspnzv7Pzgszva5rUBIYl6IMnyaNkE6WXZAe12rqqkJry9XLcHH/iK/7qhV1fTcH7nh6J95o1lbEaLn+esurr+3y4ssXeeHlK9y6vc3JWct83uC8Ib1hb7LJuP/SB9Ou37jC9RsPThd+/LFX+ZUf+ikODhbs7c7Z2z3FWlkXPT+HN1aK4/2X/4EEA4q9YACS1iRb+srzKo2UEl/zwY+TEjivqeyK3/+v/S+AyLyVKUNamM+n3Lq9z82bB9y8fcCNWwdcv3HAncNd0gMGhA86jA4onTg52eFHfvyD7O4s2JqumE7mtPWKg+0TIDD4hAvkASSszH0C7wceX9JAWEgiV6pNLnCzZRIASeKNRy3+Jp0/RrQKKLP++JWVjaVM+JOSaPt1TL1sIOcS4FJi8OJJA9DUNdY2WFvnhXyAKKbYVQatJO1RC01ba4yxFN1+eU4okgUNUZ3b+Avd3lqLz8attsoblo/jlbrBxwKVqLKcqGkn1FULcRCpRDp/oWgjryvmyBZbVRn0yhMzszb7t/r+y6dtWyaTCdPZlOl0yqSdUFmZZCy6BYd3D1muOm7fvkXXDfR9ZMjRqE1lmbZNPo9Z45yygWBtmUxrpjN5fmstk9mMGBKrbmAYBrxzzJc9nYPp9i5bWzv88A9bfu/vhRs3ZsDsLV5hb/cI/I7f+hx/4Pd9lkkzsFys+OynX+OVazd4/oVXiTHx7qef4gPvf4b3vucpdnZabF5ABEwQtoL3XkIYQkJR8cpr2/yJP/O1fO65R3/Od3D+iPzKD13jd/22T3D50jV8iNy+a/n+v/8MP/APvoaTk7dzfiJf/f6P8iu+7m9Q19cI3rM4VaOpqTGKFK2wN1k3aJGICw4VwxrE8InJxHBhf8Ji2XE27+hjxNgZk6blbPmy/D5ryn7x8SqLep7RrrdEbVBas3m1b6a0PejzvOGhJYTK97BaRkIUA/Wuc5IgRqIf0vjDYuhfwAY5D1oVnyhhsF2+OGNne0LTyD116coWSiuODhd03YDLkh6ZZOZiO09UF36FOhtoTCk4TW70hCmmlAatsZVie7sCpVmuBFAkhgz9qfX5SqCyLTVAZQ2NVqNfWohiiF03NcdHJ1R1hdKKydZEknK9FPRucFitCMGgVJFdy/dktMUNAzZ7CWasTZI2k8lhJfJmhAEQxWA/RVZnK2wliUzFDDuEgLUG7wLdsgclhvXCQovi4YFhftpDZGRQoWRQEUMkZbAnZqPhZlJRzEaB7OsYGfqEUXYEQ86ORT7oBpfliIHgE+BwQyffs2CT+RpU2fsJ2olhe6/O368AcPJPR0rQ1BV1LUmwMUnRWpLwdPZf25q1VDnhsUz0dvam9M7x2KMHLOYdLz1/OyOw4q3SVJaU4GS+wlgtUt58BRhjaSeGvYOGru9Yrdb3QokETylRT6wAxl3PQ4/vcvdwxcF2y5VKPPOa2lBXGltpbKPR1uD7mM/NiK+NgEvKTY2EBIh8N4SSypZDW2LIzbGASfVQi0Qm+/KMQRcpjelfxavHZ0/OymwU0ZlJMqZRsmYceO+otJIkUyNJb85Lp6Nys60LqB+BbBBf3p9Smmr8XOtGKOV7IMSAQlHZKkuOMqs8g0OSRhhIG+yq0jynLA9U+dovTJNNc/bCbnsQa6Ow7WKMBOcxdWGlpI11YIPZQllvzz/XppQ0ke/tnMJnrRUAaqNm0iahbQa9HeLXBwQaLH2+xgrbcc3y2wTdytcn3mY5kS0DDDIMLYb7nqF3GGNwg6Pv+3M+ZpvHpJ0waSe4DJgN3mePPGHM6cyUMJU0pAlh4laxYmtrm6puGIY+p3InQpSa1BTgRQnrhJg4OzrmpZdf4iMf/xjb2y9yevqf8taY6YKWrLoJ164/Mv7tz37mGR5/9BNcvdzywgvvyD96/3f/Vo7Ll65htaIyidVy77738YEPrLj80FNsb+3yb/wbl+77fWME3FguKm7f2X7D13ni0Zt0qw415MTxIMFLipDvez+Cl857SrAFSmrOTY85yCzZfhjBXq3EV6mATOX6ssbi8ePPybBCQF1jLaul2A2kDY8ypTZOqxjeYXPC63ivbAyp7j3OsQTNhqx4o8ksQ3EZKK+N98ua1ocebzz0AhYX4G/9O+IbybiHhtxnaEgbjM98T8ccvjVehQmGexh+VqlikpqPDEaGdM9lVgYXeXClFFVWn8jrRlTSFHjr3twQ8jpytjgTZmleS6qqGk+nzt6JIUl9XEDUFALKRqZtzXQiw7rB+RzMofL+sg4tAmH3GhXpu8V4/nwIkia68X2V72bV9/m7E6BJK7KfsyQDLrq8jyhZy42tSIkx7TKxlrpXlQBbsr5U1G1DQogYk8pgUg8qZlYbwv6ZVkybBoWiqTQu+DGI43S+lETN7BFlrGYykcFI21RYq/FRseoHumGQekMcgaialp09zaSphWXsAp995WWGQQJE+t7hnNQpxhgmk5adnS1m0xl10zCdTjBIAMnO9nYG/i3WaqzN90eKWBWwBkxVEVE475EggERlErZq8KHnycdrnn5KS6hJTt+0ORAlYfCuYnCWvjd0vaVtVuzuno77+MnpjI989Ck++dlHeOXVCxwebbFaVThv+d8DSPbKq4/xl//q5mAiYYxnZ3vB1ct3uHjxmCeeuMalSydYEzi4cMLW1lIChFIY7/81ZnLvK7y5vcOHvHbmHzdaU1XC2ncu0jRzHnt0yWOPvj4+ZwL6oeLmrQtcv36Jm7cP+MznniQEzXueeZGj411eeuUhzs5kzwhRhmM/+I8/+Ibv43v+wF/lPe96ma3Wj7OHhXFv6jN8SQNhawPIMgkhT7u1GGOqNc0/pIDShhQ82lYobQSEihtgkIakpbi0Sou05x5JRvFn8Umm17ISAs6hUiWTBsSMsKqsGOxubHxFkx8zQ2zVrXJBu05l2iz6al2Mq7PUJwlTrffiTSbmlmJkXBgoNrNqylzK5JSuKrPJBi/JLwQvPgI5drepGoyWJExrK5lmWjsyF/Q9O1aKCdtWxBwrvL21zf7+Pru7uxhr6LqO+XzO6dkpp6enLBYLjo6PcN7lVLqKtt1iddKxvbXNwYUDZrMWrWSDUBp8dCitsU1FPWmpmobKGpzzLLuevhvoezHLTEpx+3hBM3mcv/gXv5Hv/M77C7Nf+CNx5fKC//CP/hQfeN8dlouOOzdOuHPnmM8+9yLPv/wSjz/6CF/+7md4+l3v4NLBLrPtlozDEnICpvc+e+3kWitqvu8Hn+TP/vlvBN7YZ+NBx3TS83/6fZ/lm3/5ZxjcXW7fPuEH/sGEH/2JX8enP/s0MX7x3l+zySm/4Tu/j3c+8hOkNNB1c5mMKZVBjlIZip9HQolEJh/KKGLwGyaviSEEFoPn5GzB2UL+LJcOpZZSyGogyH1Zkp8YBxyl6XK56BV/JzQMMaLfREqXtDmGmAMyYi7stM6DwQjeJU4OO2ylGAaVTRwT4AlhsznMpWYSllIsBaBSgJihb2+JJLTKzaitLAkxaJ9tNay6gX7wDE68o3Se5GmjMBXE4Kiqir7vx5CPGKOkl2lN1bZijhvFj2xvxzKdKYYhIB4oRkCVNY6OQqLIrTFYKymZSlQj9M5hajtSr73zqKlM2LWRdcxrPybkeu/HRj2RqFuDrQy1N/iVfE9+KNNlAQBCjPggRVfnAp2LLDuP83kq3UeM7pmrJVVtMzjk8aH4BkRJUTUyEPEucHRnzmopRvDORayV96G1EjAspjGMwVhNXVe5CSHfkxJlvVoMLOaOyVTk1ouFnOdh6FFeGiNg9IwJxVslJqiMpIpauTa8l6a/riq65PE+sFz0hLymCkkgYivF1qzNbFBhQSotDV+RawBUrUg/j47mVI1h1fWcni0ZBgdJmIfOBQYSx8sFbSMLz8WLW9gqkpLGGU8zqZhMJU2y69fm/DElhiFIo29ge3dCXSn6zrO/16Kzv4ieyT2+N52xN5nRVhUuigyzNIzaqLzGB4i5IEb2NwEpxasnDA7IEnctrOSmbkTung2s143d+igDpI3lKktsPbUp660TGC57iRotgJqPsg47hB1RABhtdZaSrPd0AG0VpirPUwJc1mtNyhLTseFWUmd4nxncRpKUU0EHgaETRpM1cnOmLEuKMY0+dMVXTKFGRkM5Cjg1glSFQRHSGFAg12XEBC8AOmS2SEQrk/3a1MgmKx5h6+CL8mICpSuzkYalcx2Un3Q0PFeglNgVlO/F0JPqA3Tq0L4fF6KYA0/K51DI9e2GSLKSRpdUbuZjJBDHpmvSNjR1cw70Kt/BOR+4PPRzKVG1Lanr6Lt+bHKtNaQY6JcLtF4JK18bAcXGpGBhESkkxKTOgEFJ4kMJA+Xk9JhPfupn+fgnP4WtKn7Tb+xI/EP+q//qW3m7zdn8bItJ2xCx3Lw1BWC5ejNJ0eVbv//48vcoHnn4ywne8Tf+5tZ9jx/sK04P7/BDz/bAN9/3+Gyrp/eej37yiTd8DYCv/8Cn8MHjeofuNFtbW+I5lkLeEwwgdgg6p8jGIJ5HVVWtPX3L/ag1zrlxj1I5zbGqMvszZhmyYg1G5dqhyGtj9gTb9JwLYUD7IOqDHJChkxHoWKlxkMTmPx9wuktQRhlObMqMFQpTbYRp5Nqi3IM66pENuw4RUDRWTFNL6mok0mQj1Rg8Pvrs81tcUNfr1xq4SxQFqDYb69zm/52/7ceUyfHvlBL2HHKf102TgTCVQe7yvOt7cPRfy8PCwQ+cnJ2MtibaaLqhIwGNrTG6HvuhzfdSWcOslRTLHhmqxmQIOblPzk8ah7NWiz2E2yDQiOeVeG9WdtM7rZwikWV1vUcR0UaGk5U21BaqSp8D/6OuZL/UWmq7mMT3Mw9pCtnCKoVJiUlTcbI6y2oFT6V60gCqmlJVFZO6pq2rLH1N7IUZSilOzpasKrcRxAMOm/cjxeA0Z4seH4X52g8Dg3O4EJhNtuiGQFNVBBLHx0su7V/gkYcvAokQNAqRgi47z3I1sFz23Lp9TOKE3gW6YUABvQtMJxMmbZUHs5bt2RZXLu1z+eIejz9yFTvb5tbdIxZHt9AIgWF+tmS1Grh4sMu1m3dZDALEXr28R9s0XNjbYtLU2MqyvTVh0tSZcVYxm8r3v1jIZ7fWcGGv51/5tc/xXd/+3Hp/knaXm7e3eem1PV546QKffe4KN+9ucfPmFovFF1ovZZ201hN8Tln/FwpQU4RQcXS8x9HxHjwLP/JjDwKOIrs7cw4uHDOddHRdw3ufeZ6LF++wPZ2ztbVge3vOZNK9uZdNpfeSOswH6Sua2uJTJAyJ3Pacw94SPQeXXufipWt8ZYp866+Sx8j+s0knnLccHe5ydLTH0eEeR8f73D3cZ7GY8tIr59nJf+q//R1cuXSH//CP/DdinaDeeF+79/iSBsJU3nVCkBOtlJKNT2mhoFs7jm9ikmZEsLINr4Z8LSst8getUglukSInrCNI1+QyhTLCLtGVRlmVpy3I5DpPPSDlaGQxqo/ZxyuGgPdplDYppcQz457pXQHhrNIoC6gk5qxRpqwhRTHWJi+yxhCVmGoXECzGBDrRTlou7O6wNZlitMVoizXi8aW1zalgKrPEhNK6Nd1iZ2eH6WTKfDnn8y98HmDcwEOINJMJk6Zlb3+fne0tjNbM53PmiznHJ8fcvXuX07NThmGQ39nwQ+m7nsXKSXEbIxcu7PPwo1eZzBqC75mfndJ1HbpuqJsms4cCi8WKfjXQD+LhUw7vK/4//91v4XPP3h/h/Qt/RP7V73yef+cPfoLK9ty6fcSHf+YuL798k5u3jtnemvHwQ1d46sl38q53PMJ0VlNXKhu2+uw1sG7cgs8bmVP8sf/Xh/jJn3knb23RTXzNB27w23/Tp/mKL3sNVOT69Tl/9wce5R/98G/j9OztgISRr/uaT/DN3/y3gLuE5YIQhTrdNNUIRqUMBEDmmtzz9ktBMXTS6K4GT98PGKNZOc/p6Yrlqh8NEb0TdF8pTQhpTB4iDKDPp4aVpS2lEZfI73x9/T0IFBPgzsoakIo57rqwMFoaY2MM7cTiXCSGbpxAxChwTxmtruUXZBBMjesIaPYPZhDhwqWp+OQmmE4sDz20x3y+Eu+PmIRVag2DT2grvkvWKFLy1EYxdAua7e17PosePX/GJD4tEtHaaLZ3DVux5vZtMXYO+Tsyeu3rpY3OEu2A1XpkkZb7eTqbCnheV6SwXmdTNkx32VjeZuDH6ETUgaoSs9uzEOmWDpRIInyAfvBUVnF62lN8V1ZdYBgkdUqpRNdHKiPAXgE0tBEPL6U1g4s0TU2KiWXXc7ZcMLiBurJc2NpmMV8RY8C7RNNWECNaV/SrFUVeOgwDs1kjXloB0kpYi8bKenxyLAwTSeiN4OU6F2G8IpKllBm8SCmhk1xNSa0nxm6I2bNSjGlDMYTXMmQxBqpGhh0xiGm+cwIUioRIgNi6FVbM4AO20TTTivmi4+R4KRHeMZt3Jyn2rZW90ZRozxRZrXqsmdK0nqbVNK2VgIUMApKvc6U0Pia63jFpK1YrJ8wvq2nbGmM0XT/kBjNP/q3Cokcp5Cbjz7meImtISQZZWduavw9DWzfUphpZHWOK80ZDVVgWwCh72vz7Ar4kEt73rJwDxAPTaINXXgZiG5LokHI6mBJW6SZrohR21lTrhNORFVJeW+fhmiGE/F4wlCRVHwR0K2yuhNynVSP2BVqJX2cMa5CpfC6TJ+SbwE45FIo6y9FHXyKdNgZqaTyHPkganMizsi9gzGm2pdGN64Y56cLCymD/BsOsAHuFMV5ln6ACvJXHG92M8kS5JwyVrTFWpMgFrCufRs6pvNeEMOvKkK+ABCDgcl2bDEQahkGsI2wlUmqFGv2VyrlLGVmOCeKkxTtHleV5xeRewAfP4Dw+JuLQk0IPKdCkKa7vUVoSxytT/GpzzLuSgcCdu4ecnM153/vfz3d8x3dw+fJlqqri9PR/4i//5d/Nm9vj7/+Ztlnx2CPXUcpI7Xo/zeYtPZ8ciQ+8f5e2Trx+/dIDfi5Razi6c5vgDh/4DE0t++3/+D9/wxd8B+9+8hW88ywXMuyqq1pYvGoDpFECOCjE88nrRElzB5EdinTNMQwDznmoRI1gItR52Cxrcxzr6xHUzS9jjaFtpwxOGNURhVeGIUWsUtTW5N5AZVA1cR+j7/xlyygzvqd33lyfzh0boFhS59leZPax946sRsZo6Lw0ro0R8KskaZbXlwCtuPYhzM+3ZigJCBZDqdUecF2cA4Tk/VWVvo/V5YMjKk1dt7TtJMudI3FDqlQYboPzMthDrGViTLjgqScN1lgmVTsC4ZWpqKystSGGce0sgzZTVXSDI6aEaWpJbI6y9m96JkkCdCAZBbZmM9SifC/D4IAKmwM6UHKeUMLqDmgqq9HK5/OxFshvfp+KhDaWSmtMTnj2MWQgLIdoKLk2de5p/dATcxAbyDrfNIq6NtRWj+QKo0VtlJIw+ELYVBche32CwUV8DKSk6X3gbB5ZLAd8lP3ubHmWB3KOqa/ofU+fTtnZqqltw9ZkQltNOFp5UutxKZFWAz7Xu8YY6qoSD0cduXt8QkrC7py2E2KAve2Grp+y7AemuxUPPfoo6upFbBwgBWoTuX3nmMVixeAj4fCY3e0Z/eA5OVuScqjR6ekSFwJlyFzA6ulUhh4He9tcOtjBWsXF/W3IDOxNqavSd7l8JXLpCnzomxqqukEpzXzRcnh4hRs3drl2bZfXru3x6rU9bt7aJkbNd/+mn+H3fPeHCSHS9xXXb+zz8mv7vPzqPi+9coEXX77I3cO1ssYYRwibnmf/IgBnmpPTHU5Od8a/+fyLT9z3U0pFqsqzt3fCl733ea5evcXVq7c4uHBM267u6+fGI0HwiYXf8C1MG54YpVvKxVPK6r1Ueq2Y65wARkcuXbrDpUt3JLgv90+kyHw54cd+4us5PNrnY594PwA7O8ccLhJaS3qsd78EgDBNxGqDR5dtBmV0ZoKJAe+mUjYSMXkzisKzIqrI4ANu8EKfNjqnx0kTG8uoQImfWCLhs9+AMQYfA21di4mgkqjjKNWusAvyJFQSr4pPRYJR4yzShmEYKDHgY7JDLgIqU9EaKSJ77/JllAvSzCZLQG3t2PiHIEbUPhsrTqYi3Szm+kYbrK0w2YjemIq60gxuRYwepezY1E5nU6pGGtcyHdvbu0A7mbJ34YCmrll1K+4cHbFczDk7PeXs7IzFYs6qW40eCJtHeZ8y0Ya9/S1297dQ1tC5wOASXrdQW1b9wHy1JEVPiD6n162pmDdu7vIf/cnfxsnpG1Pvf6EOax3/xZ/8h3zg/UfcvXvKSy+e8Nq1O1y/cUhlag4u7PKORx/h4YcuMps21FU23bYaY8Wzwkc3MgPcIOfl05/Z4w/9e9+B3KJvZfH0fPdvfpZv+5ZPsrNzl+Wy58d+Ysrf/Xsf4pOffjchfLG3fKKqjvmuX/8/8tQTnyVpjfcyrcdUGGtJsSdRvLEYvTMSEn5Q11ruyVCKrsSdO6csl45VL9PNxbJn1cuUqnMyeeo6oWT7CGMKYwmqAMgN1/nabX2XvNFcID5AR6+pRI5UEtfufVwBKdEtB4bBU7fCxBG2gki4QoTkpTATAI/MuitIOnl6LM3mow/vk5ICkwguMZlWzM8WOBdyw2ZySpWmrsXQ3FjQeLSK2ErTTGpMpUnZj0ZpqGwt4FD20opaVr0UxGy4nViCVxjVZxN4Mp1+TWcX1WLK/oMRHyxVNPRdT4pJZMq1pV/1UpSEIpeQ967zxLOqhOWFSpmxoXDOMduu8UmK77DqqWpDv1oSvYZkcAGJhw4J5xLDIKwi78UrTRRRYkZeG40yhuCEGu2cJ6FBRdCMJrGBKGmFrnzHMsUaegfaMvQ9MSWa2ogMK6dqxphyilzAdZ7oBorQ1xq5HxLgABUSSsXcWBTD9TxgQdHWJqeReebznnZSZ48ZLTJirTFWmoymteINgiY4ue77bPJuK5v3PUHWIiJZTFH8whanHcuFw3sx39dGZLmV1bSjh5YwBqzW9DFAEnZQ05p8DZSEMLnfbJZbBOckBCCzMmNI+VqVvc8qsLqEzAhzWZvMTcqDopSn8zHaEeAqbIFyR2oj3oEqs7WAEVhRah26UQAbnZOgCxBW2BRK53S1zAgKKTc2ZGkQEautVBIbi0bMSapDGuT7UVbkfymD+SHQ9Y7ZZCLJW1qRVBzlXEqZLFVJJORaTEhIQHn/Xvvx3hkLwgzAlJ8pr1c+NzCCe6WpL8Dg6K+UJWFjYxbXflrlZ2SoFXCxAANq/PgmqbHFlzOV14kgn0Vpw9a0Zejm2RMvv8xGg1+YeT4zf9dePfL+ApGoKrGiQGQ4xoofWVJyfalMVy1suqTS+LzGGFSEmFZU1UR8a0iEIP5fLjMLlFb5/hIWUV3VG4wUYW5qAKNHEAwlrJEicXTeo7qO1Du5JgJoF2laueaHfqAxFTHKVCNmhqkwZS1N02CMZjFfcHR4xOXLl7ly5Qrf8z1fyY/+6JIXXpjyc+/353e0b/z6H+LX/Zp/kK0VLvN9P/gIL728/3M8x5s5FNvTPaw55t//Y7/+vkeNiSMzyej7jfIBXn5lj2efu8zR0RvbLljjmUxWLObyHJUR8Eq8mNYDa/Gn0iMjMhXvyGw/Agk3eA4PD1kuVjz06MN03cDuzh6rbpWZrYi/UsHWNsEwrVDaYmyDsTVQ0/VzfFJEVcR+2TRAMUqyvU9sqgilmUPu840B96ZHmeyR66CM8fXv/e4zk2WT7VYGA0oJEKTK7+fH+9CjtKZ3Aa39+D7LIHpz4B4zuziN/732AopDHIG0wspEr721ykC8VmLcL59LzoBSiqaqmEwnVFW2iilrS/6ZIkVVlHRGlYEb+UyTSiSvbd2ur7mNtSwmAZRC8IQs9UpZYroaHJcvHaC0oqrld7RTY4JpCB5FwppKrC4eIE0uAGHInzOh8W4QhpWyRPR4Pov3l63KUOL8M0ltKoBcVGtGqlaKSkPTZsDNGCFfpES/6kjGMHRLttttJhNJl4wqEpKkHQt+L0mcJTU1sE7idn3AuYEQkbraB3xM9IPULjrbEKASlVZE32cWfiQuNStn2Z61oKQGTDGz33IYTl9S63MHbozBeTfKLWOIdENP02sWy4597+ldEFVBSsShY6uKHOxMICX0RfDbWwzB00yEDZhiwmbvM6N1ZvwlSCqHzWRViBKZnneB116/RYrwueeuseqkTukH8fzdmrUYI8DZbGtC2zZsb82orWEybXj4oVOeeNyi8/6mgX4w3Lq9y7R1LDovda0deOyxWzz22G2+6UMCUNYqsFwanntpl7tHWzz5jiMuXzqibVtCUDz7/B4f/+TDPP/SAdeu73D37oz5osa5f9HAMkhJMww1t25d4tat88SJyg7sXzhjb++Uvd1T9nbO2N89ZWfnhJ3tY3Z3Tmia/o2eGRhLDyDXjzlESZLmZX2w2krAU7YSiUk6QIDpdMWv+ZZ/SgJ+y2/4Xu4eXmB//xgfNErm0gzDm/usX9JA2HqBWZ/asuBwrphGiigCaE3aJIJklH81yOJbmBdVbhBQSqZ5MbIcRBvuYtGbI7G4gLIGk0GLEfjJBpMJmQ6P09QyRt6YchbTzJLIKJ8pjRuh+B8kXBDmmlEqI+E6G2Eb+W9kwR5MAm2wVcopR2mchr3hkZv8ArJZY0eplbWWrdkW21vb7OzsiT9XSgTvuX1ywu2bN7l75xbz+Rznh3FRVsqQtMFFAS4VEZ0ExDLasLvdMp027Oy0YBSL1SpLnHw2UpTJjHgc5ElwBO8VP/APvoa/8b2/jH8el/F7332D//d//k9QasWN64f8sx+7y61bx3gXmUxbHn74Mpcv7HH5YJ+tWUPbVLmhU9i8Mfvg6IYgwF6Evjf8P//Tb+QnP/Ikb3UxfOShU37v7/g0v+pXvIj3Z3zm2Zv8te99ip/86W/l5PTtsb+uXv2nPP7En2RnNqDihLt3t9jd20ElMCRC9BwfH58r/KQhrjB1K/+uICSPUhLucOvukhQdL7x0k1t35lS1JSZYLntWg5PmOU97UsxpIFm6ppCCbWzN1YOv6oTcuyEJFvJzH4qQ/LlC8Z6H870Mq5VM81YrR2H8QC7EMhsKkIl10uPtPr7PBFVTUVeGwUViBviMFuN7oxjT0IzRTNoKlxNSqsZQ2SRGptZirMgpqyyniAFhyuWGsm4kDSuMjba8z6qR9cBaGHIxazPNf7xWTU7YDBCS+Fd1nRSR7aSinbRUtUhTVosV3SpPpZuKqhJZat1UIi9ypSFQVJXCKQNBYSvN4L2wcp3DxcAwCMg1OEmEIYGP4IaYJQNZYpWn2Fpp/NJz+fIUbyuqyjCdNLSTGmUSMXp0LsT7IRC8y+snuYhaAwvLweMGT/RW5KdWj9e1sUb89xM5Qatgm5tFTMp+YAqyd8LmJSXMOSXy2ATzM2E91pM6e6NlWZXR1LWhaSuqXCD7AkdoMuCkZKqtRFIqQKiwmkMfWJz2dMshA3AyeTNGmD5Wyf29PZsQXKBbipw1KgGnmtYw3TLM5wLyQUnqNHI+jRolLcIiFKlGcZertGFiqyz5E2ZUIqF0Zi0nCEpYdlYVtuT6Tg7e5T1Y52GPNL4mN4UFANs0cJdPVKTSKYdMrBvJEGSIUhhRIyCENIkORaWEVi+SpMKcKv5kSnxQdI3GEpJIOxP5OkqQQjbfjkW2FKSRzsVKUoqgMjNKm5HJIutHHhIUhkJmJ1qtBMgO6zpBZCdrEHCTaVaYV+PSVRp+rcX6oLIjG8uFPLk1MjU3em3voEwFxhK1AWPl6gtRGGCAjlHCDLQ5B4SVmqbIMsUrLDeNSolFiVIMqcKnhDItExsl8XOs4yCZCp8iKka0imgtNVUBTaVQ1qjkgEBIipCUeNFYSTNMSomcMQRhUFTVKIcTb0F7Dlws58ulkO9lJYqDbLBtslwr5b3CJwW2Fsm8DzSmoXfCVAkF8NMyDNjb3WVvd5fPfu5z/O2//b/y/pc+wNWrV/jhH/ohvus79/m+v/tv8fzzXzh5q2k6+l4kPO9998f4lV//99G+R0XxDfrBv//UG/7uWz3+17/zbn7bb/pJJq1j1Z23ZNiaOQbvxDi7bjL74fzPfM8f/hH+0Q/fzzbYPB7//5P359GWZXl9H/jZ0znnDu+9mDIyMiuzpswqamI2FCAh5klQAgEGqTXYkuyFu5fsFkhtSY2MGws0LZumZUksIak1YVADLSTLCONGtiRQUYKaixooasyqHGN40x3OOXvqP357n3tfRGRVFiWjxfJhBRGV775zz7j3b39/3+FFz2CLl8tisZjSP1PMmEZPrFLx20RkjROILVwsQ4SU2W57bt28xcHRISFGXvryx2XRf3zMer3C+4jOagewlU0Y06CUw9oGYyyNc0UeGad5M8pqrDRGihF/yqBEYi4NbwFr9V4o0D4wrFBTcvv03quMRkDrujyogFP9vfq3NYb5TDFqWJcm++BFyidztkanhDXyPbos5u9hnVHB7d2m2PlX7T4BxX0CivKlKlFqLRbiXhBFuSezrkVbizXChhz9KM2ivPugANM7iXRdANekQmGC6WLwv7sGwhRPYoydLREr67RhO1nX1KJLKbBOEaNYEKTQE7NcL7G8uJjmemEr6yyZUmQOqCx57z1ZZ+weezgEsSowZn/tKTPyfg1rjKadzbBG4Ug4a6WhUbwqgw/4mISN7BrarsVZOzHBYpafDSkRSoNEKSXWCeX+hQjHq17mMjRjEPniPmsspjiloWalOTqa0TjHtQda1kPPtvfcPjnH+8DhYk7r5lyZL1Dec9polM5TAI7WmtliznYYMKr4O6coDbwYuXV8ypUrh4x+4Pj2LWatk3o3wANHczK5eHUrDg8P8ClgjKUfBjQGaxpCSmSbClElslr3rLdbFrMZR8u5AH1R5pGm2Y1FwxgwRjy+b99ZYTRsVj13bp8yelEbxKxYzttiiyHPrbNMze3ee1FhIMzhg0XHvGtxznFwMKdxlquXDrh0OOfKtVs8/tihvCDaTMnzr3j8Nq98hbBnc3lGxd5n5OBgjgY+9vQRv/Sml/K2t7+Ij37sCufnM/Kn5CH5v//mQ8Nzz13lueeeP3zOuZGjg3OuXDnl8uVTjo7OODw84fDglMOjMy4dnuKacQLJYwrT2LPdtnz84y/jgSsr2i7QuJFnb17nX/7rL+PzPvttfM5nvZs8rTeFsX/18il5UvkIcBbz8x7ehe23ORD2QrcMSVo2SRumHmcZDLQWz50qCTKls56RycwqhcoaV3T3KVaja5FJVYPcmPNkEN1UuUlZlNSxX75SBkOfmGQLtVuJZkqy3J+3BDgqiH/1BSl/1/9eFyApF2PLUmArJd4IL3SrXil1gSFmjprr165z48EbnK/X+NFzcnLM8Z1jTk6O6fstJ6cn9P22yMa6XXomGo+kqGkFs84wc4ZZ07BczpnPZxws58ScGbdb/DgSYu3mQ4xQpULvfs+j/KOf/hI+/NGH+PeBnH/bG97Pn/jjb+HO8THP3er50Aef4smP38I2lvm849qVI65dPeTqlUMuHSyYN820cJOLm0uHJhGjUEjf9OYb/Nn/5iv51Nlfma/4Xc/yB77zPbzqsecA+MgTDT/6976MX3rT45+W9xesePkr/jxt96/LhAPRm8KygdmsExlk+fwYPXEI9P1I34+AMDhAwKCcwQeP94GYMute0nCevbXh+LyX71RGzIqr+eoEygqSkFMW42gt3XdlChvr7qNXE0ROrdZe2Hi4XwDWX6+yaJENV4vXWAA5ItNCetpLZmJ3iB+HgADTojtL4Sux8prTsy0HixYfPF1nCT4xb1t6PL32xRQ9oZBAiRgCrgI0JBaHc9qZkzTOLAvY85OBYStFmrFgjYKsCltFxjtrDGNIwi4zihQVxoC1CeOEoZOmhbkwemIAVKSxpcMcE7oUwSJx81hjMEYkctbq0q2v73Bh3VrDfD4jbAZML42LGKoJvBi6kind9rIIKYDo/uyWkipgFmgiV68umXUNwQfG0dOYRNdZWifvYT9EYtjQNJZtX0DMDE5bvA84Jeyj0XvyEOTZyQLAVWBf/Jg0KVn6so+wl36z83spY/9dT1SKmXGIqCJ77IdEO1PEkGkaw2LRFvNd+RO8sNWCT/TbyNBHfBQfPl0Ib3nauyYTy6JdYSqTKO2eUlXShMc+sFiK4a8Y1EviZYrSBRcQzk6ssW5mp+fTGEpqpbC+tBZ5plYa5xREaJItIGAsgKB44skxWEwzI/YrUhaDXGObvTEjMW7O8SGijME6WQhYrdB6Z5Rd/04V6S4XXMDzHcNqAmFy8dgqLDbpNO7uXY4RH/ZTKnfNK1U6aEmBj+IPk6kFLWw2K1IURhOVSVhM8euxaKNxJdVRmnBlnLCgs6SXatMRxrHw3Hcd0gp81aTbKh2UFDE3LbKn8ybjo2cMY6kTzMRIaV3LiCyKTAG4UIXxWhsLOZNLiIkiIdptio2DPHTGGJLfyqhYrnkFJ8XPS0IKKuNZCU0AlTzaGjqrSUaBCmQfGMahhBqU4B7bYFUuRa8iKTvJw1CGqKW9ppJC4UjRYMwMq0pSZMwkZVHW0DoBB2ypa1JK+DEx9MPUyGiahpQiMadigK5EFaCERRJikDFIaUKSd2bRObKyJK3w+gDbHjJG6ahnEXOUpDzNwcGSVz7+ON573v2e9/JLv/SLPPDAA3zgAx+gaRwve+n/meee+2HOz5/f3mEYdgyZ7/w9P0XrepRxKGvpZpY7x/LzRx99ho997Mbz7ueFbP/0Z1/B13/t+/iDv//X+Ft/93Mv/Oz0bDYxiowx92Wbz5aB1eoTh/B85qs+TDIt3eGVUm8qjEpgNBEj7HmY5qMUI7XFnMs7mKKEw3g/MgY/MX6M0zRKxo7GOXKOBORephLAMTFKTUvbtrimwWhFCDWR1pCzK3WEIWhHDIbNeE7vM838iJzAb9ZYEl1jpGk1ZoxWOGsIUeaxxmYZw0p6IsqAaQBVGr0itVSFfTv0I6mwaEYfS9NB9pkVjFGxjQLkHpiRHKVRX2uWnDU5D4Sgp7GjSoFT8R1MpSHgi+l1U4KqcgbXWHJW0giJAiyZMt6jNZiGbBtiqW2GwsYeoyZvAzplzEwRk2GMsOlDGXMEGLYachaGTXWPzXHAmHaSPOYJWtuBeRnEDsOaOtRKWnyS0BuxEQiiAKKM3yRS9OTsRXKLXGeteH4gDHaNiSTBQ6rKTSsTTO2A/9FnGmdIUU31a0bqrVTXcIArNi/bMaEah4qZhRJwMQSR9m5WK3QK8kw6h7V2kpvnnBjHAWKgMbLOm8zskwJlGHxgu9mgtYQDpTIPToQJpUhKjOe1ymgj9RRK0/eKeTcjJ/GEHX1gMwxo3TLELdpFjg4blILVJrDdCEmh77fSnFCDWD8oeZC0Ei/Z9WbLndt3aF3x93KWBy4fyEynLMppFIG2Mcy7udQEStOPic0oFhpT2nGKDDGJnYZPbPpyX2MibAeG8xWmbTg8WmK0ox8kIC6GhNWK2aymdAso2o+SBtqPozD/VS4NH6k/U+ilIYWwvcPGcKINXTcj+sv4FHnf+z9E4yyr1UCKW771DV9JCoq+F1sOlyPvev+HidmitcVaw3zW0HYNaMPBwZzr11e84RvexTd+9TtJOfOu936I9fqAjz3ZQX41Tz51nTvHD3Hn5GhK0fzqr3gnN2/OuXnrCut1xxgs42gJQVLNZfutXS9733DrzlVu3Xl+sOzo6IxrV4954Nptrl69xQNXn+Lq1Sf5m3/7P2e1Przv73zoI4/x0//02/mSL/olDg9PmC/WvOSRJ7l0eI5wdnchO2HfI/YTbL+tgbAIjDEKam60JJZpTVaJqEJZhpRBgyCDY0rk6tNhTZEOKJazBlUAJA0YpadEM6V0YT/J4NMW1FErxUI7mlRf+ChG21mM9GOSxYrbi2svEBfaGlwpYgFUUvjoLz6rBSlNMZKNBjRaW3nZFbROFpzKGPGsyFU2IYViXYQ6a8VY0Nhi/qxLmoe7YDQaYwalaawwwZx10qFKYq6bUuL45Jhbt2/T9z2b9YbtZsvZeoUPgRAjyloxns6afhSz0qQszjSYmWM2azlYzpkVOmrbyOInA5tefL+899JNRlhkyRv+t1/6TP7uj385vACz83+3W+Ylj97mv/0Lv8iVS2cc3znlve8948mPP80wejSWywdLHn3kOpevLDk4nLOYN3Sdw1kj6Vil6IhJ5Fw+Rk7PLf/VD3wJ73z3S/lUB6iu9XzLGz7Et3/b+7h+1eOHwP/2b27wEz/1Wt7zvmuf8v72z/Xg8M08/NI/xzDcYrUZuHPmaZ3laNESjaHvE6dnI+TbdK2la0SWp+2cTX/OajtwfGfDdivG5bVQBkniqQVBiCJ1XG+L30qKFC4HpekqVHotsjMpEGLxJKjd0ky1ga59SKU1Oe0N/Ll4MdVPlB/lPJG0dtdLVT+xXNGsnUxH6wJGybmkWBKRSLIwrN+oqrQg73V1s3yunF0WpI4YE31PYXHJQt05XYziE40zLObSBVutx0JBFyBy0Io2WqzTGGcxztB0jraVhKLzkwDEC+B+lBeKTJ66ltWnqW0NLmWck/CCGJMk9Wgj73YQE+ocM1QvuAr2pEQ369huNiLt1gZq8qyWsTOX9DhdDbSdxmkNrqQAFRZLKLJSrXX5nSwMu1SLWSY2iPi5Vf+txGwmsr/LlzpOT7cEP0IKNMYx71q0VqQ8YoziYOFYzgV49j6irUhVncnE1jGOgRgym60USbEAwM41k+F7LI0S7z05UbrA9QETEHWS2NZfQlFllkYlQAqVcUw0bWH+OkOVGgy9R5uE94ntVo7Je3nGrFaoYsmnCgtakdHKEis6pqHpHNoUFq5RaJuxBnLx4Arl3AqqA0reR9eKIW/barTuaBpL04ovnqImd8XyHIl/SVYZdJGZtbos7KQpFEOAqckj85S8J4kUfAGd6oJkx6ZOUWSOYnmgcOb554BJylNN9AtIlXJC5d17Xk+10LQKWCbHl9Qew0pVFsfeQqmMHbW+qFuMgW1f7A3szuw6Vllgzphs0Ka20GXfsiDN039DG0zTosKAmpgNdXypC9kioYwiC65eWbKLnRF9P/biFZQ0qQKI1PdHFryV3VGZNzHIuOfKe6kyUDx46ufqRdAoqv9HHfPIu/uQy/5i6YgLAJgLOApKZwzi7epDJgwSFJGR1D6HsD/rnCDnb1FlXKcs5J2SN0bDxPyMKROSdPprc7DaxEyigSyeUrEA8J1rCVNqSHl2YiSkyvyVd1dlaIyEBc06i04DMSpCdLi2K8daQLAigQIBjBaLOYeHhzjnWCwWvPKVr8Q1DW9585u5cuUK3/SNf5mf+Ef/b56/PJd9Xbl0h8XMo5Sw9ZTR9EPP4eFNTk6PeO1r38rHPva7n2cfn3y7dDRwctry0z/zOv7VL77knp+//gs+tsdo2pf27LaPfazhne966BN+z1d8ydvI2mIbS2PFkkOlsTRtNEzvY7UZ2X8jCvuFMtxZw+Url8pzpji5fQttLDH0gJext84j5AkMUsqBUZPXkTGGcRyIwRNGX+oCOZaMIekMukfrjEHGTGXFa1AXT8z6HGokPa/KjqH6mZU6p4wNOUuCs6kJe0rtfHsVIn9HFZN0Od+ZMxgrbFRd0yPL+7LvnVgbgnWeyClP41gFbDS5AGVM+4dc/LQKw7w0ZwTsV5Jeqyy5SL+NtagccNajUoAY6EcZR0Isa5kUQYk8VaapLOdH8csiE8OASrKeCuOGWENICnNYa41Rmq4Me+J15vDmEB9GUoz0/UjFt3JB+rUS5jQ5FwsZ2G5Haf4ZaVrGwtiyWpPzLi20hooZEk7JGKlyJhX2vZYTAApbsa7fUixej9KmkmsNVlEktwIqGiPzfg3+GbYbNJmulWTkqrJJKRLGgTD2ErImqQaEIOqS1XYkZcVm29MPg9TOhRk9va8IEEZ5T9ASSrHebiVYziQyFrLBakXbGJmvVWRMmawS3UwDjYQOGcNqPYhM2licNZNk2ZRQGKNVaVAGjLYCAqvM6JOAbEqOM5cGi1YQ/YhWitPTFbeOz6f51FmpQSuf+3y9YbPtWbgGpxSNbchas+177KUlxmRmVhhr3kcsgXnraNsO51oa69gOA+u+h37Nh+5EQkjy3BUWpCHjSphPpmjvNKRx5OT4lJAzm34sawBDTPBr7/+o1O0x0zaWnDxP37qDyrLGNkaz3bYcHR6gtOb28YrGdfS9Z7sduHTpiMGP+PQUxhxztHwfL36k49LRksPloniVK5pGFBhKaQ4W872m364BuO0VZ2dzTs4WPPn0FT74oRt89KMP8uzNI7xvPuEY/e9uyzgXSUnS5E9PDzk9PeSDH7p3fvlk2xvf9Dunf3/77/3HXHrtu3Z1Ua4e0veX7N+9/bYGwlDFA0zlXWFTaFHi3SIDWFKZbKTf4EdZ5GkFDTLhGW2Yta4YWwvjqzOORdOhtcbnjA8BqzRJiXRSK0VjLZ216LKwlW5NpfmVPkZdoKidd5IYJcvAKPIc6Wvl4nuli/9IKl2Gqn9GKWHXyMkLRd/szC5FJiZ+JOIdIpP6vG2Zty1d006+YFpZbEmZqZ1m6wxLN+foYMms68hJpFl37tyhH3pu3rwphqabDT74YmopHmshJrIy02Tlo5Qm1loWsxmz+YJ21jFfzulmM7l+jUQqe5/wPjAEMWWmdI4/9uQVfuivfjO37xz9Fj9YUgR/+7e+g2/+xl9m1mSC9/zar93i5tM3hTmhNJcOjnjooQc4PJhz9coBbauntEuQ7mXMldUmz8S/euMNvvfPfwVw/8LxE20veviMP/YH38nv+p1PoFXi5u2Gv/6jr+Rnf+7VrNbtp3G+W17+ih9mfvjz9OPA6fmGoR+FzpszWidCkgj5wUdY9/R9T8qJFz2wZKk03bxjtfFs+sC6j5ytBpGgVWYfVeMtRUltMMbih1BBlXpFcgERrLUsl434i2UpWlSFtQqgNvTi/aEKSpLSDt7SmgnwkY4cE+Nsuvq6+laUArAsoHOCyY2WvPMVKSwbWRxqcgpTYV7BtWnBSQHHyAUQy4gZuFyMcSgSsyAphjHIgfnCNDjQGh8SJ2aLMDwEUFLaMYzFIB2D95l2ZrHOEUNiftDQLcQ0umnE6ysN4JSYuCsjxbCzwiyzVksqXY6MYy3A5Y80QxNZSUiIjDuW0QeG7ShNCCWSq9zWLrTGj3mShMQgwKE2kubrnMGozGxh2W4t/dpIzHhhhoE0HnLMF8DMXUFfr6vIU8iZpnV4HyZZWTtraKw0HSI7KaO1BnKimzciv/HSaVRG/Kiqsfo4BnLMkixpNCGIH4nSEdfCTBusbQjRTffPOsvQB2KIDFvx4ZCKXxWvrQI4lDkoA1obghcwxFjp5m7XY/GLFPnj6BPDIJWXLvfGWrm3KUsjiLr4VnUhVRK3ZobUpEkmqFQBmJ0VEDbnCaCsmyrvTdMoFktLCKCVnbybJomeqv9OuEaXwsuCSqgmo+JF/5oL7Ktci3PIKRDGcGFxFrMsekERvADTRIPJbpIE7gNAUGA0nQX0RU2yG1OeWzm33bsp6xUZnUTmFCcj7Rprrz7BMD0xPCvgVp73lNOEvk+shozIYkNCZ002eYfQVyUkxch7GkPyfb51990To2xvEwCvNOuKCW0sC7rqGaa1xhRgaf/3c6awo/I98rH9/e/LMqdrb/QFI27Z3+4Y63cJu4LpemktPksp+guFa0pSd+1LtYzRRRkp4GQGVMooKwtoQ8Rlj06V3SYJViFHckyFReJKnyNN7IIxjBNYcTd4GqN4MU0stxyKb41i3lkaJ3OAkB2NhCeFWJpfsTDI5I56Hzg5PePk5ISr167yJb/jd/LoI49wdn7O9evX+Zqv/Voee+wxHnv8n/ODP/h15Hz/ef2xl36Y7/imf0LjSliG0oyj5+btE7S6CTzOEx998HmfnRey/Yff/gH+1t95LT//C48R473Pwp/8njcybg3G1Fmv/r3b/u/f980Mw/MvsmZtz/VrK4Yoz1JjFD5ZcvbUcj5Xf90ozMIYBJzdD5iS113RtA1XrlyRZPKcWK/PMVoTgp88+0DmcF3GSaCMqTuZsTWGYRwYx4G+35IKs1sGjIhRkVljpP5XIj1PTlEbtdZcvA62jjmqgu5x8h6MWeaw6qeplJGgr0xJghUWWL28CohZ4bOAvi7HYiOiL4RRCb4iIRESHCE7yHvFTgXGoDZymH6mlZrULwowVuawHYicZEzWQWqaLACRTiPORBmL00i/jRI2EwYsAQp4qFOaiABTc6GulYoXsgJS9OWYTPmjMFma/F21EjCKrAwNllElvJbasNrAKpikh3oaczMpZMIYyDGR9pQ9ylmilrFjerJVCUWrgDsyd1YWu2scRqndK6BkvEdJYIgqxWWIkZjFXseVABZjXfFmtfTbgXEY0Bq6rqNt27L/FqMNQ7+Vpg1MvpnCFhP+W/CBMSbWm82FZ/Beyw9hrEphG/BRoXOixRJjYrP1xSPUYM0MyZ6rz0xGW007b9A2k/LAejOQieRsaGxLxhc7DmEFt86WkKuMMhbXtjRNg8+aZ2+vuHGtI8QSDuU0bWNEXZIS6/WW45NztoOEYBwtZxwdzif5Y86ZcfQsXUPTOAHv2hn9ak3ajmiTMAmyLg03lUghkLUv6+qETUH+aLjUWLZ5JGnFpg8SihI8ymjms1amLy2hPiFn/DCSlaJzFuWE3JHI/MZHn5EGt7U4a4kpiBogemYx4RongFtUYoliHXduP4UPgX47cHh0yNn5SggEKXLrzh3GsOB8veLgYMl8PhfMwGhmXSv37XBZak0lBIMsMtGYIgcHGy5fPubxlz/Fl//OdxdVgWK76XjqqSs8/cxlnnrmMs88d8hztw559rkjhvGTgWSyRpR11/1rhq4d8cEQo8H7e2GnxnlG//yKqNms54/84Z/lta9+grPzjne/+2V89IkbnJ8vOFvNeeRFA4vlQoLVivdgSknCIF7A9tsaCBNPHOm6GaNJ97+G0t3UThbASdorPgVQ4vnirJsMZGt6jNFimKq0FjlYMXm1ZgeCtXuSt2q2mykx7LWjvPeZfTAs5WLYG8VryAdfvAWmJvWFIndf3gGUTvFun7WDobXFGDcxwbqmERDMNcIAazoxiGQ3AVrXMpt1zGYt865l3nXknFltNhyfnHC+WhHGkfVqJd3dGGXBWoAIX5DXcRzQRmFtS9M42q5jsTxgsRSjR+OcSK4AP470257gIykIyi+gpuIjH73B/+MHf/+/8+flk2+Za9cCP/TfvQvNOzm9/Sx3ntuwOV+xOl8JPTzDg9evcePGA1y9doWDZVfM7yM5x8nINabCVEmw3mi+67u/io987AafKvgFiS/5wmf4rj/6dl7yyG1CTLz9HTf4H37qM3n7ux4i5091fxe313zWNxPSTTb9wPaOSGmCDzsj+gLWjiEx+kg/eraDOBCGnGUyCoq4HRh9ZPDS4amfD4UpKH4eBcRVmpgN1ah6f6tFR84RaxSLhePS5Y7lUkDrofdkxItBANTIdjPivSxmvd95cdRHvDJWdDHLViSiyhBz6capHchFSU4Sbg1QFnMVwUM6vKZ20hRlAb/fo94V5rvbLc+CgGyluKqd3QzRpGI0Kh+KqrBcde3A5tJpioQYaZIrybPi35GDyGxjEK+vo6vt5F+iiudT12hM67CtZhwimzOJ717MGxKIBK9PAnpYYawpjPhjBPGkMFqRY2KzGsXHog/C6EqZ2bzBubawtxLDEGGo105M1pti/K+tFJ3OCqt1tmiJEcYhkqwWg+s9ifgEglFByiyG2VE8LsQMXbqqYxDZYds42laMxGuikh8DuTLulCGqLIAEsrgexwLY6SIz1dA4gzFuYoPIxL8zk7fOkpIALNZZYoj0W8+tZ08Zx4iuQOp+wyYnkZtmCrNNrrdx9ZmT98S1jhTiBDYZLWw6YY4psk4T6JFzFg/MAhyIUbDdPXex+CshIKI21ddLWI9d14CWxB0BliPzA5EF9ZuE98KO2W7H6R60bcM4RowN+BBxZT6S1GZ5jynNnWwKsIksDnIOglbsgUBQFr7Fg4cC3qgcSCESsiEohXNuUpJLemEFR1KR8wn4qLSdxoAK7ExJtoUZUdNhwRLTDgiShvmuiXVhnKpzeulJT55eiB8OafcZGfKkrsgpE71IV2tNcfc+UzFd+UTc5wrWiul/xAe/W6Tc9bnJc64kY1pT0xID1loB/4q7sdHiD5hLDaT3x7C9S1BByP39V2lmPY76M6ONpNXugYUVDFbleRaww1849pjSngq6LMLrfcs7LyO9P8ySJfO3DsI6k1RA5RpYUaRFxWS7HgtIvRViuDBFZwogi4CX9XPVyFepXeEfk4DsKUVUDPgQdkBeWTT3o+f27TucnJ5x/cEbPPbYY7ztrW/lyY9/nM/93M/j8z//83nuuef4oi9a8EM/9JN893f/PuCi7xbA9as3efjhm4BGfCgV/TByfr7l4099Zjn4e8NgPpXtDd/4UX71zdd4+zvuB6gJqzSWZPZfeuOj3K+2+c7/8O38gx/7Qu4HkgG85jOekEThnKUJkWXOySkKCF3GreA9wY/EIMw8XRlCe5tC2D7VHF4YfOLrtF87T76CSk/3VH6vyhUFsIwhlgTKHjDF6D1C8mgijZV3SimF94nhE1xuWVbIXFiB1Rr2UMeOpBRKOXQqTFlVxgSt0bnUH0oE0wU1ksmf4qOlxCh9YrOW8UEXj62Ud2PfhQO7B3BXpZmiyhqpvst3m8CLYiNnkQurJAt8uT51nRLIITF6hcseO5m1Sk2QEveMW/dPPC31XO0alOuhtcjlk8oSfpJGtE7otOPrKqWwBRSUr6lju1gTyC7rHFDANxVkn7FcX13Wcs6QiiRavEIF7M5kbN4tp6fGT85T46HONygBQStAbrQk7ForYFkMgXEYhJ3YNDLXweQxFnImoUkFjst75AdVWIf33Of7bLkCYcXrMCWpa5QS+WE1p7euRaUOlTJT1lt5dlzjCpg5VK4GZIRl5RrunJ7KuKhlDPQx0Y+eAxTz5YLlYokiMyYPymBMLN5gisWiwxjNatXTtQ1d49j24qfqvWco65DGOdryswcfuMSsa+g3PUZrWmvRPqFCQqsMZ6eS9GkVKmn6YeA0KUISu5XGaXTKHFnNYTZsBxlzkpcAJasNi24uTUSlGGJk430JVBBLiVQUIz74yS88hkxqNTlBP0bC1uOHTNNGGteQUk8/BhaLObdu3Sn1eOBstZ7eD+c0s9lMxkktDPTgPUqL7+352Yp+O3CzaZj8b2NkGD2LxYwQAs5Zuq6jaaSZaI1h3rUsZz0vfnTFS1/8sfp2TvXYajPjuZuH3D4+5PbtQ27fOZB/31ly684hm017Xxuez3jl0zxwbcVHPnqV/+L/8vNcuXrMzZuHfPSJ63z8ySs8+eQVnnzqKjdvHTJ6ecZf8fjTfNHr38crXv4M16+f07VBrmn1tcuOa1cjX/alH0DxwcL8lbE+xoWkiaa6LkoXwf1PsP22BsKqj5UUw/IGpr0xvWp7qb2FzFSoxZiJw4AOmuSyGKgqQdW1Ek8HMepOE6uldhWMkchaXQrHEAMppMkfo6Yr7k8vuSyGasc1F2PsahDnQ5mosxgI16OWNJkd4CXdoZL0lXJhvUgCoTUWaxqcbWiso20aWudoTE25EgmCMSWhyWiatqMrfk+i4x555uyE9XrNZrPhbLVivd4KbTrtzmVMRcaWs9DH44hSka6bcXi45PDyJRbLQ9p2RtO2VAmIHz3D2JNK6k8FbEdv+bl/8Xn89D/Z0R1/67bMV33Vs/yZP/M+1ue3+eiHP8TJ7ZuM2zVx9AQv3gUvf/mLuXL5EteuXWKx7CQhrEys4juT8UEo4DFl/vn/8nL+2//+d/B8KPkn2uazke/81t/gO7/tfTRtz8mJ4cd+8jX8f//H13B8Mvu0zvbylZ/nxou+j3XvuXXsp8475R5VUGc3mcPgA8dnG0KZCTMZZQ23znqU3QoFWyU2fWCz9QxDYKjS2LRzSsrFMHu3bNz9S14RKUg0mW7WsFg2LBYNi0WLc4bloiWmxHYTWI+BJsF82bHdBlKKbNcD2sSp06nVzijbGIUfxfNGJ/DsAS0TyKL22GB6Kl5lYV1ZAkWSrKS4nOhmVJBEX+gi1pMTKVNhCAbpqClXFo1JxpKYUvEDCWTV4mP5N6VjOwozr+JyWRf/DiVJlm3b0HaSeON9JviSxuLAOQ2txjqNazT9WjrJs1lDSplNFPAgFSk0KIy2pSsrbLQ6rm1WUvg4JwmoWmtGE+nmGmsLeScJiyl4kUQa22CdxjYVkIBxFNPtdubwXhJ/ROJ6YXW7e0bKeceYyURSOSZni+TbWWFbGVkg13E3FRCs70f67Sj3LhYZeRbKvkIV+aYWZh4iK22cZTZvUFozjgFWShZmUQAl1zhc4+RZiYkrVxYMvWfoR0mYrM94eQaq3D4jc5g2AqdMzwwCZtbrGlIoaVcJq1JhOUmKcfCBRSteXShVksjyFDQCAqia0i1WSJpl2DdqRjzims7inCZlzzgMtK2jaTXqsEHrwHadWK0Cp2drVBL/GGctsXhWrdcDB0vpSlorDLVEkBSr6UWDilDv5mbZLjDHYrlOOU8FWbmAE2snRTGmrt32KkVMxcBdwBKKlKgA17nIhpTIl2Q9JvsLUV2QF1XQCLVjD+2DPNMIVheze89r9eLZH0fr/Z+YeaiSklTOf2JXpelapX0dmOLC91b5Y11Uy2LKXgTtFGI+rvR0fStwaLTIS0LQBMSOQNihrgCxOymXuutlrNf5bqPp+u/9v21pflX2lUi3iueZqsB2LLJapvONsSx6qYtlTV0KK/YATX1X2AB7zLziM4oqDI4U8cO2gCNpaiTZwhwc4zgl4E3nnfdA2r250ZRasW4hgW2FTWHyLiCA6bkWgGW93ZJS4tLREavVip/7uX/OwcEhX/M1X8sHPvABfuonf5IvfP3r+cIv/EK+4At+iF/91f+SuwfDp569IUCvnDQZWZxvt4YQlgD48MIWAfffMk0b+P2/79eeBwhjOqa/9iNfxpt+5eX3/NSYyCsev/0Jv+UbvuKtaAXWuQnYUhFU9IW1XEEYI1525VlRWosJ9x4ADewApD1z9Zp4WJ/7avlRm9GqNLac3SWUBe8ZxrHU2BIOISEcYjmAAmVkzGmc1OPeJ+5vSZOn2xdzlGZjAWHvPvb6jlTDeKAAHhWclyTV2tATeV6VDe6A7/2/qxfitC7KF45MGnITzqYuqFiUkZ/VZs3dY4tSWYCvVMDmAu5VTzytJek6ZkjBFGboRUC8ApN1/7q853tfMs0bShV7ihzJCSKF5Wf0dJ2U7ByyXC9bw1kKkLYHucn4oy9ek9qoyjkLA7HUr41zuJqyGOqaswBohRlmjL4whsn+ds9iNdGofwsLUGSP1hhikPXmOI7kJNYLArR6Vuu11KRZ5N4hyjNgy3NbG72ynnwBTBhVfPaysHm0lubL4AONK00+63CuQ0VD8oqQMkoFkQRmeS9CBD96nDOAqI2MqonhawF8EWMQCYCS69l1LZevXJLAudST8rCbb5SiaQWsiREuX1qy6UdShrYZgEQ/jBPQaIr/3SMPP4AxYlcxbHpcvl4klgEVR6z3mAxEAcEHDENQ9F6aLpfnDqug1TB3LeeDB2sIqSOmROMaFkrTNq3MKcPAmBEgrbyDOUpQCimiy/xtUsY0DZlMU5ryOkYYpO7p9AxtDcMwcOXqESGKSsqP0qzOZT3Uto3Uh1rSc2PyOOtoGsOw7ek3G3w/0A+e9bYnpsh6sy1zZGC+XGKd1KvGWuZdx5WjAy4dLFFK/OlilICQw+VS2HnWcnj4HFevWtLL08SeNSXldLNZ8Mxz1/j4U9d54mMP8M53v5iz8zmvefVH+PqvfXOpnTL9NnF0MPDZn3WLz/lsVd5nRYwNt567zGw28uD18yJzptgtJSjjs7F7YX8VT0HYfPVdqh6zKCPjUHphzaDf1kBYyhRz31QSyixGqbIIqJ248tmUirSlSItqbyHJIJCTIZbujioFaD8W9klZzDtnS+qQfI8thcgYxh39n2oeXD0AykCpqmF47UCKkacsuu5NqlNKYbXBGUkug1xS23aJH6akPEnSk6Gxhq7tmLczuqYVg+gSm1wlCH2MLJ2lbVoW8xlt15FyJIaRk7Mz+o2AGsPQM4wjIQRB84vfBshg6GMounXIOnMwn7M8lFTJefnjGkkxSikxDAPej4RxpO97tGrQyvDe9z/CX/ihb+O33vsLIPL6L3w7X/UVv8isu8Uv/UtP9AE/9Pi+Z9Y2PPTgda5evczyoOPK5UNms1bMv9XegiwlfIj4EPmNDx7yPX/uyzk9u/SbOqIHrm35z/7Ye/iK3/lBYhp5969f4Sd+8gv51be+iJQ+dUBtf3v1Z/4hIu/n7GzDszf9znycIuXZW3HV90B+JkBtLMVFLMk5fhv42LPH3LxzDjnRWMV2O9D3nnEMUxFRH21hO1ZPr1Sx6fJDKSZSikIJnznm8wZXfIdiSrhCi9e6MIpGWSa5xtIkWURlrcHFkrYoniPWGGHxlwVYjFJso7UMtFNBWr13Ll63WgxrUwtM8dIiw+hLipACpcRvpGkbtC0yofJ8BB+nBfa035BQVsxTcxY6OAgraRi8RIOHiA+hdDALMNO0pWoVkv52OwICCiwP5iJxrF5l5dIGL5LvDLSdwWVhA4k3mywyJfEqT4CcTlK0CAini1dTImgBTJUWSSdZkzUwkyK67aTNOgw7ZqGA9QptpAsbQyr+h2CdYSgyXCnAd0lOOcXpfihVFwu1zi3FpNECyhjN0Hu6VgsYqOrxVc8AAcPGMaCMeCKaQvdPMTGWQitniEmuSU7CZmqsQxl2ButZkpDqPaNcI13OdTZvOLo0Y7seWZ8L2FzBkQra1EWH1hpK8iARlJXId1NMcH0pjmXhI9dP2eJ7pB3aSfffGs1qtSmKlVQ8HyUAQRuZT8hgTIJR2CkxyvtjrEZbcK2EJqxXnrFXpckEjdME8XOleiU5DEaD1hmlE2H0hNAJ4yEogkl01hEZ8XGkUW4CBJ5vq1LHnCVFLT5PITMxpEuhBhTWR5zYoiFJh1YVAKrgaNPrvg/g5JzJOotksTxXRpmpqVWloBXA2e/4E5g+BztgTZ7ZPRBM5d2iqByTYsc2m9Kmy5wdUxJvurovrXbyvCTjUSr+Y0opTFMWzntSTAGA9s4TYTjtf78uTMYQQmEhuGkxvs9Iv8A2K/uu7I3nM5veBw7rnzpvTqAcXFj3Tr9b3vFpPC4NmAqk1f3nnAQcyMIKjrHMVXv3th5vinFiCQng3qJVAeHKPagS4R2rWMzNJ8BS6RJmYQrQRfHuEc+mupirnq3CpLnILlZKFT9FzdWrV3npy17O5cuX+cc/84958qmnWK9W5Jx59NFf4fjO/48PfPBrpovz+Z/1NobRTbchUZjFKePc4XTeH/zQ59z3nrywTb7rVa+6w+OP3+YDH7jX8Lhe5/uBYABv+IZ389xzy+f9BmMCr3vlEwJKmypxQuRsuTQpENaPcmpqjqQooHYSpPjCPlO+YCBWvsdgMDvQq4Ql7L/PpngO5ZwwWrFYzjl/ZoU1hsZYIl68vIhiLF79/yIEJWw2U97H3VYYwDqXJpoCLfOVVXYHlO4f/x4QprWZvgNEor3zGAPZWVGh5N17WAEwOYLazKeAKPtgrgC8FSRLobwnd73LFxqF0/9jWldMzcy9wmlqvmiFQRFtYhMbyEkSPmH3HmcujKlKK5Qxu0bJNO5k9m+uADFSjxI1hYJc9p0gSbNRI4FdVUWT631Rcj+KvfO0WSs2CZVRHaMk11sjsspKkNBKGIxV2VCVD2KJKWOwpIAKY1hk1Wl65lC5yCLtjtGllLDvi0/y9CTlTBgHUBJCVU5PbHmUoWlb2uITpe9q1NxvE3/PApyJzpicmZ4dY8QjW2k32XjUBqTyCe1kXg0h0m9EzTRrG2yxyDDaMYwjbdPiK+Cp9MR2jiHg+x6rFEeHR4TRYUIgeLEwiKXp5JxltmiZrTsOFnNIMIyW7bZn9L6wwwIZzdHhgiuXD6Y5gSsHxBtX8JsNcRwZ12vS2ErDcWIba66UGTLEzNJqOrMLhJh3jkvDwNiPeO9LUIJCpwzOEq1jMJGQMlmLLU5rNWdjTwpBojuz3Ge0NJaalFi0FouoSxqtmGlJkU+NK15v4lvph0iImbYzdLMWaw1+DKKMSWAbAUCDl+erLUE8SkE/jFjb4lzLanVKzNC0jazlxxEDtNYwb1s0irPVhlunNwk+su23XD66xHrT01qHayzL2ZxhDGXsE2sO55wk088+ymOPKx5/HL7yK8WeRunMs88aCSIsIKEA4zUhVcYdZ0de9NAgjP2pMVWYzggRyBmHs3ZqIKcUCV7URnVNlfMORVBa1iSb/yNII8cgnTfvPdoYZl2LMYZ+GNhsBtabHh9qISILgxg8jbMcLDsS4pclyRR14pA/PqaCRspWFxoqJSw1Il4VL4JamJUFPkWuoRUaK3InqrzJk8uoG2O+Z8CqKY2m+Ls0TnxilMmEFBmGMFH+jLFTlHdjHY1rWHYzFvMFs2a26xiHgNKK5fKAWTebjPBTivT9hlu3brHerDk7OSPGKAOZNSJXKH+CL2l+WhGL14JzjsXBgoNLR7Rtw2y2wDXdNLEFL9TNcShJUAAoTk8f4Id/5Jv5yBOfnofFb27LXH/ghG/63b/Al7z+SfrNMeuzLXdun7DdjrTO8aKHb3CwXHB0uODq1QNmc0tTCtyMPEch5GL8LhPEz/2LR/lLP/ylfKJF3ic6pld/xhn/6X/8bj7vsz/O2WnkJ3/m5fz0P30dt25/4sSlT7ZduvyvuPHi/4rtdsNzd7aM41jkg7KAzHcVF/V4Kig0LV60Ekp2DMV7Qc7z5HwjCV3ewx7L5O5NZLQIFauuhffp2ykgnp+ZxXLG5SsHNK3B6NI9zMJiqeED0rUXlpd4ZsFs1hJCZBwCSazqcK2Re2dETjVsPdttoN94WZimJIVArt31+xx8LgCWEU++rpNUKe9jeZeDAE9J3nvXWGbLRorYJB4U29VA9LGiObtdR5H4yfEZkYmkRAxemJi5TMpKiitJW2qAiNKWGDJjHIrfSGYcPP0A2oi3h7CKMmEUH7+ms1NHSVgwUlGlBGhNSlIA9P0orDVsSVpT+FIMeV8iwrUtRaqkIvkxkhdu52kIxfh3twhOMbPdiM9L8PI7fhDzTD9Wf0C5d8YWv7eUC+OpACS6yDZVKv4YApDOFy19PzCba5ZLMXEdhlhYcWmSF8aUMHsL8tqRrmOdDzD6jC7hIlqr4vsnBXCuoJaR4i4X9Mxp8SPzo8c6w3zRcnipI8ZMv43TuGiMgLu1WRLHJKTCmAkBSYGKgZQjwUf8ULw2EKaysgbXCNiYUi7dULnem20vXbAsLAptDTU9GGTeUDoXSbEkkrrGTMX7OCQx6C+suBhSYb9oWgdNo2k7g+8LSypHGiPsKpEgi0fYOAactqg2MqQ1NrrCutnNs9PLdtc7obRC57sXlXuvY5JOfWU47Y85ISRGn0pYTR07KruoAmFS+Ku73nWt9ASIwI5xrpUYzWuj7xnfUkoknSav0TpW3S3FqgsBbfc8cZ5nrJSLwB6AG6fntD5D+zLDCkrXpkw15q+Lr0ketce4k0O4KOmstUf9d30f9s9hOry9zn1lyt39swv/W1383/U92IFO+sLYW4g9dXiBcqzCzpf3EDLWCXiRCniYSQx+x1KTy5in6zGda5ETWdtAzvRjYfyxO5+7n60Kvu1Lkf0o8pe2a9E54azC6sy0rp6YOeX0CgMkRPFebduWb/mW30s3m3F8fIcPffBDvOpVr+Kxxx/j5s2brNdrvvzLf4qXv9zyy296PQ89eJPf+7t/ntaeQZbUt17NmTeZJgaefe5sOt6U7pVUvvCtMPFQfMPXf4D//q9dBMKUEk+ecfRcvrzi+PhewKsfFE8+VYG5e+ui13/u+7BW/KVIabr9SeznCzBQJXoanQ1a20nODHts0Wn30jSe7h95eu7r/02L/f0mhjW0M8ft4zXXr1+X99kYuqYlOGE/JxLoEtCTd4BIJtM2GusUPjDNYdIg2HuGi3TWGAmgGsfxAtgMOwajLFZTaXbJlpHvrN6d8n6UeWxqWia5dWXRqUribEqZXAJUchlDpIG+B05XeWC+93ZNx7g/ZN19S1UNTWkmaWr9PavBGXHcknc7T03Ceg0qQFnZbHfZDZZ7qKmWCdO6q6JzubLA8wTmCPtWFuMYuR91IU+5jxUclGGrhNXsjW91PHNWGpHVAF7uVz0cVYCiVJSbIpm0tt44Chlir0lBZbE7mpIKmQHv/bReSjFNymgBTTPKyH3U2qAKk66y4bu2wdp+Ytg936a1MOjEw2w3G8csdhViIyA1tg8j1iRUbMgMhBxwKOaLhuQNw6qnsbJmbXSDRuNjxBpYzFo2PhVftFw81eT8bDHED76nteIrqyn+jeM4PWRiN5HKNRgJcQS1U15UoknXtcJ00oocgyTMN5pZs5Rz8weEQVJYw+jxY2CGvJOqgMRdY2mtQaWMswa2njGI8uD45JTV+UbAG5DaqrDhFy4LAaZ4cObzcwYfZE2UZN2cU4QSwHc4X7Bo20KaMdIQ14pNiIybAU1maRS9zpwNAaMcYYyMvRy3KCeksTMO0qhLQeqQOt9ZDYlI02hmM0tIlhQDzgpDnKzEdiMEaBoa5/Bj5tqVA05PM08/+zSL+Zxb62Maazk5N2w3I9vtQIhigWSdE8C+vI8xBDbbHrJiNu+4crggZsXhwUzqKGA5n7GYSXjVdhAv6vms5ehgPlkzHC1nUn8rec61LkNoFCCOFFA5YJTYcJS3uYwLClTAWEtvX9h6/Lc1EOaDp2KAIaTJqDVGYVTcfO6UJ587I6F58UOX6PuenDJXrxzwyPWOs80oE2xteZQBMVVkce8aphSpUeIpgrZWJAkxFpp1njwnUspkq1FaCn/rdhNzpbmGEMSoMYepe2mMpmtcMcu/SHHWIgfH+ygx8kbQWGcdbSNG+G0juuyu7XBWFh5tK5HQ3ayj6zq6piOEyNNPP8X5+Tnn52ecn5+jy8C5XCyxRs7Nh1AkPp5xCNjGMj+c02jN4aVDDg6PWBwc0HVzrBOWSgiR4MvLWmKsxRQZbt+5zPf9he/k9GzXtfyt2xLf8rt/gz/8B97FYnbCRz76JHl0vOed7ydnePEjj/Lw9RkvevgGl48OmM8bSUszCZS4v3kfKYxXQoTbJ5b//E9/OR9/+jq/GQBM68Tv+h1P8l1/9Nd4+KFznvjYnD/333wRv/Sm+/ttvLAtA2e87BU/CO5fs96MPHtbfJT63tcqCClF7geClb0U2YAwdCCnSIoiP1TszOUBfEro9PwgmLAS6it2V0GVklxQlZjP5zgn3a4YhWmkisZ7LECOLjJhoxtaJwDIUGjZmUwcpaCuCy1jDE3rsE4TfcIPoXSw6k2gdKCZCsYU98+j2vzLOeuyaA+hgBBO0gPzKAtrVfy8bDGgB/BOE30UWd3kNVa/v5ida2HTGWunxLs7tze0jcZZLQby1VycRNu2pVOZyEV6No6BzXoElXDdztxXFwlHTmCdTLi+F1AklOhoPxRbWC2+EW3TCvU6VkNbDRSPrFQ64SEV83Rdjt8zX4oBfWVDTJBHFlZa9F6611mANJNh9PJcifeiZjuIwXQCtN15m+RYikgl746zDtdotLG4VoC0GAaGXrqi1mi8TmWCjhObVrqdstCvTAHjDNZakSTkTIhgsoSFCMNIUk2jj9Mr1DpXgMFA21kWy/nkNRJTomkds0VH30diHPFDlILVOvG3NNAUM+TRS+G3Ot3QdY7RZ0gjxmrCGEnBFLlJ9aopchW5ZeXdCngvEueQIq3SOCQgQumMtRnnDP2Q6beheKFZxiHi+oAi41rNOCZmM0MMVZpfO6SGRYYrcc76vCdHcFbATucEnMtEuR6tA20Yg8KqTEAYs9OoliqjG7IqUmIli80qb6r3ui7MLoATCbIWMH+fVSHJsjsrgzqOymKrJHZWgH9vjJ0WVfvDrtqNC3U8qfuqv1OtEKbjBCRXbE/2U5h4ArjaaQF4P0ZEzrvFs1KWZMJk2l6/e0rGvIuxNYYRH6UxV5t0VSImfi9mx8C6z1ZBs7o/YKqpxENs9znMDiyrHVnxl3l+gE8pNfkJVhaOLswPbS2M9/213T1KSbxY2F2vlDIhe0yOYnZ5jVxzAAEAAElEQVSfFJvRi1y2vKd1yFVUKZIpoKIAIdY4QliTUqLRzQSYCOBykd03Se/2ABRJ3hY2sDWKFPw0xAv7s3qLyfOwXC4wSvH+97+fRx59lC/6oi/i2Wef5Z//7M8yn8/4zu/4Dg4ODviffvZn0UoYY6959Tv4ljf8Gipt8etzfO+JwZBJKB24dukQYz3Hx59e46xu85ksxLXWE/tsf7t6dUMs3lt/4o//c/7rP/8d93zG2cAzzxw873e85pUfYihNgJx7Gbu0Ycgt7fTSlw9X7EAJW4e8Y1Moap0iDOdUgiGqJDKWmgXk2RRVR/HJ3at/YszMl3PapqHvRVaU1U6aKyBcghz22FnCuEWJZ2MTcwlUqe/w7nxVkRpnJZJo66zIxmKiMh+VAmOaC+/ihW26DhIHJvLOPFk1xBDFJ0yrnVdalrmT8t1KCRu8WqzUuUQbRb4PgeICK7PekvscmzCoGmxpKu2z37XKWJ0ZopAODCNJ1fuTL4xjMs7eu39TZJo57QDqCdgsDOsUpa41JdgppkwOSfzXUjEpyWo6kakxUvYmnpllDNsDw5yzFGJUOZbCDksKUzzdKhhQwUY/JmIY8VMtaqnJ0hK+UJoUxtDOOgmj6gdiED/MylqsibtCTIjkWMayIvElS43atg3OmWlcvrvBdPFaGlJW5Fi9E+tfuSjzpQ7040hIXnyljCKrEcgY3YiVkLEcLRQOAW+rRdH5JjAGRds4fBJGfM5iM2GNIiWPH3vGoSe0Da2bo9qr6OE2bSvXpLQdSH1PDfRJCFNavBfl3vnNhjE6rl+7zOgDs5omqSqYvvPRdq142FbGvzYaVdhvRoEOHh2DrEsGDz7hDuZ4DcucGSPE4EWSnRPWGJbzGc5ZGmPYnK44O1vT5oajoyUxBXzwhOjZjoO86zFPibIVrI8+MJ6v2UZIg6clgNXMncGrxPp8ewG0rVsFxO6+z8ZoZp0VW43kxbNVSwprbQ4pEKbc0NN0LY0zXL98iYwwfQ8XCzKZw0XxRENqXmcNwxjo2lbUKdRDyOTsOJhbhu3AmAJPPP0cVy8fcvP2c8RUGIFJkr+rTLxpHZeOLjNfzBnHnra1NE1HYy1NI6BsYy2zTsbFedcWD3RTcBD5d8GxoQQKhhBLw+yTb7+tgTAzJY5kvB/pe9HPkzOzruHq1QPWfeSDT5xwcv4si05SCp1rOD7r8Qk6rThcHuK9+MbEsuCvaSF1y5ld16V0DkMIpeOwK3ZTjIUxkzAlOn5fNmCLMb81Rjq3UWRMylSwrAyyxajQ6AqECZti1spD0DhH13QXGF4Ap+enaK05ODjg8uFljg6Ppu7MZhj4yEc+yunpCcd3jhn9gA8jjWshwbybXyxuSwWpjWaxnLE8WnDl+lXmiwXLw8OScuLo+5HtuieGMJnpV3O7s/NL/PKvvIL/4ae+kJS636InY7pr3Lh+zn/xn72Zz/2sj3L7zm2efGrFx594ltOzFV3T8B983uczDiMvfcnDHC5mtK0tyXGlqxMTIcliOASR0f7M//Q4f/VvfxGlZ/0pH1XbBr79m3+D/+j3vRPXDPzim17Kd/+ZL+WZZ59fRvDJt8TB4Zt46JG/wGZ8io0HvxV3nqyKj5Q2gCkQmAJqGs/9J0wpoIo3RpVO5uqxkElKQQl4qH518pP9nQCqykTKf4ulIvHl+y3M5zOGfkSphuXBXIraupC0dtqH7z1kaOeG+bxhGAPjGFkshVKsrcJGDdZMCZ7D4NluJeXr4KgjA6tzT/IFbcm1yIC7rRUUFXAQQ+IYi+QvSerPGMZdh1MVqnmSwkQpkQDGIHHP83nDZjXcJT0QiUdWjtV6Q9e1xeAy4oziLCeUFqZBRtEPAxFo5y3z+Yxx7EWGGgPzWUe/Hem3gfmBxbU7JoJS0LRSYErtoyArtpuR0+OhMEBlcaqUoSbGKorx+A7CnJ6NEEUu7ZzIqTLQbwIZAQKFPZmm4rAmULWdpQq2uk6CPRSK0csCo+sMoxcvlyojlN+XZkfwkXGINI2Z2Ewxi1m7xhDGQL8di2RUFsvi5Sb3crFsMdaWcy1MmgKyhQTjWKUnwh7r+wGKb2NMGW0VhJ0hrfgcZEmx6mZk4iRXUxQAMNQFlexXvGjkOnkvz1IMAnKsV54kzURyDlP3U1vxbCnNbOnoW4UxGedg6BNN0xBSYuZknqlDlHVivK+1RQeNaRyrVY87tNy+tWGz9SwWDdceXLA4aDg4bGQu0iLh7TcBHwTcu/7gIcNRw+psyzh6tLa0naPtLF0nPhZtKwa2rc108QDnZzuvNKAmRoovj7zfMQdiHKdrqq2GuOvwV8ZSXfwYK4s8P/gdq0F6v6gKRBkthtaUZlYubBKliFlPQNQ+e6p+f0bkkndvFz5TQKcdBagUqqEs0pSwMqpkqTbdak0QQ5xkjqqMH2ZikRhstFOD7vm2KrmRxiBTV3r/mqikduendiN1Bf+MEUN7VC1o94rtsPMzUnrXoKvvjVJKDL7v87tKS7w7SqMMBcSVa6ZK4rWAuQJo58LGEmLLRdlYDVEQP5zi56TyVAfWZ8Q5WSBK6Ess10SBEoZk2zgZu31k8LI4qSy6felyBSrrf78gd927HeLpE1hvex7cYwVW4EbvkGqGYeDk9JTVesPJ8Qn/4O//A37ix3+cEAKnZ2d81md+JijFL/zCL/CWN7+FV77ylTx4/UHm87kERsQ8SezDEGQebwJZGWad4l3v+T0ALBY3Wa8feN5n5pNtV68OKBTOOobtvXXbZ77uGeZtg9OKh2/cf7Fx+/iQW7efv+Z76MYTrIdI48BZxWazktQ8LawMav9FFRlmjgW7rH6HCtIO0Jb7pDk7O548+2wxzxcP4MqeUdN7H2JgGAYA1psNV268eAKojLGcr44n9EMpDdqgchK2V6nXtRbDcqMUrg0w3l+OM/Xb865R1zTNBAwrpVHoe0oxxe6VlSR5AS/q/9Wt+hf3Qz8xlQVYV1MzS4BgYW4xgVDy+5ksrPxpWVX3vQOE5Vz3Wwi7LZc6KrJrFtSxIqkkJuWqjpeaWKhrWu3YSxXov59hvsha9cTWqizXOs/FXEDFSSpVwPxClhB7l8I4n86MnVTZiBTXj7mAVnr6TAXAqxVNrWuFISZ1wejD9L0hFOZqhoQkJTqnyFi0ygUE0yX1UdM0TkzPh4F+20/+dZUZpsr92rF0s8jzUOiyXmut5vKlBadbz9nWy3olp3vGZIDtmIklEmonM4fGGqkxspM6a+wZhh5rbTHGr9dV0bg5s/kcmzb4fiRO47UoCOqosJxZqbtmLaP38r6lFj8ObLYbZrOOlFpSGInRCnNK7aAJa0S27MeAVpYQMtt+EIsLpXHOYhsB2AQEA2UUWtmdV6Cq91vSRW3avYcy95YhXUttislk62DWQc6YEDm8eomzzcAT736CIYxceegBjh64wqzrODycs1gueHrd453hkUevsx682FGYJIBiDJzeOmEcRvL5mrPtQCp+WBnFqCxRO67kHgN4XerxqEimlbH+LgD6wn0tKa4qRWEmzw0axXoVKas4UuxBKYwRLIQYyN6TokcVUGnoRwkDs5YYA8M44EOgaUSeOF90hLiubwb14k7MyeLZ2qSMc5btdqBtO1IKNNbi2k5CekrDfNsP3D4+5fbxGX0/TiOaH4MEsylFvz7n8OAAUmQ2b9FkDpczZjMhAM3nHfNZS9e15Czef/N5x7Yf7hlH7rf9tgbCfAw05YVRqiaD1YFOaLSpDHwpwPlqxFrN6WrkuTsrHnrgAKfhYDHj6NINttuBzWaL9yPjuMX73UXcpSflaSCwxjF6T+PESJnkqbrrnBJJ1W7XrsCWAjiSTWLmDGCJWRDYGBPWSHfdFtmj0QW1RtE4GSzbphUArHqAIZPgYrHg0Rc9yuHhIbNuhlHiYXG+Oue5W7c4Pjnm5OSUYduXgdditRh3K5vY9ltZFCR5aWzjuPHwQxwcHtJ0Ha7raGYdfhwExY6ZfrsVw+uUpJMRA6enHW9++2fwP/+Lz+HpZ678Vj4SZUt8yze9nz/2B99Bzic8/cwtfuVXb/KhD30MtOalL3kxDz34IFeuHPLow9fFiN3oPalM6eokSUAcfOD2nZbv/t6v4omnrvGbAb8ADg5G/uB3vIvf+43v4+Ss4b/7a5/Pv3rjS+j7T0fCsOGRl/y/aOb/lL7fcnwe8T6VCViozhWIqEbZcp51YXPRJ2fvf1CBr1zRor3Ppcw0IcNdV6R8d/2p+CaBiokcgvzXCBiDNpByZBhH5otWDCNH8UcQHbkYO1bgOelEGIOY8SNFwnxuCUMWz4CQaDuJ+1VKi8Z+iJMUL06AZi2WmBaH91tsZjQYmci994WuXz6fSgdy4vBnlC3gQRKppHO2gNiJYWQ3kZXvTMXEdRh8KbASxjTiqxcTs06KAGU0M+c4uqTRRtHNWpSF+WJJjDO8jwz9yO07vSz0jGIcMsapwlIrnibB44eE01YkihG2mxHXOFk4RCnelvNZ8VmU8SsWNO3iM8KO6RVHAXN8KJ22HWtJehOyaCYlNqstrnHYxhF8EIar0yjtCiBVmwFlYm0MXWuLh0Bm7APr9YgPIuOTR1UzDh6VYa0St++cc3Ag0dKxSCIzmW7ZSvfcCPCXksibtqstfvSMochJKczi7ciwFWZWN2tYHs1YLKUoizFNQKdS4smw7JaltNyCzlMXm9KRNEaBSmRSSUTaSDEeE+vz4jHZWlKQDrhxYmKrNGgKe7L4u4nfHlilGIaRmBSDF1BouZgV+api3gnQ6IcMiEfadt0z9p47vUdbW8BcRfCyyLFW07SGlDLb0XP7dk+/DVy7ccDR5Tned8w6y9lpxGiYzx2zWcdyKZHmSkEOitVtg3YG29RxYvcM5SymviaJAavKEmmecpL5z0oDZx980cWD5O6tSvdqul8MJT2IVGQgO5nf7vEt43xd6CG+ZNO7suf/dL9tYp3EjDOSnrW/MFVaTT5e8sqrC+w1kSPtd+MvbmJam+47Lk3fMVU6e8224j/UmIbKfEsF2I5ESY+sqXrl+uwDYBX4qedQN2MM1tlJLlqve2OlUzsmCF68lMoJY1xb5Lzt7pwL26IC9PLRRNvOpVaLqdy/i9Kx/d9V2kwMNOfMxIbPOeNaNyX+VVmps/ZC2yrEwhysqW/lO4w2qCQ1XE31m54Ns5OOppTw0aOCjK3rTY8o31XZf5VaMknzvA/cvnOHJ554gsGPfPbnfA4heG7evMVqteLo6IjnnnuOv/KX/zI5Jx555MW87KUvo23F8iOHQPKRFHbPkFJKfF+U4cqlA27fviHHFz891v0rHj+Z/u3svc/f448dT9dssbw/le/B6+d89IlL9/2ZUolXPX6OUoUhZGqogpJrccVNnnr7xcX+syBNuZ28UcAMy8MPP1waHWIbMsnbindiDaCoDZYQA957sm6wtkFpS+ccz/Y3ISeUEZaWfLeY9Gsl3poisROQKSOpyskE4l4C6pRqm8uRptJQ0ZqmaS6cW4p58qtS5ZzkMHMZC1JZ0t59PYvnnDUwcGGsM9aUkkVYMjEWy4Gy1SZlziUVekLGdkBwRctySpMcb/9+VFBwPxCjSskroKxFAYu1DaZt8OMAwyg1ar1WWuwnnNWTJPCutT/U1Pu9B2OSRZW/Y5V57l+j+pm8A7cujHX79yGJr1Ed+30KMt5kJYoQceoHds9jKk1iHyLDIMzctjFUaW+uACzy3GmjcUZsbVyRk/bbnu1W1mF17PLeF+uGPF0jGQO1BJUNPTlDa+H6lSVbD+sxk5QtHr15AnvrpuuFAHaZGqr4eMFmvS3eopm2awnek1NHyoV9lzUqgnWKw+Wc6APrzZamFcudg0NDzNJQXG0C22FgOe9Y94FZ45h1rbBNtz3r1YoUxXuvtffe71QahMaIl1rjOhQ9KXkgCuPTaraD+B5XqZwy987bAj5qKdL3t5xLMA8FaJV7looK4kAbGq3ZHh6iXv4oz378GeLJmpg1+nBBTJlNH2iUZjmbs7mzIaVMd+UQ7xwPv+Ia4zhy6fSMsB0Z1hvGzZY0jCTvxb9cBbEdKhcgF1uVBmjR9KapC5bp3pES2Y8QvIxVKZLzrvkcc6YBOqVZZ1GOpLDFDgMz6zDZMK41bdvArIWURDFTiA0OGHNmtdmygCmB9uhoQUqKdHFpeKFJaIxiphWz1tIPgTFZZl2H1rp4TkvjwjrHwVLm1uW8kwav0YQQWW8GQohs5x2bfsRZxfn5lq5RPLvZTONcCIF+GGQMLuO9eFr/H8As3+iqDS2DWkxoFK21YshmDMfnPbM7a9ZrKc5CSKw3nmGIzDpBkYdhw/m56IS1VjjXlIepetaU1AKNGC5miepVxmKUE8ZBiVfNJc0kpwjalK5AQPzBCtMgeYwCVzpVIQWGcZwYBCCG1U3pbFotn2uaZipE6+Q+m804Ojzi6OiItpNiM8XEydkJq/WKzXrD6dkpm812AjDcrBNdsEDggHiqpCwLLtdYFrOOg8NDDg4vsVge4FxLzonj0xOS8IwIvid4eS9X6463vP1V/Kt//Rm8/4MP/Xt4GjLXrp3zX//pX+bVn/Esp6fnfPypE5544imeefomly5f5nM++3U8/KIbXL18wGJmaV3BI3SBbcqiPoRcOjzw4z/9OH/rx76AuyfeT3Ys+5+9/sCaP/qH3sGXf8mH+al/8ir+0Hf9Hp69ufwU9nfv5twtvuj1/zdunryX4/Mtm9OwA3eY1H5Qv0WlCQQTHxx1YZGTy/+rlFmpFna0WynEcjHgvniad09cssBUO6Ck7i/tHZUxRTqYC1U5cr7eSPx8TBwezOk6gx8jxkZm8war7ASopBAvTHQ5RcIYRf44Rqwz4pOVM5FYmGOyMCk4dvGnqemBNX0kc2Fkh7KABHQtRikeacL2kKSSXZE1jhGz9aVjWZhQpQMlXiQtKUs8MloGfICUAv2QiQmZmLJ0MFulaZtGzDTLPXadJYwBVTTwInUwjENg44dJFuUaQ9OI1DohnfecMovWsN162pnl8GjGZu3BQMgB7xW6LxRl46QLHYohdfWTyBlSJiHMMBDjeGHrIIwYVQEMSbcJwaNSmSx9oblrRVuqn3knXciYisQ6yzhotFDq551jGAJ9DvRDQBlQTkxqc0Q8xtBcvdoxjp6zszWLZYdptND4nXhSKAWr1YjKMI5ikj8OIxufpzkl9FV/UJ+vXAprhVEOrCbFkabRDEkKGV2eoaAiIQmbTFtD02paL93fCr6J5LyCsLvwALmCecdIglL0ynsnDGExPK8G3tXvxPsa1a6Kwb3FaAm6SAGyr75wkRCkoFosO+kLR9iuAouDKCwFmGTCIQhjzTpbpLGBSwcWq2asTtcorZh1huU805otKomR7Wal0XFONJaUDZodUJRSYhyHKUHRWoMzmtbKfFffOyjd3SIxrD5cd2/7Xi4pXlwoPp/hPpQF5p6MJ6o47QclMsdPBESllCbApX5XBcT2wanpnfkE2yf7+QvdQgo446bz+FT3W9kq1fYhagGEqrl3lZxXkGEMI1qZkiK9z/qTZ83uTRApxsJyUKWW0VTpMiSsa7CuAXyRL+ZpYRpLIqbWFeBAxvECTlVGXGe66XP76YGSmL2TKU73PFXW2O5+SbjSHhOu7ENbzT4TJ+VETrL4nc0Oy8JZ7Rbh5blMWb7fjyNaKV76kpfyhje8gccffwytNav1mlu3bnHr1i1u3rzJO9/5Dt76lrcxm81YHixxJcCgqhB294ritWZ5+MoBzsn3/q4vfSdvfdvj3Lx1+VO693V7xePH07//zS/fuOfnN26cT+eYnyfE5+u/5j38L7/wqvv+7PoDxyKfLltOImeLKXHp0jWU2Vz8hSzJdGEvWMoY8URyrsFaN3nOaVtrlAIcKAGclJIAm5BiYWGJrFlrw+g92BbMjKAMBsXh4YFImdnNd9LeC2IVUX0nfWDTS33dtR0hjRhKMzJVj0VDTBljFYT0PGOSNI3MXa9rzLGEbn1ymY8rXlMyrhZG1l6dOaXQ7vkF5iyNfi142R4Qdi8IL1BgkXjm3XNe1+axhIqkGC+kr07srJTpB4GktMooZQt4IZ+zJf0Q7vVP3h1Bgj0AdP8Qp/TJmFDGkotMytRndb+hm6p3pNhHiGdaPd7CPi2BLRJWI0BRzLkAemLqrZScd455suVJORdAr6zV9M7/rDZejTG4tqNbLGlnLf16y9j3hFHC1+rYM4G5e/OaeJXuGiwVL85K8ehDl8FYPvjETe6crZ9//C9Mf5mXU0nerv6csmatwG/wgXFYY62hcTMO5odcWR6yaDtSzsxnLeM4spy3DCFwOO8YvEjpzlc92zFxvup58cxwtj5Dq0BOQRqz/YbOgO0aUox0TW3vyLZNma5teODaESllzlebi2EoKWOV5mAx56mbxzz68PWSFriryafnqU4az3M59vEEgM2mJw+BpjTIZvOOy5ePICeee+YWJ7eOCcMIIXF4dMDRfIb3nn70pAxHXUOwhrAeyEZxZTYnJvAp4q0mxa6ojhJDqXt9loT24KPU3Slh44jJimid3LMY0cGT1mvGszPiOKKdxTgnS1kfJca4k9q6m1myVmyyvAHBZrY2ojPE7Zb+VNOmpawZrKKPQBaFzYGdSUBDLuF8SqETJOMYyfcEfly4puUdnncNBzN5NyMZZwwpiZIFxA9Ya0XTuYnxLI1jUUy0RZq52g4oJT56+3dRGYN2LdvtZpLNxpTQL7D2+W0NhDkj8qdYBvfGWlwxoxQttuHqpTkPXD1kvb4z/d6m96xWI30fuHwkZqtCK5YY23EccdahmZGzl2JDlxcoyX7FgDiijSHFiC1AUdQ7k3mVIkqnQmWORcrSTP5dYsBviWPcgRa6LNq0pbEN89lc9NmuEQ18FnT88qXLtG3L5SuXMUVmudluODs9Y71ec352zmZ7sZhQSpDTcdiKN1DO2GaOMprFcs7yYMFiuaSbdTTdjKZpMcqQQmK1XtEPPeM4TJ2x1brjzW97Of/mTa/mPe97EZ8OsPPpbJ/5mmf53v/yVzH6Q9y6dcqb37Li4x9/hhASDz74AP/BF3wWDz10nQceOKIrscAqSRczpyyMliS+TzEknnyq44999zez2baf5Jufb5Ph9DWvus1/8h+/lcZ4/p9/44v5Sz/0JZ/2uX7B5/wzXvnYj7Edtrz7A09y82y4h+mwD9ILAJtQWcC+rKrh8t7n9+jktdCYEnZyLhN/MZ/Ou4lXzlRJm29vi5kJNEBRNF5xqlgqhR9giMPukiEFResactayWC+AmsjHpItrnSX4IN1JxCx/HEZCEGZJLqxQ2+hJBhDGROc0wUeCF3meMZq2NcSQCT7SzZT44Y3CLBVDeV26HhmK5FfAPwXIotc6V/wB89TNqN3QKns7OGzpZpbt1ktoALr4chg2m34CuAQUU1MhO3otDJnG0mpdpHSe9elG0qeohbrI37yH7dqzWYvMYZIPlns7nzc0znK+lm7L5jwyDrV7K4WhRpGCIuqMIhRLjd09zwUQTSmL5FZJqmCKGZ9Kgl0pqrKWRWOMGbIuDDNZjNiUOVh0xSzTolQEI8EHiozJsF31DIXt0/e+MDUy3dzSl4JToRiGxHwhnl2r1cDBQSNMD4Qh0raGbi6T7NnJlvPzgcZphq0Xg08vi5S2eAuZIqOgMnLLvYpRvNi0AmdFQiNsGjGE9XmLUmLu6YydOpPWSTFrXZFOxcx2G0o6UnkFtMJYcK0wskSiUABrJe9llbKp4vumrbANdNIFuKhpoJkUPZOeX8k+4pAYQ2QcEyjLehVxTmMbGRfCmGGuSV6hnEgvQ4CU5d8akT1Uv7jZzE6x1rosPs9XI2FUrNcDpMxMNzhVi1tVmDzCsExJ5Jy54M+6XO/97W4/rwuywpymsaRK1rQWGWgKO/bHC97yrggOSaT+9asrs6d+/yQXUrJYqh5c0/HmHZgXU8Rnf9E3pwA6VaIrAQW7olKSWo146byAgq4u1O5mjNRFVb7PhdhPmNM1VKEs1qy1eyE3e/sri/sQA33oAWhti9b3lpOhhAlNEqnCzoTyvN91r1OMGCMyd3IqPkby7omnnMgtGlfTtHfbbrEtz4T4QO2apCDFsTCOcwknzBcYe5VVeI+cqM5PZVFcpc/1WW27OdpaSgDb7tcKc0MjsqOD5QJrLe985zv58Ic/xIMPPsi1a9d48MEHuXHjBi9/7DG+9Eu/lJe+9KV8/ONPisykPEs71v3OJ06VhqlWwojQRcr72Z/1ES5dPuf/85Nfec89eSHby16+xjUNfhx57/vuTYy8drmf5vPjk3vlj13nuX1nyXrTcXdjEOBljz4tnpkwzZnOOdI4Yqwj3yURzDlPUlfbWNq2E4uO5RFdO8eXUKZh7Bm3vViljBsBo5ViDImhANZKiSSxbVpcqftd0zBbWpYHHdk4tElcvnTE9WtXGQYvCerVo7L4A+WUCMHT9wNuNicjQKXyDtc6QMB+ULhuwbjZsi0N6f33bn9TpfmSq+F6AcFe6OacYzab0W/7KbnxwlYHWqo8r3hvlR+nUuNVK4x7DrEyvAobORVQSKXqecTkfRTvYi5OAOZdKSWSdVMTlFWRhtcxaVd3xAs16u50Ys7EnKbfk3cjY5SMfWOIhQG796uqHrvUExaN1gmtzI7ZppLULzlf8FdUSL3jnJ6um4ydMiYs5t3ENKvD2wTQ1c9rg2s62rajKePU6EeGYdzJIdXOl/LuLRfSBUj4BkphnCN6IThcvbTAB1lXnq42jONFwNA5h3GQCKXGT/RjwKk6ZoodTD0O2xhmOJTKtCpxYBs6K2xGozXNfMbBcgFE5rqjMYbLCzDugOtXr5OyYtsPnK43HF66LCmrxfta54jKHt97jFG4dnbhXLVSDGMoKfcKhcUoi1IjIcqx3zo955ff9m5OV2vaWcfLH3mgGMkPJO+n/SjuD9rLfd1doO124OTknNPbpzSDp+062kuH2EbTOINVCpUym/WG1fma89M1l68esVwuhNmqoFvMOegcUWtCSGwj9NbB4RFYQzsMxcdSvtmTiQpGBdlohk0va4jes96OdP3I6eBpnSFu16htTx4GsvfonHHGEgZJLiVmCQu4tRX226KlaS3JKlJjaXygPTtnERN2NivAm8e0DVobWt0wDhto5R4vtMKXOUePCRcUwSqctjjrdozMnPH9loXVE3VExglY+R1zWGkjMtwowYRSFxbZsa7N4hFZJwmrvnGWLiZCP16o6YT8JnWltQ0+RZHzagef4H7vb58SEPYjP/Ij/MiP/Agf+chHAHjta1/L933f9/EN3/AN00X4/u//fn70R3+U4+NjXv/61/PX//pf57Wvfe20j2EY+FN/6k/xEz/xE2y3W77qq76Kv/E3/gaPPPLIp3IogEwazhpsWWC1rZ0o8LVAnc9aDpctzmm8F9TbWcWmF8+T883IIq/pujkveuhFpAx3Tk4IwWJ0R785l2JONGYA4mmC3NwaB2uLPDLFSAzFH0ZDyh6tRHPeWqHvt00rAFgSjwpQtCW5sinm97NuxmKxoG0FjNFa07Yty+WSpms4PDgkI7TZ07NTTu+cst1uOTs5myZarfTeJFqSYyheIjnTdR2Hhwvmh0tmyyXzg2VJpBPmy9BvJqBo8BIfu9063vq2x/iVt76Kt73jpeQX+KD9u98iX//VH+V3f9WvcOPGTX79PR/h6eduY9uGg8MFjz32cpaLGZcvL3nowSsYI8+HUOQTMTHJ5EQqB//4nz3GX/3bX8wLfXlku1jkNS7wlV/2YX7vG97Lv/iXL+e//oEv43z1mwXUZP9XL9/kD3zH36frPsjxrVOevXXCU8/cYT2Ee0jylfF+AS1HulYpl+SSJAl0dQDZB8Fk4Mq7QiGXtC52nb9dcSSSuf2rlUglYrqkA6ksnaWcsY2b4r8BfCrygbIDW7pmKQpDYLsepRuwGVkctMzmTZHaibm5HwpolWC9GbEF6BIQWmFL+hQatFMMGwG42k4MmkNINK1lvmjQGs5PBoLPHF1t6Mtgq5UuQFsiefGuEfJgOXGDMLdCnHx+Ykz4UfyuFouO5UGHbbQswG6tyNtQGGmWfjtirSFHT0i75DdQOFu7iIacRVqzM8rODIOHrUcbRQyZ2VJYGm2XGLZybYchsN0MKCVG6eOYibkHNDEkHnr4AOM0IUa2q4BCc3o8CCM2lILc1AJdSQcpCAA2FaYZfEjMXOmyFqmb66z4um2DLGzLzKgUkjJktJibzh1kWHaO1SCAYttYQso0rWN1uuX4zorZvJ0MfnXxTxxSpt8EZrNGpJNK4s/ny47Z3GGMwmoBFUgQvcgpN+uRPieM00SlaOdyrReLjkYZ1qZns/VTkEFN7PM+EGPAWYmBVkpxcNSiVCalQCKgEXZtCJnNesSPqRiDl5SjlAg+oFVCmwxK4zMsFg3WamYLiy7UcF3CFLwPhVGoMY3BOPHyUCjmWIZYJFMpF5ZM3i0uSiLSNkZW25Ft70lZo50Y7SaypItpNYUcrFcBpVu0rrHcTlKXfWJ15ukbKSwvXZGgFojcudMTYqLfRuZNS4iZxmUyEnVdQSa9lw5mrcW2rjSFDMq4C4OXAIi7TnrOEJHkVGUSOY4XFpQG8dTIMU+pybVoquytaSFaAYZPADJViQEgJtRKTf4tMh4KGBJ9LL6BRQZ1n6aQcP12wMv0vUqaAxPNv0Z+ZzX5mj3vpsBqK5K+sv+Y4m4fPP/5XTjGzAX21PQZpcQbphg37zddlFJYZXdJWfe5djEIY6qCpftSx1A8dZzblaEpSbBEKrKgVEy+VQGbc3kXlFI06l4wjLKIbdpGwP2xzD1FJjz5Q9UKnd3fk6faXhMI6lhjJuZaiCLf3XkMwqbvuba8PIFgtqRSKmclmRKNNobLl67yysdfgTaGW7du8cQTH+PXf/398uyguHb9Ab7pG7+R07MzTo5PeMmjL5mejRgC0Q+EsMVZS9O0KKOwjSMCz656Hn74hFu357zlLY/RDw2/2e2zP/OMHNLzLhxvXF8JGxrFe957rwJgMR946unn9zz9jJc/jVXC6lEoVIK2Ea/aLcJTqYykCmYfLA9EGdE2E3tss1px++azjKN4+2636+LPlidQvWs6xO+soXHizYSCvt9yMvSTsfx8dcYwRsLyjFVhyx8tF2U+M8y7jhoi1BS/pGHoS4Ktou9lnt1uL5OCl4TuECdmpPGRFi6A4VA8uib2lSQPBy+JnJ/KVp/ftm2Z/KUyF8ZH+UpBa7UWGRFIL7PaOVQAbGrQTMyxveZoSTGOxRMVZC1WGdwCPl+UgddtvwacpILyReU7a+0oNWgM+7WnNFfLmynHkCMpjhjtJo/i+oqDeMOqqRm3OydtFKY103XfgXXymyGK36kzbppr5ZcLEJUyqszpOe/aDFrLM1ZTDVHgqh8iZTxxLa5tCmPfgdJs+1Gk5YVVPIHd9wVMFUrtQgWUkudbG0cOiSYHHnrgkH70Amp5zzD6vXMEoxqcbkh4tMnMO8tOS3KR2du0lkzEacfMNpK2HsMkGY4h4jpH084gjhOoZLTGFCuDs9UZKY4MY+DgYCnMnnEkN6bCsmX8ZbLFAOgax/WrR6TLwhodfWAYVsQ4knMo4WWR07M173n/h7hy+YAXP/Ig3axlHKXh6/2AM4qDRS4+c8VrrjDEFLsGRk6ZZ566xVNP3uRwHLl985jZosW87MXMLx8SEpyse07HQFSGFAfWa2HeDduB5cGCKw9cZtE10uzSGpeh7wd83mLmHXq2IM2X2BRx3oP3ODLGOXoF6xTQhxJ8Emae7jASfeBwM7C9dcbp2RnnxyeQwbZNqU8TB5cWrE438g4YDZ0oS1TMtH1k3loWi4ZZ06CVIq430A+EdMbJek1sW47mLW4cuTNs4WAJIaCczDddMqgooHdUu/l0ejfKe6dyJQ/VV6aC7/Uay9wvSZuGmPeSfsscHMvc79qusG8js5zZek28uz9XHlfnGgF1B0n6vT+r9N7tUwLCHnnkEf7SX/pLPP744wD8/b//9/nmb/5m3va2t/Ha176Wv/JX/go/9EM/xN/7e3+PV77ylfzAD/wAX/M1X8Ov//qvc3Ag6TF/4k/8Cf7ZP/tn/KN/9I+4evUqf/JP/km+6Zu+ibe85S2fNPL17q1KILTRgtCqUmiVQT1liW995MZl+q1Q6eZzR0yZ27fX3D7e8lBjZYEaA23TcH5+TvSjTP8xomKWgmB/8M4JVI2vT6VbmdDlZtimmboSGisyRyvm9s4JxT3lJIyvbj49TClJcdU4KeKsEbR1vpxzcHDA4eEhTdOw2W7Y9BtW5ytOj0+5c/sOw3ZAKUXbiZ9EpdAnCtspFvYGmcPDIw4PlsxmLd1ySdN1GNdgrCPFgB8HwjhK0Zdgs7W8/Z0v501v/gze/s6XEcK/PyLhYj7wR/5P7+ZzX/fLbNbP8ZEPP83x7SOOT9Y89PBDvPjFD3Lt6iHzeSOTX4r0fovysB37qVuvinz45NTyx//0N/Kxpy7/Jo9InosHrq35tm9+L40d+B9/7tV81//1DdPPfnNb5Bu+6uf5gs/+Bfy4ZvSB7Tpy83jFndMttpmTc0HYy7OGKkDWBXSsRDbnTE6BHCMxS4ErpUx55+okUCf0kuiTck1fKtOFkkFNyNQV8y+/bhCQKO/tLxVdudGEBNblyc9H2AeI0boCzb4RM3hfEvgK3d4X0MRZjVEKjwA93ssJr84HtDbUYSSGRPQiVfSjSF5rMWWsGJz7scgkkKCMpjVsVj3WKbp5g+CGmbZzbNeBMEIcY22qlnEmXlisi5+BFCnjKEl+2jn6jafvA30/ypXTBusUOWlCUsK+JIlMzBqsNWWhJ/5nAsgIE8f7yDBIQmCKcPWhJavzgbZ1xctGTVHoE8tGGfyYJkA8G/AqiLzEO1766qs8e/OMRKBfJ2JRfIoVhnR4U0lHE6fD3VZq6wkci1EKz8mvgL3XQWYoQvQY7fBjYfS2ufgiiYm80eKvtZi3dK0wI6qUQRb8MiE3raVpDd3MgJJnO0ZhhXSdFQmOUvgSrLDeiPSgaw0jmRTBomhaR4yWZHJhNco19GNEqUSLRRkJQDFWg4blgSEEWVRYZxh9pG0oIKjloYePOFi2rFejeLKFYozeir+CzD1pes7my475oaXtDMZpclRs1iObFcVMv8h/ULTZklNmPXiGwQt43I9FEqlobINtGpxzjIOf5A47HxgxY00xTgh3LB5tWsPp8YbF0mCtwjWaPMg7tNkEmqiZLwzzuTAq+03kwx++RQjy8j38MDStxbTC8sv1ISl/55zFO6o+EqVoqu9y3VKOWFsXSHX5kwqTTmGUuiC9Uyhh9BRmgzFiul1lTCDjkUiiyjjk8wSgfLJtv/NZ/sPEFLjAIlL3FmHVML96v0z7TBd/rzavFAKmYLgAQt3tWSaM3d0YhDG0d03RMe28Eff9dPaBPpUF1NtfgNV/ayXstZ0szYivIDtALSSJT5/uhS7sa7Vryl0475wnqWXTzRm2W3KO+OIRCRQWzt7QocQbrxpT6wJ43rNozHLNQgg4o4uEyUw/92WxXK+DVtX+wlwAK6sfWj3WEMPEAtV55ycXQqLrugI8FEGRVijtUAWI7rc9H/nIR3jPr7+Xm7duTvXa8mBJV1J6N9sN56sV169fL02N9i4Gohhcay3vqDYK01hhvvjA133tu3jnux7mX/7iZ/PYyz7Ob27LtA0TAHG/nzsbCV7O8y1vffSeTzRN4M7x8zcAX/myp+9JMK0SRm80rXYQezar7QSYHx4dYo0k+662K7b9lnEcp5TncRzo2lnxxMoXAGljxMZg/4xEUinPTtcJi2fcjjy3OiuMXs3pHQEwjZF7Ya1YlAzWyphvLaowOxdW/ECPLl/i5PiEWfEIHceRRGYcR4athEqFEPEhkAtbUwBg8Z10TUParDFFwnkRmP0EoHjZqldaDYC53/1TOaGyljkuZe636+rdtg+e7O1BQLDCTnRO4wr9KabMvjr97ipYFaCInC+MCSklxgSjjwWUkUCLVGsYtS/zlBpREppFQiYBQ0X2vPfdjZXG5z4IXzEQpWpwQD1/SfPcZ4pW38n6PIUgzdeMwSGhZjvD+QJM6fL+713Wan3jGoduG2xraWeivOm3A33fM3iPaWdkY7CECzJ/IX6UMb7UyHVONdZgVMJZy6x1HMxb+mGEhw65unQ8+Zzh9smanBUhZZw1U/MwJEcsBIlNP5Yj1kg8UwYN67HHNjNAEg/DONBvTfluV4Bpmb8b16BIeAVh6HExYq1YW3g/4AOkcVuuecZ7gw9hSuFOOVfVpgCR1nC4nBNiZDnvWC46jhuH3mis0sUYPxKzvGNvecd7uXH1Cl/31V/C5nyL1nB2vuXqQYuOAb3Hks/FriGW5ntKie164MkPP8WdOyd8+HTLS11ma+H02Ztsz8+JzrBsHYeLGSd9P0GGqihWqiS4WhgBqJyJm57gR0zOmPmM5CxBG0IrtkxmfY42loWT4Kl1iXC1jcPiyF0Wb91Sax9eu4TNGQtkLfLVVmv6MRLChlyb6UoAb2M0jVbYzYhrhQmbZjNyyricseNA9gOXmZPmLfa050gpzpVmqQ02KjbWcILHo8gxiIy3PO/UJqcxSBiSXBcNLJykctZtzJmQIWtZJ/mYCOw8Sv1YEl8piodSO+UUiqWOnZplQAmQkjqxda2w1PZqnU+2fUqIxhve8IYL//sHf/AH+ZEf+RHe9KY38ZrXvIYf/uEf5nu/93v51m/9VkCAsgcffJAf//Ef57u+67s4PT3l7/ydv8M//If/kK/+6q8G4Md+7Md49NFH+YVf+AW+7uu+7r7fOwzDBbO/s7Oz6d/CopJ0iKEPE+pfO7XWGq5enjNrHsT7KB5EKfKyFx0BMOvEKHgcB46Pb5dIZhiHYTJLHb0XCcNUkMTC0pCFdfADKXhcN5OFfAZJaDG0rmXRNoQYJnqtc05it62b/FAymaREZmSNGN8vD5YsFgsOjw4nAG21XvHcs89x+9Ztzs/O8cPOEHai9ucs5vt5Z3NujKKbNRweLLh06bJQqOcztBHmRcqJYbth7Hsxj+4173zPY/zbN7+Kt77jMcb7RGj/1m2ZVz1+i//kD7+dF914Lx//2DPcuq25c7ri4NIDvPiRR3jJ4xpvAivl6ddnuNGgtGK7XtNve45uXGX5wGW0tfiTc973iy/lB/7K7yLlT6Vrul+Sy/9+3Wue4/Wf/yTves+D/K2/+3nE5/HLeKH7v3R0iz/y+/8m167cJoYsjKeyVsk5s1x0rIeRp26eMngPhfrPXdww6aBTvCwi4l0nlH6RLcZyLhEKe+vCkZRJqEocFdWHIFN7WzGL1KWbtcQikYG7GAi50sxzWWgLgIHWuMZweLhkGAKuNfjRE714LWSdIUnaGTGx2coiTqNwCzMZ3XazBudguxkYBi8Lnk6Ku+gTOSvxR0pMAEwq+nMpnjwjIvfSxZ/CNRZjFU1nJ8+yfuOF2UbZj96dYAiRnO1UWNWFlDMiSwSRfDYzy3zZ4AdPvx1JacS6kn7GzlR31jVFhpdK2pBGKxmnJLXSs92OjGOS42wbYoTF0QJtNH2Jm86ppNRW6YOSyXIYE1FFDuaOpjFopViUNM1m7rh0peM0C6PJ+0QOFdySolCV522XPirPS8y7si8Vo3lVuqcXQDDESLMm14xDIEWNnyVs29BvhwnEM1rhZuJZFYOAf6MXeZVWkoA5XzRcvryYZCg1MWvYemadw+6lQ2624p22mFv6bcL7JN5mVsJP6puUlQYljJaQCnhU2I4iiYl0M1sWUgmlM+MQ8D4SOlvAFsNy0bI+HxmGOAELu4I80zhHH0cuX+nE2674ublW2FoYGbvb1pKcADx5lPfDa0mRG8c4eWZ0jQQOxN4T20zOir73hBgk7RIJB6jnkepgoSU1q0pyrLU0rSbGIMbHZZiptXfwmc0qMPRxss45OpozjALshAit1pDESFrSxuRpMaZ6/UUJLchZZF8ZaVCURYgAVQk/7htP7x6lClw0rtoM3AtICcihS5pr9ceRP1W+7HCTMf7d/mK1ANtnRUzSubtBMXayvPttxsi4pQoQeZEZcv9twnXKNbkbXJOFQ5wkwrp4d1XZ024/4ldINSC/8CV7ht6oCz+fwLC9aW16n5WaZD0AYfC7iaekoe08d/bGznxxXzlXIFj+yByTKkeg1DS77zWl2ZGz1GawS6qqrIKxNPJyyiRVvFHLw1PDM2o8XiwSoinFr4AWk5wp5wkACzHspEsoXCNKgJy5YHwOu6ZIZeptNhuefPopxnHkcz7nc7h69Sq3b9/mzu07nJ+fE0LggesP8PDDD3Pnzp0JAJq874oRcr09YggOd27foRenCx550Qld9xX0fcP7P/CS532uPtk2+Q/dp5mn1M6vSmnFW9/+ons+07iA9/WhuXcfr3z5sxhjdzVrke4aY5gvDC45XDbCArPiezWMA+frc/ptz+jHyS/MFEakKwtygEy6u1S7AIxBfSYVPnjiJtK4Du/PGbabArIntMriLamL5Yo1kpZerE1qArzSuxTbxjVklZnPZxwcHbIvhdxsNiVgyovnWWEdeR/E/DwGgg9F8toKWB1zsV5I09/U8SfXxWO9N3I9jTWYZCbW5f74VdcIKQckRfzemlV8J3djwT4YNqU6FgsKUywbKO/pzr/prpcdGWeMMjt5e3mnLj5fCh8FtEwYMT+/kCK5229952MSAkyM/oJJvi7zWixzWB3eU2FOm7sZpcA4jNOzklWemL5V9k7OGKWIUaNUKnVZqUm0eJ/aXGvo4gtdjlobSzYNWRuR43YtWsN2s2Wz3uJjQluLIeGcw5dk9zqv1OAYuUfy/8RyQQJqav0qc/TIvDGoRcvpzKLyjJSZpKJd1+CsJuPKHK+Ytw3v/OjHJQncim/csutwM01jDZfsnEaJZN6HkTY15GTYjgOr9UDbOA4O58KWz4oURlIMpCzvy2LW4EPAV9WUUvgQ6AdP60QZ4EdPKvV9uYkoJf5xi3nLctFJCJVRmKwggVJG/KByZrPtOT1bced4xWI5587tE4mzyLlYvhSAMmcUkRwjYTswbPtyLVvSdkMTPQ8uHd3M4buWUwV2GFiPinU/crzuWQdhzHdK0TTN1EiqAHLdUkwMvSSCNoX9noFoDNkY9GxGd3jArGkI5+csvDyj2xwv7Me1LeaqZbZcFNaVfJ8fR+7cPGE7eHzOnI2B1lkWyzk3rh1w5YEjbj93wnI5JwWZaKP3JD9KszomzDjiWoedd/jNloPGEbdbri7nPHKp49h1mAjn24HN6SkRiGNg9J5sSwKqc7RtSyos78sqY50jKSEvyB/oU8bHzDYrok90Y8QrOC+BW8NWGIyprFNTlKaBLu9l9eKsKdQpVIKHKs+xY90PxZbqk2+/aWpPjJGf+qmfYr1e88Vf/MV8+MMf5plnnuFrv/Zrp8+0bcuXfdmX8cY3vpHv+q7v4i1veQve+wufefjhh3nd617HG9/4xucFwv7iX/yLfP/3f/+9P1BCiVRaYdFVug+Uzm2SRbsxmoO5JeViOlh9dZCBI2fFOPQ88+xTGKWniUZkTpExCtpsywOsSULtyzJopeIboUNAN+1UYKWcGf0IOcgAZYQV1rhmGgSA6d+2tcwXCw4OlywPlljriDGx2fasb91ivV5zenLC6ckpQz+IBn9vnok5E70X4KQOis7Qdi3z+YzlwSEHR0e0XQchEkJkM4yMXlJzNuvIO3/tUX7lza/mbe96nL7/dCR9n/6mlef3fdt7+Orf9asYfcxm9PzGx04hOHxIPPDADdCKp06fA5Xok2eInj4OUkYrBUbRHM7pneLUHfA3/+QX8+tv+lRjxfdWT4Bzkc963bNY43nbO17Er73nwU/zTAO/5+v+CV/42f+ryKaSoe+Lx1SI9INnvelZ9z1PPnvMzeNzNtuRVDsbRbiY8/6fam7sRQ5ZiiZUnQTkvKS4qd4HdxcbmmrZLWefsRObQORX2oAPw+7qqLLfaV+FeodMVrn4nDoN3byjnTUYK3IXoxXKUOK3EfAsynOtNaiuyDlzldxkYVONkdDDYjZn9HLfp/Ev52KGL75LAhJn8BIxHMZEDJ6kLPMD6cq32oppbZnQjFbkDvptxI/h4qKQejEFOEkpY8siNIxRBvwxUOURsbx31SDf+4CK4k1htMKZCnjJZ6wTMK4O/CH4shBLaB1AW1wr0dZK125lrpmgRbogHUSlhMlq24zV0Dgj6UySR8jZdmAImXbW0M4jNoKLMAySglSflxxlgVAvQ73U+zkKZCngp2ukpmERKNfJGDKKEKSYHH3k6KCVeOkkTK2meDIoFLkRb6Cz84HRD/iQsM6WyORcEjqLxANhC65XIp1rW4l+Xsxb+u0IKTH0qXQdmZiLIMXyGCvjUbpvISbGMdK2ia51uE5SyeqCIfhEiLKo7geRTjqj6VoJAPBjlTlKk0LYAPIONa2EAMzmIh12zpILSSuEKPJOqxgGWcAEH+XdsOJnUj2XnBXfhfVmENPe9br4aFF8Z+T+Na1BuywJYiEX3zJdvOCE3TL0noOjZmIRyaK+3kjY9rJgMzrTzRzGWmIygHTsupkTdmI2aGXR1hSfpoy2WgqXIp1JUROSmPYaVY3yA9mYwvAuC+8cUXuAv/iszAlR7onw+nYAU20O1RHpAmNrb+GojXh87aec7f9sH4yooEjdVwXE7sea2N/EKuEufzGVL8gs797Ei2f3vfXve9MvVVkYJwk3UIrKDt47gsLM3QO5UBMwty9LuNv8dgLH1O77UxbbhyppnY4vRVC6mOAzAdop7Xkrqj32XZmWxqGfila5nmW+MRRfGDnPXBi4KWaSdihlZPFoBKxOUXyaqpSxSiyiKm9zacbkLMDSvvl89a67u4lckyX3r3u9DtFHEgpbWEEUcnbKefI3m/ZTAPDFcsErHn8Fr3vd60oARRKW0/mKtmtxzvFv/+2/pW0bDg8PJybe9CcJeyGmTBgTdzYrbh33oBUvfuQGn/e57+eNv/y6+z5TL3Srcrf3/frRPT+bz8J0jfq+wYd7gV+pR+7/XNeteiDVpMHqlaMVKG2Y2Ya2bQg+sF6vWW1WAnCWxq8wLnTxggHvR0IU+VeV4u6uW5mAat1DrZGKuTuZ7CMxmwkEjDlB9qihjAflfTHaTMyHCoYZYwvLVL5HGcWm69istrSt1PsSeCCDcde2NE1DKAwwbW1dnrNdi7xz7AeRcqdUJHOpJNpL8IyY0gdq2Ic8X2mq7SZpeLnWsdQfKaYyNlbW4t1A2K65tV8n7o93hhI8Yy4ynyo5QIArXQIG8jQWmwIo7o/LYs4unUq5nqb4NctnYrHQuHucFMsNXQBsW+Sk4mEsYQQlSVPvgA/YPdtypmkam/ebDvs97+CDsLhMCUEp4F9VLoQy5gBoZfFB5iqd1MTOl+PVWNeQJ+DUyrwZA6v1mr7fNZMriD69+ylP6d+7a5EnKwNJ85TGUd8P5V5LTX223mKNYjl3+Jhpki5sXXPBo1Eh8+7cCkNncaljOW/RzCF6Ou2wSqyHJPTE46MnKU2ImhhFgl4T0BUKUka8zDK61XRdi90O+BAxVprAIcoxW60kQRxpWlQLFGOkPkBB01hZ07YNs65h6OW9NUrTKoUnkbNmte7ZbEaOlh1DiHTOQAwMWwGJa4OrAtSusUBLGD3D+TkPXF2Srh+RYkZ3LdlZRqUIPvLU7TNW51tW64HoEy0asmKMiU4b2lnD/nwdCvC32fRstj1d65g3Dgdoa4k2AQ4ajXIOvVzSAun4jlig1KZDmTutM5jW4bShEhO06Ti8POf8bIObNbziMx7Fj5H+zjkPXJlz6eGrXHvJQ6icCIMXnMAHfD8KIBZlLtNW07aORinyMBLCCKNnPmvoLNz2iVWrMQedvFMx0fvIIJ0qYbCnANuR9XMr1KUF1y8f4Kxm66WR06BwOhON5kw13EKxGgMqw0FMnIVAHD3KC0jepzoQJQkhSXUuB1+IHVN4L0BWNN2c7ejx/3sBYe9617v44i/+Yvq+Z7lc8jM/8zO85jWv4Y1vfCMADz54ERR48MEH+ehHPwrAM888Q9M0XL58+Z7PPPPMM8/7nX/2z/5Zvud7vmf632dnZzz66KOy4J2ow4IETjRf2K39kYG5CjHU3sAUyiLCx4Bfh6mTXwe6il6PuchwnMMaQ2Nl38YYlGvJTnzCjK1pTUoGaiVFkQ4K1agLRuEgv1+ZX4vlAts6VInKXW22rM5XnJ+fcnJyzND3eF8WwnsBfFKUCpNBGTGqdo1lNp8xX8zpZjPmy6U8qNbQD1v8EBnGyLZP/Nq7X8SbfvUVvOVtj7Pd3mt8+lu7ZR576Qn/6X/0y7z4Rb/Oar3lbOXZrj1eZY5XPbNGZGzrfsVmu+H2+THaakKKBBWhtTTLObOjAxbXLnH71qv40T/2tZzfnn9Kx3EXjYX5fOTG9RUfe/KAt7zt4U/7TBUDf+Z7fhCjniPHzPnGi1FwTKw3W1brDf0wsO1HztdbNoPn5vG5yKASU/e9Eh2kox5KWINQ7VMubMHynRVQgf1CR9JxhLFR3o29ZZQiY8oCdB8S1CqDLvTpWvRmpmLz3k5wieS1mtnMcXg4xzqLs1LYK53RToPOZF8kzpGSzCh78D4Sk6btHMZZYoSmjWQi/ZBotMY5UwpqtZN25pIMhJqYnSlFjAE/BqxrxEdwjIXiL++7tcLWGvtE9IWlYqRjvi9VMKV7RqoeUCJJHcttkm5uKkDGnn9PKgEGiF7eFc8KRUnScxqlS/e2eAYJ4BZRRiRrTSeMWO8DfhwZg2fwAwpD7iF6AR9cq8kq4Rph4zkjC8usofeS0hjLs+Jai00aP2ZiEAnl3dKMcpkk2SUKo8eUcW8HEAqTDFVNcOU/hxCxxonRa47FU6v4LVoZgxORxhkaZ6jJiEopZvNMP3g8mqYp3j0RZvMCTiUmIC6GiPdRWH5KusPW6KkjrIpsjtLV1Xrn5ZEVVP/vXKLSVWHUNI2AUOJXBKszYeGhiulnThgsm/UojLeUS7G8k6P5Mcq7ZeTZbFo7ganBS8iFBFSoqdMlIQQC3GXEH0rrUBgthdmpxLtvHBMheVmsGCn0bWswrbxjMWbGQWSoOaiSnKUlPMRnYjC7EVAprJPgiBgz241ntRponabtWpQWICH6iG5kLHLOIhZoJbFW7cabymCtSXhkAcKchWpxUFknE4shBXIaqUwFaxuMzYw+4oxBEeXZ29OGXxjH7gKrpONfx7OyyDAIMzszLdz2GWEppUnCXKAngOLpdq+xfC1eTYlkqwvCKvGryZLPJ2Gq+6iLsJzuAqpUWcjuLSxTDGSz+29yruWzd8NjBfiZgLkCDOxvdcEgAFaRCKZIVtKRNXOZV3PxM5NwCWHcinyhLHgLoyKXdyilwv7NefJavXBs5f/nFKZFuzRH4jTdaGUZQ8SZDLkUyGMg6R24kkoTIt81J0lDpTZpdrL8GHcpfXUsnubFwtKqgOF2uy0sEyUpxpUBN+4DArI1jYQfffzJj/Nz//PP8fZ3vJ0HHniAS5cucenSJbquI50kfuP9v8EHP/BBbty4waXDA6zRwpKIfgpiqs/RGD1PPn3Oc3dWtG3DfNbxTd/4b3jjL7/2wrn+ZrdXvuL0nv927dqG+my++733JkoCjIPj67/mvdw5XvC//svPvP/O957PXBvQ5T9Z53DW0Pc9682azXYz+fvJr+4DjFGA/3HYPUflXaugtjbC5FJFDp0KcCSS4zKHm4i2O6NuAZjV5GcDSGNOyXg1Mb202QPI9JQQuLGWM3dWkhzNBNzJ+1QAtCIH67Sl6Rxi+CztRmss6/MzAdeSBMyMoyQc+1E8e4MPE0ux+hNXPx1rnTCufCiJqmpXp6kKEkZyFvkyVH+r3enWpqr8u4Ldklo8AUjTGFYvfQHNkXlGl6JQGKs76bV8X2HyIGbXMt6W8JACjGZlSckjjGw1GejnwoSVayW+QUqrIoGt42TeA7rlkdPVD41EjMXKQum7WGdMnq8mm4sAfjkuVZ6xGGWebqw0BWLSjDEK+yUj9LAKArqGVFiEXdvirGGz2bLdrPH+oidcHZPunlcuNGWCNKSCDUUSrPAhEuNu3JJwG9lXo6rcTJXm6MXx0PvAzFlcTFg9x5oWgyu1nXgdhuhJZEzOjNGjciZF/f8n78+Ddtvuu07ss6Y9PM/zDuecO2u4tixdybIlI8vgAXBo3HTjJpDuFO10IBRNAU0XXUW7CmInUN0x3cQV6CQ0qLpIqHbFFco0nTIQmkCMzWBh2diWjSXburaupnt15zO/7zPtvdeUP35r7ed5zzkSkgBTrmyXJZ13eN49rL3Wb31/3wGF+IiGKM17lTNG5aNwhJGul/cQBNB2ToLjJu9LsxWC0VjMDGjrGhaUYdF3PPXEOd6PGBW5fedeSS2XdVBlubfb3Y7dfo8qTVedI2kKjJ65IVWBbFObzb0wgpu2pVv0TDGy2Y5svXQls1IEE/EoLvYTm700HFsNZ6UhZKykw3of2G33szx5mDzr7Z79MNF1DZ1zdDljXIIo6g+fM/uU0CVYySyWtNv1AQhLGZ1EmmqyND5dY4tMXpE7S9NYTk+WONPgvWd8fOT8Rk93fop2FqJ4TeYkLLAYooBiQWxzcpJ3TJQJkFXGj4E9mawNOmmuXY+cJUqoViTE4onrA2E/MPoJc3nBM6bj2vUlq5MOkxMnCnJScn1ti29aoodNHtmOgWGzY4iRKXpczixQ7HPEAEOGACXxV9Qox75k1PdRZjmM1sVjOfNA/vAjjy8bCHv3u9/Nxz72Me7fv8/f/Jt/kz/4B/8gH/7whx96SY9fri/U8fxSf6Zt29k0/vioNyKXQq6mz8Rjz43yfR8irRUjXlto+xmIOcxgWk4ZVCLPG2VJApOiPM/YkwLJzkW07sZptC4Sp1KwifSnbP4SmGxobDODYM45VqsVq9WKa9euSSIkmTF4tpsLttsd682a7WZNDIHNdnNY5AvukFNhYSiNbayACq2lW3R0XUu/XNItFpRpW8w7dzvGIfDxTzzNT//sc3z059/FZnMMED0KwPjXf2gV+F//3o/z7/+uX2UYbvLa63f4lU+JKWxrO0KWjpozhmHccrnZcA/FbhoYh4Fu0WEXLe3Ziu76Ke21p/nZf/jb+Kf/4zd8mddzDPXI0TaBcbLsdg2fffH6v+SVZr7x/R/j9/4vfoi7dy94881LUIZpCrStwdrIdojcvHWfi/VW2BmTn5MFhynKZrR05lJOxIqKxzwXyiKXqcX/cZEi/1DoK8BG9UG4CoZB9QkQPF7qfA1oJx1TlRty9qXwPGxaD/u6w9+oGwOlRXa4WMr7GIOm66xMzijxCcoT3udyrqoUkbLBzgV8aTqZvvZ7z+Q9kUSrpMNki0a8dlIpG/mZiZmksxJ9wNri91eo7RSJDgnilGZ/HTFNLgVd45gmfwjLsErkOwlCKTDnS8/5cG/ID3TKpZUhOnuDcSLByzlLA1tFRp9IOQjdvBSqTdcQU6LtW6yrzJk4x2rLYhdJXqShTmmUthgjU1fbSIHkJ0lGUql6Q8nzafuG6OWcbUioocqWZCPbNuIJIcmepVBOEtagqBT0Cj6U+TkB5fxjyCSbJLJdieNcDIkwBRaLRjqJRs3piXUDYbKU1PvdQAx+LsEra6lpmwJiULzf8sx4ke14xhXwLKNwTZGgJqGu69KJFpmdMAiSiehQ07US2ogHS9vKffclhW4aPbYRDztbJBmpMMZilDFU6k+55iT+VzO7odyvWFhYFP+Y+kya1h42KVmk91pJR7ymCQ+DFJMxi2G8zhEVE641tJ2lW1rQ4pc1TQnngKyIKs/AZn13a2GqtUZbQ4OwaXZbzzBGdkNA5wbvRaKstZdi38pJGqvJIRCYSDiM0oAUYDK+5ediYVhpZVBFJhOTsE508V8ROU8iIxIVtJ4B5Mq2TKU7Wp2Aqp9Llc9UT7D6O3UjWzcJ2ohs5yDjU7OstgI39XfrPdIcJIVX0is5AFjVIzGryowQj7f6cyGFL5oMp/TBlD7GA6OjSqMO75l0xLKKxTfycDy4DtSv8gD+VNk5V36qzulKJB4+BKYQiAjrqW3bmSEFqjArC5d4rs1q913WnlhYAjnLHC2Jk/W5HdVuBfzL5qjwVVcwlHmlPrwz8eBtVqTIsj7WNEhmeSplTdIc1oYKLMRw2OxrcwgeOgZUY0zsdiPd4vTQ4FSUhLJiHF5kZPU+hBBYry9JMfLaa6+x3Ww4OztjtVoxThMXFxc88/QzvPud72LZ92QyPpfGVgEb65wWwsTlZsfFxYa3vuXJwiL5V1fDffKTpw997e1vuyzASeSnfubtj/y9mAwnp4aXPv9w4iQwg5+y5muydkx+EPaUMXRdS5oG7l/cY7PbyFygKrvmIIENUSRaIQQBO9PBYP+YAWqsxeVcAq0Svm7g6rpX3vUr3npKgTKlC1LXuAqQJkiZqESOrLQh4Gdg6MCylHHvrNihGHMItlBKoYwRFkbX0S06CQHRkgTYNu0Mxhvn6LQi9r14SuZUvMZCAbqCMDxCIBTWWM4ZtGLY7djv95KsbTwxifdUrYtMBeZMGbf64DGacyClsg4e3dMZ0K/zKgej8yszsJI04UomPvbyqw1ao0wBPGT/dGCLyWGUIQJTylgVcTPGn8uzOQBszror7FNZV4uJQ5k3xCQ9zwzpmUjxgGedKAvkPlllC0tdmFdQ2FilMZCBkBLZiwwwJTWrjWJMRe3QoIyjaZykEDYNKSX2ux3TODD7qebD1ct7cph3HpS4iqxwQHtdgENFiLk8Q1OUDQqj1Uz6qE2RAxha7nSWObR3LbpVZNURJlV8UQ1oS9RaEuiVjH0fEyp7clZoMj4o8i7hS3CC05IKGqNiHIXdq43slb2fyKmh6QS0EdatkEAwPOBXKUuds4azkyXhiRtM08gwjviYhYVXgF6jNbfvXrC53Ei6vNYFrCmBTbHwSErN2C567OlSGuQFGGsXHcM4sZnEJ7we22HCp4RPianavKCIWpNKTbLby/s37AaaVurz9XbH5XpHSIntbhBvthhpmwBaM6ZEUjCGQGM0737rDZJr8RlcefdMAcJUzqiYxBut0WX/Iven7Rxt16BisWXqlrTnHaYV2w9MFkCMWseU+j1JSrM0swRfiJVAkOQ6Q9bo7DhJdRTp4gUsDZoSqS4e6ytDmya6VY9uWrQ1pBBJk6gxsmugXZCHhN5FtMrEMJEmT5szbVK01mID9ApGLUCYV4qoLOJ+XmxodHlPsjBBlVJ4P9FYjdUt9x65Al09vmwgrGma2Sz/m77pm/joRz/KX/pLf4nv/d7vBYT19fTThxSZmzdvziyxp556immauHfv3hVW2M2bN/m2b/u2L/dUgEPhFgOFUnug+EsHtMhaQmbZ2isd3kRhQKiyyOmMKbR+RTGhzVUWVve0B9Du4JGjyiInPiXOmVnDDOJz5JSj7/o5DXJ1suLk5ARrZHO73W1ZbzZcrC/ZbDcyMcQj/fw8QdZCQHxtjDE0bUO/6AUA61varpNrKJ4Y3nv8GPiVFx7jJ3/qOX76o89x7/5xos9x4fRrCYJlvv5r3+AP/b6f5m1vfYXPv/Imv/KZPdutZ7OeWPQdi8WSkDI++cIOu2QIE5fbHVEpXOc4e/w6y8fO6K+fcLl7jv/hL/9Obr9y7cu8lgcBsMM9GSfL1Xv05V+nMRPf/cd+iKce/wR37215/dWBuxdrbt65pOsWXGw2c8KKaxe8cWfNnfuX5Fz8B3xEZSlIYhZkPBVeQspVJngVAL56SCetscKiyun4SvPhv/PxbwgalMgzh0Mjm3hBaeLxvnnutFbwR/zHalGi50IkZfBBzttaYZn0CycSrazY7UqhFgMpCbjdNY6msYyT+DrFkGg7MZPf76Ubtli0jIOADUYXA8YgHV9jS/lcCiitFV3nGHIWaR0iOQMIRcporFCefYiEqZo/qjJMDkWJAN+ZHOXZVAaEsyINSHOT+hHvmKpjTjpObd+iTV2Q8vxs0HL/G+vE96vct7YXyV+SKgayzGFiTi0MJuPAtYq2M1gnjKi+bwXgy5BjEm81LfOJtRptIRZWhfEC7gugJxI5uTcChqYgcoEK+FFAixqjfvCBAZ0p/1GZWHUg5nmD3zgrxWVMFAsIrKlAg8LGRNMaxlEV8C/PXe1jqr9pRNpri+TNe5G2piSeXkqXIl0bfJAkRxWiGJLa6s+TCUGSTE2h+wuLRjYrWkemYZqBkMYZutZhjS4bAFVYZ8VLjoNkSimRrjon4FGq9y4mkk8zs1Okr+UZADrXLrwpAKCAaDnD5EOxCBBpp/g/yPjXRsIZmrbILTb1Z8EZGZ+2+Fh6nzBO3oEaCOGsKn51AlB2nRiBxwgxagGprD7CYERSNqWJpDoabWbWakpiWG70ATxSSjxjDkAU5NIJFsDClHj7A3ugHj5EMY0lS2JmAWxzPDCwjsfiYY4rzKziAUMJiKjr/CG8I18BieomsG646qarjusHf78CeqmwGky5ji8KgKEKqFs2lE6XcIM0G/sKWFgae1ERcygsT2F4zU8iiX9PPfc69eh8MIt+FNumHhJdL+BFiIlQGCrDNLHd72Q8xSoZyuQYxHfEHJgmFDBamPICQsWc2O12nJ1dL2tDnccKcF3PqQIH1HtapZccvU/yk3XenH9HHSSfKRUfkQJ8mSLrVFnutfeecRqFYZPTzOSr0/BVw215/tPkWZ2LP0y910pVINSQUHjvuXXrFvfv3+fpp5/mq9/x1ZyenvKJX/5lPvPpTxNC4Pz8nN1+z36/54nHn+DGtXOsVsSyQUkxyvxuzNHfqmFIEiZjjOZkFVgud2y3Xw4D/mjcHY2bn/iphxMh3/PuuyjkMX3sFx/NCLMO+r7jzZtnD33v/e/51fncU87iNaozIWfOFqdkHYl+YH3/HuM4IPI1PYM0lPeiMromP83MvivXoQ/vmapgTd3UxYgPh2eZj9bzBz5EavxZdli7ZOXImZwUVLZjymTiFctWpTQ5Rmy0RB2YWZhJZPIoUE5jnBWGjHPF+7DB2QZXJGTOSbPbGGGzNE1TCAJqZj+iYH1xKQbzxpIVxSd3zziMTONIKAwQsc6I8/2pEJY2Bmss4zRQAuYBYbI/CIZR2FXaCOiTy6fMt6eAYrWBdyAvHBqmUv2U+fcRz0DeJSPsXXXYr83fyweQfE7VLj6XtvhRVmlznbO1UiQl66P83iOef+bKtc6NkJRnO4fyY4DU6SkJI/6YuSbNqhZjWtpuwen5KV3XoRTstzv2my0Q0TpJOnQZa3J9h6bK8VxWATIfAtvin22UwrmG3X7CR5m7lFKMk5f6Jh6YziqD0jL+agND9sQKo5sCVEVCUgQSbVs8rVAobRGfQLEmctqU2igzxUiOgehFPaWs1Af11irj6U4WNG1gmkbGaUQZQ0gJQ601ytppD6CpOpqEnTWcnix47Po5wziRUdy72JFKM9O5lmE/sF6vUVqzXC7ZbDeEFGjGAWsUKSs2m32RsCvUyWGunO8x4qeWi3ogxsh6vRc1QpR9htWKxln6tkUZw+ADwxQEhAGSNVidGceJi82WjQ9g1GzDEMu9n7wnBc8bl1uuLRraxzqWOvLafpQAiJRknOejxk+IhFEa/crIe2Z08QJF6kJtNNm6I2nD4e2scLNSoHWtmw5jeSwSW50zLkPIihTt3IzO2mBSlj54EgWEUS3EACuL9qOkfjuHto4xRIbLjTRhI/gAkzKYRccqZ5TVTLs9JkEcPCkkXLbEnBlnVp4V376cGXNmzBKaVueoGCM5RXwyElr4hbbDDxz/0vF/OWfGceSrv/qreeqpp/ixH/sxPvCBDwAwTRMf/vCH+fN//s8D8MEPfhDnHD/2Yz/Gd33XdwHw+uuv88u//Mv8hb/wF778v12NUGMmpETjdCmQqbA3qRRXrXO4ouOvb6XKEas1WWu0PkoRyhDygVpfje0yYtjnivxRlQ2x1oamEapr2zratrniK2K1ZdktWfUrrp1do+kaMdQELteXXF5ecrm5ZBxHtjvRiistCToKRfBeCsNcjYcNzrU0i4Z20dL1HV3f4ZqmRHrLSzsME5/5zBk/8VPv46d+5jlu3T4UJc4G/Jz++GsLfjXNxH/2Rz7Gb/stv8KtW6/w+q07fPz5wHY7MWVP61q0E3pmVIl7uzXb3Z57mw37cYDWoU47utWS8yeu88yNt/BLP/8t/PB/9Y1cMXD6Es5FjmMAjPlrqkSX5Kwf8f0v7fPf97Uv8p/+xz9MTje5f7Hj/kUS8+oQ2W4HpikyTBtu3blkCgFtLOfXzlnvBnb7cW4OqayoiEpIQVgEpKuLNQdZ0NX3X83/l0uyhnRYZId5RZaTEYNCVb+T55qussGy0qSoS7e/ALWpJJLVjUJWQGXAiFRG2GCUDa+wcExh0ixXLf2yJUeF95LGFEwBcopXl7WaYYiMQ6BtDE0XscoVUErTLxzjOIjRfAUeBJkRM2aVIMqCqp10+GzpXPkgvjMipSueFFphrMjUpjGKL1m51/NGVCnxqVo0TFNAG2EeGGtkE+OR7uODVdPRs5F7K8WxNZbF0haWzFX/ipyrtFro0KaY8Wsl/lpjpctlikwjk7Q8QeugbeQeaqNp24YpxsPmOJWiEjEzjz4U9pgAkZXlUcvcXApKY2WjYMuuNGVmeWjWktakapppzMRcGFW2gDQpziwxiu9YKpuVlDOGArJxtHnXwuaTtN4CmBkB4VLMZYyVhoFWpbslz3cYJob9hHMWCLMsJsVEViK9arDiy2Wko2qtdHXrMxJJQmS/m9C6MEyU+Ff0fUNXPCJyjCIzLN5YGQghEUuhXKX9xgobASXyUFXuQS5sBZuZ358UxYheer9xBlJSUojMhTkGPNWOH8xymRyFYWCdgMopyNyiXIEHsmyIxDxXmjuzF43WIv/VwqRro7yb4vHh5U8Ve4KUxEfEGAU6EvFgGoyqyYMHSVqdoY7nWH0EFubj4q2CQvoAPIEANTqlwtpT87tWmT8z4PTAZizNBqv6oV5HZYlnlQ/+OnXD+eBb/Iiv1c3TMVNMlw3fcdKkQjbs87XMnorMAM18T4ya2VHBB1CV4V4YqZU1dnSeOWV8SsVJ8nCuWoHJ+pCiVW5Q3cDVn4uFGV+Z9nOvA9lg7kdJALOqlYRPcglmOZiElxeH2oHWsqiRyUzjILI1pdA5E/1R80+QvnIzisSXwjjLAs6bwjQzRsCEWfKYDuBevQ855blEmOszK8bOwGzCHpP4paCLoXexyIhRNsC6gGgxylxgGzePrfVuojHNzH4mK/b7PW+8+QajH/nar/1a3v/+93Pz5k1Zt/qe1WrF+9//fpqm5Ud/9Ee5d+8e4/gMbVPg3RSL1+dBqpoKg5qyJl1cbsgp87kXn/6KQTD5/MM9u3X7YSXGc++8Sybz6c8+zuX60VYaq5U0FPb7h8OIzs9283Opm3mvPF2/oOuXjPs77DZ7NttLaSwrdwiWKPNvTQSNJf1THzVAcsqlDq5McplbhOHA3PCpXyPnw7OShVY+KMm8TZ2Lq9fqA0cu3QR19A4fH2UlKuBXDSuqc3Kpl5Ji8iNDAckU4insTINtnFieGFOAMvGWapyjKV5jSklwQ9M0uLbFlsTgnDPLflEsVcQP1U+TyJiCeAOL5LzA9KV+M0qDlr1NgaQxJsz3vSa21UTNrBRHM8yV65e7eGTJX2vWI6+urA7Nh4fvr8wZKiuSEva8Ic/1SgUU6pjSWtaxSnqYgaO5KVvAsCMW6LH8/fjvzmB5OgLClCKHTMoFADr6vQrYai3G4Lr4XLmmo+06VsslZ2dnaK25f+8ed2/dYbvdANKcy9lfYYBprbGu+mZGaqiEPK/y94yZ6wljJLl6vd0Xw3ZdwGJJ2k1JUsmtBaVSAdA9qrDpclYMU8Q6aYN7XzwZk0ZjmFRhxZda3hrNctmx6BqUamReTPEAspS5u/qYxiQpk23bsd9umaaJfPTezHJlpNBL8iDKS1QAKqVxTcP5tXOm0pSZgnhpx+jxQQMtF5drusWCx65fZ2kMd199BRV3tMOIVRC2O/YpY08W6BALU1DN+EBNPp8mj/eB/eBZr3cMe1HnOGNpjGLVOlZtQ0KzHQPj5HlsKaos1VhRSRjD1gdub3dF2WTxPqL0QMiJKQSC91wOnlXnyDHgome/3hC1KlJaJ4zWJIBpnDJxNxIVKKtnz7eucZA1Vgk4lZKwV2tjqAa4zC+jQmrw2mjVgMmYZEQpUtZtlaGLQiyKSfZmWWWUkXdNiPrS/I+tw/px9ntMSpNyZMgDlz6ynyJJBdAG3bac9D39yZJxvUGHBMNEGAJ31zt6a9jvB1IKWFWk8Dmzz3CZICYBAZ2SJpFLCYxhZ0wJlPsXH18WEPan//Sf5ju/8zt529vexnq95m/8jb/Bj//4j/MjP/IjKKX47u/+br7/+7+fd73rXbzrXe/i+7//+1ksFvy+3/f7ADg7O+MP/+E/zJ/8k3+SGzducP36df7Un/pTvO9975tTJL+cI9cCMsvkJPGZxaOlbJ6iEt+aVqkrxad8V7rsMqEYJh/mzXMdNEZr7NEk6ayla6Q4MMULo+1aur6lazvaVkAu17g57WbRLzhZnuC0o297LteX3Lq8xW6742J9MTPAqnEoyIQwjVPpMmQ00gG3xtC0jpPTJYvTFaZrRd9sLTGIh8CLLy35iZ98Dz/508/x2usHKZ9zHu+LsWj4l8ZAv8wj8dt+y4v8sT/085ys7vLaGzf5zIs7bt+8x531JYt+wRNPPC4T5DBw685d7l7e487lfbb7PVsfmMiYk57++gknT1zj7OQd/I9/8ffw6ief4MsHqiq/6cEjFymkLApf/udmlAr8Z3/4x/iGr/8ou92G7XYsEj2ZrJbLrrBRRO55594ll5c7KZD0xHo/4kts/INSnpQSvpiHXunMlWuKD2pdjq4g5sTgpwMjYQZhDvHPWR18bx78jEpvF1KqsFuUgoiGJJuEI9rBwYi5GLJK0VEkzFrenxgi4z6wOulEplc2o7p0PXP5rBgTwYuULCYYxoTajAJUhSQglNIYq/FFKhkmATqk2ExoDNo4QICIECNamzKxC0MlBfGNmH1lkvgtpKNG8IxpyQPCNY6ma0gxYUT/R9OU+G+VZibFDHqpQ3oRWlhwteE1DoHlqkWpiFJlcbNaNnv6MH+ldIAOpKiUjlGVRh5kWZRkqgrG5PJsoGtbMZ0OpfAqXWqhSMvPG5MLE8jgnJHNpcT0oADrFEol6YoXJlIoEZ1C7igMkFzYgrVTpY102VNEFVZsZW6FEBknL0blNfHyaKyLV6MVejkCfolEMaHw2EZYuTWFVwR5YrjqvczvfddwK06QCq0+QQwT2iq6Ls0yHKN12bAniAJIxZSYJs80TaVbmYosntmnoxqKi1+H3A+RSZUuLOKF1thqtqxQORMm8RET7EyKDGHfy8YkjIFxCAIQm8I4TKXQzFmkN1Y2e36Ks2S0yjogidQFaBpDyLJFyQlUUgV8ixhLkfYXll2W+xBjeaZazf4XfhNIOdM0xeC4+HSlmFkupECa1ESrO3pT/KSyonW1cJ9EAmqKofuRfMYUP7eaIlk3trp68iR1JSUMDgyn+hnHc6SqA6K8NzHEq5ugB/a5IQYUamZPPIpxeyybPD7qfD1fT60plHnovBrbzH5hu7B75N9JMc1SzC921GJ3Po8CXlfPnXrEVE2lD4cu9Y41hzXBh8gUKsutXtvhGh+67vmzgFTBdpnYj/YZV38nHSHxION93hxTfJesTJ6lW38o7CtTTOGcKyD0YR2rDJwHmYH1e/VzqgRXK00kzoz6kAKDHwrbUpiYSmfpXMfI4ANN286g6v2d54mTRhpAhQk9+Yn9fs/5+TlPPf0Ur7/xOv/oH/4jxnHkbW9/OylGLi4v+ZZv/hbe/uzb+exnPss7v+rtLBddAXPT4aYfnjTiYSVMUK1lHlhvvjSD4C90LPqDJ9Ennn/YCuLJJzYAfOqzXzh0SJJ1AzE+DA6dLMW1pTbvUhbm6cnqjGma2O+8eHVagzBya3+nzitJkh5nMObI8iALG+gwT+i54ZCRuvrgE5nkmZafN8ZeXeRjhBzLJvJREBjzz1avz0cCORQmqPCDD0B02ZCK1FWjjMYHjx9GmXOUJ7qACSW8x1rxu8kirzZW1CCNEwaPtpamaYgxzYCZ1oa27TBG/IO0LkB5qKBWLA0YP1/LOI7knLBdi58mUohk0sGPagbQkigYbIP3gRAHudoHxmnK0pTR5fnwAAg238NcLBUeAUjVd8tnCRNqiBg1VzRzCmz9VV2aRxQQXuk8s1OrH1rShybI8Xx5fNRxdcwElXFb556y/yxzrMxNEYXGOk3bLVDa0nYdy9WSbtGTc2K72XPv9l3u3L5NShHbldTxByZ3pWROA0lTnBl8SvYPXdvi3FGybMw0bhTJnVLz+NJKhGSHUSwNvBADk58KI1oBFh8CxgnLeBo8SkX2+0hOO5FFZmk2JqBpHdY1dK3F6JaFS4CdLQEkZdXIXrY0mVNM4snbtPitJ0wTTePIORJCZjQwpQUqZkxh/6XSTJ8BSW1ZrlZcC4n1dsd+mEgk2sGKwfo0cfv2XVpjWbmGG+fXuTm+yP31iF/f5anO8LhS7I2h9RN22JPMkqyPPGKT7FXGQcLK1psdl+st0Qd6JwENS2dYNuIbPgZh7W6HiacXHWeLBVMUWXvOYJz4Gu+85/Z6B2uRQu6DZ+s9Pkau9z2bjUP7ic/enrh96w7rKfDkE9dZLXuctQzjyG47cH+zYx8iPoOyluWywzhL11jatqUxCZVHlgupX+o4b5v2yA/v8N9VzaKR+VLZluPZO+eMLkB4CKHMx6Ao3og13TUj4JjVECMpazyWbDNe77i/H5lCAiLGJlol6aW2aQhdCyHi2obFCm6FiG4cfWMI44glM+zFpyXlzJRhLKpYpxQLqzlVDpMdO9ewn8ZHvtcPHl8WGvLmm2/yB/7AH+D111/n7OyM97///fzIj/wIv+N3/A4Avud7vof9fs8f/+N/nHv37vHN3/zN/OiP/ignJyfzZ/zFv/gXsdbyXd/1Xez3e77jO76DH/zBH/yCkeNf9OSVobFuXqRSziVCtWwRy2atJnXZIylFLhOrQjbEAOPkCUXPbbUY5lfj/ErbNcayXCxQQNf1oDL9QhhZTSNMMGutyB9XKxpX6MsZbt+8zauvvsp6u2a3Fd3+6EeUUnStdNZiMZ5LxXy6puJ0XUPTWtq2Ybla0C8XNF1LyODDxEsvGf7pR97JR37qXbz4+UOBYm0klFSfCoL92h2Z1WLP9/8XH+E9736F9XrNnbuXfO7z93j51dewreWZx5/h8cef5Mb1U87PT9nu9rzy2hv4ceTuvQuZXJQiG4M5W3Dj3W9jvfsAP/A9/wHkL/d66hQ3wzrz109WI+uN0MzH6Su5T5n3vOtl/rd/4u+RuMflesObdwbRqKeE1paub+c0LVXAnvVmy2Y7FD+dRMy5yDLy1c1GziLlrcla+RA5nrN449Ro9VwvEQF7Zat+YKXELMycVjdz1LUiEx4BotVDK+nCRQSgkQ2TbEb3Yyidm/rTpQdq1GzSrYqhoxTumXEf2O8CXatoO0fwif12kJQYLTKAEBUEWXhjSsicJrK9/T4WForQd8dx5II9KBiHiWGYCouHGXRLWtP3xVyyJEjuB884hJkRFibkHPMXSoG72knRRtN0jvW9HVpLWqVsxgzdokHpgE9xXiBSKoCKqp9fmCilS5piZth7UJKUmUuX1bSHhB8ZG1KYzklrScAbspiUa6WJXsZMLX6lA6VoCrikVCnGm7IpFEoDOUUWC8c0eHL2OKfoe8fQuwLayebDWF2oyFKOVsCnbk5zGcO5doCrwa6qm1gB3Yw5MP40ijAIIIkrr3g+yGhqypVxVgw9g2JMgZAS4xTwIdFnAV9c8TxxjQPEe85Yw8Lq4uuiSEkYuz4G9ruJbnloRujCCCPW6yhxK5HC/JNYe61kI9e0toQ+lMI5HTrVlWEjyZHyLmptcFbkqtqUdEyt2Q8jfpLn3ugCKEah4YQggLDSsm75MVANkJ3RWGNZrQzj6NkhXc3a9JO/WQzOjaZrFdspoNH4FMmjFHLKJWISiZvsGYT1F6MAzilnGmeIbcMrr9zCWEPwkeWqwzWGvlMiuygeGhqY8HgdWLkDC7kyhazWJPUwG+AgVzkU7zJmBTBTFKAsSgJnTdBi9hJiBpjrR8zyb3UAcY7BqnpckSWrw9eq8fIVeWUFnsrm5OoHHRoWlRFW5+zjc0o5CVu9vIdXWLpf7Ch/rr6HqvjXWWfn70lcunRRq/Sknnco8srDdVfWw2GmC7MXSr2PhXnxwMZfmBmZQsUqP1rYYSDPpbC3OHo8oIjVAkIJk3D+ufk+FxCv1HZKiUTGVjYpV0EupRU6Hzrfs29QeoQESlHe1QPjqhpkH8tijx5Z8WctKcAJXOuIFXhzjkNIoQy2EIXFvWyX5Jx5+eWXuX37Nu965zu5fv06n3vxc/z8z/08zz77LG9/+9t54ZMvFECCIokR1lEdykqL7FvGjZxr4xybzZ6nnvpF4Lu+yKD54sdqdWi03bnzICMss1zsyRleee38C37GNMGwH3kUavvWp2+XJknxX7KWfnWC0YZ7924RpoCz0FhpOmiVhcidDnKwaiCulJrVF5X9U9exmfmgCiirKNI1OY+UNTUsRWTtDaNHwLAoqfCqrJ8ZN69hjzwqUPkoICyXZpwSyfIxCCu4dgHstCaiaExDjFHAPA0pBGGxaU2MgXGcpNYr3l4ilS3vRwGDbCMAiTWWrusx2tK2XTH0tmKvoDVta+kWixkIs8bggwTA7LZb/DQxThMxStJciHFO2gzzeq8ZhoGsqzwwkaPMN3UeKNy60qx7xNx21Og6rhFqYAXIDKBVwqMhZ9qS6yzNPQFcKP+OWR3VpFKzoFSZWwr4Vf0d1aNBsC90HM/3VfpZWVwhTGU/51j2juXZNWLKtH3H6fkZbd8yjSPb9QY/TsIyP2I/X2WXPSDjL3Pa8fddseOJSeaBbGG5aLHWFvA3lxCiSfatSuwYtJZwsXk+K4Cy0YZr105pm4bJTzSulzTWIGb2i9YBSRiGZd2MSRGSA23IRQXStI0k93JYa7yXZrn3E/1iSdO2bDeXDMMWcot1lkhGkZj6LMnuZY0ps768B0COGWcNi0XPcrGg77dMfqLdNex3A/v9yM3Xb9NsBtLdS17ThmkYePVTn2WpE9P1JW8/W/BYb0jRk3YDqesxR/fcWkPXNlgroJdOgbTfY5SY9p92LaeNSOKHIKB62u9Zpsiy61guOmyK7CPkvuHJ0xUZBAjb7fAp4mNiioExSvBDbx2Xg+fW5Z5/9tJ9bt+/YLcfeOzGOa1zGK3ZhsRuO3DvzgWX+5GoNLbvGBNcPz/jcqd4bLVgFwN+HHBTI/55tUn0QG1RsRNKrZ4e9X5ymGtB1Ch1vawMy8RBnm2dlRTTJP+vksa5yIjFtQ3aSn2sjZjauwKkGbVgnAI5ei62ntMbZ9zbTUUZolg4zSYmpnFkyhBKLecULAycGSBGFlrRNZbovjSI68sCwn7gB37gi35fKcX3fd/38X3f931f8Ge6ruNDH/oQH/rQh76cP/3Iw87RtHnuvgMod7UgrS9RymIILhNiQZoReqgxmtWio6ZOaiVgmC16eWcdbdtjrWPRLUVaoxTWGVwrmxnnHKenp2KCv1xhtGG73nLn5h3WF2suLi643FyyH/YPJTPt9rtCxRR/DGsaWtfgnKVfNKxOVyyW0lHo+p5hv+fllxU//pPP8hM//Ryf+szBq8Fo6fLEaGYQ7Nf2SPwvf9en+ON/5GMM031ef/M2v/irW6YxMI2erDLv/7r3slwsecvTT2KNou8aphBpGsN6u2Sx7DCXa+I0EZUCnfjMx76Tv/sDv//LPJdj8Etd+fqTj28YJ8v9i5715itNy4z8iT/2D/ngB36J3W7g/uXIfhjFSH1mxmhMVrStyAR8kX5crLeYxmAaw6LR7HaeOIm3SqXxz2euRMKSCjNlnszmjYmwmmYF29F15iudoMNnhhQkIhxoEdXgo6ZAaxXOKpFHxUTrhPnRNiIRHsbxaMMCaI12UpxpC8qowiRi3pSnmBmHIGk9VNP1XJIZC5vJJFRhZ01jZJoCKCMdWl03mAo/TXKlOYERQLu+37JvOgAtpiTo+CnOkq7oq6RMPB6ON18PF/JyL61NZMSTMEdhszhnGYfStYuK9cUOlMK1Vq7DSxGWtZz/NIXDR5Z7Mg2BbRZzc+OkUCcrnEuHkawgEwhTYVEU366msRjT4p3Fj4GdH1GpGLUqUzpcApYpnSEGlHFXCkGVMyplht1ICoGcAzmb+Q+7RsJItJW5r/qGSEx2mvcC1XtHNt6JWeZZCo0qv1Fa2FttU+SS5RytNjObL2kt7DGYzcuNVgUsnWavx9EHWivJRalIZnIxfTJGS3FmDMFPNM5xctKw3wiAmLN03I0RA1Aon58mRu8JPmOQRDCy0LGV1iIdzVIEGSuy3m7RFkmBgFYxHRh0xxv1trG0jaFfOtpGzq/tlrx5845I9csQzAUAq7/btA6lYL8d2e48CvHuckaTBWWlcWBPG2KU30Ul8SIrrKu+a5jGwDoMZBAQWmemMdBbi7ClM9Pg5d1UtUgqr7jSNCU9L/jAMMg76BpDCBpo6JqAs4pcEiN744kqigeN0hibCwCiZhnnMfjvvZ9DcmbgKAkTNWvkuSsl/zsmhsmju4bGmLLBUXVqfOg1zhykLlCYItWbrjDeKqvkIDs/sHIf9DKrsqrWNgfZWs4YBFgNIRS2m5o3y7WjqikG3vkAQFw51yPgan5PK9hTJedRCtB6zsYd1n2tNESFSomo0hyMAdCU8VyPWMBbpcRvJB0BufPlKpFq6KP7A+K5Wpkxcp/kq5XBIuCWROvWNGM5P0gxFBmWogZEwIE1V+WeeQ6Q0NjFEubO9gGEqJs6DOioi6RKGp9RxSub65oAefw1Y4yAFkfP/ABcHgN/IhNpizytHtdbgIBSjST5HT1LHzxaaa5fv87Z+Rmjn9hst2itWSwXGGMYR/FWWfYLrDJUb6qUggBDRqO0wxqw1s3Sqa5pBXBJif/jf/X9/Jn/8k/zlRyrlZ/B2fzQ+gcxSjjIL/7Sk4/4bTmeevKCaRge+b3r1y5LAmRCG0vf97TGcHH3Frvdhsb1tM5CLL5VWqNJhHSUAK1L86BpDl6B+aoZO9QGSmk8KDWPF6WEgavK86/SSqME7BKmsj7475XPiFHGxYFBWsawsShjHnp3699KR1YrD77H9TxJCULmOCWwSicNstb66OdwERUjSXlCFnA75JLkqqtfpkjmjLVoJSwRZ52sM60Y8zvXEKKkZgv7NtK4BmMtfhKmUL9cFmN+D0rNKpWcpZYN3uOcfGYikULATx6fhHmWCjhuNeSQSCHOwNeVo6wBhYiJUhBSLsFQBQjLCYwlYCFFGgogcwxAPjBflTstwL2Rnzv2fhSm0WEteBSr7/DRefaDvtIEKN/LRXp447yn7U/IKPpFz2K1oGkbYohsNzu2mw05JfrFQvag2QtwX0HSsv4cJ4w3TSOM+1KHz82VOreiGIOn7zu6En4qaaoBbRpyVjNo7mNkmEYyYueDkvpn0YukzyAkEIvm/nbDm3cuuFjvaduFmN8Xf0ifMushsFhCaww5B3l+SkmgUwkdkSaWpJ1PQzGRt0bCMYr9ibVGWGNBlFk2HUgDuaA0VaWVy97KOUffixLLOkvjLKPSTFPg9t0LntCWbbrPfrPhmXe/E2UtJycdu5S4sxtpuhZnDFOCXVKcHD3QxlqWi47dqme93rG53JC8eJrlGMQKoLXYrkXHyHh3g/eBdhg4aVuuLVeEFBlzZBs8HUIeePHeBcMY2XrP3st60FpHW+axkOBTt3dorVkuevEfs8KGu7/ZcOfuBRfrDfv9wDQFdgGmzcg5mieeeIq3PfM0y9WSGEYJHYq7o9rzUa2JB9+VL35U0lJtNNXGbyjpukrXMVlYtkpYy8PoefrJa9yYVqDEjkYawIWcoMRzzk+BHAO372+w2vK0F4XIfrOnaxvuZAj3MxlPp6EHVgauO01HpleKJme80sQvkWD1a62P+1d6hJBAR8iqGHpHki+KdOdKJ4fSqWUuYuWQyVWj6OxBgz9vFFEYpWlcQ9+Kyb1QCq1srJ2jWyxo+5amkY3FarVktVziJ8/63pr15ZrLC/EAW6/XjOMoQMaRNAMoiWKZEEXjuuhbFsueZd+zXC5Yrpb0ywXaWF59NfPhn3yCf/pTX8PzL7yVmkCnVOLZt92kbQOf/NRbf42fhNzPZb/nQ3/+w7zj2Zu8cesOv/Qrd1hv94w+oIAnH3uMkyd6nn37WzhZdWJYTWa784yTmIhKUohlHKXz5aeGf/gP/xIpvI1Hv8Jf+HzkuAp+XT/f85ZnNrzw6eu8eevkUb/4JX32W5++zZ/+z/8aF+s3uXPvkn/2U0PxUgnzyy0bz5Jm48R80lkjiSLTJDrnSYrOcQqEFMWEOIaZGThjWA8obyqwCxlHwtcOu+KQkC29xqtAWEHQl41ls5OJy2j5naZ8u2Yk5QIgOKelk5czi76jaS1hkrTKaR+FxVM2Q8pYXOdoe+lmxixAQAbmZmpZ3Ma9FwbLyYKcoV200l0ZPMbqIvWQRV8X8LrK0R6F2Cml8KOkJbkC1uWcxdevkTj2GDIhK7rewRRQ0VNbh5JWebxtscCDE2kGgujeQ0TbhhQEBIox4RqhuBunaa0Vpl9K+ElBa4vMTIz5b99ai7s+UE3oVdlUxyCdvLY12M4VDb4wJWLIoDLDMDLsIsYazs9anE60jWMq2ktrFSEKc0vM0uX0m8YKcKUyKXkpnpE6vJk7KHJN5AJSKHAOdrsB59o5qTDm4ukQKtKpClPHHDroou07sDyoC68UW43TWAtd27DoOpE5xkiYJqYxlPGiZr8niDgj4M92L2m+MWWy9/Rtg3MGRSrsJgFajRGW2qRAm07A99ZissJPmUl7lHGkJNLEWjTEkBiHQJgiViucK6BihqY1NDazXUdCSLSFBRKCAJ4iJyvpPiVvQ0VhGBut6JzDtZpu4VitOjKG3XZPCVecj+jlc8QfzqG1MIDGKQpwnsFo6dRqDSEErIa+NzSdo2kFAEvF28FYQwgiMep7y+X9if12N88fTQTrGmEkZvHki0UWqopnSesMwWT6vhWfj5RnCWMI4H1i8hFoCF6Yq7E9gJ/V0sdhmVTG+4kHekMzu6C+29LzKuMsF5bakfdXzCXlOYsBbsWxa2E2gzZzG/zorc4Zo83BQDodNsxVVnpFGjNLwA9sIzKEpGl0cwVAqT8fCFeea/2btXM+B+McTTXHv1/BPWMNFPlrPY9qxj+DzUddXWESqIMcu3y2UgpXE3OrGX7pClutCyNP2PCSTDzPDGRSkdFmchKPO6tlHpn9wZQCKgNMlaRProS6aK05PzuF5EtogTt0rjOz/E2pkgZYkl6MbRi9JNqpUt9RmK91M5lzluI8He6DVXb2/KKwTkDAwqxlbMTCXK1BDbn+/yOaaSklmrbBtsdeWIUpo6U5kxAfSWst9+/fZ5xG3vve97LdbPnVT/4qr7/xOm3b8oH3v5+zszM+97nP0Xc9JyenGG1EhuJHYhjFm6mkFOqSbDsMk0hzRs+wn9hstjz++Blf6XHtbBSmcX54g6SUBHj8yief4NbtFVofpNbHx3bbMA6PrteeevyO1OTa0XUdfdcTgme73bDoGtoS5hGzmFonFCHDVCYI8ZMTELPtBCj3o7/KUKhPIiV89Acws3z/ePwdy6Kd1cSsQVfv0ToPGLDCuJSbMqPCqKMNXwiHJOnqUza/w8dO1484UhSmTW0G1XcexB9q8pMk38EMFtVz0IBKInV7kLMm4IFlvy0ySWtLKI6wxJq2JaVE2/U452Td1Bpj3Byio5TB2obFclVYRWmWWgfv8d4zjZOsBeSSApgKGJoJYSKnJKyyyUuCXIollbE00Yodg0LeoBADofg/H46MKkC4Npo8N4Wv3lijVfE0fPhe1HFR5dCEIxDsAe/J47FSAcqaNHwciiFMGLE6OD09xXUntN2CfnXCYrWi6zqGceDu3Xvcv3fBfrejaRyL5ZIYPeNmkLmrNIGrBLXa+YhNgJE5SkEs/qDVLgAg+CBAlzGknPE+zMnPi1ZCcDLC/jFG4WzDKjuZR5QWwNQabCNj4PFOgJykI9th5POv3qLveh67cYrKnsZJkh8qMk07rp0sWBT/bGMUziiImZA8SiWaRpqb07Bnq6Sp2bQNIfqZEa2Vnr0Yo88km0tTpADQVMsiCZdyzrJc9IVND8tFzzQm9mHHxX7g7nZHpxTXnnyc9a1bPPX0k+jo2e42aJ9Z4Dg7OWPsFlcawiLcE/LC2emCYbfH78+4myP7/chuvyfnzC5EGieqruwDbYxcWy1YlHmJmDFZ4bA8vuj47M37LF3DFBP74GmthF011mFQWKUYo+L8yce59/k3OFksaBpDniJv3LzL7Ys1r752k8v1ltEHfMoMWROtpfcTTatZnqxKA1HIHWHvcRZsY4r9zkOvy9VV7RF7K1FtKLw/WLwc+5pqpYv/+mFNVUhNT3l6XWdZLoTwImNRQG8JA9Gk0uwShc/E9WunpBTn+jHFxH470VjY3Fgx7nY0KdGRWJG5bsAET68N037PfnnOm/FLY3v+ugbCphQgFu8vBUZJLPcQPLHo/rURQ8OoNFYpYhLKsdF2jtqshsrO2rmjZJShb3pW/Yq+7+e/aduGbrlicSIT3GKxZNH3hHHDdr3h5ZuvsN1sWK/XbNYbdrvdbL4tFF7mNVSSyoT903ULTs8L8LVcslwtWSwXOGP4/MsL/sn/9DQf+Zm388Jnnp7BL4Bn3/Ymq5M9r756gxc//+gEn399hxQE//Hv/wR/9A/+Km/evMmdexd89Je3fO7FV9ls9rztLU/x7FvfQtNYnnnqcW5cX80b8u2umJIfFS5t03CyWnDnzjfyt//f/wkCRPzLAWBKRd71jntYm3n+k49z9/5XaiSb+J7v/uf8W7/5eT7zmZf41U+9xBuv3+b1W/e4c++Ss5Mlow8YLawNQboP8rHzsyUYzaJznJ0tWG92XGwGNruJEGQz7Y82XA9d0gNfUyQMiahKrW8fwsuOjjrwFCor9sOhXDp2S1NAUaMROUoT0YpWN5LC6IqZd/mInDPaSsG0WLQsVpV2L2DJZjcx7APTVLubMlkGLwCwseJfkcoGablsWa8Hifv21ZciCqxn9FENemBWkEWmuOp7Mqps4usmp3hcNfKXkw/EqJkG8f/RSjGO/gqAIxvwgFIPS6Hkbzva1tB2jn7RkJV4PgFz4aa1MKiMtvS9sHhsMTC9vNjTOIcvwZragHUliU9XBkwmBvl/soCR0xDwU2R9sWcYPE3ncEbTtY7WKSCinMJrkY1FFMqI10rKUeSMKTFuPKDEqHgSeWIIiaY5MsgvRVZOpnghNvRjMUJViAdV8Q7ywc8+hllJCIHcxyhWK7maxot0s4KsOQdCSHSdLRR/ud8xCoAaRukQGiuBJMZqWiNU6n1jibkUvVEKvGHwtI3cjxQCwUeCS1AW8JxVGWuJrrWMu4OZpoQDSJVgjGaxcOQsIH6MtQCPaKswOrPscvGPEwaNNkqAz3xIoVuvJ4bBH8yY05GEz4i/HVbjVSZME7thwLUCjMRSoOcsY0SYfyJD3G0G6awDlPTVTC73QuSI3svzTo2mMRqrNLtdZLsbiHGL1nB54RmP5gLZCDh0KXqqP1FKJbEoK1xnWDQ9I57r188wNnPv3rYwLivYmbAmFzk1CK6UZ3ZVLey1Lu9kAVTrey3f13NRpmdgpjS0ogdtUEdAdc5Z/P5ixhjmjvkxC09uVy4tAn3lvVb64KmSc4ZwNMc8tKM6nKfikHBV5yOt9EEqcPT1YzAtFVBPox/67PlvFjAoxaPgjHRgNYRYUuiOClA4SHXqz+Us407kaLJ1tBVAQhUppGzsrFJlnip31wgDssojU06EJGwNkPnCGul2cwTa6bLmCG4grDBB3PMMxOV5cEMOEzEnlJa5I0zirVmZZ0prTAUmip+qP+AR8l6lOMtCc8pM0zQX6VbLRksSuBQhFWYNRx5hHCwHtJL5SE6vsJOUmjdMscjEmlbS/o5HSJVPlWwW+r7niSee4FOf/hS/+PFf5Nq1a/zu3/O7+bf3/zbb7Za+72mahn/8j/8xn/n0Z3jf+97HyXIhLLYYylgpbGktPoSgZTNoDL/xfc/x5q1L2RRnAS7+u7/0l/l7f//b+Pv/4JvmEUixGq/H2dnAxcVVNvwTT+zJKbPZNofBWI62kZr5wz/xLgCMeTQQZkzicy9de+j3IXN2MmBdg7WOrl+gjGHab+nahuWiZ7cXXxeRlxpy8QcdBwlwcfYgCaxswXEambwA8nVuMUYYhvW9qyzOyqKpz+n4HHN9bx5gbqEV1nWg8uzDKT9WvIuyXJt4RmVcK0w9pQ4yeRlFAiwfg8HHc4sxZn48dUzO8k6lykT6aPqGyMUPcre63TBKNtgKCabgyDbHWFOAZ7le8SQVlvhBdqlp2g6tNZfrS/p+Qd/3WNfIfFHSLq9fu87FxcXMrospEmMJmfCelCPRR/nfxWdsmibiFMTEXxZxcmkmRaIYjR+BUdKQlYo1KIPHoZKMi3pUKR2HUpGclLD9j++dYk6VnBsdmblOqVYUda6uYyXFJGCiO1ioaG2w1rBqe7k37YKTa9dZnizpu47Je+7fu8frr73G5XqDMRbXthjr5kRLSbOWa62AqLFmlqO5xoklgg94fQBMqyS4Ps/BS5hBfZ529vnM4oObysVzCJTQWoPWXI4T0z7itGY/jmQtgNXpsufayYphEP8+24B2ipURi4scdvhpT7ItXVPM/WMgpyDN5SxNOq0l/C2nTNd38367rv3GGHzwApIm8fC0rloTHaTuM+s6BjQJ6wyJwJRHmqZhGCemELi53bFUsLp+xru/6YN0bcu4XnNx6ybbe3e5bHrOulNO2oa9KvNjFhAsl/u3WPac3zjj2rUTbl474/atu9y9LfY3u91eZJJ9zxmKsxvXuHF+Rt/LnLrd7rl79z53YmDM4serjKHpeq53C8YMUxL/QKMNeT8wRbh5ObJaLYgxsVp1nJ4tGbRh2Oy5OUTWXjF6xeAzgcRCK4xzXGz2jNM4M5TFjmGP1i1aSS2rpH9y/BqgC/GH+oYc/uMKzGytpTItUopzLXts+1D3UdZY+WV9qE3a1rFYdPP6WOdY8SustZel61pOT1fsNruZFTlOI6tFy3KpGYYVKiJ7uRDQIaJDxBlHDAF77x4uCjvzSzl+fQNh3stE3sqEXLsQKkkhqLSXqFJr6JVj1bZStJZYWVseRjV6s9bSWElq9N5DhrZtZ31t07b0yyWr8+ssz65hjOHerZvcfeMN7t+9zW6zZr/bMwxDoX7Xhe5wzillvM/4EFHasFquWK0WLJZLVicif2y6nk9/9hof/ltP8pGffhsvvXzjynU/+7Y3OT/fcuvWGS+9/IXp6f86j7c8fYcf/Cs/Qd8PvPraLT7687d54427XDs9Zbeb+Oqn38473/FWnnnqBm1ngQRGmCwA+yE8tLmYJs33ft9v5ed+4a185eDX4ff6fuDd77zDpz7zGC985rGv8Eozj9+44Ac+9P/BmJH76z2f/Mw9Xn/tDp9/5Tb3LjbcvtyyHSfWwzj/dQXzZiKnLGCJzlirefm1PU/cOGGYAuvNyG7wxaurdrAOPhaPOh9psCeEB3kV/OqslQjjDKp4IFT0vXyyTPRHlGvyPLeRlXSLhGWiMbYk19iSTOM1sSTh5SgbjZzF+8JkzRNPLBimyNlpT8qZy+1eACGnGfeRHAVgy8WAPITEer3jmWdusN9PeC8SSGsNy1WLD5FxKIER2hJCIReo4vtRLiDgITSYZStMtKMuX5npZ8nl8uyE4GUB9SYy7CdidGXoVBZHTXqjFNvpSppP0zb0nSXFiGvMDIJlQCUJA7BWTHmd07jG0jQGpUQCO90SQ9Kp7Eti6S52vWEc45GPj2xQKf5vTWNYbya2m5G2bTg56+j7hcjEdaJpFCHAMAjw58cggGmJjN7vPetLkazsd9UIHIZhT9taVicti0VDsqEUggLcJcRU3liRUiUfsWQaayRFJ0t3py6EscRLi7QkzZq6upG0pfhS+gDQZpXnIIikIvtxLOweTds5AQmzeAM5K7LEqoxy1uBDpGldeR4OpS1KiyxNGASuAKSSMCx+kNJdbRrDFIL4iGlpogw7zzQEKk0m5UDKYI2jdQajYEoZ4xSNEXBtv/fkNMk9ClLcCtNIxryyCpPKmEqInHISOWOKmaazSP5LHYccTLtDLLJqVcBRGRtaF5nP0fQXUp0j5PnlJMDlsPdz2ICyBm0iMYqssWnNXKhOo2W5atDGorVjv52QJGPHbjOy343EKdP3Dd5HTs+XAsalSN8ptrs9YeXEjJpMaxs606GzSL1QGlVAR+samtiR0lSCcdVDhVL9t1YSahD8KAE5+sDEyVnW1xATNl/1CVPl/2ozSispPB9MgaxMibopmdMk4QrDq35elaVUFlNNp1RGYTl4fs3z7PFGrP77mCWWMtkeMUGibB5TkcSlcAhLAcqm7GEGQ93coQ7+eiLpLHLMAszORW65R0c5A1eOo7t39esFNLPmqsTy+JnIfxd2JCJbrRugqyz9I+CxyEnJmYwmzQ2xwsLISgxza3CHEuA3pzD79IGY1NfPNNoQc8RHL6nLRa5m1EHSFlPEBy8KAYTBEFNpRCDzWds0ZLJIU3zgbNEf1AdoIMo5zmMn03UdzzzzDDdv3uT555/nk5/8JO95z3t47rnnOD075eLigueff55Pf/rTfNWzX8W7n3u3AG6FBRf8BGRsadbW9MvT03N+w9ed0bSOt7/1KZrGsd75mdn7H/3ef85/9Hs/xvOffI4PfuMFP/5Pn+Xv/N138HXvvc8f/SOf4Pv+6298CAg7O5d79qsv3GAeiOU4Px/w3vIzH30WAO8f3XF/21sv+PjH3/7Q1432QEAhyYcoxbAf2O0GTk6uNiidsWgDQxTvXmmGabKRMT2OI3koQSnBz0BYznn26j1Iag9SV6UOiYLyvrvyLkL2YQZd6/iUcVm8HWvgi74KwMt/F+aEdbjGzQAGFNZoLnNB4ooUt37Gg4EbuTLPbAXchSr8oIdPPrxk1NW02PDLPedgFVObhrXAjCEW6Vr5rix1wk4v16i1nVlkSluZr9uOtmlwzklavTHy31qTfZ7B6KZr6fWCGENhyxUQMQtjO/ogCdEpMg6eEAM+iNwxRpj8iB8nQJ5/LEnXUWlxCLNOJKzxAVPsVIF4OaLmihE6UBjOpuwBD4ngNZ21HlpbtHHzPC6WCMJc1aWx2TQtrm1x1rLoWq5dO+f02ikpJi4uLrh/9x6vv/4q9+7dJ2bForfzM1GFWfcoxnGKCayAYK5x8+t4hZVcPqPKvFUQEMw5W9KxodXCtMoT4mU4733L9SuNj5HJB9brPaTEvm84OVmV5pjm2rUlt26vCX5itejwSdIOG5OxJrFdrzEK2kYAYB/izBQPscqTpaFQE1+1tqAsMeyZxmmWee/3a8Zxw/nZKaulsLXi1dejsIOjWGs4J7LyNNJ1p6itJivD3XGiTxH7xk3U8y/QW0VrNA2Zt1474fEbZ/SLnjFGdK7PQBGPxk7bOB6/cU6MkfNrp7z17U9z881bvPbKG1zcuySSiVrRXTvnibMzdIxMMdKkzNQ6Ns7wS6+8jmosqmnAGkLTkqxFo2hTQiUByXTbkEnY1mF7R8qRYBRD6xjHwGbwTClzf/CMcYZ5xY8PJFyp2j5V5qTWxOCJwWOdo+2WUGqfR0q5r/7H4U5kMPoomCFRPIrr3CIFqDX2Sk01125aX6nprvzN2jg6YnQDJXxQALVFL42Ik9OOlMI8p4Yx4HcTYQpMu5HkZb0cUuLeF5DnP3j8ugbCRj+irQBZrhjJiUQEIEtHyWiMsfTG1a9ClthfZ8VMsmkkecWWf4MUxG3bslwuWSykA9J1HSenp0wJbr/xGvfuX3D/zh122w3jOBDDF47qjAmmoIhZ0/WO07OG5bJjdXpGv1zQtis++emn+PBHnuEj/+ytvHnzINszJvKur3mNa+cbbt0+49OffZqXXv5ygKJ/FYcsyt/3vR/hd33nTV579Savvbbl7u0Nr7z2JjlnnnjiBtevnfHe91znscfOWC1a8f8gl46MTLTD6IWgUY7nf/U63/2//x0CRnzJAFgpEh7ieWaeevKSx2/s+aXnn+Bjv/SWr/BaE//5f/LTfMe/9YusN3s+/+qW2/c2rC937HYTkp2g2U2Btuu43A/zZFSPqQInwDR4trcvUUhy3WaYCDEyjNNDBdBDR5VKHbf6KIABV4GwIYSy+VXF+6h07bU9SHhmrUj5r7qBFoyMECO20SxXLaenS9qmYRw9282emBKX6y3OdsIASQ6fpAjpl47Re/plAybjjOZM91xuBoZ9mM9fUoREkinsDct2OxBD5vJiL0yWkkCilUIZLYl2c72nxPA/yWeIgaYUCdPgBUzQihwPhUWKUnhpA9Mk9HylNCFOKCNgSybPoB9GQLMYIsFHTExiUntUfKQo56SVKimRMr90pkggyaXDLIW1NhqbNb4YlBfLDTLCagK4dXtXPq+m2Ub240TMhsa3AlrtA65pmKbEfh3p2khUmv7slN1mhzFiZu6dZRgT6/XIVAx2tVazyX3jmlK0RNrWykZPGbSSAJIYM0rZYhqqcNYKw2qK+FH8P9pW5Bx+syfkQKdq6IdsBmvRLpvCXGK+xVunaTIpGWIsaY5kAfRK8+L0bEEIae6M5lTN2yUKXKksSZZI8d41DgkRkM2rUUrYEbl6DEHOWsyXp8zJSYvKfh5vxohXXd81JB+42HgmPxKmNHfSYkrEFNCqISQJXRCm4eGFilGkr0qJibY2aS4SSGLaPwxBmFs6M+0FlLZOmB7WFraiEmajgGTiQxa9fLZIxuS8hJFiJeEyA+rg7GOMRiWYxoyfCgtBKbSyxXz6AIg7p2laA0mXTZchZ/HbCFGRPFxeDGwut2y3O5SCxaonA6dnPU1j6TuLVrBaavnfWhFS5rQ95bw9F/p7kYAoDaZsMKy1dJ3BT/5hE/bDVHU0V8r9FFuBMBtmCwNDgGttK5h9tD6UZaOmkB0f1f9FKVXAU5Eh5iyFe/Ummo2sjwo8o7+0zuPx3/oXfl1xkGUiG58YSyfh6LqOC9rKboox4sfKRBTNdcxpZnVpBDCbfKSxBqMkNao2qh48BNSuXm4VGLt6HseHVkW6VDbWs3v88T1X5XcTZUzKuSqlidUnSal5017vjzyHq880pcwQEou+RUVhL4rcShL7xjTO3m8+iIxulkMebS6BGaAP5Z0LviZfMo8x+ZvF4HhxUAxAWaeqyXMWRtedO3d54YUXeOPNNzg5PeH69ev44Pn4L36c+/fv8+abbzJNEx/4DR/gN/7G38hquaJqhVNOJYXLlccj48BaxzNPPY62LYvVNfFRGUfcxf3CzCzWAFbxm77pVZq25ff87pf4D/79V2Vs5cTFxYNm+NA0soH61ReuP/S9Jx6/5Bd+8Un2Q8Pjj225dfvR7Pob13d8+CMPA2HXzu5zMHrXhOgZxj2pNPUOoEypwlIWRlGoc8bVsVbfwcY1swxScZSSW8EnebIzmy9nRYzCchRnhLIvKL41FQiT+x/JkyQv5ywhKsYc1COxJHxrpa7MCQ+eIzCn3tVN3PHrUM9ZFx+rcdyhtKJzyxksqesoD8wfwlKLkixf4bCUhNlVapFD6fLFauwCmMdMEb5xTCFT2qKtE080JfuutmlEHlqejbGaru/l3DthfzRNOzPktIbGtbRtS86UBEo55WEYGKcR8XWVmtUX6eUwDEyTlzk/RXwM+BggBkwASCWz4BgsLDUgZk6cnZ8rQNY447CNmUGw6Mcrd6npFljblOaBmRtJbevK+Mj0iyXL5RJjDF0vbJacM2+88Qb3bt/h7u07bLcb4WPaFqNr0+GqV1oua1edZ6S+cHSFRRNCKMneh7FV14kv9nRjKs3rOscpPQcm1EOXJqVCsd6OGCWAprGW3TAIM+xswfn5iifPl1zuN9y6XDPGRMoeH0fasSWzlACcXEKufJj9u62RGgwKC8wKyJjSlnEc56ZOjBMpimKhrq1HXMfDhdb6u3VklYgEkd9nadqMGYLWbLG8+OotThpL32ieWvXok2uotjvsg4AQIWkID9xEYeJKjd80jpPTJefXzri8WLPfDmy3O9JJy52Fxuw85wq+/u3PcueVl0jGcLJasEsJbzTBGLQ1LJfibZZyJoyeNHo0LWrybIbAjRsrjIPQaPZaM+wj62Hg/hikgV7PDVApMvpI1zYM40C6n3CNY7VYPXTLrp+fYl2L97JeTKO/wiAHeYfrVJvSgSX5xQ6tDvcIKD7P+opf6aNqhfr1+r3j+dMaQ47+ikw8Jc005VkCbhYNtrHs1yNTVgzWc8kZ99Y7uuWXFnz36xoIq12dmCI6aRpjaKydteuZTFIH+cLx0TatRM9aR+OaebGyTsw7F4sFq5MVp6ennJycoLVhs9nwyiuvcOfOXS7uX7DZbNjvdnPikXNXJ5aQMlPIksClLatVx+pkwWLZsjo5ZbFc8Pwn38E//qdP85Gfegv3Lw4FVeM87/3az/HYjTW3bp/zieefJcR/E48r87a33OGv/rf/gLZLvPnGXT7yE3e5d/uSy/Wap55+kne941mefOoGTz1xjcWiFf8XJd1xH2KJ6BUJVMqZkDK7veH/8qFv5sM/+U6+dPBLzmdGbY5+T5F49zvvsN07Xn71nDfePPuKrvZkueOH/m//AGXuc299wYuvrLl9+5LXXr/LnbtrTlY91YMqAVPMjOGhKXo+U6h+B4l99OQkHhvrkmqoSGh1SKRKucTYojBKgB6hheTSHQ8iuSmf/ZAfBAfUXQr1JJ3t0pG3KsqG56iRW88zZPnEakTeL1r6RTMj/OMwMewnOtsRqx9FLF1alcQcWcvEp61lmgLb9chmMzGOcZbICBYtHZ5pClxe7vAhoLVm8p7gI9NE8RuqXVi4Ok5KISF1ALpw45vWkmKei+hq/Kw0+KjIHpwyOOsYp4lu4Rh2Ea+SbDLKxksr8c9pnIGFFjnRvQ3jMJJzZr/dkTvphE6TUI5dI8EZYv4c51QUU9gS4z6yGUfGfUBbReM0BEmHTSGy3QTazuFRjFOmbUXiJxvQhPeRpCwoIwEfWuSCOqsyrgZcTY8qQIO1oEkS3pAyzgm4p7FkLaCMawxd25NzpGkaMTA1au4aGltkUolijKlorSUFhx9HQDzxfIhlz3pIjARK6m6VqNXHKeapuoKvIaMN+CzJv01pcLRVolWSsVJODH5CI+y4rnUs+obd3pOzSB201uz3E40zOGcOsjqYjYYjGWcUy5Ul5Z6LezuMMoQcRaIZYBgnAaqzgE4xJhotUtS20WSbsUqjjWMaYyli84GRqBRdp1GdnYGwFBXTGBmGIOy0wnChysmMhBBUP4ccIUxJzPdLeiWq+GPmLGlGqsoGFX5KrE4amqYEQ2iD9wo/ieeINSJxbVrHOE4iOW0rAGBYrRrGvWG3i+z3W4wrY2+UDYg2mnahGINhv50Y7m44Oe3RGvq+YbXIbLeDPDMnFgTnixVn3QpyAeILMJOjmKBKkIVB5YjJkoKprZVxlIS1qHR5B4sZO6Ywwa5IAMU7RCHBE9nU17l0LMsmlNL5TSWAoHahqzwjhjizlmbJSZFaVRnJLCeps9FRgeejFwnUUfczk4un3gMztoKk0kGqpYs3FVytWTIFzD80MWbp1VEHOIV6j5nBs1w8GlPZNIFsFmNSJcYcAcO0sEYf2SWuiD1FVqolTCjFAm5fAbgOYICA6XLCpia1ltS3essiUdLtVifCIsgJkyI2N4VlJ+OlxrYbrTDNoRaquIA0JXQ9TSGha1v+VnkOhbUXU5zl/MfHMaAosq5jdu6BWVPZZDlluuYAJmUMIQubLGYBgS8vLvnE85/g5Zdf5tlnn+Xbv/3b+dqv/VratsVPntt3bvNzP/dz/NiP/RjrzXpmMaUk63wMHqMMi+WZpPHFgFaKrms5Ozvl/Im3ME6B8c4dYvKcHTGrRFZu62O52qlHM40P15SuyWhr+NjHHwbCvvqr7vILHxMP2t/wvtf5sX/yzod+BqDvPa++du2hrz/91E0JSGkaXNMSphGjFGcnAhyMo58BUgG5PeMw4YPIXHTxfvKxgh7lQZc5qoKdunCiqrwwxFBSlg9jWxuLdY4wHYCeBnmfEr6wKKsstTTRyzhOshgKw7KMF9ksK5yymPKuWmcPz1KpOZ20vrPH5v6ZXPzp7BXMWNig8oZlpSmxFFfuq9IaZ7vZ+D3FWNIIj5iXsfhtGoOq/j4FWKZI/4zWV3uuDxwpBbLPUmcazbDbs91sCjtKattx3KONpXUN1jmMERlh2zTFl6yl70QKLGCMMC+tdaW2dlgnHm2r1YkApiEyjSPjOM3PMaRE8BPTNBKDJ4x7QphIMTDtg6QJC9oFMYrP7JW57SCd18VeIacKNpYmktY0bTv7ogqDSpFzJKY4q4iatmF1csL1G4+x314w7Efu3r3N5198ift375YBJynruviVQi51YpwBsOClpkYpjLMSLOPEI3byE+MwlnCnPK9RKGbpfPkzhyssz3ZKSTwV46ExecySrGti3xhOnr7OdOOE9WaLcs3MjL7c7ekai1KZ+7uB/SRrc4qZvc8YLffee892u2PRteyGiXEKs+IlxoRWoowY9gN68vM4997PDN56LVVZ9UgWEYdn18zst8w0jVd+fu0DTxpAZfZ+otEK061YnS5ZdB051fRR2GQD3pOs3E9dxrlG3nVUYd+jWK4WtF0rFiRBfK2maWJHZkojP/vqiyxPT7l85Q0WfUubwXQdpm8ZtWIs+5O2dawWLfgoAUpasd0MPNP3TMaXmjkzZdlPHMuqAfFQRMkeUWtCCqigsI0lz8Y3gogkDCFEVidiQTRNnt1uYL8fZgsnpRTO1iTTCoLpL1wXHL1PIFY3yhxJy0vN+oVAsPn3FGjnrjQhYoZczuOgatKF7FFqQeVQxuDskqbfo0LATZ5+1XNxf/cF/ubV49c1ENYveroiXVRK0TpH49zsI5FyJmZQlAGsFa5pWKxOWHQ9jTKlLte0XTf7c62WK5bLJV3XEWPkzddvst1uuXP7Dtvdjmma2G43ZdI6dNRjFEDEp8wUE1lr+r7nbLFguViIAf6pMMxc0xDGif/n//A1fOwXnwFgsRj4hq//NE89eZdf+eSz/NIn3kH8NwR+QeLPfu9H+Nbf9FkuL7e8/PIl+yFweX/NsPW85a1P8NxzX8WNGyc89dS10g1S1Mb4ME5M3h8MlKMAJR//5Sf4M//1b2MYO750AOwYCHkA0HSed77jPp9/5ZRf/fTjX+H1Jr7zO17iu//Tn2W323Dzzn3u3LvP/csNl5sdd+5uePPWPe7d32KM5vrZCcu+ZTcGHn/sGhfbHVobvJ8YxnFmD1y5giz01RhqkVso2DleSWcKWZPygwtahhyosNdxr+v4r8gCA0YFkMBZ6RZoSlqijM+6mT6+rVnJ34vJYowwnJqSMqdULmwiXa5TPImss8TkC7YVSREu70+Y1qIwTPvIfhsYdpHgS5GRpRsr558F2U8jfpINjtDfi6dHzA91KmQyLaT3+f6oufiVrp6wNkIOpSN+1dRRIYCJ7S2DH0g7SUFMgStMA63BOVOYE4m2d3g/kYov1DDIoj1Ngba19H3D2bUeaxXTMAkIZsvmL2fCIN08oxW7rZjKLhaG7XqaN61h9AIgKFXua8Y1FmMbmcPQ+NGzWPRMu4lhm2hcpG1lA9suFNMoJujTGGRjnDLLTlKhYqGqa6XlOgpgZ53IYDNZZKS2zKEpEsc0F9R1zFhnCQSmrfyu9oqlW86fHYlkjlKyCrFDkSGqMi8IIyr4Cec6amBAiolx7zHFq6wa86ssHl++mtYmRdua4qsnjRGlFOvtQIqB1aJlddLjlC1STKRw9gGVxTy2W3WMfkfbWXZ7T+c6hl1E6cxuNzGGEUlilMLYYcgqgVZMXqSowhzSxJAIg4CBbS8M5aaRohkSKMM4ZVRIaC2a2JQywxBoOk2OER9g2E0MQ2DcT8K8K6+AbPzKjBXlHxLwoJl2iWSRlFakMDSteK/5MbHbBaJPuKYBLWlfubDPkhNprx81t29mtI5onWkXBnQmThHvozBFMZyses6vLwheJpLbt3bknFktJRFw8glbGvC2USwXPa1t52AI2XAd3jNTTNavtBOUsAKVsuQip6msJLmVusgtrs4NB8Dj8PVjo/sHj5wl9dI6S/CHebv63Fyddw6pjAfJ1MNrWIxR3qGjboNC0TbtFSPmgxQnz4DM7FFGLiBMqmq7B06c+byrDElnTXbymcMwyIbxC7hGiv+jxrqOmBI+gispcwlFxBx4NFo2LqhI9pPMCSmhtOVs2dAUr5zp6P6lei0FxKwyJZ01je0E/C7BMOAJwTNs17T9gpwVqph2h8KGiyEW5kjZSB03wVQBcZvmKlOMskQo2YA648gqE3I4JLQVIFL85cLsURhiEGZJ9NRKvo4vAe5rGixzsmm5W0csHCBn7t27x+1bt3nHO97Bt37rt6K15od/+Ie5e/cu5+fnvOc97+E7fvt3sFqt+Ot//a/zwgsv8Bve/w24GcCNZe6XmlbBLP3Tpjix5YMsV871cEY1kKHWybMvS4Ld7uH68u1v3aKU4nQVHvreM0/f44c+/JsAeO5dtx8Awg4Up8durAnh4c9+1ztexjWSrDoNe8ZhP8/xADHuZrNvow3LZc9yeU7OGT8ObHdb9sNYNtaHP6vENV2u/uj+18TWaj5+PA/oJGl2tjTCySU1NUOOgZR9MXO/GtqhtTT6anBW/XoOwoK3SjFMUwm9kbmgzkGV9aVS8Skrit+U0xykJfYU4iF1nGY4b8K1Ih+lW9cxrovnYsyeY+8zma/EnkCCQBLGCiBWflXA8vwos43DQKp+bEpnmoYCPmhsIwz87WbNsN8xjgM5Z7YUdoexhwaCNTSuxdmGpm1pXIspRu3ONWWdFRPh1ckZ0QdyOc+2a1ksFozTiJ/8PLcIUhAJ0yhg2X5PCB4/TQzDKAb9MWKrMX+5vkxhsZRGDEqTgicHi09i9G2soeuWONcevTsJhQB2i8WC5XLF6vQU5xrW6zV3b97mjdde5bOf+zQ+TTRtz9nZDdq2QxNROdC6DGHP7mLNOE0En9lsJFggZxjGQB687G+VIUeRj4bS0KrHVBQldT6gXFOrNSEKeCh70sgUQmHSg0N8bXXShBCYSvJ6ShD2IidbrHoWXct2K9Lls2VHRjF58XOLMUMyTOPE6COrRU+MgcuLNcMwcKHEH68qqgTIHFG5ynzBaT3bisj7L2zr6iMq5+alOVueWd1TxiL516XxknOicx13726wRz6IUUNv4X3vfBytFLfvr4kqMeXIhMz5++i59JE39oEnz5uyT8pop3GtALQ6y5yZosirl2Wc1iOEyOXFJSlm7ty9QC2XvO/Zt/C2aeK1z7/KZrMjKM2yb7mx6lDWiseltZyuhFF/7+Y9tvfXrE4WnF074/b2ArKEHoQxMuRMnr1S64uZyCnM3p9KK9q+xTWWkCMpL8ubnAlRc3+zZz9FqueqvNsPzAdlry2fp7FOVBbpMM1SPTWvkoxk/3ClFjv6mWMJuAKUyqicUDmVvyUg/ezTCpAVofhxxphKUIIj60aAsPLZRqvDO1Ckn/v/f5BGWtsULxiNs5bWWZw5LPolx1Um2bZBO4kCttaiQsJGJJ3n9ITlasViseBksURluFhveP2NW+z3ey4uLtnvdngvk4VIMRvGKzdZ4VOxIm0azs66kiK5oF8saPuOtpOOTfSe3WbNMIx82zd/nGtnb/LBD7xA1wb+3H/z+/+N3Es5Mr/pg6/wZ7/nHwEj643ncy9t2O0GYSCguX79Gte/+oQnHz/nscdPZHemlXSRUmQKUbxsSvJhTrDbG/7qD34jf+f/+7VcoSJ9CefzKPAL4PRkx5OPb/n0527wiU9+JQBYxmrPn/szP8M3fN1nuVhv+MznLlmvN1ysL7nc7Ll7f8ftuxsu1js2231hvKjiubJiipnVshcmijVo00H5vp8m0eQfdVu8D3NKjpyBAEz1X4f/PD7NBMVwMgFTuRuy5TwcYogp3Z+UbfmpwoZSGZUDGZnIiw0PKOhaAQhcYyVqefTSfSy+ROv1wDREjNbst4FpTPPzSKn4rsSEwpYiCdZ3R8ZG0j6GIZKLeXfkAILVrVLKoGNm3AVSklREsWQ6ZnpUVlWe/24soJprACXm6UppUuE0a6OLR08udVImqgyuFrx1EybgYddb/JQQo2GK9BVQYvJpkxJgRytUBSZyLkWbLNE+RLabPefXlvQn/bxhDl6MPxWwXLYo7VmeduicSQr6hfgseS+suWkssjiV0cpgbYdtHTEncpCfGXYDugApWothtYCNwsL0JT337Kzn5KQtRYPIKjOZzXoSud1YOug6o40ATRXzEtC23PYsDKcUhb2VczjcJwxtMadfLRqmIcMkjL9MBTCEtUT5rJhgnMom1pRej9bFGFX8QHISc9eJeOi2Oy3pQzM7RRhYzpnqyI51EPWBGZICXNyVYi6Tsc7QNPJZgCSI5gXjPrHdjAyDgDkxB1BpBo2l+IplQ5OQNbd0dpP0qZa9MPZEeKclDdEntAXrUkn7EgAwqwCIT0kM4lWXlWIaIuMYBHzyteAs80g6zCfGaPq+JWXYh4CJCh0Uy+iYpsByYUEnxkm6ssposjHEJH5hMQdc4/BesVtLIisqs1w58TxpNOhEDBK3Po4TbXbEGCQMpDUM+8C1G46m0fgQiUHCAVYrkcu07QKji3cJh/dGZM2HjRpKYZsWY5tZfkSVE+lECgHNISG6/l71QLHWzOyCf+FRupMKdQVoP5Y/1o30sZTpmLJf3+06JlQBW4472Smmg2l3+XsPemdUH6+rAEV8uMvxqGPe+F+VjOUsnlS5zSV0Is7SmQeBu8pW9jGTnEjEAVKs73eR1Je1CqUwpvjY5cwwBmkSVIZWbUIm2VA701xZp1JpCM1j4fh7KRLDKI3JxjKO1VdMi3TdmBnAOzayjilhDDTF/uLBa9Ra46x4yCSVcLjZNzPEwjjk8Dxlfa8plaHIPAvKzCElT6FYdB2L5XK+mLps1XHiQ2Cz3eIax5NPPsmdO3f42C98jM989jOcnZ7x4osv8vGPf5zf+lt+K+/9uvfy1FNPcfv2bRkDxpb64GCYXo/KkpV7wGyu/aimu7B8W9kkHCWj/eX/7r2sN81DP//M09JFf+Yt+4e+99rr51yuex5/bM1y8YWtQN721js8qm575sk1Xb/AGMsw7SRYpWkKYCVz6370wtbSET0MNE1TGCyp1AWHUSPPTMAdNYMa9TnJBr8y7Op9U1rCXyqAGPw0P3trFjMBXRiYB6/fesSYMDljnJ7DRHKKkBLaGKZUZJymGOVzALzlpDlYXaijDWUN8yjrS50Xc0pFPSzvuVI1ifWwWZzBaijfvwqAX/EvVLVxSPmbErogEutU/DxLgfjAmJP76tnnDT6MEoqjZAxN04gv97Ie8j5NiGuMQinDXo+yOiol6bTWFK82adI0ZQ3olxf0CyEkuLYV+f+cYqnnd9YZR9cvyYsF292Os2unGKXm612vN4zThJ8kiX4qoKgwy64y8zAWmhZbvD2tLWNFCXO4bYT91TYN/aKn7xaknBmnkTu3bnFx/y63b9/E7wb6rqOhxbYtmcQ47TE601qF1aCRpN75/8oeoT6vcfKzL5qzpgCWsYCWeWbIaPXAnipXDzphcM8hRUWZoFRpGh49V6NFZVCXnaCgBZmrcxJlhFIMo2ccJ/q+nxVQzrWYUZpnMQZitJyfnzNOI+MgxABhnregFGH08zxJzjTG0C6WTH6aAbnlYikAXkjshkGCc5QkRcucH+fra0zDou84W55DtnR+zbgfGMepeHFrdtPIfS9ze+w63MmCaGE97RljJObM1gfurgdunBl0FgyhMhcrCJxSZshRlP4lcbkkNWGMoV8uuNzsubfd8uxb3sLd+/fxIfDMu97OrddusdtNLBonifLOYKzBNA3KGobtnhwDfec4OekZJk+jHSFKyvGUY6mJjlbPnJHUMjXPRcvlgqZxs9+W8RPRNmQlRIO7dy/oOlF+HCeJKhTWSC0fRF9KiJUpKg2y6TBtCYno6GxQlCC8h0kgB1Z+LExNoV9WlvUsH08Z9GGeFKak+H/WRmhlroKRpkUFQ5VI5GfWuDF0Xc+Xcvy6BsJCUHgj5nxdf1KSi/S88LvGCbPByqAVar6mtY5WWzrtWCyWnJ6f03Udd27f4eWXX+fOrdvcfPMW+2GY2QiubYSQpzWLrqXvGoy14l1gxLC/7TvavqfvOxaLnsWyp+s7rHUiEfSeyXumQSaIyQe++YO/zLd+0/O89PLT/J2//5v+DdzFjNEjf/VDP8rbnrnJuPfcuxi4XO/Z7WUittpw49oZZ2cLHrt2yulJJ9RJAyHAGJKY8cVAiIl7Fw1/5+9/HT/4Qx+g9J55VFH0hc7n8LPqgX9n3v01t/jf/Ic/y5/9b34nn/rsV5L+mPj2b36NP/s9P0ffJ/b7iVt3N9x8801eefOWvPwhsd4OvHn3glfeuMvdyw0AjbXkDJfDnu00EmNmtezY7ifatmG/G7hx4xoxZdabNdNmQyi+cb4kH8lVlM3svJQ9cPn16nOCfADB/AM/ckToonrflV+ELJvtCuRkhJBR/RW7znB6Kp3ZtjUoqxh2nq7TrNc7Li5ECtW2LWGCcb9nHMPstRTj4S/PhVky+DEzMTHsimH4DBpJFy3PFWCG7LDOkAsAZkpa2GHDnEpnhpKQUzy59LxHFgBGSUFnKwBeFsqYqs9WofgW+vlU0vBiFFBEKUvMgW7pCJN8LcVM0UrKqCl+M65xTEmCNKw9GEBOUxDWnRIGmELhQ8J7kTTmmOk7C/0h9lmRsK1hsbACUKXMfhfYbSd2u4kUBJjcb0c6JX4ROdXFT9MvDNMofl1dZyV11Bcg2ksKaU3MXHYNi6Uj5sjF/R3jENgONZkn4ZrqY5JQSphi0ySJkjkXc3EjLEPITKOHKJHpiSBjqGkwVuFOoOsbtpdyHWTxHJAUwMxul0QyXjrwCzzGWNqukYS0ktxjTPE2inKOsay+WgsTLIN0PJWkyaWyqZDxIePaWoW1s90OurC3MgL+1mO/q8m+idFLnLcgnnWjoYpEVH7Kh0DXNsScmLywFy2ZvjOkrIk4xnGUhKcxoEORL2qFtpm2N5KimvLBlF9Jx81fYY1mVJZnLqC6OviuqeLrZMSXLKaMSrIBVEstoKWXRNDVaSfXYEoiqJWUof1ugnXCusw4yjgfw8TKdiy6lkhgv5VUWzG9lXERfOTsrOf0pCvMSNm83bs3sFy2dH1DTBqSSBqTSpjZuxCqKe3xoUC6nbVILpNHLn5ox4dWqsj/VDEQvwoy/YuOhzYP1MZEAbdCnNkgtTtpnb2yWU0FTA8xgIJFu5g/RxLTErYAGdZYQhnbx5LKeuHHQBjAZtzR6Z5q1p+4ympTpfDVRs+/P39PHdJvM1m+b+om+vBzKcPk42wlkZIU1arO6bZ44NTNV5GQoEX+HXOeNwje5xmEPJZE6CMm04Nr3YNYn2wEhc2y6Bcs+p698hTy43xdzgjjMSNNhlzBt1IQ1/+tjlh7VUIEVz1Ijv3f6nnXzXEuoFgNvUEVlm4ByRTgimm2w5IV7Kf97H8FEENgGAYUCufcnJT32I3HeO6559htd3zqM5/ihU+9wFe/46s5Ozvj8uJy7qCHOBGDsNPU0Zid5eJFYlXBHmtkjFaZC+XvVmP64+MXfuFqCFM9XnttwbPP7rlz52GQ7J9/7G0A/Hv/7id58aVrj/z91XJflAEPv49f81V3aZoOU2R7ptguTOPE5VYSwrIyZGsZ9xcM0dP3C5xrpKlw3Fys72sUs2mjmcHBygADiqG5EuZjGcf1XqgCxsQo4OeiqzWlNIUezSSV9RE8SsvGLiX5WylqJl9S045SIysjqkogU06zOiAjkqdjM+mAjF/xysszy02VlN3KCMkpyrhQpVbORdKd6rwg/y2SQwEiJIVVgMX680qZItkM8p7LUiMMen14LyqoDwnvB6Ypsx9q0mF4aJ4+HHXbrMVCA0mx9inNG2KltKRva7GSuby8T9sv6BdL+r4r8suaaG0Ke0SjtT38GwVa0TeOZSfS1ycef1zWUyrw6WcwLJX3JoRADInJ+9luoN7zxWKJsxZlRKqolWK333Pn/ho/3WGaRtbrNcN2hyKW2tBxfnrOZhpmX7dc/v5Db0Wu89sB2J8KIBZTYj+OjJOAZ1X6f2WtUw9+XJ5l/jMgX5o1dS5T+sDjMdqAozShMzlHWpXROZCnPSp6lp0jofCTZz8MNM5hm6ZsOWQ8DsPAqoUY3ewP5ydpGkjqtwCIyadDOjhiNL8oYJAuXp9ZO0LSqADrrbBGXdOhtS0NTlk9RGZq6buO62fnaCzT5YgfBlpnsVpCAi6mwOV+QNuG9XZH4yzXgySAp5yYYmK7L8Ff5Tk1TUNT2KuUr+Us6gCltXgXAxhDjhEdMzaLp1zbt7xx/x7RWaKB+3fucPrYGdd9oomZk8UCrBFWmIY312s2Fxui93TFciXnjNMWm4yQLZy8e64x6EER/SRdXiWJtl0n0uPDO1rqFO1k7it1bcoB11i8l0RXX5rrRksTYZwcKWe6EkI4ToGTZX9loOU4la6PemD8yXOpnl6qqjJTlNTY4K/MEaKUOtRjSgExktFXmLiNc1KPl/cErdBZobM+8j6EhobJCEuycy33wuWDb9sjj1/XQBiIB4Q1DV3Xs2gbGmOxhWptrEE5UA6S1iy7Bct2wcmipzUOhca1LevLS15/7TXu3r3DOIyQFHfv3uWVV1/jmbc+Q9/3qBCwxmKUUCCHyWOblnZpWayWItNcdHR9T1eSDlIW2cV+N5REMvn/WL1JrOVv/U+/mb/9d7/51/iuyWD9/f+r5/ljf+hXGMcdm82eN24ObDZ7hsGTY2K56Dk7W9J3jmunS5bLFmskOcwC+xgYgxju/soLS/4P3//tvPbG6YNP6Es8HzjgzFfBMGsjv/VbXuR3/46P81/++d/Jf/F/+l08qsj6Yp/v3MSH/tzP8g1f9xr7UbTy49DgjCWFwMV6yzR5ukbGj/eey+2OzX6YjR5rZyWTZ4bAfpzwU8S5AWssKWuatkHt98hyr0o07KFYyuU7+aEFTDZ29Ug5oYu4JTxwlyq0GJB4bK2EUi2fnYrHRJ5vU4qFRaVgddJy7bzn2mlD21oSmYgiLCGGzMlyIWARSsCVaZo7q7UrKxsHjVLHU4jCT+L1pNUhvYws8Ilsho46uimQszA5YjhcnaIWqlXaWQGIB2p5LewQpQ4FZOOk0zV56RSTknQ7cyG0Z1+eZWS57Ikh4lqH0Q5rDc7GuXCsf6pSsVUB4LRRRC9SAgHLZHx4LybqkMhogo8M+1Co1IphjHQ+EiJzAe8aYeicXesJPuJag7FS2Borfh8xip/Rfj/hrKZvm4p10rYij9muR/a7CV1SP8cgBbKxIle2DppODIK1UbSdJkzivRFCYtjLuqaNZhwCaPFvixFSkMLfaJHooCBMUZg+SbFctoRJGH1N29EvGxnfSRIcQwHl6qbCOU3Ich9UK754AuIFKZWVMHyqt1rKUWSBSmSfwctnVUbRuJ/mjrnWZp5CRI4S5udnjID3OWWGfWDc7mg6U4pQXVJSDWqSlCoQ1lXtRGeKZx/M0hyVYZoSnVMsO4fRCp8cKapS4Iq/i2vFe2W7HpnGwHY7EoIqMttcGEaFlRIEVEq5gp5Hc8TMABAwcLm07AZJvVQFCLCNYbf2+DHT9o62beg7NYMhxEjfddLJzl5o5FrupzaqbFLBaiPBEiWtzVox5E8ps98HujbgWoN1Am6Nu8TJicE1SgreIOmWqj0YjFdAr3YhK9BNKTKlUXhIIlJaz40DWTMP3lwpZ0IsjEgjz698h5wFwJm9cB48yiavVkAVrKrv/gyGlJufcnpIWiVg+4Ft5b2fAX1lZS0Tf7yDrDjHAzOkfrbRB6lflevNY0eXZMqsZwBAak81m4fPm6IKqJU155iF9iD4k+LMqxMQM0OIGaMzVtdk7YO8rzJxcgUyOWykQDzrnDNX5udMxldT+kc9gwfGdj23Konp2k7m8SwghdLS6NSa2Y/w0OiQP6xV8ZAqiZOuSNNR8gwjcf4bs9xVm8Jmvrogz8EMsvOU6y2bIK001lgWywXOujK+MyYn0A5jJPhHG/GaDMEz7Aceu/EYzzzzDM8//wk+9cIL8/r4xBNPADCOA23rUDoT8khMnhA9IUwCFEQBKmuqqbHSEJC1ubxbUVJjQdJ0pZkbIdXnKvf59/++F/gL/+cPPPRYfvhvv51v/ZY7fPKFs4e+9/Ir17E28tv/Zy/xF/7itz3qqXJ6OvDKq+ePeuA88cSOzIopeBKZlBW70bPfBfaTNHiaroPoiUG8IFOMjGkgek8sxvmhMmNlgZB5zxqpwVJZgXU++P+FSCoJ1+HoHdbqYFp+FUgvVVZFnB4YFzlHiOJrquaalbkurGB6ffeubEwLizSm+NA8c2CayhpQ096MsWhr0TpRvQtjEM9ZYyUkBlVZbvKJek5vk5RLY2zxDSvAVpTGzzymofiaQg7ie3osMRXMQx3Nv0nSV8NVkP7Rhy5zsZrfFeFzc2jyFO7oBCjlyUNmHAaCH5nG9sC+K+Cdta54kDUoJabr2liM0uwc7NsWYxSuKf5kxfi9aRsWyx6tJcE4+FD8+MTCQuZnAX3Ozk7EqqTu+4aRy+2Gu/cuuHv/gs1uR6ib+xQLWGU4bUuYTrL4SXg0uqwLKbuy1qd53KUU55r5oXUmJiICKoiv4RdX1Tz4LI598eqzV0f/zgibyWhNY7UY6xdiAzHRmQxWk5TGeyc+fimisySSC/ss4oOkr++HPXotQQp1Lq/AnLWWfiF1t4D3UUBfrbFazcuBKEfk37v9gDWGpZLk9cOFzlMzzllOlguGwc91St2DqwGmFJhS5ulrZ+jCLB5CoM1S//kQGWOib1sShtWifwQIVtZrVRp2ZU3IhWCjrMJqR7MYpcnoJ1YnqwLCZq51PaSRVdtw4+wM27ZMJG4Pe/bjxBu373O2WnDWNGyHgdPTpVybtrSNI6NonGPRd+yHiRQGMqEkYBdvPevm5l099zFrNpf3JGDFGRaLFu8Du93AZrtjGKbi+SwsSOcsIUQWi479MNC2DW9/y5OcrJYycuIkPpVUoPXQ+BLSeNnn1T1Ulj3YgdH78FGJBkq6fiT0XCsJG1o9tD4Lk0xYYakyp7WicY34IGeD018axPXrGghbrkqiY9PJA7SOxtq5OFRIWl7XNSz7JSeLpfiIWUeKgcv1Bn9xj9t3brMr0seUFArDydkpT+VE13UYawqzwhaJDtjWcbo6Z3myoutbidNtXGHGpNl8bhw93oeZYiiovEzIL770xK8xCJa5fn3NX/srH+baDc/F5YZX39ywXu8YRzGz12jOTldcO+05P12wXLZFWmBE7qgyU4QhJnbTRE6WV97o+KN/4n/+FZ2PgAj26N8VDINVt+bf+5afZHnd8v/4W9/BP/nI13yZn5/49m99mT/3v/tZjAoMw8jt2zt2w4SzDePkGScBqEKMjD5xudlx+94lN++tuXexmzszwBWjzanGbGcBj0KItE3m/v01bd+SURjXMPkS1/4Aq+HKUqUe/GItrDIBjqGjKz9eCM8FmIsCCmmFKQBY3SikNCurMFqxWFqWS8ti0dA1slhEwLcwDQljelKWJL9hNzKNYhr7oDShbvKPO1SyqRWjbCnkEjW64mHCRuEXPYAICrvLysYlStpRfZ8PP4N4b+Q8Q61KlY5ZQQhFDiBFZSott1RoCMZIQl5G03SWHJmTHkOonQuZyGNMs3SxmpK2raVprGwwciqAEkyjZbeVWOppioVFl4tsyjKOgZpXF0ISf7HeCaClFLvdiGs1J6dtKXhkIUg+YjI4pWhXLevLgWHvUcC+dLJQmUVvaBeu6PotSknKYUahjQAH1mgWC02Olu06FmArzV5FxoygMtMYiVHN3lQyKg8Fv7MC2p1fW7K+2BFDYR8Wic7qpEGhGIfAZj2y3/uSXHTwkIpR46OmReGniFbQFOaVGMIXYlBWpUsLOQbGvefYr2fyXgArCxIYIY0QXTbOTSMbm8lHxiEy7BIpZtqpGo4zAw1WG1JIGGtYLDsJxkiJED0QZ8lFTgmdMm2DhBSkzJTkHinUbLpunPiPjENgt/Xsd76kRh6K1lzBsCpLSV8Y6Nda0TSSVpkSLJaNsGZixCrw+5IoWxiPtPJOGS2eKsHLuFRA3zq2NpGSpu0tSQnT0RiDL6bEkjAl49c6eeZ+Sux2noWCxcKI1CQlCaBpShhFYZFR54dcZ7Uyf1VAqLDD5oTEI18cVZk6Ss7dqJKkSX23pcB2xUg7R2EYUDbZxz5dVyeZek/EjyTnAoTpAiqkA5tKbjrEHGeDfWAGaBKiN59y8QUsEskH0y8pe71qhl/HSfXx0kbPf9NoPQcDXPHbqCynI1lpLXorExXF3FG29pAWXDftMcajDZ+sDdVfxOTiKWXNDLglDgnEFbQsSN1VdluZbw+gm3h7aJUPfiRKJOa5FK8pHTzwrDlc4zROIu/MkmI8S1PLxj4U4EcepYAZuhTL+cgTLpZzijlSJTVwCD+oz6UCFBW4qNLI6rUkwFNh7ZTfd4UxYI7ugdaAdcK6IdM2DY9dv85LL73Eyy9/nqeffooPfvCDnF8759bNm8QYeOyxx3nXc8/xxhtvcHFxn3d89VehdSLFiawEMAkhyPgubJ0a+qDLWKtyzpiiBO6UaaTVhoxIcJU5NJRyznzHb3+Fv/J//1rW6+7Kq/GJ52+QM9y6dfXrtT77zd/yIqdnEy9+/tojX61r13Z88lOPtquwzkh40iSm5yiF95lhSqRcn4d43ph2waJtoFhNxCxvSkolAbrUXykltLU406DQJJWoXavKFJVn+/D55NJ6rO9TSBPOSJqh0gaVDJkDMHEVLDvMZjNDU11lduWcD/uR+pySGOmn43owZbLOVzbcucjwqfNcTYtFaq8YpPmUAR0PzK86d7m2P9gRAFlrURlwLO8+bPJVkSmqJGyx6oUKB1BYwOAy95Q1+Qv5EB7O9gEQ7PgzlAQtVbCxYHgyt8co5ukGfBjndzQXJoqs8RZjHFo3aONQ2so6ZTKdMzRWYRvxjnZNg20czoqvorNOGl+IFN8aqcF8FhP+4AN37tzDB1+YnCO73Y71esO9yy3b/QBK0feS/kdO5AL6vHHnLn3XElIgeE+MvvxsT247ApaURDWwH6KYyo8j4zQdUiOLAiKXuSemDDGL+2/xZK7AZ46ZmAT890Gk7lCfrawnh+CPTEZjiowtFZakLiACGXYHT4ySzG5Q1uEjDIMnxYgfS5miNdYgHm/IfL3b7Thdnc7zaYwS2GQK8GwNaBRTedYxxRmkrUBuPbyPjN7TpWqUeXgHc9kbGC02EU1hYTaNo+8bgnSdCd5z92JdWF4ObS0Rkf7FlAkJ+rbhxsk5Z2dN8WY7rLHH8mrqnHEMKhZSgNOGfuHpup7gPRfrNY8/doPeT7x5seZx1+IKWNtbh9XQ58SN8zN5T3Lm5sWaTOSJx29gCxBG1kxewOi2b+jHjhg9ftIzkA0i360+a5UZloCLywtiCKxOT8QOI0xsdjsu7l+y3e1RqsoIfZkzNePkuXtxSdc2LHqRJrdNC0ajlZ3nnqseYKUeUdKwmeeeo+biFzqkQSrPKyfzwL6wjPcrc3ghZaBKLZZLgq/UQcaIOvBLOX5dA2FNIxG8crEyOVSPAJFHOtrO0XcNi66ntQ0pBDbbC7abDevNJftxZJimuQgyRjZW/aIDfa3QzWUi7fqGpmtpW8fiZMFiuaJfLNBaibGr9/MEWiOfhURUda2WmFp+4K99O//4J76O4xf6X98h1fef/TM/x7/z215mnDwxJG7e9rx5665M5hnapuH6tZbzZc+yt6yWDdZqYs4Yq4hEKUSiMF98TAw+8lf++w/wt/7Oe77sc/r6977J7/p3P8UP/Y2v45XXr3EAwDJvuf4S/877/jZ/75//h/y/fvx3ftlXrJj4v37/z/Abf8PrbNYb7tzZsNvt2Wz3XG63XK4HkYVMnsvNgNGG3TBwsRm43A7cub/mYrNnN4wPGTLPV5APG2f5dxb2xOUleqtRWhaEupn8F3fM5ul1/leap5mrh0Zf+aoUkBnbSPFUGpykpOYNDkphjWygT08arFVFWgTKiFxPk8lTRDegkyxINTlHlQ+9eh1yxsJCKgs1Utyoei0PgHy1ODwGPK92rCiMlLpxToffn9tY0hmr3UopMDMhRUYl11WNjOX+SGEo3V9hWjWdgFjLkxayItRCsBQfCulEV2+tlLJ4kllhOLWtZrkSA/pxGNluRQq12w1l46mK11kJP8iZnFWRZco91UZkAiFIaEDOqjCTwJ24srmVh+THIrEr4Ng0BYa9P4wtpVgsHdOUUTbTLcwMFBmtcU6LyWSStMa2NcQoIQq1ux5DZhwkJl4poejnVJlKVamWsVUimBLGibSk7xqR5hWJHEaM2NvG0i8cxqrCiJWfcQayOQJBsrCHBkSa7ENJ8qmkDKVRWoBXrSgMQgngiF6KrOihP5FipG0sXSdNEK3BmDiPYfEbKJ3vLImMforF7lDTtA5dDFwbZ7HW4IP4s5FTAVbFeNhqaJxCIQVozBoIaF26kaUQDD6x3wWGfWQYBDS9InXTCj9IQpAYYD8sJ5cQC0PTSrqjsDnBNAYfMyrJJt1ZjbJ6BgZSzqiyqclEkg+M+yNmjM7YRpOzxihbAIrMFLwUqAXUEXZcKa6yFJE5U+j0gUjG4GhNg1IGKyj3/P7Jcz7MIQdPLCnCBbxXXKl28mF8VzCskjRkE1A3janC6mW6OKBuj5JMXpEi5sO/MyLjnOepfCj0qqTpeEKu6YEk+d8qKZKutYQpz1LmMp0PvjZ1HkPJJiYVGbg2ch+00ogMtkgp9dVzfvCaKvB2GCvVP6puHvPh/lL87kiYrIovR5EWFuNorQ/PQRdD2oNfmjDEZO4vha8xwnA+WgNyASkSCVvkyzkzSx1jSuKjWQjAusp+cyLnCbTCh8hUmDzOijSpgglx3qwpmhmou2o4IOuCJNHmfOTnhrnyHCuLZ5aVRgH0pLZUhKSKyXNh7BTAtm2aozWtbMqsLZJW8da8cf06Tz35JK+8+hrPP/8rfP37vp7nnnuOd73rXaWhYLl16zYf/dmP0rYNTz/1JDWgRoDCgxwnHz1LU9leRaIrz1nG67yXVHoGoI2qqZdSZ5HhQ//tz/JX//v38lP/7LH5Xpydjmw2lhAeDSJ/6ze/jFKa3e7BaHoZL+fna372o2996Pe0lg1aTOI3mEkYY8WvMwHl/U1hFJZX0xVwQ8KWchRzewFxxZJE3pWyESxjIJV0t+P5pnoraqWkcaauNvAOQHMiJI9GGJEpU5KxmeW1xpqr72INN9IH0HrehOZDImyM0kibN9UPFHbzuZZ5Z24APgKwnRmaOZOCJxUNUq6/py06peLfWgB3fQzSVaZtURIUsNoYQyxgWc5RGgvq0ecJApqn9Ig03BkAq+vYw9J1BSJrVvK35lqaUl8j88dYAqiUvrpmgkd5YYUo1crfUpqkOkLw9I1m2YKxsoaLtPKQIl3BL1v8q5yTxt3kxS9zHIYSfjXhxxHvxaR/8p69z2RtOTk94eTsBGcM0Xv8sGcIgbv37/P4jRuEOM3zUQ3FSqohIL5Tow+sdxPTODIMA1ORhteAC6UkVMRp2YtJoqnC5Hl6FqCsUECrtLLW4qX4l99XB4N5kKalUgLChhjRSRWwogC67gAiCBBm6LpM1zo2m0G88pxFa1EhtF07+zuFVMJ1rMhTU4pM04hGGvXO2XL+SQBB7zHuMJ88UAKUd6fWLMxTWP2+1oqucThrcI3FNZW0IuPdk7l/cclq0XPNnWKsJSTFfqqNA4Ozhsf/f9T9edRta3bWh/3eZjV776873W3qqlSl6lVCJZCQkEGNEUbEgBGxjAELCKCAMwgexjSGEZAcW8jggRXFNnIDDmhg4xBizEgcQicwiqWgvilBlVSq7ta9dbvTfd3eezVvkz/mfNda+zvnqqpkwhi1aty6557v23uv/a63mfOZz3yesxM2q4rRiMa1tGKjbfLygdaaJ7p5jHFY40ENK3xVcbQ54vLqmtZX7LZbchjZjZE2Zhrvxdhv1bDerHimsaw2Kx5fXPGxFz/N6a01A6LZtVmvWI2Bq30gZ0PbNNy9Iyyxy6stwziQjEOMxBdt8tpmaoyh73v5DioNE2Li6rpn10cSjlVVs6obrvednMc2EUJmHBIx9Fxc7Dg7HWnrelpDY9DNZlrrZc81kNNSjlKn4mfOgReT9sZV9medswiLb0yREA39GKXbLooOb+Uk33niQb3J9XkNhHlr8NYo8ijVz9VqRasOkG3b4K302Xf7HftwTd917LfXdLs9IY70IUilRIMZsWyWBVfXDd452nbNat2wWresjzcittzUE2Nj6HtpH1MRVQnmdHJYS7ff8H3f/wH++v/wK/jsWgX/l14ykd71Rff5L7/r79G2ln5IvPLqNY/OrwhJkvQxRFZtzfGm5fSo5fiooam8tiZZFRSXIEziU2HnfOLFNf/2v/sNPDo/5nMD8xLf9u/+KD/7kRP+x7/zDv6j7/7a6SfODrz3uX/M285+ir/9oT/IX/7+P/Q5vnfmyz/wCt/5J3+I9apnGEYeP+y4vrrk4vKC6+2Wy+s91/uO7XbkE59+SM5wue2lnUk1i7pBxCC7fmAc40Ei9VQwa/F3KUMYhommWYLyN9VNWG72CJquvn1II9Vhrc2imlcaWBzorxhJwEniVkoWjaAUJblqGke7EoHrtq0wCBW2rjI4Q6n3uVqCvTQkUiebi7gKqgBtnKvRhXaPOWw1ITPbNHMYaEqyWRJ9/eKLLVIKs1bBp6JLY8hWgL1SfLfWSnsgTInRpIdRGBeSqakmkaFuPE3jJyfIAgQUzCylqLUETf6sEcYXkujVjbRg5dpTVYb1uqauvQpyOohJ2wm1KqEiy9bKoR8jDEPEOQk8RAbacHW5JyUBnI2x4DPGyf36yk9jLWKvgRREFywctCRosp4sKRlpH0wJ7zK2zqoRIHsbiNNj04KvLGM3B7ExpAmsmsFPsRZPmkwYI+L0JoM3hjhGVm1DNqg4d1AwVsZ3tarwzpMTXF/32h6uc4usGtSSeI9BDuAYBVzNmjU77/BWWIZoQpKTtG+mmDHZEpNBhLUNtRcL6EoB0xiFpSdJjCWlQTS6EMHsfhggW7xzVHVFzk404by8JsRRWSGKwCDCsN5bXZeGZMwEXuQcNXgqLRWR3S4yDJkQrFa7Zraps5Y+JtEhu8Ficgoq1rUTLTZrWG0q1kcV45gwzlABDju1CE2udQpMhhQnsEXsv0XnbdRiTUoCbokGiTJvDGp4ktUBVVtHMeJiFDWJypCKJg2OFAxh6EW8PIsDX7QVLtspwck5H7g7T63WVtZ/uZLQ5uTPIGOsUbCAHJoAjCL07icNlXm/dnYGhQqoNe1XC4DdGkvM8WC/l6aGPP338jpIXHUvK0l3aXFc6usUtpb8S/48gW05Y1IGdX7UHEEAF6umHMtpYec99UB/6AbIWP5+KZQN4PHY0jKsoFSMWdxVlTk0JSMlwC37ao4T4CXrMOF8A2RyaQXVs6Hcj7icGgV3tCU25YMiCBiRH8iy/+x7cScbNR4zuu6TahkJI1C+k5+YKwoO6MSU1hxlD+k5VeZDMSU4YOEoGGiSJFHeeTVmEfDMZSuutr3oVTXtzJoqgO3SsMEYw2az5u1f+Db6fuTVV17l4uKCZ597jtu3b2EwnF9c8ImPf4KXXn6JL3n/e7l9+9Z0P2EU9sVyzmYEpBPtLydreMGQW17TPDTL11MmIW9/W8d3/bkP8fD+lu/9K+/kn/zTu/xbf+CfMgxPi1MNVRX54vfel/08LyfkvJDu3LngB/+/73ri1S88d1+YpqO0XRljYPbAOXwrvcthHMWESXWdYgg6l+ZfF6Yj03Mv2nUCWs6MJmmnL6zSeb2UVu3yDFMKOmZOdEVT0lirsGPVBVHBpKR75BNAtdG9x8wJaij3z7wWD783B/eD3qsMr0EKC3H6WWGZ5QKCAVHPMfmPgM3FNElNh5yXc2zxwUWQfwYdsia0TPvOFM8WtuzyvqfHX0AvpexTWBxPieWnsbJgihTA8tHK+4i0RNI1cGPIsrDliuSFMeLyt991jD30XWZVW9GPrvwEgMq/ZWyds/iqEiDMOmKQ97naXgkTrN8Thp4YZ2ZgxtO0KzbrlqaS+UAMRN3vx1FcLTOiI2gUUK+qFmMrknF6LjMl8eNCvB/ARCF2SNurnrNRxim5PLF0l6+ZikbL/9YR9dZOTNq8WGPl0aSUGIKAvsbaGdDX5xBynDsNtKjqrBVdr6Qnq5ljyWEcVL/TkpLsUTFDNgnvylqRNTtqHl6p0cU4jsI2VE3cOJkbRGHuWU82aZrHxohuZNNUrJqG80ePsbYUX4PEYP0gBgQp4bxnjIauK/q0KyrnWdU1tanYhZ4Y0hOO02XuRGXmWucQEMgjbodMe/MwDHT7PZcXF1S+4tbxMVdXO/YX1wwhYOqKo1VF1VSsGssQE+bqmtOzE+7du83ZnbsctcLQq6/3hPGccYxUVTWJ4Xd9T0qJum6p24aqaVhtjnEGmlpMsrLGNK4q3UOJMWT6MYJxHB2t2bQNDkN/fi2t15SzWZ5/148MY9RtqLC+pEBnzRyzLtuebwJaT5Igyj8JFpmujLHuP2Uek8nJqLGWxttZ1s2ui1xvpfsupUzTeI434rZazJQ+0/V5D4RVVpgulfes1y1HxxtxemhqvDWEvuPy4jHnV5fS954zeQzElOjDyJiSikcanfSSYDV1TbvaiPPj8RHtqsZXFb6pJKmIkTAM4pQy9Eo7leTbWsejh7f4yZ9+Nz/wj9/Nxz/5ln9OI5KByH/xH/99ftkHzokhcr3d84lPnXNx3dMPkd1uoF2vOTlac/f2MafHNUebRtwDDaqHZSSY0IMiRGFp/Hf//Xv5r/7Sl/O5it8//+wFf/HP/yD/zV97D3/2u3854+imn63bB7z3rX+Tl179Gj70ytfxoVe+/nP8voH/4x//SX79Nwjbret6Li727Lc7drstXben68RBpLRY9GPgejvy6OKafkw0lWU3Jozz5BQZRwXBEgqMaNLCoeMjaFKwuB2pyM2uU+UHJQE0B78sfzJmBo2MEXaAyKXe2EgW/19+31qLzVIlCuMoLTWUJ5Qxqv1TVY7j44a6ccLyMhLMJDI5ShJktFoqAZUAXM5B0zqcb9jvDWYQmjC5VFvMBEqVxCdqEGUXPf/lD3OSJJcEcZp1GabgoRzwAk6JW4wrbC1T2G5aKdeR0m4eWYRGQTVvxaHcSAtZ04iO0+XlDmMNu6teNMKcFRAxJSZB8iz3W1qi0WqUNUbcf9qbFXG5YkxgpJonLAswNjOq5pZ1oqsngTNAwleWtJcqb9U6fM7UrcfYAirKQdHvR4pex83Ep+8CNAY7JOIYcC5Tr4RFMwxGxf0FmEoJjA00tWO/j5Qiui17mJkPMgE6UHZWJoyJylmSyWrMKzocErRFug51hckqsm1om4p7947ZnDTsttLWud8OwrgsoItW8+UgtqRcWCUCGNXOapuVJDGjBuzGGCpbkVXE28QI0YpgcuWpleWSsybpawHc+q6faPlDGBXor/BVS1W5qUIOKHSrrKAU1R2p6ChlYpSWd+sd45jUyc4wjFkME4YCRKIJpEa2OVHcvyRJNSyrWPK8PO2qwnsZj5iSLHBv8EYEbpvKqQGDUVMXowmMAgMxgeojZaCy8v1CEOF7cfC0k/D8MEQcZjJLcM6qy5Gd9NrKOu97yNlhcKIZ00d2/Z62aeiCJBChjWzqVjUbDoEl+U5SVZYxOGQXlGBezZkEMEPbZyYABKJJmMrhtRJYWsVKdf0goDXzvl72UnFSmzVBYo5PJn2La0p8zWEyX9in5c3l9vPM6loI7k8gmJmZRnNUpklnLgD0DGpY7KR95azDWy9tODFMB03R2BM3Jg7OpNIynKK2byH7aGHjvimLzhpMmtC86e99VR20tC6fLxSgbcGgmy47jX95L6sOwGIAIcmZsGy1ZSuJJk8BYS32MLFDNqyU5QzINivIy+QonrNo8RSAqdxvOXdijEQF4FIB2BGtthgzg+oZVs3MmsgYsque0PCx1nHnzl3enQ31i5/iY5/8BD/3kY/hvFNQL3J6ekLbrkhJGEdZ24CKvo60Qrnp2RYnZWstKdxk48zPxel31b/Rf/L0s5KkVlXkW3/3h7Wl0/Do8dONiL7il77M8XHA2pttk/N1584lTyv4/qqv/pAkjmNgWhtwsL6cs9hqReq35BTox8DQdQzqwp1Ua8jZed1I3CAAWCxMQWBiXy7WmDDCnQJUsp+HkKa9pLACE4O4GBqDyVZrLzN4UtgWAGMaCSnM7rBW2p1Nntd6AcHKnHoao7OspycT77ml9fA1EsdFpEAdsyFlaWUmyrlmcsJnlfEwcQKH7Y01nlIihTSNwVLHsOyBZS86AI4VyMhlX/5sALCD70BZpIh0+nwJA09YoE7Bu1Kcm1iuehdFg8qYxNpGvImkMdIlg8MQnRGH2MV3nli71kLX6Wc4jKuoq1pjNzfNryJ6DzK7xfkxkccekytMjqLTibj2RmVENa24pArD3x8A5RLfZGUdmvkcSKJnaIw5mGspJ3IQwoa1M0P1YEwX+09hlEq5br6Wa64A/kkNXiwZp6CgFNRk3whjkD3VSjwVYgIrHQHZGsJwuA+NyiiXvUq1+lLAmHTAlMxJnK2zsWzaFZnMdrenbZzs4ymSAsQwiJmD8+Lii8TFxsh+Yq2lrWu8d3TdoFpXc3eWqSu22z1HR2tt6XXshpG6Mqx9I4Ls+q5jF6YCXfk7mGdzSglbydhY47Bmdo+3zrFetbz84GUuLq+5vL7m7W97K7GpqPKKR68/hu2O1dDhzDHGOaIaLlnrePe7voh7d4VF3LYNDx89pmlXOOepvdcCvUrU5Nk9fLNasVofsT46hRRoas9+t2Uc+kmvLcXIOIyAEwmYlKjqmqZpGfYdu24AxFQhxiRsSSUO9FrkdzrvnHWz/EOe45n5nJnng8RAdjGKhokylmEJhEmhR3USs+5BlDhMGfbGTPO87wf23TCl1GVPMc6x3hzx2Vyf10BY09Ss1y2rVcuqbVmtGowzDGFgDCPEyNDtuDx/xKOLc5wRdwpvHTElznc7QozUlYjsO+tomxXtasV6s+Ho+FhE8FctkgCOYsM7CpV1GPqJ2ZGBN+7f4cd/4ov54R99Ly++9HSNhH/2l4QS3/j1P8+f+mM/whhGur7n06+PDGPiSjWvsm043Ww4u3WLW6dHnB23bNaOulKadC76GdrSpb3TDx9V/Jv/zq/l9dfP+OzBL4DEt/6un+Ff+19/nD//X36A3/zb/1eEMANg73jbi7zjrT/AP/iB38pP/vzv+xzfO/Ped73Od/37/zO3b8li6faR692O66tLrq+v2W2v6ftOwCDnxE7ViCj3o/MrmrrietvhnaWLhmwsUTWwxLJY2l3mc1MT1IPNMSFio4X5lTUBW7ajlIDvKclUFhBMKo2AiRJAleDiiRHV4K68PMs9ChiGarlowmczzkOlrj+ipZOwToUXjVTDB3UZHPqxFBwlqLFSYalOPeMoAGqIAe9rhiHhKydVR72xMASCVn2SAkji7rP8vgquTBWDWeRQnMhKOqbAiwIFIrxYQBGjArqq2Wa0PbOwQ42IWQKiOWDlu1SVZb2ucM5PQtFxDIRRqr/1psXa+XAojDbnHU0jFbAYEv0grLtJYDpENSpQURY0cbJOkgrrpvEfcgA1BYhRxI7HIXJyu6KqodtFxqHHmJrKW8IQiIM6O47KTPPyjBtNrMc+EpUWHzQhkmA+YZ2Ma6XVSGuFZeacYRyF67LaVFxeDHJk5aInl/HW63N6kvViLcLGU2ZHsfautB0vxUga9TmnLMKVlYjkt94DDVXjIUHfJUZ15wtjxnk5BENMmDivoWJC5iovTKIMhjglciD6cDkmssmEQVaKaCWoqHQWkNk6WK0dFxeZOM4BvgRMGbLl6KjBe237CMLu8t4SsrBB6kraBHPJTLMI/Bsc0ckY2VVNCNKeYr20EMu9lkVRQRzBRqK2pkTVWCggaVVZ2lXFau2R1tpE3TgRx1dGReoitq2oGkfoZL2kmAXMc7KmUpKWtBCimB8odT1q++84avuvlfU0DBFfyYM2Fq2sWWLIpCgMPTkrDH1f2AM1XeqxMbMbOq77HcYYrqqW3Xov+hvrI5mLxkwJlsGIcUIJcsp+OwF6umZSmtabU2DaLQuPJZlVUMsoO0+A+xm4Kv+bxlkTkIk1pa+12U4J7dOuTFaAzRDN3DpcAFSrDm+FqeH0vW++B+i9LTSybvzSxCLBMDtFakBa2v1mUxZhENTUExhW3vcJFtvimnS8PotryTAyTva6WAQYn3KVfaWw7suevQTTQAB4r+d1UCOJUdkA8iuOZYA9xdxaECGXerEwDr1qpXirZhiqwxb0PW1hsC3GfRxHxmEUlhWZlBzOCJtE2AtyztVNPSVP5dxCNYcE1CzC6BnnPXfv3sVXNWOyXO9/nuvrS7pux/PP3eMrv/Ir+chHPsL9Bw8Yx4A+YnJcOMgCJuW5+KTsx5xnXbZi6CO34mia+kCjSu50bhmS8zBipyRf9rP4dGyNuhFQLj39MQPw0Y+9wNPiua/+yk+AdcTsyHgwSfUnEymJGUBdt5hqReyuyWFgHEY6bVErrDdnDcZ7KcQouCyt2ipAn/NUyFkyOoyZv/csq+DIORIGaTsqGnLWWGIcpbiTZgZVYXwmPb/NQgewvP9yjZe1FpQFPWltPcHa4eAZzXNqGfEd/r6Em9I7MKYsAJiOe3HMNHJQ4q2w6JKJpOQwJqkmUwGdhTWTFw+26M6FGLQ4OwM1paAirFn0jC6FoeU+dlh8WN5/0fUDyNqafLNY4b064fkKa+V555zUvGlmVFsj50NKmTjsVMg9aq43g5Es9tsCgk3syzCK/IIx7Ac5Hw2GummFEBBGgrpqphBJYYAwYkpBMAmzxRrYrNaEEKibhrpuZvDLLFrWF+DrktGpEYUUZnSuLhmr8j0KwORmncsDzc0Cvo5aEEJyA80titnStO+6w3kr+4oUyMtc64YoO6ux8ryiMDWttVR1LXNqcRUziLZtqbwXh8JxEA0/nRoynwTMwCqT0TBpAGYrcXqORtmUooNWNLHm0dKCaCVurW1TYxXI895hkhQJB83hQ4isVw2bzXrS966rmmJSMe6CGAmpNIyvvEQnqs3mvbDBrPMKgtlpnIwxNE1D09Y8/NQ52/3AGCJN2/DMvdtc94kRQ0emM6IzOwyi09q2GzarllWz4vL8kr5t8ZXn3rN32e47xn7kartliJHKV3gvBj8Se0tMvt9tscYw9Ht215fsrq9wRtj8MYmEk6kkth3HkRTF8d4ocWG767l9KuBt5R1VJcYDIUhbZeXtgcHP9K80Fx4wSExoyi6k2m9lf7uxz83PksUcTkrImYuRwtSWTxaXS+n6WLWiCWeNpa69GlxVKlXyma/PayDs3t3b3L51Rt14Usr0/cButyOMM5JOkn7YlRch+23fc7paazVMWjecb1iv1mzWa07PTlmt12LX29RCF+17Bb4GhnFgTEGqTxleu3+Ln/iJ9/MjP/Y+XvzUM/+cvrlMivVqy9/8K3+Lutmx7/a89OqWhxdXPLq45Ho/4KuWs5Mzzu7c4+zkiLPjDcfrhnXrcNrik7NqvWglrYgHfv8PPM+3f+fXo+H7Z31fm/Wev/Cf/C2M9fz5v/CV/IZv/lJpm9Gff/F7XuOV1zZ8/MW38fEX3/45fufAt//hH+RXf+2LwkaIcHUJcRSK6G57yfX1Jfv9jmGQwKmqPJVaBvdj4OJqz74beHh+rfomWlfI8r3l4JdgymiCC1CcEqdWD4pGgz0Ex3JSkdOk9YrCgDLYg+Tj5sKX71jo4XOBsIArBQSb+RKCxCt9l4yxniFknBG1HOetWu5K0lFVAurEKFWWmGf3y91+mNYNRkHmVYWrPCH09L30yjerBldlVuuWurEy9tuBFBLkIMBVSkQ8TMmmJNM56ua4qFCnnBaJLsosS9PYGFOCT7lfCdgNmUBxxbROKhjeLQJRo2NoZBzalSQtxsB+ECczX4trIqlA2RqURznwrZXxW7XCdtpte7p9jzMw5MTQB8ZxZL/vydmQTQUpEEIlwsTOUjmn1Y2FXXqW5ykMtuLA5/GV5fbdEwkmsyOMmd1uYBiCghGWdiOC5WPruFVvePjGlu1Vr2ymPLU+GmuwMeF7w9BEUqpUlyEzKLhWV46mdQL4hDgVc1LkoA1pCYKJ2Le0L4k4vhzAzhq8Mhvb2jOQpuq9zAF5TnnUwNxZxlHa8oyC7ySQ2DZOz708vwyElHFJWhJTkMC88la0uWKeALhsVTA0SXAdQpT5ZwErQasNFu9lPqZeALMwik7YOAZiqjDGSpv0vhPA1mSyQey/gwBHIiZvcJaFLmRis66odX4NY5wAJwHCChimwbEw1JlsHzRI8N7hvTyHMYo+WrsS1tvSuKNqvBo96N+nhLUZYSXOSZq3Dt84qDI5ZHXkgZzFXdRhpzbInDNdN06A7WotroICglkBZGtL30eGrILN6hY79j1hCBRXw2Ec2fcDV9WObA2tk8KTTbKurRO2nkOYTQWIl8RSngMGfAzkME5zUT5zbnPWzExamZhdqyaB9CJibw9bSoqw/JjGCZwr7UYl4MsHe/VhYmqNoYsLUEu1SuX4UBZhzMRpTs/PZEosU8ZWi/bGqXi63C/lKo6B5Tvvu/30uSCtqCVIranFBICS3KjOjDJfnArFTNqIhXlwg91187vL9ytgAsoGK0wc+f9l4iyAY55YXs5Ii3z5aoZMTHlqMbPWCTPBSXJUNJ7KnrC8luNYEitjoPaeulIwUH/HqX5lNpmgLXCZYlShjKKYVCIjaO3GSqKAIWZp/YZM1TTUzbI1UuULcmK77djtdjJHNSGLMWuVvWa9PsOYihQjd+/c5ou+6O28/PLLws7yjtLSVxLkcRiwgziitU0ztefpUpjArQKEOWtoqor1qhGH2GXriSkVfSn+5jSzbGMUjcj0JgnESy+dYZ3lR3/imelJs7gLgJ/54NueNnN45tmBmFeyj2DxRnVFcyLGK3EhzrUKukumHlSoXAwsZqZXiZUKz0WmfhLWSIpTYXN5HbimTvNb2GD7fqCpFiBFYXQZAd1yCrKSc57uxzqHr2qM81T1LNuwBLZyzpNDXgEsD1ihN1hWN4Ggsv6nv1UAJabS3mbAWGlbfgo4mTHEbHGLlm/paogivO7FBV4Y3+Hg/ocwqNSL7oXaDlqedsrKyp1ueCmnIOdQZrE+y4gngexQ4N0YyAr6lKKWDoACQR5xBpeCZozjwR5gjWhnhmgmTd+cJbawSWQmMtJmvNxLq6qawKTlHhLLGaNXXbX4qqLb7yagNWjRIRcGoRYBvLX05bHAJClhbYljC5DjiGEkDL3E4qVNvCT+2sbqfdHsLNqk8kyX87+cgSlHyWeygFDjMDBqoTdEiR9N2XcncOIQhJ1ZloebbNJzVbqejBRhUyTHKJpY3rOuayxGSCjT62bdxZjmFt3p+RrV+DOiqZxR1q5z2nI8x8xZXSZLcXYGjWcgbNU23Lp1wvmtE3FT34rkQpcz/TjQ1BUxJLq+5/TklHt3TmmaZnLNJEf6YWTYBl67fEg2htWm5e69Oxjn8ZMkElqQy1iTIQfNc0Wov2mlBbZuat443/L6/Ue85YW3UN2rxZkzJILGpvQdcRipvcOamvPH53ziYy8Sx4Gj02Pe+/73cOvOKc8+c4eLhxf0+54YRH+yqh0mZDF+sJb99oru6jFxDHRDzxBGhn1HW3tWm7WuZ0gxUHsvAP044sgcbdacHbdi4FUJqy0miZ2PN2vOTjZ4f4gHTM7VyJyY2aSyxwsrVuOEInV4swhnjObRM7CdsxAq0g3sYflaay1NVXH7zHGihJDaO7wyykOy7LrAZ3N9XgNhX/jWF1i1Dfu+4/LymkcPH3F9vcVi2RxvWK/FuWG372gMdOPIVddzstpgrON4c4ypWo6P1pyenXBytGa9XgEQhpH9bsfQD/T9IC43asXzysMTfuwnv5gf/fEv5pMvPvvP8RtLtvgd/94/5hu+7hVyiFxfXfPRT73Kp15+lX0/MMSa9dExzz37DLdvnQj762jFpnFUXiu+Jk8CiSmW4C+z3Rn+0B//1fzszz+vn/fZA2D/wld9gm/74z/CT/7UM/ypP/1r+MSLt6bXG5P5gucf8dIrd/jwR57/hd/qie8L73vva3z3d/xDVl56gEMv4J0w80b6bmDoO4ahI0Vha9TVinIaDSFyte159cEFL732mMcXO3bdOAmhJmVhxBT1ECm1tVnceGLGLP7NwZ+ZkjMwJGPlwDj4Nk+r7skmnoGYhc1kjWh2GQNGHaBMzhNjAf2MOVmSbaf8uARIk2BrDJpMyntc7zrCMHJ0coTz0odfNRVYcZRLUTIJY1XTZ6qYJehG1kcrqkrYRbu+tA/J9zeSpUuVzEprJRiKxrTEKaoFZAD8XFEoo6Tfx5h0MFrFyUh0aOaEyNeGyslp6ryd6Oyl7CRuJ9L+GNTJznuP94a2aTFWdBHGMTAOEjhUlQZ9WcTVbZKA2VeebtdN49IPcrBUzhOzJeHxNdodIGNgTNZAHnIwhDHKs8BwdmfD5rjm6HhDiJHmaDNR370NNDmKq9Y+QvbiyFfDrbsbun2g21X6nZIAXEHWRhozVSWOXGHIWCOgStcPhCABSVU5VmtPu/LErQA9GDmPgskKNM7OUBnVRcAIYGklsfTeU3uj2ggeJ/1/RKesA6/20lZdbUJidzVIlSkmSmjXeNhdayRn0hRYpxQZ+4F+Z2hqARYtiVV7JACO9+QsroXjGKmbioWwiSZ2sqCMgzBmtlc91hhWK0vXCZOt8hVhEIBv1TYCnveB3X6YzBesN9S1F+AtidGBJZOCmImMYyYbw3pVYS20rSclaZ8ah8TOGk3oBLDMJkOSZxTUMtw4lco3oveVyAwhUhlPU0uLa1VXcz3UmkWgLYmlJLvz/mAoYHhNzJGQBtqVZ33UkreJ1abCWkPfJ9ErGwJpDAz7nhCETi9AqgRfdePI3jF0EmyLcLck+62JwlLzjuwywUYGK+1DqMNiTFFYeqA6eqo1giPHQBoH0d1zTPsQOR1+J2OeaHmEQ2XFA5CMOTldJp2FPSFFoTABYSD6LtZYTYDmYkhhSwgQ7KWNY7k7641aYwQAdkwsSuNn9pcJZq7kh4xrHK5U7p0kOunG9yvOdLkUbpQFVtgDBmFn5DETiRS3Vd1ep8TEgLYMM7N7DRMI9AtdAlTOycjY76a2Q2nj07WLp7QhDsM4OQXKs7f00t0u3scp4p3Tgoahco4mwzpEQhW0oFM+s7RGKmi2SEZLNlhAB/1asgYQBphbgMTlWffjyL4btFAkhU40iS0d/ZlEzMKyEFequT2+QEHb3Y6f//mf59GjR1jnxNCpaQBhAD96dM5ud8W+2xPGgdV6jTGGq6sr1uuVgPIL8euDcYcpQS7rJ8VIiOGJZ2YMqqcjc+UJBHF543oVTatXXnl6S8nVtYh8/7/+1jsO/t65SIyW05Md5xdPtlVaGySpj4Fh6IhxxDsZu5JINc2K2F3J/K0bwthPIEzlHWSrwLkw/crzFQamMJGzMnayvTFui+9eBOvLWiixVhmLMo9Sioh5jRMxem19K6GFMW5K9jAirL1k3y3bB8XN282FOo0fkpk1zIojdWnTXra0mlwA+uIKqEYler5ao/OVJ+dMMsI0lrMUYlYBcAw+Jqyr8L4i+nkOFbZIP/T6/GTdJCsc3pSlkTEpeFxiYafs96TOu1PLuS6iqIwbQyZLr/L8nW/GywuQBoTNPI4DKc86a9P8U8Zn7bOa9ojxmdFzHedIo7hsxxAEKFKGV1VVamwi7Jebl+z56eAccVZihv2+Y7vdUdc161WrazeUqcQ4BC3GBS2GyZzyzjGOgaHfS7ufscKWDKOArlr/6PpOxc+zAgMwtZNnZdpGnSNG2gXHGLTdt2hYlaldYYybmL85M8WCMsY6X408/9JWfTCXdW9dDIXEkt5x5/SM3XbHeTif515M7Pf76ffIUhBNWYpVViVJpOth1AKA3PP1bismJ2k+cws7X52OyMwL1yAdHJv1ipPjNVdXOzbrlsoHSJHt5cDldouxjpOjI97ynOPes3e5e+eOgOG7PVfn5zx68Ih93/PGg8e8/NrrvPPtb+X06IjUgKsrbCnsKBDmrMwPKSaJW2FOYqR3fLymeXxN04oT7cPHl2TviDGzGwfOcqIm49Oeqq65GnoePHiDn/3Qz/Mv/pqv5/GjR2y3O1ZHLc88d4/dtmO/3TOGJEYPTjpOqqYWN/XtNV5t1ry1DO0Rn351y1uf3eCbNcN4zX7YE2Jku9vTDyOrpgKdkzYG3vOF99jt92xWnseXA5t2TbtqOdq03L59wtgLELdkwE5sz1DmiczJMkesm8/i0h4uT62cmmaK8XKZX0Zc5e3i/VNKs9szcr7J+Be5gIXzqHlKZeBNrs9rIOyVT7+GsXB5eY2xlv1uT4qRumrIEWVsDMScuRqFzWV9Q/ArsJ6zW2tOTo44OV7TNI2IcnYdQz/Q9R19N6hQq1RdsJIs/Nff+038/Mf+eep+wZe879P8he/5IayVQHW/7fjUp1/j8aNzzi+v2YeKszvPcOf2GXfOjjk72XC0bmlqr+0jwtaJhYqbEkGFqb/vH73An/5zXwPK4vnsr8jv+pb/D1//tZ/g7/39L+e3/u7ffGDFbUzEuUgINS+9cudz/M6RP/nHfpBf8/UvEsdIGCJxLFojka7r2O62DJ04flpnOTqqqXw76R9krfS9ev8xrz284GOfus/Lb5wzDJGcpD1MDjjJ/kuFJeVEBIwJUwWs9EHL3c0J0c0GxrzcnMsaLz97SnVfXuPJZGyOeKcVJIMyZfQgeKJAn8kxPyHFITwTSYKNthBZY/GVtr/GIElD1t4LUzRZMpuTlrEf2V52ZKywA8fIfj9MjLBKBSmdU8FEEUqggE5lPEplSsbuCSnEJ4qX3goIWPTSMpCVwbE8CIUCPjuSSLAvB7s1Bl+JRgCmsJnStDkWBg9GwAwRvoXaO/qQNWjJU1KfkyRwnSZHMWV2246hH5XdJolmW7cY6/A+SsJri/tOloocQBb1IV8bTs5aMS1YVTSrChDgq6o8YQiQ58AjxoSvLUe1OJkVZsL+WmyOm1XFqo+cn++m4CbFjPFo5TKTooA/w6CC5EYTRizr45p2M9L3gTGrdkuSsSttFWjyGEhgkuhcOKP3qSyIZDBOxFjHcRQmh4q2G01UrbaT9l1gvx0JIWOwVLWlU7p6ilEE4I1BuzOldmkMwUnAUVWO1WqNc0ZAfQy+dqQAecykbDCuCL1qwpETBAFku/1IP4jw7elpy+1baz760UesGsP5406043Z7sjF0Q2AcpYpZtxJEWuNI0Sj7Sdskoix2YxzWO7rdyHpd0VSeXQ70neiDOefBFlagJuw4+jAzOTCix+UnZ9Q5iU2ZaX7WlefqaqdziFlTISaykyTZVdJmloLolO33AWMySVsrfGVFeNwJoNCuPI6spgCJJlQaeMgcdU7GMCVxoQtjFGclIr5pqS2QHavjI8qmlbMkglXtadc1Ljzp2mesZ0b2S8vkotiQ8yEQtrhuthkZRf6i9FvinZ/OgxAlCSps37jQVyrajuXPOWcIaLVVxKdDChMIlnLSPdhqe8RyPzNTa01BLK2ydlzlpkTX6P5bEuMsE16r8pl0Y6dctvJN358yN0Q/ZqrAhzix3wowaq1ZqMWUQtXBYCqQdZhQ3xzjFAQY9ipuXFfV3OqT1Z3QFO6O7pUK2BS9mOn9pjsRjagJhA7QVIa8ajW5FKZjaRtMpTCS1SFqcbxaYycQ6CYDD5hYBmXsxiBMgMklWvVPBCS0YiJjBRxxxrBZNbSrFXXd6P3Lc0s58+lPv8KP/+RPcnx8jLWWfhiEraoMgKvrjsvrLeMY8M5wenoCwH6/5+6d2xPwuUw0y/gstcHkWSRt9XkSuBRtIQUAjX3izJ2e5aJdrzzzP/4nv+Ipvw0PHh4xDoF/+uHDeC5G2YMuLp+uLfa1v/LHqb1lHAdCGA+SFGukxchZTzYjpBGjenDGJo7WK3IWoCmM8szmNt6sRQnRxVwyGQvrsbCvDlrz8mJOp0zrLWOCOMyv72KPt55USfK1H4IWTByVtkilpAW5nDU55CA5XLZjlj+Xeyt7T/m9whoz1kwOs7OeoAIXMauBhABheHBZnZTJ0/xfgkgJyMapsYgU9OYWxpFMxteV7JnX1/L6RTFA7jdrcaxEevp3UVjxBeQwZFAzC/n8woBzYOxUtLPW4rOjMDylxTtP42lKMJN1rFLQ8YkYZYwv9615qxJ29npxJhb9rdX6hLHfERdrJaUs7be5xznHeqMs2cXVD3sx91H2ljyHyP7ykvPLK7yzrNqWYRgw1tD1wwTSxCyulzMLV3UFC5CT88R6iiEcnJmlgFDM27JxM5okg3twn/Mzt9OeK3M9Yl1FGHZYV2F9Jc8vCCBZgHUDuClG29KsNjgnhYy4OAuctVROgMCgbEcDjGFg222fek+gxjtZ4og+RcIYRJcZKcqUNeG9xBz73Y5V3eDUwTvEQN/vaNp2YjIv4wPBPgyrpuHWyTFjJ8UXkwybZo09dpxfXfH4assbj8555uKSBw8esb3e6TyF/a7jjQfnvPr6fR5fXHLn7Izn7t5l2I/U1pLznN8WNlt5FCWutjbTNIaTk5a6bfmar/pSXnnjEcbASy+/IQw6Z+nHgVdfeY3KOY6O14SYubzecn655d4Lz/Pg8SPe8pZnBaM4OaZdtbzlrYGr647uxVd4dHUt+YXVYloWV96T07vEGLna7WhC5L1vexYM7PaRLgR85bna7rm62s7nYUz4xvOWtzzP1dU1xsCnXvokp8eneL8RNlzlqXxFXVVst1uyruOl5ukS5J8ngY5R2bONsJBLMeIgZ1Qpga4L4BzX1ztu3ZqLMrOEwqxlOhWAl59lVMfPfXZg2Oc1EPaxF1/l7OyMtlmx3+3p+gFnhRLd9T1DiPQxs+tg5Q2r49scrY85Pt5wfLzm9PhIDqCU2G23jH2vQFgvlQusOKw4PwUfH/zQW/n5j/3zYIFlYOB7v/fv87a3bckpc90NbK/2fPTnP8nLr77G/rrn7rPPcPvWbd79/DPcvS2strau8K4E4OKCk6IIjYYQCRFee73mj33br+bFl+7wuYFfmdu3rvjD/87f5vjogv/H//Or+Tf/4NcSwjyV6npgGGpydgtdsM/m+8KXfenL/Af/h39M2/SEMHJ9JfbqNot48dj3bK+3XF9fSw++2pc3bUPjHSbP7VghRPbdwMV1xytvnPPg0TV9PxKjEf2ODKJgLB9vSxIEBwfJrJ/BYtNdJGjLauOypUTHf/rPJ0AwA9oeImb2MJ3RGbV8fyp2pqXh5bsc/ttk1c2qJMFt2oqmFkfQDNIGkEWHZb8bSTFxddHjvcX7ihQyF92OMMpmd3y8ZhwCTVvhK3GQCyGolsqcrlksyZRqgZmBLQVNDu5fh61SQ7TluS6i/+pMstjcrIXtdjEmU+ep2mH74vqX6Tuh14YIvQp5SnXWYoz8rmhJCJgWvGPYStBSglSR/pJn1O17+n4gxUTlBBQPUQ7DupIWa2FUyNY+DHNLR05Cm6+rhrquaFtPs/I4bxnHoFpQDWHUBDslxqHH2kDbyrPMlCBaWoaMNZycNlyd7zWAXCarwjkahsxuG7msB9brlrNbG2K1J2doGsdLn7gmJLC1JfUJZ1QcNmaq2gNqXb8INOUAknVjnWUYAr4S0Evo+fnggDVJtN3SENntB7qrwNAn+iHhvYiuu5zZdQP7/UCKYnle4+T5jVJtW60lmE7ZMcYApuhUZbAW52AcRg1+A9Y1gCUEcRdMOSv7Ewrb03tLXTlijnSd5fT2mr4f2feBynu886zWevh6YdGJFbsjjgnji86KARI5BWIXhI0zJmlHALHz9gHnI5PodZZxzhGqPAKZuhaXyqLnVjdO2hCtrqdSzdU2q3ZVo3iaAsYKLKiOwrCX+Sqdrlbn66hOlG6qnl1e7PEu42vRHzs5XWOu0baeUdpYowjTrlpps/DeYiqLGYNqfNT4tqI2FV7DG69taU1VcXK84Wi1YryW1tqcpK1iLjLIa6x103klyWCeANGnXcugK6OgZ56ZYc7oBqMBWiJNm/wyOS6vFZbwQstHkZoivj99XkbaZRfBXHm/fpwrm0afR+0sthLXwdKmiTts2VrqtFhrp7ZxXXlTALhkB1tXihHz76Hz4cBRd3F/xhRdnSfHcrlPl6T1sBVFxyJIMlOcwYJ0W1E5acO/yX8uoszl928eB0XzQ+6jvEaAQpstFkvtRQsyJdErEZZzAYuU9ZJljy/vPyWI+r+URPcoxjiNdwGRnSZ4Ny/RT5FYKsaBbIxq/2hGnsEp4+Xho0esNxt+0zd9E3fu3GHoey4vL3nw8CEP7j/gwcOHnJ9fsNvt8FXF2972doZ+ZL/bc3y8UcMWpLUsJdHx8mmKReqqoqnq6bl0XS9tWot5uWSEZh37ZcKx/IqlfckAcXEuv9mVcqLrnm4U8+SV+eL3/AS/7Zu/n8xtcdPLiaJLq4OPy4amcgy51ha9TIrjNIPMwmSnxF7luQH0Y8DkiDNMTPgJVNL1VdfS1iSu13P8lmIi9AHnanLliOMAQONajNXihO5HEbR1NtMag7FR9/IkzHuYmRJGmI8lRi33VNbkEoCUQl3h+1gF4tF5bKZwKenvi4ZeYgyFKTnP4zIXJtDUWWxVC+ASRryv9J6EQVFVnna1wqxWeO/ZbbeEfZjYS6rCKjIfEzqrT1d1dYvhUZopSouflzg3TkYGILFB0A0yq4agNQug3ojcQDm7yzMXML/MC8gYxoX8Svn8yfzMGKy6UmbjML7B6n2EJF0hpR07JUseDxnFBaQaxqCglhQJpx0mq9OhjnsII2PfkTIMpp3Yt/JMDC5EkiuGHKPGAZFltTtpsX95tqVpLAsYADc7mMcYtdMnkKK2KBqDq2oxlVfGpHNO5CKymPnEKAztURm3vm4YUlT2k5wTFqQwU0AnpBgm2luB8+s9YzxsKwXtuinnZjlfDNP8Mr7CI/nOGANVimxWK1GDjJG2bSDDxfkFMfQ0tRjhif6laq2VllhgVTfcPbsFMXP/wTljLx0xm9UKYwxX2x2PLq544+Fj7ty6TeMbbJVFQkBZjJfXO86vrviSF55lO+y5ffsUKndgMqFpx1MvYwJ372z40urt1M2K23dvcbRe8fzzZzw+v+bx+RXRQbJW9pQkphcBS8Dwwlue5b3vfQe37txisxFGVs5i6Ne2NZvNirapaeuWysG6soQE+27gaN2x23WYnFhVXuMwEdnf7iPZWU7OTrh37+7E1PJNzXq9pm4qrnbXjKO0jjarI+r1Mb6ucc6y7zrqWhikOT1ZmLQqqUJY5MrTc8/T3jXGOO1xiobRj4kHj67pupHX719SeceuG3nvF93h9NYpxhh1zKznfWh6+ZyfT9U3mORaPtP1eQ2EkSQhAEmC15sT6spT14IoJ6DGcPfOGdZabp8dcXK0odZEeVDL2n4QDbDQ9Rp4O/BenT4cjx6f8l/8pa/nZz70hXxuoNHnekl29K2/58f5lt/58RJfsd3teeWlNxhC4Ed/5Kd59dNXfOmXvIv3ffl7eP6Z25ydHrPetNrzbhT8GslR3c209bHvM3/pv/0S/upf/1I+90ef+Re++mP8/v/tD9PtKv7iX/pKfuqDb2ep/yX0eM8w1L/gO918X2NGvutP/wM+8EvuE4TFSt8HQhhIIYhJwX7H2Pf0+z1d300LogQ5yxEki6Dt5XbP648u+dRrj/jkpx+w7Xr9HUmI0d9d3MkTyVYmzwyCxd+Vzyo27QevycUBTg/rvDg0p/corVsQePLwkMTrTYbMMiU+bvGfy5lZt+I0V9Ui6l034lBlraFtPbtdZr8b6IbEbjuy3400jaNXtxTrLHXj8F5OQV9Z6iNHs7aEMDCOUr3bdXtikLa6ZNSi3IloarGyv0l558bhPZ2qi8t5OeRCSJSWgBiZRHwFLJGgQEBfu0hqVDPNS2U1A2OYg06pYgAmU5jwzhjRyUpJxFUnoM1qbJUmK+YUE954+pDxYl+lzDsBPDISLKeoLk22zCuDCAQnmlUlNHwjwcXQj4RRxd+jVMVKtdS5ua2hBITWCQU7hizgVspcPN4/MbYpqy5PgK6LXF8P6oiY2F2N3LnXsu0GxuSpsjrx5EwcoOtlXopLIKRsSMnQajLuNUGd9CtUqw6tbs8JQYYkAuxX5x1936vgNMrMMuy7wLq1uKoihB7GQBcSxlqsVyHoZERbxlpq3+j3E7cseVRaOQyBtm2nZGsYkxphiCuPs47NUYPB0HWBi/OOtq1oa8vVdVShZAHTnJvnS1Wr/kNdKZAU1InTgfH0Xc9+uyOmhtVKAN6+i1ztR7bbUVyBnGh85SyMzhQFxANhga5Wwl6qmoqm8dStn0wnvLa2GzL9INpjOQtoSGZqN7bWTC3PKYqWXeUN64201pa2q3GM5GzZ72Vu9SGz2/ccHVfEtFUWn4FsSNGQorx3jJluP9LtS8JqRYdlcNiNgMYmi6Ml1mjyCaEH0zq8tjzHnJgF5UU/zRrZO4wV5zxZNYXxuWDClGRYmQfFncoYgzc3zjYFHI0xFLvvbA7bI0H+HsOkt2OMtgWrULQ12h6krGSMgIspBhLiTumrCoMhpMA4CSBnTLY4X5GKPllx6V1UVMsZ4xGgqLcQjer7MDO9SqtmGYfSCnmwn077pABWogml88eiAT0Hien08gIQLJL15TkrrFxhUmRKOykY65G2qQIulpvRPba09LmF+ylGCwkKMB+08iySwJRnht303vLasAQtDRgcMSaG2IFQFQABAABJREFUoPc1gWRxYuJl5nOpfF9jxAFt+XflKkBFjIGcI9Y1NE0zAcnyOZa6dhytV4x9z8/8zAd54YUv4O7du9y6fZu3vPDC1IYVgiS6MUZu3Trjh37oh0kpcrxeY6PsV3EYkDZnqJsKCzRVRV056rqi9jVEo3uVsGXLvTonAs/GWAHW1P1tqs3pd48xakseU8xiMHzZBx7z0x+89cTc+ON/5O/xh/7oNzzx9292/eqv+Yf8xm/8uzTNW9Q4RQM81XCq10cM3W4h9B3mBEoZ3SkJi7C0zy0TrBAFqBUDBmFML+eHsPx1bliHr1tZn2NPDMMEzg7jSDLgN8fE84cT48h5g68rcnKsNbYuxaC0aKmmzDPd28v5B5DcrJM0/X7BUJ4SO85x3ywpIdGpUHEPgHiNdaVTBIZQmFPaGhxEuDsrlFZeWtcNq/Wauq45Pj1htV7jrKPfd+wvr7j/+BHZeYYQpbWtzJlFrFbAI2NUTN+Ac5U6kSu73AgINs1LO/85gxpszFcq8aLR70+Ww+lgjObbma8Sz5fx1yQ7a+xSNFABrJexLLFUYbRgBWjSexrHkTgxRxWsS0XjUJcUsmcYbf0spknGWHIcqNxITs1iJ7MHc1g+d167N+fC8rIY6SpZADGYw9+T4kecXGen0THi/G6MkCLE7V5dZ8t5RsbVs+6gzMVJkRhv5btWthKVsZjYhT2h6xiNwW8Og/iyDkp3RLln59R/W4HPqqq0WyMR+pHoa9ZtS46R8/NzVqt2WkvjICZ1q9V6PpPm5STjZC1HmzVxHNnu9lxf76efrdqGfhxxznG92/H4/IJn7tzmzp3bnJ9fMMbIEALbbiBTEWLm9tkJgZG2biYZB2El5ierCsjcbpqaU3PM8fExxjju3IXH51e8/uASsBytj4lhZIiJatUSMMSc6YaRtmlYb0TH3MDEUg4xiwPp6pjd+DLGGe7euS35/tgx7rf0uzXpdKNdMk7B1sD6yGNrx9mtU+kUGaWNe7MSIwNjLKaCqq64de8Orz3Y8uxz93j+2XucHq2pPHgjmnuhG9Rsadb/muZyEiDKTCw1JgKDd9MxRAjliYlm8YOHl3zkY6/x0Rdf53rXkXLmmdtnvP9db2G764ELGZOFhMMSlJ/XVCLHuSBGekpu/ZTr8xsIs5aQAt2+I5M5OTrm+GhN24rjlxSRDJX3rFbCxAgh0A+Dtj8OQlsvlYi6Ff0IK05Djy9O+MN/8jez3R7z/28A7PjonL/63/5tVmsJ0q6vex48POdTL32aF198icePLhl3De965/O892vexbve8Rbe8sxtVpsG52tANsBYhJmjVPBDzPzsz53ybd/5ddx/cPKL+B6RX/sNP8e3/Laf4tOv3uI7/8yv46MfW7LI5i0oxs9lOmW++ite5j/8934YYzp5Fr28VwiB3XbH5cUF11eX9P0eA7S+pvIVt27d4uj4iMpXjGGcNtSUIucXHeeXWx5fbHn9wQUvv/6YVx485uK6mwRG32wEMllo+MNAf8OS/GYLJMygCsytFsvLlpP4iWvePCK/gBbLzSHWmKKEFgs87OBaHVWc3FqzOWrw3k4tglI9VU0NC1fXA1dXgb4LDENk6EVbQASKoY+Z3Ei7VFU5NicVYyebzdhHhi5Ia4qBqAFMIGCwmBwAS05zYCrJEhgnwJN1RjTR7BwYlAqvbHSLJ5UzWSnYBoPRKhumJElpaj1JKStTzDzxsEty5xAdnpBhI10BrDYtzntpqR5kAzVZ/i8om7K4d2WgqeTzrdN2Ne+mWzcYFWBX1zALgtw7jo5aYdNYQ4hz9TLFRKkKhmGPd6LhI0LolrScTnoGOw++Qg5lHctiuFDmWD8EHj7asd0OAoZUlmHM4gbTOiLKhLDijFnO9Rhnxkjp0FtOzmzEgMIOFl9Lu0tJ/Cf3LVss1VFmmWhrSdtLi8sWTKb2kXGIpBDIESLi7mhyxmQJmp2DprJk68A6xhQPwOLZ8l0ANt9bmsaRUmYYAt0ggO/1ZUdKWdiNtZsEf8e+gD6RrI5yOQsLq4ipFr0Cay1127Bq1DUwGnYx0g/SLnN6bIkkdl1gu2jFnGMmSaqMM6AOjybLPTmnOly1x3jDalVR1eLyM/SB/X5gHIQJEEOiWdVUtZeWMQNtI0CH0znWGAPKdPKVmZ6106jk7e907LeBcczs91HbqNU0IKKiyIacnRZURkKwbI4FoBkHYaaFMRF2CSpLMMh3CxFXQbta0boKhiCgc55NPw4mtJZZrbFiH69JRjfK911X9bzGlIWBmYGxpaX3xK4qcbhh0oZKRuzpb96CNVbaoSbhdzMF9M46al8zpEH1zsC4rIG4gHs5Wb3nhHEl2QJyZAwZY6QaX+7DGP9Eq6MtZY0imJ7BkHAK1BWAbp5J8z436emkMDnjpZjINoErGl5WGbdg7HjYQnyjtay8/0GLYTYkK98jlfK+nn1WqgbSwmYMMZnJ7dOYuY1dNGKgslLI8E5bECfTB3nLoEDNMIwSSOOJZqlZM+ciy5a3IuobFcQEKarYFNSNTLQFp5M9K5Ci41Ou4kRXxidnSey8tar7VaaO7At1XfNFb/9CHj54wM99+EP8xI/9OMM44rxntVpxdHTEZnPE6ekpd+/e5e7du3zqU5/igx/8IOv1ik3b4hAGaxxHMgljZV5Xzk1iwJX31L4mRJlfh1hBxltp4RMmMVNCspzrZAGQhXk9ZxY5Z/7T7/pxvv7X/kvTr//u3/XD3Lt7wXf/Z//iZ1Xo/I4/8R3Y9IDjWycY29K2Lc5YQj8Qh55V21K3Dcm4CVACsLboKe51/plDzS9jpodekrCSxOcsa6VonKYMeRTx/6rSFtZSnIkzCFrWFDlhnFUwrThSyp7g6proPGEcDkxgDq4FSFR+XthZxpqJCVna5JaAs4AOc+JoJhBpvibX3+nz9THGNLtoI+wPAQkDla8EaFBdtJwyJkaGoZ9A2eurK2II3L5zlzv3nuHT3YhvN5y2R+y7jhDvMw7DU5+zdw5Tyzpw1uF9JSLqpgzG55hvGDNr677JS+V7l9byN3mfg1hJx/ZNfnnJ1huUDZgRLbEQ4+Q8C1ossR6rGp8CcEpbb2E35yxsGYnvDcM46J7kqbxIGsQU1fnySQBMPshK0FU2OIQpvSzITyzOhXZlnMBwZQnr9xaDgfJaWVMxB7KdS+gxZghJimgxHgBu5kbrv2iyyd+FYWSPoaor0WMDxjhOe4tftMJPOF4B/vQcs9bgneTnk/mLFh+mdjgtIo1jzzDs9SwTY5HSimud6GmIfqO4R96+fTwBbV03slYw7Pz8iv7ZgevrHW88eMy6bQkh4pznrV/wDG+vn+Xe3TPun1/w/L3blJbspmkgDFqEywub+sM51dQVbzweOTm2WNXzfPj4Ao/FG+i7PevVik0rci7rVvL4qvLsu45XX3/Ag4fnrDZrnv+CL6BqNtgUeP72iue+7ldwcXHFw0ePePDgMfdfex3innHs6buBszNpt79//+HEYnTrpujPkHJi7BL9fgTM1Bp76+yI22dHfOB9b6WqKs5OVirDISzFQdmEQ5COiYMC2SJ+KF0jxkFdGSp/OEZFT3aMie12z4MHF1xfbtnveqyxvPDMbd77ri/g3W9/C9dXjxiGrQj7K7ax1AkrnyfrUWIleAI//wWvz2sgLKagOgue27dOuXV2i1VbY22aBDVL61mIgWE7MIwjXddL77AGy1VV4a2Xar21fPqVM/7Qn/itPCHA9M/0ykDiL3z39/FlH3hESIHz60te/sQ5l5cdL778Gq+89oDjzRHv+MJ38syX3cJbeP6Zu9y6vaFtKhpfE1NiCL1W9sR9JMTEvjN871/9Jfy1//6X/KK+x8nxnm/9Xf+EX/GVH+d/+p/fxh/5E9/Ew0ebxW9IkPK5HXQZGPmz3/4DfPUvf41uiOz3gInaCz+KM2ffs9/t2O92xBjU3ram1fYrvAT6+21PXdU8Or/k0fk1F5c7Hp1fcXW95/K64/xqz+OrHVe7Pd04atW0sGpu3poEK9scRQtBL+dEiHUYnr6qygEqVck5sXpiVLLU7fMCLIB88HtPQGblh25OdqzNnBzXxD7Sd/GJz2rWNXeeOaJpRSy0qh3GVIyDGD4UNsI4JuIobIH9XkCfcvvGZExVNAogJYvztbRM1j2xl7UVbSZGCRxSlmTLZAEkSaWydoOvZlU/R8ccY/CVm3KpGNStK87QYwxLPQ1En8qU8RO2Wwja4hCiWBurhsdNbZtifU6eWQ77ZFhZafdyviblLOYYk4umOhyWqpnRFtMssYp3klR676c5kJK2vFXSGuEcDIPorG13A+uTWlgLYxAtslGAIGFaBE5PPa72KgDrMdYplVjaBEvw7GtDjIm6rli1iX03HM6dLPcyhMDYR/a7IJpRVsY9k6lWDdkYZbNAHKWVToo7ergUPTBlQAmzQhLFqhJnvmEUsXpjoK7nPWdigISg76n7RhYgQDRGrLrKJLA6hkirpjy3REyWMRjaVjWrsqX2AlwYpNVz2ER2nWhaXO0Ml9fxoPpatZ5njoUh3HeifWdiVoaMaEo458BrK2RtlEEnTDJXWYyHbA0Jj7GWysH1dcJXNdiRprJcXPeMIdENQZhU+kCMtiiFqUItQvfOgKs93gt4VyvrDGdFy3GMgOg6dr24NRWHx24/MHQD1kl7aKXngs3qtLVyk5iw6DO5KWBp1TW0rh27baBXR9FxFLB7SrL1+ZcKettWwp6xGnTjsHjC3kIA14CpxPo8joE8ONy6oj6yrOrPtq1KANOchVFpyKoPaOeC4LIyqPO96G5NQZqZwZyix3XwGdOTWLQ93GCeyJpOM+uoiFnnkpBoxVrt5DHglXlWtLPCOBLHUbQ2arE+t9iZcVzyP2tmjbIb95lNxlQGbyph9C0q//K93Zw4uTlIFSZDngoMVuMi65wYAlg76f0UOtnUEmkXY1c+S8HhpOC2jEGankEMaWJ8xJi0ZdJi89zOZoyh1teFMRLGgX5vVAi+Aut0f5RCTteJaUNhKgqgKxp4MAMBWZEfY4xWh0ubftHOnIN2cXmW4o4hQ05T+4sAwQmwGl8FfY2M2xNC+QqiPfvMs3zjN/5aLi4e8fDxJZdXW65VzuHy8pKH9+/z4ic+ST/05CQaX5vNmi/9kvdzeno8vWHOAn4aX01zsxRYnC+6d8U0QPSfyplntChy0MazmEvy18v5tWDKIe/7/X//+3jxJc+ts0eMQ8++G0npZsQi//3rfu0n+Jbf8g9ZrROXjy959MYVKfkJZKpccdcVp6+jVYuxhqvdpeSSOg+DFjZLdd9aT7Zxut/lepQ2UZFoCCYRc56YLOUuYxxxVTMl9Ul/tgSSi3YTKdPvLrDOTC1hVtGwlKS7IuX01JC3gClTXLeIO2KMEAWQLglcKcjlnDWG17PROioj4vcYFZvX+Rq1FbKITZf9razT8mcZRwHC26ZlvV7L/rMXYCelIG3RMWKvr5TNZNjue05ObzNiyNYTwkgI4wSCL5lo5Ttb66hcrS3lgW7oJk0uS9FxOwRvnnaVmVi0BeeXGC00zHuGRCVPK00v3u8X+iFFGS1TL+4npcQ4jBhrGJ+iueec07YsMUASkNRo51BhulltZRbf9KTxrADXjvWqwTvLdj8whmEqGB5cZQycK4evSD9gntD/lhb1omupY2SdtDFqkQgQE4mD16FSLWkC8Cam0E1GNUyaXOXRlLZf5xxR13XKicqKnmZhChcAeHnl4g74JoXqbt9NsjdN20xFKGnvjvR9z26/x7mapnEHb1EAMXIxyfI07YkUZWLmercnmgR76MPAK6++gg8jEUvdrrhz54zTsyPcWmLYuq5IJKqqZuj76dyoU8SNHdkZTFOLyPFTLmukAByCtGd656iMwQP7mBQMlYKiGMp05Bzo99e81l3jbc0v/4ovw+aM2z0SkwVnOL++Yt/tGNWNvKorfBadwt1+z7PP3NU8ITIMIxlYrSoMjv1uz+56z/XVjt22J0TD6dkJx0crMlBVNc89d2hqV5jPZaW2Tf3EWs5pCX6beRrb+T3m+WQIIfDw4RWffukhL73ykMt9x52TFWebNbfOTnnj1fs8e3YCxig+EAij/NsVQzSNvyYZHZKaCD31cbzp9XkNhOWcaBvP3bun3L11i7r24h6ThNkglSHLGCP7YU+OiTAGtWcVtzPvPJVqgO32a37PH/itDGPzmT/8F30l3v++T/Ef/fs/wq3Tgb7v+PSrO954cM7D8wtef/0hVxc77t2+w6/6Zb+Us9Mj7tw9Y72u2ayESVI5T4iBfb9XC1ZpfQwx8drrK37H7/smUvrsk435yvzSD7zO7/itP8sLLzzmv/nvvoTv+YvfzDD4g9+R6+kL/83e933veYM/++//Q9o24jFsd1KhCinR91t22yt22x3DINpgKQojo1TRnLW4ytP1Aw8eX5OT4fxyy+V1R9eP3H94yTBGun5gHCP9GNnuR7b7nj5IQFucdt70Skg7Qvl6WQP5z7Cqij6QtZGM5YDJNA2ZmVgLcqyrC1/5lcOY9ODPxkil3RoBa9KYaY8awijaUMsTToKmAQE/pTc/JUOv1uvWGNX6gf1u4OpqOPhQi1BYySoar62BYUhcnw+0bYNzgSHuRWdNE1PnrYjIIwweZx0JaWuQe1G2lBENllkIW4AtY62aAiQq74QOnGEGDeUWnZcDuezJMWb6Qe48Y0hjAiOOY0+LuYqDj689xYHEWkt7uqYygX0X6f1IVazUkzAJJOnUCqCxlIJZRoCZuqkma+0YZc74xuK8xzt59rUKVTeNZ78biVkC0xhm+n3VeFarGudhHIXJtO+Ctt9plUVBOKvGCpkkDIhfaHJnDTLGACkTjbgr3n32iIi0dNJYup2lz9oS2WtrZ3kC1tB4EVjHCKNPwEP5gDBGxjHivcM7ETkVCrxYRUdlNI1DIoQ5cBRAQR2lkHm3ZKaUpM5ZK+2YxtD4hvWqommMVG6DCLk3xhHjyPVuZFAg0ymdLcbA0EVCk2kary6Ish7GMdM2jnW7EsDZFD0XATTBYZybAQRrSAn2o6Mxlq67Vn0tz8NHvTh45rn1oq4qat3LYkpkyxRs55wwTuaFMaLbVxth7BnvCCkz9oFRg6YCLOec6BX4NGRigqOjmhBhGBIZYXc5W9SRRBvP2lIxU20g/Sw5O2X+hlH2SjlbQLRJBDiIUQwPxjEp0A5kCaSdgTBC04hrUfYVQ0iEcY/ZJRpl/ny2p0dWfRiRYkqkOGIRYPgm0K0DIYCgn10BS5C0BMZuttQfzjcN0FU/5mltcqWNcvr9cr8aKBvVdUtZqu/WWJLJ5CjJVhgl0M8+4/ETUwULxhuuww5SNTFDTJ7Btpwyxkn1O5SqtDEkHN7MLNObml45SlU6uTQnlvZwjEpCf3N8lt+9tL9ba4kmTswXNzE5ntx4hfVlyaZsUwaDtJGnII6iB8/SgEPmS8yJtjIMGAXVsuqqJLzLEyAlYAHCgGYGJ5yzVMrAK+e5nAPjpKMmiYqhqp6MdTJJNfm0zceAr2qapr35q9OcqLzn7PSUdnXEM2qsMjGAVPR5e33Ndruj6zrqtuXendu06v5VLuecuBLmOQEtrL6JcVQAPXUxLeuiaGVN83lKHMpcRR1sD6/SFZGB55/d0XXyO76Cr/+aF/mH/+ht3Lv3mO/57u9j6k7Kicvzc1I6IoZRYgDvJ+DOmky2nqpuxd1sGEh5UDa3tDOXtTP0o0gQJGmTblatFHnDDNDa0uppioNbGXz9xwBYnKsVqCj7uTICy3wJcXJdncDAxTTMOZOCsFvC0IMxODs7XWNmtqTRFnclXUxzawmkz0xG/a4x0I+jJLQx0bYrESg35eyQ1k2R80iLQm6emGFGJQmMMRgFno1hYuLkDG270nNOHE8FEOuU7SvaWbY6Zz8E6rqVonTfybPU75bjIWhTdqScZS2FOJsVOCtnDdOuJZcvzPPpPpd75wyt5jzvXymrziHzXC6gcNaC6AwoKQg67TPyjIyOf3mtNYYIjBl82Vflw2YwRa+U8+QU6BWAXhpWLOdKuQf5uSOkXnXchCG0aponAMX59cqmsVJgYwJdtdVyAUQYzSck1kwTk1ZebxWsezroWOJHjOwvzkkLXRiGab8s2lHzdzpMSgRMZtJTLK7KXd+xalbStg146/Uz59eHmPVMNFJ9HweRK1AH6OLGPPQDYQyMbsTW0uqdQmYYRuyuw/kWMbCzGg9kyCJ/UXmPNYmmKi7GUB1tMJXjeugJOXJ5dc3j6yuev3WL2/fucHT7FqvNmm67p8p7YoRPvXSfs7M1GCO6s1EYrDmNZC1g2ZxwtpIOCZUL8Po8TjcVsYKuj9SV49bZMWkMjF0/zWsBzsVU5ZMvv0pOWeLFpuLkaEVlLLfamqbaYIzhlYcP+OjHPsHV1Y7dTkz91m3N0epIHMx1TTtrOT7esD7esFene6NzvN91bC+uuLrYcXr7jLe99R7HmxUkMcO6OXfKf1kjQHs2eWIzziDZzZhBpAuWyySlTD+MXF3uefD4mpdee8jLrz/i4XYLxvKWZ+9yu205bloab3n04DHOgU6naU5KvnQTYM/kbA/kHuzTl8AT1+c1EHbn1jHPP3eHW2enVN4LdbgXi9oYA9mAq0Ts3iDWy5WvcN5Noq2lEhVjzbf8vt/BU8s9/0yuxK/7NZ/g9/1vPsjR0UOuLrZ89P6WoQ+88srrDPuA854vuPMcp190xO3bp9y5e8rx8Rpfy6ZYHFDGEHQRyaSPMfMTP3Wbb/vOr+P6evOZb+XGZUzgm7/p4/wrv/7nePio4f/619/Pj/3kC5r8lGuJ9n42l1Qb/ugf+FH+lV//cWIQZDxFCKAHeqLv9rz+2qvcf+N1zs/PMcZwfHzEqm1FkBpI1pCSJZPox8D9Rxd8+pVzuk5YXtd7aYcc1TI4ozo2QxDNhJSmtsjPflCKTsWSLfALpW8JY0RMaa5HzvohudA1pz4dJh1kCUinl0wEqsK4Fb12FQjNmdVRhTGW1aah70aCCsFjkXYkW6uekQQOXTeqMHWF94ahj+y2gXGI2BTJpjAsSsBm1BUykRKMoyEz4myg3/eMY6RpReekrr1qDhlOb22EbdZHmqpmHEZ2O3HakQi8gFiK4DMHD1XtyBl8JS3NYUz0u4FBWxSdF9bVFAA7MwFl+72AOhLtqLtdnmqSTzwpX/n52ToJ2kI30JxuiLsrAaRqsRQe+0iIgwSQCZzxJfwjZzO5/I29tpEVXTQ3Jy44Fbm2hrEL7B7sRDvJwfqooe8GUgxsjjfaVlWzux7pdz3Ggq8tvoo0bUXdSBI0DBafKqztGAc5/Ju2ph/CVBkkMQf9KBtulPlXHzmcN/R94PhkhavQNSbOoGGM5DyQ9goC6DA6VzTZRM+qrp20T+bI0I+kbPC+wroaa52wdsMgeoxjVPBU7i/GEWHsZg3Mk1ZUZze6kopmrZCDsBFTyoRhoPaVVCO1VFrXnjFGqmDoe3HX0iIyIvwNtbGEmCFkqloYUc4u1uByVZc9dwwMg1TZm8ZPlf1xDJA9q6OWcZT2N4scwAXgFLaUUf3KGmsMF9dbwqAgS0zUjZ8CNucgE4nZkMdA0GBXkp9UkMGpotsPA2A5PtlgnQSaXR9JSEEoOkPlLW1jcD5O41/0QbbbgfW6EjHgQQor5HL/TOssJZlD1nt1RhWthxATzkKz8dgGnM2gRhJZXUqzMezCwMPrS5rKc7pag4lP1AxYPHVAdcIk4cnGEGcSimhONQ0hSpWw/L2MEVPSIpoe8sNlcD8BZZpwhhhYtgEmU7RTmNgyIK2Lb5ZkiCuiw2toNZ2YJXlTECNGYTdVphLvhAKgGcPVsCUQqY0IWlvAquaayYYcMmEcGaOYnBR2ViZwHTgISv2i2PK0S5gAadIUK5X+TJ4Eb6cvsnhNmT9LFuwTrWLTC+RfhZE2vZWgBeLmTRZmvvfTWl2Ck94aoiav5UopkaxhGHpSdPNnlCxvAoMg50NWfGEGl7bXidWmr5EWnHECj6bX6RdyVtkh5V5ycTkVfcTzy3MePrjPbj9S1S0nJ6esViv98pmmqlnfvcezzxYjAtXEC71+t8V9LQbNOof1leytMdJ1e8YwIPHHHJ85LfSawox+88dycDnjlf0hX7Y4ZMvPHP/2H/hJ/vC/9UGpzuvDmIBiTYhCObM1obJavAkJZQ2Pk4YvCBMZoOv7iREuSZaZ9p+CBFpjsd4LOz2GCTBx1mJNngBymV6ZRIU14oaeUmQcEtGOUIDJ8r9cWmQzSeTqyySbEitf1fMYF6BhATaaMje87M0xx+lnBwCYssDGIPFpH8IMYmaROBFtt3wwT8s+V+ZqzgVcm5/RdC/6T4yRMI6sVitaZdckZXlZJ/pxOcTJ1dFg6PZ7uv1eWtuSMIbEwGSOXct+Je6V8z65XA/WZD2y5zlZeS+FipQJdjZZmsTwl99D40Qykxh66eKx1oo7rc6Nvu/mOVzYOQWX1/9MIWh8ZaispTaFnSeAmEH2I26wwVJK5EVreNZnlPPhd16y8or2Zcq9PKvCOqRkUjdXX54AbadFzzL5CyM+KSBuJ/BVQ+qnHaLlhwVcc14A9ht79NPOwhij6FROphMQBi1w2kV7vhWjhdSIVnMYg9S7e1g1K2mVdYegijGGYRgZx4HKe6os+r3WWuq6odE22wLyhxiIOxnntm3pOzGhMmOkGkZcFaibRt0tkzKkzVTUEP3U0oYpse1q1bDv9nhvsDGwvTxn1VSc3rtNyokhjjx8+T6PH1/SOMvq1jGlkFpR40zGOTAJ4jCqIzAElXCwxpBVv7jUIFZNTU+gqSoeXGwZ950wO704KFprSWOSVuQQOTnacLY65vatE9qqIsfIaxcXtE3Dp199nY9+4iUePbgQl8xVg7fH+OONGOKNSUwLfOKZ52/jjOXBIzFn6fZ7Ut+ThlHG+lT2xvsPHoPNJI65fbokAmlOmCPOuNmIhKw6YGV4y557OA2fVk8TQ4/I1fWeVx9c8OqjS/px5Phow7PP3eN9X/gFnL/xkI98+KOMY+D4ZINLjsrXrNqV6v/OjPx5LmtMkAuQPt3WZ7w+r4Gwtzz3DKenxypurK4ewzhV2n1VYZ0wMo5XGwYvtGuv1PLSI195z3f9Z1/FP1sQTDaxP/oHf5STk8jbvuA+b3nhnKura+6/sePDH/kYtzYn7Hcdm/aI55454vT0mDu3Tjk+2UjriSp5D6Oix1laforDytAbvucvfhn/w//4/l/Uvd+7c8Vv+9d+jq/5lZ/kh3/0Lfyp/+Breenls6d8j88NAHvh+Qv+z//h9/Ps3Z2yC5iEUscoiVYIgf1+y9XFBWHY41zi3t1TcbSpKgE8SmKTEmOIEw306rrjtfuPud6NnB2v2Q0jY0zCPNDEbAjidpc08Eg3DoBf8NJqnrj9aQuoBnNvfoloaFawKuY4DVsJZssBWAKuAwBsOdw65FHxB2vE1tgAVWM5u9uSs+P6XDbTAoQZyywKbZywx5LMF68sm3E0dPvIbitOcFIBUAFpVLzbGXI2WCv260M/MA7FuU6cvWJQN5kecZhzhrr29MNIbBOrtmF/PYiz0RBIiSkorrwjhrJpavCgrUzWCgulOLiklKbkvzDHCmSXc2YcRINmc+xUIFU+L2cJ9Irmi1HHvaLjVS5pkxQR86EbMAhzoYgPh4i0iQVpEyNJA1DZ4KWgFelznJ6tdZDHiI1zlaJU2IwzWG+pW09VSRJPErHKlMBGQ7cf2V/19HvZr1xjaNaenB1hVAMDU2jgQnXOcQY4Dr/fXI2OQdaPq8x0P5W3cpDWhpgj1sPYJbJJNFnAmXGIoq9j0M/O6hIpz0QALmF7tatGq2dxAtBSZrIAryqxUJd7kgq9gIwl0J1bp6SSW4wBHN46am+wJFIY2I8S+KzWjQRkmsxYZwijVkujBMain5UnNoV3pf1QBGGNLEliXDgQLQCgpMFKVYtmmwQvGiTGgMnonBbBbGsgjSIIXYwZjE1YK6/zVWkPBoOI3ZfWM2E5Ruq2IiobUX7uabwnxcwwRkRv1GCME9BMHaWGXhIMay39KCJfbetIqSLmTNv6mSnCzPa4vpIka78bJaiIedqnisZGeUZWLdpDEl6rvFPGaWtnTkFYkc6Bk0Qjp8SYI904cLo+pW4qRj0TDIBlaZKIdRWlKpBUnFYSjFnTqlhwV66agnOQ/XscRwWDdf1j1HXz6aynMv6GIowep8p/CQDL5x6ssTS7wE2MHWU65pSlCEcm28JgUJBOA/ZlyyFZ2mgrBdsMRoT2bRGaXjKL0sHZssgjp4hUGLiA7t3Ozdou5d6n76/JXgG4QPQ6S1vKE9eCDUPm0LlwcRvOyjkUUtQkbsHk03mB7s9lLCaAaqHJuHTGLeBl5QpDdm5BdRik/cZgvALdTlqQSwKarOyhZSzm953/LIf3Yn5YS123YBx1Ux88txIljePISy99in/6oQ/x4OFDMA5f1TzzzDPcOrtFCIHt9gpD5vj4mLt37nB2ekrd1IQsLaDoPiSAkLjKlZY36yt8VeO0iDsMAymVcc+aSFeTW2BIyorVeZCNwTK3q8SkGp1kEpJEukoS2FHb9g8q8BZhA+RIiGFqMRzHkWq1IeIIaihTNRZrpAjtfc0Yxc297wbVL7NTC4uvqhlQm2eP3GPU9tiUlX0ucX1OwjifWsKMeeLZTS5vqv1YXJxnpvDy+WU5W7AC4GeJO5YANhM+kaefLeePjGmeHMiX+0zU+LX8M8aohhq6XxvRTDUT0DKzmJaaYnLvsj5La1VpkV0ylUII03z3VUXbtjRNS2+csmYcLiWsDVR1zXp9RN3U7Hc7uv2OlOPMakszCFYGLKVETE+u+bI+i/by9DSNESH9pO6H1mLyvJaNxt0F7BJQWYv+2sJsnT0wBhmjefLzF8WS6V4mLbx5zSedUzJ+BqMttDdjxDKmpV3dTuysQwApqTyNQffdqmIce40dHAkrZ52ZddDKOJU/A5M2oK0q8hjEWVJjetSwxSHsuso5Klc6V3SOhGEq4OtNTn9Madb+KvPrpk5ZCKL7uizapGTEuCqra2oS1lvd1KSYxACpC6yOVySX6MaOpmomsknKAoCHoE7qWddJTApUynpdriNrLUf10dSCOTETs+QpMUjHCxmMs8KGBErJyjspDl9eXEpHUZJn19QVx0cbyODHqJ0Cex6/+hrVekXMmcY5eOV12ufuceYribV8jTMGZ9Ikv1a04FLXM1hLLGzdxRQ0ui4xQbSxcmY/jGJyMYz0Qy9xcAysVyvqqmK730NOWAwvffplKl9zfnlF0zS88un7WCyrVTvJt4SQuLzcQs7ce+aMuvbUjaepapw13Lt7m91+Td/39P3IydGRAIVWpD+OT45o2kb1wITJVeoPSUH44nQ9DAPWz9q/Bes2+m85q3mCDVamolMzp1rPZqX7k4Fh6PHO8v73v4ecEpvjDVfXW27fOeLsVitGC+Ypa35a7JJTJyTv6J/Sefy06/MaCLPWMo4D+yCWsVHZBhkNmMsTshZnLE0tB5lzctBXVYVX2vTLr3zuTKqnX5nnn33MX/7z/4DTE6n0bHd7XnvwkH/y4Qtee/0+w36UCu9JxVvecsZzz93j9HRD2zY0tbgqhSRgTiYxRgESsk7Kf/KhW3z7d34NDx6e/KLu8J3veMS3/JZ/whe97QH/77/3Hn7P/+43sdu/mQDqZwuAJX7P7/wQv/tf/zDGRCanMT1Ix6Fnu72i1/apYZC20MrXnGyOWLetBKq6EY5hJKow7RBGrrcdQ0h0feByuyco/fv8aoux0lY1jIF+VABMGWBTRfOJhfMm3ytJoFeAMLkyOcv8Mov2kamiqKCXUTAJBa3mjyy1wtmVSd72xj2ZxT8UAGyxyVjRQdqcOlL0hLFi2Ad161MQISe63cDRZiWHRgh6aEhi2HeJ/V5AsGJNLzFbGSP5x2REhJXZWUyCykSKhr4biWNitW5YH61ISPtL3VY0lQBdQycbf/Ze16awiQxo1T1NzCiQKouvPE1jRWMso0DAOIFYhfIbo7iNSBKUSCFQN14E11MkjokULUkPJudF32kpDB1DJBKpvKHvxCFK5o0AKV0X6QdhFYk7bRGsN5qUZYZBEuZSfbDWYALkHFWHQ8RHC908ZWn1kRaBLHpKTpIlqWob+m1HvxtFGDcnTCUiqTFYLI4hBTDSblXVNX2vTKsAZAs5HsaspbKsm4hxAuA4ayfHQfl3Ju4y2Mz6pCYMiaCmCCFogJckUYCsbEFtHU5o2588y67b4nyF81KpM3r4SVBT2F95qvyVZ1L+kTFxOAUOpD3aaAAirZYOi3GWcQxYVwkAljJjgFz2n5CBJK3wVU1VWdp1i6+sgMMhUJnCtLL0k1NmmitM2k6Vi/6ATAKKVtZ2N+ArJxoS+rvDIPsFKICs61hkP2Qs69rR7wLkQ9ZSjPL99vtRGCBF10ojk1Lhds7Ks8fRtBXrozWkkXEY8FXGWE9VCy+yqoURse8ixgmTs9Lgsmmkel1VtSZWiMtWhklDaWpbVWAqZ8aQVKTfYOsC+OlGlo04umXRkXFWgJB+HHi0u2SzXrPyG8LCXXSZ6LFgWAg0NFcISqwsgZcmqpUyCApAxMykyaYYLuSpUDABLinPJhfLSsciNyi/b7VN/GYbZVVVsGh/k5bwNIkFLxk9h9v9DMod/n0Zw+lDgCxJZxLgNqr4tTUivp2jcI6jmUfN2BJkoueRnIlGzYBiGDloUs0C7IdsIFmyEVYAVtW/FuMuSbuZvsOqWZGrzJhG+rEXUAxDRtkNRhgiAjcYbTW7xOgeZo1RNo8FkxmHYSqCCBgg4ESZ/IctUstEUp5VDFH345JsJ4y6pAnYPs85Yw05ZgFXsu5hWRjg1sq4TsxC6zDO09T1BEbo0JFy5o3XXuPHfuKnuNpe8853vou6bvi5n/sIH/7wh2mahrZtJQFxlldfe52XXn6Zd73jHbztbW9jYgWiou/LVjrJErFO9NNK25sk2V5btdXAoTBSyqMtLp6L95mSCcO0bmJKGObzctACxeT+pczDUtzLKZNt2bMTRs0TYoy4ugLnGIYwSTKM6mjItM/ruE06AwX8u8G0SbNhgZ3MMGQiTgLxCqwZFRQXMWgxWUKZzsKGCtMcKWs5KRC/DMcSChrrHMuL+VX2p2ke3riSjg151hQsgO4EhGlhuzDRnC0GCFp8CqWAm54ACOBQv3DJZiyzUeYS03ha75W9Beo/KSCcAqVVVdHUNXfu3uPBg/vcf+N1MEwC1YeuhkbHoYD8T882U04K+JhpDIvMSJ7uUeaXsBcViHez7lOaAE0Lbi6YFmaeAOxzIlviiZt7emF6etXzmg0Kyj4tQLF5YqyZ5tP8mohRpu1kBlTWUy5F2ohJls3RsQAudYNfHZGrSta4CzhfYXSfy1hstcjBjNUwTiRGhPwg8g/WyzxPSKt4SpIfAtSV6sNZVEpC2L0pR4ICBMvifkjFUCTPe0KGsZeYu24ajG4kKWVCHKWlVePquqoJVaDvhM2ZY8ZWjtrWOHUtTLkUFmeWa/nvlDOOssYO86Gcs+pFzs9yCSqLbpSesUKNo3RrYBzOpolh3A09pqpBO8FWbaMO8Hv6fc/FcJ9hv+fkmWdYHa/ZRMMXve+djP2AGQaO2prRSleZx4tRjwLl2QhTOWJU9uXJPWE5p+rK01WOGDxYyzAO9ENHW9e88Nw9umGgaaSYEXNmu91yffkGwzASgcuLK9brlqapiSGIiUpV0dSeo/WKZ5+5rSBYNeln1nWNq2o2SbRKh76HnHBWJDmatqHIrjhj5pZ3pDgZo7pblzPVaBxmpwYm/Z66bpOAYKU1cYrZjBAmTk7WpJTZh0hV15xf7UgY7p4eSR65qnnmhWfxdcXq9IiqdlgPZN2PKPqJZrrRnKVzxFgp8KScCZ+lWNjnNRDWdXtC1I0kI2i59VROnFLqupEEzyil2mi1S7XBJjtxkzg77f8X3IkkW9/5bf8TX/+rXsciFbKHD3c8enzJGw8ecnl5hXUVm3rDvZOG5565y717dzk6almvWqq6BDMQlHI8xqhBryR3f/Evf4C/9jfez+HU++yvD/yS1/ntv+VnqHzg//43v4Qf+fGvJT+9N+Wz/t4nJx3f9ad/gPe/9zHWOoYuEYMcCCnPVc2+33N9fcl+PxCV4ltVNevNBhO7CYTJSUDNMY503cj1ruPR+ZZHF1uGIfLwfMvl9V6FW8V1AgxjiAwhTi6SJTCValtm2bB4+F+H32cKLp6inSEaOZJkS3yT9DjMmJyn9zQmSfBdAobFOxj5mOmz5r/VqFCrI6W9qiTQoGCAl/bfzUnD0AsQZqwkzzlpIDBkhtGw75St1EeGITEOmb6P9F2YKhbGWKn8lcMpJVIqrDVp/TPWzQF6SMQRyJJANq20EBoNvCyJummIPmMrswAHi/HAEvCYxWP1XBa9EIcKzfup5dEqkJIUZKhrT9/HOUConMCMpcpHEu0ML4G7Y66UTpW3IAyFIpZcgNsYiiumAGExZGkdKtE3Wg3KKEBaEvKlXom4TsWUsKNoOBQQoaodrnJYY1ivWw0whFEmzCoBwXISJbmo4FzOiZjGKeGRCk0kq5MfyUK2TAL3xmoQFScwYwIqkjwPsgSeMURhJOj/Uk64WpyAVptqMlaQdj7AWsYoFXpJPAcK1GuKkUaWSqJUfA3eC1sqRU/O0iqJmZOxYrkcS9UyIwwGY6a9egxR55E6oiVh2jw+v6ZpW6zzDEOeno9R9pVXtzUJpLUF1xhp88NQNXFq3/ZONEwKG8IYQ7uqqWuP925KIIXh5jnaGPb7gf1uEHA1xKmlNScZYwmaISPtgHPiYljITQmgaQSMLJ/tvV0AZaLFFmOW+02yzzhrFNiLkz6mswK2aRiria6b5q0xjrqGuq4YxmLmMCcZ0vIibACjyaPVcU85qfhzYVoKOzDnrALnCZ9g2wtQL66mCUwmZM+YI06NNqbWOjfroDy99TBPSbTcooIZS6aQMiDnyIxpzZdAe2ol0QS1XDMjL06C1Mtr2RJQklNpWbcHTKZMVu2uGWQASDZNc718ncnZcvoQDkDs8ldGgQJJ3CR5I0EykmynLEULOe0SxghvIkt1Sb+sMmzDiM0R4rhwaHMYq5pdBfUydgJdnzguzZzYSHBbk0yaAlL5npbCUjQGSfyMskU1LnDWC2gCGOPIIgDAqLhnSEmBEmGGGl07svfNGjXGGEGP5oelbm4zG1D/evr9pcFNSgnrHdlYDaIBV9HUdgKArCYtXT/gqkoSoZQ1CXb0XcfHPv5xLq4u+aqv+hW8+93v4qWXXibGwNX1Fccnx3zx+7+Yt771rVhrePWVV/nZD3+Yj/z8Rzk5OeH05FjmNtP0uHFJ8C+AzwxgWmWAGW2FOnAUNWX+3MBVn3KVdVUE4pdsMPkcGYuZoze/jmlvknjcOku2lnHoJ5AjxR5rZM8UZq4Rc50YGYuRT3py3U3xAhoHOCkuZOuIyrI1SCuU9V6628aBYJhYDDEIq0xAQPl+hfV5Y4gxJLKxwnTV3p88FT9EK7IwU3Ka2bfz/SroWPY1ynlUTldlGS/2JGct3roJYI52frZljzjUGFNw1wgIWPa/eOBIKTPGOicdEqmf9kyb5JzOKSpjUwqOOWdOTk65des2Xbeno9M2zwVTe5pXhfk6aw7efG4pi4OpsGTMEz+P6gpbWGETo60UOHSPLS67HJydT3wioEX0dMjmLSywpfD/BGzpfhpzpq4bKcwpeGOtJdv5d8rgW5LG5oapOL4oZpXntTo6xle1/FM3EuSSsL4WQxB0HqZ8MD7TdFLwG8CkNM2zUowTDWCZ/3Ulro2ib6qmVEY6JowpxecCRk1Pcpqvsn/Mbe4xRKKLAj5bAd2CdlAICGGxKmPhK3GE7roRbyvWtZ+MjiZfNb289/q83cTw+QVZPiwAzWneiLlaDAM5BQxe50w5H+SX21VL0zQMo8hbVE7AZlKicpZ9SnRBzh47ZvrdwKpZ025WVNWa7cUlr734Cu973zuoDfT7kaHfiuSS7sPZWilAWaP6iofzQI9FuS/vaFc1u73n6ipyvduTc6auPccnJ6yaCmfBJiEqhJww3uLbCld5XnvjEb4SUNt5y9FmLXIwg+QPzjtWq5q60rNvOvDAW0d2gn+I6UMQ7emlsRBlTpeXaZeLr4R1jzmIWUrsmpUwaqW7G+eYXMxvXtYKK+/2rSOSsaw3a/b9KOxkY6gaxxB7jm6d0Pc9jZdWzRADZpLZQeM3fdNShCwFBr3vNzvrbl6f10BYP0ZhlBgVvvcV3lVUujC9r4QyOaG0EkA5J3oCWSu3KWf+1B/7Qf7Yn2r4mQ89R+U7xrDWTymH/NOuzFd9+Uv8mW//Adom0/U915eBvh94fC5uQSllLI7bp7c4Oz3mzt1bbNYNJ8dHNM1KWCg5kXNgCOLSF5Ki7ynx4qdW/Mf/6Vfw0z/zwi9qjIxJfMPXv8hv/g0fpu8t//Vf+XJ+9iPP/KLea74Sv/Fffpk/+r//aZq2ZxwCXReJsdNEMEyBgwQbQWmx4pwhtqteW40qcteDEb2dIQz0w8DVds/rDy945fXHvPHwiutdT0yw6watbMlBH5KIREcNanJZkXqfU/Iz5x5PRJgzY6ykEk/+zvTqHKX+lVXDy5Z2Gvm+ZvnCJc61yHCc6oSFnKfNu7xA2AN60EwHFHqQoULlGWMSzkGzrjAWthf9FLiGMaoDXGAYBsYhMBTWUNTgpHKkgLoOLhhEUs6a/p2z8DHQRKwkmtYa1kctdVvPgXtOUzupMcIQsxOlLU+H+6RrgUK62hLpapmvghoYxDjMTIf4FNBnGBSQyUnYHjFkxigJeDnlM8IOKUF3pdWyUoVMUQA0dMyMFU2lUR1CnbLXZLN1kN1iZ5XnKQDVco6V8SktZfLcCohatxWucqQMvnY4pIV1vN4L44OZ0ZL1Y4pOQ6bolSiQlyDnQRh/Y5r2OMuC+cZcjSu3Pd3vlFQpgDEUxok8Z+csVeWksmQsMSaGfjYNGIaE85UGJvJMvRfWmwRhwpYsQYC1UDeOpK1/1hocZkpmnZf21qlFzYBo7jGNZUkg6tpT1yomrqLkMRvCKMBvGNMEHLeto1IXy/JdJYnQKhceb42CQ4ZhlMhlCtKcoWkr2lWDNUZFiktyk6gqxzhKu+v1ZUdp56y9m5KHbEUTJuu4ixNqmp+vvl8qbqlC0FNAXNp1nbcTwGetWJ97b0lJzrUYREckG21fCBG/9jiLCt5LqC3dBLpfWWmxGEKm6ySJLpW2wvoggdG25NLWIc88QxZ9M187vLcaQAsgHYdEUifRmBK+MqzW4py7i3uSSVTJT/pUUT9XGHRLUHmxpeas2mjoOrMHSdgEii0DuUXCWfaFJeOrJMMFiA0hTMnZ064pQSuJWT5skSptZMvfK+ANdvG804IdXDB2i4hogth/KAhsy3cv/9NiUlnPMzgh42NIktSoVqJFtV0yUuxAnKrKXplynlrRjW48B5qY05FgJpYGOhdIkT6oCHeIypotLZNzy2j5O2uyaM3U7ZxETqwKfTTWCrsIWdd2+ubzVfb1cnMCeAk4700lwJsthYH5OSyf69waJa/LCBgekyS6Z2fH4kzuhZmZUsBbYZOGWBx6HRjH5eUlr7z6Ki+88AW8933v5ZOf/AQf/Omf4Y3797lz5w5f8RVfwXvf+14F0+Hu3XuklPixH/tRXnntNU6ONrI+dcM7wEQLIGXK914kLiioRAFH3OEcXSZlZVU8JfE0WnQwBQTTs/xp6+Dw/eefx1HiP+uKuvECqElRkry6EqY4LNrk58+xCxajMaqXNqpLsi+sC6axKJdz0mozjAXEcDiVR0m5X3x/ZSvd+G7yVeZxlzhhmIqisn6LiU5ph1ZnaZVcn8wncp7YX8sugAIOLRlGkwvq4rl6a0jWCcNtAdwUdk0BQqZCov5dJk4i+mCERWmlUMyCxTSvm4S3hr7vubq6ZL3ZcHx8wu079+i7PV235/LxI/pxYBgPQUr5vhaTBYAtbedp0U0xSZK8CXhV9sKY4mI+6VxKcdGOP4Ngh68XBgs35mgxtihAqLHCQi176/K9Za5I4SeEUA5L+UH5l8aLKc+tjanELhk1MZ/PLGPEGbCuBfCq1ZG7DNzyu05M4oPvIOY1SxbUIdh62Cpb+4qVtraFkalwLWZqAe/QYqSbnlGaw/wZCFNm4jAOxGgYhkhVyRlS8htjS+tcnu4rG2GJD93Iup0LUyYLXaCcp+V+i2HdXHQrueJsiFH2FmfnnxsMlQJpJidxw4wjNns1Y9HCt0lgYb1Zse829CESYqbKUDsPXky59sawVzBxe7nlsg/s9j13j9ccG2GjxSGwe3jJ8a0jrq8uSLXFr1f4WnRwk/EkoyYKGr8sH2Vx+jRITFnXFU1T4StH32d2+55Hj69IKbNetwzjqMZolbTgr1fK2jO4x46Lx5fs+8DJyYqqsuLMPSTWTcNq3VCkPw7XSslPdZ+vVJrhacK4N5ZpmYPLZyLQkaHkzBqqz9/TgH0TIEyer8zFk6MVVa1rw1i6bsQZ6Ls96QY8FbNhst9QKZCM0X08znurEgeMtU/dc552fV4DYVLtqEW41Fc0TSNi+K7oQnjNnIFcLJhFRyqpGElaaFB8x7f/A/6N3/uvs9utF59yczLB0WbLf/5/+rt84Rfs8Aa6buDR457ziyuGIbDb7un6nqqquH12wu1bp7Rtw7r1HJ+sZbOKhkxkDIhQdFaR/+Toesff+ftv5c/9J18KrD6nESn3e3rS8U2/4SP8y9/4c3zikyd89/f8Cj7+yTu/yJGW9751tue7/sxP8uW/7JoUIt2uJ2dLtxvYbvfs9jthq2ilymi0IsFdUpMCh3WCpkfpwZnGdd93XG2v2e46zq/3vPL6OS+98ohH59fi+GikqlSSQREdLUCYBB6yAwnA9Ob1BQ4OdDkQk24KWW/85gJS8MBmrM6ZpJD03LazOFgmNC1PO4TgQWkOdtEqgVY4U5rFQ2dwSf7tvFEmTMHow8SSsn6uEkkrycjloy3GySEUU1QBbIs1pX1BHdHStD0i/W2lXUAAP5ufNhZQNxXHJxvqxs8BmCBT2rJjpo1QAj85EEKU8cogSaEV3SnnDcaJC7HJgM0YlzHTOi0udlEFdRdBbDZ0u1GCukpcDWOQ9iFDli1bg2tJ1MU9VvA2L3pCoQCgMjZoYCqaABbUjfbwOhyb5eGXUkmKJTCyCtqVaqe4bRqSGg2IqO1sK51yJBup1kj1f6ati1C5BJtNoY4vq25TgDWDYCWJ0pNEE57lQWVJsTACJOW0ug6cs7SNJDZNm/S1luvLQZ7JGEjIs3UxU0XIldP1MVPeSwGC6YBUMLeVyqgxpcWlUOolOZ+CRgVmpb3CTGKuKWWsq6Rdtg8EBX2tA1cZAWkqp0tRWTUKZhU6OMxBexkHoy1CvhI9Ma8uqtm7AzAMmFkOmqRZo2vTCqumjGuRZ6oaS0oO5y1RE7ccM1kTP+sKuJj1/WaQRRh78j7r1tMNKpC/7xXpWDr6MAXeEljbCbwtwKLME6HID31UBydJ0JJmpKYwODTQ885Os7+pHb4uAr8IUJULEKyuqyrIXHR2+tSRY8TnYwEGY2RImWgEgPVOgrlyfhj9MvJc5oQdDtljhaGVC3IDExNySaNPGlhmMs7MyWRJoOYCyiKBXSRlS7CtMChvXiWAnH5f9ZWWVVqbbTkYpnsr912CScmtF0nHcj1TEnZJtl156Mboc2ByASzfF0RQ1pUijkFdEcdpXsk1639N31XdKzOQjIDEGEScN+u9xHJ/oseUCtsVFZ3Wz/TeC3BbjlyYgHPZA8ueehjUFmbk/HxEe807R4ri0OarGiN9yHNIcLBXz26R4zhSwCEQ3aXL6x1HRyuplkdlAhozaSX5yhPTLKptK8PV9TX7fccvf+c7iTHyIz/0w7zyyqvEGHnPu9/DO9/xTi4vL/nwhz+MAb70Ax/gbW9/Ox/84E/z4P598jvePgE/JD2fmLVFUShQGC4zm81Mrb9mAhysETmQIoD+xAmeD9lehdW1dIvLBZR/6mvncSx/tsYSBhGOzkhLqveWuqoUSBhl/LwaMmRhdohuU1nleWLDTnNzNNP6OgAPbrS9FE5NVgc7aSt3OBXWT3ru5iXAUtiCBZwYF3EhaI9qnNfxxMiRAm9Skw6PAAnCxtP9D5FBKHeHJmpBtcHKzyYQrIx72a+NEfbZNNvnPxiTKU7c5TnahbQIoCYYoveZcnEXLgBmeWaQncXaPSGOuAczc+rs1m36bk/oO9K1utMfAIey1+I8UvxRR+Qc5vmhhasbUkHz6+3sgFqAtHLvUTXdCvgkobk52JMkTsnTPgEZ7/zE3ppaey2kmAgxHMz75T3ELI7NJqsx1Y15VggVxliSmVsiy/Mp92B1nD3CDsopYk3GmUxYfK+42JvKmC/H5sk/H8yE6XLKsKk1BsnK4o4pMwaZ634BqpWYKabZYVCY+3oP1pMRfVMxV4pigIOuU6MM5KAAntwkGSlQ65OX8SfpmTozL0sL23xElxiESSajqqrpfC96VTEmTBZHxdLOTIrKCAtUtl5Q6aRt0XvPerOmG0aurnYIeGxxyVJ7cQ7f7nquth3DMFJXnu1uR7hoGY42nFQ1R03L1eNrjs+OaXzNqFIuUeeS8Y6qxEZvArxkXR+rVSO53jiSw8i6FrH8OI48enxJioG69qzaltV6xWq9wjphG8cYWa0aHl/ssN6SUqTbC1DvjJ20h0W/68Z9LAkipjAs57NBCrHKOH6KKdyTJ4hFAxrdOxemPCW8+QwYlDHQ1k41dWX84qaV3C6Vov+yGCcJTEmtS3yQ06whmMp5lD8zBrC8Pq+BMOccdVXLoe89dVVT1QKEOU2oSpVTEkiASIhgprhVDwbgX/03voWUbk4C3QSJfPef+bt8yfvv0w8DbdvQ9QNDP/L66w+5vLwmhEijTkKnp8fcvXPGrdMjzs6OqCvPpGWRhBGRs4jfhyBAwqdePuZ7/sIv4x//6Avw1KPjM12Gd7/zEf/qb/owX/crP8GP/Phb+MN/4tfx6uu/OC0xuRK/7Zs/xu//1p/j6EjQ1m5vSTGy23c4a7k4P+fy8oph6Mnax2402i2gpNFNSfbTKMCkhTz2Sg1O7Pqex5fXPL644vHlnocXW/bDQHFwFL2qQivXwyfJGE56C3neOJfXFPAhaHEZ36U7lTEHadf8WrJqB0iwYRVvCzkX/hjp8AU3Pr9ATRlyJGYRt5aWC2F5tW3FbtvPDBL9vyln0uQmJxj6iO8CIPpLKWZhxZSDbRBdJ+st1huSBgrWGrLxgLB/grYwTegI6Fiz0G2SBFfGtSRjhrqpWG0aLEaF0BM5ShtBikECOMn+JWkq/2fnSoGtDFVlRbvLWSyGRllBISRimIVSg2oujUOiGOdNpaycCWOQVj/jkIp42aMlYcxkxmGcKntSvZNxHUellxsRj3eVRXEObNaKY4lvyyM1sp8scqEn5luWDybGLGBnZbVyKPM4qIuiIRKCaOeBvK9Ry1BbWW2NmwNAa1WnRZPqInYs30n1UJKAgEXjiowSF4wKZpeAKE2JT9HpcdP7zkIBpUpfK5hR1xUpwtCNmOyITSWBvTHSMjnmaR+QaaBiuGZepykFqsYLK1SfY9JKj7GIycJiDcYEjGCdaLNZE3TdG21hFQHSHOc5thTXlDUlwIyxWedJ2d/FAVFcsmTuZAqA5KZgvazFGRsw09+FELHO4CuplhV9C1/pMzVZx9HSGEPTelKI4hC6j8qGUwBD17q0PdwEZJiqX76yuCQtqyHkaY9JMYORdWF17opVugBRMUJySW3swdiaurZYk+bEROdWSZCdF6fRygs7zXsrxgtWGAxBgfDCnKjWlm0UJoZzqpOnbTKYxBB7Kn+bkMQNLWRwNlLlCmMqBf0VAFC9piK27hdtcsvt2qpoxWRNnmXOlWSnaO6QmRKkCVDKytCzM6uraGiVll1rrWjsLYG2nDE3QXIj9zKt0WJGstD8mf9Bn7esC6eRgrDzdPabJWAxJ01LcFw+9vA+rCar1szrQM7LGTn33kzg6jLhzpqAlj3CGLPA62Q9mWy1oLHYgxZonsxH1duLwnKT86Rs31rVzdran6QAk3Ka2lMnBoFdshXl/vLCVMA5KXIYY3Aqvh6VGZGdjH8BOgsbJyYVfbd+Kl6NIagIfcN+38sdJnmGhWlRVYvQWTe5ruvJwK1bt7g4v+CNN97AOcezzz3Hu979LoZh4Kd+6qf4yZ/4CREub1ve/e53s1lv6Ls9JicFnxPEEW8syUiiWqISuxgLAfCYxro8E3GMdHhXScu9LXNs3gNjlgLsGNKBCcOkCVfGfjGfpvlTWu/0NRMzBEcYR7KpSFnkErwyIGIIpFHa+k10xEkioYCibp4zLotQfy6V/UNgYGZV3YiysiTUE/PEzgYRoZwBaRbMF8awn885YzAhTO8jrcFyGJjyZzPrheVFgh+NuMWWdYrGHfN9lT1JOj3KGBpKy6lVIflibqBPXO9DF5Ouy7mtr4x/2QetM1PsIhNa4rGS18zjKCeYSA547Cgi5o8ePSTFxHqzwfs7WO+omgaz2+ncvBHbGoM1btIiijnN7ekc3utyDpU/l9bFZXt7KUQUxt2sUbsoKpj59QUXm97TOWxemJXoa4po+9J505pihGInHcxknO5j6Yn3mM4DirzKvNuVoU25jIUUVgwCIFkj/z0MA4PqKJY2RWMt7obD4qzLJg/eGCgSGYePQLV+y7zXARljFIMSmObQfN5IcGtznkkE+plR2/rLFApjBM9csM9Znaw19yksOdTcIEUdk/Ls08G9zrnGcn1ou2MME8tbWNMy42yJ9xHgL0d5LilFnd9p/u43rqapWbWNAmHlo426mApr//p6pwXmxNhELu8/ZP/4iurOPc6ONzgsYQicHp2x95GeoBIeWVsA0/S+KT8NSILaO2rvWFUOhgEbBjovRd9xDHRjZNcN3Ll9Sl05mtUKp87Xm6Mj9vsdMSVOTte0radtKkzOWC+F2tWmkeLwTbmF6Wkqs9U4ar+cD2YCkoBJf7Ls62Uvnd+q7G0KTGlufBN2Knv70y75mTjE2xJMSxqL13Q0kRnCIpbIWc57JL+ZWbVFx7ZoIOq9ZUOInwGN0+vzGgirXU1dS7uKc46qrqhqsZa2WrFWCYepEp91sGdGjv7cGJomsF+Ixq9Xe/7cd/xdvvg9l0KzrR19J+4Jj84veP31h8Qx8fjRBZUznJwecXp8xMnphuOjFau2pm1q6spJ1SLCGETXahwTIWX6wfB3vu+tfPd//hWk3H4O335OxSDzdb/q03zzb/ow737na3zfP/oifvvv/WYurz4XNtnhe9++teM7v/0n+PJfei5CiyHSD6JB03UdcRw4vzgnjAPbqyvGfqAuWhApKRsHTIPM7OUamUArGJK4fO77gV3Xc73reXy55Y1HVzy+7BhCwHhDGtVJKZUKRgnE5gBw+c+UpEz/Jxt4qWiZeasmU9xtDpMq9DfIsihtzqAV7KkyNmMxi+vm4stgklTEFZEQtw5hQlWVo209XTdMDMVFnqVJRCY7aTsa9ol+P+J9IoxZqrBRWSBmbghNYxJZHodqb4mYuFWtADm8MlAip7lqEyU7VraEJCA5jzgnWhzea5KmwVwRQ87GqGimvE9TO4bas9+PuvkZjBeB7qq2qrtU3Mw0WElir7vb9eyue4YhkaK48uVcKlvzuMsZrwyXmERfxuSpCmZAHWaSirUb7ZGXtT8MsqE2bYWvaxyGmMAFi/EGYsbq7y4/0/rMMLHoD5+5ISHxhNW+eSPi785Ja9oY6XKvgIVq3I1BgrjK0lYtKUahUjfVpCkGYihQNVJlH3p1wvWOjGgMgtG22kITTiI0q+NcKocWO7VWpMnNSN7LKHOjsDtkD3UamIgui3cW2zYEH7He6PuLg03fh4naL0YBBkhavcmTiUDVVHgnwHpVWfa7kb4vgaoEN8OYsUHBGCetgDkNhJDpulGDQGULRhWx90V/gkkzSyrt2g6owaoEp3kC2DMKImpbr6+ctiTOSbZBQGen7qLOiY5XVTmMhc3Ret4PDEhcIWCxtRKoWGepK0cKIsg87KWlJWdomlkDKE8RtlZxJ7ZNAQczTQ2Nd2AyJoutfEyJ3fVAjknAZqcVPJswyQgoMSXAwm7d78VlzFojoNoCDPXO4Z3o90mgkqjUNr0EJaTZNZGcaVcVwxCok+w3da06eVYc6swiYFw6LzrnEJsYM5WDSgBfklAJjpdn4Px7GGFaFWDLmpnWb9LMUMTJz+YPYWJXGjXrUA7AlLwV4Glx9B6AAQU4KAHm8mc34kT5vQkYnAPPGhkv6z1StNGkrAAP+SlvVD7zKeNRwGe5hTwBCQXo8piD+11epR3LljNgAX4YBfpLC1IZnyWzoYBXB1pMU+wlLY8C5EsbDxo7hCgxR6myW3W7jApkyMJwpBv6JgXMMdaRgzKQCoicZiBsyXVy1k1xS9ak6+z0iMZ7hl60D4Wpqkm5dVRVvUi8FqCmjpn3nqZp8VXF+977Xm7fusXHP/5xPvXii+ScaduGGAJ9L+CZs1ZYF1nAwhxHXNFoU6a4rE07tRWOpc0/J50hxQ3RSWeEsYy5JNqLBBs5D3ddoA+JVSPt+QamtvQUJbmYCgnkCQBOobgIHs5pa4SJnY0jI2eFdapdmCI5z6YyZR0dtEspUJ9NYBiKgckMeJdvUORM5rkq/44xEUwUgCpq6701s1ZNTtPesQSQbmqHypsF8DVYEcYuekCar03nWAkiJjx+8R4FuInaUjezFaa8bwGwlH1E3kO0+7Iw0l09AUrln8KUmuagjqtzjuiiMs3lO5PtdJ+H61tWcdlTU0oMfc/FxTld1zGMA3VVP5UlK7nVsuUTYhyf6hy7BCmWz7v8nnOOXJj/WigQEEQLuwWkWX6+nZ/bTfBjuR9Mr8150sgq7790yS1X+W4Zj8lB4a7CBDPTPc7x8/zIrTKVSywRlXFa+VmgP4TIMA4M48gwiGlVytrG62YnvqmAySEL+GBsF2eSOLzGqfAhYFgpIswmEtMYqfZdSoXhX0AryHmxVyOAmtXYfPrYxWfHlBg09jKg+pjiLJt13k351cFV2giNFvfmVmEW8/1pzzhrDigxX5xyTudmll45p713Kj6vxUxd+1L4FWORtqknQPb06Bh3OfLo6orTow13bp9w3B6R+4Q9dlSrikTAqJun5FpibFRVDUMuq3u+HHnS0xrINJWjqSsh6mQR7z91jiEm1kcbrBEAz+kXaZuKlGpCinzhW+/IyrXgjKWyjvWq4eR4zfHR6qnneBk+Z4U8VPlqGlvrLC47kpE1Xhyjyzg//Vr+vZE9xtwwOclPecUiXy4Sm8uQymiMrqe7vHtegGz6uyklQpoB0JxnSQdpW7YMIzy67N7k/g+vz28grGlpfK2L1FPVtVaWSmUhP4GeS2As1clpXRrIJvPX/i9/gz/6bf8S3/o7f5pf9VWv0I+jtIrkNSFGrh5fcn5xweNHV+y6noePL6ltwzO3z3ju+VvcuXXEZtPSNjVN7TEGUkhqcSpMl26QTePFl4/4r773A/zgD30hnxv7a5oyrFYjv/4bP843/YYPc/vWNf+3v/FL+CN/8lcTwi/2sSZ+46/7JL//9/5T7tzugIowOrF6HgPDsKXr9rxx/z5D33F+fo5FWhKaqljdo2LOsimJBsQwVSkyGZOgHwdiFF21/dCz73q6fuD8cst239EPclj0o1DtYxLXsRiZREYn/SPKYpJkd2aRLCs2JSFRfQSlilqSgKQmkdOCHsC8cJNWhpIxOK12KX4x/aIkKk/b7NFPDxgDdd0gIvSw3tSs1g0xZnbbTgLGWBzqFq+eEgfUpVAAMRDzhxwNvrKMo7S35cxU3TcpYU3CGUNOjsp7Rck9YVx8gac4/+QyhjljtGWpaYROLC55g25e0vIloumJYRAqtbPCeumHpC56Iuhce8fJWUtVCbNJ9Lvs9N8YGMdEtw90+5EwJnK2gBhfFPBaEhRYLvEYJQkZU8AClXcTw6MEPs2qlrYREHfJFDQRlVaEFHVuqC6TCRbt9zjY/2UPKYHmZ7iMBDTOWsY+EcZEHKNqBMrztNKBia806Da1HORq8FGYGf8/8v4t1rYtO8/Dvn4bY8651r6fU+dUkaziTRQpkopoKLIjWYIlwZID2VACwQiihySAACMPeUqAvMTIS4IgsINcDCRGgCB+EALJVuwkTkxJkQTDQgwLVmCFEklTJKvIurDqXPbZe6/LnHOM0W95aK33Meba+1QVqbyUMwoHdc7ea805Rh/90trf/v9v1lh2OwEhdrtB6fcVYx2nU+o+cFWDsUrBeYNXs3cfvBqGV6yRdve5CJjqBvnMFjTnRQ3tqYjHqAJJQdtfG6vG8vDo0Q7n4XSKxFlYdiJFkEncAp24SIC0v9rjh8AwBrwtUBM5ZeKinYkMAsIrSGeLJSdLipllSYR5odYmQWx+XE3WqCBAqcQUdRwtNqxVaGGpitlvjLJPF91nBgV7Q1Cj2CTAvndWK3BewFBlYoIAccMYCGGkVZJbS/Wq94UxeG8Y9x6yoQ6OcbTc3c6cjkmLOhY/rB3uJIEXGD1nrZJ28FXWwG4MLHPEOU81luP9kfMpQbXkUdhUuRR2Ck56HMFLRTSXymkR6WTtQYcmeI0RZg3WFDWcDrgQxK9QslnmGBkG8ee0WJZlIWUBza4fDVQqzhuGvQBUy1IZre/M075MNslSX2u6TUngVHSnMphg3jo5t4CVNSsY1oEKNejWT7j43Za4tp9v/mjbe2t//zBA7OyZdxRSKm9LJx9Wr0WSIv/uqrB2swuIxCxTa9KtZgNqPZCGNebUw6vkolJXbT2vPObGnpbfMxRbuxyu7TNZ29NXzd4bK6oBCaWuAN12/LfJJX5NhhsLrz17SyYBFqUL2yJNJ2pZAQiqsJRjigray+8k5whbEE+Tyi0I2RoC9Qo36702AAZjyVmKNc4YUsmE4GnsM5BGHTlXAe/D0NcGRtbq9fU1tVY++ugj/uAf/IP84T/yR9jtdvzMT/80r9+84dd//dd5+fIl3nuePH3K8xcvmKeZ0+nMF148WUGWWqkl4Y3M0ea/09hgxqzm5tJdW8Dvity7d46gjDgxczfUjTVAKTAvmbvjwrxkDCNBizRdnqfAh1GQVsZV3kP3VGMDKrd3Wds6sYAAYdZY2qq1Rhilw9ga38je5oOYSI9j4P54r3teVZa37ufV6Bq1Ak51cKztF9LYZlkm8SkbBmE8afILtUsQ8+d0OmyXs068EI3DEHSdKCNMgVjxS5Jxk3n6NiDTGJV5sz4UOhXg0TRfocudrIFspmSMyQo0NUld7uylZvkgFoCtWORWIAzNOFsVYbPnGG0uZq3vQLwBlmUmpciyTJRSGcdRcqEkhZKh+Uy1pLbJRDfeYBfPUkqfM9u5sgWi5BVdAl7b4kLbZ4Duj7gF1UQUXvv3rfuLnO+9IYtMUJGSuc+L22SvK8YTKMpk1mKY2om0PLKtWWsM3jbvtdLj+Lgs4mVqpGvqMkeWmFiWyDwv4nWLMNhLWfl2DdgR39U2Rk3JsGERK1A4zRODdk7d+UE7Rlqc+sVegn0SzqJdrVHWcgdGNjL0di8dxKUBiev45yQNzqzzhHHs7GnnHaUYaUplhdnZ1tHK3DSd+Qcrc38FMJUl14G0DRhahSCQFQxLRtaEQACmP6szlv04crUbmWPSfTxhjHjN7g875nPkPE9c7fY8vr4iLxPXxXI8nvHOcdjvMeqTmzHYYWAYBlIWT/AYI+PuwOHpI9J8kgL35mpzBZ0rwxh49OwxV6Xoc8szDWNg2O3E89xYvMkdbGMM/OhXvshnL98wxxljYT+OPHl8zaPrA16VcBWJzTVFkj0dBc28NlRo7HhdX1vrmO31LoZd329bTKtw8TY3ar/2EAxT0VAHwFb7A/lBp8oJ2ecqtjQvsvZ5a6fXVgxYSU2OYkRtNS2J1zc3fO2r33zH/b99/UADYePoGYbWLaJtVK0SstIyjVmlwx37auvKIl26gKfPIv/W//YXMdVRisNhcCby2as3vHr9hlevb/nmR9/go29/wo//2O/jC09e8OGHL3jx/DFPnxy42oXe3azmNdjMqTDnyulc+Dv/0Zf5X/3vfoFpPvD9X9uMwPDhF478+X/x1/gzf+ofk5LnX//f/FH+3//gh9hOmN/NNYSF/96/8iv8V//MbzIMBWM9uTpKSsQ4MZ3P3Nze8OrVZxyP93z7o48wtXB92PGl97/Qg9mYpCLUJve8VNJ9UdlXkgqJgmopJVIWcGSOkWkRZtjpfGaaxRAfJPGe5sySigZpPVyktW2utf25jFEbrTWla39SSCWzDyNiZVm0EpGpPlMXewl0byp0hkzFX/z1Zl+mbg7ih5d4A6nXUBCwq+gGeLgKRPWlOB1ncjKbaqeyzwoQ5XBZFglqegJTLLvRoS03FLiTuwUxjbQm46wnDGL6PU8LyTlyChgjAMC7rooEZM5kvIVh8Iz7oYMDy7zQOsqMweKtx9vMskgnIOscu9ET94V5bl4FAtqUVKhqVG+tmrLvBvbecZMkoPVBZHMpzkhHxqyhmpPqk1FmZ1XlYl2Tw90Yul9YO+TTnMgkzG7ABkO1jt1+ZElJ/eYKp9NZ55B8qAsOnzJxUd87TXZzKdgALOtsu3j9LThVsESo96azlqQg51imhVqjzhNpHjHufO9KZa0haCvlFJN0ytQuWcaY3rkzXQdKAesdp7vEIkQGWZv6/CUlweyKwzphQsUYqSeplrpgCM4wBOkiKcByhaqeEDVKYOEsYTAc9iP3dxPn88xhZ3n6ZKcqW8NsBAALxbMskWVJAqbPUaSJxoBJuOChZpF/Gi/dc32k5qz0e2FSOjYysSryxpwjzntKsRhX2Y0e5ww5R1oHz3U/qFhv+pnhg3SS8l5+ZpoSKaoZrtUOp+pd12SrzVNJmG5ediDtnGEU6JQcaZIEw1gFylRkZ1cQ1xlDMRbnKm4MPHo0MM0TJSesG9kFj/Xis1aKbgJmA+t3zxwAy27YMQ4j03IklUIYRrULM8SkrLXakn+oRpLhXDTZxGkjjtSlVEYrpuv8rhgHOGFyGiMsnrpkdvvQg12vAFfOBePRzrMGa4W1mHKkJLgedsQSLwyfW+DVAp5qGvVT332R/TypD6EAmnRAXirUuYNCNVeWGCm2iG2CAkVNNvmuy1lhMLdkud1Tl1c+qFK3e/VmDadait78NrZg0cOrJRPtav3VaqlUI2xda4xGifLZuWSR0G2eu/37FuCrVGKO2KL+RQZJfBrAqcmUAGHSdAIFEZuPSLvHNqbWWFJOPTk1znaZWq5VKrib5MUYByZ1g3FnWsGjAZItR5f/Dt5TfFZGrLyvFJfOxOiNLvQXi87hNrdRgKSqPLzH8m3+a2K9Tc7FDN8xL5E5JhqmIYm6fHZaEqUaxt0Vh/0jAaRqIVWLd5733nuPR9fX/PZv/RY/+ZM/yZ/+03+aEAIff/wx/59/8A/46le/Si6Fr/zwD/ELv/AL/PAP/wi/8su/wvl84umTr2CMo1aR23Wgwyijo1Zp9GRXiWvKiSVFqh36jLPGEJzD+9DlTq3DbqkC9MclczxFjmfZi8fRc8hVGK3Gqq9b1fmn80rXcEmStDYrgYfzOKVMGIJ2hkudxZzU81GY6a0glzcgh1V2hhU/U+TclE7RrTd37X8ushqDeJKuSznFKJ50ChZ475WltHqCWdYGMReXrp0GMHkLS0HkJG2+NiDL0GVLD0Gs7Xj0JHGz/jetcPrW9i5ZV3vHKcsZ3JK/dn9tPT/8PeecyN4bC7Oxwjbgs1UmjMj3vRZXsj5i7aAbCDCWS2VJieAc4IU14kQtkFKkRn0/KXaWTVvv8DZ42u65rW/pSvjwdej+ZIXJ25i5VWOtxgQyxm7OkCrqlGHc7M+sHR/7h7+d9APd/qPFkdVIt9sQpHtNjFGTyZW17fT+m42A7MHqXaxsqmmamOeZ12+O4lOapWt2A5OWeaY1LoJG4qgdIBqGIPGHleKPbVLUjayxKOBbdC4NIfTnyo3FZre5ErqPWqxdWOeoSoE1bnQKgJci8Wh3MtZ5kvTF+TDoO5O5IAw8w+35hLUaY+r6l7gftutiO42tlQ7VPbpWELfqPhhG29m+OUtDHm8qxlaZL0aKyn1aDJJ73Z/umZd5s+9b9ruRaZh5c3erskx49vwZX/yC53h7zzh47uY7qrG4O489gnu0g8NALpnz3Ynb2zvGq5lweNz3YbOdXpv6lHWWcb8j7ASY6AW2B1c7yU07B4Ljw+fPOHgvTSxub/EWHu9HDrvdOk4yqr0Y7p2T0EH38M4g7XPAdIXI5zPALq9SkipxlCXY7lZ/37m+XSpQrMBXkVB2xcs32briN0UJL7Ui8Y/x3Qes/RNT0iK/kb83nozhdD5zf3/i5vaOTz99xTe+8e3v63l+oIGwhh5W7QAZFxn1fjiZSioLkAl+AzwZOdvKBjXOuWh1xBDnzHyO3N6d+PSTl3z725/y8ccvydXz/vvP+Of/+M9y9eyKD957ytPrkeC3B2FlO5dKhZevPP/G/+Hn+Q/+n7+P3yv7C+Bnf+YT/sKf/zX+yD/1W/zr/8Yf53//f/yLv7eB08/+Qz//KX/pv/0r/Pwf+FgPP5hn6f4YY+Tu7o7Xb264u7/j5acvmaYzj68PPNH2rBW4Pd5LUmLB2iJgRTHELEDY3f3Mq1d33NwdGcbAkhLH41kCeSnOkKpM/laNTKkyx0JMhZQrSyrMSyZ46YC2gk8tNW7/3v9ifcoKUtYXVkhwltM8sx9GnPOUEjEOyhy42B0U8W6duwpBkjiarwObKsnnvTdtI+sMtVpad6dxCITRcTpGDeI9h0Pr8lHJx1m8GOr6ObnUnjEYC1gBtQRAMIxjIKbKOUYylXpxqAgbaBw8+53h0aMrYsycxsrx3nCq00UiJr/jaN3bnGkgjWd/CD3gFQqtUJSt9+z2gel4ki4vrWqlsjGrAMq4EwbKMkulIwytKijeSkuK0nFv51lSIQyqV6+GZu+TFqlqiy5fWTNVzfmtYdgFhp1SxcwaNFSz0tVrrVRTODzea3tlkdGIT74kcbVUqIXmz9U6obYCa8niV1XyQi0DW2paywOtNwQvVeOk3megydvWm4016XLK2rJtshf1jLGVaNScXmUnBiSBceI3l1X61ZKfbA3LAiVHZTUlfAi4sCMvk0p/CmYXCM4TPORFu79mPd60M2TndoMCW4Z5iRx2IsXDGOZZ3p8fhF2ZYyFnYSqe75Mwr1JSOaNhHDOMjsePRnIunM+zBFipSMDWAF+VdDrr1M8gC9hFRgy8oebKuA9Ms3TfHEbxL8iTAO45FhgN+/2AMU4YJkshDCtYYWzF5AZ2CTOj5CbZsz3w3Caksr7lfU/zrKyNiKlGTd+lUh8GK2ob40ixYq3M4/Mp8ujpyBL3zHNitw9cX4+EQdZAjM0nQwDuUrWJgqli0q+BlDWWWjzeQDZRAO4q8L2wDI160snPi8xSGrZUI7IAF8R/rc3htseKb53DedlHxp16MKUKtnT2WgtURKqbwUITORoDDs/o9lAqp/PCcAh4Ncb1Tt9vKSzLIgFUEGPX1knVgI6psJXmJSrDT7pJ0VgCLWmq4kVXq8UV6drYK98PzuKLYLQBIbaBbZqg5KL+UUWZIKb/HH3P1kBefcFyyX3MG7t4e1RULr2Y9I/JaRIwxwhItQVA4hL7fXWJEIbgQvf4AO2OtvEla+8S2xLtIk0uVJ7YgRf9n9c9qMny2th0MK6K3+R24MRIWZsjuAYiWBrruD2v3PuaIVxXOFUYnIMhcDpnpmWhNV5pV/OZE+aTjEEuItfzIVBzknb2rPFgA0hLUfuAouCjvorgvSa4+p6rmjObpImi0f+WBNN7iRdsBap0JH7x/Dk//ft/ii9/8CV+8Rd/kZ/4iZ/AGMPXvvY1vv71rwPw4z/2Y/zRP/rH+Mmf/El+/dd/nV/+5X/E4+trPnj/PWrztUOKQzHnbcag705N1VGZZy605iNOk1DrLCF4kXi3eVsKWZmv5ylxmlSWBcxLYl5y7/paMx3EqFbmjtXGH8V8PoAswETCbAFhu4JAlTUZ03Qb55WdiyTdt7cnUpLOwW1qSOFwXRewvtMGGGz/rM8TIz5q7bxs+4Kxsqc0YKBdwQeMkTnRom4DvYvpegf1u7CJ1kti6tqjwYp2Ny+5P0dRcHaN9Da/jzRuqFX2RoyR7r1rSUibJKzPLOx8Mc5e5cgSxxjnaN3aOxMLkdUZJM5TvOGt55A4pBKLeKEZ7/F6DxiJ3YxBpXbNTw1Kygqc6lxtv6Of25j6Fx6cb41EA8XshZdRvzcDsWriXCt3r1/z7Pn70iyNxqCyF8/VihcP57LXn4lFmgssGHbugPdBCi8+wBL1OdsztCR/lQlS0ZzIUnLhnCSnGkwkYbqJfRuPlNOFKMNaK57KVlj8OWdccNJAYVOAac8kAAIMwZBKeatrYElJC4cDVs+Hdr4Lk9BpIU+AtyaJDt7hrABqMco+IWOKdG0sGUrEO0PFUjLEJTKdJwwWjCfbK2q5p5REMuB2tvullbKyh62yK0MIGzZl5eY2Egbx/i0Yrg5X7HYjxhRykvUdl8guvL0xNdA6eMf11Z7zIp7UMcU+94bBM44Dh92OmBJvbm9ZauWnPniPL375S30cjzd3mDeZOE88fe85jz54QR0gVIsn8PLuhP/kEx4/uuawv7q4j1jWPMLYZjSwxlfvvG/aWlx/xjnHs2fPyPkxL168oNaiXaVN/8UWs7T1ANqQrIGsFBzr/GisaIkPNwD6g2vdWys5L5SkRAiE3SuglNUOpbImzDZfly3kEgRTkklzHywFUlqtq2rJYpPRpOWab+bqKARyFXuSlBPH05FPXn7Gdz76lNevb/nkk8+Iy/LOZ3l4/UADYbVuTDNVbtZpnS0Qkp/UpFhZO1WCBmcN42jIsTLuRl69es3d7ZGbN0c+/vgVLz95Q0yFJ0+f8nM/99M8ffaYD77wjCePRsag2mAKSRPgXKAoTb0U+M/+4Qv+Z//Lf5qPP3nC28fcd30y2lIYhsQf/2O/xZ/9078KnPgf/qv/TeBP/BOMWuYv/je+xl/487/Jkye35JSZFwkiU4qcTmdev7nh408/49WrGwyFx1cj+9Hz/pPnG4NWuZa4CO07F02qhF0zTZlpzpzPiU8+e8Nnr27JRtgVS0os2qXPOQm2ix4kpWpFuMIShYlRS+ktdOtmUV0AYbWp+WvfYmrDjnQ4DRWM6LNLzZJM2wrl4oQE5Gdtew/GQG3SRzVyrCv6vl4GNWcCoHfbtogBcpHqZQieZU4crgbmKXH9KBCX2uUBMSbyOa6VG9NuTUOIAnjxLnJGOhsaDGNw0qEtr14Yxln84BmGEafeT2HwhF0QsMF6jueE0c5OSlWSxNSKt5MkEagHmUD7uWQGu/qkOG8ZdyN3r48isVM/qpr0wNa4MUapBOUs8sAwWGW3aSBr5KU1VpQzhtO9/Hwt4rvlPaRkWLsm6TBZkRFaL1IX2WQ3wZVuCfOyUGplN+6JMbLb7Qgh9Kql+MAYwiAVQOkiqAGn0uJLNZQk0jeZgHHd4Y0B4wiDY9zLod4rjFXNqY1UAY0ptK6Cxkr3PQFt5k0gU/He4kMgeG2LHTNDcHhg0oOMIkC0JHvCUhiCJGnz7IjLQsrShMCoDtOpHDXnhLGeuGRySmJUnyvOB/Z719em1wT6dIxMk3rG1EoIltu7M80MGFRqZgVwSaniVD4dQkCSvULrRniaMo+uxCNsiWLmLBVINbQ3BusNu30gzgvGetKifiQlEdzA9fXIEhfGcdTGCIBt8gFZs00WGUIQ38M5cTrJOw6DvLfmRWYt4mVlpXIIanY7r/P1sHcE60mt+UYuLFNktwvS/SYEnJVq7hA8w95ildHYpGnvf3hgHBwv3rvm9aujtNU+i3nxfjTsBvH2qxhy8cKWVWC2gYRtrngvvlzOBWIuGC8MP69ZjozpJpEo4ptoPewOhuN94fpaWHbdfFQDEGtRXz+HCJ9kQQUfdNprklYqx/szYhQoEunBW6orFJMpLlOLxWGYU2a/9/hd6Ga5VTf1OJ/lmdTkuFYBj3O2pLzp9FgEzHPWUauCaFo5lnciXTjbXtXu911XZypYB06sDVoC1xlLTXZWawdWqBBZz8aYIw63yi31umCPVC6SOmcdlcqC2Zhuv32tBs/r57bE7jgdLzzRLn6nybgMnU22fe5R50mpCj5s4uGYI+SV4fbdLmOlHGytylqqVKWrXb3gMGZbJF/vU/9/HMXD5DzNAnLllUXSJHHOCZNYvGIUgDSGmhOpJMZx5LTMpN6MVxvKKDO9yh/qPUsQ3wyUoXkOruOUS2YYdzg/9JhCPxhrLD54fuZnfpqv/sZvYGvm7/8n/zEZw9Mnz/ixH/0x7u7vqLXwm7/xm3z1N7/K1772VWqt/MzP/0Hee/GCmpeLZL11we5At4J/Vr1sSm5yw9LvpXkQFv39yurZE1NlmgvnWYqUwrqvzLNhmhO7ndOGN6g0XxqW1FpwJvR3uQVeGshljGFZFmKcyeUE9gpnpYPf/fHINE8il7INxJP1PAxBG1tJnDFNCzFlZer2b1CQpfZ19y4GxUOvr2Z+3WXJle5b5J2XtaCeQtZanjx7zmn+DqHNzFrxpnCKlVwTncj4jnn7rqsqmOqVQZSLmJe/a2U3yZ4kv5I9Fp1kqRQw6n/EuoZqXYtnnVWiN+e8yCNzzhJHea/d2leWZxuT9kZb4m2296T/L3NNrQ3iwpbV1T9DmXvDbqfs38pSJ2E4vjVvROrc7R7sumc1Ca5gb6X/zKUv3Ho1Rcq7rsbOenitcrz1WZsv12rpAjjH/ekkjYzMCtJ1AKqI57MzMAavNg2mv59SisSWpRD1XBKwuTWqavHpJSbX1npjW+VcMKGtkxbzGmWAqswUAXx2IXTrj/as04OuTmLTIXnqkpUB7Dy1VvVDfMt0oMfG4hMqv+tMwjtRERVrsH5HPWdOS+S03PLosMfj+hyzahGEvVxFxtiLObBd3ykVwtBOCyOA4uA4HPa4/RXTdOZ8PiIFt/VU2U4Va40oTnZ7YVjOlpSEZTwEz/XhwKubG5YYeXVzw/7ZM54+etSf/e488fHtLS9vbjnOCz81jPzo1YGnjx7xxUdf4nRY+I27lxyPJ4IPbwFhv/TL3+DnfuaHGQaPZW3AlIrkaw+G+gKN7stsw24QP0XHhf6ntr8TcK/nyqiMW0Gyqv9rDRZyzXK+Fm2ss3n323Ur8vP2ifpnmitZow3WXKBWiSG03kaDY4yR1269E4CrJCoiNY5lBb86CKYPkIt02C3VUgikVLk7nphj5HyeuT+epNnANPPV3/oGH3386WYw35Zqv+v6gQbCUhGpG2wQ0c+9MlqeBmC/C+x3A9MU+fg7H/HpJ6/5+ONPscGTi2Ecdvzsz/4+njy94sMvvODp9Y5xWCflkipLTiyNXl8hV8N59vyf/trP8Zf/6s/zuxvetmrlqP3ih6/45/7EL/GHf+Ef8ff+/s/wP/6f/hmm6fdqfg9f+vAN/8pf+jX+xD/7MTnPnM4TN3dJjFhz5NPPXnF7d8fxdOTVzQ0pRp5e73n26CkGy/35ltfne6XCLqrPXuVCYMgVTueFu7uZaRK2xfk8c3N74u7+zDkmYpVN9DTHLqcoLVCusiEaJJiu+h3tzyU4UGS5jZdBF54AH0+u9pzPE/O0SNDWVl8zHTYNZTZY2yQom4ShIdNmI6vcgGMXwXP/+81AG/HL8iqLu3yv8p/SKVKkbDkVpmkR7wprRa8+RfFKSlmxFa1UV0mQhN4sXbZ6Ewg9qLwVYLGZ5IbgOVwPDBfG1pDnSAX1NHLMKrnE2M5Tqj1Rq/JM6o00z4t0NVKAMAxeKmBOfBdqLlKVCE6rbsIyuDpYrh8F5llo4aMGXWJqK0a7UhmWDbv/nXqnlYpK+rTaYDaSZyP3ap1BvOPEiN1Q1fgfZQ4kYl6wZqBWwzwv7HcjoDR9A8EKwyDn3JPK1nmxF15Mz/P1DzZsMNe8ImC/H7m+3pFi4nxa+ueIj4LAJ6247CxkBX6b75RRyr21g/hTGavGqC1AlEA+hMDxeKTWQhg9JWrioJ8x7EZcGCk5Yq0YmduDJcZFut36IB0gKczTwnQSOcSjawc7S4qVesziv0AlJ1gWi0E8EubZUBX4sppsZ8QP0ABhcFKlDpY4J6bTIv5oSeZxQQwuHz/dc3ecKZM23FDJO0aYELv9wP56pKTCdJqYJ2k4cD6eOR8nAWRHr2BqwFuHdYayVKZzlLEYA96K5OTm9ZkwWnYHj82yX/tau4G/Vb8uiiVHiEsmmiSASjDUOsr6UEBKjL8LN7f3IgsqsiZbl800V66uAznPwjZt+1mFZy92+GD5na+/Vm8RqNEyHgLXh0DBcZoQuZD6mRVT+gSqiI9RrdKR1AcrHR6VRdKSLNODad0Pq+H+bgJTSSkSC+I9FzzDKFV14fkXKSTsvBYfLOOwZxwD2Cg+KQRevbphOkb2e0PwAoQeF0Mus1Sth4FxGKR9eVwugj753NWIuHezoguMOojhHoA9MSXtzmVZ0sraQj+ztrX3jsSoAeXvkhiWUi6Cwy3LpgFhxmxMivuzfD6YdfH3FWG1N7Dcfv7vNcaHx39u5bZUAe/8pguZNDMAjDJk3xEuFS14SF2r3YP8f2OZFWW0NHDhu9zp9qZ7E5TGgmiXSGAkAUspanMWea4QvMxn7a7Wz2EjZ6gADe18fttzbRgG4hL7mMkNV1KFlAEn+/44eHa7kSUK+ysE39Ld/iwheGI2wqb1Mv+li5XEa8J0sjy+fsQf+kN/iB/+0ge8evWSVBxXj58A8I1vfpPf/OpX+c9/9VcJIfDBBx/w4z/6Y3zwwReoVWFlTchzTgzWsShwImvX9CZQtQF5DTFoz63sU6qce7bNf825JeEsPSEClKGdyGmAsb12aSNUinS5M85uutwJ6NrYSHJOO2I6kbKMd0pRfQ4Nu92Ou7s75nlhGJyAeTrHjbNacNxOlxXcKbn099xABGjrdAP8KDDcWGENUClF1kIDs62x/Uy3zVhbPeXubm95FzuTIsy5ghTbL9DK73I5Z9nvQgfgTJakrrNGjVEvJ5G8OmUeWgT0KVa+r+Qk8YICUTml3txmZYsKENvurD8fkniG4FZPr88BEksFW1uorMBHNyLP/bwoObHkdDH+LUFu6yOEkXk6afwlP2vUumPr27yVThojnZbb3tvecW/os2H/Xb6eIvaxRsbh+YsPeP6FDzjf3+G8J8cZiVneNvJ/eDW1Q/9vIKVI8BZr3l1AMaDxu9H5ZajKHt/tdjjvyEvp91dzJOeFWmdAmGX70ffiNfp51MzggJoYHKRFG0EpU94ag9fO60OPSw35YZnDVPb7/cWasTrfYi4sOSI+vbLHv0vq28A3Kd45vHXCFpVTmhx1KhiD2V+Ri0gt788nHj15zrwkcpW9fnCFJqKSx3F9/Xag8GKOikKggYwxLcyz5h1BYvq2d7a94+G9g4CEwzAQlgRYvB+Iy0zKkd1+4P0XT/ns1Q3384nbeeCmGgyFm+nI17/1EYNz7A47PvjCe5Dg9esTo9+xC4nqwe89X9w/4pufvubF8+cXc+r500cd7BcZvhZkjWcspTdYiEkl5LT88btfTuPtbRra5Oht+LpNQwPMEdZ29wxtLH7naV6DMurrWqm19tgyZoezhQaplSRBg3gxFkp1Yjm0yc2McYQgtiTOeZblLBhBlLO4xR3rrFi/t1aIOXB3jrx+/Qn3xxM3d0fmJbLESC6FIQRKzkxLJOd1LKd5/t6DyA84ELYNJN8V2Fnr2IWDHLrphPPiXbDfDXzy8Ut+6/bI8fbEdz56Rc6FL7z/Ba4OO64fHXj+9Jpnj3bsRqcdz+RrihpD1woxwaQykn/8Gy/47/+r/wLT/Lvp/Li9efmOn//Z3+Jn/8Df56/9e/91/sq/8yf5K//On/y9DI1ehT/3L/wWf+HPf5Uf/fKNmjdWbZsdefXmDW9ef8Znb2548/oNp+UENQq10cHr+yO395+RF/HzwpgOQpVaGb3HGqc+UpZpTtzcn3n9+sjxNHO8nzmfF6Syo+y9UrmPYoCdN0Fx7IePJI+iN9YloT4xxgr9GpXtNQIWJWKQIDqlTOsoCaXt04q4rCNjTaV107HWYHIm2yAA20Nj4/7/K6hlNgePqULprEZ16c2OYS2t9f8wRjrRNRzJezGYTzWzP0jHj1apoaKyENlyYl2w1eKyF5Cp1IugQTwGSk/inbdcXe/YX0l0WxUYWZaIxbC72vHyk9tN0iNg33bjtMroqUXgpTlm0cp7T8mL/oZWIDe72ZIMsUBcBKw+7C2PrgfQallKWRgzVTdoC95mYQRNiemcWaYkAXosYgbcWmJTOxAGwrASv9eK9bZX4jpZQxOwJidJMTMMrQJlqEZAPKwASqUUTM6YaREpZZYGBe+cFNvLtHemAaihlzd8cLhgKYuAKN2bsGzsAzTwX6ZZjfpVxmDVUF+rlbaIYa81UJ0IvOZ5ZpomwPD48RWn48I0LQLEeCdgzGgIfo90NRPKvsgwHWH0hNETp5l5jixLZhgcgwZHyxJx2ZGdVJpyzNzd3FOJeD/gHBpAiqn6EAKKA2FQoLNkTdQquyvPbj/KHHaWuGQ+Ps4cbybOR5FQypyW8Rt2nsP1SEUDwNFzPV7j7x13b44qHwTInHMUWeHsuwmoscJyWebEsizY/Z5ahO1QsjCErx4N3BvD+bzI8zphQIVB/MRygvnUWCIF50YMrdsmOsc0gY/aJVV9Q2Q+WnIU8E+s1CoxV0quxJi5uZm6FE1+3qyyJ2fYjw4fYI4wn8UXw1rDsJFBWQPVGq2gOq4eBcbRqel0JRVJSlISFk2MlcHD+T5xvk8yv7xd15TJ7EYZx8zKXkTv37mKd4GUwBRDNuIFN1753nVunmaOR2H2DEOQ+82JaGHOifM8sx/l3bYgsF2lFmxtG72ew3X1RfEbf7GUS1ND453vSe2FabX6TrXiVZeZIBYLDxlcrcDwruRxK1H5vBjke13dBPrBfvIuedDF31vzlpTmXUlek2d2KVBRUPkdfKyVcYOMjf55LllZRfQgundOsw43PIh53snckM6RKaV+Zjnn8WHA+kCtIpkWrmG++KwGNDcZVA/++7uTH2v5j0gDJWkNQ7hgzxmbKTWpV0npkuuKMNBLlbjRW4PV2ID2LU46bhlriTkpuGwxbZ/WezHGcnXYsR8+INVAdQHrHE8eP+ZHv/xlbu/uoBoePXrMOEr3yFqmdbxVYhiCNJloBcOWSGMaY+/d77uN9cU7MOLxudt7xkmKbPNixC5hDAyDdLxtlKCqmW8rhjnXOkev86M2FF/vTWT2tRcwnRsYh52sdVUKSOfbgnMtdrm8hsHjhFgAwKzdK2vrJrhZi9vnW99vi10EuKOuzKMtYyzGKG4Zev53ZUnXATxIppGfsXWN/b6fy1mr5twCdLYOgg2UsEYbAKDxFuK3F0ulVoOznmybSfsa+8AKIjnj1+7GiByxy2YR0HSZo45PwLrwTjBPnpHeXCDGRM6X4NFaQNHZ/jAsKpVaMjVH8Y6gPuiwikoly1t7RAPepPOfpcm0ZU2J9UOMXDC5Hl7C+PU8fvKU5y++wDyfOd/dEOcTU0rfozTx9nU6zmIJsofdzkJ1UrjTZxu8gpjWXAAQBoNxcDjsuTpcEcICRRpcLMuCqRKnox2v2y9ux8mYB8OrINhSZvFzHQLGSm+9d7Frt7924UGpbE+MAuqlAbOtu/R2PLefs/rjtc2ugfOhOva7K6zx+OD5+KWYlIsP9MzTx9d88vqszaugMXWc87gwSOE0yxlggHG3nikGAcKtBauIRYxCFvBez5q+H1zO1ctn8Qw+MPhA0bld1DQ/7A27PGDuIcbMd25v+PR0pjjH9MlnnJaF6jw//9NfZvQDaQKK4XQ/kQssO5HvT3cz1/vx4ntzzrz39Hoz/yuV0ll53a/QmF5vlFxVfr5ZL1kjFIUGZsuv1O7Jtj7z22vb6vf0fa2iseD3d7V1r79KZbUxKiXjDQQH1EKtjdTi5P06bcjRxqMUsiq4trfbwihrUD9LKbh9+5M7Pvrslq9/9Jr745laK4+uDlqM9lxfHzBUPn35mtvjmah7y5yW3qTle10/0ECYtWqGZwTYcD1Ql8OqqLnk46sdLjzi9vaOaUnc3R755LMbXr+6YT4v/PhXfogX7z3lxdNrHl+N7EaPD7YzNVKuLFEosK2qQoXbo+Xf/Lf+Gf79v/Gzv8s7rziXyFl8JrzP/NE/+mtc7b/NX/+b/zz/6Fd+7J9oXHbjmf/WX/wH/Jk/9XWuH4mHxyefnkg58/L1G+7v7zmez3z7k5ecTidinkSuVhecq6Cea8YKwGWLweYibdatJSGL+XiawDiOp4W4FJZYOJ0id/czp/MifkhVDHRrFglpLFnRbxBAqQVSevOlKn612cWq+I30hdM2bisLBgSNDj6ofC6+BWZREZkeWlCx+jnN68sa+QH95u0muh5Ubc2WfiCYWgUAC7p/bc4R0xItBRCtNewOAaPVf2Mcjx7vyblwfzdxOp4Zx1HNLmsHavojK8CDTeTs8aPVxFmqurVKwOpc4fp6FDZd6Vo+agucvTDDjvdHQDymUhIttXyayNFaFRZ93/Mk0o1xL11pxsMonfVGAT2WJfbBqpVeWQvekZMAn6bC08cj13uhSFsD3hhCNczHzP3dwukYhXkTsxqY137gCnVdvZxqZRyFjt7HrJVRNIBHD9iSlI5twFovrKpamBepBjmlErcALcXc5XXi7QMZowGPeEmE0bLMThIZEriqnXh0biPJ1XROhKBBxqAAZpK1hL2sjhpjCOOwWRNrYLTEhNVOn9aJZ0NFPF7O05lKZRzGTXVVpGLOyYFRq8p7gvinjXsDJsieqdTCuAgr7/rJgbS09tDS/SiEoACd026I4smz3w/EmKUKWEXxn3NlCAHnLWG0DHtDzpYcK+6J/PntzcwyVU53C9NpoVI4n2aRvxpPdbW/j2VJ3N6eOVxVdvuBYL1IfRtgruurBQe1wrJk7CA+VcZWyJmS4XS/UKsEg94ZgqM3OTGaBMZlIVwPaP9qnFdAWhPQUqQy7lzQpCFjveXRE/H5isUQlB2ZKbrPFCyopLMQcyYX2KknTs5SXfPO4Q47hsGIp5gzfRy8F5+9+/vYmRJ39xPlqrA/DITBk8+LskLE9LodWDFKAwKMzIPDwXN6c+bbH585naQRgrWW/fWACzLHfLBYrwlb0YKEF4CuKj3X2oUQKnOSbqJ+dOLJcT1wujtTjXwOqWqgLWzIwQemtHA/n9nrvpdrxW+BqFK6l+e20LvKNNYUoOh6d4YOtsg6agFo6Ub6FEkOtnIiDF0y9fBqTJ2H1fJ3mm7r6v9eMsImt17ZVcrqbR5f7c+l+gQ9tpGJapwnr7o/lcW5DWgg3eq251nOlVQLtlyecd7LodgDU7Pun5XamSxtvDpAk7WNPMpiMMJWpkm3NqCVcUFMr42RYpZz+v5UNmMNJTyC5ZXKlmfmGJVtKTfVzNaH4BmCE/l9raSsLCJ9ntWE23aWSVUgprKyoVqVfF5ir3gb3eebRKjPoyyMF6xliephZxyDsZSasQVah8s+J0ybl5VhGHj/vfd4/PiJFCk2c6vWumn4skpxW8cveUciBRVQPl7INh9e28557ZU2yUxREql3jsdXI0+f7ATU24xf99QyBhc8Xn0iyyYmaPOu/VaTJG9l2rtxR0xR65CyV+cifrTec3GPIEUEMchXmbHuXa3gIOb4EqdtAdctC6zLgtsrMBsfvQffl1LivJwpteCsZ9xdYzCSJCtDfbCWRZn0+irfwpHWMXkAlBmR46YsCas10olaxljWl+wDhlwlzkhFkvF2vy0OaOCZrB+1ftA5Yox05yu5qJ3DRs5d1vuzTs/6urJv2r7/9vi8m4G1Zc1ur3avOSWsFjSGMFBc6zIr87AU15lmrbDZQL1SJe70ugUaawlOEmq5T5HG9d+tVRoGHUQtY40A2PP5nhc/8mVu3kTS7CEHzF7ufVaPx+ZPuO3W+PAagshnY8zclwnjdxgTsCVLR099x8ZpR8Gy7ivjGMTmYDpTUtIiuaNUkY0Pw9qJUgoEbe6iZ/sKVJTxR0jzG8gnjKmYYtWI3xLCyDDumU+373yG7TuDlX3XzlBD2RTS3gUA01k2xkorl1ykEV0pAdhd+GTHJdK6aedcOJ7PGGM4jBvA2tD//+FaEsJGFKBPk66qjCmHMNlKKUxTxJiAsV69IhUwZxsTrCw+awshJIbgWCbJHyxakLZgfBXP0jQzLwuffPKR7PW395yPJ4bnT7g7T5iDpRpDTIVX04n5tjKVwqs8cX3Y83o5Y4zner+Td1mEfFIOloLBqOWHyCMb+9og0uPNvl/VniC0PWwrGf18ND6941ywpr1NiU22s72dedvC3vb8ylnypBS1ey2FKS3KYBUApq2gWgrWiaWKD0P3npN3rbG01d8zHtQfzBrIxpGx5LpQs0jkf+tbL/n1r33M3Wnh+tE1uRTGYeC9F8/44hfeU/uEidc3N3z62Wve3NxzfzxSa5Ii+jv2r3dd/wUAwmoHv0S6AUuMWESznWrls5tbjvcTr9/c8dmnt9zeTrz/3nO++N77fOnDF7z/7Jr9ITAOToy9LepRVVmyeCkssfbN/De++oz/0f/8n+Ply8e/yzuuPHt65vWbAzkHrC38s3/0m+z39/zNv/WzwO8WULv87Pff/5g/92f/Or/wB7/Dbgh89HEkfztyniZevn5FLIVXb95wmmaohpevX+O849vf+Yj3PnzB48NALJHMIoZ61hKsxxaDSZXBOe2NaEip8OmnR47nxPkcub9fOE6xHwQSNNQOGpYqEYTaXlCKpVSl6X/OIbT6dGlw6ORPYbtYBZEenKcUoUI+lF/oLfS9I9WMKVJZNWU1bjW0BOLtY3GrW5cNdN0ojOIfxq2/dxmC6h0YSWpjLFxd74T2r6yuqkDWeZqVcWjZ3kWTygFYIx3pjFtBstxkcEYO7y5hKIV4XrpPxDgM7HYjt3d33N+J90HN4Kz8rBGOuYSeGpRYA9ZW0pKJVirhw5M9YfCMO9c7swgYIBT8eFrArYymYfDsdgJeLEvheIzs9x5nDDkVPnlzB1TevBZvrFKrgGBNLoTKJJ0hUTA6bjYYhn3oRo99fvSwC/VQUg27kS5A0xQ5HiceP77CuEsWyDAOas4tCZN1ELAMZgVLrIElFYYRpmypBE0gC1grv1kLOUbi7DAMGOvZ7wLznAmh+dVkcFU7dZUe1LaORAJkyLws2k573AU1sg94Z5inmRQzUk+WilwtUUahrmbfDRTLpTAvM6UKE+/J8wMpyYiFwYt0OGd2Q8CFQqV519TOjrXOsTuI7ON8XDBWvBzOi1R0xyGozFjmvA8Gj4O9vMy4ZAGJciLeLaQk3m1ZwXODMJ2urgbGXcCpQbp1hvM5s6RFuripMe3goTY/MbTTnreUlKXzTM1A6mDnPIkH16PrQbqMIQHLPEXOxxPOmzWpLQIoWWPw3lAwVCtJeNsvMKjHn8cHTTIy0NrZG5R5qG3KTSUJyZZ5ToRxwGJJ88Iyz+z3o1RA9WyTPUlM78NgGEdh9MWl7Y/K2qziJ1OyzJNhFJPCHCV784P41R3vMzefTcxnKV5EBVSurneMe4sLDTS2uNGJz00uKscUeWaMSd4XkkwFDeC9ghPLknj+/hX73VMmPSfsJjFs7IZXd3ccrp7SGmW3fyrCPrZV1lJVcOlhsvbwqrR4wKyfpwBOB07LKvtplx88xZQeFLYAcRvINWbVNliUwHUFQPp/6z7Uv+NyS8epJISiLCD93CZhfNexePHsZgPCmcYWkgSZlkz1QoZ44qQsnhzVmO7HOYRAqG2k1mJ0MeWSaaZf3eUrTdYURX5gmqxJbQyqdqszVeRnwzDgfehMZu+8xlpVk3qRx0u1vigLwGgQb/q+K40RpPNgm2vZOcbBczqe2IVdP6+71MqY3uHsgkmkle3mWdXmivfakXzzvBRhmxl3KeZrjB6oOFPJGDBBwQoL1Wxn4kXS0eS1RotytRRSjCIXRTue0wA9rbAr+JoK8j3tvVlhwhkjYEEFRuc1slHgKBeysrEBfDBaBNAuq6WuXkxmlZgaIx5gKQqo5YLfrEVhD5Wc1EfS9jUQhh2LWmjYEHonuxQTVhn+7d106RaN/Q3N5LyScNZLrPigyNkAba/oSZdDb4pI75ICXqypKkXVNM8aN8neYN24Jo4ax1razrLOjaKJunVrcbL9PQgA0jxq28K2ChwrFY9SLcKMzBf+Wdvxad30BCxZy8UpJZ07lyyPt1lXWQrF5nIdWF1bZggY01hY6553+Rlt3NbnF8aW+I+VnMnGdNuUvpfqszTJeh+7Kp3km3eggEDKGLLyud5LfN+8rLZJrvWeYRja3UGOjGPgo29+nTAEiWfU9zZvALQOvpXS37fYMdBBMj9IPCxNDgq+LuAdtoDrgDXKjKk9XvXeMaj3XZrn7p9mkDk0J5lH3m3Gh4p1EleUUqjuCcUeKAyYOjO4JE2U7KpmkPGWOGr/6AmnuxtSLn3f/Lx5v55d9Pla6mq+369WzDHrXFtihio2GhKXzFi7x7qVxbUb98zLRMqZeVkwxrAfR7Hp3lwpVwGZc1WTd0tOlZgih2rZjYPmIpscyFhKtsxTwZjIuAtYr0WlhhzpPF3nqsqHvReygLUEL/tPjKmzgw+7UVQgpwUz7sjHe4y1eGu5vT/xzY8+o9RXsq/7gHv0iNlYvvXxSz49vaaUzKPDnsMw8Ad+7Ed6c51aK7vHI9aIX5ooJCq1FePkLvWMU0BZ9+JcqqqMvvde9i7gWjaudJGT1s15tP7MarPRWODWWmIs3N+fO0jnxiumZWYIMIppMKXClMG4SqCQcuY0zRpfeGVNrrGbePV6oi2kUkk2UKx6uOcK+cx5Wvjqb3/Cy8/ucd7zJbUQsNYRl8y8iC/Y73znY169fiPWLgZKtRicsnAvPc0/7/qBBsK2V86Z80kQ2f3gWZbIze0d9+eJ2+OJr/7mNxn8jveeveAXvvLDPH58xaPDjsPec3UIeCuLLSZ9MVW8iKRLWOU8Gf7K/+Xn+Mv/9s+yGil8P1dlHCLDWLi72/H6zQHvMz/z+z9lnj1/9//1lX/CJz/x83/ob/Ezv//v8vTRHdYaPvr4mquDVOLe3N3w0WcveXP/huADn93eMqfIfI5YU0kR7BgwO8s8VChZDVPVnFjNpU/nhaU4QvbYKovj7nbh1auJ4zwzzZFqTF+81WzgLSO+B6o+Y8nSVhegd4bbPlIPuFtOUDd/rIlflUDZGDH6m9Pcg1oefpb+U7WjHlVSdFMFFBH2gEiR6rYXd3+Fa9nC6PNUBBArzRPLrLnLRZpW13v3weG9YxwdKUaG3cCsUjnphFFJSySp/0PbyI3RA0rvq+VVcY6MwV8i+BgNEvRnc+F0SioRS5zCjLu/xxo5ZOJ81mrw6ivW/P63/3gjh1TRZLjmfNFxqYN5RZg40xRxTqR3ORcqYo6/Pwzc3S14b5nOEUzizZuTVprh/k7YLEX35ZUBIWCcDxY3eEZncMFcVlizadGZeG0lVsZGFZZjSZmYBIAU1sHC8e6oRrKGcRx7FytJgsEE6W7pncOAdAUylcEYxOLINJxT7kfniNFsVLokesIQKMXhvWGaF7xzTClSnMjQSsokDcKsKZo4tmSsaLXLcDqe8EG82gCm81neWXZEMjnKfBRGmCSlMUpwba0w9UK07A+OcQxMp4WnL67IuTKfJihycA07x7j3hEFM9JdFGAGuB2/Srr5Ww3yaxfTTyByvZgWf7eYQlxUszCDvJVgrBvwoHos5rT+bUyGmzIh0lTxc7TgeZ0rKHO8WqWxieoU+DEZBTT3WlHlaaca4ApLFuBD62Aak+6h0MjVWPDd8EBOikgvZWKwRQNQ50xPbYXAMg+MUpcrsvYPdQCiR8/3CnAQUtArENplmk4Wn1OpokcNexrzmSlpmFm/YHQ44h1TYnAC9hSRszFFQd+cK01mkTnsjrJFlLgoy6d6gAH+JIm0+n2aWKVKA0/1MykW75hnGfWB/HahIQ4beXc9VgrPsB0tMhVgEGF+mxNVhI2Ow0vSjVFn7be+6uh7YH8THIcZCTNIdKJJJKfOdT77Di+s91noqhv0QelB+ShPUymgHnKs9UKymkkq8YIX1IK+iZVCjXjwPpAF65ZT7hu2rX8FEnbtdWqk/1Mybe1pgOrQhQDvgve9/31he+h/yf40J4lo3ODE035p6fzcQbC2cwOq3Y/R8Qzp5PbhqEbPmaZ45T4sYJFvH4bDj0dWVMOqd7HHeu47ZtUS1ARsrCLYmwJfgHAqWO0xuJ7Z2N3Ur0CJAmATHJa0gSIqRwUhHVO/Va/DieRrgt56PitmwzEtnSWw9o2BN2IOXpHpekjCYod+PMcJebonplt1UFRkw1rPtdClFi8t5VSvgBnBgcsUkBQqMA6PeW+1nEamIKUW9KRPLPDPuRmqaad38QnDsxoFxWNlt4C9okg0Is84xL7N0unO2F4lKbbYY4jnlNJFu73m0gVwSKUf1jkwaAzpyzMzauGAcR3bjrgNOMUqxdVkWME7Pr8ZcEni7aEFB2EoRa5FO7kbYt6fzhDGGMLTYek2YmnxQ4rg1wmqWB8aazZhswJvKRYzSribRbIyYorGoNZa4bJrUNBkqAiDKnDO98NEu6VrW9ozaPf6267RFj6Y/mgJgxvZEv1bxQkpRvNi2zJ11btUuc7pg+Wyaeny3q5ZCrpEVkZDKdKH0fXIYhgug5F25dQOPGzOrM/GaL1spF0DYdo9oP1tK6cC8rC23+Wzp9hv8QeeZzN3K6g25xoZ2I3mXXPCzTz5BGNRegDktegibLKuFysq4XaVmco9OpUb5wfRJKWFLEmuVTZ7SgOXtNQRtbOFK36gqbTyNxgNVn30E63DDSMkTAN4s+CAsGVOz5iqbPYk2HyvLNBHnmVqtAPG5CGDfigzW9sIFiCfTNqdwokfrRuX9XfW9VtdLmkA7qfsQsFa6b6d8TylnrN1h7I5xfEwtC8ss3brnKntrsLXndSAFmVqNgr7gNtWivoY3c672lySN12JMhMFLfFQzS0yEEC68QbcFkZRSbzZTXOks78raQfJQdxxTYZnPfa7FWknTwqe3E/6wJ1rH/slTxqsdLz99zSd39yw5gqncTzPj4cB0mvBBGObjOFJjlsKtsdJp2Vqxihi083eFYFZ2VZsvORdtBPRub7/v67rYs9b8EFreUmkF984eVT/FnFO3hjFGOiU3s3/9w3UtII01ihPViFjLJHbDgFOwupTGLHZkMxJNm8uyvnLMxKnw8cs7vvPpDW/enPnwCy/4B7/0azx/9ggfHF//xsd881uf8Oj6imWZuXlzz939meA8z59cixw8Rnbhu4mG1+u/EEDYeY5aZbPc3Z9Y5sTpODFNIu0Zx4F/5g/9PI8PV4y7QcEvLwFVlQN1SbIpx6yAZBUa42evd/zL/51/+fdwV5Wv/MgtH396YJoG5gWurya++ME9X//WU/7Rr3z4T/TMj5/+Y774w/9XvvDFf8B+V8kETrNX9tcbjJWDZFpmPru5IZWFlCuPr0aOszDnTqfIo6cHlpSotknbpFrTAo9SYcmFpVbO84xjJk8Gbz3TnDhPkfOSlAm2OZjrGuwZPSi9dRqAPECi3zF2clrUi5zA1iz+YcYg7L8sYJi1mCan1OQHBd0qjeav5stVAyoKzYdAgnw5+JwzpJhVaqihS7/dtuAV6FPvrNYEpcu6G/DWgmmMJj1iGp5T80oyxCSH/hKF6ptipuSkQYbcq7NSLbFV5KHGIKb43jEvMvdXHxG9CUXyS4VhVAZbMQQFCVKUCsF+J5tTrZVyViPWEtcgyxjl0wcxEbZmE1xnTsdZpGrBSe4ZHD41u335HumQGbDe8vrVmXH03M2R8zkqmJL1PVTinKTBgQYK8l2rpwHaJSUXMEXkoXqjAlpooCMbtb5blb1JElsx1bHfifw550axjmKCXCrTecZ7L++qSPLmvGPU5HxXJBidzpFXp3uGYNW0uYW6MnbSZbP2+ZBL6ubFzkm3zJBdN83NVlhClMLoVjaCdZbBj1Ity4njMauvVJL5Eis1r4CZWKOs9yCgcdHKHBz2A7VkcrJkL+b6OeWedAgQW7je7xS8K1hvuR7Va0mZTOMuCAvzvHA6TaRcGa72fb221WutYRjlfcSliAfcKWKMJYweEzPnecYgEsQGitaKgj5eGWeRYbB4L/L1zz49EpfUx/P66Y4UKy44as09kclJ6l9Ok3EfvCbEkhR3DxocaRF/sWH0lGpYZq30m4qza/I4eMtuN5CzzJeYM+NuEC+tBXzwiLKhyRoFRC25UoswaqXBQiZrNbm12Dlc75ii+jJpgwSnay4VAZZ2B8f+ynM+iZ/eVmKx3UerRpIiZzDEJbFMwhDNi3o15ozzAsSlqL5hO4stwtARSSUU7zBV3n+cI/OcpLOs1WKiMxgPdQw0RknKhSUuBB96FXsIcH3tSalye5eYz5G7eSbmiLcDV4NjDI+12xoE48T+V8+EVjkuVRqNXF3tNsnB5lLPNqute7dML4wEeg1oXo+dujJJNsFjD0DfdVwhyVf3YWkYxaYC2gATheNlzrn1wy4C3AeJdk/6eAA6afLWzstiKqY51K6/3T+ysSDmGLk/Lxg15w5qNDsOHrezvc06ChS0PaixObq8UcHdLejUQAnZd9d78bqPY1siK/dWlGnRZN67qz02FnxeWLS7Lw+lS7o3lFJ6olrUEqElPC3B2bJQoEnAVG6mWb5B5JbZCfBujMEi7Nk2PwQsW02dL9+N7e+nMd6rgoZGjuIuPWwFnu2r3r7ukqXIEsaRnBdaEbCZqjcp6RwLMV9OlAYwiD3CjmEc+/twRu5bfHhKZyW0V92B3lK1A9fEvMzqDyZn1rIseO8Zh5HdOIpNRpOpFWkwctX8cSp93FNO6umTVL5aGIIVW4kiidP5fKRWeOQESGvAa9F32Bg/WyZW8/xr3c/e8p0yXPx3bc+XCrFsoEj9kQ6IKiDTCqtt7QhTHWU0ssrINkuyeTt2SwsF1kupXTq8BcBqn8vteap0SGtM+AcoVFHWl7HrGhOw/W3Prc+7jAFjlBm1AZmLFu220vAWl60f3UCjdbzXoq2wRKtpnpjlYg9s39H+rigrN6t9R/8x/bIQBmXwKDvLtffC5R5jLMc5st9rt9cYydrdXjpzN9ZnJqXYv/vheEmcGDqA1sb74aiWnIlYIuvesCQZiycHI7GCDzg/4LwjzlHPEwUYrIAIVp+tpAWvAG8pmdaut8Ww1kRqycKs7TkIUpDbzj39/FIyzlhla8v79s6R6vrMjY1uN6Ctd06Zb9s1ZBg9LNXgFMRvagtrbN+PjEF97I6UMjEMe8bgmazhfJpxOROHwGEvTU+6g0it6gdVepfndabJ35v1OOrAmDECpjVZq7UWsrBWQ4js32Fv0FiL1lmG3UgrQFUtbrVu4rlUTsZyTAmPdLdOYceb5UyYEu/tDeHqgN2PLClzOk99Drec47c/+pRnQ2BPZb/fcXV9RVxOmiRWyblrxe53HNgxavJYkQznxCBcpiogd25nkv/+gJ2L535H0FJrdxi6ALtrrd0PFFBm9npgtb3Web96SrZ3IyVIKS6UlU2esvgsT0tSoLoo6xgtrmVO08T5PHE6nzmfjtzd3vLt77zk5s2JWgu//fVvkWvl5aevMBhRMNTVamOJQiC5Oow8fXTF4+s9V1c7nj8+8Pf+3t/5nmP0Aw2EDc7inSefZ46nifubE68+fcM8Jw67PU8fX/P82WPef/6YMBgePbrCqNzEewlaYlyNu1vL22wsv/Fbz/if/C/+ON/+6Pnv8q4Kv+8nX/PVrz7j6998AsDTJ2dKMdze7fiNr/1uzfS318QXf+Rv8N6HfwPrf0cAlMXjjOPT6UxKM97DEmeWJZJzJJWEdY1qWfjsTeI0LeSkgfvNiUWBGe8N4651PxEq97mkvlByhjlnlqliSdyfI3NO3bg403pzWkYnFFCp0KpMwRqSjpH4UOljaTzXfEfqOxauoWKLeni17omgEjKjXj5dqUyt0sWyVmGaULe8sorBXtBNK0aCM6201d6xcZMAacc8Ld/1jRokuLUPc5B+5zImPkh3xZIrQ/AY4yg1sSyZZZJ/pAqbaOwfqiNXBfqM72bVErRkaIGuc7jg5ZDPAgKI7KaItlulrnsTBLTzDjt4wiB/vyyZoCh+k1waDM5LshiCY9yJP5TVtuMi4bB6GDllkBSyvobT/cyyZHIVpuV0FilVGDzznASw0eqfgIPandGsm3Np1l4tCTZaRauIKWsR803x6VeKu5r2F6NUY30xtVaGMJKM4XDYySFTCn2oS2WZpbPgMkt3Re8s2RSpyB8G9oeBZhR4687cvTlDFalgzdquPsr3V602F2WfGStG5OM4YK0hl8w4Bg0+srRSjllbI6PBdMXYoO9YaPpWmXnzlNS7pQXe8v+lKpNJK7ZooGygB4A+SDK6LNI8IDqDdxXnrfhpSdqtXiWVcQyMuwGwTOfC/e0ZUwTEnKdZACkjYOR2Wa9rriUFFeMM109G4pwZc+F0jJymCeOqtNr2RgDRWkmp9MO4ZPHS2u0G9ruR02npJsBhHAhh0CqsZY6zBuxrguB8YNiNPaDOpZCmRRqiWKhWmqn4HcSlMs+ZWi0jFe8LNhmKkT0jKNA1LZl5jsogg/mciHPB6rvo4Kgyq4pZg0isUPmbvCEZYSft9yNLPpFKxrJW/lv3R6wATOMgVcLd3pJiYTpP3YxcOqCusp2qCW6MSYIZtGmHtRgstRpcCDgfpGI512ZDQ1FdpzGwgPy7tSLbdQJ0SkXeE/OaOEvlPWrDD9sZcWLan0kUgrfczZXrvef2OGHIpOjxzvPiat9BLPpc0qqks2IsHb+L4asG2QKsvyMwtsrS2XyuyKFsTzDf+bEP/nzLyBX5XboAwPrnb4AsAZ1t/3dn3UUA+ta9bj6nttzdiP9WY4U1o2r9Mox1G1hex800qVURSXtLTG2Tol1+bwP3nHUXIFdLyNp/O+/wzgt4RXkLMCpFpT92HZfmIRNT6s1y7AB1vCbEMykbTK5YW9Y+aMZ0Rs9W1toS8yYjayyANhfbmqhoIF5U2vkgYeoJfU8SzMo8cqEDgv2Nti6sDfavlWlR1hVAlj9zrYPnBtPbMpgM4kuVWzOBh/5y+q6tdqNbtFj3rnkiYI5K6PTPG6uxQE9gq/qQAtrJsXUoXn025d2tfmMtOZ9n8dGJceE8TZRcGAaHxa3nnTEcT3fMS+L+eCQtM8FL844hjDqCsi6ErWxp3k3WOoIfKLXgg7Rrr5vOoQ3YaIywi2fX/cYHT1zeIY0xKyBuFZhq8UMtBtM9+yzVuL5+vM6fUos4IOjU6QzVFm+WtifK3G5nP/peRS3RwJkGDK2A2cOi8jrX5N9yyVLHVbBQWBjfmw3W5oF4awoz/OG35JxIyV5IoutmHsC67ra/a8y6D0qMIXvZOAwXa6ogDLqtR9i73g+gMkG3An6bdy8/pn+u42/gnYBge9cpiR2C3Pvbu3utAmIZI4CKMYbamYjbjbH2z2j3UxTUTXVkPzqG3QG3vyKVkSXeczwvut+BC4GdsTSpOlr0lYHKCqxb3DDKPrC2fO3fvDJQt+eLXP7B+qWi0tKyeX59nxsg1DirXozyWV67qIuyoYjkOYyrR5/cOcEFYY265iPpGIIh+JFpmri9PzPPmUfXoooxKfdGHw0Y5R3z4F0g5MOHlT1X77EBsHnjZ0m92Eudc+zGHcF7JufJWZhD5MwYAhZhmjlnuTnPDM4JcL2/ohbLKWXuq+NQId7cM88z52kW9UYYORxGhjHw4r33mGtlzFnWm1UwvUpH3XmapHhQK8kIQSJo0xbFyvqeW3IhIQoPoK+FLRDdC1PbYt93uVpBprJObVslSmqfba3t+bgATpqDaB5zKVNvpA/5zFQKQ2cGW3KWeLDVHXIW9t79eeb2eObu/sTN7ZHbuyO3xyNvXt9yc3vH7ZsbASw1PkjGiPdwy3OSeB4/f/GEZ0+vefLoikfXe549vuL6asezJ1ffdRza9QMNhN3cHLm7OfPpqzcc7yfAYm3gxfNHPHv6iPeePuLZ9YHDYaQ66ZTWeErzIvKMuCRKyeoZYvjb/9FP8K/9m3+cpjP+/q7Kl3/4DeNQ+I2vveA3fvMFAFeHheNp4M3N/p/oOXf7r/HeB3+V3fXfwbjCHD0me3KaWBa4s4VUFu7ubxkHs9KNkUDThzVYy7n2zhw1i3m5cXC8PWMMjDuvG2RVI3TxvMlRKvGn+1mkiFPh7ryITKyPgk5yysp91at1VRkHz918AirBOvrKQRfg5299NIvbLkypWuc3tXUU7htjiyXqBQDWPqdVs9fPrrWKx1deuzS1oL0nEtRuEH15X+vPDKPtjJbGKrDOMoySZFrnyVn8IGIUOdb5FJmmpGDswwM3yzNUNa3WysGiTJiSM2EMUtkfPNZUahFzTwwQ0e4okpznLAwgEHbItiOVeDu1wAPtvuUIg7BnQtAOg4PDeZjnKHLE6hQYbKCyVPmWuXWGrJxTZj5LoD3NeVOFUD+yUjtwua0Atc21AYCtuQJGJDi1iBl6SrKyheXQMsWqQGjuh4VzgWEM8lzeSABcZF2YKu88JQGkqNK10AXLMHrGnSUM6mOTCrt94HA1SmecWCneEWcJEkouYFcJkS0V56u2gBavq6u9J84JbzSBLLWz8axFATHbk9XmEyIspIUQBo7HkxgMqxeVtbL+m8fI1lTWqnfZMHqGUSSrOSbQADzq4Xd4NLBMSTytrMM7MX4N3pOLgSrSV0sl9ipPxm7YE90hScGs6bwGjyKZMYx7j8+FuGSoHusTtdgecMu8lNdd2rozrYuOYX81cvP6jB+kZXvrUmOMdNuSal/bBzZSLmsl+Y6Z4D3jICyKVDO7wwhWWG7LLHPausIQKskIS2QIAhzlUojqx5FzZrmXcalZggoK3dC9ZJETikdOFSacEcNVY1ZGgLAfpMtjr7Zj+rowFgZrOQPTLHvv/iqwTEm84jShFFZvq9Y1yYPI4eywSst2S+Y8CYrvnCOXynzOWCfNJxoYjQLS2TQmhIFiOki53w8CcrbgRyu0tcQVVEDGbJoTropk1BlPrYZXr87COiuZq+ePiDVzzoWxtc3s+7QmIMYo2Gj73i4sy4AYQcscctW+BcoYTTx6+/AHgEoDUhpYtZW9lVo60OUeSOScczj/bglDk0j2fWgjA+qV6vTuzo/rZ6w+gSBWAyJBVk+ujVzKOmE/oiC7cwYGT2XgUa296HG9D1ztB2HsmUs/NO9XpmgIQf1CpFtXGzPDBjiB3sDiIXstlyJrohr17FEQQPeKZra8TDcY56X7jNHOkFbcDw0N7BAgN5Wq3VdbByqjVhYF9+A9roy+rZePJtBaJGyJbf8eVjZZLRUbbPduXH9OuymWSkLADAFV1hjl4Vvc/lGXlVWr3l1vAzftXq0VBUN6UKVfP6slNpux3wCyRmOl4C2HfQAKviW+22RR9wIp3NX+Xd55beQgoN2ipuNUYet652iyKZD40TtPjEeCD8oAKxsfSLnf3sUOo2eu1aYVIkNtvmfFxt6kpQ3iQwZiyWty+LCxRRsPKYDaTeJWe/GuxQzyb4VabS8+OedYYmKJCWcNu8F1fzVrLLk2z6nWlEHiWdP243eArlnP9VYkkvWr+yvrftELtvqSu1Tt++yKtn7nGmQ9BL3l3kU+uI6d3EtRa4YWs2E6h/ACAJMzY/XilCGXz9gCgOuzfrd7RT2SVgnjw2dpYObOO5wRNktKkuthDN7aznJclrgWBo2FB2dLK9SU2GIwh3Fms5/Jzzmn5t5FmC6GyuiKevxZrBXl0TjsBHDIkVqSeGthZW8utbOR1htAzwWDtQHTijQtAN78bJsTLUaWP2s5y7rXbSVtrZNuzhlbcz8j1+8QgkDwRnZT03yCBVxqxVhjLKlkiuZW1khBqYGy47jD+0DOhSGc5VZK7T9brbloDGyMxbjKw+nYpLMitddzXh8vBLGlaL6GS0x4q4Cfzi+n49MUISigM4SBrN06l0WYx7T5GDz7YWA+jFQrheCKkAH211cyh6zldJqlYUop7MbA06d7xt0gxfL9jqdPH+Oc4cXjUdj2+nzeO+Y58+bVG5FMOivFxROUw47haiexZQ+arOZW69zfAsItnl7l4QJm5bKx+Kn0GHL93ZUn1mK8XCoYeTHS2EnZX6o+WteI2aTTMi8lB5DPkFsuHNRfz+h3g/gAT/PC3f2Rjz97xZube27vTtzc3nOeIqdz5DRFpmmWtVyMeHqsk4Vx9OzGgaePrnj29DFPnzzig/ee8cEXXhC8w9rKEKzWuP7/oGvk13/7I66vrpimyOAHnj17zJMnV1xd7bnaj1wNgcFpu1ZndeNaA6GU6cCGAf7S/+DP883f+cL3/f3WZv4rf/hb/MZvPecb33oGgPjNiO75eBq++wd81yvx7L2/xZPn/y7W/ypLzBxPIufzzhOcY1qOWO9IcSGmiWWZONoWcGsAX2pfJOjeX7VbX6vGAcQ5E0ZPXIpIiUwFU/BVMOqqSdQ0Cwob58pxjl35BayAloGkm7bVA3NROqTJ7RdUtqILObXNfP2Yi2sLckluq8wto0aC1P7nEpvpjrn5wLVKLzcrY1D0LhQhb4HIRUVWArRaSl/0PAj0AZyHcS+gVFUNfgiWMAT1RzEMux3WJ5YlUebE8X5hOkVi3AQZtO9u9QHTYg9EVipzeVkS3kkyWoXIQQhr4haTdFHd7gUX3aQqHfAB2cB2gxhsO2cJg5N/95ZaRGImhU0Zi5SyeFokNSa0hnlKnM8Ly5TWgFWDd0MR6Yp26WsTxxiDcQ4pjm3G1DRTRz3gLyabmuAjXWpSklbM7WhvP9aSEfkOj3GOw9VOqjGh4mkeKRrs5cKyRGpWA89RwOGdGraXUogpqqRDPJXyfcF6YYQ18KeLejfAXpPgtCnlvZfxqHLQTOeZZUmdodoSkIomalFB+9o62U7kVFRKItI054UJtCxr4NyqgBKMG8b9jnHvWeYFY1awLCeRGocggJp3huDF1JLqSBllDyZOx5mSCw462NmC1hZwlpzJzpKWVZ7qvGV3EHNTU1WWFBy7nVTnUlvgLUWpwqAsOr+cs4TgKZkVcLECQLQEoQENjRF2cSkCm1JUVlXof7wbq/ohih9aTAKEUopIPlTSbYzp8hVrBCQ8T4sGjJWSqgbAUhAw1RCc17hbpARBO9KVmnvQWWtl3HvSknFBg3CzSqqELWilayMwT1mLF8LejculGantwZGsCD947W6VexcmkTujMit5l8f7RRmJdP8WNxiszRRrtWGABDvTJMy9cfScTosyqQx5yQyjxRAIXjoa1mqIsTIvmWAqPsN0SkznyPEcmadMGAbxoPNwjAv308z1OLJTgKX2+SHvzG+6VbW1Zg3KAoN1n65yMLX9RneIqv9r3SRb8aL7UilruAHaLcBsFdi2rq214GDro9XWX/tMkQ6tSfq2sluqSgnewfLpU7fdr1Z5ajvl2rnQ/kMHx2CZs3o9Sb+qLjd6/EjWwTiOhCEAKzDQ7ptKN6oOw5pEbVlhD5+jyxExF3u1VJZlDZWCgPV5TWS913FbJkqyLE66KedmWm5X5pxRGwNhYZu+4a/vXIFJqw02rNGkupG5C8aI754AYaazxEDmj9PnApW71Soy4K3bszFd8tiS9pgTJbsVPDXrPw3AepjQO+ugOLKCByUn4rIos7iBAGv8sjXlbnELRpoW14t4rImY9EY0rAmD5cqKj52cofq5tfT10D8cRC6kRZhaa+/a1961c464RI7Hk7CmqvhbDsqAjzEJO8+iwOol8GZQtp5u1bbNn5plzJ3DUMjGkypiSbHZ55uBeH+GuvrarezU1azcWoNdR0XsP5SM2bqgoX+ectFxM71z6pLks4bgCDr3heG9rp2idgreQW1Tpu0BrACPeIGVXpDsk1kbMFhnueyMuxbEvtt1AZxtrhYPXAJdlz/TmXZGuhsa5yDrrNAz12hOUEvjGa77bNHzu1bUj047NFpHa6RxsTnQGHXrxt6S+qT+gQn0DF7n55Z1G7wcVjlFMTdXQERiyErMWXbLvj9rQN3jS6uyswJWm+dgpDiq67xtaWKR0GKLLHuJUSZ8naEOYr1gLTEumJrxpnBKE2J3YnWMt0l6y16MMHnbWldgfAvA95qg2r+0PbCySnLbuNYNKcE5txZGkTiydjKWQVjfytyucsLcnxeCk/izgZ8C3Ot+l4oWoGS/NdYyjjseXx+4vT8zDKF3323vynlPKlLEt9bIvOjzk75v5VJYUsJjOouxDZVtsvVqut+bGR2UTNFiqnjUXc7tJh2vVQ3zQ2AcB/GUWhZ5Dm9FqYHDDUWK/VgtTEsjMvSd7g6OF88PPHlyYNjvsGGHD76b8qcQ2A9OCAqoxUB7OwbIhXia+li44KR7opGX5oJHwNM2X+nxxLYAsBY+qq6lFYQ2KPBVET/ESl+j29knZ0rWuMJozt+6z8sNV+MoazZOj9HVIqgimIo1wlgOGynnEiOvb+549eaWjz55ybc/esnxfKbWyjRH3txMTLOAyykmyTNNy9BlHe52A8+fP+EnvvJD/NiXv8QH7z3n+urA1WHP1WGvaztTSiLFE8sy8f1cP9BA2Pm08N7z57z37CnX1zuePL5it5eF56wRGmIplFSp6qewRPVT0r24Vbsr8M3fef/7+NbKD33xhj/1J36L/+Bv/hT/8X/6lf7nsvm/Ux/3fV/D+B1evP/vcvX4F4n5NXPM1KUlxBUoEmxZoViakpjmmXk+y8RRL5VmkNyMRsVgE/EurWIi7ZzpR5L4/mjXHUVThyCHsHWGXfA47zlcZW5vTkzzQiyCPiu+tu457UON3HOjQ8cCF6hMFTBMZL5iCiuLtv2+LP5aW80bchT2V23r0FZyNSohaomx2WysdfNRAqYIqcrgbNYKlpiz59ySb63MN/ZRR+BamKgAVU8+0CTfEUapVFCFVTUoiwpjSaliyDg13Y6LdK8TWch2w16DsQ6E6aFlrAYixiAtYrViUMXfKzuP9wbjZEN3xcpz6Ve0QEyCLAORC0+mYfSMe8duL4BYGBzOWpapcEqLNiio3Qy9lEqNEsw5bzmfFk7HhWXO5Paqa3uvVQ+oFVBoj22thWWVFLXXux1fYzZjoAGA1SRG8BDDXAo1lQ4uNJp5xWKMADxD8KQkwJxxgLXSfnqamI6zAGCgh4CYpzvf/D+KVp0FaJSgtplUF31Pmghvqi/yefoqtZtazoX9YRSZhTHM86IBQ1Y/i8yiLYutzQqwaqCp2nrQCl/r5qiePU3m0roZWZ03zgtoNOx2WFuZWSglk2OSn82VcXSMo8ULCxqRrlRIWTp5pso8J/KS2Y2OQsUFj/Guyy1iTCrBEUDNalI67gIGkWbmVFjOER8sh+uB412mFplHVHqSIKCgMoCMPJezlv0+MO4HqRoh7CpPA3tZC1dbgKCuvmnD4AiDSB9KlcMwxcjpfmGeUg+mhAJe+2FsjFL6qzJdlbVXs1ZgSxXfr7wG6w2EzL2jUwtgJFlqvknOwVIkQW2myFarlzGLRMxWhBFaZP3trjwGx3RyPZAUrySrQUqBKua242EnzJOYmE4Tw+ghFoxra0nkGpKISpdQ550C1YbiKsLUkb09RpG1JQXUc8rMU1Hzdc/VYWAYBBiIsTBNmdN9wpwMpmbO58R5kqYty1IY95DIZCMy53mZGbzjoIylB7UHBBBplgaFYCE0Btgmuu71jZYAm1Y60T9rf7+ZJ72L4wbEEuBm9Z5qv7dlhzX2V/vsDopti1IIaFbQZLgBcfatB+z3a6zBFks1TYaw+dl2drY/UzBgjpGYU5+7TRoyhkFAEF0oTTLdEqms8vLGDGuJjNXmD5159m4/gD72tbSqtd0swdqTuTav29jLmZI5RglgGxBW0S5oG/BNkirXCy61SnHEaWLlrGUM2owgZckHG8Cn4EaT0+csnXJBkk5h7a7gSqmrt8/6iCtbp53eIm/bsAgNHRxOKb8FhFlk/8nGrkbVORHnWYAwGuClKBarVLNdjUntu3pUz6M+R7bomMRbxtv+Xtolz1k74NX+GdXz7yEIswUiBAg7cnU4sCwL+52Y6S/zTFYwwwDBB7y3Fz5UpYo/UEFYHN5aSo4YrHYpb0XIlnitc881n8d66RHWmZ6b5xZGtM6Bfu/N1sIhXQldH5OaC6XELlsT8E387prHzVoMbe9J5lfKRXyitEtwb7Kh9yfWFuUBCKYTBkE5jNlKVTdJsD7f54FhDQgSBm7u0rP+3UXyCPnPd39GuxdjLUYltqYDNQLmmCqJqtiMrO+0ghbnJGovygC1Vf189dmqspxWxlubwKsUPqbUVRJVx7Hq2Esc4Dqw19hsVENs4IhZ4zHjxJS8tjiug2AiS7NefCebcV5RWa15cO60WPZdl4Do0tXWADVLl9WUk3iXlapFIfnZvuYrUDPVWigWbJFmXFkY+9ZLd9i+hyrYWo3BGwFKKk3OvxY0nNMzpjRygwE3YEyCnOTvWo5UpIvlFhzNRf2Ft7NC52UurbNhVtDJirzQipehUzbnbreTta178xgCU53IaCyhe2qtVTun67/TwLZEGEZq0aJo8zWjnV2FlCreG2pKSEyQAd/PmHfObo2tnH+7AYpXGfoYHCkb0mI1HxBSwG60jMPI1d7z9PGOwyFgg6f4oTNAAW6Xws5bRmd4tBsll8LwaLcTlQ2GEqNAlqWwzAvFBkoQQMeFncrcVxCyxRpSIF2JDaWWtdlPS/IuZi36c2+Phe6stC1hG7e2bvNUNs0jak/S2npsIHWukh/OUfK5FBNv7u55/eaWb3/8klevb3lze8f98UxMmRAcucCsnrWmZqzJ6jtpMGHAW8Einjy+5ke//CX+y7/wc3zlhz7ksN9dAIGyLqLkqQRq+S7WGZvrBxoI+/CD53zpg+cCgI0e7wWZrsiCyUVMMUuuipQ6YloR2Vor07JIUiEnJA9mz+aq/It/9j9nt0/8jb/1U/zlf/sXHvz95/3e93Nlnr34D3ny7P9GMf8pKRfuT2wOfmiCwNZZqhTZ0OdlYV6WHrg2X5h2S8WANQVXjXTkKGo+qIdPTFm81oLToFcZdKZibcDZgLGF3X6HC57rxyLli2WWhYEcX16/7yEBo6It3N8xPH09Gg3OyuZzDII1YfrCLVSB0cr62zI0VRs7yiFrW5JT188HRGJh9EC3DkxLmJPK8A2ltDbWl3h5dwHpCJyKOBvI4Yx0NHTKWlEwglopqWBdZRwspSQMRiWU4k1kDeCkwr3esO0bTL8LIQTSDGcbddqqx1BOmawHIkbYNy5rQq3P0RKelgB571h6xxsFS5xh2FkBgJyymIJhMk0KJTIR7xzF1W7Y7rLhfJL1lDNSLVRAwqKBT3sWDdKNJpG1lM4OlFexBv4GesCLQYAVZ7RDllSYGigFUkWiyucKUNEktOsB75xTsFAOAO8dsyZM1ipAbNDqkQRYPbEwhhSlC+YyRZVWilxyK0Vs86+UqsbYCi4IukSt8n2mbg0mm6xLEqc6LSxOqlhepZItAA8hsNQoXmPGdxo7Fa1crQmmc17YEe2A8w5r1NC9FuZ5oaS1+5PEJsKQKzZTi6FkQ80yD601oCyOcRcIQ8AFy3lKChJmjBGPrVoM3jqCbwEbmiBKEONtk+AGhpQoVaRSMRkF99VbrDZmibA5Hj858PLlkSo9UbonmjHKjDRt31/9mEpq7dEN4xDw2gAiZYjHxO3NxDwlNXYWWnhLno1WC7eeQLIutYIZM/MUcbU10uivXE2/V1CyKDPIGc8QZO0HbymxMEcxAm0FDDAK/ktzjRQXjreLsvUkCbGDVeN/eU5v5WiPSSW+apbtg5dmAUMgLpEAnM4R78QwPSmzTZZKJYxB5H5FQNKcJUkrtVC1UDDPiekkLLKSKtMxMgyGc6nsgqN6SfLjUjmfCnc3WZjHRSrzznnmuTCMgf1hINvKkjKjdYzB4xUQdPoe271JgWWVzZQiQbIZt10i1yDPqLek+LOtoNjF2fSOEGALbF3kBP2YvWQHl6QMr+Yvw5ogdyDu4nTZfOi7wgiZAjRWt60NxDArQw2ofZ6vSbPMsdUbzGmSPI4rW73WquNhFRho+8jaUWub+F1I79rv0xIk28dmC054vwUPG5AhwbV4Sq2dkqGSS2TLjG5rqElemulxCIGlzB34aX9uNs+7WakXiaKpRZPijKVga1YPw7BKTVjP4AYCXrwWq9LI9u67v5O+YbO+0+YjtH3dldrZSbWildna2S/rlylDzQjLYzsdC+u/y3vQLrVtXm6/r65sMmPs5dRv8WZZzw1Qo+3t/C5lZePq4wpLrCpTPPXzaplninb0K8oeGYYB79bkN2WJv52zBO9xxpDKgjXimZNy6mBxzspYUIBoC6iJR946MFsfqpb0tvsXQGddJwKkbPySFEg3tiXFzWtOipsr4KZj2mIqjMqnM1Z90loBbX3na3JujMHq3Nh8OQ30sJv3IOujNWF4lw+QURAs4H0QO4mURIpcSi8AtTjw8y4Zj42cvCpTrs9JvR+d+9bQO2r3e2/rokqs3cAnCxhnQUHJ2hQiWrRszyGFBxF+tjhSmv60d9ruc1M8rQ1AtJzOM7WBbO2dO6eNEEx/CQ3o9yGAlbyxdbdt70rO7rZPmx6zvwsMEwZtkM8DMbm30tQq9wKpeH8aK4yzJqNd1Sbovrh6caFzGOiFZAlLdO5hO7Ao87v2WM824La9cyPMt4r4KCdl/3kQIK7fhGE/eHKOm9wEjenFT60VNFIWtm8YpdnSm7uTfp/lcNgTi/pGYgg+kF2EnDrjp11Vqot9fBvDxztD1Dks8R2daZZzJi4LMQpTLaVESolBJdWXh/Z6fpm2p1b6XMGshRbnYEmyX4cgBfFxcBx2B8bBELxhCBJrTHOkzhIrD7s911c7YTAFT8aCDzwaHZwnplq5do5hGLBqn2G1u2FJmegcyWqg3c4620DkDQNso2xthboGgq0dHenv0xg6t+Ph9TmYGdYYLTRpsUnzcvWh6XtZWaepgGGl8urmDgfc35/4xrc/5uNPP+Plq1tmlaKCKBDOp4UlZm0qAc4mrh8dyLmyP1xJU6pSefbkEc+fPOLnfurH+dEf/iLXV4d13ujZVUoi55l5mUk5M83v8Ih8x/UDDYT9yI+8z3svrrVzlTC9ksofs2rucxUz7IZs1roGp3OMfPbmntc3dwTv+C/93K/xS7/8By6+4/GjI3/sn/4a3/n4Cb/4t35aqK3/P7pC+IQPvvTX2F39DU7zZxznhVJnSWxoVPGq6Lj+rwi1pwIpLpS66VYFOlN18bdD2laoFruhMDfGQQtyrx+JF5h1qGRBDj/nAtWtdGPjIIyW66vA6W7pG2GEtWrSYsE1Jn/nVSoEKweB5t3910tFKfBKaYbuE7U5i+XSPaF1u3oYtDeqvNVOoGDUFDBIpcpETXSRA0c9peReTBtK3s6CMo0P54IVYMVJd8HdGDQ5F78s66TzUZNRtMRod/BYPYCbF2yta0C9PkqrQFYBwdRU03u/BudVOox0oppVRo8GdO1dV4DmKWatdMlUAKhR+ltQJxtvk3ha6lKJsTAE16VqyyIg0fmUxDPqgf9Kp263tVcFJKhGmHFFd2g3BC1vtz2+vXdhce2vR6oCSWLiL5LAmiLWSvB+6i2jzTqORsDBVumXxMxRKWKWbZMAlJo8D2OgqpTCOaloLpNUta0a80znzHzOzFOS7pwKJpZmUF91Leq7UNRUwFgFg3LOzHMlx7QmW0ovNzqPc5aKXVH2ZEsAQnAc76eVqaEV0Wlq1bkWxIs/gcgwXWdbgQCKw+BZ5kRMIg3a7wbtrC7vaNEunAImeUy1LHMieE9xGadzwFjD7jCy22dOZ+kSVpSpV7NUWcPoZY5lTf6s4epqJMWMc5nDlccPlumUCcEwZOEDNFNvYbDQ94JatMNvLvhBvA2XJRGCwTqPsRJgSoemgdaps/m9NHacJGOZNCfu72aGwRO8GLs2L4owOoa9JwweY0SOK1IEaS7grGUYLPl1Zo7ir7Ct5kswLou75NrbrYfgCcFwPkW8rcoCFHls2IW+f1UFJ+KSOR5njncLu8Fy9XgPpTIMA8FL62lhnFlSTszLwjgOhHHAWJEwNalfGIIkrcaQU2I+zSzz0gPmYTfQWl1LtzLt/oeyzBCQsRRlcw0iCffOEGeR2N/eLJxPGR/ERDsuRbwRl8zpFPHesduJWey48+yvB6zTBhM18XS3ZxeGHqS2CbCyGlpCKmw06RacZK476YDY2NHbM8HjO1h4saX3+NGsyTDCsKVCMeV72k7knC8AkF6U2ZxZnVv8eeVqNslyXX/xIejWJAz0j98moggjyreujlI0cab58K1XyU0KtUKHDUSw1pJqUlB39S26OGcb8NjPTX2AzX9L0Fz1rDVrgQS6X1i7dgGScZQocsQul9OkubFC16Sm+cFswR2J/1ouUMuWWaT3rQGFc1aBfpUIGPr7aXKW5tmoU0GfVxnHn/ceDRdz4e13vJ7xpahcqrbRWq9+LnRQRJOUd3xvn7cKgJa3foJ3vsN+T80upAFh2onzrftuknrtmGqM5TRNcnYawzAEbm8jtRbG3UhSWn9LQlui2ySHzRusIgWnor5tOWf1XsudAbFlBW73ADZD18/hNn4KSlHXc7T9nLOWbITdtB3z1nBhO15SHJHxyE1yaWxXWEgMl3vjkodjbFjltyiQUfLlpiLszcvi3RZwXiWGtYNIYuxuMdZ3QEp8rqy+k6xz7N2G8ut3bPYYoeHoN62AjZi4o+tEm4wY6L5WVdli1mKq+ia2O65VgSCniXvV+Wov5lV7bmEKNnZzvXjffdh0fwhBgMBpUfDGSDxPrZ310/e5KuPT3nHZeGb1e6iF1DdvKaK4IuqT7lvaJpmB3qTCCFO15EbAKH0MWq7RwKpiJefCNF9QXV+teYrZ7Hu6b7YisuQ2Kpcmd9DVoPYLZusFpfdapre2I2GXFUpJWHwHj51rVjOb+zZGepNhL5o0GCP+uqUuGCRWSKWIx1+VZ20ewu1+Simi6W53pM8YvGeOkTlGYZl5g0dijaSxqvMCts+zkCWyWsFsAdPmuQYta0byNJzGhitw3ZhpUvCQZ10WsZ949mRgvx94dLXnsBO7BxAFQ1wy05RY4kIqM8+eVcarkcMYuN6Pwp7zI0cqQ0yUZSFYy+i8ADftTJUFRFGA0rTipfcEV7RZksb27zhQjK6B9pzNs+27hBiXv9/nyHq1An/vJvsO+KPZFBljMLWyLJHpPPH61S3H05nb2yOvb+84TlP3tpZtRD53miJxiVhXOez3eB/4sR/7EWopvP/+C66vrzgez3z5Sx/y9MljfvSHvtQtTdo8knceiVG6Hd/cHbk/nbm7u/2+nv0HGggbBpnMjSB0jpmYLvXz7VDdXq2Cc46R+9OZj1++4mq/41/6c/93fumXf5oQIj/7M/+Q956/4T/7pX+Kv/63f441knmIwvxur8yL9/4uz97794j1H7IskfvTSku3PkrlugRFWgUIEs+SQiqFWhaRY5V4EQK3y+jk754XGIxT0zux0lFzbQlWMBU/SEUsp0KO2krWG8LoqEG6DpaS2e0Hrq8Hjjczu53nfFyTeAFY6Djcd7usVhR0f6du4oDWfbLF/xZ68tYZZ1uLA70aYPhWsqBBI5vEo2TTD55UGmtKDj4JAmv/gqysLwnEK1uwscUp1pnOMtmpeX2TEXgvQJn1jeEh7yYEy9NnezETP4lHTlyKVsd5xwYmDAoBwZCAZCOlyblgvbJRrPqc7IY+NlkPEKowgpxxmBpx1tBCnZINy5zxoVVLJJCwzuK9FdCn6j3SwKr1gOuy47pOga5QqM2wsQFklVotuTQfkAQ1ofJ49BXhLD25r0qLbpWhQSV5yxKxwRG876yIFtTWUjo4hxFgK7fKexsLJ/T4/X7oXmBSfRZDU4PRMQjc304c7yLLnATU0DGtRTs+1e0CMH26NDPWqMBXjgmjnTKlYlr1edWkUtkNNDCxA5mVMA7km1NnWlTE3+3ufiKRldlmlfEk690Hz7gL+t0ZPwh4nHJZgxPEP2fcBbyz3N1ETvdinhuGImKVLL+XS8WqB4DzluvrPRTDGMS0fZ4jS4xiItyq740NhUpP9wNHZsIgbLFh57m+Fj+61vDBqKdPS2ZSTlQq81K4fjQyxxPnSXzdjJGmJ9JMsLHHLOMQGAYB4vImmWrJU4pJ5J5FWFSHwyBMt1HGbDwMBAW30xJJOfUgOgTLaRJ/B2sMy1zUYFT3l5SlWqmgdMmJUqQD2eAtQ7AsbmE6L2STSLniXNB5oJ0IY+7dXecpQans9oOsDWO0C63F2qJV0kLMYmxu9pYwDJScmc7zyphxAoYfrg3Hu5mS6fvDNu8tpZBjxvgqckxNYL13lGIESPeF+6PM/2UWAHQ+C0gcgser71xKBaqAnsvSgFTD/jAy7B3jriVSEOuCsQdhelO1Ctmk3Fn3pu0mWVUeo8murj+jm9FaPZfzYQuEdZas/s72Wo1oNZboybzpyfyW1bXKn2TfqJpFNPPZWukm153F8o6wovTf3cSfbR+pKPjwMLaRLmTNdmDwfnP+9R96q5uegHemV9mttWRt8d4lZlXmQt0ko+2etuyvVkSRbm6uh+arwbt2TW1AkzHCiK4VW1qxCoKTdeydV2aXgBPBy1lknaH2wEG+U7qlKiDB6o/XYr7y8N7bb2+AgFIvkzvvvUp7nHqOgXgMKcOkaZyqzLbSskbWedIOvgv2XxtbfV9FmU9yDscH97CRnmmS6r2VM0Sf1dqWMCPAQPvvyzyzJ7NvgZn6l10S3G+zjVntCXHeMJ9zTuQixaRSCoPeq8Uwn08d5NrtRJYt76dqzLvOp/adDfiSvWbtdNfWbZMmy32IjLs1v9gy4LZ+ex1AZC0Ibi9h37oVdLYGW4VhchlLtk6NaHc6Zat6SbilC6Aw4DoA/uBqgIg1WvDbgETb7zHK3GmxzlrU3YDRSNHHWqceePr3Wkg1xmLRJhbGkrOV5kkNMLFr4w5ZG+t77WuiJFp3P5kj6sdp6CyxqnuM1fisdTht757q+xP2z7dWwLCc9B06amkm7tvxoj+znG0b8IkGrq2s15iyvMsGpLWiiWxUup6GXhhtTCVhPTeQpggQZRwGaQLRwPHW3bexrExbczo/QxAp8el4IqekVgOsY2zWnMSY2veBWtUmpj305ipFirZvN7GU3CSXSirpgulnqxFgFDknZUq8e+8TdnGh1oizWnQtzSz/EkwRw3wwOg65CDBqne/M/ZQS50me3bJ2spxmbeija9BQsHVtkiZ5V9V9SGSRu2FQT19LXLIyiIX1ZTcqoJQy+MzQz4WMtwHjtYDVlraXXKzaip0bMxXxpdDkRNaa2D4Eb9jvBq72I/vRcwiG4IQAUYpY+sQSuT/dydmgKoerg3S9Pk0LdcrMNXM4nURdUlYfw1bksdZhvce4wKDFv/73CoCuc/7dCfa7C2Xb3/veV4tJjDEybqBNUug+nG0t9cYg+u/zEvn0k8+4u7vneDxzc3vi9nRmTmn1yMxZbHxSIS5SaPfe8vTJNT/xE19hvx/5mZ/5cY21Ki+ePaXWzDh4huEKqyb8DTRPKRKXmWk6cXt/5OXNLd/86CXT6cQ3v/PR9/HEP+BAWCmVKbWkupmRKhBmNgaHD4NF4Ob+nvvTxP3phLOWu+MZ6jf4r/1L/2u+8c2f4pd/9U+yLO9qvfl7A8F8+A5f+uH/M8P+b3A8v+b+gYdbOxiNEc01CoKltAjSnyul0V9zpDN7jNKWNUAvLQQ0kjjUQjcndw7xjzItoJKxiDHz2cuENZWddhS01mK8oLSt0+SyzPI9znL1ZFT/Iuky1oEbPdx7QPY5I3i9E8RfYDujgGWlWO2+U9cYrtQq1I/v+QqEIiyvu+pzgHWqZc9i6GfYLOha+4LeEtgaWFN1k5bDR9qD9+qzSisx4LzpDCVJfCWJ2O28eOQo4LDMpcuj9oeB3X4g58J8jrx+eeT2zfxgpOr6bEZ8rdr9hcGTYlaGi45hk4JkcKMXKZcRk/O4zMJCWiLjYZDAvKoPkDPKCpOEmiKbs7NWupPVivMafOZCjYV5Wqi1cjxOOCOVowbKwArI1rrBR6u86VKluUCpVtqjA9U5cq1YMqklgAoCWWc3FQ4BPGX+6kbtnRy6KmVIabvlm3Y3Mo5aNQLpKOkQn4BAJgep5EmMtxDTLEH8fs84DsJmmQrzJMydPmOqeCaU3CfOGpA3g+hYiGWWu2nsiU11bK3Ai6xxGII0KmD9yFIq0yJzpMnmvHcCUqasQFuWd6FdX8fBshucADnWcj5OLPPCbpTE4XAYuL+fMMbw5OnIi/eu8d5xdzcrWzBRrKMA8zRxf7Mwz5Gwl8pdS2iXZZEOtS7jLZ2OGHGEQeYiRubPsiSMEc+YlDLGW7yRpgPOe1JMjMXLmk3qk2GlIng6Sne1ec7c3wsA5owRg9Eq5qZxqQpO9xyVMHjxfFCWYM4CVMxz5HScmSfxFxGJXmDcSTVPGG8aHBe6x9YwyLoBKcpENcd3bmVwGWNZolQnvRffRZnHIp0L3giLC/j09Q1Pnu85jFeM4w47ZFJOLGdtrqFBh7GO3cEy7gO73cDhaicAWykatBYpJijrpwVSJRdSjAQ7oEcj4xgoqXQT9FIsVoOfBrSUXGmecwIaKnvHinlpznCaIrVAjJCjsFuslfuNMWt3NVkQuyGQc+XDL1xzPEWurnfsDgPDzgnrORdO85liMh8+fo73nrRETK4EDVlMVpB8w/U3pvbkotRCroac2rm6ghymGjWkbd0LG4BfJXlou26RrsoWYTxa9WApykSz6gdaqrC1+33onKhW7BlSkXfti1FpQu3yw8Zf6t0pVzWgdGjFYPTsMnUjWVNQ6iEg1zKWhg85Bba2QE8uD1jk0MGGWkQ229gy7ecby6gVCLbf3a61S9zqAySDbxU0aO9J/Unryti1BpEJWdd1FmWZoZZe0JAzWNlAanTfTaeNeOAJWLRKSDBNxtYQoPWZ64qWXgAj+S2J3Ool05/XmPUZMf3zDBK3tcvVtQGCgAwFtABYgFpUAlNFjp1zxrtBJkBLQkJQA2YBz1MrcDqDyWD13gUctCso0ZKnDn5VPaPXu22FNOtbcyXxStt27k05E3MSZvtmLvUmKyWTc2I3jsRl1iJfYIkLcZlxdujnsjUi/c8lU7I2VdkAH7nk7mslDJPU7lS833R9lixJVC3C2PPB0xlf7bP0PASRE5sH7399yfSiSJNANsCjye29dkRuY5qztp/YGpuX0uOKdzE23gIXNwDgdn22eS7JXiseNvBH5WgYUCBfbD6UIt0+e/uZyJpUjFhj1KRrpNkt1AspnkjFtr5JLc9A48aHgtwGSK3WLcaqSb6afZfcjGplnEwV9ppr68io5qonE5dj1wD6txltLYcw2hCNDq4LwL+VZUtC5DZMvz5mXLJF5TmTrldd73aVsbZ4slbJJ5oHo1GZ7el4BETaK817ksgQkXOqtqJ4rQombeWhb00eck4YtJO4vhOMQdTxDe2ufUQo6jmG0eJV0cJRA3vkKbIO+ZLES3I3OLEpsWKFcQGuWYcLoz6/wZExVth2Pgx93g3jiLRDlHMw5cKiJJWYEsFZBm/FRL7G9fQ0lWp8V+4YbQyWs9ittH0pJcMyR6z1PUZb4gImi1rF6PP2Pb6Nz2bWmAagC5CdtgeUgVozpyny5EqUBEMQz7FUDGMQtnkpBessGcv5PDGMgcNux24c8CFwPi5MdycBMmvGxKlLlHPKeKuya2uw3hL2IzODvqLL83XNYT4fCGtz+fMuJaG+5RPWgCyD6QxfOfM2nUs3V6b5IgvuMs+Ru/uJl6/v+OTTN6Q4czqfub8/cns+My9J2WUib7fq6+2c49H1FV94/xlf+coH/OiXv8j+sGO3G7i62ouySoFVgGU5EvMB4wdMrZxOJ25vb7i7u+P1mxu+/fErvvXxZ3ztWx8R08LV99mv8AcaCDsvBRsS1uSLjhgPL0nOV6T3eJr4xu98ws39UaRHSbpjnM4TbvxH/MNf/u+S0uEd3/i7vSJf+PA/5PGzf49YfpV5Tiyn7d+3QwcqCesitYqpelzOpCQU06aDNg6CiUzqVB6zxJlBmQbKHevniHVgvGEYLLudY6+d2Rqr2jnD3d1J9N2lgTYeU9UE2jZPqCLAkZOkd9h5wlk6Cg47T45rkNv22cbSe1fgMTg4z6lvRO0gKbrom/Sgx2JbfbrK/R78sX53lY20byK6p1kZo1S1UyjtwxWA5DJG1jxji2VgrXQSqUUYDsssiLbRD/DOKyNMxnBZIjFFhmrVG8kxHSV5TzEzTwtXVyOjskwEHHPaDcWQkh64/WwzNKlgA+lSyj0B9kGS2xBcT5K2HT/CsOBmGWsDqvs2+rzCsDBGZHolOawJ7IeB3WiBpEb/MpYpFaSlrSTEwxCIS2pD2pNOya3knWQqnRrVEshSlYIs8iVThYmYasUWae3ubJuLSltu/kS5YoJMMB8cQ/DMOZKWijEzVT312oECKPNirazEJMmycQVrzzJ3Lb0rVUplbcWtba+X+7PIuxbIyW9YDjqbGihdoiY4a5W6aEBf9SWWUrVb2uYTjBitVl+FXbgbyCpxK1VM0ksuLHPSgAtdy04aaxiDcdKlxlqrRCwJPpYY+35CqaRYGcaBvbc8frzjdJp57/0rXry46nKBu9dROh+ZCkvl5maW7zaVHA12DzFKp0hjjcw/vVrHOapIMMMggaez4iU37jwxTR1Ax1tqLlRbemKTU8IFT1oSy5QIg1T7llg4HhemaeHxwVONISbD6X6iporNIp9lkGA/JRmzcfDs9o1tK6Dc+TQLI0pfZYqlG2mjds1NAlCLJHGYNeGoFXajx1aRjefqmE7yO9IxrGCswylr1DkwpAvjXoAnzw46bsIcDW6vnW8Ks465c74z23wI7JR6f3tzxiDsrJb8DnuP84EweGrOpCVSUiJbcOMqLTpcDZRSuKlHbu9hF2TTyZKfE2xVDz+ZVyVlgvcEL4HhsiSO9zO1WpYpd2YjVRmOrkmZJWD13nB18CIPeuTxo2EYBXAS8K1ynhf2e0dQtuY5nalJKq39PN8APwbwm/0eBUlaIajHk5pUGvURFKBKgAvvBkzRPZ0G3BVcsQQv4JBR/7ekBTfjLL5JB9saDquH3FIysyZCA0iBwRjtSlgZjCaCWnzCQkI/S/EU2UuLWoaswFd5AEx8t2srJ9qybx7+fZNA9DFGAIX2XW38uhTie313yWAvE86e6H+Pq1QEBDQqRzNaOTcCM9RStWNYk02v50SlalKphSEj4+29SKhrrl1mUllBCWNMb0agf6mxlL8Ya3kGezFOvai2ZbQUCfqNAkAtibbGqEl1hrJALaQkreUfP30m4B53QMUPo4BcVrx+lpSYUpJOeAacJuTDIAURAXbA2NLjwN5zrTW6qRJRNOBnGIMA51ESm23y22RjqSSCC8LQ0yYFMUXKlKkm8eTqitNJGUwqOTod73j6/H2Ck/VknPhcNQN9YQTKOIYQSFnOt1xy9z511jF4yWjmOl/svzmJZ5jTc+ei62oVYM051wM5Y1avsHY1kKNWcCFgjCUukzxfjCtrSIEOZy1DEEZ07utiZfu9Sw55uf7o+5ZTwKaxFzvg04BMbSJQssb1crctugGkyNs2i7Ym1380Vq6tSLBdB2v+0X2qNusUUNBZGFNZiwZ1A5Kuz4cAdzTcQZmOHSy2UgRQ36PO3jMGemFe5vG7x++SFVaU4d+sS/R19zO8XaXt9wYFnWWNJiDnzb7EFty7/OKakniaNZsDqc5iSqEgHq/eee2uOygjTH49pkhKSd5fB8oV+Cr0eLCyFqzeDWQYfY9gqxaI1SumVDC1dql4LYWSZqoZEMN42Xuk2YDOA9r7dQxeQLDTdCL4wBBGsXEhk7hkDlcjrEcpcnic9Xidd60hRPCB66srbvJa5PUejFlIyrqr+t6LEc9TbMvXxMZEpkrt8y6lrEVHue9SMjFGwjB2mXPz/BJPrVaAqGvC9OCyVvwKr66uKLVyPE/K6JT7GEKgVrHAaABcewfOO8bg9D5g7y3Pnz2WZz/sZS9LhWWOWgSqJIn6SAjAfZwXBucYNGhJuZLvz6TR40ZHCNJ9tC2T1vjOtL2CysNzfZ3L24R8k9u+Y2a1n2n2LkBnH2//TN6JFONKtaQMy5x59eqOb3/0Gd/55A3f+eQ159OJw+Coaebqaicy1CTNtUytBGU27g8jX/rwOT/+lQ/5kR9+nw/ef87V9ZXsN9Z2ZYy8by3A5cLtzWdYO3A6Tbz89CWvXt/w+uaWjz76lJv7I8ZaxlB5/uTxZVfx73L9QANhtRaWGKE23yBJNPrmZnSjMYZmjO6859V37vjWdz7ls1d3fPDBc6Ylc46J4xzJeeFHvvI3+cZv/0lyfsLnTJ3veoXwLT740l/FDf8PpuWWu5NHEqq3ngDIlDpT60JKkawbZ6MO281kIBXOBZG/YRm9JPJrN63SP9U5w079bYbBcf1ox7gP3Ufr05f3LFG8G5a7I439k6KAEzlXplMSw/Vg5Ts3G/T+euTuzSSyHm9JsfS8pBevzNvDpzkGOYILcsuSbtQenDlNZIL6GS2LvDsvZDVqZfUG6Aey6tlzA4DU7ywVpqms99Q2Bp0jtq66/eattYmBqVUqrY+f7Ll+vGOZEtYa3rzMDc9RSULBGE9RVtA4BsFEqCyxUKLIUEPwxDl1oFHaQ6OVTaOyi7wOVreCMFCdHnoKFhZBtZyXjTpYp00PoBY10tagL6gEK6YiDA3j+oMOYZDuOw2tb9JCYxiGEfAsy1H9szy1nDkeZ4bBMc+JlEoHmZqZes1gWoW0BafGKZiqLORShX7uA9Z6ak4UI2CdH5oevUniNoCWIpTbhKrFWBLrWP3VugmYEzka6i6QgbQIi8BimOfCMs8EL+yXdnam2LqFGeKycD5GpfJX9gfLm9fzOya4Ae30s85Qlf1UMZUdguc8zQq+mi6Zbd0EmyG+nEViFFq843ycmI6LgJJWPASDF+DsPCeuHh0wag6ZloSxsrJiLGQr3130c72TcX3vC48wZB49HmWsXeVwGCVICJGaa282kpIcRI1JBXB7c+refXERj6rO/kK6kA6jtJKupUqHwSSV51ILw3B5BFVniLngqjAhhv0OY8THztqZOCcFOwrTNBOCJDvDfmSeJsbDwHJeNLEtsp+Vov5oAqwMO/EXmKbEvBROp/mtADouhZwWdrsB4xx1SbIPWglEmm9OySq/tJZXn95jnfh+zczkVBhGp8Q4lWju5L9rTkxTIi4L3stc78wVDNY7rPVSBdXmHdY7Do8eSRMIB8NouzR2fxi4vUnEmDifF54/u2YcHN4bPEJHb4ukpEj14sXjnJfCRjjgLExzYr/bsSyRXJs/iJyhbRl759iNgYwE9NO0cDxN5Lh2HxTAQ/dalcBUJPjcjdI44erg8UNmDJ7dvpKSvN/dMPDsyUGKQ3qeW2fVL6/gzbarblv9l+uwn0VNldsqocqSrraQy3LxOyWvLIlWoEE7brniuoQol8q9NhU47AciGV+lcu1Eqyqr3pp+niwxUS0EI53kfFCJn/XYjfHGu+VUa+KyDQyXZRHDXfv9BXvtvZS8ys3ap1+MQy2YbC7uYyvlEBl56NKnh35jb10lrzLanPvbele6178PkeBIh7VCxeKtE/arcwQFN05p1mTBkG1jpJkLw/fmNdWuJhmnClujASYAh6uDAvCZGmqX3LkwdNCoj5rZgJAaLHxeNf6tP68rY0HO63LhuTWdTwx+/R3xvDOkXJlj7gnb9hLmtNt+BTmLx2KLbd51iVTMsxzPlNQ8yta/a0b1ldqbM7gGXpTMPE/c3d/w9LCnlMI4CBtiSRETArvRswvC3ItJWbMGsI7gQ2dVhCFgqmHJsn9ncpdDCwBqoQjA3f47k6VwlaswQvr8WYGcCx9VfaaH/mKmWnbjo/47IYy98/G2I+zluHGx9la2YBv/ejE/HgLQLRZ2RplfLSa1atVh5J1Wu/r85aoNUFLh7VIwPY4P3q0vvLb11mLf9vnrXt0AyRYvtbhL1rmQDISZ/e75LR5lRoulRpUFG4ZTLR3Ik/11ta14uJUbWbgXY1V1PDvQ4RytmJWambdezet2+6GlyLkn+7KlJrdWTDa/5/zlKlnf6erRV5FYTkA+YUu7EBRE2uG9GuXr+09JPFPzZp+UfVPiAqPjFnqXWtkhraEb7DcwtzULMg0Ew9Ic0LOCpc3iZQVEai+4pSyNLlqzirb31yLvf15m9sNe1BVm9Y3sXrtFwGGxhFiZw6VIN2vxRDOdRdkAlZwzUxSrjPvzxPV+R/Bi21ERxUpouQsNbFnfYVaP53bJfMy9EYdICKVJUCvS9Txa588Khrf3LXLtEAK7qz35o084Hk993lpTeHQVGAfPYT+u36MsZ++V7WgqwRoOKo921lJSEtArLuJdntRHcQica+D+/h5Y+MKLJ7z//AkAUYs9bgz4QbqJy/Bqd3hlZrezart231Xckp+R6VE3z22sgKk9V28/+P1cJYMplOrJufLy9S2/9pvf5Ktf/w6vbu7JueCAq+GKYxl49vjA6ZM7dsPI6D0xJj788BnvPbviix8+44c+fM4XXjzmaj+CsdLYx22Bcfq/xyUxT5Fvf/wt3ry+5dOXr3n56g33pzOpiKfvfjfgg2XcP+V+Xribl895kMvrBxoIizkTqnaxo2qz5c1hpP9UpDJ8nhO13vI733nJ6zf3zPPCb/72twWIMYaSPf/J3/3XON7/6O/hbhIv3vvbPH7610j8EssSOR+zJrQix5IbKtSaqCyUkqjEnniLdrio1M2Kt8ogHUxcsEzHBZuaJAyo0hHKtKCqCJgURsd+Hxg1Cd3tQjcOLqUyTdvvTDy6PgiQEpx22GtSDUvNhupWRKuB685bxkPAetVt54UYV+rlw3fQyx4IiGXd+p62RrnetsBMPAZKKewcWEpng01dVroiVkFBHgDpkHaJgvdqmpW2z0IdbsmF/FDbMEC0+gWU5SKb3Tg6xsFzvDmzO3hO94sCaGr0GhylionjuBvJ1ct7sYZg5btrqSxVDAVbcrcbRdIx7kfGSZKxeYqUqIeZUfSvtMddD+sGGoVRdPs1F1xwVB3HRokPwTGOnsePd0yzNGSophJMoPiCr74Da94jhxSGJYrsYYny3pZFZFrTeeH+bhOIVQArB4TOc7YgmAY37ZIgDyBT0gQm9GTC7zw5J9IcCcHpgbMaMjrv8KPTCpFR/6TEvCTSkmjMs5U1Id+XsmU5G8gTLjjCIIFQ64gXJ6VdK6smxco0F6bzwuCL6uSFBXK+PzGO8iameaH7l1gngVl7ZA1KoAF1hblEghOZImrm7L1hCMpqQBKMWgrz/5e8f9mxJMuyBLG1z0vk3quq5ubukRGZWZ3d1WiADxDkhCBBcMIBwe8h+Q38DQ7ZE8444LwnJECAjUYPGiC6il1dWZWRHv4yU9V7r4icx+Zg7XNEVM08M5qzQEvAw93UrsqVx3nsvfbaa92qjSGCnB3QZQWZc4cClBXPtSLOCSEG1CKYpmBC853lQjtiiucrQoooGnE+n8wBkLpn//j6CXltuDycECID6m2r+PXn+2gFERvP4up4rffrSgDYwIuYTNdGeN+lVAM/ue54D5xO6W3VyRKGnCtqJRg2zQFppsZUmitKzvj1pw3i2CZSmqLeM84fZpwuJ7x8viHfV3gviFNE1V7ZZnVxuW0IU0CpBff7im3NOLY4hY64wyrKnVVkyW9MFGnt0ZVToG4F6RLwutzZOteYNJRtg5cGLwEivIdWC9aVzjkpBtRGW/fWAD95c9VSVN1QS4FowXyyFpa6Is6PCMEjJWBZNiz3jOVesK0Vp1NCZxBFiYjew0sEXYbXEXxvKwNdd2ZwueWMbSPQuSycjzFaO0cpg0HjHK8Vau1s3g9WqzgdbZZqWosxRjiYhokCQRq8D5gmh60uCEKTFlVFDIJvniKcKM6nhJcbEL1HFMG3lwvaTFD36HrXXVZ7YqCNYFfPT8UZOH5w0e4tkqX28/BdJ6fGLMcAKGqjSHzXyAAYhF9vK355udEtzcZ/d/AMthddLglPDzOezhM/0wS9tSX4P4/JxXuwxP3dz2mOsWCedwvx3wJiuqbK19An7kNHw52vX0eXnehMz86u+meBMICJvgGnpVQsK4bm1teOVrYBDIvYNiKyszIgrCpPabDzUuzvyBL53kp/ABHft1hJ25k4RxfBvGXgZL8DOhMfARHuq94SPWNrtGNm8e5+DIRt6Jgsk9Ndx6hZ1bvgdn3FutwRHthSSEfdgKZALmxRfJvm77HOsRAMdCahwIX9/t4fHZRotVor4n5476k99DW2DDrY9haUixPB2bx1x1pYK7DuLoEG+HpHZpkWhST58hotdiT7UlgwKDp0uXpr5ttrsvcNA6I6FtUUOWeOuzmMInO14qm0fQ8gOz8Akoem4hfPzcCKwZ4ysffexrMDzLvu2vuz9Ba5pl0nqBfz9+fb1JwNnYPmAhpI/RYgBcTAQkU/iXfkA5aSsQ5Zhd08gPP6reEDGXp07cylUlqk/RMNWSIQF/a4Tvq8aoA4i2eoX9haZZv3AalTu1mxc/XhdrwmNpIbo28A+r2tv88CGxe52n0CCg/Aj5hKO63qEJIObaXj/BWroIjApwgXI9AUmjOq6TOLCNSTmR9iwjxPiDGh5m0AMaWwPZ7jXeAUyCo7sGfM/eDdKIwfh1uunflrhQzl8+ogbQfTFEDOGxwafEgcf623y+7ab81qHF0XudWKZgZhCsVWNsZO5pLrNKBpQQgRil0TKniPaZ6o5bVmrMuCVioKBDmWN+3E1/uN0g4Gzm2ZUg8pBORW0UAJidTbMuXY8s/4Ud+tDWSgkbjRQVvvGXe01nBfVzycz/CsZvMtG+g8iBAGCKcoOM0T7vcbWgWCn3A5J/xNnLmGOYfkHc5TxBQ9gsWLIdDQqHqKyjPW3XB7XkfnBkTwr/6bP+LhPOH8eMHTw4zvT9+jlYI0p17x5hwwIIiMXsbkHKgBEKC0su/1h31tGIPYEnaUkeF4MiZqB6ttDDT8+RjY8WOtNXx+uePf/sOf8G/+/Q/45fMLWY4OuEwTvv9wgX56xf/nv/p7/O/+t/9T6innhu8+PuKvvn/Ctx8ueLxMmNK+DgsaWl2ZW3h22yzLisVi9L//+x/w6fMLfvjhZzy/XHG7L1iWDc47zJdp6IZe14K1VnNE/fNu7i8aCFuXjaiz0FnoiO5vW8btvuB+X7EsK15vtHd+fl7ww0+fcbstA3zpW/zt+ntcX//D/07X4P2P+Ks//J8Rwv8dDS9YGgWXVY80/YJaFluMSOtm8M//dk6wZQIgaZ7x3e9OSCdP90aDzMvGnt2UK3KuJtQNQHuop0Nc/nJOmM8RfeKLcAFuqrjdN7y+bMOuPKWAZELSaAXbtsH8nCFNEBIXag+HrVUm3QqkmeyybJBz1xlsyuRj6MlbwcL1hyx7a6NzoK5SDySAsSGESBAJzSjFrr9XO40ogv3e3nZH9lYXVw/BDcFYbXvlg4KcPI/tzW8ClB54p+QhXcRXBJorvIi1Ke33F8zBsGZuzM02CQc1Bk5g5cZucl0LPn++AQJcLhNSPCGmhFXKcBRslgA4HOTRhMFzRcCR8emcQ5wY7LD/3AJAY4o5R1e2ZQG2vOJ8ngFUa7WwQMk2nWrCnq2xr9+VipIbbreC5+e7te3W8bzfHg1A6HVHvJGAFWctMnuSWkrfA6jDwGRdUbdmv+/ggkdIfuhL5a3Ax+56yg2kVGC5ZWyZifK2Uk8B1iYswUOCAUwG5oXakJeMkPjehs5Hachm/75uGatVhVEFzTMhPk0BU3pEbWTXPX3/gLIUpHPC869XtFJ3rTBbAcQYq2otCAKH4GUAsGkKTLZCwJQ4t+q2oeQM5z1CCliXjOu9Iq/UwWC1nolpqQ3LbcX15YY4J8znmQy+yLVRVQ1gB3yg3tt0nlFqw/PLhuAKoBXOFRtHgn//98/46U9XfPrlhnXJZGEK2yoUDSkm07aABUh03/HNW7sOAXPnHNQT3MqtMJnBXk2PwZFVCKDmRhfJXgCAQ7ZJ74ODTw4+RvzuX3zAT//+E7Z7RlPFFASXp4sBcQ4voqgb2cIhsFqda0MTANpweyGrMWeCNt5TGwnCObAuivMlEYR25lAKoGZFip5gs1p2q4rrNeP+uiGvBDYfv7ng+vkGND6XmBzOlwAo2Yk9SFal2YIAmOYJsNa7mhuyNmxlQ0gO8zmONmfVFdsGbJvH68sdn369IYSIbPPmNEWcTxNSmJF8gDbuh9u9YV1tPMqGefaYERGjYs3A5SHg249n3BbBshaUpY42pzR5sNy0J4swfYh5njDNCZ9+uY92M055N5J25wWzdyzMnCJCAJwF6117jDpswA9/aviXf8dx4bXBd9aGE9qMV6W7nxCgABg4aauouRmw/ZXl6XDU2lDB4D8ZyEW3r68AM+9iqW4hnmvF83VBLnUkK9QqKfDR43cfH3BbMx4fZjxdJkwhwovnvP8zDm9t04LuBIY3CUI/Si2IQh2pKUxjHe/7QDPpA6Y9Ni/90UFtF2LvwvjiBDFR9Lk74Xa9MWpv4TcBMBcTQjBAtnAOFgNZWCRgoStFPxxu93thMaKWzKTAWs21VWxbY4vRDDP54T7Q2VGcTz2mImuklPIFUPPmXdpz7HsggKGf5pzDuqwo6pBOx/VcQIbI2/FydCn86ne9+0PTBg9l60/dAUVqUp4hwmfhw868+MqZ7Cc2KIGRFHcX6vfoS0+Euk5l11trtlb19kIx5lyp5TcB1r7uH48QI+bzCS8vn+x8dGsfLB2F6bU2RMQ3IGRP8gbjtrQBhEGxt9TZZ7vpj4L7W2+rJM5Gg4quNzYE4kUMDLHn0cMUVYQY7XP7/PktwLprE61bseR+w7qu6G51zlhczQrUXz0s/qee8Q52c2vhM2ItTVFEhj7f197H8VqdCKKxRd0BlOoyKxwAewslZVDegkDMP9rh2nsL6dv5RKfEsLO80EZxvqFwnXfUzYLp/6r9Xn9P9ii43x6S1w782BehOzv2Na4OXTbGCLkIYj0hGMieQhz6VD5OIz52oghulyHojpWbxRoCrgnZCitta/D1UDCTzg5uxgQ2HeLWgLpCG4uz2hRrKVhLd9XkfbAYYiZGg1WlB4Cqr81ACn5IXHhROO26lsKYyPdxVlGrgWNDN5o5lI61RUxjruvuiXWKsN2QWmYGdnVShGn0Nq2jgK7asG7b6BIoOVOs/gBC86YAdbuWnnd0La61Yc1sOS3VIVfLz7aKOTVoqwTQBZR1qIXSEoe52PeUmAJO54TWAkpZsJYVZ3fC6TRjLRl+m8Ya6g7r/H5QluY0BZySg5PIHEiB5x9f8XROWNcV7jxh6nNa2W3koyDOEa66UdBVGwfrbUUzUPxf/u13KKXiu+8ecH54gHMsqntvHV61Erx1biRIY7f5ZwpmokLJhsGQwbv2/jZA2ze/Z/lle4f//llH47i8nCak6AfbsTXFp5c7Pr1c4UTx+GHGf/Ff/ms8nCcEF/DxwxP+5q9+j4dLhIAGgOOUTQGtWLcr/vjHn/D8csfrbcX1esPn5yv+3b/7R0AFp9OM55crnHP4+M0jQgxYW8MtZ7xsyzij+zPbIoG/cCAMIBWSGiS9cqi43e749PkFv356xcvLDVtecb83rFvGtjUs267VAIyiE/4f/9n/CV9EDV89Gh4//D/x+OH/Auf+X2hNkStFdHPJVinyI9HpABgrOQ0+CObzjKcPj3h9Wejmd6MeEaTi9WXBuZEJoa2gVsVp8rjME2ppeH1Z4NBwv5d9UzzkJ9vWkCa2zvQAJxc6Qm5rHVWUFMNg5YjQSSMoky0yKPhPmgLmKWF5fkXJHGbrpzsgZJ955xCjA4QJegyCokrHp2ruuHYUJfhFtPtATQdMO4eLaMl5BJZjgx1ioLDgqOLpwxmkqdI9J5eG220z9xzYZs9FXK0k239/HMqf2cf3a80NUTzmOcA7YFsynBecTmR+XW8EmIL3mE9pJChNFVttUFTTClsRY8LpNKE1wfW6DvQ+JWMmOQbxaXKo1TO5Kqb/0HqrnW0vLgzwP6QA8aTCd9vk3dWooTm2OgbvMc+J17OtmK1lqwcUffBwA3ZDf2rbCLwu94LnzwvWOymqrR70roCR0FZb3ga6yNIGjkI9x0VXYUUrt0Hh3iH4dLqsJoir2lBqRlVFRNwD/lKhFShFcV8anBecH07jEoJpFEHIoFpv2QJiOuo0BVKMw50pBNo+l9KAyu8oNmiKZpS1UJvJbJhjCnj65oJf/vTKexEhq2fcIYPDkhnIO+/QSsWaC9IckU4BaZrIcFNgnmdM84T76yuTghQssdkwzRF5W9DdF1XZzuYiQcN0mg5j2kTOWWbFPEdAGuA5lvK6ohZe56oN3iliUKxLxn/7r15wvxWK5VcCDWJJMYF8hyl5OH9CacVcKZmQxBRGSy617yzpsmv23iGlMETzU2IleV0ytoVMqm1ZWdktDTEZy20r2LY7cllxfvyAb37/AZ9/fcX2spopBMdXmih0X2NAWTeUJSNMnJ/bVhCcw7YWmgpUxYfvniBNMZ8mJjGe66b3QEwJKRmzDnurbEoe22rsCQViAF6fF0TQWXXdVmP1UtTeB4/7PQOtIQYZe05tbFVIpwfUulnQV4GNsz14gtXstqVW2LYV3Kyws60Vt+sGbcD3337A6TSTMRk8BA7bxuLFsmQWP5TRz/k0YVm3YZThPfDryw0qDudTgHcNr1euC3vLMca6NVhn0TOgBY0nAFiFj2AE27PN/RR0mpwmM+rIBenJkyEsimlyeLk6pFmQW0OKxjob6wGfmti64iwpUWsZEMCqw3hzVMu/jof3giDxLTNLqeLnvIf3EeIADzecKXNle0vRhgZFTA7iI+53YDNtpGXN8N7h5IM5eZlD9ZZRCpACEFsY7Zd0bdtvUiBA3R3WpJdu+2oyYor9hx246cyxfp5SC1JMUNE3QfDQOjqCYdbmmHMerJYORuxP/y0o0MG2rTB5jD6Ot7SjC/bfVlWPwntmovply1k/uw9xJG+7lhFjnVA97y2Enf2jfKcxEMymLuBGV1wfx7VqN0M4MCsAjNY57qGCaZ5QSsHr6ysu33xnGpxvn2FPbLuD4m9lEx3U6EyKaj90Ynt063ovBGrW5U6ANsz2XgN8nBBSQtG3TqGqwLpVTNMMSjN4toM7HHbnr18T1PZtcwLuz6XfH2cXgdTgyP4broodC28NOW94OD/idn1FqxVpmrCZMc98PqO0Bt910g+gSmcLk3UfR/z0JmGT/q4a1xfpDoj8bNa8vw8DaFExWlo7kNv/ewDJh2fDc1ms2QrWZcWybsiFRSFo1yYEWivI1VrU7HzRky3YtGM4jHlUFbk2tjIq26feJ6OdJUaWkxXjLF4/vj46FLbfBMH6SyXDp0CRhsZOPbA2h5Zys9ZtcaZdqVC1mFu6+DzeXMN4bnLMnAUiBIR7kY+MFGv5VYIalHlhPjPmbAdQD4AcIGha3zhbjjFp1XQ++69jzgIMDcHfPGxtaqpQMw3orJrW9SKN6eO9Iw+tg+SdNWnXxEKzR0gzQpoI0MOcwZtiLeac3ZqZqPR5ZXOvx8TAiDlpLGHSEoFFTsZyGIDY+yHgnEPwARr5zPktzWIIzvFcK9sXld+jTsc7TSHi4fQwtPlgYJj37DpqwlZ+VVixn3Ii2vRrHbrY7pvJCzBPcF4wpQQFsMaMdcu4LisqvJEE+E5y9Wi3hhQqzifPlsJaULYKsbXPm16jkzLczlMKNtY3mmgYeYEtmz1vZIG8G6r0n3XHzhgC5hRQWh4SQs7tY2PNG+6rQwzUafUhIISImBIAwbaycC2e42WeZwQJyFse5hQfLzPcPEPF5F48je1UHDqh+GvjendsBdAsxmp7keqLo59kJMuH81bgTVRlBSTFe9C7j9b+8YOEQ2t4fb3jp19e8Hpb3xTnRAVr2RC94Pkl48cfV/zhdx/w9HQabFmA+VyrSqbqsuHz8w1//PETnl9v+PTpFT//8oIYHX759RUfPzzgw8MjYxInlO8ohc7aMaKvWC3nwzX++ejeXzQQFlMyBsCOQKtSrwVC8ejP1xV/+vkzkve4rxmluoNDB8bgo0Pk11wi90PkGd/94T9FnP5vUPmRYqV170Gtpn8BUeRqFqmNLpBNK3yobJs7TXAOuC93fPj2jJfPK04CLNd1CNMSINARBNbKfg8FffLi5OnEcAT0vMDDIUZ/SAxJSW+VjIymwDxHiEQELxY8C5xXwCjYgMIFgQSFmPPVsm2ouaKs3NRzacgraZs+AKoOcU6AOGylwtWG4BpQFGItYT2Pagqg7lXAGAjUaGM7XdcjGYdp1bS2VznjFPDwcMK/+Ntv8cunGz48zfj3//AJ20oGgzOLnFabUf6NcmyYYWdmj4rpuzmjBiRoLmioyGtBiGwDOl8mPHw4YduKiaULamFLaxNjGzQxkKJiyxUiCfcbafnFrGOnE9sP2ePPa6RDSg+OwYuz6kEHw45Hp9IH5/C8XDHHmQ6Ikcmns0RrihPmOeF+X7CtGbfbgt7e0cdXdw0phe2nXfPGe8Fyq2jZoWwbWlFeCrFPwLFNJSCQassyJ/+xS+Y4g7USHB80b5FudUDTDDEaobN2Xq10qGy1wnnOi21ZUXKBcxw3wXtMEYgfzxy/h2DXuR7EsAIj4vDp5ztaK3BOMc2eml1QpDmhWJLfiQRyCFag1BnsXZ8PTyd0uvjlccL9vkK8ZxUOHOMheIQYTAOOAXvZLHl3HQS2e1UZgaoPAQ0cz9CuIUfAKUE6653gwmUerA21wd3BCh89YgjwzmErK8q6wQeP9b4gTRPilCCiaEWxZIIVzglKVtTmSElXgQgTkVoq3BRwOgfk2vDx8XHXL6gVMYaxdtXSRiDEeaeAkMYO9PkD+z5uxiF4a8uzRLM21Fb483SGDxHr7YppnvHtxws+qeD0eEZeq4FqgjgnuFoQpsA2QMfqKdfCiui5TqbZoxZFmDzO5xO2fMfttgCiiDEguZm24NZeD5jAetkDiXXNRv2m+HSaImIkg2eaPR4+JAKD2pCiQ2uCeT7humxQoRhxLhVaG4LHMB5Y1o1OlxODvNttwfPzHetacb2uDJo90Irgu+8uDK49n22IdFHNOdvv3XBfV3gnOJ1nTNMJaWZgc70SMPjw7QN0c3h5WcgUXR1a5qo91m1gBJi1KVAVH54u+PFPn/H0eML1ZTOGURzC0lX3gBxCdtA0RVSl1k/JgB8sKQfvK6Q5RB/GPC72fQKu611qQHwAxKGWFV2Y+QtS11cIQc2SxmNLEIENRdeoGaLCsscWPfm9nCekFLDminvacE4ZD5eEWhUxepwvCTEFRG/MZKNJqwJwDjERWHG1jqR0rDFcdb686L5k2vV6798k9LUekmcxdo21fB0BtO4G9T4pd46mAF+4Jr473gNCcyJg03+PRawuVv/26GNidz47gjp9M7Z7c10Af28V6wF6KTRnWTda3IsA59MJ4gS1GGvTnmmSxkg3eGzFYc2NLdJbxboJzpcL5nnCtiy4vvyMKUUEiTYPzQHT+3dte5YcCwGXhvpuY7NnKv0+e/TDg8CGHirpx2SNbG2FUIw6RAKDcKjtHTtL2JIV0kSgARxjxzKMXSZGm5H9ujYW6yjsbEBhU/v8ATCsBMDewwv8OxYYc8l4OJ+wtYoQI+PY0nC73RAd4DAxubZMjxqUiexiew5BPIqaLmB/vsEApkp2bEN7I4Y9HE3tZosrA1SD7MmQOLImvL3HzqwabTl2DrYPEgTrz7nWCkTOl5IrNnOybKrGRnR4engChKxZiA4tr2wyC8Fas/YRvr+gntB2KQuLoL5IiBWH7olDq3QfQ2rjqKJhXdmB0gHCId0gdC2u2sGVLrCuZLGBplW/3ezc2VM9FlVLoHuXBd00OwuNwFyGNHNzNwDgyFLpAFhfAZ3AYrB3La9vaL4dTvryGfW4uQORpQPQv9HaqYdn6j2Zi9PEgmJuvbOhgybbV9vBvT3jLRfclxXLsmErGUsub7TBeJ4KVTHWVo8nGnI1dhnc0BAey7kc2FAiBrTaOmg5bycMcK9p1noNTIF5iRcZ7OUOFPVTDo1axzhxaH1iB33ZurmvV6Ptzt5eH2O9KDDaW6FwEJxPJ3N0r4MBW2uB+OnwTgHxHtf7gm8e5sOc2M3BVNmVUDtzs+37soiMfHVO1L2tJaNp7yBhMba3bdKNkm27zjlMKUAF2DKLgME7LGuFCw5//OUVL/cVf/XtB8ynCSFE+ydwj3ABEjKBd1WE2UHPDSUX6xIKmCOwOd2LU/0fI/KoSZ2waL0/v8HmNiATwJd58hcDG9izIPSkFn13GOfRBiZqB6KJ/ftYz/dm7KMAbk2tkMV56q2rrW6Wvynxhl9+/gSAZjenaYKIw+1OllctBeu64qefP+GHnz7j119f8O9/+BXLugECnKaAx8sJ3318wjSlMf5zbbiXgrVUqDh44fsJPlByBBgg7G/VDN4ff9FAWJpmOJ/QWjEnGU7u2z3j0+cbXl5X3O4Z6wY852zgKEtT3oTYuVEKbtc/ALgC+HD4BkVM/xa//+v/KxR/gvr/jCyGbj0uB2qfAA2N7K7a3r4EaZCQMc0JD48neC+43xZ8fHyA80LxZie4vy7oy0otiiwNR8vragp3ZMgI5lNAvZpmilLEmItxRbLKQs68RibZ/b646E0nCsv1pCImj5rZXuIjN6x1Lai3DeIdXl9XvDwvmKLDyzPFvkNk0jzNEyACHz1m7Da6UGC7Z9w+L9hyfbPB1qHRAqPcUu/tOHjpCrNvCB0x33IbtvatKdaN7Yq5sIVLA8yyWW2hPJxznAxf7KVjrRgfMVBSzD2zKUIMvSOK4n7Bg22LXOBK13FoCi8Bl/MMbWJAWEVrsHYE6ihdb6atFBRp9ljXOoIDK0mCnui9EgrAd60zXsenl1ei4hFouUC9g8Rjnz1b6NIUB+WewRdXulqoHZczW1+J1BPMoVV5GRuiE4GLJqRtwmpshlMkFWxiwUgDukujd0YDtnHYCwP9WYt4KNiiJsYaEBAEWRfOXWp68fvXdYWYLoDWhqJAihNFkG18N/QqHyuVPnBTKWN+EiRetjZExzn+mrEHmTTGGHZreuioPMcUMM0JpVSs95UgS1NL1D0dLwN1qpL1wvcgKgRWPlld8hbcM/x1xhBxISB6ZUVpq4hThL9tI3jxQSgMOicTqCdTsVWyPntVr5pteWvUkCiFInvee1RHsJRsLg611gQxBYjQqdCBOiYheQQoQhRMM7/r7/7lR9xeNlyXNkDhfSPlpp63XdcgxTgSnWpA3Z4M69skGTuI2eclwTEPFyaoCE6niI//8e/w8w8vqEWxLkahdwLvIlR03JsaMNfXnAigmCB+jA4+Zpwmj1wcrtcrnEtoNaMUq15Zm3ZrDBQdgLxmvH6+o1SgFLJEHr+ZkBIQvOCbjwHf/z7i8uAN0BeULHj+1PDf/puGXKkhMirMtaI0a4cWrmu324a8kZV5uxIsJLPQ1iQAZQP8xMSwaLHCg5K9JAp4S1lsPq5rxjffzvCRSeE0J6RZkdeGMAlerw5V2ea/rXWwgwdzRpkghhDQiuL3v/sGf/8PP1MvTG2eWGAavIcPZAk4awfOOcM7oCwVpwvt7DlBee2+BTzFB0TPamttDbnQREG8GEABAykcDQBqhYReXd71wt4HQ0PnBLZ3Cgi6+Whrj9tBnK+wC5wTnGfqfrUG5Asr03EKaKUZy9ePsdsLLrWKrU3U2BIQ5G+1gjiKXainLs0/eYgl99iFv6E7S8t5glpHQGNnX+8MjF7trqUORtlwjfxnosieWKdIR7/bckNvh+T7teTDrqGDWjH63f333Vf4EOFkb7HvrAxqtvGaSlXkCkzBw3ljFnZr+9KQYrRr6iL5anPPkgIBWi1otQCOa+/l299h++EfsG4bnl8+4btv/wppuiCdE8L8AJWAWglOOddZInZrtkd/rTL/m69Rd2BKQAZ8LbuQXW9ziTEiThMFy+3+jk7FbCOMBH96a6+NDd66Do2rntzaF/D5GhjSrMLYnd+O5+9mA19jM5WScbu9Am1v2evg1rLecb1ecZkTICwGdA6gcwREj62rIoBTc4C072pN0fLOZgoSRkKoophkMuDaQKBaLQawa3R77MMksoNbXBiGzpg2FBWglKE5Z69pvAvuzm3ofbWDE999rUgpsnhlIFprvfWOwMZwTdyHwD4WKsept2KXc/q2VRFWMHNuzAsAX4AsnZVGYNOkYzx29mVfNxQW52Dsjf19OwPs3s9+AZlroooqwHAHxjtheyXLfrRk1g0ifl9X7XfcjtBiPGB8uV5//RjJ1fjO2hTXteK7xxMqGmqDgSW6v8d/4ujkiBB2zcRdDgB7LPl+P7HvLtYmmWvDdVnRcrE2WQenjIH782pNjGXN3+kx6dvzYsx1wf7OeT/Unhotv84ZewuoqgM0jN46ApzjitrjKHveTIFkgLX9Crh3yZgvKXq7Bh33PJYSGFgjyrXIzAL6kcuGIBFi7PcpRdzNobGUAi/eWgV53mXNQKv4cJnegNTA7hLMFle/s3HRMSXm9fdlpSSPd3CNLd51sBR1MKcJiPfAkgW8qA7ZWM6nFHF9XXBfVtzud1znCfM048PTE4vIKRqYzuc8xYQWKErqUQF1iGm2dd5hdQ3b9QY3J0hiy3BP4pwLCEkgpVILEAoXnMVTdbBxVYgPfBXVfXd8bcgzDrQcyAZEh773J/21Q3BfVrw83/HH5wV//OUV//jjJ6ybaUh2EX8zO7he71x7Bbjd7/g3f/8Dfvn1Bf/lf/X/xYfHM0qmVMK2ZdzvC1pruC8Z58sJj08XRCgeL/O4pgyCYEupyFuh7h64/kYxN2M45JLhUzjgO//88RcNhJXa8OnlClHFmjcIgPu6sXfc2hRebxsBmGaBbSujAjKesCievvlX+F//b/4P+C/+3/97ODT87m//U5zP/zmdvXLFVtjmdjw6Vb8WBg+d5r4fFT40nB8SfJzRmuJ8YaXxdAnYthXiSQvfltxPyt9sQFvJkGyHjWoAAQAASURBVBo0GqljizpfErZAoIvC0moAHJPUknetB22Ngo7KBIoLENub5suJSS+AXBpK4+aUc8Oy1EMPeMP1nnG7ZdxEsawVXgDxDZeLxzQ5uEh3HheYzJZccX9eCaap7iCYPSK2TYldU/mipWXH7QRwgpZH0x0E1IX6N//6R5TWkHMy0XAu0KVWxN7HfwgoBvbV99+e78BilC82o07DZiDJtqQVcSJrZblneFEDfPZsvRZWMUOMSNOMVthSqFBsC6vY8yliWdhmeL8WS0ga8tbwdv7KwMSCA3LlZn0+sQ3ER+vBhx8iiX2R6Q6aEuggF0NECRXr0pOgztypKLnyuysF49WC9aE34wh89kSp5ErXJgXgWCEN0cE3Jn1qD7u3Kx0LWs7tLS+VNQRQgDuybbZX0C1RgyXRnR3lvWfC1Ap6OxO8bXy9lbbuWnCDVqykUT99M+PTLwuAPRgm0FdGKxSEwXdKgYmt33VOBlXZjnUtpj8HQGg6ESKNFuZTwjwxEVCl6w7nbaZYJnqQ1itaFaVknsMRpGzG8grW9kYXRbG2EqE9sTYC08GAALV2G3Woa2b1DdWYNWTjkMlYh81wd8uLyWM+WYutcj1w9Pvm+/NAnD3KpmS3rBnd4QuNAXttTBTWzMRgnhLO8wQnglwatlwR9BjIHFq7ZK9g6xAd1AFsqPa2BCtAtAp4IbhSC+Y5HEBgWt2TPWJrBOhcJkIjCYKRgmKbebUN+vX1Br9sQyfDOYErFXnjWCpbw+1OAF8AOGNiTnOCD7zPdRVcHh3mi8d04jxtLUOFDFAZ6SF1WYJr+Pz8ilaBdWFhgiw6j/NDggsEssQlrFuhQxinD4GvnCGlM31Z8OiOr3nb7cEBjs/aAAkRXjM2NPjkcELC/QaEtutJedPECd5BK0ELKLAtDBrnU0D1ivXGvUcdB4Q/tP8pWMWOwcMn6mWJp24IxEMbmZ55UyQ34ZQm0w9JEM2o6wKnjo68B8DGh7gHh4IBgrUvSbQDCGqNblQEWsj0hGLomdBkpw5Arz+33jJIzRIHhbkw2vrCtWZfQ5igUwPRuzBqGxggL6+7me5ZHw5qLRuCbiiPN59n+5oM3SQdwFYFmrDNvOwyED2pYBvenmDsLpIUmvYhWBHC1mfb/1RhdT9FF2XvOlM9wWK135hp3sB1Mac42D6qPEdTtv6LwN4/i3FSyf6royWSYuM5b1jWgqYO0wSyDoPHPJNtVEodLZ+8N+4RzjFWLIUgGnMesiakrNClYf31T2h5RauKbeNaEROQ5hk+0GyiNEFw3go8FaIFaN5Y5sd21X1f6HvoMYHuIMqo5iuBuVIObR32Ye/oltlBhVLreC7Hw8kOiO77LGMSb4ztN1VIC4K6TX2xltgj22Uwr76SFvVWzlIyaqvUx9rorBpDJDh0v/G9DZMFd7g2tjbznXB/iDGis4d7S9IASbBrgjlhQam3G+239GXrIUAwUQHTq+V7arWgtWKF1EbNQXVkF8Kc37QX/pzFizre5/FgAa1AEckerrsmk7dCE0EE3ooex8r4IVkfTRuk7a1i77/HBscAHdu7a+lTVA9zvscAlm+/OWvT7vht3ygEyRwAHFgVnZEk40YASP+7Lx45GbdynAeNUZ5gvFcBx4N2EFkAB0GpzXRxv3wG/afH+3XioG6CQhE9++Bb3ecWv+vt73XQ93j6vWXcvc3jDvMpBG8FkF1vLsaEeZrYmtidlnVne47x06rFFwoo45raAprmN2DOcb/pR1VlYVZ2hlYHwpxTiHgEeKgHpBI0AIBge7ao2nULUo8XQPCu2fPx3n8BrKoqwpAh4MM4soyPz0fB2KspW6mdNybikLZRuybGMjln3NcrvGZM8UxtM20QzYAAr/cV8wHUrvWg8Ydd/iWXaoYXvYjusZWKGAisO1UAFSE0iHeQVtAKn4eDwnWCiYtw4QTU1YoxwHlKKEtGywX31xu0CT4/r/j4TcGHb8xQ4xC/AgovHtIKGX8qgO9zrKKEBEzzaJ8c63AvuAk7pMaGqsp96l0+2Hog3n/S//44IQ9r528eth71+fFPf5odVmkK+PnzK15vC0opWDdKeuBQaGERnC6tCsA5xcuyoolA/Sf88vxiMhkRUIU6QZpmnC8XnM5ndnZAkQ3LKVpRIYCn3m8TscfTaCqnipDoUppzRjMN9D8TVf/LBsJ++NMvuN/ZitHR5dtCB7d1y/jl04LbvaK0g+PSYVM7BnK5NNT2R/wn/6P/I5a1YNsaPj93pL5T14/BTEPTQseNWt5VngtEGnxwiJOD9wwC5pnCz3ST2GzAUkemMeJFSHQ+4OZs4Jbw+3qLQKfoh+BxuSSsa8G6FpTCAHWzZGeee2sJKyPrWuEcL3SaAoEHqxbmXJFND6qWZqAI/1wMJFkzATHYBlwAnC8BeWuYzw6Xp9NedVTQdeZM4Ac4Alu9wkHWBNk4bCHdtSqMwu+AYAH/cZY6JSilmYyP221FT7oQOLE7yEOnth4B6I6ECfZ2NSjfSf8SGxsDMLMBxLa8Da+f2Z55vtA5cz4FiCi0Nk5UBZo4EwPetRO2JRsVl2Pp+sL+6q6Fpdb+aZfw7uCi7eEwTwF/9ddPuN8zvFD7qBm7USCoudChygmNAnpVwSyjQwgoecN9ydgWtrIstwwfAitpnaGgSpAPfQ4xGAUAV/nsUYEwe1uEGlzZx62T3nLUk759Gjr0FiVnFaUuljsyLvsdNR0cT8aYnaiVBVornItseXSKhsJqmyrKaq0JrjOc7A7sz2miqGhVEzK1oKm/bicECmIi6NnZh9WqfK00vD7fEEzvqmRWIQE6S/roECZPcNDTmjvEGZdwMabbHSEErMs6dJUAbvjeV4TkxhhNsycmbuO1t1zOc9oFo62lMqXIzVP4TCz1RSkEvEphxdk3Y/6tZKbF5BFTpOHA1pBmslZaU5xmWl231kbbiPfUw3p8esC6ZiAJ9dpsLevrKwV6e1DILbfUYq2qMsRF2Q7ZgU5nQaU1g4sDdQUIdnqhlkOvDp4vBIVeX68IE4Wsqf/ElgG6nWYIFPdlg4hgPkVzwNu1FLuzJ9d8QckFtVT4QDalt6SUbpMF5zPb6bdV4RNZgKrNWlIjXPAoBbjfmcTe74rLhW1k0+yxrBX3dcUUA0L0CGnCthTMpxk///SC5cb2rJgE3ph4aaIDrA/O9qqCvBZsWSCuENg1FmRKPO98ImtwuW1Yl43aYWszNdyumcH7JiOhIQaH1t+REggLwcOngPVuFem+F9SKeQ6410r2l7oB+Ipwn/GJ2mos0DBgU9Mi1KbQQmODTz/+isd0wpILrqVAXCIO6gWIEa1UaCGAWCvnt4QAL4BqHev+EQTbGR77JtIDJW8thICOfw9Nz1aNacO1wzuHaO1VYudouoeQe4OPju9SFWMTA0HU5qk5udpeqejZp5r5S696U9gZ2MXy+7UfjQmULw4Qxz0EYmyPOtY0DGBY34iFQ5gAa21AtfgIO9sQBoSJJY8BbgAoHbgn05YyANVa1eG48kj/feehkOHu3J+PE0cWkL3iVnetqJ4gKDxK3fDz5xterxsu5zPO54VM96bDzCKmiGWrg3kabW531kWtzUAxtghBBUsuKC+vWO43M8/gfhzihBQCAgq8CnxVa1UMCF1zqr9nbYex9RYIG4lrbz1pjWw0G5NN6QaZax7gmAhB/RgDguc63K/9yIJgEsU9zb8BKzDAlZ6IjjHa4x/dGdqtteHodjx+k0WjZFNwjm+gW3IdrUKLSRdUE50fVzvGL//c2/a67lIHXLzve0ZP9o2teBC7Hv+2s1fVAd6xUFdQGrXuStNDtmhJpN1D131qMFC9M2NMVD4EP9rFeM3eJoUBwAcdQTIge2H3LfxyZGCMJ9Lnos0DNEFDO3wXf78bGbQ+fvTLd9WP1gA1ZtlobZVmTHYZwZeYvsObNRG8rTFi+tjp+bWtmV1f9bdS5w4YMv+gBht12GQk+KqjBDpahRvwBgT/AsDq1ym9FY9jCC4heCDGBtQ8rksgCKOleb/TbtaAwzzqIBiLcb3Tx0FxBHKsWGntyyKClCac5hNiTMzThJq9nd/5hsll7lzOkZWkLsGrM64DCyFfc9Ll+6/w/tCi3EFdhQEDzoC0ff2gOP7hHm3fGnG4ty4CZe+LFBjTpn8vzciGNKAIvHg0UbaDv3snvXDeWoNrZAsftSibNsCpFR8DlkIHzlo3oHk4wDoCFFvO1Dt1xjBzDiIB6hxUPBoEuVUs24qwCBQT14h4sRbhwD1HyTwN3oM9Ux0A3YsGAGhKFSZgpeRKaw3zlCCPQAoB1+sNLs5YN8Wvzwu++abg8eEBIQgLAnXf04e5yXivtvaLOcCakVtnZ0F3AHSsz9hx8uMk0Pc/6D8b+Zr9TqtvGQg4fmT/329pSX5t3nnnsNYC7xw+Pb/i0/OVa0jb1ywaOeyAHGcQW363ZcOnSvbs09MZMXma9Z0DvFByRlWxrTTByjXbPqCAd0guAVaUHlIQtn9pYzElm764dqfMP+P4iwbC/pv/9o+4GRCmqiYwzgGXa8OyFuR6GDTSJ9nYB7HminWrWNaCZSnU3SpkxRxBLzUav2p3KilodWPgXQ2xgQCoCJHMrzQzWUlJRgK3LnmAS/xZQWsER5xVphsAMa2ovtnlrbAVKnrMUzCAg7pEsGS1tYJszoXcwNkSGaJH3ipqrtDg0UrDNPF679eMaVbc7hnbWrEs1LvJGwGxWvvCdqhq9kfak0dhJfj+ug5dKQBWXS3ItbJP3zbYGB2ZKA5I0SFFbpYdwOsgWAPohmEvzBQHoNrYimfBvDZF2RoDvtbjHQanYhUM12QIfVMPjUwg54GHx4T1njFNk1UaTWsJQhbXV6ok4oXaVImOjb2F0gWhcLlRqp13VnXh9XVNNlVB2Sq2rRp7xuzF1dwT9UswWyxKiY4tldM5YjpN2O4FpSmcEQo6yEahcwJSITqcZoJEAuG7vhfc7xl5q4PNJMqefBHbtA/o5RBj7pPHeYQUkZcNISY+c9lBPznEXT04HwlOf2LSWwGOwW3/p2Iww0D3zRAIuJVtG4ugE2P3mPiiChlADdS6cwPl6hU9AtCnS8OWC9AEKVHAvnbWYQdyZAeemDAoWgctVVGXBt/ni3kOOC8I0SFOve3RtP0sUD8/nNn+5WW0LqrN9c5OU5hYf08WvTBBRgeOScUOQTBPHr/8srAFUKnl4IXmHb1VAhYw1kq2IoLHtrEyHgIQUoU2uiPmVeF9tHeg8Mp2l5AYNGUDXsrWsIWG1QTCW2de2u492uKch4YORFBIdlmLbcIO1+sCEY/WyM4KFsRvW8G6dd2wMIoW1KeTkWCVUuGjh5SKz89XPH44IRcyTPeAhBNq29j+y/kNOss4a6Ky4LhT5zuY7rugelU01wyAYEDjTG9GleuaD2RflFIQ1QNCMfjlWrFcG7as8F5xfW2Wi9L+O5eC0yUayLs7/fVAJQQZgF1KAafzvqflXAAB7ne6NnaQhoAOK/EhsgoLjdhWCufflwwVj/NTQgpkYRkMZOCx6Xc5bwL8e9GkjkSO73RZ6doqIvCRgOX9XsnSch4+KJJzqIHV3L0tjzouwTQ5BMDD4wUNDc/3G1xymBID61ILekbmNHHNyxtCMvH56KGFCYN1ZVvQqENs+g27ZcRqnCtUtxFQNNr2CNPUkf4/kQNwtgNfTi2uOCQqag9HjEmpAnhVSKtkpsOTGWRJagedt5wNZOQ39HHe16Qe7/Tz98OJkD1pCb831tP7o2uLeKOeeWu76/HGcNM+rP3jGrShHACV4P1op8ulmeujhQhyZDbouPb3gt/9rYxiibHsxO6hC/n7HDGlhC2T8f16paj86+sduXIfnecZcwrUZBRrDXLOElB9o7PTNdYaPF5vV9R8ZxBduaY57zGfTqavaBqXoNNjcA7BCZx2RoWOvcsfnVOF7AmL1vkca2Ubr41LPrsNOW9svxZB8gnOkdHhhIOng/7NEo9+H6KK4GT8Q709HVq4PkS2yys1YndGIDfmWquBYJTiOLb01t9wjCTjpaJUck9OpwvW6xUPl4B5nvB6vaI7LzqLF47sIga/YoWI3ZlyFHuBwephXNxlMLqsQYOgMdkXAimbtsGMG0LrA1A5QiqdGUm9y1KLscuscGKXB5vnKYahA9cd+RQEpArMhc/WF9e1mgbeQ0YyzKVJDwG0WDzUA70dJNs147z3A6jsexPD29/O8BS9RdIEw8F8QuHQtK+/9o2yAxj7bH97sG7BnWgoZkkvnWDsAfuYxwA0nROosIgHY8XYAIKKgXbS2Y685x5b9WvRN//uzEdrAe7XY+CkU0Ez3ebRVi29NXiPp4o2fvcBcPDemUg+3nx//7/OmNQDWO1MniOlBO8CWffSvtpe3tlK3aXSB4GKgmZEpiEJ7GuU/Xdf+5l/9Xj2oMX1DhR1QgAsOIELFBLXWtHbGmXgwAKnZOGpUKqimPtmP1/XeuSf3YiLRsFwPId9rdfDNcmbuN50qYQkjpQi1AHV4lg0k65Qxs8KxvLqKI8A6WPP5q565Er3SoDtzcGE8J1zKA1AVURv4+04SNVylLFX8xpDCDidTgPQiz7hMp1wne749fkFa/PIpeH1uuCnX1/w+HDBdx8fQekMu2fwPRGk9fbz9qZ4Ntir/ZoEAzgae+YYBod1c7+Bt5PumDAOlFPegGD9Pt/EQIevP2Jo/bNHYmRwgjTR5ffbDxc8/JTgHXCaA4KL+Pz5xj3OGMZd6gWg+Y4o44xtJWPz4XICGvOV08m6plZqMMJyt80000XAluxQR7HDOfdGzxSAEQQC3V8V//1ojfzHP/3CxE57oLujpQRSBLS5VfS+HRHS5NfVALAtYysN21bhhNR5iMIFo+taRaXWjFJXtFb2xVDaQcCRydF0cvjm2xO++90J0ykMOuenX5YRYBSjcgKCshFUK6ViOrmhn+E9gZ51zXT9ahUt8/efPsyYpgCZmehdXzdbxAPbEKtiWwscyORwE8Wrc65wppm1LRkOFEqOs8f1SpZAB8Bas/Y87Zv1l8/fOcG6FoRzQCvAy6cbAGoieU9Xtdttoag89o0peEEQaj5x8WFy1cEYY2rbpsfFolULOHVfvPq/OhLfW0n63w2ZDMgIljqQEKLD5SFhWTJO54CUKFrNNkE1aj9BohEY2hGSN7c1ut+F4C2oA9LsKVRdxCa8AkLmhY8OTT3mKWK5b8j3gpIbimusRtr4FcEIro5HT7HO54Rppvg6WUIGYGwM5nrRrdWGslVUVeRMa/FexVyXimUp2FY+d+cELoRdHLj2IFJH0AqQJdNKByfpdALvUYqOzaBZZc95Y5F4030SmLAiRX9JE4/U6wMwUNbDO+zVkQ7CUX+g2bvlz71tzvtmwAfQmSjOktPOVFIAaQ5wtwxduWL4yGSn1T14HrFzf56NrKpaCFJ1zQiy8Xg9Prj9H2tNo2xBG0mIc9Qx8CEAtSJN1NRrpaJkBg8ZZOzsQUXXhlDasruGFBwuDwHzHPH82WG5b2anTRfVVhu/27HlaXIRq1VaUICtVkQP6OSRN+C2bbjflWvBuvE5W1VxsDdUkEKAs0G25YKX5yvZSfeVwbcl6nuFS0ZQuG0VWy5srTZgZV0yvLVzxigIVlntjDC2WbTRntgqATwXZYDDPgjbuG29LrkiBI+mlQWCrVm7eDM3R851cWSoOGFhoVp7efABOdPo49iOo02AIDjNCbV2Eo+itYwQgmm1GZykDbUKagGyEKC5LxXbUnBfKqpSnzElh1r471Yz4sUDGrCsGQqKLr9xObagvTU1lpbDuiiyCb+WwoJJCA4hgG5bqhDnEKIgTWytvd82QCI+fOsguhGIR3ch5FguuRAqCBFpYlC9rZl29MEPJuO6FZRCo4M5eNRsGmpKlhGr6Aa2W9WzJ0qAiZ6v1Hl8fDrjdl3xOdxxugTEZEBVT/6doKkDWkBudExFb+F0bjgxibHCqpmQ/FbyWFpD9I6J+2Gp9+JHsHoEdTpA6aQnBoKCYkLjYu5g1rJjxRoJYScZGCjCdWX8EFA6b75erwgxYPLTaIlrWvdlcRQk3t6H957uU8aocE6+2hp6TJx2do311PzGoa0aUMK1q2iXKZDBSP1C3PrwHWwd7eL3b8Ew1d2lEoK9im3ASDDWQggBH54e8PCg5gBerPhZcb0viCHA+YD7RiAzBbbBwK49GNtjtECFgPPljDR53O9XtLIayMQ1LPiINJ0R3Z5A2p2xCOF2YEANKOB7f5+A7OmWmMj4UcS4P4tSC5wQeLmcJmtptMRfO3P2HRPI9kwmBjBgqLNwjLViRkR9KOgASSzZtUJvB192UwC+F7Xre9PqBrYm5pwhQgDhWhumecKUImohuEQGrTMccH+OTsgDF9Nom6ZprAt8JjrWI2dgRlO28DZjCLgOrvbE0q691WaM415Y1XHukVD2xNzAss5I7m3G1QogwTu2kvV54rxBtLu+kHY9xpzN/ZktOjtoA+vRBkZka+MQB2BFleNDTN6i9v1bD86kYhwqkX+SFVZaQ6it04NsDBJY6Cf9uiT/4eigXB80Fpt1JhYvY3+uHbDpYGQM0Vjkha7H9d0arFz/mlADcoj+j4/w2p3t8aMd0FiB9ga/cuG8JuqjHRmE+5rUtRB3zMDat2VnzfKDhzFvAOwb0Mk5Y/iwLVYNYHMiiN5bUt8/KxD4A1CogFQWQkBA8O2q0WMv4odiwN/+3L+u4yhC8yzv3WhzL6B8hgJjTPZxBZjhh8U+Do5smv4/7UUQBRoslyy43nsBgi3j3lqXuz5hb1PD+E6Otz4vvOl3KawoYXrYpRA0ooFUsHFqwOdxDRoxuWnyqSJaTNLfV4sBKcSDMYBi/P+73LavE1NKKKWg5AIvvIamisvDGb/8I10Nn69XfH65UsAff4PTTGmNWnscyTcVvMBJf+fAnCK2sqKBGtf7PRlwfJiTcrjHzsqX45Q1BuF4GPsAePvv4/FuuHzlE28//u7zwTvIPOGbxxO+//iAH3/5hF9/3SANiGaEsxViJE4ck0Ct1q1WGGeAOfv9vuJ8SmZuSEZv7u3DIphigHjHuM9eWLXWdbEiyrHYwVsmENbdr/97AYTdlwXiArZyFPjs1HA3XDk4STJKVSwqWBYyYe5rJXVbTBfHA8HRmY4ii2UsfqVuKOW+JyTv/u28tT6EgA8fz/j93zxiOgm2teD6uuHTz3csy0bG1VZQi2k3QOFChbaCMHuCMjEhhYhaFc/PN2xbsYoGN8c0eZwvESF43K4bQvSopcH7/aWX3LCB36HIBFxKQ9cGut/Y2rMZe2zbutjpbz/vMQflUFXQDroAJZO5UjagOUXe2GJVi6LbxMdAxsc0BZxPgWJ5ax1ss85g6YgvNcRg9rkGjr0DwgAwUHrH3OoLgb4THfXB4XwJmE4EpsSB2js+WKFAsKwZy8KNw1sgKgJMp4j5lBCCwzRHXC7JEnUgJcH5iUya+61ibZ2dZ0ym4KDVmXOPoKhCK9lhsIpzs6qQvnsXAmM+eYeHh4R5ihCFVaD43KkvYVUIeStAW2vB/WbPsijyptiykj1rznXeNJBggCWgQwC+x3Ki7F5lJVFH69O6ZX5GezsqGTLRs0XNR7bp1lYNQFW4YsYBBhhR18cS3h544W0SKqCzk3Okgx9zjmOYzmCRCbHt4odKrdo4MJDKWpBD9Ag1oGzFgLR9k+JUV1LqS7NgoOvvGMAaZbCyxrrgxLqx9+Q1bxm11ME+CIG6UqsayLYaaGNAU206ANfWKlssXcDpFPH4SH2c02XC8/MNQT1K9hC4N2QQb62aTan/Rh24YhoJAXkjKF4+3XG/0xnJG5AS487whCUITgAXxdhMZLi+Xqm55hyTluA9wqFVpY+h2vaCA8QhxAjAnIpAVkutvXLoDEAhCCXBzD2aDqZOjAFexOjvXB1qod5eCMb0q/zvy2Wiq605NeaN7mY9UOrBZwiR80mctWmSARHMZAVw1DRXc/P0lW6tiSAkIMYuBVr0qA1k6xZFaeAeoJ7JhirmOWFOCVspEAjOpzOWNZuT5i7yqspCjm57hdN7Yy4kagbWWuE9EF1goRx0QC0237x3WO8Es1jJJVMt586f4lgNUZFXstt88XZ+6phtW8YkQAwEFOEwAMYUA0pomObIKnPvAlNLyJgtkc0LjqmtVFZvo0eaKJRO97YMiDHv+gYkCsWGJgqpB+aIsTG8CFzXOjJtqN/a2HqgCcA0NJlS94SYq0ln5jHAr50p64EgoS852NuQOoN0T6gGcKUdFukJxtvrYtGNDL9puGnZ+cGEXapAgpjz6nGOB0tyOSe7JuFXk+U3PxLb09+2Uby5rlbRWgXEqrEQSBVUz7X+bbueMViqWFsME5xubd5bZd6fH+gabbyOXtQkkMb4KkaP2VNbZFk3vLwucM6ZRo/DaaKT5y1nqBcDo4sZiLjRCqgKuBDw9PRk7YcOufLdexcQ48QU2xh2Rx895k4dbOJ61vTAmrMPdcDlzf7kHPdjiyvfnBQE+x7OJ1xOJ4jCWKfdDGFngb15ewYWiIEj3Kg7m3kfx/ur3xPc8fytYPu11sjW2hffyWSvcKwejpTSDli1SjaVY7JbLcZzDlDH6xRH4DgIHZL7c6rFxOLFvCOMfnRkQurYyzlWWMhijFHLQQtRMYwljs+cTKFmoGeANzFT5xxc45rb9y8AUGPy93Y+HTGCxSU1I4HgdTeqEGMqUZ5CDVDmnivOUSey5vH++XcY8WHuxlzY3+Vg1LX2xjX+zRvuTPPWWzkdBM20ZI05qubkPtCg8ev8Y68k95mo4+wjKd8LXehhEFtbHZ1xffDIeUFn/345vmCM0j3W25+t2H4uB0Yv91w/EhC3X7CtrL29sWs59oWXzCY+z31e7DctAkugGXt3JrhC9qLw4RB7z1OaBkuljj2DwEAu5c3VHePVsVoIwYKvrbz77x7HOv+8g4F7O2SPE7wBBf15DsfMnlNZJw3vTWy93e/rCHbuBYteoIdpcG+4LwuB7BgZ61fTBhPQLbG2wegFuJ6JF3RUXqtiLcWYZ2RBN1UgA9M0w7mAaYpQFXYHHAB57WMRZAjrqqjVD9baESwMXRetj+GqgLVIHpnVYvtOMJBFwNzEx4DT5YT7/Y94uW0Q/4qfPz2jtYo5OfyLv/6I0zyRJVrMlAgOcZ5Q6jJeej8fMYk24gwBW057jKDorX0CgsACsVY/1cPI6D/oC+tvHX19gfSReBiD/d77d3/tkPGP94I5RXy4zHg6J3z6BdhWtkt6VVQr9DvngBjQMtciPoKG3nh9vd5xPic8tvPQYV9LttjFI1TH+L9wvEJtn3KNBRbv4JtHVcZjOuJQ6xoqu/zAP3f8RQNh3bVkIMbAG3CkKYGjWiu2bcV9LdhWxZYrSnd4g7XHgCLkJ5/hwWSDvaamI9AKmtiOrAqgorskiDEV1NmC0xTLUpgEtYZ1oYXu8+cF61JGUiBeIAHcoKSiVUdgIgUIPFrdUM2Nx3uPEIGUPE6niGkKqBV4fc2oRbHlhpzfBmu1KtYlY12KVYdNbBGKlis0MzGqXxkr7/ZEWA4wFnLvO/WT7ny3e4aqIKii1mw974oUHTRwQwvGVkmJemnnU0AuBT8tGV0DQkQHUMZ5w3dctSG4w0J2AEneC5e/uQvtjBoBxA3hdu8FeS0IHlC1aqABQd5zQeoW8/3UIXo8PM1IKZJxEa0CcuiPhlrQ3wA6/zS0kgFPZ7LKFIIPMQDSxJ4LWRwK4L4UrEdnKGBobcVEXbg4+R0dF7ZOzaeEVhpCDCitWrMPKyWdxVSrUsdK2W7AgMEP4IvfR30g71mdyXm/Pz7/ZmIuBIacbR6j4mbjI0aHFOhmGGKACBDRq25kq2nj+0uniUlmYTtVBwJVLRexlXBdqT3CAK/beH85dr2NVzX9GpgOTQjUntpWuguKEzgV5FwQpwlxuI20A9Dbg6D9HlvXmqmK4BkgzDMAB+SsB7B4F4B3jmDN9fVq6xJZJPHxgjhFNN2MAcnEo5SGbOzEBI7b1hpSCricEkX8o0NeKx4eZvwa2KaU8wZBYLB9mK+d3TXPCVqB+3VD3kBAdKOpRd4Kci77fTeGXk4E6iqgFOp0Hpgc27+1Aa+f7thWBpFcKxQpBGiIA9Cm+ybp0dFcMp04pDmiVmDbCKq2amuZ2vPrLxOsjPnoEVQGLTpaYj0cJhvbgjefEfxkVtkVbhKIRGy5YtkqdCt4fbmzimjzPEW6i3knOJ2CgYFceGqxNqaVa/JpZqUvBFK7pykiRTJeFZa8Q1EnB1eBdaWrJeRtINKULsbzNENcpt4adLSFTSkO9hxF/KuJz+9r8JQCpkQgZG9J2AOnWgkMUnicz2ddM0L0WO+bBZN8zM47S2SAHJ0BpxRBp1seGRq10vFQRdgeXhmkEgx0OD/OKMa2OK6jsH2kgdejlewt7+hM6pzDh29PyHd+Jx06d+bB2AHcBtWIUivSkDwwxpEF9g5cxztQtbOUxnJ9uCZh61MH69BDxv199aPfU9XdzYnn4/060z38jahytG51EE/cQSsvpXE94xpExrl6pbMzL/vPekEkWNtvNPF/GppQNLiz6vr+uT8TGQDUzop4a7hD3Q1bk81GneuvH4lja/0ZdNfhzlAygM70O3qSslfvrR2sB+OHoLwqgb1125CzOdAa86eWjFILgmcrZGsNXgTRi42nEyAz8rqi1crPWEw4mfGIF8YbwZ8J4BRqaV5fXpBSwpzizrQyDbbNNXhl/FSsKl0tS5RSWHjwpn12aGnrr7HpnoIQwGKMl2LEeZ6RYkTeMtlFrpu5fA3U7EUrXl/X++kugWRD78fOMO6wE8dcbw/shd6vw6Fvz1NrNU1IiuYztktYM+PW4APdkn1vH+/SBCYV0Aq85VdNbHxB4CE7ON0UqI1mONiTW2K3MkCZ2vY992sAtNie1MEYrpEO3uIRxnyW6DlKC9gXEmxSa5vHl0xMwNqQG4Gu1ip1npy5eAIEnqCmDWeAlHPUO+qgqO66eMELWvMWu8hYA3qC3+dVBzD2udjTVbW1me8YYi27qsZysn9ULB/RAQ51ZisEg312TL73mMjmsHS2lhVnDBhkq2gyRoz8xqCy7E12g4I+N7pWHBPgfb1q2gXQ+/NwBJNsg3Co5m7Mok2P2wYTUBXO7ew/tXdba2XhBb1t2EG1oKk5MzZ2T4hzo2tnmmbM57M5yVMCpTYCmNGxwNzn/i58c4ylARFv8aZ792S4nrlulsGbfQvgSe9FwsihOhOyOzxTy2+ztl7Xm0KsmN2LDm9fTjd56EVNguQ7iBJjxGmexxiYU0IyYXuu6wN7GXF9q9zvnL3nDl4sy4rX2x0xBBZPnR95ikIGmN6aDumjsTmML4EVHm1ee4/g2LGSW8PZ3Kpr5Toq2u94JJToMMJYY1X5zB31oC/nE06nGS8LjcjqfcGPP/+KP/7jA84nb9ITDjU3fPzmCTE5XM4nfHrdxlesy4bZU8OXc7uPAdnB+gNg1RTGqN3Zf8f/B2CqL1+ZXMetYiBovzUP/+njfX4dvMPDecbHpwf8ernic7kD1iobxA2NQec9nbEth3Su2rxibrncNyzLBvHBjGAajQ4AlEIt3BC97dsHIF2wd85ZvtaLH///3N9fNBAGWDVBARj9ELBWSaNH31dqodyXhS0mmUCQs8+KE6AQZfACNKlgp1tFaRnrulsp2yyBrczotFzvHWqpcIFsgJfnFS/Pi7kYCbZccbtu1v5nYqAuIHhBnKhf0fusAUHJbJPK1obFKpHg4WG2QJcC9S8vGT//tOD1ZUXOZDx0oeNWrS2k7tRWM8Y5LMBfgmC21hqQ9eXfxyhIEzfqWgnMlKK4vW4DaHMOmKZIxkqarIUGQ2Omt43BEZxRew8EJhymyeN8jtBGPaLWFHkj2NiD5FartaAItttmz6hvbMeJa8udmoB5gFUOYQtjQZriYGx5azMsmayKHkB5R8aXd2Q9XB4mlNqwLNmABi66ry/ZwDl7jo4BSq9vb7kgpQkvL3eKtAeP08nBiWI+ETCKV4fPrdHhrb8r5Uaaosc0B/godOVQIKaEy3kGvMdyXwHxWLcNVenYVLOiZMW2gawaA0amyVyanM2bVq3y4EZSCMhYtHbmhBL5EYw/W9rNapSBLgJLzCJpw05YhdemiCnCe4KnNRdAyX4QL5DqbHXvLRluALmdxeMt0VF7Lu/Xvh7sduFG5wNCxHg3pTTcbps5jWLMP/XUfBMEA9y4eXe78F6R3ltoga3BqjVKNpkFdXYhI2jMuaAuZGfG6MyFsjIBVbovxlAxzdSKenm9Y7YKkgDY1spAwcZqjGQwTieKTT5/e8bLy5VMLyEQ6cSbTldn65E5EkNArS9Yc8GyvLAoCbYpO7uevhZwKlXOH+eZ+GSyo7Q1XC4n3J4XOKXeU5+LTRqqsCotkWBrmhKc69bfFEeP0Y/WyNbYktxZeSPBd8KKfKPOmjiCSz1JBDCYddUYU32znBKfZ80Fp9NEIW3JuN9WrMuG6v0ItqeJYF1MHk5Ng22m4yo0Yl0K7teMlAJaY9tWDAEpRsRk7DEDNGo1R0jl2FlXMpH7+3PiIIUBjg8MgkKIuN9oqOKEa5WLbMEWMRfKOwGsaPpzKYWhW+acw5azAb5mbgJL/hurcdQncSivFTkX/PrzHdN5Rpy4d4gwqfGBbcXedNRqK0wE7XvWbSM4FugU3KRZosB16nJJbLVv2TqDDowGS2B98IBTIJJlBE+NMe89iiPFfisFyUUcTRc4twTNV5QqCBoGG6YzBZ0ICvbWVjogd0bAYV8wkC768Cbg66vKkaXQQd7eygZwDDazDO/Azmgz67+LPfAXJ0DdQbP369V+AZ3F0gEshVM3PttbCvt5WlOEeAjkAcQpwdUGyWQrUO6hvVkxS6mAhAE2jD2zWbvjmIcOzlrZvAUIR8AhpQhVatZ1m/uWyXD0gTpu2hQVdQcfDkfOeZj3QBldHeUQSql4eb2hljKyP7am8Pk0EVxvq72TAyvEUc+zsZKAWiqCF1zOE+dIzWTaxoTz0wmvv/6KpornT7+iKTDNJ6QY4EOE+ojqPdpWUbCOQoUX4JK8CXUTUJ+ngCT9ObXBaDnqXPX36MThPJ8xTxPm6QRoG+1bMQYAbchDHNFbEbKWBvsM6DWD8YEOnPbvYkudxTZNUVAMCMvW0iJ47/qHd8CdgjFYtt9Z1wVTjDifT6a1mZFCREoBqnR1j8HTUdzOyyR/Z5tpU6jocIMdoGgH5zoAJjt7V5tSf3Ykg1/qMvWQnWYD1HMU2Noa/K7vJ8IY2Z6PAlBrxRxteSIYwtfje3R0O0ALlnXDaU4A/HgfncXFvf4t0E5AmynwDtjAjB7MHe9di8+R7dfjEYZkPbfZBwGBZzIpnAqkO0gexoo2Bbw9W7+/d29AyxEo6SDGuFZ7Fr2Fln0nCt2MZbtrlHxxiJBfx1fnMBzK0YvtHRiwVWnMJytoO0/Gm58AY7m1vKHrMm1di9mxXZBjh3tvcAHBOZRWUbUMXcn+5HKhdt+x08SJQ/KRIO804fHpGzx9+AAR4Hq90ZSjNayZhWhvrF12CbTRYs6fAYICD3PE+8qhCsAFOFeh4q0t9Nhm2J8jn2UIYQd6pctRbCYfs+ueHtdusfHfi9kjjzOQE3CoQuMpgO26p4lxVLkUVDXNRNNcdLKjc8wdCtKURhvbuB7v4XxErVfmK6XCC4EwLx63uGCeT/j8csWc2EK3tXoYCx3k3GMKCFtcfUzMGcRhzd10xtEUr7JYEgZ2qmM/7O+69sKfEPRLIeC7b57wL/76d7itBS/XBa02vL7c8Mc//YzLAzsztjVjvWf8L/7n/2PEJKjtLWM2bxXzKSDGOIxECCa/zWI6ILaPg8N/v59IXS/Py5u9YfcyMGBtPLh3v453e8afcYgIHs4z/vp3H/Hycsftthnrq5s99AnPnF68R2sFzjWTSSJ7Pzc6NKe5jY4k72QQmFRpUtUKDWZGQbDfi43Rau+s52cs4P35iNhfNBC228h2QUki++tWcF/vuG8Lto1gS+lGIhWAa6jIABqoHC0QVWwqwOQQ44QQFN71/v13I6QVdFol/GHybA23umFbiLI0VcB1BytaoDrnES3ZdF4p3E61ZggcWgGKFkBB6undGF2egsV06BI8/3TH5+cV21pxvkxY7pkAj+poK2oAtqNsh9rtHseI7P/t5SApAKC8u23vBdMc8PQU8fTNhOtrweOHCT/9cIOWhrKZ/oWQ5XQ6J5xOaQCUnBSdxae4vlIcVtEA5+GjR/QOpzkgTZasFYf7bUMsbJ1LiSyUUipS9LjdNizLAS1XhcIT8MEhkR8bro52KQUZU96c+FLsTnO8/nkKWJJHK9RLKlWQNyahwSo9t0x2yDwnOLc70on1wBOs4OS8Lxvuy4r1TkMGAFBn1OFKjR3vG4IXnGePDEXNZF0NKNYJ7kvG2UVsywbvyEZJ0ViJla6P0xSwRE+gpxMZW38PDd4D58sMNMW6rFx8tOuFYNCqxdFhUKzNUH9jsaRAZLUqHhczb8Cwd2xv8MHDhYDWgFAVaWIVQCC8l7C3xJCWz43b245VG9sISXUWtOasavob60PryQMAR6v2hopaFcuSsdyytRSbCPiajWnRK5RiTJxu3bwH5GNc2ZerEqiibhlbg7H/9Qj0oA23l4L57PD4cYLWAO+B1siKlJ4cCnW9dMtk3Rlbw1kLGhztt5dc4YoiTRHf//4jGhTX1xvWdYMqTRKgQC6Kkhvy1uCFWlEUPLWgqVEnLQSPFK2KY458BLE9pjmNvvxt3YxlZO9cuLmhVbSs0NCs1ZU21t5aHHprdEjCd+/4e14casnICx1w81oMVDfwOgKhckw6AytjioiO7oQU188QCPJGkC5LhVhbuBcgBkErBfMs+PjNA66vC2qso4JL4JOOTo/eIUVPhlegW2OIdG+spcKBY5FsQDr8hmii1AaSQgA/EVwpuRqzqmFrNOOYp8jzWdsmAQ1h1TCVwUbTppinAIhgXcncmyYWRy4XBnw5K2rl+/Su09AF28q2G28sLwUZWA9PM/XRtoJPP9/wjQs4nc8IsZjeGs/HlnHHPbTy+TpYlbsBFQ0VDTHGAVoWKKLQIfLhMcFHZ8+DIrhdV2yIy/bEuMc4QlalWPtkrhXJJ0SfgNJdhGTMr6wZoVCPs0IxTzPOcUIVhyVnSGt7YmVOk90EgWYWZKF5560dtoPBGIm44nCdrVnAv7dIkXW4t5gd2zL6hXa3YC8ecHjDSAC65tCuGaatkYHUE5b+3ZbZl9Lp/7yGgjr0i44bvPMevvUkbC8s9GuHEoA4tnzxcx7O6UhynXAdiCEYqWRvi0oxYOmsMezFN/Tk3ECODu68b9k7BvedWeE666w1pCni4fEC5wXrtmLdVjRl4P3hcUIuLDgOcwx7nmTgd305NaH6jGJMhO++dXh+frVC6R1/9833eHgCxHuUdUFVj6UAt7zB+4ppBqZTQkweyMCnG6v9l48f4fVl5B6tAfdlQ84Z85Q4Vyr3Vgb5bP0TGDDnHEKacJ4vcOEEh40sau8QIoH2ZTs4gI6jt4/BCm5+3DtAgGNbM3LOI1HosVjX7mLM5ox1sjs4xhDfxFUdPesgXjEdMLamznCtYJonlJxxvy8otWJCtDRMdiDpcBwB4Gpt4M3vYG+/hzeJoFoAa/tv6W5txrp6r1XXNcbejjfCCEf9V1V2i9yXBRAghYgQIotvNdt8bcO0BcDQQBPIaKG3kxH4QG/H5PMbYI79GbqD8jD5jSGuLVyzIDLGzNtnsK+CggYvR7hqHx+wa9AuA9MwwFlYrPX++fQjBLapH59/B8IA3dfxdtA6a0rnwVLQaobzgey0vo5+LUFVJSBlreXRs5tAwDwmeLJ8O2PRezKFYqAhTVZrQcW+rg1Do7Z/q/duXxkt9+mMX+ccJnk7Hvy7roMOWjjncb5c8Ls//B7ffv8dXj9/xrpucC6jR37HNIvrdgWLENjXTivjhjBDNRvo2Q5PSFjc6Resit6j+obHJbuYf6nF4iDTGM0FnbV53M/UUljG7OHNXM+1IUl3c7dCQssABCIexczkYgyYfRgjra8v6qgFK9IL4X48jTQnlFJRKnAvN86LPgWU+tWlLFAFpmlCjBH3+0Idz8ruHfEOwVhrNCfYHTN9kKE7LIBpEdtcgqOpkScg346sZ1WIymDeNtuzuunElCL+7m9+h0+fr1juG6qwOPPjT8/4w++/x9/+9ff44YefsOYNDg6X0xkibLvOZgZC85EI6M4872PqeIwCGHS0jPfx14xNdpxHTtxuitvH7/gPY2S7Nz9Fb8mE7tjSb+V3/E0dH3AOmGLAN48XfPvhAT/8+AnLumLoXB++oxfY6sa4C8HBhQjnParSaOlUCqYpWb4syAZgG+F8vB8yeWUUL46ALmAxFvZCz597/EUDYVtbIUhoWrBunflVsG50ZqxNrRLdIHrrJQQAjWBWX2Vt0Wqt4eW64fn1PhYqjwZo3Scq2Bo0Hn0F2mEE9mRTrBWLVSegrX1DUkAcYgqIMzDNHtuaDa2nm2LNG1pVVtxNAL0n66c54vOnBcs9436vePxwQi1qrWwOy5KtZbTZxPvKyD4iqqBmlkMbdMaqxh6zP/ck4nSJmE4elw8nPHyY8P0fAn78xytb+5yDJNmBpOStzdDABJhmjmlHbCtZK8tGRtX5PAMqyJsx23qriwUrLgJBSD+dZjLNalPkWil8bRX2N8GO9cUrbO8gfoBcK5wlL/3aUvSI1gpJdz/F+eLQWsR6b1jvGyudjUKRgA5xz2UhQ8T7ABGH6/WOmCIeHs7WwtqwrgXLVrDljNt9HdfohHpBpykgRTJxpsmhFjrt0JWU9SLvKHQ9TR6bsX7YxmT6a15wq0y4fXAIyUNuXBCcZ4Lf5wPE4Xa7Yk4TAI7Z0orps1lg7D2/v1XbbEbsZm12+5BiYhmgwgSTLJlgpgJ0GxEnSHMEFJiSYLndAWEb3npfkObECq0Bg97v2mXUpfJMgo3OHyLBMsZ6e+LVg0xVoDZBaWBl93a3hB7GMqSTWFEyT2qxZxk8mpjGAjDct47zR9ux8mrPoPI6etsw0PcNbnSlUSMqJgYFneXjo8C5sO9CQkbZZFW0XpGm3pgjVdg7bIVmDtOckAA8PJzw/MzK1P22UDsrBOQM1IVrGJkVBbesaHXXy4FahRywFo/OaIExueiMpFC2AdSGkgvymrHcFnS2DKz9hcUFULNOGMg6zxbgEAOSCq63xkAWbCtZbhvWa3fs60uz7vpxFai5YVsyQaaUsBpzDL4hpojlfjXRVmsXCqThazUAvDbc7xtiFXx4nDFPHlUdXl9uWBaralqwKI6Osg+Pifp+yqAxn9kO5xyZwNUo/+uCAbAwiAsIjknIlgv19CyJUuYJmE4R2jKceBNtn3C5PIygVsDr6M8vRlY1tY9BYxF3c4SyFTjfkKJHU0HJDHSCsTFC8DhdTtAGTOeIz7/c8PnnK86PG9YlQhHhQ0OMbby3bd2TS+6prCo5L5jTCbft9iY5bK1hWTZ4tRZ3sXFm+yaB7TraA4+gSAP3Htt2u4wc4Cm06mugps7Ym1i0KJrhNCKGgMlHOAicjzinE3JeCYAAVpjikGG7btxBIeho6epBqqUMBui8becblVy3t07WVqFFoa63p+57UW+D7Nd9fF6dWXM8tHFtEjS4QwDbg/RSyptzlspxGczhk2vSQWRf9qJGZ6z2yreXsGdtJp4uTuAQxvrvxCEGMpQEeMMachags3U3myv2XjhooG5bL7AcASt7+BQQtgA3es91vinEK5xTXM4Tpon26F0yol+/kM5C7Rdx2HLBtm4oOWPbMtZ1ZZBcCZbNc0QKgufPn3FfNvzjrzdsueDpP/6f4T/8m4/G5iSDu9QKLZnv2bGSrSpYyw4i9Le6/z+Lbq0p7suCYC1w61awZDqao2ZMQaBlI3N3Olv7/B1OBI9Pj/j1+YbvvmuYJnkzx/o4kPfZD3pYuwMyzVhNu+FG359GUGsHzTr6flNQDuDZu4MIJddn5xBjQmhkpNy7th8fAv9lAGj/p4PFfa3t+l8A27abYuwDwA4A11L31j3eyW7qhPrFHAJ2xpx3b4FnezzoJAOuoxHAwuKKtYADguDI7Cm1QKuO++jGD0d08nKaDDj82rM7JKLvIM3uIPr2+ppJHAg667yfp7UeG75j7x2O7uY3GIlOIboDok4AuO4iuR+dsdkB/lJ3DeE+91s7kBGsbQ7v7qmUwo0OO+D0Hgcbf+wgl7HrOu7Tf8Z8jNcWA7Uogw+o6pDfEm/e3EcwZhk1mX/78NJjl3FBNr86tAWoCshSOeHx6QnnywUpJUwpYUqRbnX9bg9zs4elA/Q4dAzwxCwo5vpOp1m43wqAYT7kdlBA7R7JUOY72rZt5EIhdG1etgTuj5pMygZwbUJGbXzPuVa4Jhb38vNut9rguGtEKAjk6bgVAKhaRptaZy33dUI6UzdSSmhKCY+nE/zG9b7kQs3r2rAsK66vVzw9fUDeMuaHCR8eZwKgMSBMAU2AbCYMyQnm4AE0oFwBADEmZJk5/tVDree+1b3Nf8x+y6dQaRwWVbBtC273FQ/nGQDw9HjBX/3uA37+9Rl//MdfcF9W5Fzw88+f8Ye/+g7/k//h/wC/+/iED5czLpcTFMDl/IB/+PEnrPcbiSFO0GDFMvQl8phts7hatNiz35mfR/H3Y0mEw9TG1Jg4u05pw84C/6214p86CKSuQ4tu8gqXPPyHB/zN77/Fn37+hOfXF2q9dskd72nO4T18SowDtoUIigDiOC6px52REuVeUgpsl4Qb99tjBpq3cJ30RkbpcYAen4j0NenPO/6igbC8VmxtwfVWsawUW+uOjL3yCRtkTKQdtpohHRw6oOOd/UB3t4YDCMuXJv2/94Xxa6uqkSKYqIsgdpaWVV+6GHpMAQICVaT3O0NTmWCuy8qWBfQkweF+y7hdqefSKnA6RYSYMJ8cal6xbdTmmpJDU4pM52yVGEucVBXD99gGSgxkgFQFateJsWvnet3gg+Db7054/Mj2TAVwvWbE6HE6JbRCHao0BevdpeYVq+6RC6M4oBaIKJZ1QwwBpahp7CRsS4X6NhaGUfhzXKxPp0h9I7uX0yniTz880w/Uy9Bq6YK4PUDquzdBOfuR8BFcTjPOl2m0aYzqZCuIE3BBgDhFqWTM1VogLlHEVK0ylYK5DQZ8+3TCh8sj1rKZXhMZSPfbhuttw3IlC24fW4KcGx4fKDI5zQFwDiU3rLcMrfuiESb2zrdKxtblcYY2xZoz4iQomnF+CHCLQCVgWTKcXwAlfDufZLTnkh1dUKoxUbRZG4AC3qP5aKTHTt23Fis1lN4d5gTA6rWjILtzMNc6vn/xQGkFXgJaJXvp+nIHBHSXsuDBB4+SC7a84XSaENOuL0UAxUGV7oh1bQjNQFLPtrla6SQF5YZRqmLdgC0327w5FHLZA1dRIYjWGratIKVIR0TnTQcu2N8biOg6qGib2L4aoCmdsCBWaZZj4MB5GAOQIpCNng6rNPV30AzcIHNqp0t3p58QyQztATFtpmFMUIqu314X+BAhjmtABxJFCChLU7w8b7BiEEojg6G0jNutwAvB6BSjsa8ipnlCmqhdVEqBD56ssENrp4MFsZEJQkwUodYR7HGtmU8R92VBXQtOU4JzwPW2YlszfJQ3QvCKniDtSYkTQS1sHSaQnOFVcb8uePzmBIDtr2EKBM+qIri+3gOtCtqS4ULEx4+PuC1s3QsxjypriHze61JwOkekZNpb6PmfYkoe9xuNT+Y54uVl5TgNFH2fJmocoJlltBJ46S3rtTa0LDhNJ+RcBosieBj4sLMFaiOz0ZvWIkDx/c+/3m2d7QBzgDrBfIp4faFjb4w7CDbYT9FB5ES9s+EW2Yzl5yFuxcvLgtOJTNdSyK4pmY4+MZChdp4cnk5PkCpYyoYaMqQCrvJJNiEI7hx1nrIZNQRhG0XeKkLE0DnqifH1dcPDnKBKoAnmMOwLoMvbZEtUjFSdIQgjaBIRnFJCkIZcYMxsGXHiMAc5HN6cwwbbq71lg/UEcQBA9j3FWiBGIqvcY3uSctTdeX8ctcKOR281+Frc2lpD3nZAkILknGQiGEDXaFc6aJJ0I5oBsrc9yelHT273NlY19qb9ecxLRS6KGALdrZdtJGT9CIfn1YthEIwk+3iUWhCcMcYs/kjJm64d2zoHmHLQzGLMEfaWdLu+kgtKJhDWRbAJ7nBfXdeM19qw/Uf/S3zwG/7z5xP+9nFF8A5znFDbjZpbIcLHwPb1SBOKyxzQJKDBIViRoY+RHjN2vEmli+sbayNXOmqvK0rOqDWjlgLnYKYcgu+/ZTfDfPoVf/gd2AIIfk81MHQrFQ/A7kL4G0fXwjy6z/ZnxNa6Pk72hKy3p7w5DzqgARbJtCKlmfvYNOE0T3j5/Bnbtu37vz2Insj3JH20xiqYiRg4XUvBZshGn4fVgNW9KLSf13uyPEspQzfy7TjmhY+2266ONrBCGZcBaTifzwQ0tLcVvr3uI4gN7O3Q4wnJ4eTmVn/McwUd4OsAwteNCoC9rZEanWJaWTbPrVqg767nzfuytXA43WuF9PklakDpl2sPAZf+3iiC3XVbWQxhK+bbe/4SCDsev8kGs3N4AZo7AD4H0LJreCo6CBYRbT8L4lCdR34DQpksCbpw+g4A9KKil94iuifbb5+jWOFgj3WZHxFIn0/JWEb8TDDW9Z5v+Lfzx/khycMWfeaoPZKsDci9eAASYbqWVQdpgrGvijnz4fCsnAhyecv+nKcZKSXEuIN0jBc7iAm2sequk4bWAO+sdY8tuilF5Mzv5f5CoM+5YvkWOzNaa4OB1Q8+l86cJ0mkqrUD27ycYkQtDY8fnmye3bGuGTEFc54kKNL1X71z8BBM0WMO9k6/ohccY8TZgLWaAjRFLOuCbGDheDVCl0LXQE274BFcwz/+9CvO5xkX6ZISDX/9/Qf8+ONnfPp8RS4FtTa83hbc7yu8KP72r74fI15A5tSHywl5zezc6eOQURfnpOX4QDr8HcZ/Dxafqq0/h1E6RN/GgmbJr2kxoo3fd11DdpxgH29485N/6uC4Pc0TTs7jdl/x8emEf5gcbusNXmhepeKQe7ClCh8DWvVotSDLRs3F4ND02M5rTqO2PqqyiO28g6smJ6MNrrpRbGQu//6q+7z888Cwv2gg7B//9ILcBJvN3eM44KK7IMiKvsgUC047wML9qJJ66CnIroeB0R+t6t6jPxZT+7vxucN7UBAwc8JJX0z4L3dHqU3Mca4BCzeoh4ez9WRTy8aHAIWjcLIItvsd9zvP74PHh6cLHj5MSCmhVsWvr6x8Ou9wirGPPZRScb1aRdxAJYGgOgODGrBu+U0VYp4jgrXlBM9WnaqK+73gd38d2AdfbPFPHiEqLpeZOlKF99gFil9fFsjrQtbKxAF/v62IgeguAyUGrA0VEmzqNmctasBpjtTzqGyJW9cCiMP1dcH5EilcWHbw0pnWGGDiiI0aX2q6VtmCm6QNITnMp4kaGVVRQUvwUshUOF1meDdhu7/idlvhaoX4DTEt1s6EwXoouaB4WimHBuRSUDbaxD5/uuH18536UGF3+wrBG3W7IU4JIfHv0hzx+EGQTxXbUg0sFcxzJFjiBXmtmM5skayqQ1PociF1+Xzy2B5ma4vLuH7KiIGuWq1SuHVbM6Y4DUS9VnO5yRvEXL64wXXKvoxxf1xivPdIp4DT04RmjqgMhAXiLRBr1ItolY6E4gQl7xuS8x41FyZO6As2v6g2RbDZKabxti4NELX3zb8jiBTsPpyBmA1btvGxx5GjXdSZYKgIRX2Dd4ingHSKQ+S/VUXNDaWw1S87Bg3HdcI5tljDmCzOAuCh09fodhRE4F2zuZYMGN2r471/vj/ksZiPBJ9/bI0OkNPJY61sD5wmtrKp6fSESAoyhekFDhT5r7YehOSx3audD/AuQkwnipp6bIXqSQs118gWOT+c0RrH97YWrEvB5ULDgR5IM4gjs0+8IJeC/InA+nk+oW4VS1nx+dMV3jE5boVWyn1dZU69gwi1KoJXrHcKYFOMs+B8PkHFXH4MPM1bxbZSHJVMQIE4YyTkgpzJFH58vJizXEEztrCzytW2lVEN3+4F28rq7eYKponj9OefF0uYjaUZCKQ2VdPXE2jzWFeiqT2Qdo5af8tiTIym+ObbM2n7rewtfNa26p2j66aJz5YVyEvB4zcJ0xzhvOC+3U37jiAU9fkO1UFrL4jJD/25WowZVBxq9UjhA54+CICKdSHgWErDslIDcVkyCyCNmyqFaguZbc6hWKu5V0CajPG6bfx9aCST2pjL/HyEC7zWVhUOHqUItrXB+4qYKBzMPbkj2TZnzPa9toJ12xDnXe8qRrYf93Hfwa8xrw6beU80+tHZYBhT0AT13ZfJ2jss6c0hkGGq8/7oWlb9FKtpj4nndzk0kyX6EsRopvelakYSloQPZoLuoFUz5yaFQ4MBsUcGzXim/HdtjSxRyyrd2FMtsO76ZkLArdbCgp+xYskA7KypXowzjRB7Jh2cEAuYBYx/XAwQ75EmMkOckszv4OBjhHMBW85YtoXPUHZdxiNo+XA5IYYLtDWs62pJldpa3/DL5yvcqtimb/C/+hcLRNbxTmKMmFMCZGcyBnNBvlxm/O7hA273lVoxtwVSvbVzW4FGuP8Fz/XzfmtY1pVzxgAGylg4A2fZjvz4eMK6bfj7f/gBPp7wy8u/w/cfP0Gcw+U0IQaPT88rGhR/9d0j7mvGw+OX4+o4Tpg8OQjqm1gPwMGRr79/S7S+AsyIFXmqFXmcc0gxMeGbWVDcTDvw8hAPBWR7L7bGDXaImGuwAtlzPa85v2EyAEBb37YH9b+PPu6sLGCAvR0A6+3G3tm7Cw50gzdQR/24RtalyK4NYcZy30Ycbd9sIDiMFahvrqnfJ3D0GIXlGQZojGRhX1Q6w/NrORu17bru4c5QIkbl4A4aVO91xPrBToXuVilDe2u0X+lbpkm/n14Q4GeOdzQ4QO++6agN9Pborbf9O7/8ewMjQDZOZ4DpEOBn7BRjwJQmOG97awPUWLnjKqwQ7kXg3V5UE+li6Qonis0YN1U7W0pQ3oGCsXMp7P9Z4A94OCdcJo+AjLq+YlvvyHmD1gxpBUEaYiSLqJruXr+GXkDogNn+VPd8UgEUAIGDEgDGOjJAMPs8dZWor9YBYaCvLxXLsrx92Go62vZcSu3x374feOdwmiKyaZXy2vt+h8OcYfdRNGfsEWcfjilSv7MDrs2KELBiaUqR7XHzbLmz4OHhRHJEWZFCNHIHc2h/iAEEQEoBU0qMybYNy31h6+r5jHk+mXtpHPIitQhq2fWvxe63my7xZ5RI+Zd/+9F+ku3emdfMc8TlzJxXvGBZNzy/XIGDZi2PBpQNThTfPE14fb1BTFrgLWys7wB0fAEadwDMvX/A/ZNt/7xlQwA4DjoYNiQHDjHLe2bqbx1vr4a6X94HPDyc8P13H/DxTw94uV5hvgQk04BqVNrIXE3nBzLLXDBXZsaEv35+gQ+Cbz58wGCwQiCN49IFdtipKAvwUuFhRV3vUOuX68oR/P7njr9oIOzz8w3iE+D2/uNx9CpP4wPtgnIqipoLJDii7YE0/FYB5J2RQdMQDrBtK8MWfdQ0rMwwNlxb16pSYDlYwNsMUa+lQZqxW0LA9bYhBsGUHEKcCICVyoDTO8Da8FTfvWDl59Y1w10ZSJatIQRgWawSGwMuZ7qY3e8btrxhW9E1Ptk+AQPKBGNBDMFjmliheHya4L3g8y83tNrw8GHGPAX8+MMVPgY8fYgdc8X5kpBjhYPD519vI6GvtrD6KIiTQFvBlBweHh7w+rLivhR4pQaPCKBZsazraFmZ50j3I9vAVaincb+uKI3P/77koYnG99W1XXrVUdjSB4V60zewzSg3hQsU+/dRIL7Cw+HleYP3DtM8I8UTkgdenjfc7htKabjfVqtWsy1nmugiWWpFLtQ4qqXhdl9xvS643++4Xe9IMVFk2A6yFAXTOeB8nnB5nJksrhnQhtNDwlMK2LaK5Zr3REY5vltVTHNCzhXPvy7wwWG5Z9PPYsumOEUIinxjkp63it7eC7BmsJrOkygrTk0VtYNgY720OQSbSu+mWwge6RQxnRLBvUxQ1AfBNHmU4rDeC9ZlA1Tw+rLges0jAHPeoZWCaYrwYTZ3Ka6oBJiA5ZbhvJgOj5ptrrnLKEGqx4cJgGI+T/DOYb0VBLMldmAlvarifsum6WUMu9CTWwt2UjAmi7P2LUASXUdLFuRt5TPoe5IA4j2kWVBn7XkhOmtz5phwDkAyUwsRrDljy3lUbocLiqpZuru9Yms/L7mi6yutS0aaEwDB6+2KIKSNl8zEprVq+oh7m3QrdYjIshVWME+CUhk4MgjgwqCVlaTaKlrer6MH99S+YgV/OkekM6nfIQZrrd3HiHR2X+QzmqaEWhp+/pRxva0IfsL9lg2kPLTv9LGmHcwDltuCrWyYzzN88EhzQpwiSaetAbVhmgL1JCQjrxW5KAQ0wej30VqDDwEIAefzGYoFn3/dsK3ZghUmCSF5i2no2tn14375+YpSaBqiak6R6sxFikHmthZsKzUiJDhMU8A8E6Dq77IbrnSBfZWGx4cJt+vddFOAOQWk4LGsGXnrldje3kc73OYAOIfXlyuquZcGT8clB7bxr7ZmTnMcVX9twHLdICCDp1ueh8B7i5PC3xkId9OKlBK6q1Xuovlxf7hN1UTVCSSXTEYY9bgqXHQWuFcaGsS9fSlOBFGWewOEAr2tKYI4hJPD/ZU6KE6pfUH3NwdRh1YLXrcFp5hGAgLh3FUbh2hdx0L6YDZheAZPQ5dDjfHRQWnsIrY9qWttD/6FkeoAsHcQm/qg/qCn0j9Pw4g4AH+t1OUJluQTGa5fABOqShFZE3txzrwqKxOlnPOu9WiMAQXnR6nvGEDa9vXd/mmtIjqPkAJa87t4fWujLQsA4B1u1grHHMUNfa9SC7JWtA10rbPrHiyV/gysDd0L4IIA5si4Lthb0C0B01JQZGfQ0DHySyAoOMA7JtDqyGrozr2lUsNGAUzR4T9yP0DLDITpTfC8G/Ds2bRqw/3lE/JyxfnxI26l4PtvTgTKCyUX6nqDdw4lZ0zTBAGwGlDX2T+9zRImyvy1w7mIpoJ/+PEZ53nCfd2T6qaK//rf/ACo4u/+gzv+k3/5t3h6vHBkCmPDOth+xmJujgXfnoyDSUprdEHv93kEmt8c0kEXshjmGE2rB5jmmSxkS8R9oJOtM/A4hgAPPr9WqB8kXQDSxkGrBQIdbS/9vXf23/F9jAKa28HU4AKqq8MZFOC8TvMZyTVseUOWCjUmlXZbuD7ExmumC/fra4EI2byq7BiZYu8uMXBJKLy9t1gLqrsA+YqOpKlascs+sT/nAzByeNjHmL/mTMd6vI27dsfVDoK9ZeLw3htUzUDC+yGA3tvq3h/ijA1rSXkpGV0egwBIdzDUd0ZaPbN3APpn+XPvOzPQ5nx92956OIMVGvpr78Lr46mh1IqyrKjKGFcHOHnQqXr3/PbnJiharTOmoIvH7wdjw+MRaK04/uyd4DxHPFwiTpMgYkNZFiy3O9b1jpwXtLIigoV0Z23A1JzkXGReEvpXDjRERDC5gGUIrHOe5UZt5KYN0roD6z5Pe7swjePacCD+2htWWFfHu/usgxm8f1JVEZyg1oJc966G/btNeN6zY8QJiRO5YKzr3jEX5p5zfNOWfzYDTIK1wwnjqpQi5Th8xNPjhKfLGdEHcB3bWfFOPM6nE+aZZlvzaQYUuN/uuDw8Yj6d4UMYa0atilNKcAqsOSO3ZqBf+mJ/FdTR4t+1ngG+i2+eHvDh4RXrlrGVivuacTfH9ft9xemUOJ5axvV+x21ZIE4wJW/rLPMpNUDSOViT6dff2/vj/biVd6Aq8JYl9R4MG+zl98W1f/abxwkBCPcBrXg4BfzVd0+43e64LxteXDGpFWtnRkQ2FiTByA1VBUHiuJ++h3cH397B1pnrzgonuWQ0bQgxsPXXeThXv2AvAyxG/TnHXzQQxoWsQEt+9/MG0jIaQdJDO2Ot1QJVhQts4wFgznWwSj61WCCgVX1v2xgrln2Rdh0iI5vYX6fo8fBACn0tiut1Q7YWwPM5YZ4CvBecTwnLfUGzdsyHpwnBO7y8UFhdQYBAwb2gmsC7s2vxXkbSWGrBfIoouVGgPDaIL4iT4nSOtgg0tMq4ug+PCADB4fww7Y5WfU9TYL4kqDasa0bJlS6AU8R330V4oeCf9x7+4QQnTOyur3esC5lsp1PEw9NMHZdSEYO31kMCEKdLwDQFlOzZbigEHmslMyY9BDxcCMqV2vDysmIrtrCWcrDThSUDYq2tAgwqfN/cFdthsnCPrVjXDefEd1xqwekykQ4embRrc5hPCd/IA5b7hm3ZcHu+A6Z9pdqrMh7rWqwyTTH4ZRWU3CgmC4FPfoxFteTldI64PCRsK91utlyo7yVkaIko3ESNtClF7DoBwKefXnG7b7hfM8SxXfjhAzUqUvJIzuP2wgS3gdV453voxyS/lkxxU7Ayoq1BmwAjCLBF0+3aYG/yDsPI2Koz0/3FAh/ngTQ5TBP139Z1xbJkXF83bKsxH5xgOs84nWZMKQKtUby8lRGwcW71NmYYu6+Nn5XMStiUPM6XGZfLhLwW3HJDNVAoTAGnOeHlSjFc7/uGTKHo82kGhCyc+21DTBEpyg7WOdIol9sGiKD03NTu35uOEyeZoG6KslH7p2tpVAqWjSpYd8NTtbZOUFOBOjtlT7qFz33byOqDkkVZS+VG7xzCNGG7roAFE2TgFLS6mVgzr6EUAuwUbHeWOAOni8P9uiA4QasVRRVJqJdErR5L/CvbsvomtW0ZFQ3n04TzY0AI0+Gd9dKhJbFQQLleBR8JuhaCI6VuqNlYSs2NoPhYKFMbx847RJ8QEluKg1l3q1IsNW8VaWLLDtuMV2x3ajEm0ysAQBctEZStYpMMkYBtqbjfNqsgU6Q4xTBAdnHAbc3wHnh9teDNmHpq+4k2YM2VwP2dwBNNNmSMO7owAQ8fTmhVcX2+4XbdyI6tFZ+XKx4eT5hSGJp7pVbMU8Dryx0Qh2kmAxACFK2AFWxyZtthZ3ak6BFSRHQeW2vQAoTGVuyQHCukVSGBiYdqxXSegbbC+cJARSkoXwp1HWspuN4XmzcCCYJWdlFn70x8u2XU3JA30w4JbG9IkbqKvutXHFjd0xxQcwOyQm+9FVnQvGKtGXAK3+KQMWBiVqhT1QqkbFAwgJWxhnl0oUOnFa51NpWgi7yXdy5PnQnZdTo4BHS4H3a9CiYNATFEBpyHkFLAxPEtPWbfsyC9qOIBcTi5AIjDfbkziRK2l78P1PvRtBmjrwAbTPtyr5rTtXlfsGkqZG1eMaGW/EVlwznBHJn0QgmeKfaWy68d0b6zoa+pdOKkdtlv/prdQ2WG5mXEW7VVJqb2zmrb9XM6iNeaormGeZ7fnM87IIX9PP1ZO/Fk4UJQ6me09orLLHDtBWVZEOZvgDD95nUyEZ5xPtFxMm9XhAr8N//1v4WKw4enB9TRogWklOBQzayCCV8IFaV6+NAwzxNbuiyeqZVyCiKCNJ3hwjRAy1Ir8vIzYnBw8VvUUrHljNM0Yd0KXu8ZS7mj1YxlWbB1rdzKuXY+Tfj2mydczmmw4+EBJwFaGvLGVvc37ZNfJFcmmq0bztFBzmdjeCjODxdc76bFZhtA19nk41e63qmgFraCam0IcWLBZttQCx08ncQBujHmdSx8vRkzbLd2cIMR2q8x+IB1XQeg1uej6i7qDqgBRbtgtgB0tgYT+fPFY1uBZfFwwqT1FD2S97gtGbkSGEuBRk89Wfao2IylA+yOoSwkNHQDrfGYZden6ufoovkszrc3guPvj14Uec8KU1WT8dCxT/SfH7XNOoN7B2SZxOPQftwHhDP3Qmj9AjjCABeZG3X2WTNtyZ3J9GWTpDiBM4di0Y4RvQNsWkVpDaUJmvIcQbk/Qw1cKfxM7yhwHWgXWHL9m4/xcBdfBwXIqOuyH73NXlFrxrauyOuKWrbBXP5CC/GfO4TraC6lw0X8sb0Xzs+3jCCSDuq4pxACukPj144jG+zNDb87J0NufletFdu2WRxqc8rGBs2KKHUw9hUA0zAV64xdakKpCLbmUFrXzOa+eruRVT+fZ6QpIDiPKQVcThOezjMqKOkiwkJ1DIz1Hx4f2K5ugPjtekOaJngfENM05nsHnUUEKZGtGkrBNM94enpC3rbBGvYCnFPAr5vix0+/4nI64TTNCD6hKk0CphgwB49WK5Zlxev1jl+eX/D5dsOn6ysglNj5fL3iw+WM4PwAQzk/WsfJ0Xodqq95v7HX/zkHz/5PD/B9Xr39ZC866f7BcRxDBO4rC6Jn8fzxHPHdhxmfPp/YxYa9oCbew4cZqXFvWKGAUP5Jm8BJwLJm/PjTr3AOeHh4RIzBDL++lJWIIZqMDMdfl345AmHe2r//3Nn3Fw6EWSm79QdPSnITc1UQUmAZeDZLzvjwkg9I0VsSRIcz74H5LNY2kuCcx7Jk5NQDit2RAwDQuKiIA457dLVAcwq0gm+IcF5RM11DfHB4eoi4LQvu9YZSK85uxlQ9GJkAMG0xFWpf1VoMqLKWKxB4YOuLR0oTcs54fEpIc8Q8B5xmVkC//faMz88Lfv35hufPKzJIuzWZagbGueCb785Y10oG0p0aV1t+K8jrnOAxANAV4fSAnCvO84TzZcIvP7zYRlCwLhlxCjhdLjg/pJEIw+x3vXcIkYHS6eTweVU48TjNJ2xCIKwWc1ZyHiF5tExWTWtKvRpDmDugBGDojxDrtB7iwwJIVt8e9NzvFR8+WuuWMNkrrUKd9SU7QFGRksc0X/DwOOP2uuL2cqOjpwX8PjicZscqucIC2oK6sa1FvGCaIiar7NzuG6ZTxLpmrCsdMGOkO9s8hVHxgBoTYs3ImQtns02qlkYXrVvBfKb+1nwiG6iUivstM1ko1BJRKKaTN20cJgTLbUXwASVXbGu2FqdKsKQdqqVWUXOByXNvcSymU1Nawd/93V9j2zJQaRNMtqSDiMflPOH5c8V63/D6esd6r3SSs5OfzjM+PJ5RMqsr67KydVd7ZbcHVLZpgP+ezw5aG+YUES8TUvBopeH2QrCqV69DdJiiw3xO2LQh52YmC5yP3psWTaNjnjgyuZDEdMIwXBB9CmjXjBGPWNTUg5UQvLl1FUAU4hnkUb/RXF0R0VpDbY0tYW5njxRjyTRjAnVHwVKo0TRPga0UYFsoYMmMjfdp4vuptWK9K5Z7pjmFc4gpomvUEdgUzJcTz58bTvOM2/XVQH61tj1hZRiACIGwbWXQcH44Y1tXa6k0wFSarS6HndMCUkDgQ4KXCcAGdga5IbB/yytydgCYOCJ4E6o37b61wpWuC8cN2VQz0NX5pRaykzx1FztQVraKslVUXxACA6GuQ6TakM1pU8QYwmhY7nTtLEkhCFZp7e2lNGmZUhymEBBqORZreeqIca2NWhlireaFCacPHqmyBS2YWcbry31PmGq3lQaqEoCaElslxVGbygePpSxwKoNligasC4GaGh3Cg0OYyXrsIvy10vVInCDMLJCUXFFTQbDvFm10fKVK8dgD0NhqVQoNQHw0sdtySJwEZnQgyMpdJ3iux7U2lK3i8eMZ4gTbnS5RJRtXVQX35zt8EBYwtoDtnnCaAx7OE07TjGXlfgo5BHbaBlMhlBXN0079vT4X52MP1b4eNpKBUMg266D5QXS461gJTKS9rwHKWOSYdCrA9bKS5ZASNW5q6260vUKLN1WGfr7x38frU7KPcsnvvsuEkuPb8E6MEeaChwMLHjlv8IdW/eNRm+KWi0kUfEXg/v25VQcYBnCfyqUyGerxPw5JeL+P1ozVbQYUVgmutaFphXP1i3tHf1rvEntvBi/OmD799/paKz4inB4I6t1uEGkIDrjEG1Bn6PITJMzAw+9Ry0YAQfq7EXTtw9N5GhpAy5LxH/wHf824TxvkPKOWgrxlNK344U8/Y5qSiUAXtG1BgOLp4wO2TCHn++2G777/iPvtFTEG5FyxZmDNOoxxVAEJH+DMobWPnRBYDHA+wPsEQUEuG0KcsCxXathsd7y8XvF6veGbDw94ejjhNHcXM0XtRaf3Cdhv5FMxJTz84Q8AgJ9/+CPurzecLhes64rr9YWsqdEa3/coD+cDdEgBNLuHilrKYB1BucYOzqZ0kfB9j6Swd0PVimDulw4OKkq5kFbhFmdsWXMkrhWl5gOjhYynUgjwhkB9miDs2gAYQ0Zp+HjiuFzK7ijbZ21vy2Wi33+uCN5jy5lO4jCfLhzEnXUHObrkAZmSOwA25lKzfMZ9uQ7s+mVkY735OyeIPjJZNF3HWt8y5tjyazGONnSzjK9DQcq9wIS5Wy1v8XmxPMzcEY+g37hfm0cdGBzv2HqqVLkmjLjq3Th00CHRruA6xSdu66zqAI+9taP3se1EvqIn9PZZigApBKxb/toHECJzha5XtxcHN6zrYk8JBIKtpfxLtspvfD8EQT0yCrt25DDedNfWa9K+cFPt+05f/30ks8YeCoC37uf98I7MTlXF9W46Yrq30gOw+CxaW2bd56R9INdqFI3e6XIE7yxeMo3DqpRloT52hqmlYdUMJwGtbJCWMMWAy3nCeU5QA8EAsunm+YzHpwc8PJwxT7E/cWhTfPjmGwgCLo8fQDfMipwzJS+wzzeysMX0JwumacI0TXh9fYWrKwSKKUakGHG93/H8esOUJjxdHilDcpoQpwQxdvzn1xv+7T/8Cd98eEQKAQ8PLPTO0wlVYUxqjDGt+0ixvK5Z0beP5H8Grf3venwx7N/+oL/r8c1fuYT+mcsU0E1iJCV883jB7eMDfvzpGf8u/0r5mNJzDABga2RnCDKXtdxZuDaKKNZ1xcPDI+OanL9kNgpGayfZiGq6uZQM6lhF1yVtX40bvjz+ooGwUtc3lPKMvVPJjOL3jdU0hHxgEOpEcDoHrPdCuv8heDxdTvDem/U2N9YQFSptuBb44LHd2V7VGVo9OW9d1NTa56YpcGFPwVp/FFstWO4NLTuIbyZsb33qpQ1dHG2NYsa1awxQR2xbM7xXq6pVeK84nWdcLolUVdAKWk3Ucp4DLpeE+62afgzBMABwTRFN5yolb85PZKME71C0g01MyuezYMseZy9wIaI5xbplnC4M9twquDzMmE4RIdkG7wXiAsq24X4na+Gbb8+AFnz6tKFs1IpoCtPTydQAKgUqgukch7bEPAdWKNZ9o/LRs7WodQafCebXtxWV5Kl/5pPHPHs8PCZcHiLSFABQhC9aYBmMeVPbitY2xHiCSMByf7akQLFct70tSATrQsH19U69tvkcUdvE95U8/BRQ1wwfHW63BSEGXB7PbF/ShmaMvBipB9SaYlkKalak4FGLsg+fOy3y3bQusg6dJgIt1CaqhePaBcE0R5wvJ7Z45YoPjw/47uNHOCe4m9jjsmy4Xe8MTi1RdCZU36M/ahHYam6dqK01/PLHz1Z5FDhRAhgu4vW1YN1s7Jwm3G8rilPUugIOSDHidGJLShe8zZlabQoCGd2pi0ESvzMmh/OJjEXvFOuaoUrtiPMpkAElnLdwBFQo4utwfrBEtFRM5wnTHNFqw/V6R6kbmVfJI81xF+ytBBevL5s5Tu6HiBDoHnwQMkB7q0F3MSSMTceaba2Q6LH5gofzzBbDlayWEBznpFWtaXphgufBIzozJyiKGBK888iZiRugOF8SW9HWAtcUqBVbMc669pKrMkEz9pjWhgImriF111LFumzIjusoW9S4yl4eLuZkyLnZAyBtzZilOxjG1KahqrCF1AmAGZLvvO+NuoPZerUV1brB1GyW+RycwwiYXWBQmqaIaaazozO2rwQTG0d3n+Kc6I6OPjj4IIjJY54iPv+yIgSH63W1hKhhuW+YUgCtrhXRc23KhWyvvFWabygFw1U8vnniOG5W6aQeENejnAnS59xQ6wYfPM4PAbU0+NCQouB6W1GK4jRTaD8XBrxxdqb1BQAztkL21vVWyDZSEhFFC8QF5Eywl8C8Q7V2u+N47UUB5x0BxdTNLqwdYqmIZhIQk8PD4wTvPO7LhvuyIJdsZgkeQQmA9u3YB2dsKYUPEfPFIaWCvFbcb5Utt5UMyaAeAYkA67azd5atAJuitYLl7lFKw1Yilq3gnCrmmJA6yPXuEBE4VcRWoeLoXtT/Dta6bAlkLW24XKHv294NLRIAw6VQjBHwRpfoz6zeEljjZ9+DVNVYejGYZttXhH+/do89CeP8M5t6C+zDYMPxaCYT4b1HSIlGJeUryR46y8CSyYNrddfy6p9pYNwyHb6LoIBDqUyAetBPJni1liGyuqUDWFawrFVAzbk9mQWaARW7uUGzvaCLqHftNieAaAXcl+BeqQ3besd12SAgwzz4CSJ5JKwAsC03PD//a3z7uz/g4/ff42N6gJgOUYwJ0zQTcGs6DCaCp/aghyDZPO2stY8fK0ptuK8r7s/PuN5uEADbug4gNUrDND3iNHmkmKwV0GPJiudXtpv0+Ed11z06zRNBcWFhzHK7rx/KJHRrDc/3FZ9e7wjGonh5eUHeVgTpe5cfWodHcwj8/7j7tyVJsiNJEGQ5N1U1c4+IvAFV6K7pXtqlednX+f+P2CVaoiXaoZ3u7a5CA4nMiHA3M1U9F5kHlnNUPSISQPUbVkGBjHC3i17ORYSFmcWStc54abVCvMfj/ooQIn79+S/Y1gd++fUXPF3/+U0uZdzuUxLN725W9GExeoJ3CWuxuFwOyWEvQDNGbFYMOhgUb5gxZm0SU4QP3BvXbR2yTY5fM/cuDdOyDEbJtu1o24YUE2LwcNY4KDjBU0rcE/cyQL7g3bBCOR+9KcVeKkL3vBog2AkIPgHDnW3zzcenlN1/DYjbH7AQ04sDYixTFvKOuTvkRnYOHh4KA8DabwFg/WiHLyH6S3W8RwQGEnVf5a8/S9HlWce1qD1YtT+jkGCASv83gUdKnukLLW++w8hFdi/JBDvbkfA1354g3pHZlwJtX/ZcvnptCGRni8rozlgrPXhz3g+5uFpH+0Bvz9bBfrQx7n/zEGCZZ+y3FwA0fB8ekjY2nKPUjQ2t1ABEs7KwYk31FTHSqqI3NKI1ylvmTwwez8uEx7YD4LrfZXvn+3Xu7tz3mh7rfLlb6ZirXAOrqTzWbTcAm2bqkG6wz26RDgF73el1PAdcJvo05gYr3s94enrC0/MTlsuCkLj2oRX6UDmH5fIEkYCUOrOX3QurNovRj6LQnqk86YC5gCCoA73Fn5YLtpzxl0+f8HJ74PW+o1TBPCc8Py34+ddP2EvB43PmuP4PP2JbH7h+/wEQN+7zuj0AEcyO9/5bs4JdZk/2I304fFHE+3q4/PXfH9/w9bf+Rnnpt385zon/J+CceL4+4fv3Ge+eP8N7YTd2iy2BHcADcBcyw8W8JX1ACmxERYwAqDUjxUTFSAhUnhiQ7p23go81yjHfafFkHro0GYmDxY7zeP1bxz80EFbrhjgtWAsXl2ZJIJSVYrVVkawgSsUUimlia8/uB1YL2SnOKR53Gih3aZcqkDPNkyUScFmWZOBDQzRfGG8mjGly6GaNqgx4tRX44JC3au1TuYC7IPAaIMbIud87I8HkZ8BIGPqiFKIiN2Dy3BidmceJiHVtZICybeYj1ABFM/No+tOsax3yFYDgYd4L1rsgTgEpeZNdHsFoKc28oRpePq74p3++0n/Hefjo8fLrHYtzyHnHvETEKUCFbJxaK5ynQeA0C5yLg7K/bQ2qpMwWawzA5FHgY0Spil9+vuH6NIEdoxzWbce67fDRoVjiVPJh+K9KAKQDoSOGU/q3XS4T3r2bMC8e0+wQIg1Sq5LG20TNo6qNZGC933D7fIP3EZdLxL5mys5KA1bFq1uBZh0ys46Oe71iKwLq2OVgi3WTyn3dUNuETilGT9AMAFm3AjZzaQaWHpItbm4FeWeHOybZJhnsVSRH74wUAvI9A07w4f079DbmrXUQiRUsLqwmv+SMMhNRYz8WwFuXp75Y1qp4+Xg3eSBZNiEK5kXNPB1kkOSKvBeI0t9MBUhTJJvxacG27vQrsznUvbBEYMbDgAaBSEP0inkiEFMzn0X3Oai18l45RZwFzjcUzXAI1vVrAlRNWseNZJoT1m03+rVVzwqpoiUX3G877i8bwfPT/LEtHyXv5mXHe7O3asBVN5zmfOyMDwVQdspWaqvsXLntDJQnGgj389BG8Lgng2pVUM9SCivbuYOg9AGDKtlMtb8WiFGMScg209E87qCC7D2C82jzPIxXWys0QfcMfrqn1TRPmJcZ4jzyVhBTGIERc6SG4b8iDACbNut8puPZtnYkdewoiKOCKYKw0JdFC8yQlTJtcYBUmk077+E7kBGU0l8Dc7rfzHKZjCVVBnOt1UMmEZPH6+c7tLJwkIKHv9C8tVXKa0U557Y9Y10LcqmYEv0xVBgM7hZotaqIyaOUIyEan2Pjc1kS5smzgYZnwJOLwot15vRMNzoRxzuHKRHo9V7w6XWz52iAodCHaVuLSR1hyYZHrZScJ/N44ZpZTYIulCJErjuvnx+YFodWKsQA1zTTkzDvQChiXTS9Bc2wvdT2Lu/oKxb9IDc579EK16qym8dfa4gpoKIYuGLJ4BMrwMUAqqoZW8koaNhzwpwC3JPH07zgdVvx/eWdzcOjSt3ZWgrQGn4EmMpkVBXOEbzxwaOad8yWC5IkJBfeBJhNGyW5zRIQPRKEXoH/ew5VgmqP1TrlnpK0cwK879tfSYj1jQdYCPTKaHCwPtMmSXFvQl81QwQFC2gQYFouqDl/ExBzUDOLVmirNLH23ooSQEgGtO7b6PIXg0ewZ+GcIDhn3iDGPJEwnlGrBMW0NZaF9fCeqrW9uf7aGqQe3UBbZVGy+32t24bLMiM4NqDovlTj2TWgVHarHk1OVOF9YNGmgz0+QqB4/eUT3n/fTMpMINsZwNe9TxrU1hAuIk76CCZ4f4i/yKTIJmOU5yuZEKWg5TtjVQB73eCcWvfuDOeZzF3nC6bpCWdIqbWGbfPIuSKmw8D9q2dobBQfHNI0Y5pp/r/nAiiBQMYSzWLSGT9/+nmAi2MAKQYjqzcDEAGCVgQpCJ7PdVtXxmYhGavgSNydYxWr5Grd1njvcl3HvSKOa2jK6fm/mV9qzJ/GuIC2A2SHdRlsKw0ppRHjbOvKwpqSmdalXa0polPMM+Ov5AW5VNytm6cTpYm268GQANbtzjuFd4p+uvULpo2IYE4TnpZKoMnWHQLYXz2qN8z3bx39evX0GQTACAxTKcBzI1gpI/fpgTCZNYevIHOR+ncAYOfzqNalmgOj+wyJHAD53/wo7XFAH2f6RlWjOH2G1dOGr5HYj7xAhcB/3V7GewXAZE1gBDr8IAn6uMHu/RK96VyxCrGmKQXeTQS+jCRxWSYs80LJszigUZmzrQ+qYWohcSJEJJuX8IFFh0bLHnaidOcvtjnVm+H0zrrRamgsyvSx3dnxzbyR3Uk9IqYEyCUjuKM44QwIS9EZqcEYpoAVMWA5L+XGrVU4rWN/6UWX/rycHIURN55nZ3F+vac1pYRy3SgnVgApzezC62gV1FRRVipqKCMnMCkuYEksQDy/e8aHDx+obMCJLeQiRAI7l/vZ8o0OxnHvFifmK2yeWabcqo3KpymSORlThAtX1LJBa8HTsqA0wboDn14+4/V+w3fvvsP79894/viCX19uuD12PB4rfv34gj//5SN+/7vvxzjPG0Gy75dnrOU+ilyCzqH7Yt0YcwDjdX/tIMzxds3wloc0K2YreuuaL7/lf/7on8BiQMDz5Yrfff8e//k//hP+n//v/wMkmj8MZHendzFWnGey9bYNuFyireUNL6+f8Pz0HiHEYcFyBmV9cGjViCO1AYFyySq0x/mfkZX+QwNhEGAreWxqQANEQaBc0c3MO7Pih58uSNHh3/7tFQBQihoTqC8uwPrIkLUYY8B0pmYMRwPYiugjRIEtFJSdhuTLwhbf3FhM/2uVjV457JTabc300AI9yFrlxvSAVZlGIAAwHOUC6IIlh16hWuBdwufPNxqup4Rlidg3MhXyTn1/N/7vhZuayWCD0NjfW/BWcoV7SpiXiG09KKRNu6SKyeI0OUyTh5OG9XPGsjhoKXg3Aa+fHlDNTEBLQROFIiBNHlEcJApa84hphriMj7/e8emlYN8r5jlhN18xeplxo1arKj1eNzgv5g3GilQPpHpraDkFybxgGdVEVUAMPFjmgOs14t0Hb8CbMRlO5nyAM0mWBftweNzv8IFdHLeNSS1wdByh/41HTAEhEmgtG7uUpWlBmmig+FpvA2hwxnQqtY4qRTMWSM4Vt9uOde1ySwIpfROr1i0z5zoqjQBQlclBp8tHx4pgr3iL88i5DE+ynItVkcyo3wCWDlj0/45q2wlYhMVYDTquwVnJo+wVm2SEmGlGb52DQojYazeIJ7jsvMO6brzunaAO8wtB53f25yTO4XqZ4Fy1wBaAdwZ0iyWXnENpCpjnMFq5Nzh6S9ichBhoEcOQR9DEnL9vNh4KHfnhg2C+BOwbQaTO/Np2A8HMswg237QxoOsA4b7nI4kW+mPlXOBlRjVzTu8dfaIM/OpgZa0N66MhrNm6bTFA2dcVUMqbaymouWIzCvy+ZbasBqzC76yaWhlseIfnywxxgs8vK8pejOUj9DSAABIsIGM78RC9GcjT165Ugmxw3eDeAjsBAYYus7CKfc7saNiBWjYJCNBSKDGrVs2NHmiCkCgx16bDE1DVFOSOY0obOymKACH1ZI0SzWkmUzXvFY9bhnNkZ/Wur3ln4Cc45BnLZYY3ebrIMc6nyaOhYNsUMdAnLrcGH1ikEADXS8KeK7Y1Q9CMCQPrvsnvYxFXLXkWvL7sgFbEINDChCjEOJ4/DWX9qMTOc8TLWiC+m0Q7TIHV7/tjQ6lM/r2X4ftYWkPbGiSQeVPMkyLObG5xfZqRc8Vjq3j9vGOZFT6S1SrOYV8rvFM43302AkolmByD7zGOMRGcFU4seVEguADvK5pSsi0qqFkhvvvj8XyGf5Ht0TDGhRN2pnrkjPLxM4oWxOkAYL90nenSK+c9vAu2lmdoo0l6aUB00QDmYIwbfyRyp+TLOQcVEMitFVGAYJ3oIKfkHZTXDwDN9i+FItdinUUdmmaU4uFTGJ5YHSAF6Bk1bsg3jr5PiZNhFs9ulkezgm7UPBg4p5BalcVD7+kng1LwZUDug4frSbd5lfmYDlZSq2jOQVuF2vtrbWjOW+5qe4FdSpf1nP/OKvyRkXKs1689bNBl8mQS9S6l2b5XAIgWoAXAUbJYSjn2PFsvCOod4qgQHFKc6VXnIxAS1vVOX62UaN4PWlQMCZx4AmHnfF9Aw2KI3dto+6Da93gsU4JeZkRHNtjj8WAH7JoB5yBSCdKYdHmKHmkKSM7GfKX3lapifWyYHDBNisukuMwBThoIK5shequ0+YgeCrI0nRVOVNsYDV225sQjV0qdnRh4byyKKU2ohamnN0avAKjOQcMV4f0F/+W/f8TtdcVegWl+4j0Vzt0YPIIl42JAsipjBi2HV6hXYzSepLLfPkzhISYF+2ruH4b7+04pugyAgz5SjMEaPBput8+AAtfLBc4Jovco1jGPSXUHeTD2b6fd+6oSQO2gPwQiEYyjGtLOtad3sOw5xRG7Hiy5v3WoMQXVzqXZn7cJrgMN7hucHszVAdyrgt22TfJMxPKvfOch1GKM2gsLx37Pz++5j+Iw1//2dQ1MEX87JT/vB2LzME2R3deF3sK31/38jjdKITn/t6/HtsD0+QBY6tjaYKMwYT+YosF7TGlCjBHe9gk2LtuwrtY1UnXkLEeRQ2wcHd/bf8MclZ6OXfLVdjOfdX7sU74eQCW9BC2+78Ufd3q2ClRUJJfGPWvaoLU32uigAgGTFDhHSzmagtAypz/jRruPATAcMuUOijl77pZ28f7gAEabgU3Z/KH5KNqxb0Xgaa745fVXPM8ToucciTFguT5huVwwzzMulwuenp5QW8XWO873MSbWQKFW84ji2XYA0YeAmNTyOYE0spnUPHlzStaZWwHHRm2t7JjgcK0J76+Kdd2QS9/HPZZlwvt3V8TAnva1FNzuD0rjt4ZPHz9DBPjxd98xnj4P9m8ANl/g/1+N4d86Rtxti5Cz3KQZGWWsM1/OOPl7Pv1vH4wHE949PyFGelk/9g0hOah0/76MVhPBXuewb7ulaUZKMsxDG1BKJpvT4rIDBGfhkphK/WoNHfv931mY7Mc/NBDWoKTBc0sGRhWBgb/zwLxELJdk3eaAjM5w4mtpSn5CsDtjobHa5wIXwhA8/WW0ohUGJFOMqEtBU3arUvvuYj5RrNoW7HvBvmXEKdLU1iSLAhzaaRv8HKbG/PDeZGkeKQjm2RY0dVBQ+uCco8G4QWgvnzfKIqxbIjdjAj6lcLMQYXIXhcCdKKDW1UtV8fR+opRL2Knv/hlQFIhv+PGniOsT8NOPDd+/V7y+3vF09ahZgCyYJ+Cx7qjFQZ2gQJFLhi+9osAK/b4V3G4Z652T9F720f1EFYPZ0xPqZs+FncicsVOsqm5ypyHbMGRZqwKgOatWJiDxGnn9Nkw6g0oV2HfSd30EvDfZkz2T4D1iivj4y2ZyiBNC7TwZGKViSjpAl1xI60wpYZpJb963nQHAMEFlcNhaswSJ1aC6Kz5/2vD50wa27HXY93aYcoNBTDXGD7sg2Tk5R246SInuIFJrlLm02nB7fRAIgg5z22r07dYGIQc9lu9AqshpsdYRV9jY7YuS6e5rQ0WFjwUhMijvktNSOF/jFEEpTMM6vJMw5hIrZ7xHqhUVgJeIVtmunTImduzLZUdMHrU0rJpHBTWlgGmmQXouilwp38w7jfFZ8DV5mLEe0sSfFQMlaALegSoPH4DlKUGE3n+5djkYE6Ja9OsNze5bqw0xMElsUDsPJge1VayPlYH8SZbivUOMHrkpsjVkoI+GsNq4V8QULIkC7p8pu+2+iXDOvKYsiCmsyvSuPz3A7BVF550lqgTsuiSs2WBQ0FOMTFpvnRC5HsEp0sQ1da9kJnWanKqitCPhq83WJwsgRQUhOaQp4MOPM0Li9xPUKwjqoYXoZ5euxkhWKgG1Bi/sVaOtMxPpBZczO4Xl3IYnnHMMhq9PCa0A91cawl6e0kgSvPla5Uwmz7odHmDd5JSgHo1sFQ5p8hBUNikohWPLRzCtbiNYSDFg3YH7fcfjseNx3xAABOE4dL57MZyCaDuvNEVjjzUm+sYS2LeKvTeI8H54zOVc4IKg7J3pa8/fObx7PyNGZ555NDCF0F8QSmm7D2SCxqDAbM0MQkDwMqThHbumd10PXmCFi2pApowEPQTzguuyHIFJOQRpSii2Ri7GVIYAtRVkLVizh0vAy3rHh8vzF1PtkC2aCMdwumNSVq2QxuQ4+mhyPZrOv0muDXyHA7ywglyazRuTALM3kgL4Uk7TTV3ptcZkxw2pTGtq/hhMKmtTtJN867eOs0dL/9N9gJggU0oglqyKyT56Ao0O3Nm50u/q+F4yr/yRRPuAEBN8CHYNDU0EIhXNe0Sl3UO24s7bznT85nMwe5yzh37RoADaq9fHGDoDwVCTI9XK4oU/wBYxULwJ12sHN2RE3gHJOzRrte5EECLPzUmEt4JRlzB3YzNn5+LgRoMgXtUBvwhPElxxj67AahJ0cTy/eQoQjQgCaCvIN/IoOmPfmc+Ucw7Pz8+4vntGcwGfXles6864pxR4BxaU9g37/sB3P/yAfVtRczYbCj7vp0uChJlgpbMuocpmI6J8Te/I6J3Huq+U5veudoZROrNueJtHCVmVLkIgWLeM5iZc3/+TjYsJjyZ4nw7mluv3PfRCmxKgbw2oh+y+NQx/F/Fc/zpDjVAP18AuQeXtJ9un1GMO1sqGJewOTHZLbW14/tKDlooCZ/tbL0h2384eKxrUwLnhyaLZ9x1QUCrpJ8RAwK13K6MXURhMhRCO7nMdMGKc8vcnbh2qaOh+sQdAARurtPoyv1znx/rCP903sVvC/Mb36DE2VDGAXZ63QvWQtx7X00aRF4B5NHUG28GeFOfI5nLOQNnfOgcqYhwcJDjGEeJgPCR6TZ5k7Vw7/trNI/PsDA6eCzYAhhTLna6tr6/dVofd4Xds+477/YHNmKYjEYcMxRHHLteEL+VpznsC7ka6yCdfsugFubEAvrXMgskJUO1ApLISbQogMiP7TYghsokK+nqlY83vuSbst33N6jGPtwLlGVwYbOvz3oO3YKeIQwoJd5OOduZVwxcgjzYEEVznK5xTLDEiNHb5naeEGCOmecFyvWBeFiyXBTFG5FpO98BGvNpq3OhXXKSitXCsW3b+IQZoYAdwaEHODll1AOPdIomf6+DChOgjLlIB6z7/er+hVMZ6KVFp0xJjl3Xb8cuvv+Ljx094/+4JH193PF8nrpH/7jn+9x1vAMmhNumxoo45L+cK/fHuv/rdB2Brv/srJxaDx3fvn/GH3/+AXz/f8K9/+gticshG9VQAZRNAExnewvlQqiKqIHoB0HB/vEDE4+l6RQhsetKB3n69zszxO/DMfNgh+IDs3rLI/p7jHxoIO47OOIDNbk72njwKSPfU5vD6uiPnCu/4s1K7lOw4euKvvcW4tKE7FUcPrRiA+RIQlgm3152JA4QSs8aKS9kKNbHd26E1lM3oe+Ago6fY8DIEAIhTNBVAHVL0eL7Sv+r5/UzD1ULjzG2jLjpO9DColVXgOQYmh9bVpBvQOs8AobN6+tDyQrZXiB7TJWJeWN1qNsjqFoiih4bnZ4937xQf3jv8X/9vT3j/fMW//fFX7I8AzQ6324ytBqxrweu9YG8ZcnvQVN07bPeCVoF9VbzeKJNxotgrmSvdIxMwNoP3RuuPg53TB36tfBasVpiPy9jkFL5T4K1k1sR84Dz9gdhVj5r54+8NwQKKWknjF7Bl7rYpBHkAR52efr1OgHP0CaqNErVGZpoYI48G/xvu95VdIZ0AgQxBHxiAlcbgLJfKTndrxuOR0RqNuEuhZ5vr1RIzeXfewxtqRSa1w7ZlPNbCQr8wdOTeSaZT3jkOOd4PGWVPXGJ0xmAU7Jm+ctq6D9GRQ43nZeBcLZ21BRtznFC1NfjONIoRsTJRjylC0MyfqstYFICzCqt1IeoBn8oAcyjBdIDzcEHQwE5CNTfA5H8xEgDqYGmIDhL43Lb7NuZHpw8rDv8eSip2ZJcZQmi/fwVpipgvliiqAhsD6hAoPVu3As1HMt6n98Hk8EjJGYipuK/WOSxX3G4PAKxWTVNCSqR8i93rYMEVKyLAI68ohYweEQcvZhIswgdmiw0DGgvsThVEMqlM+mP6+0NmxrewIUdEaRWP20bm0csN4oAU3QgUm1KOqCJsd+0cinND6qQiaGbMDGO5KehxtywBUDHmgiDNDnFy5n8kePd+wraRJemDoKqBQZ5dw1oBvJD9I+ps3tBbS0F/jG3LEHhMk4EtMeByiWyykAWvn3cbX+ykC23QbAwuJ6iqWJoao4cMZLFkl3EZNyEGk4wertdo49APqW+MBGdzbljXitsrZQP7TqN/QZfCcL4Hz8RmXWGAh7WNb83k7zQmbxV4POzctI8XjxCdAfuWxNRjXVS8ldxQVni8vuQ2AMnamt1PMlkBFi20VlvPjA1m6wODZkXNDdtesG70/fPBwUc/7tGIWWwdisFj1UZQNLHtuHc093agnxmL9u3oCtj3T7QDQhH6GFVjRzvnKU2wL6xagSqYuqzXOUxuIhimOqRMbiQBgMAZc5EdCzmvyHykDYEf8qPOTo6BLILWFOtGQL9LYFhMORKMr2Rpv3H0BKUzw47kBBC1veUb3kUiBwvCbpEBaO1Nguh8AIRsYx8CvDEUKeOuI94SMEluuaG0itAcajvYZ/2bOvDRP/9bQThA8EJBpmRPtJ0BRdHAx85YFgimFKxAdAKKnRuJgTZrtFEK7RmCJ5AZKNfrILY2Z0a+5hljvl8CT3BL3Juk75wMMpHs1yRvr08wxpt3DlMMZOLXhJtjMwl2K6fXYkVFjBHvP7zH0/t3aC6gyQ2QG5kVO+X7S5ptrFDiyfFcIM0h2L3waLi9/IJpnpACu0Wu244M4Pnpwk6L6lFSIDDUyhtvvGZdaJux9Mc4swBy3GO7vpAuaA2ICWjCItwtNyyhIbr+/NXiF4KKLWfrZHfsO03J7qjmXTXSdSEg6QAEYewK21/fPBfI4ZVUD18gyMlyoX0NAtVW4cUN5r2cHiE/g8CcU64JweTXWtg5s1UHiEPRatdHD9RizEXnOyQPm28HC0et2sjz+0K3h34+pnrAke58eXQAubYGZIF6Y4M7d4xjdxQLfutQPTq1EsjsBZ9zknnInrop/pv7bW/uMXmPNfu8UZsn8leS1i5y7F3MW2NRqljzkb20v7s73PkzO+EBAJtjdaGaWvH+5I1HECwhxQiFYN02vLzesG079n03Zmq//wBEsOWCZYqD7eK9H9JpAONn3nzEWIy1PNPGdra9nQxqsnDHPt0LlYBZ6PDeZzW/KmUjisGO612/T2NLoSgN3MvUgNvgLbc4dxvuc8vZPurGGncGyFhgcGOOAcwDStMvmItA9A5Py4QPz1d4L/hsCgWtbBi2TBPmyxXX6xXRgDGIIJej++gAAU97Zh+je85wxpPpcljnnCnGTixkBWjlQSDsuFaON4FDms0vMXg8P57x6eUzHus6PHt7PF1rxV9+/Yz/9sc/wQfguw9XQPzYD//qvv7Fnvym5vBXDjXpPxzGutwB7P7MIH9fswZ+4IFHcG//6vS+cep8/k+XGf/pP/yEx7bjdn9gvk749fUG48ninitipOpHlLZTAjZfcZkev61lBL9imSc4UEnxhuEpByPxnFsBzFNijCdrl7++xvXjHxsIs8TUOzG/pG+8RBvWjRV55x3ut2LtqQkIPO7VEkuMSTQCGVXb/FklqNpwuQRLwK2StDI4hjRak/WKSWnYajbGiUOI7ELHVtOcDPyPTUnpi3OnKzvE4LBMfnSJCzFheZogANb7isctW+IYTErHDmLTEkenFAEXIvrGmBwMh1kiAMTICv60RPhIjXorXccM+rgUAmEpeVwWQWsB797P+PH7C/7yywtcTXi6Av/hn99DPHC/Z/y3P77gz78+cHvdcNeMpg7bvbJ1+daQCwMc78maOBqrMDHwMWC5JMyXiOs1AU6Qt4KQaJz88nHF7XUbk6Gu1II3baOl9pdHK83MkRuAiJQwwCEokeZ5ZsKyPdipUeAQk8NydXj/A3B7WYdHmAh1/dPClvetNqsOHdR+BkE0u308VpScMYXeTp1gXal1VHVKbij5aLddq5oMlP4MvjakiZX/GJkkL8tkZr6c0h8/3rCudQRbrdEjSGCeR+VrABgAUvS4PE24Ps1IyWPbCz5+vB/SMRsUqmRclpXG72Sk2MZqYJiKzQW173TFJG8CcRPynq07K6wJRe+Ec3SMsqeGXpruSVFfF0M0ELQSiFi3Yr5ZQHJMPBg88VycJVJNabbfJZiP24MyUfMlyrmi5DySee/ItogxYK+FTAKxLNADPgZMc8Q0k0ZYYJ3y9AgU1EBvJnFAtg6o7LTHziklF841EThpJkni15Ax2U5VmUPK2+XPThgwXy4ztkcezEqCvQ151yGFEFAqvT52Y4C5IVN9Q7eHHsCjMmhtxmYJHvCB7LKSC3bdULYde424LgtSnBCkJ1Zs/FHLDkGw9ZLPNE0J4hpBDIsVSqkswgmrTe/ezfDe4ddfH1AIcmlIc6B/Xj2MlZ2xNgTmlaCUU1cDqX33sAseyxLx3fsF+07vDuf7Gs5EGSrDz1ABTMnDuYmb+mMzhlNHBBi+OHf8M0YGuftese/04uP8odfZtmc81motp01i0KUD9p29UkvPQqb/zeji1STNrHJ3/4seyHUQlizVONEwVlXg5ZB9dqlOr2A74f2EUM5ccoFINTN7gtQ0i7dR2GUw6N3T7OcmnwGaSWKNEdaAWDnPdhgoa5PDG0jtHLCXDOfpMRhSAFqFg8c0R3iviJHjai3bV+vYOFQBZfFFQD9OD0UtecQLTRsy8gAAur9YtywQZeIrze6r9kWwAwWVniMnkxsdc6RZckEpTykNpW4oJlfI2TroeWfSfRxVBgMNOgtjJJ898fAeQ75+Cgg7y4FvP943klAHiHgMzpUlNUE7c+UIenvVlgk497eSN+so1hm7tj6NAWGJmy08AxLq08QSehV6Fg3vmb5KnICN3mn2uGZnLMejMJJSsHnOe97lTL2Fei4ZpRYrQCrEC9JI8t7K0sS6Ti7LhDRNxuzp68kRgPOcbF10BDy+rPh3Nli/P86uRw3I8yYv7OdLYIDx4mWZ8f7DO8yXC7I6LAvXr3Xb4JxHiOwWfrleMc8JKZFxTtZWQ3DRPEgb0DKmMCF5+sZIYoFijozrxDvUxHgieMEyp8G02bANpgmBVU+mocWowzB7MAf9kBj3+7FVh1wq0DKuyeES6SOnDlAtcNUdSTScmeGTGSIGYnaQzDtPZpvJR53F6h18OYOtis52P4CmWuhPlkshK8HGX2kNUhXidgOyK+QLeGUk+85Z93KbA/35aoVWsW8Gdm2IPiDECDzuh8y+j7dG8PYAvzlSOB9O97QDuz35s6uD9kn15iTRF1CqVJRhStch9sEIQXfOOnDaM0j99iOdcxCF7R/nqgXnARsZmTT6dN782KO74pCy9XUNBBoU9euk34BWC2pwWknIyK7GoLUmOuf39dP7zUMAmDcxGhUCYlJRAaWB3hj1UBrWz9MEH9iEad0rtlyxl4rHXrCdOtzRxkJRWsEUD8ucwXzXrnZx1qRD3oBuZyZLCm40HAEOObZzHi5Qfk0bnmrG9A19J+hgQJdxeufQ5LTeymGx0gzl7Pv/eU3is3QoxZhy7vC4U21kwvowunRrIzu4H7RN0ZGjB+8xTwkf3l3x3bsrnq8zSqNXrnMLvHO4XBY8P11wfXrCfFne3J8vwY3OOnPi3/ysdyN2TuDgR05M0sjRPXPM2NZtPL6GVTtb98nTHy5Xrh/zPGGeEm63B/2cd3aI/S///U94fl7wT7/7HVpLw/v28Hr7enCex7/I3weC8VoxGicM5pQc68m/5zifldWqh+S7n9dvHSLMP3/67j1ef7/hX//1z9hRMYUJsK5q2e+oQvZxCIF5YQPy3mwtB6oD7rLh+YkJwtg3T9/lrEDcLF/op0X1XhhyyW/luN86/sGBMFsVzov8+degp0fXyG5rwbYqWxzr0c3I2XLc5xfbPjOA7x/kAiVXzpnZMHcXYzQwsM4bO521Yp0eHZMXOSXuPnhuKCZV46LX0OUvogySQjAvq8sEWCLDLUOwXCd8/vUV+5oRkh/0V80YwRop8PzS9Z7x+pmgUclvkWHnBd4b4Gf3tJRGNptQEhpSgAucFDk70kGtxfd/+f/9BdujQjNR/Pg9fZrmtOPT646/fFyxlcquho/KRDz4YQAOEdTGDcmPbo0O8xRxuUYs14h5juxAGR1aaViuCWXn97WqeNx3i7HJHrJlb1R4AFjASnP9dSu47BWtRcwzJS3ZcTNkQqfY1oyXlwxt5h8jDmmJ+JAIePz8x8/WfVPwet8hXhAjAFFsjx3bmukr4t1pX2anGbQGmD/RNNEocpicGzCSu99RcGSqaU+IzDMgOOssyU5jNARPmJeA222zhb4DYQ2lAEOB8kUA1TugOU/m3dPzgt/97hnOAb/8ejPZBkE7Z4BIUzZY6NMQcvrYpoyPvE1RG+elVFYtPJltrREAgQFmXcJAIKaDYv3z1XwWrJMqy1fo7ca3jUl2KZWeUMGh09G54R9+W+IZAIfoUUrGvlGSBjjLx5u1xu7LjHXSseSPxuK8/xDq8WOin8u8JORcsK4VO8oACAikK6WTgfK87dGs+ljg7hUhAK0VrjHGzgJoGq4WXHXjZyZS3MBjdHAhmGmygzcGgyKjAQaSWZBq1yNghVGcQ3xsiCkiLZMxv5KtOXKSKiv2NaMUSjlqqZQlJjYDgcDAX2cV24LVkopkHVBLcdhbwbpntFoAeJOAO3z30xW3lxvnqk0YtiS3anYF4ATPzwlNgZfXDAjXolrVWLIj7xzj2nuuGfu6j45hXXonoljmgBS8NQNRpOSwZ2bvpVZ4IQts7V10g0OMDsvsUQpB7tbXcKVcxvkD9CTrjGb1rRX0joRNFbf7ilIq8m6NSNQEdr2Y0myNNODFOcBD8dgKtr1AEUblTvs8bAT4ggFbIr0yS9aJA9Csk6xw+YU3BpcaSMGqa6F/SqKUr2aTGEEBdfA+wqHZPkN5n4ciOEDEpAatIU3N5NhHkN6qYtsJ/k9TtHVXDbg8vAkhByDifYA6gVMgTQkxOFyWC0pdmWQDaK4SpDolak3JDPZiyTsAdR4qdSTeAJkgHfDpLbgtrTHwd+Cc/PiDXMlzd19EiHokNG8kNpb0BMckKrOjAVT5gVzzbRzZ/eJ6V8c9EpOseGdyRgOOeM9kVL8Zh9Q3IJot1YPhxnni4T2GfKMZuNotA1qjzb6ahK2TYPlZap/nEMwPyjs3nkGX7DorPvRnSbCRrLWmwJ4bul1PB5XImHBkhvU5bZ9VW98PMMAkjPdRxqqih7SrseTYwCKZd8HiHd4HL+bRQwoz5mU235fjOIA/GUlCh+/egAeWTL95LweKFXmO3yjeJr58/oJpinh+umCaZ7yuDdM0obUuc/OY50pJb4i4Pi2YlxneR5PL8Y61UtBqxpQippkd1GqpeEqLrZsNeS1m3J/hQsA0RUxTsjgko15m7Hs2MIpjz5nkFnavO9gOGyPfkqSsBbivBV4CnlLn3HOdFXDMO2UBEha7BIsfemV/yB1tLpznVf/ZYPn0udkLYAa00bS7sMOfNYzQqsMDVIJDEfNr7YxXA50oiexsl24wf3rCeoxUAdUhLP45VPHorFHg5O00QLADBDn//Bh3GD8HcIDm3zikj0Hrojqa2BiY3cfvGTFSu1eQAwZoHaay2Plb7Ip+b3juXz/7XlR6M8ZPgBaULHHoW69AACcgRn4zAxfBKLz0ix/30lCj7pHZ/w3Augh2qTC95rwHgnAvZOd4sjVFHKY0YbHmQNu+Y2+AuoCiBbdtx30lAEJAqDFeEYxCFVm/DvBu2Kr0gguv4+3z7usnGYdUBB2gukBcgEiw+UM7CgW9wc73vqkaa1zHnvRm/dEDLO5xMgtb/rj36PFIb36GU1ytkJMMuDQSHMp5rHjHnDIzbk/J4XqZ8f7piutlYqFwK3aP2Bny/Xff4cP795jm6S1I+M0x2EGbQwbIa+ssxP4qHE1OesMI6cVSFuP3fSdz0n0NhokwhgoqmJcFW84IYUX3eV63jLuxxH759IrPL3f88KPS7+x0j5jD/LaE96+BTb/1+nPzgvOH9GfkhQWEDtbai3AGyka+c/pcVfzmeX559Fznulzw03fv8eOHd/jjL3/B7AMaaF+zTOzGWqeJ2It39I4rbH5G9RrtPbpyorPGxjnKEUd1GXMpZfildibjv0ce+Q8OhDWguaMSKacbJeAie4Y0leyKLinve4Gxdi3QODae88Bw2oNHBsdqX++joN4q9o0TvVa1gLprygl0lNqGXLFVhRShUb4F2928lgwjQQqUg4TgUAu154JDB9xbkPekjikOq4md9ksfCAIW+1awr/mroCsm0/A7oLc1VZPmidCnyHVz1KbYs4c2j+erx89/upNNAgevYXgsrGvG7b4hZwMOPaNGL4KsbfwdxuZRBUKMuFxnTJM3X7eIaaIs0ntBTJTqxWtCih5t4iL+8onfs27dgJsQ2Hny0meNBvYCNRSa4AY7h7FRQs0Nj3vGtlas94KS1UAOtQpMwHyJZihvgZ9WPB4bKchOMM0B+0oJUDXJivdkdPQ2wskWWe89pondZWBjoLMmOBZ5zSGQoVd7BiJArWwAAQt0alPEiZKvX38hVZuqfLI1aBl20PLPB9kgGC3TlbsJz7dYICkwTxX6N9VKeaVzglLVfJQ628jmoBl1e0/tdqkZZNoQkEpzMJkV52remdSN8FOPTUxw0PurSTS83cdaFHs+KjytNkj04/t7IOe9H52jADVpjEOtO9ZHQYzJ2vM6zMGPhZTdySpaZVUtLRHTHHF5mqBNsVjiUxs70/ZEs5r8opZGkNyew1aN9dR0AEsAq5oxqsnSjNUJ0FDZ1pRia8GQOarY+8hWa6poWaG1EgTrYKwlyxBhEF8JhrnMuR6imhzEmoRAEYMzZgBN98teTWJu3hdKD5C9ZORcMc8RMU6YU4R4soFaVfgJmLzHCkXODXnLeL0VTNOEkCKcAMvscZe3QU5ravJSMrMaSZu4XCNeXjOrrsacrMauEydIyvuTbP3c94qayWhy/gCiOhPvdt/NkyogTM7kaoBoQwOlYHvJqLVhkQifHOLsEbOHz4K6V3h/BF7eGYfRKl0yOdQKlL1RDhgUWg1cJTIMcQVa+np1VDYtq7Fghw1OclHkzPf3zpdjXbe9LMUj4GawQACL46h3n+Jrxc61VYKfIvx7f1/3htMGhKD2GQoXgiWt/OxayO51QcF25kArDhCCX41kFa6LBWiNYHSI3vZNBjgMSrk+tFb4LBwlUa2JAWgzkr9ApCGGmZ2zXGOCWCyx48UjSYQPAT2oF2X1+Mum701hu2hnvrrh69WldgrKIYFT8Gn+JOdgdAAyFqT2JEQECN6hhjD8Qc9zinKMiuQCuiSsdmC0++6IYxEAQC+8d2BK5biHtVlFVE8yEhCkde2QgIvz7FrqKevKhaB/LvWoqKrJchpf3035RdsIulPwQxZ6NoX2QhaUQIzNFZg8OQ+nO3Kll2BQwBnD3/cE3nmuXV/8gbGUuMZUNAuMhxm/xUW1GXhr/z6jU92Xscvt4I9fz/NkskntSBu6QXyzpKu2Qw4m7gR29qlrnfy4lzXUWg4w4bQNHwmwJTWOCVdKAZc5YcsZKSS01EFXxjfBsUnPcpkxzzN8WuDidCwd2rBvd5R9Q60Ve7YGNZ5sws7eWR8rHnmH7hu8D0hpQQxscuS9w7ZuZCNb4sR1hxfR+h5m/mGtlQEkf3nw3jVjYmGA/egV/y6ft7FbcHT37HOqDkBYbH/kwCdj9wT4GqhzloIxBiMYWDOLMQQCrFcEgPnNo9EDZAaL1Mw33srLxvzTnjwyB6glY287FAINk/3Sfi9q+YRDL7gfYERncyi+5R8mNlYcjnk/TmI8e56M9wfbqMsqz+CUnRIBbmVMAHt9v5deuv/jW1ZGv0cdZxggizvLP79ORtU+6WCIYbx2nL/FNwQ5OsB48oqzg76mb0G6UZRox3rYkek35yLd7sL2FzEQ39Zo7wV7BaInOJwMjM6VvpNVHda94rEV3LcdIoopKHyISAGAP40TA/C1iXkrHs+llori+kL+FlRvrcJLgLpA+wFukoCQOQmbh7WR7T06Er4Z+8YerycShLwF31jsrWNNPYOQZ7Csv7YznY+Ps7Wh6hsQzEUPzb2Qy3irS0JjcPBCwL1Y4S2EgPky43K94Pr8NACNMZaqsczlBOMqQAFOQzjRl3rxmxLSDgZ7QOuRB51yln3PuItw7UvpK+GwQQoQ77EsC3Ip+PRygw/M00ozxn6pWLcdH1/uyFUhkjHNz/hWs4Tzob/x87999LF7SDQbjufTYxQ4oKCMc/jWcV5PuBf9fcBcB10BhyVN+OHDB/zzjz/gdr8DyCjq0dCbGimg0bq7c80oxQqj/jjnnDPePb9HzsVskfTN+tPzoGr+biGE0TjozGb8e45/bCDsdHRUWBWs3jYmnaWQulmLGrovNmvQ11WcGnLYZmaAlx4f3poihIhlSeaF0z2EMrZHxX63QMEzY3HeqnrXGU0Vr/cVKQVWr7URWROTAfSdBDDZJf2ftFbcXx+UuwVL8otivW2IMSJOcWz+faLX2qAb0VH1TBBVMaRNOHVJ92bq7q11eUxMbKpV873zY3aSHTYjJuD1Biyx4POnhikBz0+OPiyt4bEVvN4zzUOFpstOFXA6OqspMDwtiMo7XK4Jl2vEtASypMyjTFrDtCQs14RoHbam6NFZRE/vJ+xZsW4dSKxQPTZs5wVxoqn2NEfknQDXuhW8l8kYm5QzbY+CX35Zsa0VdaP32Bx7lytFiryHLx/vZEv0waEN+5YRAj2jetfLXo3sZo2AJQaBn7ks0d4DxCjIGVgfheaBwSMEjxQFJTUUtFGR7zU7Jo/C+zKxLXpKNLkeWS4U0GPD6wHB+YRKriPID5HSo9IsYfQ2bmABjKOH07rmI0FVSsZaIyOkNXYr6SCUd94koJR6dU83nhI9jnIu2NcdIuysyAS/L4rs1tiff1OCWIBi2wv2jQBiM/+iATxWHeAYcKqmmt4uJmBbaaZ/f8lAhIHVXYpGAFs2W1uqMUfrwR4s1g02RI9qEuwQPUIyhkFlcwxW6mESEWbcDFYOGQGTYE+au1G6u+edG0wiY4DYpqMmf3DGxNHWDGxqJgEXNtPQg4XqgwMCGVwiZI/Rq8Q8WiwA7YzVUirWtRig1BCDR1oCnAvI+07pnFUt1WSxy5ygODoredclrQRodvPh2e47weTX+5uNqwdhrQHBNvpayIrzxhrNRZH3ZjJWjvU0ebsfMsBZNmBQiHfwxritJnN7edkQg7OmKKwKF9nQ0P3frC29smABb0FGdJgukYCzsoMonPmEqRUkhEDypuw0m7cK5dUAjlL6UhRNPaABkJ3+M54VSQbnPaGwDm7asJWGXIUsN+uA1Ke3c2TTQhW7NWFoBmhxqBk7+bQGqFIiWwZzmetIsBb0ZOHQh8954fwdMTXX4se9jtfFiabCSRzy3rBbNVjNj7M2pcG+Y3DuQ4A4h5LbCHBLaZgmh1oPTxInAUoeGh7rilYKrvNsXUEjRBMASrCPYLyhKiD1YJQciNEJcAQBHpyqqo5XxzXbGcjTKEHoxa5emBII29UbmCVKcGUkt02hzjruBfPzdDTnb01R0Y2VgVp2IJzZzI6G7XpIWpzzAxhT1a/UHL2C3wfGYBmabwzEGHD2+TS+Pt0LoT0BcYqDodLXkP4a1xvPAEMeg3q0qce4f7xPvRmJgvyPJgHONSxzNLkbizcs9PH59GSy1oZsnoIwWdsIePVUbQdNyZ35feHEEOrn3f87ih21AE6gmZLZeUrH/XCe5uiezHAFAenOhuxgwpdh9+HTYpX41sZ6PxifX4AEABOzEGm1wEs9fOpqYSExxQBBMz8fa5o0JYRpARNfxzhTM2Ikc1Uf5s0VoyWYxqRzYuCaUsrug+03NrbsGueJTK5tr8itAuqAViHIiI7AzravNJK2GLsnY+M69QAgewdw3iuysnI5WOwNYt1ij8SmtDISejYWyujy3T4nuy/YG0NtAxBbU7RaTMZ8AJDH3T+Osy8Nxx+7/2oHuzvrwOaZmj9EL1jVkfQqXN1QDFQTA0Ybekd6/9V4OBI5AzK+BMPkAMT0lL2K9mRmcBXRfZ168NfvLz/TkeVjsWXni8RgskCTbnpx5tf2Ftgac8hiBc5JztvzeH87xA3Edn1u4PCGVfMrhR6gp4E2zoXx2ecx9RXQ1o6fu3CwrsZirhilcnG8T4PJaoOglGqxlUNMAdH8ERXd64oFmXXbOGZB/0ovnuO/KXLNmKyz9/npiRij35NZ2RspdMXC1/erIMRn7HrYwLDbat+E1YBu5j4dvGitQ9cnaPc8D7W9KQ5UA5m8FSsYV5y9pr4+tX60dthlAIeqSkLA/ePryHPFCVKKWKaEFANQ2b0eAKYUEVPCZbnger2OokZfM7ofb2dTqsgASGxYQcGC4Tnfcf4oSDGe6bL0Pk8493IpgCguZUaIEa0Xe6CjkNx77U7zjHci2EvBmnfstWHNfR5VfH554OOnV7y+PvD8RGukWrM1ULNP6evBOS458LlvHl89AwOgiq0RXj3XofPn2t/V6Tftgn7r+K1z4O8st7T51LShKJtgpZQwpQn/8off43/85Rfk+oqsAWV4CXLt9U7hhJ1N15VxdPeXDUGwrhtEBO/fPxGkvK9DoTLAa++GBUX/45yzPexrVt9vHf9/A4Q1ZXCielwU/SyErUTVqqSlVziBE4v0baB0/mBD8n1wmJaE6xMrbiF4vL5klKwoWaFBbHeyySUeKQYE73B7bPDi8bgV86JhRZdzoYfbDFJo5E7T07pmMlBSQC8Xvrzc4YPDvmfEFJjsKBAdPYzWbQd2mkhHicProftCnS/SdbaMsJrQSqOsb88m4eKdPG809xvgaoXuisslABfBkghkPNaKz58zXl4K7veC1xtBDmd+JPBHxQKls6Ic5kvA9TnicpmQJspCSs7s9BT9kDV249+mgGvFWmKDkrRLRLvrWJChjCNDJHsjzQ5hdrivBbkAaaVWe98b9jWjloZ9qxCl2bjEOgAgBvIM+tc7qbD1JDHlQvzbeuTO0AO4AaslYjEyWE9zQPBkt2x7xbYVXJYZUwojCPBeUKWTx7sBsGKagrGaDMCsPdE4qlG9uqhWGRpgWAN8Osz3OwgmzmHdGmou2NaC3r62h1L0hnLYjMIyzwFP7xKggA+CbWOnVLUOrV1yxrb2gi+DurIxMCqlouRzB7GjEuyDx3SZIAIyRYrisRbsWzX/NNuwxUz+exWQ2xhKrdgLZQopJnbfqhUhRqwPBtNtNEdQpCUNADEEtpauxjSp1oFwMzp3n2MlM7CfzaMvJnaizJnJCwMYBnY1kwHGvZ5Msnkh084bS7FXS72Boqq9uQDPIcUA4skcW/u6E5zfKvZVGRRJTxaBgF4V471hxzqyldqaMS1sSEHJFdkgI5AyRtZeGuYUAaGxZTHj0lIKcm6YkgFYVSGOoN++2Qbl/QCn5ilimgJuLw+UVg1osG9zPbGV4ZcI5b3b9ooYhYAXyKqVwuCvM8I68PPysnNeloq8FUBNduY4AT59fIW2hss14t37iyWJHsscIajIO+XhqkrvNDUJcxFMi8flKY01Jq8F1aqLqoRrggOrcBWomSyrvFVIcIgpIcaGGipa8wAS7vcKJzOGHUoPllRRGh1x9pxHMlZrxT6YsBzr3ivmZcL1MsO7fcx7GNglrg0fst5Mpa9x1Tq5OgDzxIptNGN+Fz1yLfA+I6aIVsTAT8FjzdhMUvDkAlohuHK/FwJmKmiZbMBS+5h2mGbrBNnX0c5CU8UyUXq57338unFPWmtYc8a+blgmj9ttw4/fHQF9v56+4uLfEfwBx3433nUCTM6vaWBnYnV6MLQ7cDmS7IMhxsdpZyWUmncJ4pfJ7rZviC58u6opNLKP04yQowWAJ5o7azNvjtaaJWh8PzuQKfZ9RwgRCF+Hgv28gycQsZdCOW8tBmp5TCHAW+HlYGO95WRbvYOFqiGp4R1ubsKH58R1tVHK2VqGgHYQtbXhzaboCTNxvxjjALw6CNf/HLfNmEQl04sKbnjBiQqfoclFugmzdzCpoR/n65zABQ8fA1iAYFGH95IJeoMl8Sa3HBpSsfufi62DYvtdNpCpg93Hve/yHEUHMQsgDdfLBNUEdjB2qMp9FSLEzdoGaIOPCRAWdtSYoMtCrxbnA08NZJJftMGtG8ERbWh5hVZK2XlmvA8JiiAVWlfsj1fUUhGjwxwE796/g3jBf/kvD/qk3hXwQJoYL5dakTzN5ZvCrv8YpM320C+N7UXkqPQ7B5cFOzobsDOmyEzvwGGPzb4EbLjX5WOuHNPJACUmul6Y7PbxfHzOEVN0Rjp9/shoCXAIkd2ph0oFB+hJRoSBP8oATMXb3nqsL308sLlKG+/3J6YwISy1DuSwCX+w6Y/v7kDyeU6cpW18FxUSHNMdEOJ+zLGTa0VpbYzHceMM4CDT7wDkMArA386mpSN51pO1FWOcahkx7wE093HAgnFH/TtTqV9Pv/Qz40Wsg6oacC6+x9+HymeczwmYoC8vx1WaJgPCjnvbv5vA7fF9Hfxu2hAHC5nvO53VAHfPqoP+ud86fFpQ14yqZmPQCN4fRYJK0B8wawtApA2fxFqOOVHtnDvLunscHkWWgzXILundn66vhYdUEeD4UmlWeOY+MzkCqevrBoDFbVXFlCLXS7P9qKUCpWJOEcu7K+I0I00XLMvy5vpV2/DgFBjDyWLSM3bYWc8QgXhvfrYVTo8uyKOgpOStqGM3eXaMdtbt/gCdBhNSYVYU/EWMEe/fvUNpijDN+OGnH/C//3/+K/70p5/RWsPHlzv+x//4Gc4Jbo8VEdmsCoylrc28royBiXPc0r+rj5hjjRrL0HHVZOaik0/cly+wV+lvTce/enwrBMnNzh0GgjVahzgnUBTM6YKffvoO33//jE+vN3jnsFbiHDHOKIU+Xpe9YEob7nEztcsRd+x7wZ/+9Cv+1//1fwEZYgVtL6jnmeSEIV495mVnW4Y38++vH//QQNh5Pe4X7N1h/tiqou4NzZgExJ4MrPrGgBAx+nQzrxEL2Ocl4nJJCMYOolzNIziHHd46nyhwkvaE4LDljJc/swNcqRw4U5oQpoht3e07OTi895gTk2OxKl2IDvM8kfnVFJ8/3ZhwloqUAm73Dd99/8xueULPjT1n63hE6vu+ZTPgNmmd7SMO9DXqfmTRCUrO2LaGUht8CgjmgdYr1ewcBMxO8bkpXl82vM4N673il193XK4Rnz5lrBs7oa2rslV5M/ZSB4wa0LQiekGcJ1yfE2K0zmaeCZ6IIIaIEBiw965zAqDmgmIytKd3M+73F3z4MON6jfj1lwf2dSd7qgL73uAmxfPiUFuBS368//664+c/ZlymhnUtKNWBXgV8+EyChZLX0vDyeUNIDo/bhv3U5vibR08wDYjow46d/wjsLJeINE+YZg+tO4J3mKaAfSd44qwyPk0Rj1KYoooCPhgNtSdkDCzXR8PPOeP1dSUQpZSZxEiPnBGXW4UqzAHL00SQ0eQ0aglz2SvytiNvme2M5wAXHHwkW6pmzqsQHJaFPj/LElFzw/pgAn7MsS4D+xoEAxS7yQN98GOTPuZ1lwU11Fzx9GFmUo+jAQTROesYkuzeGAOkSy1cCEjeIUxkj9SyQVtGMm8vkR2tVoSYCIAKE5boAXEerVVsVvGqpZLxZcHkNHmU0gFwYH1QRteNXmtpqPkcCPFv3JQLQmBTiBAFktU6ejZ4k4754BFSJMBSTQ+Phm3PmCZn1b9q646HajF2nlWCO5jqzJPrBI51ELyKNQqwKnr3mAtBR3KpqsNQf5oD9m1FL9B2MLgP/FppFFxqRdkaYmmYFjfkB5eJSdFySbg/NmxbpidPM2mo47o0T5GttH2A1mZMRCGwKkKmYGQQXHIzU1qH9cGklub8XAumicam4hQ578iZ5r9pCgT19oI0CVyYoA1YH5VSH22IieBVzpSZpylgfoqUbjvBFjIDgqzYdw84Bm5OYJJTj+vThZ2bpIMFFTGQCVUz/ROn6QqgwkkegKWCTMJHqXjsFVtl1x0mSNWSKKCpICECAP1MxGHfd5RSaLS9MhATVO5r08SGFt1LpSnU2KFxoneaN+YWbH9hm3fued5kpuuqSAbab1vFvAhydVgfO3rH15wb9t0YiV4Qk8e7dxMrek3xuO1v9uFagafnCRBnRvdMPLNmlL1gzzvurw+kKeKdT9i2DfM8cXn0XyZ98jaas/sPS8jPR59HtqSMJKFp6wqm4Sfm0Fl7h3yjH957Su1MRtWlRw5dzmMGvEVwts6NwSNXekKh6tjzzgEdGRgVIpGAR+FeNHxNDkyA5+KYzFKKWU0K6Uwu+uaj31yHcw5Tojm9c4Jtb7jdH7g/VmNMCZYUELnM0X7gS0BNx/+9DUkNIKLPn0cuxarWDtvG/SOY1NE7axzjBHAOamyKKbIBQU9sqtYBjgUxRqwHppAQ1GEOM6pW5JrRqjHePU7PpyFvK+YYMMWI67zAxQSEiBAj5YdspYroyeDuHYBd5B6hrWKOM3LOX9wDS8oti2laUfcdQDM7C4I7TRulQ4GA215BJuaOt0gZTC59ZpAKMBhEROTfDnvp7CBLlATj3vXf94NdNs/xrLc6bxusIxEyJVPy+OGH7/Hy+gIvBde4IcgF3nvc9hUQMtJ+vHhcIsdiB08AOZpdjSuDMcFgDHQWtlQUEgRBncn++6ASoFGS1WOFfj29mBTiwdbsHjK1HY1Z6GEnUJ9Q6WhzAJQ2h5k7VLAIRHAQwj1kLRukCopWLOZ/cz5qa/SfUxn3rplcjKfbziRQAAcQVkp5I0V7Iw1EZyuf/ZEOZhH38oLWDtl2Z4c1ZVyeezMmqHVfPc9Ulk9La6OreVc4dIZNlwd3gEnLYR3yrYMgmNkdVBYTjiKyQDvg4TqDpPu7VrQWIGIdedvBbJOx4Mn4ahfMwZAPmEBX0xETHvgmX9P4f29qAt6zA7c3v8BSClqtyHnH/fHAtm9kvllsrVbsKDXjw/UyFj2y3bocVQb48W1W6NfHx88Z6y0jCBAHL+IcT8vwlA2WH/jTeOnFxT6eFIDTE2MZvSjGAmrvJD7eb+PG+8AYWTpbrI3rphH8jtoa9lJoB9IAbdW6yQuu1wVP1wUxJNzWHb4WPE0zlucL3r9/wuXpGeLTm2v/qgjVx7wePn7j2QPYa4WKtTgZLFDagZxl2977ERt3oBygLFvlSxMZ/svJAVCJiO0LE6ZHxOO+4jJFOHHYtoLPLzf893/7M0qtWNKEaxJoI/OpexIuy4yn5xnRe7SyjzH55YgY26jlkd/Cd7rvmTO5yVef8cV9PH5+usoDtzVQ+Iuf27HXOmwM3vpeKvayYYoJT9eEf/7xA37+ywv2oigi8NG8AGf627XGbvcvnx/49dcb9lzf5DO5FGxbHutfDB6oFbUXFM3yRq3Q1k+UftcJ7n77+kZ94/iHBsJG9UYo1SBN/5T8OqLFAjXPHv79Dex6OrzYxtJgnX2YWKcp0Jw89fbwlAzeHzs+floxRY+ttDcDip3GOOBVux+AIMzBDNQbxHvMoSGkgOXiEAPlYM2QZxc80hyQkmBdM9Ztx+vrw0ypge++f0KpGbUkouQCLMvFqkAGCBr4nM1Mrg9Y7x2WS8ByicPPiH4ParILmtDvgdVf0Z48N/yiDfvLhryuWCZ6makI3n+YcX8U1CbYs4IFCprfVZOpOXTmHn1mnt8lBOumUnJBbw9M2SYDh1JoXi8AJou6B2UaMC8gj7x7bPcdLQt6I1wAyHvFX/78gI9GiXX0eXj5nGkAvjGBbdIrk2RZ1EpwqZY2jOGdc9jW/RS4nRZtqYZ09THGqoTzAS1bB0AHo8wLHo8MPxUs4kfPHHZuo7nkvm0EnFqhBEEE8Ex0g2dAuT4y1kfGNFvnKqe4P7Jt4KReTxM7TJWioxrOQFtxfbcgTRG3Tw/s993uY8X22FFyhnPAZaFf27oV3LcKV4H5OiGlgD2TAQWxje55wuOxYduLbbyKdS2IiY0dvD+8t7rJOAC0UkfVCjgFsXYwoBVsd0pYKvtKwwf6sjVjVUxzb1ft0Lv3qFVd6DfnkPc7amGXnxgNiGgE9RR8PjlXTJNHmpgArCtltjnzfPNWRutkVWBeAno3nRg9Xl5WGhEHQVXgyHaPDQMoR7W4NaQ0W8WI3b4U5hnoj/vWGiVmECCm/iwdQgyW3DlMybzwCuddbexq5xIrz8sycy4DWEtB1oaUwgGI2BpXK8COe20005iSxzQFXJ4mtBaxbxt6hzgywrqcib6DzjuUBxPPaZkJbseEvGcslwn/6Z9/xKdfH/hv/8evyJm+UtuW8fy8YJ4TpmniPe5VL2skMU3BEhmPp6eJXoq14i8/P3B7zUAz4KXWwWgMwSHXDWpg6+jyKTqYiNMU4KsiN0U1M3tvhv7dV6zkCvEyEgCB4Hq50odx35FLRVwEUQKZgnsDqoxnGKIgmQns+vrA9Unx8799QgpCAMxNKJUAENdvmlnf14rXtQyQEAijoMI9p+Bymbk/ickT5DA63jKD+BDYZXaJAerJtGulWmmVUa0TWDMGQS1k+DhwnMUpsBVDblZMEVwuBPHnhYDY7b5jfay43XaUCqj6wVcgOB+wLAkKxedPK7tUogP1ZK3kSvANpeL+WGmkr5WsodoQYkDWhn3P+PPPn/C7nz5g6myfHhAZq/DLoHZ0QdSTb9MbBq2cZurbdai0npj6wbLskoMugxxyHEcQTw3U0qYkgKN7XLw9s+7p4kQwXxdLZNnpTndKimupCKUgBho0ZwM7fWDnv2KM6L58ttYlL0eyeLAswliTcmFS7mz+O8dgtQOyew6IgUzqXz69YE4JL68Vcwp493RFnCdICHCN/qIKoJXeuZaSNZwYPx4FQYDaIrzzKLVg3+7WSINJ5/WycN41difuAX5RRVBF2zaCGiapynuG5h3NOxS759EAKO892DGs9l7dIzns4GYHKfq86f6o3sB5b1KMvrfxRlcAxt5zHhIcWtGuGmbSCYL3rfbkv6KUHVozVB0kCH2dWkMpYt9hsdo3/U4IRC+XCcucRgMCgmAeMaUhnf3WQUAoIM0Tms2hN8yWBuylvHlPi25Ia8/FKnbUm/F6e6U0e55YeJoSZrBT7jx72iZo97aijJxyfs6R4Ci1PMBf2LntA8TqaAvXvwO4VQP1+jpOsOHwjnLODXlbU3o8ZaHULIiHvwSENOOhigLGo2tWeAuiq4E7B1OJMZQLbN5SGqXhpQWspWKKCZBsDVrI4KwQ1GYG9tbtrMc/CiCfMHnWdsTAMIuXrIhgM3hcP1kUvTCHUTTu94YgUwdI3UDJm43h1mkmxrQiuGX+SjbfOsGeyTYlVkV/a3z9dWBHFYB5ZKr2taqfwyHldAYEGkzDphqlDE+nfn1NBZulsqIKAbvNaVbobudoZIUxxC1H5DwguO6M/WxtgQEA0zxhWhaoBNxuDzxuN9xeXvDp5Ybbyx1tX0H/P+Y7fub9yrUA2tgQJVf0xjVcSwWlbQA2XruMC0J/AOLfpuYzbrjXHfDNVCWcI978r5w7mqKICKJ3mBN/FwLn577vbwD6DibVWscYY94stgbitGfQzqbrSiACEc/1zAo8j7xTAonDJ2zdHlj3ihAcnp4X/PDDe0whcb3PmczeOeHydMG8XBDiBIV/c+0d4DndHu4tHXm1cdPZfblV+iajN8vhmDpsUjA+6CzXD4ExZbY5IeeE/gR+eQPDqkmJ45TwdL3i06+f0Rp/fr1O+PTyCu8Ee8748O4dyrYCjYqKGD2u1xnzYuDpmxjj2zOopw9jGRSAbdXduCdFCTCLOpxDCxGT8//G3OwuCqYiHXf1/N3nfxMQNOXV6ee1kR3mYsUFAb///ff43//rn7B/vuPqgQ0JKg5VV3QLhBCIs0yTN6sIoGS1serw5z//infvLseerAQ2exMKxlHms+6E6o3goKLDB/VvHf/QQJgCcD3oAP1YxoB1vUrQzeMJlGVgVMP6YXvOAKCaAvPi8PQu4nINCC4AYCUwRA8vDq8vD/z66x2XOcEFQZxm3O/boEQPX5ZekQoeH35YoBBsa4HEgOQqWhTM14mMG6Ecbc8VvUlIl030YK8pTYT3rdPsI3I2xNT3TnO8vLxlrPd9sJdIXQRidEjRkVUB2KIG+nwVggLF/ssk0DqWRYfrdUYtDggBr583vNrM9MHhz79soyLlA/X1uYottp0eTjCNAZTg6ZlAUqs0MK2ZUrA0JUTzNlKtyLvR5ueEEJ01EeBC9PQ8oxVF2ylxC8FZVYay1XWtEKmYZs8umZMgbxXr6rDdK1Li+KCfWvceYSKf94L1sRMIsAC5L6jeO9R6HkwnEAwB4giS5J3LiAirUjF4VlYCWQneCa5PE+4O+PnnG7ZHtqoMJXTMiAsgHhLieJbaGu43+gS9fIbRxBu+++EKjX5sZL1SP8GZETsrR+frCNHjNRfIgwFk3tgpShwp2I/N6OiV5s1o1jVwdizuNYZmjzWj9Q1UaY7sg/kbVUFKMxfsXAB9oFXzUqrt1L2GGUSv0BxdzArSTFNuMR89F8x80+SD05QIJO55eGR1mnctGbU8UBt90bx3uK0Zz+9nvPxK/fnrR3pVxeSB5zSkdqx+KrzQg6vFXk2jn5EIAbnLdcLtdcW+FrRSudEHjifS7W2c4C2jMBmw05TXhqbWnCAgpogYIw1FhSACTfvD8MtSVTIdS0N0HnslFPx0mbCXivtjQ2sOk9HmpxTw8fMrpuuE/V7QoEhTorzW1SFR0yYmPSUD0wc2C0gzfahEaCz9eDyGlMib31yfCl3mAqOz08xbsK0Zf/7XVzPHFjwyATcnpEFPlSB5SoEs1qBwgR4dNLR3KKXi6YmJ4utLwfoo+PRxxbZmpOQMzANSEsAJk2KhlDiliJQik/ySEY3yv0we+bYPMIHsBYUXh2lhB1so2MCiKKo2FN0gSYDC5+uUW2vZycTZ94zaOM9T8Ai+QGTH5VkglhxPEwFMHzbMk0drglwb7hvXovu94OVlHUwNH90I5kWAFP1IKMg0aNhzeZPkijVEgSplbYtHqQ23m3XebdVAdIGiAj7C+QAniraRdRc9k/NqJvjXa0Kr/Pl3Hzwed4GgYJpn7Hb9Z16Tc8LEODqTXvMeU4rOAok4OQAH1eEjEkxWFqMVqLxDes7410+/AhH4l+9/RPcKEls7vO9gGLM5wxtQK+URpfHnNkROlXbFOUStlvgpgL0W1FIwhYCLSVxqqWjGCq9FsXUA65QEhe535ijRm8yLTQGTDfMLSquIKZEFlzNks+JL359rgWqwa6zYc4GrTGxwqm4DPb86JEbjWUgvvrRRiPHuABCDP4KkpmStX5aF7c5LsYBckWJEnBb4EAGcmQIdKGJxrUv4DnkoIMpKPQTYt4xaj3WxtYZt3xFStG59RxBfWsNtXeEUJtUm+/tx/4TrdcGUIg6pNNmZHIf8X9M2vEV68tjBhWmah4/Wm2RgJOy8n2+8P1sBnDvGWGsDBAEAbQXiFE6BWgpyXrGud9RSeG0t2NhkzJKmeSTI3aPw9DBBdw0mbzER4Kll5/OYWOgolvR+xQIQmkbTV5+MoRgDzl/hgyJEY0A3UwXYPl0qCysSCKSmRED79npDigkxMvap4rG4jIs1iGL+TL/AvLc3iamIIPmAavJUtZ91yVhnsTmbJ+x0axK2xj9feuJ48Sgohyl5paim37e+RnTgPcQJt23l+9WY9goADvCJc0MbpNL2obWKWrIxpQr94wItKh75MTJKg1fHvPoy0WRx9O0jyp3h4Oj/2vKKntycx2qPb5zjs2hWMKVdxrFeaat2jzASntPdtx82awxTaFXg3ZCXddaVdwGuHR2A//2HB6XFMsZyP2pTFLPbmKJHk4iaJqAVuErQH40slOD9WN+bdmBQj/tqaEFnv/V9sQ+RZmviUSjp9/Pt2cY0wYWIXCrW+wOPxw37tmK937Ft9kxa92Ps95Kg/1aKFWPrKHCLP/YlAOajhpPn8CleOh0OivdP7NCtNiePplGCKYXhW61Ka4E5hqFa6NJaHwJcKSNP7WAYcxnKtb0nsN695HoRpSntE4LdZQWBlVwbct3ZHXqgVROAFdu6IpeG6emK5+cLlmmCqOJxf0HJGU/XC+JywXy9YponVJVRPehj+9yp2PUw8jx0utwYSj/QU+GrA2Zs2MKmUTAQ0cFhbywidWbRlhtutztqVbx7vmCak+3JRrIZ+yjJCJSXByzLjOf371Dqv2KeIv7y8SN6c7RaFT//5Vf8b//3/4z/x//r/4s9Z/z+xw94ui64LBNZTmcgjF/31VjsR7P70NeWPnB5v8hsZbZyGlPRwYug7Z6FdD3A8T5qIbYuybE2qXDtGs227PDuDV785mCM5zBfE376/j2+/+4Jnz7fT80HbOzbNTpPm4x5SWStF5JScqm43TY81hUfPjxRjbGzCV0z3IEF7gAvVMB1H20vbPwWY/r2SX5x/GMDYeY/Q693eQujnpKY/u/OegKAMUbsQfen5IPDZfGYLx7z4pECRxwXGcH9dcOrrri9rHh3nbHMyTYIj8u0YF0z2yaPIIuDLU0BMXqkELCvD27oC7vU+eghMWAKimweCgzgO/VaEQKZT2sQlFZxeZqwXCas64rZAp++aHQj1H2jN46IQ8nsRBWSkJGQzFPDksJtK3jcyC7q98wnSiKgLCLR00gwzwm1RpTc8PqpQmvGfWuYfBp079glZwD29dD9l8IOS8vkRnfI++vGRyHCKuJ1RprTUeEUD6Cg7EbplYOqS0p7hQuCLffuelyQKyrMXgSqlDoBAF7xBgi94/i3swq+84KUDlbg9ti/CIRHcfsYT+LRDZh7pQkAmpCSq5aEEDDg84lTYULtTJLZFDEEgmetGn5Ao2jvj0ROVI1SfpzCNLES3LX4y0w2DT2znJ3b16tryTTc3o31FoLHvlsCLc0Yd9R0pxgRU8Dl3YXG5YESKAiZCGevhf58aiU7JxmA7IytVgqXn4cxb9QCCXUEsKsAVi6GD0x8AWAy9pU4JoG9eh7jNCqmPnrbLSqADO8BcWz9LM7BBY9f/vzKzT/THy4lj1oUcaK5pXPOOow2uCBIS7CAesd+zxBHUDtMwaRGHve1jA3Ie4fsAS29agt4r+a/1cNhDClw3wG7lNhHAcS9GXf9v/R2YzV62xvWxwuulwVPTzPu9wd+93TB+tjxeKxoNSP6ZvI4BrC39Q7nAz7++sI1qDhoZAVFARSTV7YGYxhgGCDTl+qYNK0Cy2XB5ZJwuU4nbz0F6m6BiUdrRlMv7Hanjaa0uSliZBV+mgPevbvg8rQwofJ8zmEC4nKYZ5daELwzo2h+X84Nn182bBvbMZfcbJwI2grkDETvEBIr57k0PEeHmID7jWtItG5tuO1m5mw0ew2HpBSshuXcm2JgABnvv1vMF65ge+xY7wX3RyZAmSJiECzTBa0qdgNQn+eI1oDJmxx+YWKfdwYre84IgWMyTlYtlWP8HPM/4Pl5MTYfT6qWisMwv7F1+TJRnpAC4uyxv+z0wVM2pZhSQGuUxM0xIQRPqUQTaBW00gbAzWdtpSYB6j6hNe4j93tBtsqTqdoQvMNsABYA3G87VmOw9uAXALbbHdmdmgAYEFJrGwBrKQRNd/VYFuDPHz9BmuA//e4n9MYRWhmoxyaYPA3ve97XfEPOipYrfBB8vm94XhLSWRtzWi67JANCOeNeywCcci3IW8O6F5RW8dgyCriH51yYrASP5AVTZBeyOJNRWk5suPu+IreM6OkFGANtEXZX3rBi6CtTx3+rJVS5HOckIiYRfwsSaFPzQyxkUEHhpzSYAH2d2a1Y0Fn23ontKeGNpNR5j+iPfa8XHgChnNZ5M5k/+aXhWM+ymUWXQrBzWDEYwKGW8H15NHB1D2pNfRzXnFIanKvG4uJ3Va2HP6l971lyFk2Ok2IChI1Ovjz4/PvfCV6cE5a+hANks+W9jPPWWim3085sLch5t/vkcLzTGhAIL3B9rGOdGZqcEdjyv13uU4xJp7Fiu99Qcra9Hcb2taRfFQqy0mplp7gYwijs9IOFKZzGxIZt24ZsSoQy75SsgFIqpkg582h0kCsUDd3eqio73H3FzsAx94e/3mnyDakfYPurWqKuJ1YT3rx+AK5fMOoI8obRsKk/vLN3mMPbSMn7gGSMMt6zitbomwVjtDVtyCUbg/nt+Xfbcv7d228Z3zmcU9K311BbQfQOMU3Htdhz74DXIfdrOHehPLPq1Wwazufx9cGEvIMkHIJ8T21AqR0wY7HiqxM+ow9f/cIdf1wBhNfuxcMJpXxSG6Qa87oqJmcFHG3mvXk6U0fvQhbFjOBgQFdfi6jEsfuAt+8nSeFgvX0bdBBMywwAKHm3P9ksXuSLV1rX2l68VTIhv1Q2fP0Vnabxt48kwGadTjvuJgboeZD5miFswiBcg0Toj1trGd5ezrNJC21v+txwZsMyM+4S845tFQAZVtkaIQ05mgE97MaqY311Imh5hTh2/nv//gOevnvGPEdsK1lwpYPSPiDOM1xIKAVQmNTVmXecAUmw51f/CkBkXLWvmlz0FXb8VGi03ws0InWwrnuHZoIuBcGbhK9L1k/NGgRA8h5xdphjQBDg9n/5Z8xB8XJ7xZozHuuOdWaB4uPrhj/84Z8QnMPz84Ln5yuul9lIHTTS79f5t46xFVjhzRnhRwzF+pIDz889g7XHMfYv+9xRt1ZANWCrxrbs8x5A02/Ln3vRoRNznp4X/OEPv8N/++NHrHuBlwqYj2x/t3OCFCMu1xm5FLy8PCDix5r+8rLi+emOEAL2XLCuG0IKmOcFU5wgALIUqJolTWvwA/j1X53jt45/aCCsbytZv04Kvn6lfv2aChqtiRqbxCNNDtPsEaNVRC26UTUGQFNs624t3CPWveDd04WSwuAhrowNapoDYnImZTRDSN+QosNubKBWKtIUMc8Bgoy2E+0M0SHFgOg9vI1M7yhZWDcmRhAdXjDX6xW32yupzNVOuyrun1ZWRlOvOgebMB731wxxTFr2zUy9j3gMkgXNuqPF5FH3glqtXXZTxDlhrhl5F6wl4/PnfTAUWhPUWkziZ9ULAZZJ0ARYloD54skIOD2XmCK1vU4gwgDKOUHemNTppG8qtQSsPPJW8e7dhH0jK6RXCvV8Qefjy+HSKdqVmz8rajTjLqUeQ0h4juIcShlqGgAEUdPEtuM0GucGuz4KdpNRqG1E/RRKqVi3AggZbq0JHq8rK8UiSNEDAdi3BlU/Fqlv7QUxRlwW+k0xCTGmnzJL6JRmgItiq5QSPF7J5OMmbp1H2zFf+t9CZGUeTrDedjgv2B8V8EyO98JAsNYGf0okRNji/v6SuQlVgqFxmixI9tbZpYNX7nSBDs4D3rNynaaI3//hGeoaHq933F4ycnlAxGFfHUQT0hzgvIxgzXuF8wox7wQnDo/7Bjjg9mmn3K0Cda3wQjYH1aiKZqCOCwRkHq9MqLx32B8Z82WCa0zmKC3KKLvJos1P4nx477AsV0wLg4LPn24ABI/bhjgH2wAK2jD3VKzrzq6kVk1UIbkiOofSFFve0bTCxwDxHj/+9IMFBHdLuPpTrASjSsW6bijtAR8Cgm1cZyPRkgtKoTw0hMB5vBeT9wqloTEgpoTHbYeoIE3RKkr94VnCI2TSOuehje2pb3UbYy3b/fr9H96hVsXzuxnzwoB4L9WAaQMnPeWY65pRiiBGRW3sSkrGniBnRdnJcenG+Lz3QI0e1xCRZo+n54RpYRAnTtAMuHBesOcykrXDW4cSeQGbZqgqHveNa5iy++inj2xgsW8FmjtbgQwH78QMWgVOHa7mZxdjGOzcUUgwz8Rq7InajM3pHfZW4JPD9WnB/bYieBY65oXXY72RBjuAbEsGmDEEXC4T5ikiWPEkeIecgafrgg/vLqi14fbKarcXh2gJY4phNPCAJSJjjnvSGkIIeHy+sbukF6QgCMZCi9FhvkRcLhHT3CU/h3F+Z3pY8R6PGztysYlKZJv53ZiWTnB9x6DdB4dWDt8YcZQvlHZUV88L5jk5EQHmmUF+Eo/HvUBn2HV2QPd4M9f0Q87Eqi/X0j/++hl/+XRDDILHtmPd2TUsl4Z5jnheEpbogQs9i9SqzLDPeewbUDwSAjzYzbWfr5O3zAVVA5FP1X0ANIUOwQp/1NY6iEm8+D1NAWmUnHWAIXpjgPRqupChNc/JpHAwMMxZcfDt8Ua6d2IwifNw3tNU2iQrvVD39cEknlVeY499AwAbN6ABjkZsp2STlfBmEpFW+KRK7f5blmCpyXcUw1C6tIbXdcP33z+jqqKqQmz9co0xTU8EtFekTvedCK2zZ2OS267ArBXiKrvhlYq85S9iEBtrQralDxECwfZYse7cnw4/QPNUKg1lLqPBS0eItVb4MOGxbygmDaud1SwCSv0q9j1jt+6rMqR61FA0pXRTAFyWhR0hHyvujw3rY2WBMNKM2AeP2+2Gl88vCC5gniO8s31vStj3Q0rZlJIVHMuyPU6lX+GbsSP4EkhQmN+sHmOyv/9bHffO7Kl+l996K53OAQSXJueGX2Xp/nuWnHcASrwx/kuBdw0xJNRKFv2XWdXXINfX3+3d1z+tStAhBW/G/Me45Xg2mbmxHtnp3R33Uw9W25kd8tuHAPCn+cE5QBnY6VX6G90gzx8zEu4DAGNRLdtYY5fdDjg7iDWkIsCylYpCJOaNpFWtyNrXXQBHEfEbR5fijgZBBvaygH5iQ3zjCCkipgkl78jbg81GVLFlxrpjXAptF5xjgzQAtv6yQ2k/Na8NQF9n+9ruMIxEv3HUUpF32sJc0oRlWqAq2Cu9ovt35cKO6T2OK3Bv5kNnxBGo6Kb3BC5CjINcQHZhh410/KyUwrzoNJ/IunRoTk3B1P3PAm1T1g3vv/sO83JBDJGNxkQsDlQE5zFNE/MA8WCaZUCYfVaXWKoeudbIgX5jayDri15+VY2L2dnNX7zJeQ/X/JDZySgq0IKjNTOFl64yYi7Y75M3FnAKAR+eLvhf/vATXl9f8PQ/FqyfuHY81g17Lnj37j3ev3s3VFvBk5AyRYcNgm29/8a++C1Qy4a8AnCW5xoA1lnJb1//rQ8+ftaBr6++9rxG4+zJ9i3MhSzUUuuISeZ5wj///nv88ON3+G9//sQYwJEVraIIwnEQ0oRaFZdlxr5VoAqWacLtseL19YaX1wkf3r+DCL1DnYpJ7Hu3WcYm7Fhc0ar/tmfpbxz/0EDYV0WlXlhTDM+Ag1rJRZ2rKN4APmlymBKQoiJN9AILnhXs/joXCDApOHhfbyuaAs+XBXAOy7tkFHzTUlvFjqa4gKIOlo1zHmKtmEP08I4bYeu038AHXBu78vRO2FWrATEBl6d5VNWDj1jXO1rJ1NFvpBeurzsNpD3grA0wbDArHHwS3D498LjnryaBOIGLDnEKCMmTpVb4on0/KoLTJSDvdbBHeCiTt8INtev8vXPItSJMipCueH6XrJMVA9I4RfjooVpRc7WFmuCACw5pihYM0BDwLBnw0WFdM3LuFQVAC06rxZur++Kf7dznABYrmvSSwbyimVRtwuUaUSqwv+7jozr7aV4C3r+f0P2p8l6xd58CkOGw7oppdvj0csd0+UBD8epxvzdsa6ESUhlQb7sCjtT9voh/axMI0WNeIn2PDEgkWNCYXPbspk8VoRdT3liZy7kYWHFspiKCkMiQidYG2o2ArKDtB0Nj3wuTMmMDUrrWNzAFlH5NZHYwqPQxocvUyOqqcD7gxx+fKfe1zS/nFUCBwGO+XNFaw76Rdg0UzHMClOytvGcWHR0NP4GKOEeEFBAnshnEOTT9jE+/3qDasG0WINv+TzNv6+YZGVDs2boiTgHbmrGXDIjSQy6zkcbjdUWxToMCmPcATXn3vQx6d84F1+cZu7jhAVK1IQFIc4QLMoALgJVhglwONZexB8UO9qWAaX7PDmoiKLlgWWZcny7GTFWs68bKmlSseaMDmVUDO0MkWwWz5IJ94ybug8e0BEwKxL1gvbNRhNyA5TqPamvODR9/Xa2DqDHztJvosrpYS0aaFgsCCaalicxR5wVPTzNKrXjdFZ+3B5zLCBFIKaJoxKQw1h7X9tIUtW1MnC8X5FytU6R1SBRAzRIldJZhVWxbRZrCIUOtOtiW4tgZc18rWtVR/aQhtQUZjV57ORdsW8HtsdEzJZMdlndu5NE7Mo6qjanocb0mXC8J2VgVwcDqafaojf5y3eydMkBF2QvgA6IP5p0i2NeCGHcsF3azujyzayt7GWaEEEfb8DHnDbzqhJLWHPQOCyI88t5wv+/Y9x1agcnYzt2fzYlDCgFbqQhEPEehwQr3+Py6ssObZDgBm01Y0B2CIHkZtP680z/FGxOO8h7+t1TFvufhjzfPZLquqmjOgFHz7BQBnp923CXh5f7Av/38M/75+w9g5ZmeNh4C/EZxsNTeKILXknODd9bKG0Lfim50DIKiF3/BPJiIXONeH4o///IJL68P5FZQW0WyOXldZrQPTwjvLkPWsuWMJNyL3z0J4v0Zey6UA8fI+9tZLSLobd+rjWkZP4OZF5tvTGdUFSbGw1MHVu/Rg8XYj23f0VnW3ryGyMw42IQEFfUN0AUcXcb4c6DWglq4lrhgwE0hWHyWbMI6QA6gQoSBm1AW0SAIsNY1vXNk42dRWk85sNRwDHMBQnqPvcF82Rq0FbS8MYDuRShVND0yqmpMmF9vGb//5wSIILdm5vDsfOy6h5qxq7thL/f6DBRFnC+WOB5BJuUa1SAGoHf5PLOiFByr2hpcjON6utxDG/flUjh22KG2IReTgri3/KPWTt533zr68zJg7RxO9Pl+jJkGeG9NlwqlXuYZiYXM/fW+sgPpfHjOdZsMVQzmSJQKuIb2jcSrflE06ucx+EkDmDbA97ev7vT9Rx7wBgD7Rh7nXMC7aUaUYqwSwboLPcrsvYMJU6uZjiuCC1CvbKpgLMQB2P3GuVUAO5i0B20mdfaYh6eNwIUIdRHVOWgrcKCnknOUkfajtdaN1wiUwtZ3Hc5g/Yb8tbtlN8QBCCZ9lG/iMzoSra89wizroYpBuzVN//psMLWHM+9gmm5jFND6a91p7euyvu6v1f36vsW2UsVg2I6fiZoyRIbtizNSwVgbBagQZD0+5zItcCFiXx94PFbrkN15Rx6wxjTOAdH2JIIvhPP3ShZdP8foKiYoRDoj+gQqnMC8ZgBarY0NbGzs5trzrhMb0PJMAAbUHdcdY7JGCcdDPKTg7vBARO8ECZz9/9gRtY/9dMQO4NrhHBn0IrZ2gZeRG3C9TJiWCX4lIFX2Bxv1eG8ekArvI1Ka4OMEkQDy2my9rYo2wM9jqvZ0rg/l0zb01XrgRsFKUFThlIU979z4POc9HLjeu8pYxLvOmKuD2cSv4DfUWgw0B9iZ3bqSasPzZcH3H97hw7sn/PzpMwBg2zP++Mc/489//gVP16fBmjo/f95/eqB+fah9L9/zBrRybArA+ACAnMkfbz+CHtzfXpGOUXS6j3peIt/e3T1XeGeqNVszeiFLtTN++Z4ffvwR//IfP+Hj6x2fbwWlNlyXi/mbb2g1s3jjBCmyQ/DHT5+gStKJcxWtci8MPsDNBFK5Lzb0LqQ5Zxrp2x/G7X9rl+DxDw2EDVCrB7g2tg6g4PDpKsWMas8sdA9cnqJ1RurdpsQMbW3AQeBCghOHXDNqqexwFlkZv68bXPQIljQ4ObqyjEMAYS2QIE8xtkAhMwpQVgztbdzE2I1IfPcmEQtyHYjaqJl9BwCNMqFrxL5V1Nywl4xtzyiOBvM+ivkTiE0KVnX2vX0VkIgnADItEcHkaDVnwNGHLUQm6j4ItAi8p99XM2N7Lw7SGmnE2gBxCIFSPUWFuoptb0NzXjIlBBERtRZIZkcKgJX+cyADC0K8eTe1qtj2YkGKIAQxNpCcbz/wZnE4yPcABgh2DqabJT0QJgXXywXP1wmfXlbs1mUHjn5rDg7Xp4jrU8I00/uL1US2yg2ebAjvHbQB12uEeMFP//SBgFvjggolUw9CA28Lj4FaoM4NyaDzASEktJahlR3sLtcJ88IudnFhe/T2qNh3RagOMUV4B8SJQU7eM57eLVhvD/zpz5+RAqn/tTbzSuMilyJ9lEI46ObduLVYpbfkasEXN+d9y2bQLhw3FkS2WrmJw0EkIE0zYqLEdr5O2NYdMZAJI44sn6YVew5wvUlAdAzya0XOGWlKCD6gZEXdwaSmVCAQUIVUVv5EECfKX/a94OXTAxA1/zyCjL3D4pBb1AY3MRGvpWGtBVvOKJXyJ94jj33N2LeM9bYjRIdpjhAnePdhRowe9/uOz5/v2NYMJgYEpqDA9emCx32jN18l4AbAgjwcXW6UXkpsSlAgQvlcmBy8TjwXsPNhNfZITAHLdUKxoKpptvFsFG+VcT41H4lZrfVkRGBTwoDeXmDY1gxx3WhU8PqyI2/0FpsXsllU2WSi5AIFmVradpRc8OH5ii1vWDf6k83XCPWCy2UG1owtU4YZI1vO79sOESXTKAimKWBd2cgjeA9UMvi8gVnZOpXBgR0+TWIZg0OKnoUN5frBe8x1474V1MxONQoMhhjnQqD56crq+/rI2NcGUbI5eyWgFpwakIiBaZQFTing6UrAL3dJsslysyVOIpQCpuQxL0BpiZ2BVVAKgzgXFNu+I02zdUbinN1zBtQhOAZwzjnrUkhPPSZyVq0WQUwRrz9/xl9+ecHvf/8eMXjsm2MArdx7XGvQVo2B4xAAMm2c+cRoB4/IoF3XbF2irELpOG971+WSK5NEA7Fk7Jl83qpAua8MxIyRo8o90gkgkWM4bxVlJqgJP+EyJfzrL7/ih3dXwFFuGyYCaK4egK93/mimoTiAAMcLU3XIBWgIR0LWY4qeTHfkDwfYTxm6gd/qUEFfKgDQx4aYIq7LhEvLWLNAsSMmwfV6gY8m7XaJXcoMMCpNId5juSz87CjY9g0CYyj6wPVo3w1sALQShELdAUmAdb7s7Opaipl/992w2xdw/es+hETbJvjo4S0GyHlDLQWtHrLCFLk2l1KRrUEQAIQRsZtM0fvRfbAZoMXiSOCe5h2Kf4LmV3y+3QGhJymbVFQLhMkW2Mz3Lmdgd+d26YD4B6oCuWYmbFaEcz3B6R12vbGkbefvOUKcD38uAGOMnmO6dvocsp9PKYMVB7QRXChV0TIZY07YZIIqAUFIR0Hzt6r2pVV23SontpSdGNeRAklxLNfDFPvb9ILjk7VLWP/6cd82LNPEgp2xJMTWt64wWB/rb77fhwm32wuqTpgjGZXOwMcDSCdTrpj0qzdIqQbI9OISYD49f/OseZBJ9AUzxtaV7smpCgQfME8ztBYEOXzj0Mgs7msEwYHesdcgOht/zjsEJ/COwECt9PITF77C3c6JfRYHDQmoijU3xJQgIUElAJ5WBU08IaS2k9tvsXzTxkZW6CoDY3MZGBNCHIVN7kPBgLzy1XgjOMK53FoZeUyt56YJduedIPqI6CNKyXjdjuffmWnc3QJifALKjfYQjrLQqhjG6iPEsefaQbF+EAjrbNXDFF0NJIFWSNne3Fvn5tERdt3JBg2BIMhWKn2Po3sDDjYAnWQ1eY84mSyyWJG3NGxZcd8VuUXA7lW/JU2MAGqhe947aMjDSz7GwOi4SWN/540BC66z27ZhmljMingr7e1j7/z8nLN9xnKJrShQsknyI1rbz1ibkQX4fWuuQK6Yk0fw3kzQ25sxHuLBqjsDyiIsDDh923ygFe4DooqyrWjKPanWihA8ko+YU8I8TZinCTEmm5NHF8LOXn4z9M4gWP9jaX2fy6qAbUm2JpoU3DZxEeNa296ujszjUhuccI/ZchvyZ9ga1z/JizUNUBIBVCz2axVTivjw7gnPT1ekEFBaxfvnK15vd9zX9Q1I1deTbee9TumKdf38Tbz6PFX1y4VEua8wZGjQKpbS2PPq68SpcPlVFUC//hF//O2V9uVRMCeHiw+QIfUWBB8RgzX2gsClC65TwH/8w+/wb3/8H1i3Ddn0rQpAXCTDtFnjBCMOhRgwpYSmivuq+PT5FaUqfvfT+5GjQQ+/1YMZ3C1BGqqvg333t45/bCCM+QuPM+4kMN8wWGUOfXUdAe80iaGpCqfNkvMOKwugHgI/2AuttVE9Y6cDTvySK2q2CijMoM0qpGq85F6lEQSIbZIuCqYoZHzZxXjHDn8iDCqdSTOdd9j3YgmZIPoEARfodV3ZdcHPWK6Uj6iysxm9Q4A99xvVMHWD/F67kc5mYuXfR3ZJismzO5gTJkFgcAIBtm1n0mnm2KoOMQbsmWyM0qkvFmR6R9mUCM0VfUxIxliIluyXSs8M5wVOghnIEsWWau2gVTFNHtBqHeFOHXy8YK+sdPQJ3Rf+L6fy8bMD8j6/ZsgfGseIiEPOgnXj50ehf1OICc/XCaVUXC4ez++TdRQlUOY8J2RKDDCC+dw8PU9kaYGtt0tp+MufXyGgDErfcOl7aKBojSw5bQrxrKuFKWG5TpjmCOe5Hq93vl6bwjkFnKKhjEBChF5A67rh9tiBhkG9p6TPNkFllSkhYkoR2/7WyDjv7ChYa8NymQBUMgGroDWP5hpi4BjYtgxRzj/ngGlhR6Bt3ZDmiMe9m9oq5iXger3COcH99oDeqxkqRiyXCbUU3G93+sldZjg4+ACUrpfvvj25wgeyXVSBsu/YdwLZBIHL2FSYKFJmAwsS2N0Vo2NezdYB6MSIaGo+CyqANGOwFQKPgXMofmHa773DvmaazK8M4NbHjhiNeSSdpn6AwPy7wHtFNN8mF91B9QegpeLx2GwNuNoe2RCCR4gJ244RyHCcy2BxNlX4Pmf7BNGeJorJaClNK6VintMIMujvdQZJG73YzOuGrKYdOxQap5EIBxdRasZ9z5AgSKkgRquuNYEYAFnQRgVze+y8p8HBXSJq6SC5+ac4oOx1+Dmoa/AOSMGZ2T+BitZ47ZTtkPUyzRPuW8HjUdh5JmIk7z44OCHzoynnYWtK2WgWtMw13eJaeKcQ19iNEZSruVMV2DvB1hpSDFjmCVUn/OXnB1xHwtC9OFhxbGCnW97jNNiXsGeQs3k+5cL1Uwq0GWM4RmhrCNGTcebI0Ko1Y3/hnP7pd+8Rksevv97IUrTOQ614VrYLCzdo3H/ujxUunQMQRS5qa1gZjJHeYdJ7Xgu9qTjAmtBnMU1fdMVrgkZEBs5Msdn+vI7Azjk31r19z/QO2Sr+5V++x+31gVzfGUPSZretqaPTkZDp1UEuHwRibCl60Fl4YTL8aM04ukSx6Y52MnZXAT68X1DwHXwQfHx5QV3LmMMN7LJWNJMZ2goEEaITvHi0HEcxp4M2EDmYuZ5d76Y22foj8C4RjKmFlW17j4hgWi6YlgvBppPnD+BsnT1teArspY69VIxd0lPT4bliiXEz+YF0pjIHADs7qh73/HwYiOiMMVOFjESqCQ/fO4GgxWc8LxXFGJIpRaAxYC6l4rHuIwnuyVdf8wE2vrg9VrRWsa4rJb3eY3XOjNwFNVd2KDudpoIsB+/DF92mnMkKbVk078BWD7bAm0t9c+mHNNl7VrH3PY8GRsDXMj0nJmHqAF071tXOoBeT7wGslOfCtfMMEnz5mWyScSTSXybTf+0otWLPBNi6uXRKOkD4bd9+k20AkxWpArk2oGaU9jbJpeyojM8GzAqjA+HoFEYZBeO/dXQZHZSsjGYFgFr1zTogcsTZYk17um9nq7QDQGMzAl4rDf19CCMJ88FbbHNAXp1FOjpPNq4DAA556Ina0gH1tu2QLdt88fAumMdrgwRu9gpBVkFRFsSiI+MQIC8gKf2TpZG9og4QNKBxrYSQ4ey0nrrjKVrLw0iejbqGrOL0PO33jeV9r6coVXUUD7yfEcMTUF/HWjrGu+qwfFF0ptLXuThZxWLnyEIcm/joKFZ/azg4R0sF74CQrO+kEEZ9Nq9RL83Ys2/fndUhpoRpmlHaEbOVKmShV4PsxEByKzapvPWmO19LUzJcIUd82plVqo1Fbu0dUxUpRa5DnvmEntiSqrB8jbFLz1cAIDggn0hF3RPM+xnoQJR3fKq92Nq6+uDtfaD8ORLIVz6DLqHsxQHK5VnAL7UhV2Ar9HOuxlTVVg0sDliWBctlptewD5hmNiYJzllHw3ac/5foMXpRot8IjHpUtdf3oVwrAZXj9Tpyj46m9fXVO4fmeE+cY/HlArGGGafiQ3+PxSBqTM6iDdFM7Lx3ePd0xe9+/A7//Y9/ou9Xq/j+h+/ok2l2BaqMb2oFcl+L29sGWn/XcQL/mO/yefc84vw659zRLfmvHO2Eq9CYvsMixz2LPiBJgFNvRSPeF+88UkiAClQ8xMDin376Hn/4px/wcrvj42shRmCsTmkOThvUukhOcwLkQfkx7zwejwKRFarvMU3siNwbCQLEIpZ5hgAWG1MeqfK3rxf4RwfCvnUohgSpJ330myIjJyWPmDyenxPu95UJTS1jUvdqUauAOneSinUQjIsA22irIY5sj960jI21t92uuZmRaIMPALxDvpMavywTglNUEPxwkcBbCASlDnaZydhyZnDvuKBBgZwzoqeZsfcTtDbUvVr3nd616GAEqOrwT9pW+kv44MmcMJNlp978tSi5a81WE23wwWPfaZgagqdZtAXNKfJz2ehHAKXBOsRZtx+H+XLBY1vhAp9HDAFVG/KDAdaE6XiU9izFFvsQaCRbypmWymDZmVyk+86MhfobMLeti988uuREaDFiZqFkba0bJ16pipACnq8z5pnG0ikCy9w7t7Aa7gHU6nC5BqhSWgsRLHPAfS3Daw2ODJB9eys54WHBQx/cCvrxgMkbu21ESiSUAa+MLqFtbAIQS3CEiQq7TYXh9+SCYLuX0eQBgmFGrk1xv6/2mQdYQsDWvkN1GFKOaktzKFnhg2JeEsRe4cR8yKzqWjK7UC1PcWzMtTHIDtHjcp0Rp0CplqOB8LJckOZI8NYaGvgr5/l637GvGT44hChm1EwQtmqBiOLp/YzXlwdi8mirvIkB3BjuDVppIr5thc9QMZgAzvWEhYbBjeiPBRiKfav0Aur3x1lb4FbgQ4I4h+v1gk12lOihFShbhQucK96qy20Aowb6MBocCXJrDeWRkbcMtQ59bVT7BT4GLFeHpmSnlcrqaEgB6yODDd3YtIMDRQ9Gj22mHfDsTLURQNk9oLzNY17oDyECKw7Qx08BYy+sqAUM7sWhVIVmSoLnqaJMlZLAShBMHVDRIFJRg8O6cexcn2ZEJ6hZ4a1DI1qDF67RVSh3FC9k+xobbLpEpMSAIOeCnBmAMkjUUVUUYTEgJSbFAsW+72MtL7Xhcc94/bQa001RMkxix3bhBOPIXuveSN18vDYy7zZtaOqQUsT1mlFKB5Z6Mss1z3mBgycAsSqmKYJhD+di2ekZkjNZxwAQ/ATA0cvLuouKrQM+CHIp2Pc2/C8+fbrjdrubFHHCMs0ombLALofqS5P3bsz92pQV4L1i38ju7Y00YjBpniUQxcBkiMCZv5cP3S+lB+PC69look98p7PlOFfjTMlu75gYuXHj8RBcpouZ8VLO2QGwvmd2v5++0pKdAgOROr2/UcLRmIwCYSTMsPeLYwdLtfd6L/j+3TuwWyEwTdFka3zu14XdoVN0NMyPE4J/glY+JydHM5UOwjcY8GLVEXoGRQaSIqh770opw4+rg88d0/56k+vXidOa/rcP59jtuHRfH+cRQoTWPEDavi5++2vJFgjeQfMpufgCCII4Ao+AsT35bJ2jlDh4BwFtHmJwuFhTmPE5ISGmGeu28meWRHaW3b6zC3SaJnRPr36EEHB9ejqKEeiAxTE+a6vGCiJ7uorAoQ5j3m4E3eWkvYjapAG1WKHi+NLudeTdsQ+9ZcRwzpRTrCUCk8Ri7L+lqDWlYIyarZEHP+sLeaBgFLu6NUGX1HKPMymjyTS3PWPfdtSyG9Pw8NCrtY6urjzfXpjoiWqD9xNKplcOzfq/Trz7HFVVW0OqfZYDwKYl9Deyxgv4AnBg+2pQRkbQUFUQQwcj1cyw+fIBOPa5rA0lb1CT/HXfLYC+jmJrTD9zbfQ1G4Ul9GfRWeXcf0s7lCnHudpnjByScZG6zoRp9jkV4hu8C8OPCFWhrSKIYArOYi1ArRDd72oUoICNmfrPRDpJgEzDLvHqz91KEIztan4Dsnw5TZsq5XonAKvfC+8viE7hsMJHj1xlrL3n13EMfsH8saPLfbkXGvtYrPvfeP+3E90BfojYnt5BHD5L3qcudT/ep3bflolKiFo2IGeEpthN5SFomIKe7g3BgjU7SK9N2R3Z9UEgEgqVhOoCHgW2R3MsBufwJB7BJ5ufDiGyc2spFVvJ8MnTB9OYpFy3aPXwZeOJLjXtf6+V1/h43OBsj3A+jL3FOa4b3h3yegWM8BFMHWHX5DqYdBoHrY3YqUHw8dNnQKlKmlNCDB7ff/cBMSbMlydMczSriIRpmQ3sw5u1r/s3fvVcT3/vcegJx33zHE8faSAYmbvn4kcHd7zzSNMM7wPZqMrx70NA9LQ9EsCsTIwRWyu0lMGA9M7DtYqny4KffvgO//Iffo9/+ukH/Nd//ROWZcbHTy/Y94xk+8RaWTUV2z9E/yeAMBzX3zuXutjBSvnidecb9fXNfXMb7R+lVbQB3x/HuykhOa7DnBGgOiM4Av/VisAz3znPEz58+IB3T3/B7fEJtYEM3GZkJRcgbkVrBUE8Yor49OkVl2VB8N4KQIr7Y8M8p3H/a93hfMA8XZjTxmhNrgiG/WZryy+Of2ggzDmgfVmQs2fcn7n3BJNidKzoeuD5KeL6fkKaAnLe8fo520LpjpbawYLoSN3uWRIG9ACOa5LzgnXbB2oaYkBwHY7mCYUkCBO9tnz00NxGsj2Cawtimpn39YCkmV9KzhXLTAaQmtY9mmdBqxWP2wbSNVlxbM3aXFvgum6Z4IZ4+z4xMIRtfTECjc5I6dfLFqUCmmifvRwEZLGFEBCLx7pmAOzORzDF9PBeAAfzjnKH95czI+29a+m/6HCFfnu6xPWoHqUUESOTu83kOHZSAwAdkcmXY+SbA6p/GaDi0M7noWpVXYKiXoDLEuEigZg5ecTokIuh/cJgbl7IckJzQHW4W1dO+sERqHHW1fNxz4ZyH3cX6MAqKx/OjJBVFTBKL0Q4+ataZcXayFrLch9NrtqTyOiRpmiJueL18wPrI2PbTXpiG2n3wujSgi6x6nTTEdwp7LkfydAxdhQhOczXifLilUCCoCdGHvBkrbjYUHMjoKkwjy/zcrDdt1Wapy7XCfNlHjJPQHG5zHi8rlBU1MYgjlR/dq+B6yAwO7mpKqY5MbiHQ0MdHhyUZ8qYJ07EgvIjkJvnhOUyIUWPVoH73TY2hVXKYb51rIiFEDDNHvueSf1dImppuD5fsK27VcDZ6U68YJ4DQmCn1WwdEDvwC0t2ffBI0eOXj3fsGxO8kJKdI+99iDSVpyeE4Pa6E9wtamap9DrL2Ux7Hb35vBeICtrO51K2BjQgTQEhwgLBilrJ9kmJoIf3nqwuoRG6r0w2G4SAYlVU3xAdk6y8s6NqyQXbxuyp+3OxKq9QoTkypdQV3/9gfkouIG8VwQX6mlnSKQJWgwS895EeiSl5hCjY9oKcFTmTeZEmZ/myWFdMtbVYaXxvbMlmnkn7VrDeM7aVTJpaK7Bb1V8VAg9nnnudRRSM4VVMVqatYtsrAEreYqLvGJPmY25xC9GxBtaqmPp+Juz22pRMxFY7i8eNvQnOGI6W4VQF7ncm5M55qLBzK32iHPY9Y5lnrOtq0lBn1U/KgtUFM1FmA5icK/a1oGxd7MTuozF6THOgz0lrcPXwMWi2Vzrv4AK/Y0oRQTwqGlIKdn427xUoSoPkaPL3dVu5zzuPabli/fQZj/2BRyv48HTBZZ7IkFGyp7uvFItCEV2eQrkggwbnwwAWelLQq8BjH2B5Fb6D353d0oAYAj48P2GKAff1gdqqVcyBZZ7w/fOCd1PAHNmdMvh53JMOPJNt4o/A1O51D+pCCECptD7YdybL7u06qWaIHr2HS3EkN30fK2/8mBSSLSnGwVj48ugFPufZAbazGfh8TgCD67KftxutdyZj7uUUcb8ZqBZ/has35G3jeiqC5jsARwaCgA1ifGDzmgOAUyQvkBQQZCEjAYf1hfNugNmMUbxJ/wWXi8c8L4iBDPfu8XMAW0xOS+lsYrXxzMqZ7hml7m/8oXoirk2HpPIMhPV4oK8Vx6fyqPUAiPr19TbxZ18lArACqBjzyZ6HJdxwejg2GbgApbdrdw0RkKXePytYoede6ZGkrQwwiExZj23buPcYaESmrElRbc2kN1OGoA7gXdupq6EqjhibY7ffwaY9YSTy1xSDrSEGHiscRHR4YpP9xRzBG2ur4kBselKbbK+k/xqvT8c8PMa0yOE1TBziBLz28e0JlrUOhKmis+HOXS1pCk8GTGtqgNoBFIvgDRgmxuB1xtTUnvA6h2hjuolHqd6kdl2ybTnIKY3tAKXY/tYDbBWTjpvnTtOGdbsBJwZJt1ToI06Ee0tp7BhKVpyDuAAvOmJJw0/eAhDn4wxgnNg3AEbDK2fgXbPrcVaw5kb/9yW7f8/RQUAfKNWuZnavqubtSIa3f6OqZDdYLxX1C8ZNGOtbN5oPPF3Lq/r+4sXDyyHjarWhoUuFK5qNfYc+d4ypqAKRt2n8l4Al+vmbrx3XygAXIsR55gYAqnoSE0rfCwpgTXcUVDuod6Yg8gZSWkMgZTMq5GoFw4z7Y8U9Obx/fo80JSzzhY00ugdqiEgxwkkzeSzZ0LnVry/gq+uxdfWvEH60I2G2f5y7Sfa1RUAWUwgRk3NoSlBLBdDd9uTgkVwcHSPO+6MPHlob7QechzSPCMFyWfDhwwc8vXuH/5zIVOIaziKbCA3ja2ODrujqAOAxzuz8PN2bn335bEtptoeEAXQzfpGRK/wt9m+fqwMmG8vlt0plVNE523+asDmSF8Cp5ZF1B/IDu9L+6cOHd3j/7gl//uUT3F7RqvlFiwDew/kJkzg8N1h83jvX89u3reB+3/B8XTDPCbUUrNvdJMBhMBizWS602si8/TuOf2ggzEsPqO0HevqDDoY4W/Spo50mgi91L5TOxIA0JTOHpIdITzB7Yq9Gyc8mMSy1a9ZZqeJmxiQWMAqiJxBRa6O8wzfSY1tDSgkxhOGZIs6hFqB6+m85L3CNwVreC+VYoxrI652WCKwZ0GR0+4p9vaPkivWRjRnQxoYhoFxpt2CO8iBlh0ERG3Qy9pVxS7UbRvNm03+iIIVkbC0a3GkESiGS7oNHrfpmY4+RlYVincycMfRCFITGpI7n0Maz6wBQbxaw5zqeCZRmkDFGtEYZ6J7ZLRJ6VNiavA0qf2sv7utM356+nD7cmI+qfIgBcXKQSPDEJ3as2DcGyAwiBWmhfCSvDeoUM/wAWkpuiIHPYXtkPB7ZfEC++G4HeB8Bb/4Y1nWlCpPQXNjmft8LsjZeioFQbiQIDMbYIjmwG5jqkCnue6G3Um5w3gLikwGmOPrG9PvHQNhBmx/Sj7eHQlGNfUKWkPMO+4OSIh8SYiK650NASA56K7a7AWzoYAmTVXLORp/zZcY0T3yFAo/7HbUVKBogDeIaPGTIRZp5ggRHmdu0BKQpYF4CpjlivZMdCRIY7Z6TGdjncatHZy3vHa5PM3786R1yLvj1LzebLz0uMznhTk9AwBgy1g0wxkAZ9MyBt2/7KYnNUOX4IZuo2R8/1jOBSZbVcR5MAZ8+vpC9VBuKdRuMV35nzp3VGtBBnm0r7OD42Bjk14pdYV57BIZKKSPgoQSEXcLSEg1oIYg+XzyCpxdWNv8e5zHk1Tk3bFsbkgb6PXW2LpC3ivuN3Wudc5iXgDlRlOobAOcQnB8yOoViXyvKVpC3huwagvdYlvR/kvfvsJZt21Uw3Pp4zDnX2ntXnce178Xg/5OQjJAwSMiBJRICGwggInAAESKwBIEtbIGAxJYsWzgASwYCIyQjEDgnswmAwIllEkgcIYSwr+/jnFO1915rzvHqf9D6GHOuXXXOPffy6Zesf0rnVNXe6zEf49F76623hnXbmPQJ0I0T6DrpjWFkDLVSUXKzdubuMGfhqWOVvZhmXs2NrAy7j9ul0CTEgoXa9jbWPkGcJdkUwPejNSSXzODe0z2yJyvTFPD8SNp4ECYBAWyDa6afk7c8HJUIsHR2D1s9SzU9pBAYrOrOthKhgPPlYm6mqmas4bCuCfMSqTsZAtm+xsyMrsJ7QM05VDyFhVUU8A71yhuXU0UuLPqIayhFcfYO89nDgayMtBVcrwnblpmYjiIQ5wRaxRwiroELfy00HHGerbJeGHBe1g3eVYQ4wUOxXgqmKUArkDe2x+VSRptOaXVnicHBabe654R+ue90KsKIIW6KIiC4qA5OyWQ57ivzRJ2M0xKtKknm5DJNuD/NOMeI4L0JPu+Fqt5GmXNCbQUDIHMECrvDmqKhNrafFGvVpgaejrGhHXxBZ77s86ZUBYrFN33cwtqjD6wgCFmdnWXTFz+x82ZC1lmit8wYoDPn7TrNZVAEox1bhA6CnTlFx70NEMd2jEZWHlueCa47kSE/QOaQMWJs2nV3aoHV3gJFmAdYpNSIk0A2Ks/RWJNwmCx2mOKJRS3o4b0GQBko1Rl8djFoSpfX65Zww1TRPTDt+kxMqHumtuvbHAKvw4g6BLXj2FuU3glqLPHpx0u2jZ3Je1sjCfjpMJjoQFsppm1rr3cicOYodb1ekHMez38HM/ZPzdZ624Gq/v29uKQGCB3nmoODONNYG8msAeONz2PoFjnc3IhRRLDz8M6hehPeVx2adXvBt0Ez25Z98KYlt3eAVNVRBOkFvJcdB9Gzrb/rhzIJ7YDagTFpAHBnKLGlrrP8TGNJFdBdzLwTONUCjH1d6muCUIvM2q+Yi7y/bZf3RAYzSsUBjt0bDjqEqMXGwrhGBeAJHPR1knEIz6mZhqN3vR10H2Oc47ZX3awTuAF/O+DknUPTQ9uktZ6pkrMmsrd3i63Fn3eMBN9ix72YCQNRxzAFYGtWCGy3dwHqPCrE9vgK6UW5Y8irCi8Kahvsx2QabdrU3KLtboplGkKhfUVFVTWJmEJzDi9jXOc1Y55mOOdHHlnV2G6wriOTsOkyEtHvrE0AiHEe+1yndR2ZQwRwxTSLMcCFeT4QH4TMY8hefKdJnFhBSDHFgEvJECeY54XX7hymaRpFIZ5PxDRNJtNQWYwyMOrzjgHQvATBbFwf18K+7Kp08OoFS0pgeahHnGaIc9jShmDt/knSmLcxRMCTCNIHSmfMcZqL7UWs4k/ThA8//ABwHufzyVhzBUOjQVnYDE7B3a7i/exG7m2c77fXdly6B0HHdTZ7nxyGR1QW2D/3kDEkx42+Ueh5cYzYov8nNHeKzv4MDtE1+HJBzgL1M16/esDrV68wha9jlc2KRdHQeUDgIVFwOgMfW/HgD7/xKUQ68YIDszbF+XSGQHFdn5ELZZU6HhC8RxFj7P3/AxD2DqjxIl7w1g5YG8Vd1ZOhlLO520WKWs/LjG1byb6yRQtKzZcQHFLREZCLE+Rc4STuVYuuJ9CZCK2Zuw6ranGmM1x3n5nM1U8BtFyQEyvVpVSEyAU/F+p8NdOjqJUIbD+cd6b34qwlJePpcR2tJ32985assiLFQK3VQlHvOQy7+m6Lyj+telCFVu6mW1Iq2TxQBxFvYrBcaIIFBq0pFkOkvacDpyrZJ9uWqSvgrDo7qjow0X+MHnQf2G7lPIX+cqVVPF/Tg3pWNoA6klTqW/XkV+AK6xpjtOiAufdA7R2wvYe3fcPsf/KmxoktYC7omGjiqU3EgFGNSeERJo84s0V23TIUglysxa5UJHahkzm03TpJ9QHdF9kQInvOwfY8FaBtha2+9zOgZP1VC/2nwPvvooM39giU7UkbFZugAM53xiBCxuObbC1PZDY5ZRIanD0PRyCPDIQJcWJb27bmce57EmaBqt3H7i4mYOvYw8NsoDIdP6iH0UE1q1iCyZKi3YBR1do3nfH+uZGycqXabH5Y+6eJBYhachYcchJMU8QUZ9SpopXrAMHF9XlN4LvZ/O9BZ29Pdk7w8OqEzz59PgCBuymFqunpmHGA7zpDvt9LYDnN2K7JdIcO9P8+f22eN+2AByskog3OK4CK7ZoMvWaVr9/nY3XVB0GIgklZsXUiWE4Ub8/fItiVMwH1VoFiQs/iHJzNRe8F0xwQlwnz3TwC+ZLzYN5ACIR1vTlvQvNQoBlg61wf00qWI0yPLlE/KgQrWIhpJoUA52hMMc+eDrHXjMfPNp7r2nC11qRlmTBNFZIZlDrH5831gker/F4yD5QuvU3GeJomj1rN9avy2W9rw7Ya4L5xrcnFGGeHxcNZOwc1sQi8eWNOMHhkYuecYloifOntpfwPWFk8aWLaP2w3rx2UMxbQfFoOSVmAwoH62KYxJcYOMhMOgPtSVsWaFFrbKI4EA82Cj1Bv16MyAiGeLyyJ4L5XTa8rBHNSK2rrryLYmt/HXpwiggH+4hxSqRBrMR2tSrZMsPDdNVLYPr6uFeI84uyNmcx2Dx8iQoxYrwl5veDh+xeC8ye6Ea8p7e5iAiAYH0bEEuI2Ar6m1oZnRjSH1AxqVvRdMpoAsIkbO+Y+pbLtrW8nTuiC7MzUwhkbavIUJHa2pu9ir2IAido6hpFIhzhhcgtUyNTYUsLz5YqyNqRs7VvSEIoiFq593gogtTWI5TFkEHL+dXZJRRtr9QisdQdCusNXTyB70nvUwelb6g6E9OfJvTzEQD0rkQGuqjIuUXDOq6q1uG6HZKUXcqx9zUCr7lxcR3FQhlB8bYou29ULOGM/6mCGtRd157jge5LEz9eR9Hac1sZNxwMOYIT0e3AA40qte0jRbxD2vbEnRXr8PPRz5DO/iQL2kGUcZAnd0FL2i/6cY8eldDAEXhbdPo81UKwFyB40Y5sQAThs64ba6jArIKjZBkNPFWiVjoEDZO7XewBaWqMrWAenAMCJJ4MWXQ+KC8VgU1nbOIuXhC2ZmI/BjC5pEjmi7Ta53cH0AHY7R1H6Ys+HUgS3jpZsEbbkTHddPC+CrDv7yzk3VpLjE2ydPvoSELJ9QCwpFWN8AT02wMh+OxDW72OfV7urIcFjrxhzm2ztI9baP8tR50fotJ1TBpRFMlW/t8a/0FUbMZ5jqzdsrtCgxaGUdDO2ARnMt7429LbdHj8oZIBWwYmZmfD+jXXh5ZAHxvMYPzvMA+k3FA0iprd2fPP+QgJIkYDTZmJVTRxSYxsotELAltuX81eAsfb0Izpru3diRQYd4LUICw/EkxnLVS1IZYOAbH1v+qslFXgf4Ox+FKUZAQvBjHvZ0o/xZy+sANxr4jSNe6na3ViPgD31pDuhQ8SbjAoB12lZMM0nA74TgTMVKDwaBDlzjD3c37FoG+IoNnWnTwgLscETGAtxz6NbB/Lw+QCMnWZfhm6e4UsgDLZuerfPlePRC7GUiWHnSGsV3oeb+c7z4uta7Tka/3Mie2unoXE+RJxPJ3zlQ+Z8pTXGVoiDQcX32v5iLLHPv9r9zzEF5CABdXitaIPWYjqA9tNm7FIHyqq8Z93v906BL9VN2Fnf49xsk5LeiWDXKVpxdooaZrQ44+HVPe7OJzxf6CIKkE3d5R0gAgkB89JwvlvgnCJOgYZsqlg3ds6cTic4AZ6vzyjlglw21Dqz2yk4JCGoXN/rwvnu8UcaCNOX/zj8gA+js8YUuRTMSxgaSBTSdePPHig5z00WQrexECOu64rWHBlhYo5ypUIcdWj6mIvRm50sgSROVm9aIhyQLhpaP0XkTG2NvBE91wJcn02st5CJYLEwFIpp8mMAdgHHh/sZbz+7YF0TtsQEretCiG2G4jwXbhGoVuRM+vs0Mflt9bDBOQJU7VApcG7f+GppCC7CmescF+U2XjvFMKpoBNu4QV6eEratkIbrgNncLkvZ3fe61hPbmPxIYGutyKBDEpQVd9opm1hso4BpKZzwKmwt8+pQXa+8OpuvAuPWc5z0iHWPErkhAuj0IFayiOAzwXV0KnMV27WQ6VMbAaPoTWCVeVFJzVhtdL5LSaHK51FyhiYAqkjrgc32ObFsD8qLUWy9cqymRBbNaXHIpRAMFLVg1Q/3OIFDTg3X54xpcYAwaZpnuuGJCvKmuF5I2R0iqqIGfhKUIdhDDbFQyD5ixb7aomtVaBPA8MbG6ZuwD3TWDB6YTwsAQU4ZAhlJjrguQMsgsCpbUtKacb6fyTo6L2Pc+WABW+HuEGI3e7B2GgHUAJCaG0oyK17nkLZi90hQDotIKXxdtfYvMsMAkQgfGGx0Nhzn+jGwJjDcwWNnlV4mXgEK9q8rCigSyTld1RxTpQNY1DSkptHuDui0mBgo1495cbh7dQaJPjzPlCrchaYBvSrawczWFEucMM8er8sJORVcLhn1Td2BHbXqaKTjaPDANHuc7k+Y72Z477Btm9nIC6CNenPWvpI2itzPMxEOcQGztTI7x5bPohXOCaYgxpYL6G5VPVkOoTsvClt7KnC9ZLz55AqANu1k2bFN+/WrhpQD1i1BsTtOQcmaYrEDx0lvAETBtETcnSe2G0KRN+oztcYKcGksUnSDkb42Rxt/8zxRqyw4TDOFQtWSGmdrMdsKzOnWnByp+1gMFjfwKfN7e+5YG9uAezGiNRio6ux+9eT4GPT1ZJRJZ6kVpQJaWP3PKWGaGuYpIKWKaZ4IkOg+BlsVFAEEDtMU0NBQ1mTaWhUxOOTVNIoM9OwMj7Q1eEfzAQjbG+Ec20bVxKtJ94AqRgv+3d2Ey7UgP1Vcrwy67+DgT4IYBctyGmyQTz9ZcZocFAtCdHBBUDfFNW2IMZgxi8duL43BDIHubIzgnTGIbQ1oOvZF6M4ac86ZZhBYwQZNAFC3PTIVUHA5TLwmsfZYL6PYw6ICHakY2Cpyeo+bm/NDIDrnTMHZN2+ASuZ1d9rrrF3vHOZ5wmmh9hjFeS0pMCZ4dytjULxr/7XGLn4PjIKAmkihGpDVarH3mM6aJQHv27e6mQcE1lq0u1QTANwT+dYa0Erf6Dj+nCe7UagV5wSjFblUA+sa93vr9OsY3DgGAHbQunPOwUcy9/oeIQJMkQ7h67oa2Mv47QbkQ09AxzKJ8QEHkBDSk2RL7rQDYYwhu2yFyA6CGYRi39UM3LHEdXxsB35kfP8AH/s1v3gO/RnoPqwxip8dpHv58KSfgww9UxWBdwFhmhGnGc451MJC8BQjun4tcQkrgir3KQcWcwYApzKSrmYmFVNkUa6aHEkfI61ZA6TTmySMCeRtktvvb9/zBgjkuEYKjMl8WCs7KNZ1wbpuG9fa/R6+1L/r+3GwVuam/btZLORztmTkEGjesIdvfgNkK3z3/YUFjQOrrIOwcvistre+QQAnwYoKNk466BIO4K0SNFMhkCEWh23bBkFhq5PzcEpgq9bevusZu9j5xxDt/ti8dbP1phaLm/mNo/0VcvPEjqAVn5Eb7FQWZRRdy6/PgQ7u9XXrZZvqi2FsY1nGnvbe14nJV5wWKAQp0V0oF7qF50ymZ19fOttYD+Pj5Se3ZqL9VvzogJ7AJDiGOYrFscIYrZWKVsiqV2OulkJ2ccOx0Elt3q4DOg5VqPb2YjFplJ47KqCNbtDaX8GjtB2Q0daGH2D3MxndJcbiFWf7fQVarQhRcXeaqCHaBE9Pj3i4p35TcKA2Wc3WjjgxvreCRm+dFeGMPjLuvhDv//xHD1XKfAxnwb73iK2i0mNLrlUECxVa9i9vqgb0+xE7Q/eCWS/Gw+6VDw6nxRxonUNVxWmZ0Cx/3PXhyATDlwJr3r3I3tncQUEuYSxyAnXso7UVQLuJzTtQyYsbdvuPYN/xcq8rzeJqsBiw9a+JAAEAAElEQVShvVjb2oiPQ2Vs+LAENK94rsDrV/f48MPXePv4jHK5oNaEXOlyK9LjfjUzHmBZJszTjCTF2JLV4jCaW52WE7Z1QzcbcOoRAtuyUys3hkZfdPyRBsJuhs/h6Vo7NQAO4L7Rd/2N1ipE4pgco59WKIIOVcTIKrmqICU6ZtXCoGSaIzdpcZiWQPFpRw2a2Tts1q7Gc2Er5W5f7FELq2c5UQC/H07YophSRd6s5c3xO3ykUG2M3lpF3ADfxHHD3uMvQXDU5vIThRGZtJPtoQ3IRXG5FoRIi1vnPUL0mE8TXLBJZQt7q4pmPeKAGxtU1ynrEd7uriYDJOwb+TQHhDVTz1QbphihulEEzyibwfSOQugtTDt9V9VE9RQ4n4IFXXx+OReknJDMMbwnDcQzFUAD1N+uAKbjpe/ZvIR5uwUMJpff93gDTELkZpZSRb2QUXP/amaLnwbUTKZKy4CfgJQLUs5IyZIQcdjWDBGgJkVKGCsOq+DYg1/bYVUrwaau7VEBOJgTG1uDlsljQ7WNtidxDlq5EaZUcX1KUA1ImYLy0+ThRTBNHvevJigE2wqIaxDHRak4BrvRqMCd+t+DToXRqg1sGjcMBoguE67PGyCCGGd473F5Srh/TXvwED3S2kevtasE04eqHXwmS7IHiM3E25uxyrZLRjXXKbKvAsXpE0W3VYC0VdTM6khTYL1uWC95tLCh2XM3ZljaCHamrSCVhmK6JsspIMaAN59dkLPpnslebuVa000rqItXayHYEzxKIwDUWmaLtDSoa9S46vPYgnVn7CK2L1gAVAXQghCY/N7fz6i64fFxxfqcqHPVGkIgi2uaPabZD0DOW49KbcC8RLbFqeDx7Taem4PAhQCRYJUZY1BYsi1CUfNWKE6p9qycYwEhGOjfW0gIVkVIMM2QrSDGgG1j28z5ji2eUEuMtA8jng9biLlBltKQNoo0n04TTncL2Y9OAEyImW3KKVeIKBCNodds3Ba23tRSsV0B5xrWa8H3f83j7m7CcvIAGq7XAkiliP1WUbJCPBAcn2NP4nsb3Acf3kMr9YdioLi9H0wcN9ou0pqR8nYIrmQ3GXEGiuRqLeYMdHvb23I6QavAT9RZbNpBqrhvhxagB2PElGxOwpXti62wlaPY2lEy2XTO2mKdmDZYT2SMTTlFIUM6NyRj+M0WPPrAhK81AEVxec7IuWG9UOzXR7aowgl89DiFMJxbCTIr5iliigTs4kTG8vq0GYM74HymtmcMirpRS+7xzRV6jrhcyMiKgS5OKVM3bbbKdDtG1p9z+MjKMHqiBYXTzkTh4UTgehKGvT0AuuvzQAFRP1zVhkZcz1WEbV7BnGpba2xVelmqBZPtnDNQK7Ztw+V6wXW9QqsfwG41yQNZud/e1zP3kcla6m2P5Xil++s4hGw4ttfQsdU7mOD+sfmLa9oA0WyPdMG90BzD4bt07N3VWuEAA4at8Nb1a9579Eqzk5GElVKxpcK2XSuUSHMDNKK5wR7XNQOAb1oB7f4fW/HEOSwziyvZ2Cwu7O1FYjFl10PTfn52bzqg1TW5vHOoWm009diTCXmDIAQyJXuizj8Zk/R23magNAXXiYqHrkdjQKQqY+Eutn90Nb4ZRxYXkQHJdjgIq+bidpOXJmoseUWxJK1Wc71zES56TPMZ83xCcNTmCtZO3ZNk7hlktRZYO1WjwHcvJDM5o/lALdWYXLanD52rNoBAOV6T7AXoI9tjADxqepeHjLnp3k45WE399fbMqGtmyZbipsW0f31tDbD22GKg8BJ7+84O1jQl0N9j4A5+oMdNpsXWw9KmpsFrbEcnZljQs7TWLMndz7kX7fvesuu5MmHvOmoiZKxF58y8hvuhijkS14ZsJ95agbbEwoajCLj3ETG48Vld56i3mN4c/gQgIYQFzu2uhh3s5tfsz+UIJDsncEpQuzbmEDAwrx2CdQInx1X5Ox0dOPxiwCx4j3mex/kCwLZt2LYrNeRUdyAM5BdSu/P9n9mL/H2dOZILghkiHUGdDpIRwCWA74TyE91U4PhVn3s1fc168QrOjTZa4scYwbuFjM4a80JTmPX5CevzE3BYM9VyFi8N0a2AUixdwDZSSnx4BOcQvCB4snoQjYACMmhLaWNOj3upO8hDsPM9D+yLDumsr8P5HsCrAdz2gg64z/S1qN87Uep5FecGM5njoA0wahQpHA0tgj3zZSLjbZonwGG0vzKl48z/8mP4xeXZcCZ7dOBevHGjgipGHXtfq/7nHwquW1Pf/1+Mu8uarKAQxnNoqkjWHeeKmfPZz6VsmKA4zxGvH+4xzxMen5+xrhuerwm50IX6KBGQcmVngCOhJlRzw1TF5fmC8/mEeZoxTzNqzfCokFYQA7BMDtfLATn/DscfaSBsPNrj/uiGLjsoXMl+83liYtPphJ1tUYv1kSrb87yBMCIUb26tISeCAV6C9T1PqCVjOs+YJg+kQr2fpsjWutVKRW1AmCKqaVt1TTAFH+S2bWS2NEWM0dgPgSyEzKqQn52JbMfBDCnXDG0Z3gv+8OtvECP1LrojGZk1FMJfzkxutmtm9XhjgED8qhlDpiLOrFQvC7WTVCtqLihFzY6UrS/9vokIUs4oybQfPKv83oAuJxzROWMESSF4ujELacLV2jqGnoMFu0MItjPRrNrF4MAbaMcFppQyWA5bLmS7ddDSQJkOpO0Dpic6nVB/uy3vlZ1e9QfoL8BFMsQZyzmgaUEIDtdLxroWzPNeeUhrpnOh94hLoLV8c5gmQBFRC3ApGSUrTH92nFk/UennMjZwA2KjR3cFc14QPbBtCWrgipf+yp7M7ZoOtXDTeXy7IqWMOAnKRNA3TgGvXi8Q5/H0KKRrC1kKXTfMmxtqShWpmK4WMNxr9sDRjfOttRnTge6KwTlMMQINeHyzss2hksnWKgEX78HWuUKmTkrU/2IAQbCkz5Hn5yu8CJIBi2yxjGwlTRmXxzSqmSVXpLWaKyXPO3gPzKxWL4vC7SaEZAIVc0wEAKtUekfXvG9+4xExuiGEOU3ToVLYxTE5+ES8UcaBAA+RBlVqeoTo4XI+BHqcJ+I9RAh4CCzQbQ2QCVCKST48THCyYJ4ctlCwScJ6TaiFG+6UJtxjMWaqmr0yW2K1MVgo5jhYSkOIHsMhMjdEaXAxIFqLZM2K7CqaFoKwxYTXwXbpigBp3lpD9GYDzTmTweWAeSbb7boW5JQxz576FAJWL50bYFMuZWghns4RwVPMFrNY+zkB1csloalSby8VM9AQJGmAFkADvAPWC9vRn8vGRGZhsSCngjJ7zBPPmm0wBMQvq1KAX8ky9o4it9M0YZoiQvB49eoOU6QhQq2cj0z0uaat6waFMX5TRggNKXNNTRvVWXtrQq07LV8AnE4R8zJh2xpyUWjzaEKQobfrdLp5Zw5Q643r57ZlAl8V0KrIurcBS24AkoFM0WQFyP5iErW3GHaw5OnNBucc8sy2Nh/Imi5ZMU0OKTWsa8YaPeYlEjyePVwgIMrikyXyJgheW0MB97NuA+5c18xRmJs8ev1IGnX0tlzx2ZsVuUSc5wkPDxko5uCnNAvp5gf7LtBXff6stobJzbwnvVKuStDrMIbfLZyYBp05aY6dpLHNEQACyNAQdR1jQG8q6eBF8N70NW+1m+iMmQDHli0ngvNyQs4NNSvUkzGWcsJlXRFCwBQSUop0WUS3OLcVubfmNdNn9BHwDcU7aKlDNFubudDJuFBL0DqQxTERvMP24p50gGEXPt/bYEWMmzcSaB3ufIdonnNBYbGAIzHZQMPWaF1Px1FF190v2iAujPPsLWN0NetzOhDg8tS46kLhznucz+cBkDEJFTMQYfKgBl6MdmNOtpHYNK2j1RsDCOzjiy20pTUoHJynTqaz/ZrPuo3PrWP/6C3VzcZaoONqDAYQ8HZ54cBSxa127ngedk6EZyES0IwxEMKCCqBqYRLkGEQXJYOO+noeEma4GBEXA8KEbGPv/Vjv+pzoUhm1ebTanzXbbVtjAba1hjWt4x41bUMQnPfMGP0vJt2xPe94kd3EY+96lD5sMf5vgKCiYkxXAw+pOdsdZg20PUaHigGU9bWzGSP8OB6OWXsdbDaBB9ch7wStCTLqYJ+VurtUdtkBgmU7u6xfb6kFLZM17w0omdzEFvxmRZ6mKG03xhD73GjzrjQFS7hukIg7ewuH8dhaQ2kUN+9tYN2s4h1wAgL4GTA3t+AZBwFqbP825uSOIRtTz0AwrwB3WIvB8K5mr3aQ0r33JA6v0/0NBhJ8XvuvONM/nSZs676i5bQhbRu1Ad+92nHP3vex/mDEcQTUaZiwryHHIdPbh9nGBsByj854/U5Hz3f2yOsAAKpCWweduy4Y49OdiX94n+tA5D4Fj86rjLdtjjU6zzZ7fiEETHHCMs+jVU6rOc+2xeam43UZmjPqSLpfawfDvtuD65JDP3kBx5gXu/e6tyny/71wwjEafbB2cHZ2SCmYQrT1pLuq789OtT/TnWnWDU20MR+9QuFmjzmySAZ174xufc/fXsYq4/FYBWWMnfGcdyYrunOd+843cVzP4btk/G8/5iAQsQ4W7LIJtTQkqXSGBokivSNFJLMTQZgVrGvCm7fPeHpaKZfhHbJ1RfX77p3H1lYa7YSAVhsu1xWfvX1El6eJU4QkssS2nOFcwBwEp2W+ife+6PgjDYSN2XkAOL0fxazx8xADHh4WtFaQUhoBEhzgZ4/r5WofKMbcYqWylIK0FqSN+kHiPGKgOLt4anNpa1hOE4NXq+qKgRXVPq+DMVMkK2Tb6OpYcoFYq11tHKc5kU3gjB01LxHnhxnzHFl5TRUpFXz4cE+gTpWtI63h/oEC9tHa0HJudCFL3IhDtMSi0vWkNgakfqIwf9oyapngFwuwGtCMebElBkTLEuHmERnjdDfzfbVBpEBVzO1PIdI/pyc8jW58AJ0dpI6qxM76AGpiQh7nyKS8B7KN+lzR7449pVE8PoQJ4huqZvatt54MgkHrO/PhENT3io5YAHUMxkGq8rQEOM+WrG0tcI6AW2vANLHl8OkpIwRBTW2IGKNW+OKxzHfQJTJQDgGffusK7zxKKyNA7ftVR/U5fDuTpaKi6/9Qd855ChM2VWrNqbVkTRGdkt7ZYwJHd7dUkXPBlpMFWR7nO7Y4LOcIHwPgHcJMpkIfF6WQ0VZrBSo32qenFaIYjKghxDkWY66qpdDRtKRmgsmOFOzCQO/puqKWbEAbK5Z5KxAEQBpZdo7sES8EwhwE6ZLxfLni2598irszAQgFK5gxzAyoa8G2kUkUo6PLX+s6YjzPcPKDbhtnshoh1AbrLUcMOBUBe3vR89NqGzYTo13MWtFapuDpaMfoY1DhAnWvRLohQdeJogON947At92r2nb6eGfhkdHFoCUnBz9HnE+CkjLSls1BsovRk9oeg+DN24ScG6bZ4+5uxsfff4/PPr3i299ccXnc0HLFlstg21VfobVhCg7iIhqAck1ISXC6j0MLK7gAUYfUKqnOrSJ4AiJzZEtLyqa7VgB/jnh4TV270ymglIJPv/nMdvRlwnwiQ1W8hygrPXANd/cE5FQ9pnOErGznc16QEllKKWX0NshejaWOXcOzL0hrRsl0fBTbM6YZON0teL4UxCgQeMwz2zpVgCU3PDxElFLw5s0KL3xOpyUCrmE+Cb7y0WtqZEWPOFGLSZWs2XXbhlNdva7UBJsm9AwkbQmfffbM5N6bwcMowymcBKsuC+LEReL58YJ4mujE2VhwKCOQs++uXIvSRlZjqcrkTxnATsJxW5vSZMHW2doagiWUbAUkAF7BVuFaKtImKKnhSVZAFFN0SAZoPV8rYvBDS2y+Rpy3iNN5wrQEhDHPnAGNHDO1VmgmOOSDN2dd6nGFyQ8Tm8F6UcX5bsbj2yse32ZcLwUfvFageizRIceKXCtc8AaE7YxLVofNVMXKkIqdrQJYIt3LIi+iceUPIcJ7PweO5+4uyISvAsXAsuZQaYHIZNyrAWA7W4AtqsWS1x7kjsqMMeZeQSu1HqkrSf3My+oNjOF+X0pBKWZI4qgbhwMDgaw7BvYNxigKflS8O0ur6951YXqejxuBfs62Zx0SFx1JVoPLZb/mvg+bVmIfhz0pPLImKP7Nv9dGAImtGKDLte3Z4oDJAPNkQJ64ri3akEsF28NMhzRETMtiuo2cf7kVOHG4u7vHdV1HIsNWcoV3za6ps9oMLFXu0QEY+iz9GosVCah35Gn4Y3WMLhw+CgW6J2JwfiSxil1v8B1Dju/5MAkJvCuWfzyY5Dpc3l6RtzyAa+c9YpwQQjTg3Rx21dofAXSJA94rarkOJool4tL0Ro/GOz9i+r2NTse4GvNPdXwH/7l/SBf6Hw5xltg5A7f7PVVOVDLOD+/XFyDWO5wj2c+j65s571Gq0sDCpD7Eir1Nxdp52D4fnAGVfW2u7WZdGS3KSgdw1V54AHBsW6sEXaGKahpp9C5hbOxMT7QXYpy1RqKDrsrxuZWCohj6q7w77zJn1QCTJm20ahIgeXl/utaIwjuFarn5dRct7xIzegMQ8Vw9DFh2lHa5VaW/OSuD8Qwteu9L9lKc9FjtcH1D38uAkimygPqUn8ZrKGHTbq5VD3uCG5/4LhjmfcARBAMwWvr3QjUGSE/QhzIKEMXLPef22FssvdvZVA1kAOsoqHOtAXbjgmbMULXFpynHVAh7izDTIDeAsIGjNBYX+/fS9bHBxckY94AKnZ+9eBPt7/et7w9qAusOKgGpvXvvDjf7HSDmOx1i5yuAmTj0eSE7CKmwNbCO/Kvv9p3w0VKjNnUtAARTZNvn0fF2bM/OdApteIXAmK0z0kphASCJ4jxRp7dVt69V773wPXV9CZh9Hovvc2/I/4tHdJRXqlUgwUBFYVGgeYcCQSptECM6+zYGj7vzjHlm3Pr27QXP143t4AqsRrxx4GfGQDmr0zRhmSLOpwW1KJ4eL4gxmCbwjJQrni4J3jX4acLDq1f4KGxY3NMXX4gd/1dA2C/90i/hH/2jf4Sf+qmfwq/8yq8A4IP4+Z//efzar/0aPv30U/zoj/4o/sW/+Bf4M3/mz4z3bduGn/3Zn8V/+A//AdfrFT/2Yz+Gf/kv/yX+xJ/4E9/dCejtf+J2IPSIrk+zxzxHbNso/4xgb5omlEhrddXOzrH+XxvhrBABThXzQnAmRE+HoEtiMrdEYCIrQRpbUrxtCjllBmWJDmXTFJBShvMeCkGuArTK1pVSzTIYmKaAu4cFD69OiNGzHaBWzMtk9tQRJRdspeB0ipiWgDh5nJaAkhu1nmpDzrv737wEoBUs0WFLFfOJge/6SHeoeXJQbUhrwfVCJ8Ntq8NhKU7mLuMczg+z3XfFPDs4qWhNsKWCpg4+gOivgSEx+qEhU1tD2RQN1drgrE9eYIwwoGYCOaXb/o4NYg9PxHnMy4L7B17ntrJVi/u5BVHicNit3juMuHgrnclMk8RgKPjI1k72yTvMi8flQrH5jqArFM9PyRICwRQ9lju2Pvjo4UTxapkxzw7rmnF3/wrf+PozWwm3TsW1FpvGU20iN/RvVYpTx+ARTRMJUGstoN6ajw7zzLEzAkUUlEwEfrtuo/2AWg8OaS14+OBsjESHZbExca2odo0dWb9cNpTCMVhyobNgbuaMCHQmGB+OnXfj5rCcqQmwnCZs14SqdOL78OMH/OHvf4ubogLTxGpj6ALjlcG3iOCyrqYHl3k/Jladaq3QGOHEmdtNJOi8VpRk7qumKc/FmecYJo+cygCK+3hAY7uWd47MKdski+mhXNdkz0TNPVAxRwMrnLcknvejB/QiMuiqIXiCh9buyQooB2icgs0zxdNbA+GF80YgOJ1nhDDDuTuU8gzVAKiHD32OsoVRK+fWNLElyznBB6/n4U6aUkW6rARWYxiufa3sgqnFBO2nyaPVabTsUnHOYZlnLHHm+tmA6/OF7B40S34YLItVFtkGrXvrsgDLKeCyOlxqRblWvLqbjA1EUWZtvTpM5ogoQZPlPGE5C0qqyKng+W3CZ99+hsKxBbYoW2Pr3h7f4wRn7cPAzvxTVTw9baMtTJXC/A0EEkurZJw1rlsQEJwNE+YJKG3FtlmiPbkB2Eu+IteEbUu4rgUhBCzLjOXhFTVYRPDNb33KFsVSoUFHAtcDXGeMPWftaFOsAAKeLxs++eYFcfaIi7d2fh0siNro9JhL2Vu6tF83Vz7n2KrFLr027nPTgsmbvpaJeDtl6+T9/QlpAz79xoowuQEkwUwdRBRb2tv+W0vUOCsNpxxxqhPmM8f45ZrxwasTgyVHhzlRBudxDph1gggwzQyokwk6k9Dj8PqDM7ZUUDKNEb797YTt4iBYEf74hHmeuI42QdU2qrPqPII5ErFFxUFqpUC8GqBk2naj/coGTQNGq5YIQexpoh5YysnAqG7NHpjk2zMVY9v1MZ1bb2V3aN7D+YbgyPyxdGsA2v2QSaCLop7ZHny5ZMQ4Y1nMfVlNOLckUFuQTM3g6PYnIsby8MZOcXBCk4Fq7ni58b5MPgwnO+pEHbVi+D1B9ntTlSLXPblLeQd3OzOya6x0EeV5Yig6wK/DtfbkbcsUZZ9jxDxN1lZs+knYj5Spv5fNSboX2o5sJSa81LwUAVJyKM0PwfdxnwXG/OH1qoFIn9eUparskD1cQj83RTd12Z14R2uc6mDC+yG+zMM5z9hKm2lACaZSEQIlNr5Mnthbcpv2/bgDQJ8PhIXgscwLPvvWW7L6DOAJPrLFXcScJIHFYk6Ahdie3OXKmyjOjba+/V42A6LdYV6xdbeL0PdnED0BipvWRZCJyWIz94judjh0mKSb1+zXbTd/7zg4gItbSlCLb7Wzog/J5cvn3s0uettpqTR2iqb95oUMFIJPpr1ooFKxedZlCqS/1tZSxmi4PQfdwRE1uQhpBuQrUKTYvkotN28mR9H3hHs3j8i54Nn0F/nRvPfaXrYps/m7g3e+A4uNXRXeHUAoFSC9gZNiYKjcjDG1B9qM/evcrbOhCADvMQWuudXmdjcjOmq59XWi4XNhMI6zrmEsu9ss0Pc669YJcWjGlpKxruv4hFIr2zI/Z5Z1MKy+ACHeL9C+Fw2Ohg7UkjOyv/cITvC+hGWvifTiBNvwpmDeg5XgvyEz9un8TG5a9cXnyTh/gHlrbfs3iwjlDpSdJwIg14IYIqUYLI/2COOaqgqkXAFsEM8xP9rSO/F3FGTUdELfe2vHNb+8/i9D9BFYIcZ0Ccd8st+h/10bWiuUEAKs4wgj7lUFrluCtzjSewep8kLaS/a81DV2b8mJ9191gGA9pyyl4LM3z3Ci+PiDu32vOK41HSAe//vOxyimvLwRuC06vPO+F7/7TrdXRMae3xqv3UMHDt5U8ZwrHqLFF6p4Tg1rK/AhYJlnOrM2cxSGA3yEF+CanigpUxWonId6UpwXmgyWyrVrSxlxjsa6jHAu215IskB2wPol79v3DIT9zu/8Dn7t134Nf+7P/bmbn//yL/8y/uk//af49V//dfypP/Wn8Au/8Av4S3/pL+H3fu/38PDwAAD46Z/+afzH//gf8Ru/8Rv4+OOP8TM/8zP4a3/tr+F3f/d33+03/6LjRfHC9oKbQdOdgbac4bzDNE+D+phTNoaYIsTAPuBSEWNENCbStrFdibpQpOZpEDgXgcDWtGYBvmsC8Qw0Xd/EnYNWunGUApzPMwCP62W7oexraai5WOXWwUXgdDfh7n4e7YLVkuYY2eJ2uSREE58GyGZ5/cEJs7VgfvAhW3JSpvPWds1YnxN8dHh6Loh+DxTO9zPyVvDZJ8/WMqrYtoptK0MDrVVFF9XqFPb7hzt4L8jbM1vICsW+uaE6hBhRG10RU6q4f2CSm0pCbhkhUiR7mqzdrZBW6UN3t1JE68u+XldM0wwR25SbgM6RBA+0AF68Vd1bj3cwGGHvA8MawQmV7jLKYIsi82RiOWdCxFPA+c7hfBcx3wnefsbKcYwO21bx/JQwTQ6n84TTXWC7m3gTGrXWpAzESUl7thYLFslYkRubqQgQgkWwXNx8cJgitbPYHdh5xPuE0KbD/MAJF4S0JaxXskJqbUAAWlFMExMt5x1ardS+aw3eK5YJiD7geqUrIMFgVlopLElQV3uv8VDss9VRGoYDmzjMpwmvXt0hTtTGS1sCtOHDr9yTMQlWkKfJmWOcw2ZV6Bj7zwIaFFtKRnlWbNeEyYLyXf/KkYlhTKyuP9QMfFGjgkvdHV9FBHIF0BRxiQgxYJ4DTqeAeY6Y5wAoAbCn5ytSBrbNmFMW8OScMS8znCeowFblPYHurK+yKa5PKwB75rXCh4BpAlIiJV9bw/PTFSWVkWBMU8TDq7sBqj3c3+Pb31asa8P1+hlabYizh1yB03mCDxwrD/cRH7yacH8XcV0zddaEtGUGhxXXC91rT+cFacsmLs0N73SecD5PgPBenU5kes7REyC2cfbJt94CsPEHiuHHwJ3ROYLDU/SDAVJyZbuB0l0STpBKudnMm9K1sTXqB+RN4A2k85MJxQuQrhWffbrh6YksWACDoSfCoKbZJlGbjqCuT5/agFwa8lrxpq64PDuc7qI5xJqQavR49XrBp59cUErXsXKYFiEI/+aZQGxVRBfgFrYUu2uB23YxU+fJAiJQ5nB5vuB6WbFuGT3Z7vtZ7omP9oRJR/LlXcEUBB9+dMK2FWzPBeeHSMFvRyaCNnN8dLsLZPAy2nGYGzFAVEvYaqvQSrZKD6IAGKONzOBaGta1wJ+cuUpxXnlhIP0y/ujFkFK5rvogEGWC9uqrZ7Z3Bo8QJ4Qg2NIGbAwoQ1wAZbWarEi2SJZSME0T1q3gtEy4PCdsmXM8ecGHdws+eXuB84KPP6ad/C6abmuksbG6kL00hbfe6KpqbaUcz55kNI4XrSNQ7a7kNOVpqI3jLkTuY8GHg+A672kwtluHIkSotQVRoDm0XBD8xMLP0B7TEdADve2GiWStZL6FGHG50sAieG9aojKeQWeD9IDxmIQW0wjr48L7Q2HguzyoIxpQWzU9wT3I7+tg8N6YAYKXqfc7h4FAVRtmW+9n08SrtWJLG2YTWu/u0jnXvZ3wqCOlvQ0uYJ4P8WbuTKZjkNAZcNhBZP38ezJYb3ZbxQlQdYA0nSHmPO+NNjHmhQBuZwfoF9x1gtyKXDJjFR8P99dAkxfgINvyuQa0REb0bcKkgw3Rx2MpFU/lGU9vn5Ez1zLvA+Z5xjTNTBCvCbW2IRYvsAIW+P61ugEAthFH5FH463tZ1z9731XzMwN8CCOh7u2y/Vo7WFRboyGLXUez9b5rglZVm2Jkd7uhx5gNfGMrsghjeXF2V96TqHct0vHcraWY/zYn2f46Y2+UyqL6/lzezdReMsRoLMN90uEWmNO6gwvj5lktsrbO6PTwVpTydkeZgLZ3AIVaM16Obq4xO8PP6pN78ePm5A2o0ortch16W/ZL0yQD4ALlU/rNGtfcx7+tcW431OC1GKsXu9FK8Ldz+/Z0PPwXwGRAL2TQYGSK8dAhtJ/efgUY8idNv2iOCmKc3vt8Xx40/2g37ZLvO4Ixcp3s4vpkfjfkuo+34Cg9UUf7o52n88PZ+IvOm7eTxRIFZXR6ebs0wIdp7A07W9r0m3zElpPp1RHsPp8nhOiHsVJ3Um+NmqXUy93X145VywF77Lel/9wf1uPjU+isNbtVjGe0As002WRnePeDXTNkTe86hIJsOprEAsjsUwYNbL/vEgby7pylOYJHa9T17OuCjDnc8NEHd1DtTsf7XGi5mI5qxM3xJUGdzzu+aE8BvrSc1jhEeoHb1mR4RNvbRdgi+5QrHiaPx9TwnPkFwQgD65ax5QoVBwkzxAVEBaY8Y60NTozJrRU5J6wp4+584vMqBWndkJcJp2XC3d2JBg2lIhWFXDfDCL7cRX1PQNjT0xP+5t/8m/hX/+pf4Rd+4RfGz1UVv/Irv4J//I//Mf76X//rAIB/82/+Db761a/i3//7f4+f/MmfxJs3b/Cv//W/xr/9t/8WP/7jPw4A+Hf/7t/hB3/wB/Gf/tN/wl/5K3/lezklO9iW+HK8+ODwwYevGIznQm2uja2JPrLlo5U2NBd61cQZ2h69g8RAmnOquHu14HSOuDyz3UWbWmBHLSzx5hbjACdtVDROJ24KtTbUXMmmKdxA85oxRY/TabbWKYeHVzMe7heUUvH4uGJLFdtK90sR4O5hYQtUI0jiowO8Q+vsC60o2kVqK9KWsdwxoV/MfeH5DRkhpVZ475G2MlB9LjIEkYrZYedcEDLF+r16xImtoof1g8lLIECUc8bj04ZSFcvZA57tIiUDpRVMy8SWm1rRlFa9LgBhpsMNIFivGaVU3N/RlrdUxfPThvP5BID6NKXsC1LXX1HZMbBRBhDcuix0beR+8rCkxATFvScedXfP9tQQHKbFIdt9F+H4qpeMOHlDyBVhcphnTw2wQ5WXQRw3jdevJ2xrw/W5mbbMISAw/RLvCSB4oyGXUjHNbgTPHdwFmBhS/6Vh2zJd8ywwLwYGqSpKqjeaED54zOcA74GHjwMe3yZcnvgcVYWsRzDBuDOnxs7siqGZDk4H8HIvs9ifuyGFOMGbT9+ydRfFFlE+jGkmk2E5cdOE280YnBPcxYB4njFNka0u9pnZmJxMjCZzbeU4HYwApah2B8IAbqDexoJ4+4GwAhQjXQhD9HATwcjSFCEK7l7x/NgidwEU8KAY5rIslnCZBo/6vdoLgfcMRh/frii5YloCtDYEs7X23qMVQdYGbYUi99OEOGFoGpRcEWeuY59++haqDdtGMfHTTDr9x9//GtslI/juAlWwJsU00dmvVkBNqHvbyMoLXnC+PyGXhvtXGHbFIVIrZ9uucD7ChwmnxWj2ZcPyENCUz446hgnrNaM2WBLMdU98wDLTobS1iuuFDqpe6H5YKu/HhGC9/5xHz28JBg53rsnDhV0AeFoCtmtG1+5pFUOEVYGOO4wqLCAHgVrlOHV0rdlKhV4z5jajigCbuZWa9l4Ignn2uH9gcaIWGoQ8vc2oJ9Mqm4ClsW1FYfPUKcRx/DgfEQPNCaq54Lx9embblwGKR50pMjCoD7dte4sNwWgWTaY54PHNRpCnNLjosMwRy0ym5KPNEbJnrIJr4s3eOYr/B4cY6UzK/YDrSBc4p2tqN3xxePX6hHkJeHra8PSWRY4BrDQM0ebj3qxKPcq8FegpokFxPs+YTzPuT+Y8pqxNtFxo0FIrYFpNWio2JVBH52cygk7ngMtzwuXNFW6OmO2z/s8fvsH/52uvqGtWGybfgYnb9V4tWe5pXRwuo3xVU4XWauwG/niKfqw7XXy7SR17Sf+dGCNU1NJ+EUtQCBoCMKdKa4EykPPW1U5xFLttdWcOhRgQY8TpfELs2kUGjLXa1XX2tpNaG0rNVoU1RpexPGHg10j0Nq77vDe3z3OI3gudkkt+kWDpDlBRsywQaGgEoLq7dO0o4osjDJH+PZrjZ/T9rKCpH0AIZELVbTyf4BwkCpx/t/2PSWwbOlLd+TdE04c7XCrFjw1MtD2HLYDvP1Sb7a18fc4ZrRTAsdiU0oZtY0s9okfzhirslIB3PrPViqacX8EHeB+oPRqoK1tbgUhAKx7J2PCD9WIfR81xRxA4J5T1GdnYT5M4oPH50Vt1PxdtjK/655FhTAHjLa1Ytw1xfkCYIrZywRQC5sVDUHG9FoiLeHr7BtJdmnq7lmlAlpJQzHxBZB97huztz2E82cO1mdYU5RQ8vKqxvwiWk0VY4aQiOLFWRNM0bdUAfK7jpVD2oX9jCEfwGgMJoI7t7dPfizZtzPuqjRpc1m4YvLkGv3zPoejzPtAk21wn415RgR0sUXBd6Ym4gVN6YEB2eYxkTHanCq9ircaHuG2MtTwS2R7nDaH34EbhAAqoe3nOzkaQXZsBv51l2QXv3wWQqI/YgRzey73NtjtJwsyiOk49oLMXt63UdgOO9VeLcyYS/y6q6cSN675edyDs/6YN+cuAYJ//ZryDtjsvo8XveG5NcWsEI53g0EFa6zAx98Avc96hmylpZ1FFOslbSys1dvcW5FobttygKMOgobWGVPJgQtGEwToNzJ10WmYz5MG4Fp4D0ImxA8eT22fdl80jGHYEzI5HLQXNOzRx8MPcoOsHyl6QtaLgkd3XRe9VdHQ2wHu06qC1so3vWFbtUigGhrKbiWSWkhPeZsW6cg9kXNrg0DAJII2xRjgt0BdA2PtG0w2G/D0e39MIFxkEAMbXbIMuNWCSHayvEHy2Vaw33jyCu/s7fPTRh/j0MaE8r6jdMlQbYmSnW4wBKNxHSknYUsJ12xBEsMQJ13WDPLGT5bRMmKaA6zVh2zIulw3zHL70HPyegLC/+3f/Lv7qX/2r+PEf//EbIOx//s//ia9//ev4y3/5L4+fzfOMv/gX/yJ++7d/Gz/5kz+J3/3d30XO+eY1P/ADP4Af/uEfxm//9m+/Fwija8cuXvj27Vv+RWBtBla5NGDi5ZO9qXwKtUdKoUBzqWUs7tM0ARBrUVFzPvMIJQDiMAUKijNJq6ahwcRlampsMNPRUB3i36ps6/DeIQaPxzdX011SlMygcl4ipiUizFzowhQgjsDUtiZcn664WqtJyRnAhPMSSOUWxXyeECZuQj3Oz01xXTO2S0K+ZqxPGbkqaiYz7fGRiXyqxXS9+Pni6FDXmQLUGSCizAEJzMsEEbaWPj4+Ykt50NK96VYVBZa7gLhwA/QT3RYhwNtvFWjlhtpFjLV1DRyCSL3HurWGu7sZ61pgXh2YZrbL1KLIWzF2iZpAtloweJM/jOc/CkSHORIccGw/aa3CG7A5zx7zFOiuGBxyqli3ivXaRoLuD8wt5wTPjxnXZ+q8eC9Y5jhMGNZrxvX5iuszxbwpSs+NHqpcYMxlhYQXwrPNjBhqafAzq/0+eMynGSKCz771GbrzUjJjg2jumsMBshW6/3jB3f3M+eJAEf3q0Sq/a5oCWnMElPJuj95URxJTEgHYOAVsm7OADKioYw4609dqreHp7RNUqXHXq7hAo06e8wjWEvj8vKG8JQB2OkW4hQkQqfm0Mb5crwRGnYM4wbZuiNHjtMzYUkYuBTmXUYEXyFgfRgDRWCQj4A2Od0sKxbSRyFQDADrREdTOAATLQlru5XnDFAlwqFbksiGlghCjUfkVIU6IEuHA9uMtbbhcNpyWxZhbHqqRrqK1QKtDy57C8NExcM0FQEPJGZdCpy6oYlsbJCTM8x3ulgXT2eH+9QxAsV0q5M2KtCV885MVaSt4Nnc9baYTNXvc3c9QZNx7sptwsgqS9rZOVtm0VmhjUN4aIFrx0YcL/uDrK3Kq2LaKeBKUy4a8FczTHbbVoZaCZQmoJsgPMJBSKuPSPMHMJ0quWM4R63Wju91hPc8bq2XnewoDD5BVgIfXEx7fpnd3dgvcHTp123QieBdQUAbYfz+F4Y4FFdQiaJUA6d3dgg8/9DifA7Y14/lxg4iQjXXNWLeKOQJp2zAv02in4JrmrQ22IURB2hrerM9Yk7HAtFe++WD60uR811wRoAnyqiiuIoS+VlXcnz2+/489oJaK65qtCCI43y14eroimfukc6RFpK0hzqyQhuAQJs5d5wTLxMXxPE+ANpSUDZwxTSNloDzPcYDWThIul4TtyjZk3k5vYPievDrHVrTeStRqw3q9oraM1+E1H5UJxj+tCd/+/UecloD7B1agc65Y316Rc0WcI0pOeP0BWVfbNVG/7vIM7+9xfV7hnODTt1fmFKr46PUdlmlCK3ITuvL8GMyHcb9hDI+9da2ouSoaK6O3X4mNJ4CAYqnc97vLMYx9KAeGVa5sEWgjm+NJ0GF5wjRPKCW8N3FRmHlMY/Gqu8rSGdGAASeojppVNJphW4c4tvrW2rCYsQek63juoJ72aaN7MvK+mNKJadO9AMJqYzEAlqSpNz0c5xBDGIyCzz207a9Rsu7EB+yueAExTgSJaoGY+Lt4oNXNxHat3VDpJBmnuDu4gTqirVgLvHjEiQWlrqvUQcmBC2FXW+hjoh3Gwd5it9+oenRH1IbaymDqlKLQyQ9W1HtCVwBk13QGlVgraRf0720/HcUVwNoybQx3oFHIei+54nq54unpabiEvu9wXhBnh5Sp3bksM8Q1Mz4KUCjWdcX1uuLuNKE2tqTGOGNQOYRx1XlhnFFyRjoI4/NVbrxWXLB/1/eAl203cbj5nQHYxsLQopDW294VCmrP5NSspdK+uwiw9Wf27vXfgGDH++Lce3/en71C4YSSJ0fWHZk7dcyvXshE3RmEn5ey1da5vDya7oLeAN3rnXBMl0O/lveeySTAuQiOnyIYGnFshzcdU1Gc5vkmV2IxkjlSiIG6qgoWEIX5Ds2sGnCEh92EadKbeS5gG/V+w63AoA0jeByv3QE/usuafAEYKjcD6Nxh7R3PApbD9CTgnWdVcWQFETQMaA14vlxuGKHtRZuoCKyVHO8B9I6vc5ZP7kfwpr9ogFBfb52tt9WK2H08wx1kRmDO0djNMb6bYwfBvrs31zZbx0pn2XNtOBaKIHTH7SCzHhay2houlw1L8JDo8WzSKn3dpPZh2c9Kb+sC/aO+E353HAHv26d6UakoJRc64MXvZMxdU4KbZwDCMSLj1xAnKDmh1d6KF1BKNgByN33Z/+S4994PgBUg2F9LxpvrM/et1iBaEQW4XyY8vH4AgoeG7wzNtH6vvuMrv/Px3Q4pNQ3eY01ABPBSkdMGiMM8zePkorc2ebDofX+34Ae+9hU8Pyfk+gke1zSYgE4EUzD2atWxdm3bhlzPlEvxioCKmhLSljFPcaztLDLvzPYvc3zXQNhv/MZv4L/9t/+G3/md33nnd1//+tcBAF/96ldvfv7Vr34V/+t//a/xmmma8OGHH77zmv7+l8cv/dIv4ed//uff/YUDggemWQYKO0Q6zemNlOUKOrgBrcsaWiBea8Xp7oQ4RXTNBCeCEIg05kLx5xgd7h/OcB5IOePyvKGUbu3cbHE1sUonKDCGQgPgPM7nCA+PmoDnt1eb8Pz9dJrgo8PdqxOBBGOvPD9veGpEQ1MpqGi4v7vD/cMJ9w8LtrUgiMPysGBePOWHSoFrhUFIVcxe0JxirQmvPz6jZsGrV3dY14xaCz79pIvJ7asXi8MMBHuFXwD4oMNpxJsWTUoJtTIBC74HfCDLQAAXPO5eT8Oi24nAtztcp28hPZsQued/IjDHQLFqcTVNJuB0jnSurNxMgtEg1+eM9bmgbA3RRcyxoqUVpcejjKs+9xCYbJN0u221Z9oTmwgfBCklAA1t1V2/QpUi1AbCeUugU+qUdFYCwzQBQi2ty3PC5SlhvWS2vDlBLXQXLZUVghA9ptmqh/ZdJVf44EbQROqsMRBldwMk9bhBvMCHSJ0Z5xFnQJGRr1eU1DCfFsQ5YplniDQ4l3G681jXgm0jCOis7bQ7fjIBnsbfa87GMusLPkEvBbAl6rlQQyvj+bGhWYtds2CNGx4DlmWOyKkhTnRXS89lVF6tKwi1mh7OdcP9/RmXy9V0eTzceUFFxbffvMH6nJET28JK1pHkso2Rn+cPOaaR78Y59Uq498L22FLQSkXxk60zDndmEtFqw6uHswleGxPIHlJLFJRUKGouQNswWcvtskQ6aQmGO17NFWgNp/NswCtbMl0Q5FqwPlNnkCy4jPrMoDLEgGibcakbQvOmveEQo+LhweHqBJ99WvD0nEa70OWa4D1bGEshCOB9MO05phE+mEh6IZO21YqSG1uyew5jbXgQYF4cnA/44MM7rNc8gALqRlGrL8xAU8F8itguCdd1w6sP7pATGbqlmF5i2gHVrqcjCoTWhqlCnxfrU0IpdYjMd/ei3g4p0gNrS0KsOFKR9+9oTE5DAEQVOROYoCakw/kEfPga8L6gLmCr6aUB6lBLwOsT28fFKfVwGl1BXXBYzhzXz48Fb95UeMnYCtdEOvMCtRLssjSdRRvnMccZPnq02pC2ZC0SdOntTADpjoulwsMjl4Zv/OEbaxFgYl8qWwRiZIu1AHCBTLb7U8QyB3NXJgsoFeByXbEazXwyIKFpw/m8wAcyAcWx5f3uPiCngus14/FpxbpRQJproWk0DQRKEOcIcRV+ilhzhg8eUbyZzrCF8/K8Iq2bJZltP7dERnUIAR9+/Bqn0wnrc4IgIF836BLg5wkQxf/5P9/GN//wM3z80QO++vGH+MqHD8Ak0EK9se4C2z9bQOC/aHeDE1sb3EGzZwfUYftFJO0G3glyT1adCfDbOHS2VpfckHxBiLv9eC/67IyTHUTUF1Udsl4zruAaSKCKcwJCBglbL8NYj6ivaWYrAaNtuTUDWHDrZBbj3orp7B71Yk6//v535wPbt2wR5VrYExBAIYMJdpona3MFnCvY0s4aaSo4TQ45FXNtdBYjOKiSHSjO0SkPBnA7D+fjaJUbLDF0AIX7ZfCB99seKd3KiNU6x6JRfx/BTTf0pXohpgMnN0weG9T9+fXEaBgvaW85LoPJR7e0Lkh9AF0OgMp+2Nopbayl/LyGcAQPLIO8if0r1xgxbdZuukIm6H4N9cgoAaCOr03XjBht3rdEZ1Pv0Zpi2xLWjcYhzu8tgpTQsLW70bk4pcR4oeyskGZMwx4HdP1XtOPc6ie0G1AMEPpwz5pprz09P2MKgvMyIXiHST3dzVvBEdN4P9NHcKkzFp9tGOxtyKUWa3HcGTk377Sio8gOlHlPx97SdpODDqBC93nd29SDmVwdWTE8q/clqsw7ALZpV9TBJKVmGpnfjMucxdJ8Ft2Jt4Nv4hQiROwF8wAdAUVzSs1c22/7tY220Z6JV0WuV0ASnI/YisMpBJwWJsNO3Ghp3HJByhQfF2M7v2TFdSA+eI8pRibBWdGoJmT7ibOthBqX9sTQ9Qtv0ZNdnF/FtKBEEINgnmbMyxniI3JeUfKGGFhYuFw3lJzMFZxF7h6T6wGRYs7Ec4qBYHUraQd8hB063jvqfzmPpgQFqkkK9PHRExfnb9Pzat/J1dzuvWu3ZgLKlmSIkBVre+1Y15wnCGQFgn0esNz+3CYoBGdcoE0RfIYzKQUZ52Z/cw4hTGS7IiGbQ3Kvf2kDHt8kfOWBLYkherg7weVaRlEt+glznJHyldpmx/t5mGZfBGi8/J2852dH7ccGrucBHPGChlaBIglhmtAAhDhBHAtINZPJu24rpokmVhCHGCY4dTsbT2VPVg7f7wMZvLVWSJiABjxfL/jGNz+FlISv3EXcTR5rTvi+D+7waZhxFwM7u+x4X9nIdp0DIDn+96WOvk1+D7gqmtgbVeD7OiViBmRc/1Na4X2EDx4OguiA3Gj48/EHr3B5Tvj2t9/gkzdPuJghm5rhjIPiupo5WghGXEpIOcE1j+3q0CagIGPaEpZl4lqb22Dtms/Dlzq+KyDsf//v/42f+qmfwm/+5m9iWZbPfd3LjeKoa/F5xxe95h/+w3+Iv/f3/t7499u3b/GDP/iDZBg5Z5o83iicDqoOxSlaynBC2mHaNohn0Cmei3d3d6rFnMesAihBRstkR61TytiuGa8/usPlumFds1nTMzGdahwtC6GLyxo4UaviekkoWbFMAetW6ehYgSnawq1AWjNccGiFu6G6iqrboAyfTjPuHxacznTniNFjWc7ImW2e2Wi/Pji6OwrQSoa2imWJECc43S1Ipp3hQsDp4UPUvNGFxnSgoEzIvFN4Ubjo4CcP5wkeDu0QVTw9PlKHKmWEU4REj1QqUIHYk81K57/aFJfngiWumCaH+/tXeH6mVlSIXdAQBp7UseaG6OBVkL5V4L3H8+MTUha8/eQZNTdcnhJqoRtiLaROH/97d4ACffqLYCQ33R2wX9se7GU4VzDNEc60Xdyh0tWdh3KqcJ5jEo0skHmOFFxsQM4Fl6eE58cNJe9B8jQziKqFzlgxBnsPE+RW+bNgoEQuDbOIgQE8D+cdYozIawZAhzDvA0Kchqve49tHrCs3ZAb6DcvMhPP5ueD6nCDiEeMJJSuT0FRH0NETmRgjqzrNEkdLVCwMwf39jLNOeHy6YNsS6nVDycbwO9MuOMTdKa0ktYSwIU4zTmdq9F2vBCnIDBRcrlfOvW3D0+WC+/MJ3/z2J1jmCaVSL0jEIW0F16dEMFPBwNtigV4wveluEOB8dwYgbLuqbQQawSmqI6BWUh2BZTRtnu4AJKJ48+YNjQSMHRaCgTqVwuNNFThFzC5gnvaqhXN0+WnGSInR4Xw/m+tOb41yyMGTrWWFPQHM5Y/tqNu2GXDiEV1m0BM9tFDP7Ok5IaXMZx/pxvL4tOH+fsE0RbbYWoBezJhDhHbrEpw50ClqAZbFIwSK4TLRoQbefKJejfeC891kc4nJ8rpVbG9XOA/cv7JqqV3ees04necB9uatoglsMwTm2MHXhrRW5FThlXOvVWWre7HEu6mJdXNECtT0SI5BH7UjemEEtiQ4ARmpC7/v7j6SfYUG1WLgiydYJlzbz/cB0ykgJzKvtCmcrSMinQ3MxHp7VpzPHtcrHVzj5JGT4vJckQsD7LsFWKLHNEUsdwvu7u7gvMN6XVHNAdGHgGAC480Gw+ns8fi2DOCc4vo0EzD9dxaOzAWP+50lFcYOA+jECwco2D42LxOaMcq8MwdJkREAhkmwzBMmv+DxiXsjAVJvzmfUpOv7Rt4qykzgbp48XYImjyn0gkFm8lYqWq4E/KcJqoptTVjXTFCkJwMQTCHCiyDZHvjZJ2/wtT/xFcQ5wD2c0UrBWjO++fYNntYr/p/v/759/W67oHIMB50itcWha83B2jXai3amFwF7Z34zWbU3qu4xcm/7TgUuuD2pOew7pbC9q4OYXVelJ9Hcqy1QLxUhBogLCFNELXkHhAZAQbCCxgcc6K1R2JuC2mG0OnTdx84m7of3zlq8GPzTxdDWLxBUbqUNoA2IJhHhBoASQxiFla691mMsAJgdDAizFlC0cY+bJaPd/a3Z+uSc39s0RKwy/K5Exkgz3xtn8nOOcegAW2QHuXoLaR8kcmQW8EaP8TDYa550FpowNDNz8ch5I3Di3nc+++EO39HjFAUBEKiakcz++5tzAWyec48R0LlLpgmtVUzRWpXKrTi9Cw5VCy7PV1vzC6iXuruF9jbcLW2YptlE06k9RSZiw9PTSs1Gi+2GXp0l4p0NJNaB0E9gz893xk/JmfGGJUfdSKWzvtWA5tq1rIK3Nvn3a4+9PEIISCUiKtu2epswQUt973Pq81GMRejN8Afg1uaCQKq1+okMw4n3sYlKVYtTdKwJTkBmkeoAszhGWXjr6xYTP8uFegz7Yu5572ky1Mz9URyOw4XDWghKht1x3Ec9xDl7y+TN4WAmOxWtZZzuPwSsBds5dgn0lk1R3evTPT5DA8RBvB/3b00Fp0nQPMXsVamLp/2JKov178x2kQES9p8qjh3P+5pGnbeIEKjH2FqDg6KWjOfrhmTGTNW6MYJ3cP0MDs9wRBfaxd8rVMuIETuo0YE9yh2YQ3NpgL99FiwmvNQ2o0lPX4NEhGYvDHMJMoO42AAD3wOMsCApcK0e5gXXuQdrJW/VQcHirUocv7dTQ/Ae8zzBeXaJhBDgXN4LOUpDEA8SFnKtiDHgumVUCKSxqLdtG+NVcP4914ZU2ihO13azpKLpuy2St9f23kvmGDvsZQTLbl9I3fAEMa1JAv4c06d5gROHtDHXjFM0PWl/AEQVeCFELUKgtZY69uswTfjo4w/xwf0J+fqMcrkib1c8ryvk+z7AD3ww47O0Aqfz8dHfXuf7VrWOHn+3h34Pb5X9Xvf3OnOyH9ujNtSa4EANMCeCIIoCYJkjXr+6w/3dGcF7oLDjhV0n2dp6Gy5rAuARA2fYuq7w84znNcOXhhC6vnI09mqFSI9T5EujfN8VEPa7v/u7+MY3voEf+ZEfGT+rteK//tf/in/+z/85fu/3fg8AWV9/7I/9sfGab3zjG4Ml9rWvfQ0pJXz66ac3rLBvfOMb+At/4S+893vneX4husjjtITBMpoWtki0qkyUakO1hfz6nABxWO4cYIFsyQ29XaNv6vN55t+hBnAxsenOQx1o6QlsMy4f9WOo0RWC48ZtAoNc6BUQD+cqtlRwupuRP7tgihRgd4KxOU7Rw80OrRlYljCqiOe7E16/Po9Wwvv7hWBcqfj0k7d4+3hhu0T0EFG2rywRUwwUvS/GhjAmBZOZAsAZBVgsqO0VIhm5QJy4UBeheHbwAQJBqQUlNUQ/jQ3ZuWZCdQ1FFbPjc6lFh+PhRcFWR1WknKAIpqfUNTN61Y6LiwhwPgc8Pa54fq54fsx4+mxDzV0vigtmazBbYCYendk1jrF5NYgQuGFlBTsDSRlgtFYIVjkCdfPiTE+Ez0tAHbjzOY6koCfmUMBLd8rSkTwNZoSNH+/4zH1gxVxhOi2BwaAUUFPMEW1XZh6jZQeAid0zMXLes63PgrjewpRSGt/ddXWcsLV3ih56XlAz24GLgYvPj9Qy8Z4gWG+ZKaURgHlZmYVAPFuPacXsUYobTmHblnB5NsBMFee7E1QFcZ6hLaPWzE0mGgMNeQTxW85Y18S2EgHWbYNAkUrFuiUs84zTmQvfPEesl4J0zaYbtW/gvdJbK79nnicADS4InARIFTTXqMfgFC4AEIK4eQjI92TX4bJliHfI64YtJUyRgqt+JCdswanmhDXPZGVMSxxjorda5ZSp9RccwuzgJ2MGNToldsYdDuOolEp2p7GkYgBKEawbjPWhWGaCJHTFjAAUzgvWa8GbtxtCjFhOi90jGe21rTWydGbqHHjf0DKDpMc3DS4AqbbB+gmhV2Fk0MenKbAQcE24XirSVnE6+1GKKqnh7tUJT283AKwa+uDYGm5sqlaqgQjWOh0NJE7lxgmMoJPDBgIJIzzp+RV6sM+Wmc4wCsHZWGZLcB/PITrqkxlLLCfB9crviZEgUm8v1bKzSEeRRQOCm0yfp8FHR3fHGHC9FGzXilYo0u8DkE1MtLvw9MpvB5y8Zxs0BEME3QePU3AIHnh7WZFTwd1DQDVQMOeClNtY9gTGfLXVnQ6jYvbwwLpR42Oa6UBcM1ByQjadiwiaR7hDfdg7DwFbF0updD2NDqWSoeocNSO931vvhoOfJ+MOIGsgp4ycqAMhDgiTM8F8tpOqKoIXXC8EcFpVbJeE6h3CFHG+X+CjALXg7jxhnj0uWSEI1KD0Dh+9fsBlTTgHxhRqa74DQQeyMhqGapgl8IPVoRUjmRKPY5LQo3DnOe+dsNjBYJNtuDRjCWS4rmkwOVzw8DLb+poRhJV9HaAXwekjEwHAcKRicZ5gV4CB0AZq9faCzsbpY7yWAoSedJvWma2RIs2YrjLuEzXGdlY971sHtiorxWCi1GMrb0l6v0/Hz6kGpvRjjgQ+QvSoRQYTg2ADW+i5DxnI01sd5TYx7QfbFwGnL9hEkMF4V7sfXVNnHNI12vqH7cCX6iGRkhtszIDC7g6phoMWtEpnbspN9PWS+/E+toxVpsfzr+NnXcvIiTPmKHWDnKM2rei+7vXn7L3BFsZwdk6gFkN2sI7GjWJux4xHnp42XJ+ehvlInMI7DKMYAhyKlRZokpRN8yub7np/LmpjuOQ0xqEqoOJQNFsM1wyYNud108p7qSenh+s7jh/Oq2KMvdvXhui4Fx+ZJ7BCDQCtLPzOE5A3DPdUMvvDAGv3dse27+GyA1DHew9wzel6ssGYMLnuRg7NulV6m2rwbginqwCpWSuf0WS6u6gI5ztZ3JH3/2hl5/p6ZnMyeMtVKNNRKqUj+hwMLuCa6LzmezdI9FChDh2aFTQObaNsIaaRWP88EUHLG3MTbdBiTqtWPCm1WOuy3fdWDdBz0FYhPpqhTXeqLJhihColMlAN+IRpE3dq+piLX5T9yg6USNelI+rSlOY93gnWvDstswtGbf4p1B9H1X70faSV/RkET3OANsauwPsj6/fzznIH4/vRbG7X1sy0ioSLXhgYdlXS/3sfCHYEDAnaiHPwoTMBzSjCOWvbVWjNgATqiIDj6DTPZoohgO05yczncFhj315WfL919qRcsKaE67VgihOuyzO27QExnJG3Dc7P3DfEoaLsOV3dQZcDVs57/g5A9F4cbOyR3txI+/gW2T+EoHoeJgdjf3O9zdEhpQ6Kcr4459COe8+wZuz7Gs8mHllhIpRNmWfcvXqN7ekRn/3+/8Hzp5/h7SePcN7hblLM84q38uF7ESonhjPg0KH0XRzHl38uqAjenxEP4HbUqwAVDTThkJHfwq6a6buiaEPACviJ7GsImghe3S/4/u9/ja986xXePl3Z9Wauks4FTDNjprRlZAQskUw6aEVpiofZo2VBmiLy/R2ginVNgMgo2K1r+lL347sCwn7sx34M//2///ebn/2tv/W38Kf/9J/GP/gH/wB/8k/+SXzta1/Db/3Wb+HP//k/D4CU6P/yX/4L/sk/+ScAgB/5kR9BjBG/9Vu/hZ/4iZ8AAPzBH/wB/sf/+B/45V/+5e/mdOA9J0lYHB5ek/WybVxoda0ojYlrzg318YpcGuLC17HXWiFNEaeIMFG4uldeumhxKd15i4Pi299+ywp5UDw+XoxqL+P30msPPaipbQhPiwI+0h49Ro+cSZWdTxOr9rkhrQUPH8yIU0RKgL8oto3nGkyotBj7qQcBqkRCN9ObWc4REDGRUwwK/rIwQaoVmJYIf6UjYjW9AChGIOvkWPPpwBBFzc93E/JG0du0FWyXhKaNroMAqxng4pxzQamsFI42yOBJA28eKTdsK39PZh8rWBAuXrWS2ZATXRnffHbF45uMyyP1BXrgOGjPyj+lK+XfHAastdIzWEgXn7SYl5/Vqy7NXL/4WWqJeK224XVNOiji5FATRrDdsiKZZk53HlKlRhCZEdy2WlVkNAIA0Q29AAbqDN6aoS8i/edqgBTHT6+2RuuTbpVVYmpzVVwuFwYoIFAYp4i0VSynCaoNMdCJc0sbSq54epvw9HbdN15D2X0ISKlAte5tDBb89oMBoUOcZguMyaprrWFbE0QIzsXoMS0LQozmZllHa0BKFbWYSHeic6kLTCYFgi6ss6Y8NBbWbcODnoyCn4e+T5fXGKwLiyc72DktEdl0kMQB0dMgQJUmALVYu4Iln8V0AbdrRogRTVdsl81aLruWFu9Lzg2567BY0AVhMhInsi1KLkO/ZzB0vDMxhs5EaoBU+MD+dwHByLRl6mboru8TIt0VSyELSsS0QILg4X6mvXsutq41BAfcCOmNAEOHJgv1+7j5xjkykWpkbOTcsCW+ZoxVgNcKsTZvroetNqva0LwordRay4nfn1KmGYdp2IkXeKt4tqJQ2cVZ81bhJzfO8+5hQpyBMDfkpHh+pF4ZTRK6ZLjAUSJ8gGB9zE7WCuHAFrc5Bgj6eQMFIHAuZFlx/Ai2xBbK9VqHZkIvCMDMVUpSuKCAU0yzQ7o2pNSwXqlnSLMQwAexajOQKgN9uZBR4T0B0mn2NOVghQUODtEL7u4XSFD8b+WceX5O9iwc0NjS1yt3pq/MtvW7icwKc0cMBsqLN00W00LhOXicTqxoz7NHKQ1bAloVXAv16xQEok+FDK7M2wBnrki9ukunWGrT5HXDRx++JnDQFMEi4BhYuDrfTWaKUFBywbVQBJ7gcWFro/eYFzJ2l8VDNdAhzgGvPpyR1kJ9OQDLFBDgIUe5mj7mDwkpB4cauGB6U7WMvQxgEsfD235iQGkvSLh9H1UrvXY2l1Nj4Am1L0OMWJYZ3geUmtFq4ppte1xfK8b4OhytNRY7SmOQHeJoaXZ119J731EL56E2Gnf09irvwqic9322FzUIsDjTvTloph2iaicyWuakg2Dm2FmxAw3Ho8/vOM3wnrGcZbtW0d8zoW7c4Hy4ub6e/I91vu336Nh66qxdm3EDmY4vz+Wli9u4H4eUoK/53Q3QIaBpZmUbhExLLWglUQ/G4j/EOIBGVYy1so8LwBLcakx9MGGNgQ5ZgmZJUEOYZkTvUXO+ccrq27Q0AnBVWALYSsHlcsF6vZgDpDl+e49lXnB9eoPoAK8b1Cq68xQRo0NrBet1xXa9opYNr+8mKBpyyUjGShZxyEVvnm9VJcMDBEg6y0xdMAbBPtZDCICEcf9lxKM67guAd+ZBd1E9tpf21MzeeSiI2Xfyp+yy8ARDaq3orpDBswuAOUG2cedNeH0HE7mH344htj4ac/IQU4sBSlCgOXejadPbcgGuqARhGvW0SkEjp8ba8KJp2QaoMOY4slX7vRjdLo5O6E2thch7i9P2da/H7ipgsmALZcsVwQF+tHPb/HDuxkV3B8mAVAocCB63Wsiual0ag0H3AEq1oZuLxMHG45io1cxBWmNhwNiQHUD73g5r7zStsVwqSskIwdNMpB3WE+c+d/3cP23/S2f/vTy6i2nQL+6S6gYtfXw3u+5ihihwZCmqCdb3dufaKPje96e+tnz+CVurte4mAuI8eU3Oc3/TBqACuutRNlWknK3jhmDYPE+me6WjQPl9H90hOI91S2RJ14bgGgQNaV2xPj3hfpkwTQtyO9wPNd6dkGxwcw0vADG1tO6mHvW+e9oaxO6PU4X0fV52cFS7cKQ5R/PZ74W6XijusTGLPB56dOMcGz5PzAs1gGOIgxXG4hflb5pzyN6j3t+hhYa0PeE0Bwg8PghXvKmnw4fu39Fbg48M9S97GK77BYfs4OPNG9995RCQUN3V0nT/k0xOwGuGSBjs5mkKeLhb8Pr+jNNpxmfXDQEeXnToyAE70WPLQPQRW+LnxLsID7KPO0YzRRb6myq2lIaD9Hc6visg7OHhAT/8wz9887O7uzt8/PHH4+c//dM/jV/8xV/ED/3QD+GHfuiH8Iu/+Is4n8/4G3/jbwAAXr9+jb/9t/82fuZnfgYff/wxPvroI/zsz/4s/uyf/bPDRfLLHjmxTWRaPJZTIBhRCxNAVwcwUivXc7QKr4qkaThO9U0vbxkt9GpUs1a7ipStTcDTrS6Xaok96aDBeajTg7gmE1B1BMQUdOtzAjqeObbM+RhG68ps7BCKkpsgtIq9NuwtSiHgclmRrhumhZWvnChmSWCMQBu1XBxS4s9bU0xTwBy6Vg8FNkNwCNGE6mGsCwggChdNl8MGeS3cOOclkC0QBWjA+lxNaJ+DvtjrpsljmtgG0du5nFPM98bm2BQ+sspYMlBKwqRcMKBMsjtulbeCt59tePPpShDsGUPwuCcVe8BFDae9RntcXIEjbRUYewG885a8miaC24MVZxUgtgn2jYlOm7W7AjlWZ3KjUHIWTlAxJleIvJeqHLfjlFQH08uZqHY/1VoVKLgJMHrCoeBiEczdsi9aauCDeH72eqEbUpx3rZVaFae7mb3ulpiE4LFtgu264fHNlS2rAAMnVY5HX23s+LHjjAq23W4GFtyRglFWCWYymOkaR8tpQskFy2mmzto1Q7wYu0hHpXE+Rc4BraPy4ZzDKZ6QajKKOXWuOruvmVkCW0/5xAUKk0mBVh2V4VLqaJlWsURJYCYGbbREELTi/GeVwpxgRHhexdillRVEGE232Ov7Bt1bhTrtGtKfazOQmNVvAuigrXKrBsoSxciZrJIYPdYrH3wxwO1QhOJzG2NGcb73UDiUJnh809A+YzD5/LzhdJ4RwskmxYGdYEzD/jyYABz0SXJFydnYf3adVvXuAsF9HNGJUyyRqkjJWlwCWUbX62YVwAYXHNxMloODs4RO4BqGPlBJ1QIhBvJ3rwLuXwtKAc73BZenim2tSFtD2iyJf0+9sIuaL3NEt9LWVgmO98/vYBgUFym4rmxhzUlQq8PlKUFEcbrjllpSxXMuqBMND/xEvclt3ZBWMvyoc9gwnRyCV8wTNfoEtJbWOaCsilgbpilgEo8JXFudCMpqjmCpQC4b4Ey4f6tss1HTaYKMRAhOUAgLIzi2WJ5OE67PbPX3gdU0dWxpEbjBWBbHuxcCqeedoXG9klU8TRE5FSaOAES7a6EBX4Fj1gcHMTZMK4opeEwxAFzuACWwcTpRyC9EZywqh/OZwvmXC80JaqtQeJgsCqKPBtJzP9pSgQ+c13fLhNcPZ+rUBQ9JBkAcgsiX4uHaOmiqGI5j3ZW0tV1HE31+NwMpnOWPvVKMoRU1kmPBEEfmyBKEUChr4FjlExcgTeFcQ4gTfDBkX8nGvz1ZFiVK5r437NeJ3ry3Un54M1ljGfCmTXNs2ewg0miJw9F9Ffv32GfZl/LHViwCh+SIZ9pROFv6PWAFWvwEQYVYm9Fga3fXQTiTA/AQZ0UHMxMCdBgHiNB1OYSAeZkR5+mQVTmIUIBfVMgwPF6OsBhxvKoOJntjbFOPkwtFywI4YwNrQPEewbGSXuzZ4KCVOr4DO9AzmGEDtiHgLkIwxhvwIcJEs5YKb8yEd5JAm7eUDLFnoixsPV2e8a2vfx3f/MYf8hx0Zz8sy2Lzl8DFsiwIYcL5tGBZJqjZ2UNgoIFV3VVp5BTFgKNq8/BQUFFAxQHiAWFrFnEMZ+7TGK9l/LXrtPV8Ve27oL1AuDMyRMisd9JsvOkAp5nA9g94caNsrAZXh8FBj92c61p6u1t1L5gC+xyvtb0DhHWX0zHE+0jS/XeCvW2credjAOLovktiqX2YJ0M4xIBoLeVdk5XsbW+tqrZveodgcc7eUl3QnVwJTnOssY2z3+9xx1lc9TiMJ7X7wv13qEgZ+LKlDmI3uMNcvwVeFO88EG2oyphGVRED0FrmXtzq7T1hsDXYSt/NIeLgPXV0GTe30WLd26sBWHzdC84v1zXsCbvsLFO26O7M2X6MlvbeunX8oH5Nyrip1e4238HUW8CD8bCM+DSEAJSCJr5PKru7lIpQxSicdxYe72GzfW4HctXW+PFtXRcNGJqytXXDBtnnnX2nd4JlikP/OZeK67qhNcZsDpQHqOaq65eTnayi7aN85Ge3N4jX0gGyXtyD7a9ftM+1Wlmw0sPr+iQk6gqtFTFExvLid3KI8wg+oDJKuSFCjP/kMJaFRRCCxx4lBpTM4l83bamloEJQ44yn9ojnkvBq8tR+U4VHwyu/4inPNzdCG/05+3jpjH6aqHzBDcAtCNaXUV7fO7f5MDVv7+puWmPxgbIDDAUW/9wCsKqU0XGuGvOeMeJ5mfDhB3d49XDCt94+cb3Gjp1I8HDNiugK5EoAM06K3KxzwTuUlDEtM853C2PjUvD26ZZt/kXH9+Qa+UXH3//7fx/X6xV/5+/8HXz66af40R/9Ufzmb/4mHh4exmv+2T/7Zwgh4Cd+4idwvV7xYz/2Y/j1X//1QT3+sketimmhw2CM3f7WNl8LOBuAZOBMuWbkXKFCvSc4angRLGNLIQ7VuVp2YdHunJhTPrTRuNE2FkMAGmmxh6YKo8EzYOzulM3QyxAJnlyftt0xRBtqFdQLq9k+COZlsk1NzASgoBbBtmXktLtCxRjoPBm9WUPHIUobghubbbeoZ2sghf73CKFr6tg1C4wpxURtmqlbpIKhr1NLGy1FImQxnc8Ryykag4oshZzYHqnScP96Qi6CoA5rg4lxNzw9rqbNQC0LKHC9FLz5ZMWbzxK2FailtxI0am8ckpcOgu3bdz94rYdQAkBn73CyODFtODHLYEcXQVGgacGaMtt0QmeiWGVfPJwEW4ILHcPMOdF7gXgmTn08HTezXk2G7FpjvbeZgS6rqj7InpjYmttKQ3UVNTgTdnc9xjIdGoxgolUFhBu9gyJtFd5leAkm2Engd7smXJ5XbNe6D2DZg06e8+FcgH1ltXnXafA+epzurJVrpT5Va9QvqtZKtl4StmvCet1w/2pGyWXoaYToUXLF8+N133SVos4S2ObgGtkxrZLNFqeAbpYRxKH5Dqoq2TYKNsVphRZBLQ3zicmQZgvOmjFNg4E5rSHlgpQq1msiKAyPKXo83N+x9ThRz0zgkHKBqAEsNsY4lvyowHL9utV7GPovTZHWwva7eW9ZYruoGyBpmAIxMlAfEdoZcGKfSXHZHrQ468kJAShpgsgVgGK9JpTMCj0lyXQEnLU2YwRyfCl4b3u7Xs1s72pqoLAQ8O/sO4g5NArnbQpkfj1fKs5n6qA9vFogcCiNyWzVhprIVuvixMxJZQByrSge36xwNvan2SEEwXwKUGUrd4gF2+axrRXXp4r1Qjdg1b7t7YlMKRXnc0TJFesKY45gCASLAK3rl+UK78lIzlkhLqBkxbxwjyi5IYi5CheP05nr9/Oa8fi24Ppc8PRMLR2IYF48YhS8ejXj7ZsNIsCbTzdcryxinE7TyALnKoAGODchBKFzUSM70E1kFqzbwXXN1pMuCN8qK5jOe/isWK90LQKEbbvo05zzXmzfE1Bs3Ac/9hIRsuBKVsTI100T98KUVnihDlutXH3FW2V0MrC3NWhWnJYJy8T221Yy4ATXa8I0ewM7jQ3rBNMSECayXdO3r0xeoOgOzjoC826aQ9b302NC8g3f99ErPNyf2MpaAOoI7mB+37f70VrdkwZl8kSDAX+7w/SlcMglYJ8DL14DACqKOmAXGiTUYsY4iftL8GSbx+Axm9ivarN5WbGlbVSme4t1rzJrK2iZeyTdUrnPkcGyJ+feWytZKWN9b9Z647CbsTQBgusAKMECrRXtIClwTAxz2UX2maU0Y3CTweG8xVo9mRC2bD1vXKunxUB89GJm3YsstgfRyMbbONx1gcaWZPtId1f2geNXG+MbPu9+X27ZbP07+j5HsGBvg7NvIWDvdsdXMd0lOhE7+ENRYXeK6602O1DBda1/1gtgQGCmA9YC6fb4Zgda3x/w7wXafZwrgHma8eFXvoJ5OWFbV7RWsW0rWmHrYqoV16e3fM9Dw4cfLTidF3jvsW0JW9rQ5Te2y3VMnKPb4pHAd7ipYJHXA8EMDoSR2RHQ2hlfVvA8xE3j7vd7ig5Q8jcxeAjI7iFIQZCzakPnL4wlTtgK3G/jPAmuG1H1rg8mcAYq7ihaB4Q7eKgGHrXunIedsWE4o7nV7eNz5AGOMUFn8umIX4/rizGXggdAPdg5ToiBAv2lkBUhNo5ZDj5oIlnxtJsliDO2dWPxsdUyNDUBgbpdIqC3sXqTY/C2rvW1pDVFacIWuTAZMGzP0Bg2VQkSOufglLEfn6caaPOC1WLjtNTbMSRgEel4vJwu4wHsf7w7DkEJjzBNUDhcLiuu181YoIoQHDbDd3sRRsBkvud/bOMTbLmMdeGmZdT+zmIHY2QyR4sZ8QQbZ+85fbuvL+dDf5ZksfViQBgAKCAo8Kjix7W32hi71bLfCOk0q72oOe6YFWYH0AugwsOpQBosZyTw0cdw9AEOxkrThhg8Pni4Q60NW0745LMn3J8nysDYOGqtIW8bak6IpzO8I9DRcanx9GSfQ0fYdIBgyhep7RddP+vzIJCmLLhZY+eQMIIqFA21ZDKSmYQa0FtHDN7PoIPs1N1saC2/M9C87CB+DCwqllzZru+cCcBniPdYzifMdw7XnDG7MIBib/cz5wOBAmTs90JtzwsVvZVxP97BEW+Xlc893juvxvvefWPTXT4mOH/72WrkA/CkndBccJkCXj2ccH+3YIrejMB4hdT7JS7DTqdqz5zA6mVLmH1EyBvS9ULd3POCV6/v8fR0xeWasH3RRRyO/2sg7D//5/98828Rwc/93M/h537u5z73Pcuy4Fd/9Vfxq7/6q/9X3+2MeRSnzlARCkyHejNZcgMR4NboEhUVEgrOyzSYRF3IkRvcjmBqwwAY8lZuPpf99h53dzPi5NlmeGgdgPZqVJ/4ahOG3xUntpdUowF2AMSJBZuViOfdqxM0WRXRBj1ZNmUsYsvCqhBb+TzdCgMAmKi3oxOTDgqzYp4B5ywRUiYSvDYDkwjdEzATIEwUS2+V4vjNmDXTEkbPdTCx+BgIFHBTbsggm6YkxbwA0+LhC7CtvCe1ODy9WZHWjLMBaNnTUeXxs4SntwXrFai1B53NKsp9pzTdIQsiILfhhKBBpAcBALQzlwBABlMh+C5ea7oPzo3X8PmYFk4u5hJJjQEnAbmW/u22eBpTsCiylgF0QXaYrmtgQQmUlUwASAzYENsU+gKg7bAbKBdVF6ydr7OXvAzQk9ps9dBmWhBjwOVpA1QRnKCcql3vHlASkO1MR9v8+1kzrwGUba5TDFCvQ+8nBCarqgqsDd7RPtdNgecIwXZJ9qxop+wctThUuzguE5icM67XasBYJD3ZOUALHAKFRkUh6jDNcQSAdGfDEGZtvYwEsqNEyb6iBolnMlirGV6wia6UBmzUs+j6R6VUpq2WAM5zGIlcSnz+rCjzRnV3Q2oAWXXbuZu+/r7BkhlOAL5VA+5iYPFcDKB2ZrLQrw8dqN8XphEAqUJzQ0rU5hI43N3PKFIxzWyhfvvZZvp/im27jnW11IJcFH7opPAaW+taFfwep6DDW6vIpWA6zSN57AlhZ0/4bFpbpaGVhlwK5hbYAuc8wsT2RE0FNVeadBgbKHqG9VstFsOR7ZSvGXH2mE9G2zdgrNYdmNIm0JMDNGBdK0qGgWEWqNuU6pqQ1YCCnujE6DAvERCyiwkCUkcudC0/u1Z+nyLMbFWBfS4uCc9PGW/fJKzXim2TIXLthe3X3jv88T/+gDdvEtLWkPMG7zsQ0AB4wvkqUDhjd1L7IpeKKXYtnXoTxPS2fPZuerhgYGg3epmM4SsCP9oQWJfzYQfE4sSCkzMGah+DqmJFHtDUwzlMwSN4wWagtPgOWHpMp0A31saEA9K1fSqKFZq6I3NtlcCfEFiAshp5dhOeHgtbLs0IQQ0QUwX15ZwFX0o9yBAFUwiYnEcWmjH4bhBQxJLXvRin1htKJg9/J94c/NDBpK4Nyfs5GLtOWZjrQEqfMT0qNmzCvmkkvSkl6tSEgBCi7akO0RLT2ipKIyO0lIKiZby3MxH2BLZacrQLaltGD1U6Y4UQAWF75D5vxQLsBhjLtguW83MxXBO1t/HZ/iAOQDEW7kgOx3Y3glz0P3FgxYQIXxPW1EbicRzDQN/dTSDf9NlYcFCbD2wfegkmqVLwHWKM3NjTIIx7dxO52787CNMF2G8+Vm7LbjdzDmq6W3sxpTOK9nssAziFrR/O7Sz88TU9qrDWth5bHk/1847R2jnAGL4vThNexYj7h1comY5dJSeUUrCtV6xPT4DpebXKFqBpohEKtYDyKL7t+jsRU/AGyAaItd8f97n+J+caHa15vXu7UY9P+VMetbHs6sxxc4RuBvK6njPbXsqW7jRYOb2FrwOkY44A8E1Gku1kP9euxdYDn73gemSF7WBFOLToErgz8EcEidUAaGcC2frpe26gXHH7e8XvMgPHB+1DgBeaK8U4IZjA+xFoZdHcoVrsIyALsElDaeWd6+d8IkuGmlgVzgU4YQxHSYMKFxzZfN7DS2+p7PkSo2yyq4AYJ2i9coY7AdTfEB329lW7o603qB5aWAFAdeRL/Xx3fLU3Hr9sR4XpQ/c5YK+9md4E0kOYUEvDutH10EGhJq3RH7yIM3BVIJV5TNOe1zE+6cYf4xyO54N9uvI5WSHY83m+bL++vRYd2lI3Q8HGQ9eXVFUEBPgA1MI8BcDe7dMBNRvDPY242Yb67+U4BwUVHs38FbvDqZPe+s75NgXGwa2x8LRMEwTAZd1wuRZcciaRIu6ajlCaEpSUIK3gNJ2gWyKbHfuJ9fNTPdzH8XRwgL3GimBnrmM09c8QkPFYbex1KZoxppRF3loKQmQs6624VEq2sN74kH3MOwc4uhyjt9fbyUpvLQJG3H5dN5rUeHakbdsKBTCf7/HNpwv+xIdkX3QjkW8/Fri5IYRInckXxyBHyO1YG8/05eux7xkjHX0xDt73vuPhOyv+xat611Pf1tx7PtRKlhAAp9nhg4cFH70+49XdjE8+K+PZ9m67pgo/eUhmvO4cNQuvm2D2sDX0iros8P4V5mlGnhsNDVL8gqvYj//XGWH/vzxipJButEq4E0sUrD+5H6rES3rAQhqnp5MirJoiFJAfQuANEHh40+xRkB0QXUDO2TZya/cJAu8VKtw0YG0aCoIIXR+l5DYofiJ0E0sb9XqagV490BFHAboQAiYfUfxOYe5DtlUy3XwQeD8ZyGIAkOy6Zd6xgpS2gm3LJjJMRkOMgqsQCb89ZABCrcKALWqG5FRwvbCNSVzAvHAY+b4oGgCWDRDowQfBQNpEt1YNSKrjfuRExh3zBTH2UMPjm4RtbXQyaQCnUYHC9HqaB4GwahNTDejC0MYZq8OY9fZLIfA0TftU4Bq9rw7OCdAcRRTBtkjKOFGkGg2ohRVjammNW0h2j7VpMGFqN2Ozg2ClNOxi9tYi5x2cV5hUEd+3x2IcAwrToGNbHgM42xwtSEsH1iAt3I1lJoI5uhF8+sEo2yt9XMy4azZzNRInJv5pRhV3AT6ayHsMdPk0nRkoN5llnsAWRp5rzgX6jHGtnbU2zRPEmTQFzIGnNMCYCd0EQJuHtoxtY5tza4q82hxJHHdswTGdiVbH/ejVuT0K63OzGJDN89pyGc+u1TbA6hgj2Z/aDqCDBXbNggEQpA8TARqVPq54314GNtPkjV2zV0QGTtMZguB3tkrXRzhq9tVixg/2zNZrgQ9AKDtTR/t4BKC1PyuCE3HyaFqwJbaEeBOPr1VRasMEoLti5VLHvQAwrq2vuS9ZMCJ9TWpkbM0ekAk+F1sbFNu6oUKGpF+rbcyTDoBMkcFILtWcsXgNNbOlW607t5tKUHAY0FyghW2l84kAxiZAyUBrHh0IgwJpq7xfraJOAa2xRdWzQw8l8/7WYu3EXnC+j2ha4aOZWVjrK1tQHaRVfPbpBQphO9+1gLIbgvNdILDYyALOqWD56IR1a7i7nzgeTCtvbwdx0MYHydzOD3aCczDNys3u/V6NhIhpCjNg7EFMKgUnVMRpsqANyIW6W31vcdbKFYI3l1o1oXOOkWCsGKCLLCtCsECaF2gAkpgRApMoyjSycNOZCttWsOVC4whgjKlgTLSoFbUKShacThMDQ+GcLnYfSiG4x1bNDJGGOAuWxY/9qzbuET0e6Ps1TAekt0SqTR4RMtrcgSkB3avpFTuocWS2DIHtvtj0eL0ndva6rjdSi+lXigIm7HsDbkFv/t73kiNb6nh0t0lvWl7Ho+u9qAbsjonOWiPZnrPPY763WrHglhmFm9f1JCq4nYVOoh4TPzFmCEGSFwme3Z9WK9lCByDl+B3O76zC+uJ8ehsRE2gdyXxOlAnwPZGP1n7X28beex2dHfEeQWKL2J3DiEvGrwx8rko2brH9l0xbITjv9vaRkcx8wdEBMX42F4DuBPp5ubT0/1n80Azc7Sa6XhzcNCPGCVhOXONzwielIJ/PcHKHnBKLW4GFrM4+UidIG01sGhT38xkI1L6kChDeC0qO67VxIgCftSo060iUFUCu/Vky7o2hrzH7I+isv/7MgncUccY+vwgSq93zvaVXFaRp9dbboRtExpDYpnlkg0HI6mOBIqMUfaebRezkRrLebM8Upt2CW9H5o55UP++dDdT617Id0ptpBGz8N5oQ7CxgfkZVHYChamNnh77soOAYpLsm5zwBNQeBR2uFLfCNnRxVaJg1HCfHc2y27vFzHehGDjiLpXcyQDMgvgPNPSbqY+I4lN8d1x3a4PlB3PtedAMiMk/RfS6gs7y4vm412RoCFG1IOdn7DuO2Z+e2gIt97rEI8d0cgw33np/1PadfrxOKi/dv7+Ab2ZIyvt8H6tnKzmmAtoKaM7SV93zXPv9ufj7MCASQgKZsGfd2zb3A74whTHfWLrHDO1IbNYGfrldsVtyq2gZ4580dtJSCdL0gXU84ne9wJxNEwPd84Q08PBK7M/uTuU2TuqKjjHvSeD99b8LbIVUqGnUg7ITWCttcASMDmInFAMA5x9CL00dkCbhZf2g0wtb2dcsmvM9ig/cO03zCJ589427acL6LOHlFVo9rVmhLeHVvLp2mU3pzCPCuJvb7jz5lj8PsRdh+e6vfsy85A/yathvn9WOn0MvPP35gsycVvMOr+xlf+fAOr+4XvHl7AWpnkzvEEKjzZWAkWoWAeynNFxzm4BBKRkmbaQIrwjQhTvFLdxn+kQbCvLUAxuAMvBKUtNM1iVpgXxRgrYazxzxT8Nf5iHWl/tPleUWtPUmgno3zbE3oYAH1nTr90uzUhcFNsyQaysniHIijCwGdnCrEEbjokzJEj/WaMFqkwHYthSJGT8bFWm96xJ21DtZSTXuHQWzJZezATXVU7ptTTBNFrmtrSFvlxtfowPVSN+EmCGz8vbegdtvKWKgAwTJxQ/Zd/8UC1FoayNTtCHEXdWTgWa0CDxO9BAg85lTw+CZR16001NKQ1oZWiVuxEl3QtFtyRww8v+v7jCntyEQQBmXNNl8VJjwdHIgTz72ULkprHwnTf2q8H3GKRnWlUGStCngg54Kct5Ew+eBGokp3O05aKJPE/sW99aoDUwABppKZ1bemxkq0ZCnvwvuAbUqVwVgIu9tmTz6ogdVG4s51mwm3E0HaClQneyamM1Ua55BptGndVVm07i023BbJhpsmMsAIiAq0knkpwnaa890Z0YLop6cn0KCUyS9vt51jA06RlaVSKnLigh+iaaA4gQvdK0vGa7qr1bf/8C2cudexfafBeetfV0vsDgFSa2RjKjar1ldjgJL5wXmIoaPhnFDof4qm4UUmjvbKcANgjqFiDJ/TaYafDazobrO1UUDduZG8huiNMSgDIOptu9o6eKHQSjYinGCeApZzILvOGIEEThpEG853dG1kizUDxi0ViiN7Al7LeTJwo4O1rOg57xBmjLboLti8rWTOMVEQqOsuoRR07zseGXM62FsdYJtPE0IMmCvFy1UV67UDYRaM174eKII4zFY1pYiyRwwU1BRxxp4UpFTRamQXb+ltKcZYqqwiTTOFtX1oyBu1lKppQMoILDlHepzKDdlzbykNNZt2AQh+lGKAkScYUTLZbuslISU6bdWqg1W4pe6yyNb67koG4di4XDKmKeDVB3QWfXq74nrNRt8neNMahblrI3NQYW6bnuBrD8i8teYwYe4tGDaHjM1ci1lOmw5iVav6qrlLGuPV+12UmLEidZlaa4hTMPBGCHpKhTilq52BTGLnX0qFy24AEAR6gOv1CucF1y3jct2wXVacpsk0R6wq66vVLyK2FTjdBTx9tpn+4q7ZlFM2/Uuj2kMH6yIVmuiU0uCbH5BgtSCeXQ4NrWa0Y3KJQ5BnyZc4QcdxetHAzJYNFFc0aQP86i1LL4sy2pQOZS5AujBdqdCJ86Zqg9bMxFsJ8h8ZpR3kep9odAcRxAm8+pHAaGcpWZLtQ7hhXvRr2nP/zpa/Zfio7i58FsJwbZAeD/DzcmqoIhDnTQj9XTHpVumUXRvgG1kovR1CAWqFoI5xPKaExUUsfPB+VFDr0RvYB1XUXNnW7RvZOzOfj/eexY3DcQQfuR4fwIljgN8T/AGK2l7dmReN51XMMbG1Cte4b3ObDgaUdNDjPVlH/66OrhhI28Fpb0Wi92UsfU0ju9JAkKZA7a1PFjNYm5aKQp0x8qCYlwWtVYQYEXxANtdScdwf17Ti+ZIQpwAJETKdABTURFdEHQCSjPun2tuXbT70+WHPtIPqtbFFvt8XAdlO3u0psNg4pD6RASkCdKbiEZTuRZpe6Os/885j8mw/T/nZ9mUD4zqL317bmfE9werumce2uJ7E9e8jow5W0OwF010nrhcd+3UqYMZdfOgdDO5SJU2AKrteWZfo6OezgxjSVYSA1lsbGSv3z+xgemvdzbGLVLsBMreGvZXYzrVIfy5ki6pa4VO4Z9RSUEtCnObD+BXAKV0k6+1YFWPr3fxs/O/2pzYSgO4W+flTpl89eutqn0L9efX5uTMRxQyRDu9XNX0j/tsdUIPS4+rv+uBz072/jffWYlQVi7EP19+7bmjiQBfCLl3AnI+thU1dX7BQS3ovi4i7qo45d7yJNFNgO+RwRX6BCZJtSPdFbyB2VToBt9awlYrHpydcNxblQvDYUoHe2f7pOLdySrg8PsNNE06vPsA8BZzUo5WErLqH68JCXjfs3PEmQQeW2c6/r9kjZsbODGMR4YAC2aV17JD7jOm4td2hua/nfV7T5db2Q39gBrZbZmAH2WB5+zTPeP3wACcOb5+esRZjwDkA4hCnBb//zW/jdIr4SBYgZ7RUkEpC9g7zaRnr5eciV1/2OM4H3IJVY4XV/XWcR/y9N6OZpm3Xb8axRVNHMWPEPIL9wdk6JyI4zREfvb7D6/sTvjEFXFcCgyE40EHdGNnOoVUBmkJKtbbbii03TKEgbxuu64aUCtwcEUK4Af2/6PgjDYQ57xAnBo6+L/AGQnmrpDbsA1McME2C+we6UMVemVbwJl4ranOIU8QyE2Sj0HlALRVpNYe3qiO5DEFuqo5kk/jR0lMzk/myFT6g4LBeEmJwyKVS7FUMs1aCKtRccfALg5NOywc4cAgMAGlL0MKWAFVjBkl3STM2j3cUyjenvuAdtmvixiwGdNTbRnzqqzB47SAJATq60dE5iO/NqJimOIKFWgjIKdRYJ5xFtTRIVWhUlGzOcZWaS60RGGiNLnTrYyZA0TowIIaos8JIEAyAetTaL0QPgWBHPnu10QKu5gwEk/GaPoG9UdFb3UUHRXp/f8OyzJhipDOmKvJbs502zaa0ZQvCw95GYjoIrZFJ46W7XFnAJ70dVhCi7IFTI+BQRpvezsoYi7ct5NuaTefKtOGmQJeN0pC3gpJsk7fnGzyTk45ndRAVELLaWq/pwJA2u62iuxCoY0WdYyuaOyWTdLK5OkOFZg8hRGp0lIqnxyeoUs9uLRnJ2FtTbzFED6Q2pK1gmj2d1ELXlVGUVJEzbYzRBNdtRQwBZTPxUOH3utATcQcfA1oRqOzJrffcuNIljbmlTTAtguBNU0RNBB8EYe7uZ7YTKUGlkgpMnmgEbsfAyAfB6TwbiJ6pD9BMtDeCwYQJinYW4stKpOrLBJcJFUQwLw6teOSNG0PKFcEz6ffBsdLd2rB2b02pqRgcXr1aUEqCE2CKDgkVxZiN3tNltqlgW3PPvwheOeX6ZslhH5YqPZEBvGfguG+uu0DoFAFgwtv6bMkZQf9Umm2Qap/BitAUIqq1QsfoMUWHWuha611fX9huUJIxMRqg2pNEtofFKWBePKaoKLNDSQ6lMEkWcbZ+W8ujAwMUYaCllhjkzAKDM8SjNdMTFEHNiutTweV5Q0pmlDBo/g25NOQCBN9wf+fhHBAnM0/xMGMUxTR5zKcZ57sCJ9R4aoXVMxYTBKWClUFt1rpJI5ajnmUH+AZIIoAIPz9GT0agMCGnbkmxtmIaQ/jIYCeEAB96pVch4qFijqi1QcFCToiB+2/guna+m9CUwv89+MkbmT4h0mwgRk+NDAdMMxlc23XDtiVoaZhiRM4NJIWyFX5aIqYouFwicgpYrc26qcIFCqWWEozBSRdaJ0DzZLK5bhsvGO5eY8q1Rr27km4T9hcgE/fsfc/sQbRYQt+BsAIWp4ZZgb13/xygMzFybhAJKJV6nLkL5Ji2Vhc0ZrApN5X5URxBn5PST8ZY5lZIsDW0M0PStrJ9ywcC1zfntid8hysHpOsd8nqSaSFqBxOd6QK6vTWvf6w3JgZEUBr14/odVDW2lAXN2naRZwHFwNEqvI8Hpth+zmLj33tvjsoB8xxsnyxsoRRQn83kAlptmOJEjdcXz3cw7KyKNkSlVWDkaCvMwNb9PejWpuOJ7IUEo64q12TOz/7evRV7ZB0v77x0Jkob1921XAUHoO72afEs+ucf/mvVkvue9dj3lpxGPJ1ThhOuwx0M7YWNUgqu64ZSG6LzNHZwnnpTxuo9XkoHAwUd7DokrSPk2M+/i+cfj1Yr9H3sxpEDGLCkHZAS1hjsITUxALhRy8YJMHmHKU6gc/YTC8TR7/PY2nFEHETrKF5wbYwAdoZYlz6I1tbcWfEEqxtyZTHXgTp1/bkdjw5ujbHNh0cNHgVy5fd1YEQOceZgQh1bmZXFTKdcm/jIrejEEYpSK9a0WbEpjsJ7B9hcL2jYx+ZaQAwnIHg6LRe79xCHqsD18sT27gNjUfo4ln3N3QHEgHcGfmtk7ujtunkjSn6MV/uvDwDoeMkxLrN7t4NgBjS223HVP1YPoEy/D60R7O3f15mw4xw61PRivR+5RytABdtJm7VOG5h4BMF6jOX9blJlGzxjMoNxSlWsWSGOLcxq2m/vOxjV7GASbxXXNrZD0lSnk33eAUq0S2Ts607vWGrapRQiSqtDp7ha4bvAkfVjbPjr9Qo8TZgvV3h3Qi0Z3nSJkzaotUL3E9hTPe5rzsZyL1QR9JRxbV1fUDpr8b13ZCzzBK5Kg6wr3Zft2Xprc1YDI4dRW+9A8AG1pZtBUgGosb2hgmmacDopti2RMFIb1lSQMven6Dwu2eP3v70hXze49i2szysW5yAB0ADTCfw8HEw/9zfvGwPvuxeGq47fHfeQm/cLdQZFTWdQ+3rPN3O/OsRNvV+y3x87QvB4db/g+z58wB984w3WLdOwKQbGazb/U8qosFZ6zzUylYY1FyzRI5aM56cLzvdnvFqmEZ98meOPNBAWHFkXpTQ4CShFsW0Z21Zw6+gglvQz4X794WKAEjVPtrU7+TBGoTtVxHIiw6Vai053F4PlR9Ri2kXQW2Xi4YNY+x+FwdlKwJaex7cblqm3XgBbNf0O01jJ62Ytl7vjRm9F6gt7OFRad4qmgSi1mXMdAy8f2ALaNxKF4nw3mzMlM9UYgjFj9sFJ3QcAYPvnVBRoTIBzVogG+x7BZaXAcZqNOeMJiIgD5hNdPVth8p9TwdPjFdvGtsaUC6ZpQikZPgiuW8LlslHg0ZIytmtQEHwEe3V6MRreFzl28JDgyn59evhvoC8ACFz40MEqspuo7+cGusyxE/H27WrAEgUrc+4tiHty3CnLsVDUNES2G9Wi0NIGxRnAGAO9algyE02yYIJdh4xzqNY+lnNGXBya8rPoXmmMrOig6tHdUH30OJ08zyEzGSylQbWMQHkPdoHDDYRa29A0R5zvFj7feYKijqBfVUZlMBqYDHNaI3uRrcXb8xWlFKxrM8qwQ8k9+CqA0E3vdJpwOk0767EUrKUgbZmC1w2ILqKbEinI2rp/dQI1tTh/H98qsihapTh0b6fY1s3amxU1e8ONWDGO0RzFbPw4EdzdLaiN+hIuJGQvSJtAF15/y3UkbnsrANueO0unNbKGamlobm+r6EyNPs6KWf96z2qSPXlMExkPrNQ7nO8jngyc19YgIWA+zygNqBcyteYpwDkxJ9yEjz66Ry4VT8+NTIyiiMHWoNywpQrJaqwMAj59h4zRmWEEQeK0bRbwWwtfb5sAxrpzDAC9IWQueDzcna21k2zbzrwTB0RPrSmCFfx3X1tLzpgmMksp0q94fLNhWyuWczSQzFniTbA6eIcQI6RWROeg014xSltBThw/3gumxeF0F61922j/CrRGQGO9JojzKJWW0R5k9Tx9esW6VayrtZQIDETGSKwVna1LsChEa7uPAaIF3pHNEkPD3dmjbQE5ESz0Tkx7qSBOTMhI9jMNI7vOo6NhZ+4ouqOa7V/OwLUApEwGJRrb4OmiGzBPcbRJwjk0NVDI1qg1bXh6vsIHwcP9GSE2iPOQIHj44ITpFPH8vGHdDnb01v4dIsGUUhVIBZdLQqkMnFtrQLDWBVUDSALEZWhrCI7rWEkT8lawrZkirYbK9hY+ESaUKTXUuuLptCLngiVEWI469gSuPemQQHUAUfc1sO8YI/c6ti32BMHmL1iwEScDwLpJig5/OgEqKlQpklub0IFPe8uRGgus2Z5orYwAoMZyVoV2MVoXDPwy8fbg4QLdKAm+VOqz5AwfzYnQ7YEjTQHYMNJ5AxS53wHArq/ScrZ9me9lwU3Gvta3EO+ETD0Dj9QJ6jG5qhUhTNBcWXxznXFmYLv2pJVrXzf3YJGMnwsQpEtbwTRFnM+zxYQsuIjpWqkq0pbGs6JjNKxbVtEBUOgOTGjfZOwYhLmRoO1AWGfl9qSta5oOt7IXQM64B5ZEHp3xXo6XY+xyHHvct977seOzu67VHk/eAiaqiu16wXa5mGZmpdvmFNFaRUrZilB1JIJk8whciDyP2naAwZKipmw3aq2OZPJm9lkR8nOz1H5fe9I9nhF/TiMDa1M2xieUerXHXEwdUFpFK2rmDcZ0VBYqa+2tX4c9+VCI7fFJd42PMRrwmg3E3AFv5xy6cVA3VKBOLZ/m5yWYTgTqPGBABl1wBQ3snnDNoTmLxx0NpUop+/M0wPQIHDSQiaU364+YWYGD1AYVbzp0AUCX8Ohr9j5kO0hWrIvBOT8KMLCWXw8ZsUwIYRjt1FxsbL9Is2XXjdIXY597WW/d7msRIBZvQgAPmoj1TxRxaPLi3trlOAMtuK8XABXOGYNT6zCzOL6x1GYuwPy3KBmrY68QgbhI7SR7Ds47NDjLPfrVdnMaA8O6IzdkBz/B5On/S96fbUmSLcmhmOiezNxjyMyqM6CBxgXxcF94X+4in/itfOGncPFDSKKJBrpPn67KjAh3N9uT8kF0b/OIzDo4BHkX11mwWllVGeGDDXtQFRURHe9R1en7DAy/QhZO6siJ7NVk31hziA+DawB13G8cBl8KEwTjeTcISv8BiPABYxnrycD1W2OsHJxn7Gae0l9fXmld5Bz20gDf4SPXbPGCIgrNBcvlhs8Pq3kGO6g2+F6h4uF9wAxB7XD2z2Dy3V/n/erqxcAZcfjxqvv+6B3IrUBVcArxiNvHveREhoIFxFqHB3CCaw3fMZ0BDG9kscJFH7nMvuP19Q210vdzXSKCOvzDP2+oq+K5N0iuOEWP8+dH+M+PgPeoMLbnu6/6byye745DxvwddKZHLPNbnzrW4HGv3dyHdL5nFnUAYPQTtYYlZnzM34jgtCb8/ucnfPl0xr9+fQVAJZ43W6pSGqozKySnKHafe1dspWMrDUutuF3ecHk74+HpkXll+B9BGukF+1bx9lLhXEEIAduN3d2KodDjaQ4puSr9S0JKKFVRb+wARrNmheuClBz9fbzjZ2V21MsGsAFGxjQpQSnV/E5Mz9069m23s2Tg5oKgbxVfPi80OPdM/IaXEn05uLiGJdHwc6DoZnhO1o1iPXmT47h3nmODaq44pIzeJF6sKDg8PK3otSEGwXZt7Fi2eGw75ogfskOMFM+Snhg9XPQIQVFyQa4F1Rg6tSqcJxgYo0kApWNZPc5nAhmAw20rEGxIa8D54YTH5zPQBaV0mh9jMPnUEgJWimeVe57X/TF2OLEGh3dTd1SOPgRegLEIOv3llpSwbRmAItwDTjgmtRNKPn3gPd33Ak2Kh4fTZJLk3TZkJwZw0KckpYDWOv3saoN3gu4dam1IMRorhJt6rhao6dBKGythSLcw5Frc+CmLZQVcbaM/RXb4XEw6mPeKnDMTI0fweIyR1287unbkveLyllGKHqujc1y03GBeEgz6/NMT9pIRfCDw3BogAcMnADDJlY07lTYZlrWxLTtgCbYAcCaF6KQkx5X07yV6hNCNgaNoMpgMBTV3aKV0tQs3nBCcmX97hIUJRb1mOEemAhSIkd0K11PCvnPgl5wRIlktMS1YTonPuXdLRpU+eUtEiCdc3q5orSIsHut5QW8Nl9eAt29XtPFcxP50BpUxRqhXaOvYe8a+0ctrSfbcjLXTW58GxM6Z71oIBoxzbnlHJhE6gGQsUU+5a4gEHXNmNXdZAR3dJjs7kKp0nB4TPv18wuuvG6DVkk92G2qV7J3WO2oBarVusA8RcTFK9Mi6xpzTwYrt6F3mmuSE3+kA7HvF5brDB4+ffnoyNivlkTTI7vCBc2Y0XnDOI4ha10Gum9utcDzUgtutoHVgyxXL4vHYFI+PghQjnj6dsawRtRSCKaVz7XaABAeoN3klgdmWOwskiQb8XmQa/LfS0RxBYybRCqAjbxnaBa0W5BsZD1TEqQFQah5mYoCAgzaFDx7L4pHWgFrZsMRLQwgNTjaICB7OHugR25WsTufYnahlteRfoJ7AD5zH8/MJ//rny/TvGPJDBce+wCEG7hLBsTh0rB9MGmsvlNJLQKsOLkSsJ/oOtkYfr1obGZGtY98rfBU4bLhd2Vk3LWGa66+PC/zSMFjq2nnt3jvkfadkdNtxu92w3Yqtd96aSlB+0mqzPXmhRBUN57NHLQkKwe2yY9uLFaWODow+ME5ojQliaQ2XveDxdMJtr1MeRrlUYyVYKKEdwK/ebTEjUes6JOt3IeSQP939NAibJgwQbOzRzvzYGJAqhtcbm9mQGdErO6i6YKDW8JYSAdyAp+73N56fDJQTYnuikJXhA7vWKuc5tB9d7khlPz7DUxbD/rgGADqHIEwoelfurToAfwNx+JXT/+g+YI7BI3qPMAo/7mDxjIVkSQu8r/BBEcT23OkT5Q3A9fN5OSW7hODq6MLooUo5EJmZZoDcOmQAbKK47Tf03rEs6x1oMO7n/BcG++H+VntnvrRWQB3my+M6Sq1wxjYfqoPWGvwERuTAAGyUzXuF9+eid6DXfJ8eMcrxrffn8P4YSetga49unfdm+qJAyRu26wUlHz6DwwNo3zP9HNsBVDjnsJ5OWJZljvnWmai0wWRUQc4EuUcsAz2keex62H7IAPvRdTQrInvnMbq37qVwDZ3nQCDyKMLwGMWRbnuWgA0o6NHHfc6FBba0477BAeMuMnIJyvKzp1m9rQlVK1w0MEwcaq/zeXljaGOAOHjvDzaeqXMeEumBqCZTpdrF/MHu1pJRIBzjxcXEggAGUDvNQ94dowDvAKhGnIT3MgwJYBC0zhzjnsA3QXGhJHLcY8Z+BB9VgcdPPyHGSPDcATqksgNctntCb0oW1gbbdUy2kZC7+Qzu4nFnHoCAwQJ3jMy7RP/uhwTNgkdKCcF75N7AHE2tiF2/m1f3Y4/PSg3QVoxChROxbpZjXh3sX7lnpqhYSmJg7gDUiOxBYHuPeLJORZBiwJKsWYo1Luj6vvvvwO7oFVvIknIHc8nJyEdGxXisNwT4tStd9cQTGJ1P4N2pj53guB9GxBjWLjEEBH/4RD+eVvTe8fX1gpfLhr0Bn+FwXk4IaYH2Cu0FHYpaMl4vV5xPK8efq6iF7CDbWunVZePvY2HpN49RfLj/UVeoM3auHRM+swuvlYB/CLYfm5H+tCVQjvfaGlwlWOd8RC/5u8l2D80NdnbXg5l9u23Yth0Pj2eSK3JGcw5/3yv+Q68oPSLmjNwbmkS0Ow/rcY33+89fPt6f3AccERMJ+wtH6yx4c+0gU3+0eRl/fvy9csQZd8eaAv7w0zP+8OUJ/+k//5mAqZ2cwLCL84JamfdVG8oCEpTecsWaKly40XMuZ6pPlv8BzPJL6+g3Btj0l8jYc0MuNJ8f9HM4enkBwLp6Mh5KwbZVXC67Ge07xLSAsZQgF9JUyRRoKBaMkwHGBSomb5UozDa23OMrtmtBLiOR9VhOCWvtiJ7dGx0Eb6803Y8uIER2+1AVlFIQqoMiEgCb7CB2w2QA6WeVSbtOGZjzDPiPqj9ppb01nJ5W6nmbR5GCsnWc1oDX4O8qVdlQ27ulUI+KaQoywcFaOvadpve5NMCk6Lk0xEA2WEgRLgbccoP2iv1a4STh93+XbEEgzhITmS44L0ghIG8VJVfkUlAtGOkYLbB/sPjJYCr0+/0Qo0JmL7ENdLDdeH3RWB/0egCAYIDiYdwqxlLpvUOaWNfMzgYLpeGn333CvhV8+3q17lQCFwgc0YenW0eXRq+SpmidkqZRLffBH9dqwWY0I/8Y/VF5E1a8Q2ASn18KIEBaEoYXlVpiEpJHXExC/KYopeJ6pYzztAZc3wpKrri87ZPFMqps86a50RHUm68RZWbrKeKXf3mBCkFAUqApYRnd2A4ZonXYcs6ks7z/wWS1pVSkGlD3huXRwQU2itBG379lZQVBlMb2pQC3Sz0WXgf46Ez+FunFV03nj+ERxHk+ZAxpCXj8vCLfCt5ezbclJgPBDMS8Sy84RhQ+qNF1+fO0RKDzusoekU0Sp0oAe7vt0K5YTgsDk0YAx4mz+zS8DetRbbfP7r3zfnWlSa0jo3A5J5P9uCnlADDZDqo62UxMRAhKxkiZ6r43AAQqxCnKTeED1xaFoOSO281EHCpwHpTfeQMWMgPaXgksTSlQb+jdo5gazlvHS6/AaAQy6fMg++joylkZ9AtZcsmq7c6b9CVwI92uG15f6AVQKwOwbefiU6vi+pYRnMPpc8KSFjgHXHvFfs1oRbCuZ8To5r7ctaJrQ9disj2Bj4K4OLTMe/n5c8LPP614+Zbx9esGIOJf/rShZMG+HYmQF4EMvzgdIfpghHE9ct4hLuZbZGvV61vGT58CHp/OAA7fEec9zg8eKQGtsRtmy/Q6YvLBLmrptEK8R0ob/Q5LpwFrDAhhyO8xWWkxBSynCHZW5DiVRLZxiAlxCYAT3HJDt2C+KZC3gm8vN6Bb98/ugObQmiCrGvAE1K0hqiA9LFhXhxwpI+kWUGpteP16YSfW1uECPQOXRKDGObKxOV4UpTQs3UMQQBP7hoezQy2BLNeHiMvLDa+vG2plY4beK5IPyFYPK7Xh9bph21kEUQBlonOw5LwThJPh3zc6w9njNEnV8B62bfH4CIdh9zbnY4jhWEMwZPowxhXQZTRKcVZVVzi566BXqw2eEXzzi2To2qYfkdDE1jzodHSRGN/7MTh3HskM0rsZuU8gyNHnxzsHCR6j8Y6IYNj/d5O2BO/QrCnQfSOYcbSmcOLpZ+UPDztnTO/7I4YIcR5xqXYvBKGPJBUAApwLNN2XIdUbUnxKRFmlb+i6wwk7wNVCBtksLoWR4DvzB/Qz6QZgYAdsrP2YqSQYElCx+2y7Wgf2nKlYcA5NzXdoYmw6DZfFKRfKrub9pfTp0sHeOpgaZPf5uScdYIjtsz+yQ5m5HVktbHJBxrYXR38nWGwEYN9v2G4XsMECjbCfPz2yQJd3oHd2DvfOGPpcX+OSgFYAdPRSAa1QAWKKaFbkoBdbAHpHKfkAPvBexnaf3A42sHcmLwTjNIjDkixB7opcKkrOBq7x8A6I4SMgwnvnLJ7RAbT3hjhumNCrVf3Bzv54fr0P8OmOBagdTt0EetrdfBrjzlt8XltH/Qv+NaoNOnXDBHujSd6+A0Dts4/v4lwN3h+ysB/My+kXqCyqOPMmtsiN99+ZFGx624JgMtzAwW3vY5Ehhjg9tNySAGXX4A41U38rlDVaO1AF4ejH2Pv0Z1VrdHSwUd+DHgNEHWvOvTm+9wH5ztvN7uDc74eKQ3HMsWbeqx+bGB33f34xgCGTG+wvgrlT2WFFnB8d43WCMcebAZ0y16FRABoAQLB93ImgGnNtEj3GaY2h5PjsSt3NmP3wt4apG3jdzTwwrakEBBUBCocgguDpN3Z/tKYQLxjFFloN6vRVHmOTvt3m9ds6zucTrnvG17cLSm0IweN8eoBfzszLO4tfyQNfv73g86dPABQ5Kxn89uytJRqaAP0ur/vvOWbhwWxjJmu7vx9jtWTEGJFSAn1Rec/kzhut92EnwqZ1tdS7B3Kc5hiD65rw+HjG2/WEy3bDnjP2PaO1DZfXC/7tT5+Rbxv+nDMuv/+E55ZRnCB7B//fYP3+1devExe2vPjjFveXv2RYTxFIPRiOA6oWzKGI4xeWrXW1wEnnzfHe4/Fhxc9fnvD4sCJ/u+B++HnvSBLyHgjMy5uzmLIqdFfsa8RJO66XK94ub3h+emYTmL/i+JsGwupOaigTVMFtr/TJGpz1flQJxkPf94aXl4xt7wjJY9syPj2fOcnNu6R1xcVM4YNz6J7VCjgu+OIsGSwN/rQgLCY9azRzVWmICzeQnBuc0gtlTYFSxccFdSvY8zDj43KfFnp1kO3ADX74sLTaZuWFcrvByqDUCdWkmoGBkrdq3xHYCuU89hnODWkng52JYs3jwHVFyFLZ94bn5wQoPaLKntErAYexyQD22cEjrhEh0cx+WbkxpGWBNlZqz4/CCpzjxFgeFiwPEbe3Yp0QuamJD5MZMDdjh+/mKqublLKMxLT1BlFBWhNCayZZDbhcrwAwwcWcs7EOIrtsBgYdrR+GwtWA0FKPzo8EWzqurxtiDAg+Qs4CkT6ZOYoGb54Z3YDT2o7NVYTyPS2H14rzjpLK4JEWb8ksZhXBRwfMZIzdm16/XnC77EhrxLIOSROMRSRYFnb9HCb6t0vFtWfU2pDzAAcj5gdDiPp7jyUGJJMSh+jZrfFeYtJ5TpTgmGZf1HyeKO1UpR789HDC9e1KUNe7aXJcS4OLlKUx0YmQ5BEESMJgYdvYHbaboeisiimlCssS2YFRmlVbRvMBwWldMLobhkCDfyf0E9MOhIWdRkIgeKjaUauYB9hR2R9BV+8di1+YGN7JvVLyU+bJzocKkQIut7yf4iKkd+YOiyCliNut8BkIQXXvE1prKDWjGvARvEDFYwWDUVWyD0aVXkyaUXKdVUIm8WauvwZcvhVo91BpNI2vDRLHjCdoqwZutRGcOq6LwQCEZlK6xS8WGBM4l65m4D68wszEvPP/lyVg3woul4zbstMTsREYHkuI8x6n0wlpSWSSefpoOA/crgXXS8btSnbjelpQSsPZfBJ5z5nIlFINYLCAXmGy20afBQFUChbnsJ493l4r4Dx8WJCSzf82vApZDCilY7t1fP3XTIbbrVlQyGet3ijrYibiQkYZAfUwu54Gk2C3Btx2xenxBHj6amhvFnApQvBYkse2Ka6XI5kmyMpE3qdk3k+ClAJOp4RdymSDcb8IGIbxzgHJGluEFFH3bAUV4HxaoarYthtqu0KV8s/bNePt7crGBk1oro0AQQM0QKRb8NPh4OFMTs6geQRFVr3vZPOoKJxrQK1oteN0ikjTs/AAJQA1fyE1+Tfn0dt1x7dvFQ+PKx6+RMQFJq2kVLZXawzjCfZKx6Ta3yeo0wh3ggv4zeN+yxkBJCyeG/ZPo4TkhSB1K806ALu5vqsw6B4dlwbTw8+9mQn1PDdLGIdE1fkfh27DP4rP05Iluf/99+/h+IhorbBb47ww7ktedZoQixNEJ3BNsCsB+2AS294VxVhSx72lhCpF7mduNNT40YnYkUJErdnYuCO5GuAeIN6/A4qaMY+7rVcCVvC9V4TAWJCdib2BVpSwQwYjWaDuvWyGfmrOfG3UGESzOkSWnWURvZufoB2td8rGnEeXiFxYbI0hQAz0b53PfF0CubqqBJzvBl+xYtt4hrMgJzSFjs6zuKSKtue57rw7HNBFJ8N+dF8Mzs2iSW0dJ+s412phIQ8dj+cVznl8+fyMmAKub1dIEJyXhWCFKmrZsd2uZKfniq4cL60XJAd4n3DRjd6p3mFZFpSSsd0qoG02T4gxIlqjjiElLHmHd4JqcvnoOP5LPaxCRpfYUjJyyQasjvFHwAkWCwuA0ivZaqoDkracbAA/1kUbuCuM2q00JqKABbne2pSDDSCqtjolkd7kyxACBl1pcxGcACqo7ccMvvvpQansYIEBh4TNIKKx5+nx5nvpsoigW0MfiQaYWy353vdwMFS1NTTF3DdGMxH2QpFRLzAQjYbnvSu8U6QYKNUcp+Ideq6Wj7HY0no9wHJVaKtQK2Brr5AYyaYyO4PfEjZN/z6l9xOZveMWMEGfDRFwB0YIAafWGlpm7jSAuWZWFO/nkNx97gAhWQiNdyD+AUq570CwIQ0d1iMOdu+gkNZM/upoKWD3GAPAxIBu7bO8A0CbjTI7lh+HmuqMLMGMYX/w/TGiPaDDoYEsNGcFlcEKLNbUwwnHa+tUI4xYbUhk3y87RiIYQKYI1nXBWir2XLDddvzL1zd8uxacguD5FOBcwb/+8gtciPiH//pP+OnTM9YUTeXS3521mGrIOHn/7eOH+40YVmV7scmf5UPnxftGGOfzCT543K5Xet+JoNYy9yEqu5jD91Yx+FHygb2lAM7ris/Pz7jddtyuG5Yl4eG0QK4XLLXAC1CuN+SHv8O32JFcxGPO+Ao9Aoy/eOh3lzwZle/AqePvNk3f3bbfOqoWSO9w00T6eM8AwwiQiQHanKcQgN3SBhh2fNGaIv6nf/sT/v4fP+P1uqPlO387BbwV0wDAh0glQcnmG07M5mFpcO4N223DTz99QQw/GvvfH3/TQFjX+4pxRxsgGABDwjCgSfGObIboJ0WUwfeCPTekxbrmgANmidy4oUCVaokoJWBpodmw8w7ffnm7kzd6+CgIiYtRSjTCrq2hlYrTw4LVZIIXVSwPAWUrNKEvDa4LAryZa9OYujUmps48MNaFbJWwCuSVC05rbRqWt1bBrsVGFrYJenszNPqRXVxEBMvqcXmpKKV9H0DNg+b7gCAEwX/9L294fIy4Xdg2uk93weMYfh3eCbw4sNUNZiUOwSpq2WSGAKCk7u4bF3cXPHzq7BRliLuCEgQRTLN3Lgq2QY+NW9Ro2ArUDvXA6bzg55+foV3x9dvrBMIAJqx7LsiFfkpssU7AJ8VgQADlJHnLuF42XC4bAAYM3nksywIfA8LW0PcKHyk5JWjSpp/KYBa0ThZYropVAa9E2Ys1LhjVBm4CDMByq1jjykU7OCDR7DPGiH3PKIVgJllvDm4NFqg0LAs7CD4+kPb/668bbpeMfCsHrf4OzARgwHDA48OKT89nOAd8+/aGt5cN3dB5VjL4vVEofXGW9HhjAJAFwOe8nFeEtyucJ/V7VJcUwHKOZCWJY7UWDqoOCsp2HECWZi5Y1ohta0BVG3PcsEnk6hjlhOAc0uPCpLJ2XN92AnImHT2dE15+vSItBADEqkSAQ0w0FG/NI+eKUk0GFrgxp5RMMUoQZFkitluG8w6LVR0p7eM8Us2ANHT1qOUG51asJwI8KUbcNmdJnCDFEwBB7wQphgdSSh6xC05G9tgLGZzeY3qt9QbkjXLlYB0XR/Al4vHwKdJPMe+oheugE0ADkwcxEGw5RYzW5+I9QqA0+HZhZ6N7DyDvPUop6F3RS0UTArhj821dZ1vv1gk+bltGaB7aOI9ijDjHM2qtnE+ea6m3qn6t7NR5u1VsW0OIipoz0hqwrskAZJiUnO27e6uTHRtsUxTXoJrhE4sVvXfs+27AIZMVL2IdSDOcMCFPSfD4HHB58wQUXzeUrdg6IAgpMOj0RzeqwWRJkU0Cem3wJ0/prwPOa8Bua1qzezPuKqVXHS5FxKjwrqFXSjviGg8WgAFxQ5afYpgMmfNpnU0helf6rMUxv63SGjy7vqFh2zakxA5q2ljIue0MXsteybRWJv+9Xu3am3mxURLhTGUn5ovhLOgshZLo0oqBcQmnh4WFBVWIB5Yz5dXNDNidklGb94I9CoInyM9NJ8GFhutlx8OnBzw+Ldiu5hfWaCtQr4rtWigXf1ihEHy7brjmzeaayZ+gBvoHOPOP+eFueBf3jf/KXDd1yj+dAh30AoyW3M3PvNsvRzI75ZKw9MSAqMFaANoEO49AEwYaeAy/m15+bI48zlfemUwzYSRDys/kslVKUlxIiMGZEfnh+aUG0PU724bTQqB1Ef+uzNzub9JM8o44/j2waGmfbZAjzRxJZkwJtXUatNfDewmjg1WnNPbf/vv/iN523C6/Il9fObZCtEYnZvXQlSbMlvA3Gb5VPFfnPRMt4R7UtNO3aZ4rsJh89nIrKIV7Bq0oOPac56MupaLkAq0FHs263JOts9dq/j8eQc0LDwcAOlJgdrsNs9HDOImPfjh/6ehWxBkenh9TBCeYkshlOQEAUor49PyEl5cXtNoQwoKQEgBFKdmk8O9ZNDlnbPsGVUUMFdF7nM8rzY5HMRACCGXvPng8Pz2gVMyuc733yeR0cnRl806A4CjZNbZLNlkk45gDxKlmMaCqBP6MwdNao3m8ZwzvTBIIWIG1W3w555g1eAALkSzwUabY7jrLjvW4tYbb7YZaKjsqm3xsAPDuTp7ZfsAKG0bf9Y76MSWs8FbUYeViyLQmWCDG1zSADELgHebz6JwjuqTH+fINA9ioDKmmlP/wqxsjjcw2BcRTdOPUGg8cI4oMxfsEecS0LFK+kyDrfXde25MMAH1ncwJTw3wAjEeyPX5UCv2dxj0Quy2MAdhtkftDs2d8yHTHKY1zxiyOGJfXvDi/k+XNTeD9bPTO4fHxActpRa0V18uVEmARG9ce+rGoYdfcW0MF9/t3oJ4jQ1tan+f37ggrUG/HPZMfISdi0ISggSzc4ARhNm7Su/cy7/Je4CcYiAOcf/epfEatdcT1AdozmgJLSvjyLPj2eqE1yu0NWitkSVhDR20FuG5wnl7L3nnUxwfm6rUf36EgcGqlmXFlfxkXEkMHjbXrjmc3SDNDMs8b//4DWytwLmHIIZ3JsRWYIM7w7wQ8QojIbXR3ZhEiOnk3xn2MeHp6wuVyw7eXF7w57sWP64qH0wnXLUNvX/Gf/usvWP7X/wn/+z+94OXLZ2znFU38d/Pix8eYPwqZa9wdeKjjJ38Z9PrRwUKEeS0D00bVwhZ7Xp05D4LleEM+DCMpWSJvMax3gs9PJ/zP/+H3+Pp6w//jH3+Z5+lgDYF0WPrQukH1UAxshf7RyxLx+vaCy+uZhdq/4vibBsK22w6BA32e3mvtp7xPGOCFQIlNqYrrlTdLhFWetEQsKbK6ZMnLWLhba6i5otcCgWCd7YCVP+8MCELwWE8EwpynVNEHYQJyzWhlg7gVIfrphRCTx82M4Wup8OpxelxwelzgvcPtmlFed6TFY0kRy5qwLEy+r28bOjrWc7LEALhedlxebojB4XxOVv3k2TrvcH5aGQihwzvBYuw3ekBUasQRQXbYWA3MkG4veH1xyDurr/udX9p78ASAKOVFViUePhraDGE3c/6S2enN+WFITfBFgoNfPKKyW1pvit7zpOCO7/Ge86njfs+1RN5mt4+Ch6cFp3NCF/pWaQfO5xXXK8EsBi8d65oofzRDP++DSagE4gNKrXYfLiiWcMQQyIg6LVhTwpenM+Tzme1ua6XHi/eoGJKbZqwkSnuX6KySrdBcbXOxK5mBvphUjGNv33d4FwmO7SbDdIcxe3AOpVYsoKxysKboNweIBTC9cmwzCRQACfROU/gQESM3yNYVty2jtYZtZ5U67wXVtSn5K7lg3zJc8FhjQloCeieAsxl7J4TADdyPgIrJRpiyGwYOdSdbcXTX7B24lYb9WnB9bSg7mZ0xBfReTIbIDdx5mcF+VwWGT5KIyWphsoYDNCdjhHOlt4a8mwl5JGg9mAwlN9y2fYLSgzkhtguIEBAK3uF6yUhpyNJoPC1CgKnkDcPEuzdWF9+uN1Ny0wtMRADX4H1Hch6tJ9yuHfumeHgwA/kOLHGhpM9G/5Kc+fUZ/tw6QVdxKFktaWnwgayakhv2ayeDVQkilZ1NNkI4qptq/x4B/fAA4hrQZwhZq0JcB7wz8GN0PLKFQmENE2ikrA1IaUHvDU8Pj5SoxIDRqZOtzOnJl3PFtmWTGSlaVgQvSN6j14blnJAWgsJ1z9iuGTuAZfHwgUUJBaWQIh0PpwXLmnDbOsrzGSVX/P6PX1ArsJ4IxL0Ju+rdbh3bdiMQeC14/UZPh3eSjOARksfpccX1sqF3D984vynZGvfCYVnoUacgwLcEDxHFtu9ALVxfFAg+kOXigLgy6feRYEPdWUlutZFlu21kOXqyD6jEVIhX9F6RW0EAGW8CSmfZyGHBeU0QKG7bBfu+wSPAC1Bzwe31in1n5ZMYTUepN0QX4dCRTiucEzw+rng4L1OK5v3oVDjGPotXUAbK4iinXiID/eApbd63ws6dIaDnji4dtTZcLju00/Pw9LBAgkNYA64vOy6vGadzQIyBwG4CXAjYtgbfKMFNKaE1oXyyKxbnIVK+S4A+HiPHsXgNg1Qxck/mm4OZ2lC1I7oAL1YIcN5atsMM4Iff5RGIfzy0d1TpCOY7MqSiMG9QgeK2XynbCCu888gdaENyAMDHhKAM5Gsh02cYzDZjbkIpQ15Pyzu/LhEgBTdB/GKsq3G9ZF7SU2ddF5Raye6AwvmIuNBj0SmbCUE8qgpGXKpKJoLCTUDHhYhLvWK9T7Zs8WnGvimVjTwAGkh/PCj1orm28xE+JNQ6OnkN9o8xj+z1BL3uPmM8ZHvT9w4z749mDR5Gclu64unp2dYu2HMmmBW8R0wJzgWUvOOe7eGtYNF+8HWjKcC7nwnHwvz73bNT4F2hQvso8Pw4gRrsqrJvqLXivCYEDzw8PuDt9c3itYLmdX5RzeW4t3dHqQWlFjIcvce6JqoflJ1me6sIMQA6GNbcp9bTmZ6D227yRz6n4B2i4/otsGYgjsyvybIxoKLVCrVxLCqoSpC76gG+jH1a/QC/CKJ07RBvBRsczG+RbsyQOwNz+zOk/mPPvk9Q6zBvF7ECrs15HWn0989CVbGXZgDEsHMgq4/gy3v4koxnFkVyoeR7PvWBu5tC410nSfuuY0yNJjUeasAm2eF1+iQ55wxYZFGc4Q8BpQXR7FruvuMuxoLQusN3eug2YzM5u/fO0QMQGJ2Jj/E87lIKjK3GGjYO7xyCKTm893h5fcFiHlv3wKqLHg+PDywcbzvZj31Hy8aCHGMpMp/y1mHdy5BBjkYBzBvf+T4B9Jj88ExDjIgp4stPX7BtG3rveHt5Q2+Nv4uJ97W9lzr2PaPlCrcm2okI98rR5KmDQOGIp+Z5CBCQaWXQFQXKrpvvZI5iHpHci5NzUzUylhMRQRA1M34geQIVwIFhePmePU0Ge6TsMa4InWBfaw0xBDydT3i5XLHvG2Jnjn3d+/zs4BW1fUNcEnqIePr0CT4sQNmAVtF/Yy3+OFZ+fHBOyYcffQdquuOXzrFpTQjJ4gAxcHswueemwjEpZN9LNlBcdSq3gvP0z7NPjzHi8fEBp7RwbwbQvIdLCX/4n/8j/vB/+j/g908nQDv+KT5Dnj/hlhP8EpFQyMa6Ow6yxYC37u/I/c/eH3zP+Ix3+PVvHiN+UyHUJMDkHX3cllUrVCOXnwmA38lV7tag6Dr+7udHPJwXRC8oVfERahV4yn5Dg3MFgmqNmyretoLTkhD2Ha9vN/zh04K/5vibBsLYMdKQXWvVPALWQb1hAm6mwspFc1kSTufEzVY7eqsomQFhcOy4VXLGdmdA6b1HiBHrQrlSih7bLZsBOSVR62lBXBxc1ClJUyh64+IhEnB9eYMLBN1YHQIkOtTCU26VVP+y0bsprQyeljViMcZB3ndcrxekNUEMfV+WiLQEPH0+Q+swmafB93JasJ7Z+ed22aCt4+kp4E//nNmBru537Mb7QWelIbCj3/VSEGPA9VKP1/sfvA0MvHrr5mtkDCUHwLm5AdbWIL0DjUa6tQ05pMfptCKFjrxV7CbpvF/mxvozC2p3C5kJsyBBzLuKiVRKAUEctu2ovgOsIHExtC43XqALQYwYI1rn4pBzRcsNDm4awffecVpPZGmpIoXArkRFsd0yEwiDyGtnQBFgngTGLhjV7T7j7yG7GLd2SJF4rnvO6H2jDFOY5NVCCRjHP+WDMXg8PlIjve0NOTPwLDvZHQCQ1oh9qxiVRIDAoQhZF6O6ernuDDJ7n1KC0YHq4fkJ22VjJ781cqNQeoXVRuN/HwDnFdI6Tic2F7i87fCBy1w0YGAEemWjYbIomVwKQSvWjCE4tE5PoWIeJ85ZQwhHhscIlLTT9L0b8FqNacKNf1QJ3dxEAHbtUrtGZ0yXdYnYQ8Hr621WEnNpFpiRsYnK98QUkdqdd4U4AvaNcpfrGwGVdV3YKfWyTzNnnwRAQHcZMTkEicZSVDN9FuRd0c6KnBtGd9xgBvPbVrAsEafT0dYdoE/Vrewob9usjIsD8t5wfevwNzH/L0yAT5Vdnpx3SEuYvmi9q9ELKFmzZlazslQKEAxT7/cMFDMb3bYKrYBf6XPovcfT4xMBlF7ResG2F7gK5AxkpSTy7XXDtle0zsRj3xpaVpxPEQ+PacqnlsD71gqZR6NRysNDIiBpsnBgh/cBf/jDGT///hExefzzP77g4ekBeOR9Oz+ekPeKPXcsi0dICSHkCTyPw5lcgBKi3QqPMgFSgqyUDwsUvXSkzx4lV/jgsCQgJQa1t23H9bJjWSIgw5OOoEHeO2omQBJcwF4z8gvN+gWKvXY8Pp4BOJRSreMsWZXDFJqeKA7d5kJYI6IFd10VvSXspaHmgutlR94rahkG8ZQKdwh6bDiti+2vfJbracHb681kmQYM1I690MszOPMO6RlOgPUUsdkaHpLHbrYAMRJIJ/jRDFA6zNd7IwM77wWlNrMZANZTMgb0hrp1NKUsY0kRMXAOihPsreDp+Rnb143rtTb0IX0yz5YYI5In00nNR2aCZlTzjDDDjgNoaL1jNCwaYOCQH0350I9zYSvlCNJ6RlqWOV9HYxyyHcjE2Xd27F3XFQKw0+T8oDv2EAZ4pSa37nM/CSEgLXEm3/PtwkJPV8r5JqMbglwrcq62horZFyjNj+/uiQibbAxWOTDYZPTGGfs2pb4F6vQIkkFPTTJNOyDO9kyd2z1BVgLD0fwmW93RWyHtekx+YLI63gnSxJlR9f11f2Sc/PgYzLJ+9xzVrm+Ae0MupxjSdYIZ3ntoDBDx5nN1vOeo5B/n4yTMvZhsCAVM8j3OVYAJdoy1eN5zM+5/d/5DwmnHtl3p3WVBFTuOr/j85TP+5Z//5Xiudp6tV+R9nxLL17dXBB8mC4seTg5LWpDzjQWKxj0zxkjGi1l/5FLgYkVKK0IIZkBtfjzM18fd4P1pY61qYFjpUOHQlGxlEZlstYM1xWsNMcBcnudA7a3jur8ArqKL4rYPbzh+PxnK1hXT9kAnYvNTZtdI7mfsjD07qSksrlGLzw7Z0mBbjuc0vJfGOYcpSiZIM7rCckzwfszEVwFo4Xoj7LIuzpnBGgCzhRiXPdgiB0OS4PmYC92KuXI3ltkFMlK6auB08J42AEqG3CmxqFLVQdHesW3YKTBCqkwVjQg7X7Y+pNSUDosByx/nIruOEgQa8dlpXako2ff5PdEd0maFw7oss9GAM4ZgNRXNWDdZsGGH0xhP+NExTuejZ9mPDjZtqfj1l18ICJWKPvcSY/8N4PZuLYwpwn15xGTrCjs+j7FaSkE1coZvzgqbwP2G4h2LTxVg3jWSJbv+ZagFxJRFNm+G9FFFIW38zDrSW2G+1DY9gQcrzAcWtvcKfHpasJ4fsF2v89mLCIsBYUHeM+PnWBD9Ced1wS0XKww2/Jf/+s+45oov2w1PT094fHiEawW6c33ism737e7K32eJ3z84sReK4l0Tm4/Pkx/iUbsDakdq1Ri58+Ef99K8C9XWoxACQozY9m2yKTuA3Btq7+avxfv58HDCTz9/xq+v31C2DDjFRTrW5PHaC4Ke8Oc/f8MffvqMc0yIKf3wIoeqRgxYOvbfv04a+O6y/4pjWEy8e5/dknfYFgAIgeWu9B98d05jMRKY8arCxYTff3nGP6y/4vrri+WcHiksvE6hjHiAzKVUtF6xFaoXrlvGT+uC7XZBPv0P0DVyOUXgWrFf+6TkDeuorvw/FwTrQt8eZzr7tAQ8nE94eXkhw8M5FOfoW9JHIMs2uikldO1Y1oXmk73RwHyJKLnidF4oCVjJRlgfI9kVYFV83yq8J5Vce0MMJ+SeTY4BVDMfjUucBsg1NzN3bQhJEKOh7Aa1llxxu+6ohZ5XYaH3GLvL0QR2fFZKgcbHAmzbju1WEJzg9ZUT9HY1f6Gpw/4IhBk8oJiJ97LQ7+lHIJjIHdhrybL4wQhTlK0gnhb4QDCpWxTpTqv509imokDLDVd3Q9m3KRW4/577s7w/hgGodkAifXPy3vD2ulnHTLIGHh/O2HNGKQ29Zzw8rBMg42Zp1XcHbCa7rbVhv2XAWGTFFVxvw4OCrx8MM/q+WNDkuWACg4FE6mwuHSkqnFU1gQOQYLLDJgqt0hcgl4yuw0hUzXyUwY2PEafziUmo58KzbRXO2sgqKBsquUEbpcStNcvoBJCCZU1YzyvWZcF2a9g2k7v1BtVmQTuQ9zqrf86Yk2lNWJZIs+7azduuz4TbCX1JQgpY2jKrYJQaR55z19nJrO4yq+kCh+ADzmdKVl1gt0AG4ex4OKpKAIwBxMV63ypub/SAE8f5JMLPnRIsJ8Y4FDtvdieMIUAigzZxgtNpRa0dOVsnJXSUWmhCb10xT2lBSGQ9qg1WhUerHdu1YLsWQIFloZRqXQJ9Y8z4Maw0vx/sltEoA8Jus3HhddLwnp3/Su2otXD+K7AuEVDbnAGIUzKnOjuWOmEH17AInr5EfPulwClQTRbio+1N5oHCuWDFBGPqla1aUNZwvW54fj6TWQuhxKfLZIjW2pFrQzPPkJiCgeOHeXZaIqQ2oDoDsAg23a4Zby87Lm+FnTCtU1QtDWUvWE4RX35+MB8e4PHzA2JkFXLPhQC2dYM6nxbKavcLu/aGgNN5xS+/XFEqAeHLW0Zr3/DwvCLGgMdHY7c4wfXthre33TrMHkdKATHRuD0CxhhVKArEO3hHQCVEyqDQFNdvFzQ4nH9aDMjkOMvmTeMNtPMmJc97Ra8NvTus6YQlrdi//oqXtytErUrtyF5c1oiUIuWgnuzP1stsPrDdClppWM8RAH3o6LfDRhRlL7hcNgPCClo1f0wBgV3fzASce2+M7BJJ6ZBnAKjAdWOls5Rmaxs7ZjqwIBKCR1oHsMXEZV0i4hJxu5gcOVdKnz29NjuAvVT0XNEVCFHw9dcLfvrp0dYDwC8JvSi8UN4uEOTMnSIGdoMevl0KM/BXZ95BHdFHjIhTxLHrImDVXc59MXmUqgyYgwAyFMPHxJt03nuya5kE11m0uwdm3klw7LOc8wg+Qluj/6iO+OSQz+2zw597t0+Wkmei39rRMbD2bns+5zc8JcYujWs+9ljnaOkxpV12D6BqcknrMDZA3wFU6HFNIzAewTn3RzIwHDe6CRjJXZen3g/wdibtGJKi8cfNfZWWBh41X6Gto5YdvfIejDO7P0QotfX+fWcpmYDTAC1+Oz0Yr+tG9bn3nLt///BJgrF8urI7KYtkckRav4G/TUHLfUFQ5K6ABVD2epcWqsDHgJILJfDDR9IA5drZVCcGPoPL2xt669Ng2AeP88MZec+AAqfTCWIyrpozWYaNYHPrDXvuKK5CJBiDiNYP5fWKmhtSTFiWkXh2FFXUunOf68NX0uHx4REheLy8vGLfNozOk6UN9oIS8IGxxULEkC2VWqefVra9pmunPYoc5vC0jDAT8QHy6GDwCaqB8CK4s2kYINIYD9ybGX912xuPLooA7p6zGYuLTmIWQZBjPPMTHYI7ZH1D+q5Tgnl4R308xrU5Gy+tMYfh2qWAY3MGbR1ah7xJbQ3vkxTgfIBLES4kUAXL62utGfBE76aud35fVrzdCr0p1xjZDGQO18MCwymA4OGUrKThROYdGUktq4GNfcL4Y2/0nrLSEZ/LYQn3fr7YA3DeMQdxwZiYjO/ZwCSh6Q4pZL7rhxwDCoIfSnb7kLGKCJYUIeKQ80dv5fdHNbXP6XTGtm3Y9n2uD4xPhheiToCKYxJzxeqtY6v7ZD/WXFGMoe2tAKWwZhIfQDoBrW0ynhHdK7RxPw4CRO9mB9+ufAo+eNrveHd0L79rIBBCmMDd8K+OQm9TAmTCjtkiSI5KljFfuqoxI9nQhd5+DrWtyKXhciv415dX/P3vnvH17Y1z0Dwgz+cHJO+Q1kTLg1GAuH/mNtQcuDerAL1+v3aP4TJY2nDcWVrl+KZvpAMtaRgTb7lj9czPYojIJR9N0UQA83yrlcb/PgS02/eyvA7mUg7WSC8EPD2e8eXpAdvbG1rOcCHg7XoFHOX3zw9n5FwQdhI2QgjoJnW8h6PGPjy6ks4g4//D46+oAdnr7hN/fqViUGfGz+O7F3SYlPJdAt8BJWO4K5mfa4r4/Zcn/PlfvwIguaHWHRIX5jPeWwEvIZeCthGYveWMt5vH42nBv/7Tr7/pMfjx+JsGwkJ0yN4BrsFsXHgomNg7Z0mBx/NTQq2mpdeK6/UyUfUxCRiTmEbde/hEcCnFhBACrtcrWu8ETIS+OTEEtNJoluo8tlvD5cpNo2Qa/LrhkVRJoVzTgotWqHVlAoyhMJx2MbwcMGWdo9sSwA2ePigdrQWs5zQTfxGBVnYVY5U0MBhqNA4uDdi2ziQQgly4UHLtZUXXkAfct32wsJCL967od5XmD553x0JuCfRgC/TWCMrZMbTy3pMdVgcFG0IJl2cVk34OR3XbYpe7Sryd7uiwksKsOjuh4WMKHbfLNssGj49nQOhVtO8Z+14wOnb1bmCIVSxrV2w3Sv/UqianlS1+W2vIueDX/A2v8cJOd4Eghh/G8cokViNQcwXUISSHYlSI1hWuKRoA7xQ+iqEQMHNkQWkFh1+DVRDVWdeWNitZeSeYFUJALTSyV3CDvbwSCBW16mJn50CfApbVY8/7PPcRtLROenzvHdbg0BZjVrXFK16/XuGNNRQCE9F3Ha/s76UUuCpw0eP86QwVRYr067pcCupe0PZqlT4rFnSrJDjS2sMacTol6IWy45oFTUzu51d0S4bCvPdAcYesp7eO7h1lm3tBWoOBcx7tRkYHmYbd/M8a1kKQ2zsHSY5jU43xIQy+GcCw2caskk2ZEqvTNVPy1ls/urtOM3nFMHQfyXMtDfuesW07/VWs89ZRxSILrLdGk2tHwJDAhKfZcu/wC9ex2sjoGWukC0C7mRQ0GLuywSJVGvOnmKaOv3dMf5I+CwZMBlKKmN1zgtj8VktACIa20vkzHO3ofaAUtJQNqsUAyorTGuGimx2AhxH2lCYIE9ZWK3795Yo//vETHp8THh8WpESm1TA9diIYjkO1dawicAjwLlhTDsXjI2Xn2neUPaPmDSINn356xumcEGJg9TtUPDwkvK0VrlQaALeGUhoeHgbIKkwo1ojeKWENns9UQcA2eDYcUOnWhXiBiEPJ9PpzTuCjMxCsmxyBIIYTj9aqdV4D1oVr0dfXFzjxSGlBSuajIeyCKa4DQslYWiKbhrSKUi7YNgITAqAWQckFt1tm5+OtozWuNTOuEgI9Anp7LMvJPHQs+PYCEnI6JRm2Vg8/RStd8nmY/6U4QVoi/uW/fkV/7Hj0DrU05MniPPzMBgvg5duVIF1rCCngthVaDXRAleBjDMEk+kAzVsWWFV8vN/x7MdmmbS1MxNmZN1jCrwaiQARFGkqn5NQpWbopepPq0hj42CsxBimqbaZiIAiUich9MOjMh2iCYSLQO2B/7HkTeOnvgaLBRLk/WjF2iKdkqVbrrjd8k3yY0nu1fcUFdri8lweOphmqoNeqCGCMv8EQOjbjkcTj3blPEKx3aKN59/jhhBV6h1Nl1y2TKzYI+jDbFQbRLtAL0XuPtCyIaUEtFb9evnJtWng/eq9WBBjxE31FnADed6jQAzOG9/dNzHPMTvgAs94BYgfTc1zE2C97P9hXrVab0xnOdUCsI3U/YpnjE7/37QJsDN4xF+aLZQyM8bq784HFYI4FsDasAuxtAwThmOeafnmjnxrnMv+bUsLl7WIyP4dWMnIp85o6AEpNefatcT9nAkwQu9UO6YLn3/0ep/MC3yty3vDy7Stu3rphe1oxPD4sqG1HjILHx5NZhGzGhuLhnRCMCUMqaMXG4LF2gmY1c0/23aH0g8nJR6pTmqcKhMg9OqUzbvWNILZTOJdw7+f1viMq2eqjsyxjJIX3y3xeAAzoZZOW1rvt/W6CyHj/iUZipG1Jt8IUGVvmM6sAF6sPoA3uPQNlzjkVz7xiDlKd/lgcE8NShtdjQYSNTQP67X3OWryPzofrEtEjfeuip8dyMlZXaQ0ugOu/3uUGuI/rCPaIO4BDNYC9N8adg7EE50yZ0VBAgDIGGpPTv3dYODBuzbWZJxnQtGMNjMvHtcUYIUKbihDKZEUd897WvL3AuzCNxN1djiiO3py1Vis+BwO9730aOc/2fUfe99m59hiLZtRv6+FQHg1goeSCmos9ugNo79ZRl0Bmm0DwiCnH0HJOECEoXVD0GXn/M1KgZHPYW/C6FC5wPQxWOEcgYNitgFKsFbiOZ2hjp7bOjqNy3Kc9Z0DfyOa1hhXiAdcFLgiiRto1lB2vl8g93At+elqhEnBeT1hioifz9YZf//TP+HQ+4eG00sfMUTb9ERAbMYqYjNolYeOqe9oufpvx23s3xvZ90w2g1IpVE5+NzcehkFHr0gwY2Nc6m26lhGwMxe++ZwBiAiwp4vHxhIeHM771hj/98gu8ODxdb0hwWFJCShElZxZkgzeZ4fef+xs//vCK/42OkWMBKAokT6KPGDg3YxcFGxMdpTUuEH6lV3bZ8fn54c4XkYdqg7Qd8FyXQwyINSLGYIxcWie8XG/oAGJa8O31fwBp5JiNzhYksfsqYpWZIFgSO91Va9va4XF5vWDPZUodgg8zQB2J5tCuKzqaNrJnlB4Y4jxq71jOC/JWyRiLCa9vmyVnbXqqkNrbEIJDawExOHg4nE9nXC6/QDurKLAEuFX6E41zCH4w2Sy5bM2qUB0+JEQzpA5hGOaaCWwaJu+UE+x7x+1asd8KZXtbhVYaT5fMRFrNe4f31u6xAEC3AJj4Yqn9jqoOnE70q1ID0CgHregNcEskiBBobOpyRWu8DnTFel5wOi1gkci/n6bCExndFu+n+PCcGYyXIA6nFGiEiMEqUgNsFN5a0oujzDQEjz1n/PrrBhHKZyjn4Xe2WpH3YsEEo4pWjRoemYxFSxqu1xu2nFEaK2S+0qPLBzIYvHdYThGP4YRSGl6/3bCZNDEETGBBnE5pQx9+QgZwQtUCB49erLJfNlTrfuXDEaCUXFFynb4G1e5fNVPqEMhQgn1uiKzOiAUbAkFwHo5av7nxjcMHmt86r3j+acXtWshIsYR2MA9YZOQbnbMOaqJAJ4h1fjojBf4+l463r1cE502mZTLhRtaACw6tNyzxBOc88i8vEEdmUUyrsUUssbNFwHtPFmM9ggZVUq+dzbWSCWKczpFgVW9QZ63P+/CY4PvGuPGO8g6RTuBWh9SQ7MeyFeyZ38lOSoJaOJ5aMf+NPsY24KK1VTcQCyqUrjpeR4z0p2u5GT2eVW5RSrpaKYDQg0MbU+5bVrS9wjlFMJ9EpxxPeSdIRAPxhLyRkr7vFaM71JAlpCUQBFIyXIf6q1c2KCmlohiIIhbl+tbN9LQjdY91CUhB0F1HlmJ+PwrXhJ39OgFoVlcp2TydPBttREDP1ro6d8zGKHaecfU4nyK2646UAPcsuO0MFGsjE6CDXVFV1MBXT1Bgd/Chz6QAWhETkDfcdfnr2LYdsdEzkP4oEcsSbE8ZzDZjfUqHd52dXr1H7xGtHcm0cwI4NaBqACMF2hM6OlIIBLhtXgJk7Zas2G6sLmuvkK5oqaC1yv0LlE8yaK2YXknWcML7IT8n6LWcVnhZULNHzuwW6JxD3hk873vFtrFJDHR4+DHIJp5giZ7AWGQVp4dAKbgDfBSCgOZDEiIlgZQ3dlQS5sw/atgcENDKe8Ue2c6+V7JQvbEDW1UyIHNDvtG3yAVKDXrtKJXrXDCvvtIVt34ly8cFY4HY/gEG/957S7oIgI3i1AyWJygktnbpRCy4Lt57pRxg2Oh2DOCQGDlB8AFioNx4T3dkJcQQZhODpiMJrnB3yfWUVglBVnonOUsqnSVN1oBgdNg6Mk2u6V3Rpc+C1UgOHCmIM0FqSmz8IH4cLI+xLvLHDi5EtH403ukGgt5v6MPYWwQQF9gpzeIF58y7Uk3SOJLcIATux30Vxkqj0FAL5UfX6xXOOTycH+BDYEfUnLlWWvWd3rDcn2vrCDHBh/eMsHs5FhPb99K68XwH02sAH2QVGRBmQG/vbYQxBHLvYrkfHhMweP+aIYH8WACcN+TdD+1XNm5HYepHHmGDeXi5vuF2uzJ+MRlUjAkCQd5oil9qRjZfsFHkYjoz4lVvtgG8N7U26yitiC6i7DtiEKhj8izOk/3lPdbTCeuyIqUA34BS+MwFYgUdmTGx92KqDPqM7XsB0LCuaTJQsnmWtp2dze6v2sHBp8jmKk5MJgWEEIEyOo6aZ5IPdm/fA0+9NbKrzVTJOQ/nYACszjWGXcV5LwYQ6bRDvYPHGDf840z+XY29ScYjAcUBtE6o58MQ8rPBx8EuE3cH6NobWmeyOIBAjM+0tQkdkMAmEGrPUkQAd/hkCRzjQ2ssJRAsMWIvdc6D0jq07kc+Njzdxnwy0Om9SmrEmgr0jmDrMFUZzuxeeL4T94Gzwif9NsVVQAL9Cw0s9EIWTTCwbrwfxpYbTvoxRpzOlOZe3ugD3A1YtRMksK6AeG/NFuqU5rIpTTNQ+O66WsN+I+P83k7Bbi54e6c5lxUi2HAKIFhWi9mMzHsHxjaqJHSIoLaKFCOakBkefEB0jr3Kc6Hf3rrCSX0HuI/1n3ODsepgRt2DtcFsAoYkdqyHk83riHblXPD2dsWbXk2qqobLC2JkXl2Dg4JebZfbNrtwbnvBEhMeFkr9tXVc3y7Q7YJLDHh6fMDT0xPODw+WG4uBTzpl3sOT9Lg+RS67rWvmlaF36Czer7dUMnwAqZU+q8EnGyvJAO73ILuNTogD1iXNdWI892jWEMf3Aj0teHh4wNPTA/Za8PJ6Qe0VelGI/wPYdMsUX3HMc9tfbF0QWL16nsNfOt6Pz7tayl/lD3Zc52/DaskwZy8NVQVewrsCAfNCxv4QjyUFiFlAjHgrBI+fPz9h2zYyyJW0mA4FhEzwkCJSXVBaRbMmCyEEfP32DV9++oJ833nyLxx/00DYsgbcLg1qFYL5YAyMCcFhWUmJZQczAK0BXgAvWNcV62kFPZg8ai3TiNk5jo7WK3pphl2a8bkZzdbW0RSQ6I3CqSiVnirdukaIyKzAw4Kp1jgxYowGELBaJzi0+D6wkj8Sms0knHvOE7QotcE3N5PWbgsmTIKmXZBrR9krbpcdt8uG22VHvlWUoiiZya2al4JAp54bwAF2id7dV7wDwQDgfIrsuBg86bLD+8M5kwSS0qqqNGgvlf491i1pSArvvQhUQTp/76S5fgj0RKhpR1cEoRTQifmRaEcppKDHZJ3MAruP1Vrx+XyC84JtZ3QtOiQlwuqOU4S4QKEotVDm1pt5B/AebXuGgKb7t22356qT2eYqWVq7E6TETmcSO0J0OD0EbLkAzbqMOZqbL6s3hlBHL9awIXgLFhx6pmH87cpAtNXRDn2s62baq4JBkD8qSePGASEFLlKB/nm9K/LGAD5GJvutWaXFxtZgEdOrwOPhaWXzhhWohc9DlWbrbDrRZ+v30TFNhSBa6w1SGtZTQggEA0Icsiouki5Q3jUWRQaa9jlKj4Db6w2nlPD49AkAu1Xttw3sSMXgqZsMqJpM8V4eAfB8n57ZRELCDmmwQPLuNb0jl2oeNIJ1Dbhed8RkDJXu6DNnTJXqaAg7QLneLFkrh5SAsbVdrw4gk3PFBzFgmdFeLpT3EXz1JiErEHSImqwsGlhopqglF84HkyCO7xVQUtgM0PXB4fETEx4B5ZYKYHSgmFO96+zW1JTAKjszNmN2KkazhiVZIukEQyYnnTLIGIccQ6G5wZkv30iQvffwgdXeED2ezgmfP684nSK7sXWCYewQ6VBzhyZ6853P9CqhlBSQQGm8KwaiKMflVhpEmfj0LsiZSTEMCHh4YoWJDSB2tFaxbztiiHBwWJYFMW1wV9a01lOkkXTruF7J0lpSQFoTvCcbMOdiIJGBns4jeEFMCW/5K1pbpweHiJsMg5K5lpFNHOAcuxDVVll2Q0cIDmnxKG1FyZQg9t5x20YXXAdx3HdqJrMgBmPCqKI3GvUDwPkpYrsULClgC8UYfJgMtZAcYuK6HhIbv9TccbtmxMXDVFUELpxHsLrf+FfrDBJHZ6m8N3Z7PZun4dOK15frlCIb/MSEbq4vOs1/mQwp6p4B8VDxZFLUhlrokclCQYeCRRgngsut4J/+/Cuez4td38GauA+KR9CpVmgbIWjXYYI7gC+CAiNRFSjIxLjr/itMwtl4087fe3Qou5fKsQ7w2hStZHR7XmQUGgAFwElgF1BxZlTtMTp+tdqNiX4wtEZnVgUIfhqTzFki2HuD9HG+dj2O/x3yLnpqKVoH8jT15rNWEfR3RTvFYP458UfSK0IJr63pY+/13qNYEjISZtizF9FpJs/QQsy3M6O2nffDJPrLacX54REA8Pb6grxtgCWW67oiOIfbnoHWkdLogngcA4gch9o/74+JTNyNFVsqe6fXGczkv1OCHYJ899kfD1XMJjHf/eKH6c1vfJYQ+D7efjDABvipNp6dE2zbhpLNi1UV63JGtLinGeOk1opa8wS7bGbSaxdMQO9lXyWPeBosLtWM/UYJYi0ZqizyrOuK04ldkqekXNXYjLS2UD2AaUqP3LShoF+jzJ9rV2PoOL5OojEaj/un5pc14lrufwXeBzSpZoBvsjNt7wlYqnMd+Ig/DvY8HwELAVMVe/8o75+LrR1eApytEbh72mrd7qbc2P7NR3Ukl94YnvP7zYvwGG9yxyId4KXN1ZpRlXYeqAdAOg7Kj8UsGuZJ2HgBqjY0NQ9Ki/nQjpvWK0Gk2gjkeCErmjG/n+Mzl+P+ze8WwZICcmkod58p4pBCwpoW+LRwPQsN4r15FRLUXRK9nUNMBuAcDaucBEA8miqieJxOD/jy80/4L//5H1HqFRCqTLQripmhqhJkDDEhLQqxqs6Iusl3uR9r3TyTTdvLAWfAuCl5DgTcro2x2zDCV91RWz2UODIaaemU8Ao8O6oqmefiA3yMgHZIu0BdRxSLzQew/GGtISjn59ifjC4bZ7U2yj075bQOwzdSgV5MZuiZr0Lh0dHFhoLwWYbAwmFrATkX5MpxE5aAVQNKZbF0SQlLjGhQlKZAySh5x/V6xePjIx6fnrCeTgTEROCMuYwP1+S8Q0zxiP3teegArFXegWLAwW4fhxdFrxVq/njBe4TTAlUrBpc6nzjtH8Cu7c7TJsRzv/iR512IEQ/nR5zWV8RwBfDGPPJGf8yfPz8jLbSdYdHLZMy2BSlYJBoCrmPkfdwbfgyT6RiPeuwL/72HAIh+ikiYg0CnRHysV10EzgVED7NVGMVHMuT++PMz/o//y3/E3//hJ/ynf/wn/N//4b/MQoDThj7BssC9Q4C871i8A5T7+na94Paw/lXn/TcNhE0zarUA9B5ptXvLhZbmahCFdFYHFUZDDcGkA+xS5vTYxCwEfreBkroacNk3XN5uUzJVSkPJFXsuTHgVVv09klAfRqDKRSTFADWAbFDq3VzgDtSXsqgOdFaWVRSnc0JMgQCbDbo2JAwA0AqlcVvFfs3Y94y8FWy3gpoJ2uS9IgaPYlVLAhuJ1QjPOtq+F2y5TaR4rOP3hwB4fEoE1cCuOyNYvWeXAKxyaSMdeLzmXUW1k4FTazNQbXR9obdRt+ijFQXbXPM50WOC6mSBIgaCa8ti3jVNocKNrNYKNKB2SlOzARStNaPds9rlo8k/ulL+Wjp9kTqlbXVKRsQmecfoWCg6OoMGuDXCuZG0Kh6ePboGXF4LalUmG2oMv0RmhN5v+AaQdufQSkM2tuH7KjXBm7vZ8f2EESAtHo/PZNisCz1hWqbvACnzin2rqJ7XMYLNwaTwwSEuET6yqyCBN1s8hSyAISOo5qsWUjAPAZtDzVqQy3GmnG9MIVvviM5jPUcG47WjFoJj17crFA7blrGuC3rtU8pJqQYNa1XufHHsVkTr4khw7qiUl9oJ5ICsntPCxKhbkD2q/qOd9bgPZDbIBN5rbVNqNe5ZrQZW1W4M4KPtO2BJVwiQ3jA8pHzkZt06k+cUI3Am88N7B0hDb5QRegsia2nob5neBJ2dyXxIEEePBRe8dUfj55bCrpveCx6fHIEvoR+VdusK6UxSZl4rDNwOcLX3IbPods1tgpUigHhY8kcwkQahxuRorNhue0cvFbnSIyBGj/OZLCpR4PkpwEeHfctYksOSAnoDATgLwlrruFxu6H/a8fC8YF0jXACczV9KSbhe5K2ht91knzRHZxMFG6uRgbkz0Px23bCcaMTvzBi4D78ULxZMO8TE4LPa+F9sfLHLryDs3jqhjap8Q0wR6ynhemGFckk0kB5ePnlvKKJolXNbhJ4/rnGM3270KQu2r3jvUJwipYj9tqPsBVgCu/hYh8DhreSdt0TQmUcSQypnY6BNqZx5XQWHGB3SiVYDrIgL9o0TomrF29uO01mMLSmzw5VYkWaAAtOrRhUtN6gXxNYhLiClQOsBT1P+sf6NwhTZEQSYU3LwPs09ZCvChKuLgar0LrJu5wiBc6w3wdvV/FpqhYclpMJnrk4RjSXkBktZmeR4cRBHmWBtCu/GxkhvMbmTFmlnka7UoyJs1bEjeZDBPucYiGaqL8CUYfwokebfR8OPA3wSCKunY00137AhE/beIfQANRLUMPHX3o8kXpjp0t+P69W94TFGTCXybpeZSfl9IDZuj3wIG+Ya0mbBZJQyndCMv+GwqxgJhDg31xHto/ED58uSEvacsZ7OeP7yBdv1gnALqN5Pg+Kxl3rvsXiywd5J1O4Slb/I3LKL0LvMQ+w9k3UITKsJ51jgmF31BpviLm4dz9jLHRR7lzzdwbOMnf7C+Tmhn08Ze5fFC2IB3IRyuJxj23djrDSkuMA5h2VZOSZ0FNsOSfxggIkK9kLmT7M1XMCCRKO53AG4aEcpGbmYVNSaBnQbe84Jcg4QNxhsOgHcOf4NhBodAvngBcG3I+awFzub/yEQzJgPCbB475DnCgS9F7KQkoCNExWijZ5dzlssegCSH8dH720Woo65EMarj1EzQMnxmlEgHzRZGMPMu9mIYTATB5A61rwJjt0NmPvxJPN/ZN674Ngg4mAYdjTQJ3BcV5jzwsFFDzgHUYIN99c9fcZynp6/BOvjFJd1u9cKzIZYzZm597weLtJSx31Va/ZCf2Pts8csQxVbE8gAiVwXIIiJTQ2cUnaWQsBpTViXBc5HqNa5XvBah0/pMH53SMtiz1ksxnJQr1NKOooRIoIQB8hqNgyOvsD1HZbHhziBaBsPTgTBs2t6VaCpGpBBD81u5zm6nn887p+5KvA+HyDzabAEYaDVEgSigqKUubLsc5xs65T1Tc86I4YMaWQuxRoMDHmujb9h69MrC6CdNi9OFN0BXmWWE4Z0NwbaDjFnFXRYF8LW0EWh+07v4dOJY8YDoVe0dsGeM67XKx4eH/H4+MiO0Aa2wGyKhj50yOjG2G6WsMjd3MLdfH1HUwQAbWCzq2bxGYG7mDwlfq3D393FXjt66Eghoqqi9oIBfv7ocM5jXU94eHjA+vqGrsCvLy/46dMzbvuO9TT8XgEBi7g/Ks0cI8vArR8eH0GwsQR+fL388PXjp611wAq3P/p+4ADVOJQI4a5+hYhDRbNmBR/f65GCx8+fnvB8PuOPv/uMtHj88u0FX7++AgAcGhSeIHUgK5BYi4dYAz7vBa1t7/zt/tLxNw2E1UI/H8zJrhjsJVaTxcAyJoMEjfjgUkqWvDIQnp08VOeNBfBuHFB7zcWlNWNCJCbhe8nIe5mVfAYuzmQzgiFfdHKwcyYdVhUKdtVikOZMez58ljA3bRXgfI7s7ubEvDLcca46/JkUeWu4vNxwfd1RckUtal4sabJTfBDEJSEasPFwXnE605j/div4+k2RO31sfutoTbE4B+c7glIOCGBSUalnJqMqBKvUOWddg9jSvfV2VBysy2PJlHLS74eL0QAlSiNrztlmnuIINLkIeLWqYaBfVOnNko1KZlivFvxwQUM3w+sYqEH3TMqY7LFrWi2UyIoXBMcApw1Wlw7GQr9DC0fQRpCgK42auyqePiU4UdxuDSUTTGtd4Tvf67w3g10xmrRD3njuY0wfxwDBZl0AP0IrnRcsJ4+nT8kWKIdamIw674AMlNKhWuAdjagHsAcLvihFJPuo9IZuwK/z7G4Du6e9HYEeQUVWbdQkMOwkhBmIDnbSCM6HrHRZCYTlfcfl2xXigFKBvO1IMTGZdzoX8xgjvPmztdpRc5u+HKMzmjiZXRoVQlaKrYRkvJExN4K81ukFUPeMNtYFu58KnTLD4QXIn3MseNdNUiyzhXnvHVooo/TRo5SG4DgXfTAGnjsYks47rD2R7t8KtBcM5GrIUuAE260iRMXpHHE6B8o/WqYX3F2yRtnLYVIfg8d6MnmufZ5TQAIbNOt8lrBq1BgXTNJNgQjnuQDRSoTGt7w/hkONsrpRa1Rpet5ymXJVshr9pN7HIIgJWBfBunrcbpTN9kqPLWegysvrFRJOOFmy4INOD4/eKe/TpthzRZaKmAKWn/xcn6IX7FsGpJPBu3jsQxKUK5+hSXqAihCtaj+STAhK7hZ/0Stn+L6lFCBOkYuBq43ylw6gqpKlEshcvdnG3Tu9HOmRQnC11YraK6KPlKUoJYIhdriqdv+scUQgYIPe4Fw4khpPg3CBeZSNxNbAl9GhJwRPP0dnAK0XpMVhPQUsJwaLvD6HmJikX14ym3KESKlDwBzDIoCCBQ3iPwIf4jsGRasdojQi3kdLe+hMlmbS1jjGllNALWIJsLKzZVfcbhXrErCsnNSt0HeQnlIBtRAcuuWMh+dHoAExRIgKmjZWiMcKKhy32hl6UkrljBGmxn4wgE7Gmi82NgY7piKXal10q8lImLgFR49C7z3assJDEQ24CZG+Sdr1PbiEI4YYRYTjNxyTs4uYKqrFgs47Y1QdBvPj+cBipD5AMHHw6b4IMq7pAAF88BgoXe8NvdYj6f7BcS996r1CDWwY/i29Vfj1NEOu4VsGYN7rBqEP52RRHCzykTSvJ3q4qvkqpZRYjNCObadERryH9+EAU+z4vmL/l8Ew3g6d8SYz0oKg5vfWOy0ZAosCLIz2WeBzBkoczxIQifysTnW8G5IeO5dRLOXa1ec9hbrj1pvsq5ds7AdKI5sVYbvS3sI7JnD7tlkxlntVTPRMzDnPMQAc7KtjPDSodUzspdgY64geVEoYYBOjA9DYeKGTLd7MW2sklpRkcw6pVdZiNEme3TMB2OBAHGi0zjgTjizZdpf4TONrDJb3IWHu6NAux3g01jJghuxiMpxeIOa1aFmGAUz3IDY/tJT+IS7D7KA9YnIAc7zOAjB4T0rPc544x0ZdIgqYib1qJ+Dg2KCDhdc+X388E46lVjuSU/jBKrJ7rG74QglGk6CjoDzu32g21BGNcTOBU9v/gaMYy+6fIznnGPEws3OLE+7RfNWjS2QMbgKCtCfRu8/i+trtvLxj52HgjjCgxvQRRQAboaE5eAFSDAQRUkQDgXTph8JkyJVn3Dqen9ypU2DFGGE8wTi/vdu7oDiYzt4Bvd1dq96BqMD9mqIYcuoBJA9wFGhFflDwPo77dXn8XXWA1GPNOL4HeqgznI2RaliWc8Ixb9+X950xr8VhtVaakjcyzj30WEfA9IfMvg5txTy6js7aA8jrIJN42LWEGOBU0eBwzcz7nBWEujo0ANIaGsicbiK0jWgZtVTsOxli67oCIlgWeq2mdYGLAQp71qOgY/EUZmHN7k1XqCNLaTz3cWzXF7iHB3Q0oAgLhwJjyxI36ArKbG2etVrpwxbC+07OPzgGoLqsJwAOtXGdbarYc4aKstu4/Da8dXzWu2n28bf4CGwd4+PDh8yfvv/G8dldO9xHaRiOMRXcAMA4vpN/gEIQXJxjlqXs8R22f9o6FANtItY14d/93c/4u3/8Ca+vF0rqtZNY4oZ8fXQ0FdS8A405n0ckRvNXHH/TQFgzeF4ATHaj/ffoxDKAsGGMS5rk4pwxLsRM78x03OjVNHe/Mxh1Q6sukwUzFpraCNrUykUi2Pu994jRH8wtjIDl45XIHGBMGDGrvq3pNIsGCHRD2IWrloqHJ7b4rXUg1TpBlVJoqp+3huEfdX5Y4L3H9XqD82RALIt5ZzhgXTweHxNSCgivwPW2IUTbWNuPJ5kQNTDNtrEwLHEhhZ0ViSH5TImAxOVyRS4F4W5T2jczrjdz7bxllH10/xkeRXfTx1mXxUDGDNngY3Pk+fVRGhNMsK1DIRZIBe8RkrHArA18yQqRBu+F3ZD2irpXuCAIycBQVdy2aiwQZ8n2wZwCLBgTFicE9E7yQqaFdsD5jrfXHb0pSmkjlwK62E0HRAmiDs8twWBPKQhBjNrb+HN/qAEPBApj5PPwUdCKIKjg0ilt8966wBWgyggQbdwZ6BqCN9luQM4ZeaePUDRavngHNXBzjDnnRwe1MV4cXLiTS5oEalkjm4XrAYxRWsbxfrtSprrdyKRreceyJujsosnNKEQml3mjL1c3xtKQWYgT1Hy0fiajShlcw6RXFhSNeeVscjJGYeLjJbBdOyhLiEuwoJ8y7GHw7jw7XSIS3Cx7uRu7gm0rUE/AQk2mO6QhKUZAImor2PcC6W0m2ExG+UxaUxRv/oHWBUo5wLiBiiWcQgNU5xjYbVtB92q+K4JmoAY9S8zg3aSQEJ5zL/z7WJdUj853Y3kY4H+v3a7TdkYLfhWUb20bOyDF4JCSn/NmVPZHsrgkwZIEp9VD4FAr16M9MKkZvoUhOjhvlSaTUdbM79l28wUKZHA5EZxOAWti8CHeOpguTJC9d7he2J13JAosRjQsq8frK+hl18zMHgqpCh/ItnWe3QmXlexGn8W8yKzwosCWG9KJHoqtdVBVTgCiFNh89RO0r4UAPhkmDvveUGqHH2uzUvrhHLv7joB+MJUGEzJveQYJtVSkNRl7y8P5jtMpQZzD5W03kIEgbbAABQioKBgdkxCHwKej1IqIowI79r0hl+pK2d56SjRUtjVarTthjA5lr9huNL73PmC0mVfQk8yHgBjpF3a7ZPz6NaM2ZfOX1pGCefaIoOZuwGSg/4ed8+ttw9///ifUzDb02nQCg+PoVukfflDjHooIvCXWgxX6QwBIWRV3Tm1NtLGpVgU3s3ux/y+tQbqiO4HLGcvsdHbcx+lD9d1mzHXL3fmKjiB8eGqNkPODOY9N3CPhGuvzPTtqJgi2+XrvARlNV/Au+fvRocrXjgS+W+FxvF9VkQywCNHBiHz20WSId8Uh9xUGzMGYMwPUX2JksKxqprxM1lpXOJNUex8RlgQf778F9Cxz37MC5r48Vrp7YND2BQeZz3jCa72T+ewdgudepzA2G45OfOO+hxCOtabzWXmT+Y8EGZbMOWME4j5RnmPQTbB6SrNm8eIw8+/aseWO27ahQwAXLCljnFhymbHxSPpH3KvKhG92NNQ2WkIQTHLBCk6N67oyfHMG8o7C85hDI+E+ACOL480+gcWSAZR11HwnvZs2DHIXszic1hX9bs98/1AxJY9MBWhtcfyac34YPkPo5TWSDoHMfYLDoN+BhhxLbNShtv70CegPANeblLF+ADvoo1kRQgSlfM1UDwwKB6dvgOI093fzs7vd69bIPPbWnZXdJIcVCmzuG1vbPK44Lqy4JWJ1q5GDWBJrxZ/BEqSVhl2DLerV/DTu1SRzv7A73BSoncw7N9ZSMF5O0VtsaFCUGFvSgfGsdQdtvSPYswiBXlPaNjjtM27tELRa7tb3O1BqFll4b/Zth3Pergdck4E5rlTV9jEDHqw47+zjnJ3/wMhaHx17j7VD7LnVqqgg06zVNmWIzhqk9d4/nOq9cgYYnXPHFXUla31ZEgsVd+Oq24NVPfbjMYr8kKapopbMtbk3dLCTc7kD/YZKYuR93bxIuT4x/tAuaOYpR9ufMeEof73dKhpMuaEd6DtJBL2j14an8wkpBjjx2PbMtcjyhOgdUnCIysJkNnaYDwnLkiHO4VQyYozojrmwCIHl4RU34qHBRJ5WAGh3Y2OsqfQJ760DBVi8t7jY5pgTFmXlYEgNUHUAkh8B8ntMajCUT6cT1vXE/18f0DuxhettQ6kNjw/r4b8M7ukxUOXy3wLI/tLxm7jZjz5Vjvf81vuaxXIOHWs8o6siuOVdLDhy2AnYzL/b19j/OgCfnx7w7/7ud/iHf/wTrreNBVjtoCWW+XV7wRoFfWEBrLfIwoz77au7P/6mgbDRUW7EoYNpMFDCYWquxkhopcNFerx0pUxySjYsKaCGmRtYwQFA3Qeitba5mNCLhH8AtpEPMUzQgH/nebTaIKIToJnXoUN37ucAE+coaYGg2kMf7JztulsgzWPIMhWj0kJZzXbdUXaCc3FhQP3weELvHddNsUSP508rwTo7R+cpzxpsnGUNWAvp/SLm+zE2AAPrvBcCaX4wMHgVzqShTPyO4CGt7MJ2vd7Qa4OafKbVhv224XbLNKavipqtytfxzq90yi4n4+4IqABYsOvsGZlRrAjiEjiRvElhIdBK2V0rHb0UdFXsN6vy2qZdzdR5OUWodblom2IzM9iPK8QYgz44+ChYTgE+UKqZFmsX3mAUTsHl9YaS2RnS2dgWcCFolV33PNE0q2p4kIU/kiS5uzeYlPqxXE1QMppH16BOu+ETYL54TWeb6PeDFBPU8p6SMjIjj3E4/U+4I3NjGN1OLSj56Fsx/y0wzzAPNHYO8tb5pRaTGDqHfevIuZFNoGrVl471bKCZ8p4PEIpSTXvO6AgLwSjKDzGDwVrJGlEF9s0aaVjwrb1b1fJIeoMnMJl3djYKYGVVBAjJU8/vmiUE5v3krJmFKtANLDO2Vd43BL9OSrqCDAcJJoPprIJI8OhW0fTe4eF8hgilXqptVlnzXuC7wke2OlcY+8eAOmdgS2uUSYpy3Hgvk9FKFh3ZcTlbt0vnUHV4ZbxPyHWsZROmNnmtJQTOyfRqIQiWsd+sM+eacH6gZDd44ZxtipwVaSUg9PDA5h/XSzeWmQK60D9NMOU1jpZHDDJzw+Va8Ou3G242vx7OidflgPUU4KNgqw2PzwmtUjrnHQF7FhPYZbfkPr0hR8JkeNu7tbzVzsYDtgakk8fDknB6WKA2Hg9AYwT5gls2qTQ4T0bHydqMGeY9ImhIXjtZaespWTGn43LZkHO2/UZwfliNpaBWbbbE0ne0xmKD9zSZd94hefo4OsfPFfFkWZnM0PtRhxCkRH+MUemVcOy3W+7wnkUkdiikj8a279j3HR1WCQ6C9TEA1iRiVKN7FyuCVAP/MSWWGp2B9opagZgcWu349pXegLkqzisBbVUY/d5AWYsBIArnAzo6Xm83nAKrlAefwdZSuVs7ZvGFe46fDAxjdZi0R9+tnfy99w6Li1gQAF3mPj3Wgj68klJiJ7Q+YotqwW58H2C3ht6rGVXb/WoyFcA0nWfS3QwEgROIBfv3ueg8F2CyDyEcfwOQEQwg7Hj9BP+chwPB7jYBHWNqjGhWR2Hh+26RM/YSayziIwSKOIAHkFHXazPU4mCpje6h3gDSZoVLrQVNK1rJ0JbRawFcBGT4+iz07FpXsmXkiPHERas2OrtWu18A1OS8cnf9vEQ9AEYFzfetyDZkqvSxseTRwTozgh489owms03ukwIx4+b3LIXvMNDfOkbS/IM3qNJguuw7cs4Yu3GKCeu6ABCz+dDJ3JqMFYy4dci3uK/fM5MmI0VkAtnoigAWqfvw+BI5xuOdBHeM0wEychwZG3kkhHfn45yDg045jBPBmhJKLSjGWht/xj45YlioWSVYEem4Pp3nc5yXpXEyiu0C2n4MqeeIf+8Aw94me3RI1oa882P6Pb5nssbs710VZex7UDiwgy1fa4C6xeVNBXAeqpnd1YYfsSqcsbcOKd5Y0wKqVIJ9do6jAdEYjxOsksEKO4Cggx1lBZHukVwfPZnmejDuSzfALhcarSfv5rU7USRj5o9lRExKC0c5YzJLDHZtzljXE9Z1tT04vgPme23QzqZOXggY9bs4hvesYd93vHx7mQbsZD0dTPnB4MulANYtcs6lAdQJ5Y5tFgf5T9fBCuN+qyKoBpKR+Ke2Rip87/Crm4PCmfRrAFjH+MQch2NP8s78Aa2juGpHs67PXXheTWkFMkEyVVQRaAhoWRHAdav3ilLau/Vj7oUDxwAg1k0UVnAdVjWiIOnA5n/vLGhctozRe6n1jKZseCIgIJhiAHxEaIrWdvtMqoZSjFjXhDVFLNEhqqD2Am+xkveestroAU/CggML5CnyfcE6CZP1yHPsBAkAHHMFANbTec5/gpqjmYD98Q5qPmf+bs0b89aHgG6yY/7u7o/laYy5Vjw/P+LhdMJeKwIUtRb88usLcm34/c+fUErFutAPL6aA58czvItWqO/vvuKv3SL+e1C097DVcQwmr3Ocf9Gf3/1uzIPJDp8g2MfzOKSf5zXij7//gs+fHpFzRebIQm8NQQTJeyRP/+QYTjitAcHAR0HD//X/9t++nr9pIAzQyQYaQQss2PBBEJM/JEBd0cCg3gXbyIcc4IMfEwEhB9fYGc72nZno3evz9+3wBAvBWtMnAmHRaLkilkhqQ/QytcvzKpSd0EQMbbc4ktJJJkMdChlMldqxniNOjyu8c/R3Mlps62QjbNdqRtZKgE0BEbVJLHCuY0kJ5/OCx6flXaXKz4QdWFdq4GvdeLKmABHA0Hwu4Ot5gXPsKDkqaMGPYJByE+fJTFgXVuZTCvSTUatE7BV5K8i3MgOewb67PwZY54OZy0OQ0mHMPxFnW7xGtVDc6A7pyawIJpuDIG+F2u4BfArBSFiXtHTyCCdrQ186kw7UGQhDYWwdneCZ91bZjg5pjQQVTzRnabkipQVQxels3QtH9zbvJwVb0LFtZXZQ7BWsBLvhhWMniwEEwjyBRmVUGJQLgaW0kBnWinXG3NoB7I0qD47PBMZizkU/JI+0RpRMCdYYs/evHVXeYVbrRIkW2MBWKHqhnk4H2Ow4f2IINDm32zrMsbsSjNz3xo6atknR76FBXEBcA1xlUN5qmZfBZBM2X/MRzIoYyKAomUBYbx0ucEMfla9a25wbITijPEeUWrBfM5wHegRc69PP4elxMQCewEi3gJ2yNQY0EGf+QR1oZtA76PmWcdKHrAPSkRLHzmifnWLA4+MZpRTE4lBKRYwevdG83IWG5QxjezpK68pgjBC4GxVrUcyNf1QZfSCbldKEjr2wqybZ9GpjnH6L4kCJquisWjk3qOLmEaLGhOp8DvuNXchiCogLOzFer2T2BKUH035TrKtiPQX87ndnXG8NL6ki54Z9Ax6fVnYe1E52XDLzWVHspeP6Ru+q65aR6wFohsixHIJDrg25VayngJob9kxvREqSA8QRlNluDXknK6Vkrq334DzHPO9/qw15B27eIbxwD3p4iFwLrMMX2YYMNGM0CUkjkOEdWQSbjddg7OIQItRk6qOAUWvH68sVt0tGaxntIeF0WhACkPNo3sLnFVOAC47yBEtylxSRcwNcgQgbaMQlojZgPSeMLn+DxZdzx2k5At9uMvUQnIFtHEs0MrfW661gzxmt0/dFhLLbJUWEwLF723YA7FhJ9rGwECKUpeeYsZxWPDyfCHba/KdPW8d2o8dcK50+LQZ88vy4DjLBA6IDUgB+vbwhPX+m91s9qu8DqNRmxq6wRMy56Sl6f7DZgHWUBCvQXAu5XgfITOqPfR/GBAGi9zgt9Gayj5rzB0ovQIC+ltrJwml1x+AGZ/Ohcj5QttMauxrrCPA7uhk/k9k+LxTF2InOs4jXO8FeFzoizAxZjoIK7vYIESD6xLHrgkkQ+bvBZOuto5Y82Saj+EHmOpkjXF4dnEtA3+2yCeDmsqOWHb277z1Jju2a66sILq8vyHmnZ2RvgPjJVh8x3GCJv5dBwlhzR9Iz9uHjvP9ygqGqcCEAlWwpds+uwIg5B3DjKJsj06kexQQdthrHBbrRCQiHJHacxWDozdLDAG/kAM5qq5N99/HorWG73d4luiklLMsy4+OPBY/5vXYaIrTbmEn6CDv0jqU0gVFWNOk7+L6DpipZDsEfUuhghTSxgTcYSN2+95000FEO99EY3wkbSlQzSa9DztRgBUGT1hl4pYrJCL83vn/3XEZi3BqAbkm6vW5IDw24GF0gD5+695/nvUdKaYKN4/uAg0XmvQf6yAV44zt4vdHRr1St4t97R64KcWQbpoUWElz+PFUJignyMNYFfAhw1UOtE+OwNiEgKZS7TZDW9vnRXEwosWWxrwHY0XUlK9dgvgHfiYzu2H3gAGRTwtiCc92oE0gGwKZn64oQDmm0Nkpm6+3GTn68e6iy4KBlAr1t8CgTLCitQG3eDQ/i1hpeX1/Z5fNOFghts5g55tWQy7eGd3PXGaC/LIfPFr8f0N5oqq6cY4c/XjGZmYECbqiXLK4H1wq4w5PxGJd8NovJxYcnas3bHI9QRdWj2VRRRdM2bWUm20s84B74PtfoxXQHBt/P/QHCEeD2h7TSudmMYXRPxcgFgwOKFchyxvWWCcqhotw14XDisJeC5SGgiofUguvlisvbFc4Bp9OK88MJ5XxCXRNS8Aiuw7eOFDui+baVKsYT4HXmXXADsBurfVkXrEsCvMc0G5mAN7sLfzy4xlXGhWMnMyDyvoPwYJAOmeo87kGwdx/Mn8UY8HBe8Xa9wEPx9rbhH/7zPyOEgJeXC0Lw+A9//28RY0QKgTLxEOFU0Wue38G94Luz/+56/nuPMEgZZt0DBapWi1MEj+lh3q+RK4xmGvfqkd55nziO3oUWgDG5Y3B4fjzj5y+f8Ou3K1qjJ7tAsUTB4xpwWgNOS8Lz0wP+ze8+I6WAJXrEIPg//1/+iuv5/9md+f/D0arJ0NIA/4/BRzNvb+bSA/g6QIqPAdBxWMA3ALHAxEaAyXAJVsUZbI7JdnJihviHn4AIg/W8ZYgDov/+lrM7WDWgiJtoTLZwmY+SGv1YBIgpIi0RD0aVHKynkiu2W8btkrFvBB5GJ5mURgecDudsofbvAYxxS8Z0icnj8SlBQfZGb21Iq2H750xGGnm6rERJwGllV7Rs3fK4oXvKj7xDEzWzRIIqlEM2lK2i7Pfmwpjn5wKfb1roAeUik3jvBKfTAgWfe8004lMZtFxep7NqQowRzVoko5MOrwawjMAyLJ5A6uqRVo8Qh68Cz+d2qXAbF/hm7CRm+sf4Gb4/fhggW7W91m7j1Zs0VfH4fMJ+Yxc2KCUdNG9W7NsAKsbNgMk6G0afmhAaQjBmAAZANiJ4ykQHU6bs9NPZ94LrW57BVggCAf0nxrsHwLus7HqVlkjWllVQ4uKN6WjzSoHgBVDbHD2TRNaf3OEPYgCQqqKDnUHZMZCJ90i+cm7Y9obW6cHRarNa/XEvOgTbRrPt9cHmqzirIlmw1RXbraAUCw6NFZVzZvXOWAkA0IsirdHYemRUNjP4D0a1H4FA147gPKAd+cbPWFZuUvQPUBp/9mNssb7I9SLvGa2xsltbwyJkp7Te0EtFqQxSp5zPWHcOrNZ2M50MweP3f3icbK7L6w4J9IlZlgSBI3C3V/ioWITn54MjqEvSJ5MRTy84slG8zXPzLTTwpGsn09EFRAv6SzXgwRKiIYntXdFzgypZq7Uo8t6Qc5mFhbTQIJ9gZ0GKAc9VkXNHKQ7nx2CACeVVwbPa2WrD4+MJcfHY94qSO2LkeL5dGy6vBa2we5R3iuAdTmuEcWO43jb6tAGAjw6LALdbQRd2Kyt7x+W1YDOvQDVc9x4EG0eMrKo3YwqXvSBvHrdIZuDz5xOWJfK6PQsHr98KylaxnsjCiDGiNQbtNbMaW31D6wHR7tcIsMZYLKXj8XlF2SkZGd6FqkIZceO1E6Ais8ZZ5fS6FWjLSDcP8Y77SieA2lsDaxFk6HYDp/e8o9X+jm29LAwOveNY2badayuswy/YqXN08VpSQHAeMThs1x2Xy45erYggAc4FQBoTHuV+C+0IHlgXLk70k6S0kNUTVp73G5+VDyyQLIGeRwNbgnfYasPp5Og5BTYNaUrmY5XKgoOthF4cosPBer073icKtv67IY0PH353JxMRgVeyJ4I/QB5xMg3hBVawa6NCf7BgnDVoIUBCeY2oohh4wWYBx/mJjPfdNagZ1zfYKVaoKNb5eIlxBta/dbR+ADS8QjWLAGcAqjXyaZbUzxiMoHsUP8F35/ycV2R6DBDs8As77jusc/foXMbjcnmz+2XAvj+emZoCACMZ/3Dcy0GHHcOPAKT7c+B/CT7N5E8bat3QW7aFleui0/tki3se5Xf1Dni5S3hbN+ZBsP1pQAeYqOQ7M3sDPQFM/9VRCBxMohm/KYGwt9e3KRnzJidcYsKe3+6AtXHBRxGETDOeH4Tzvtq+7swfVw0UncCOFTjECk3+7rmNsemDf/c8B7gkBrZ0C7MYe94pAYzVFJWdlo/Cjs2l3meCrgM5BEGGIV+SbM09ZMRLdz5NvVu3M5ksKVGZQD/AJJ7ooCPI29iIpasV71Rnx1tvzNIlJbhlwZ53XG83vmZIW9XYQiq4I1PaGBFAPHxY7MHQS1fRoFInw2jfM1LK8M0fuZDqfDaKwQJVOJ8gYmuiN/BSR7FT7BoH819Nys842DvBXityLSx++hO2FnDyfYJIuGvsMRix93PfBYfzusJ7j8vbK0eaKsQ7rKcz1ocHxIVdrmvOKJt5WdX6m8bYLL6xUcOQ8ZZaCXRbTMpHo+wg3a8GLB7vv18sxjz6eKiSaVVbQ9L31gB3L5rgGwt2ZIf6cV8GmCqYsVywpm5aRxFpNFyz++cPOx7AvESdsw7wxnoEz0twD6JZHDpA2Xmugl0fsOANh6T4yBXHe733UOtQOVnHAgTvkHub+YN3AmsRStBz2m0UxgZoRw5issPbtuGLNvTlRA/DqrhtmdJyu/2T7KBARaeSoBRaEjmzY8GQ+fc534uQXe+uCWldsD6c6S1mLLBSR/Exjot99/woGx22I4cf215G86IAdFMhmXew8/TEnqDA/UdadqQwkO90xhJfkEvGZa/4x3/+M/7uD3/A69sv+OPvvuDr0wX/u3//d1hXY7KPxfCHT+p/m0MVcEqP0yABtVegOyyRXbhbPyT/Tdvcoz4eLGoQlxl7I/Mb3hG1Z7ymhE/Pj1jPD3C1w7uMGASfnlZ8+fSAL8+P+Pz8hOfHM748PwICPKaGl8v1r7qev2kgDGBHqFoH4+XokuFtIgw84N16ZH/xVjEdkozxu0Fldd4hCmnLsA06eA9v3gsio90zB38wTXavfQYBtdBDiYGp/3AiPNS03vuNXcVSUrIxIgVdI8BqrcM5dncM3pFKKgSFyreMbau4vlXkXdGa0Z2FkpXTecXT0xnOC16/vgEdcIFmpHlvWE8ywb9oIKJzglLp77DnirLfmNTf3U/idIq8Z5zTGXAK6Y1AiDgE56Guo7Y6A4ACbkYP5xN++fUN19cbQbDSKCl6F3gyQE+RQEDr9I9SpW7dCc/1tC5YloDXy24MPxkQP1+Po9uUWEDJAE7ZhGzU1s0LiVIFRTo5nB8dUgqWiNFc3QWOuRgUbR+G6ozQxuZquwxjFCVYe3uzznEVrBYrN6YQPHSJ2JXMOAEBJRWg94a89yOIUkFHRzdqiLgwk5wQ6J3EOMUSKxzALsckGRYC+sPdbjTEjebfJuJRMjfZYB5U3gvEK0Q79tuO03lh58zgMSrSUAvcbSOfCZ/9Dl3hjbHUGztVqlNIoGHpmI8AwcJ9q3h9yXh5LcgbExv3YYnv1qa4a0eINAN1wWHrebJgYGO0d4V0QJviVppVHjvqXSLhvIOYVGpZF8QQsLkdvdM/MISIEKOxxByi76ShK2WSpMUnuChMtoxR2gyMGAEQwM249wyAkg8ImVVeHLoedHT6UClcsw6lYPAuDpCgaMbOiw8JIsC+N4RkgbSZuoYQeA6VwOCS4uGHokeyHJOfoK539Pga7+uDPSt8fUyCxSWUMuTJHMu1Nfjm4Hqcsp7W+BmtmsywHEkMfRsE243m9E7MJNkRZC6ZcymlAB8yzueAX/68YTDseN4RKsD1tkMcULLi668Z281argtInR4eeQY8qPl2jLHCnwOfHhO2HdBK499SCGq2Psbyd8s4n/OoapoexBuACRC0mfd6BEQOePl647l8DpPlFYI3FlrB5bLBB4/nz2cLqsIM2jjuvfl3eQS/IjiPbWv0Rdsqcu7TI6pUMrVKbQTGYCxkdLy97Fge6B+nAvi04OHphJozrtcdt60gl4bTWeBdQW3Df4/J4TlFOHHolVXmPXdIt73WCxYfsawRyxJN1kIg7XZl8WZ7rWhNcTo9oKqAinyeixN2zEwpIBq7hk0feA258LHkXSCZTUBOZ+G+5sT8OoP5SArNZx2lKf/4r/+Kf//z73nuA/b17JLGJNBNyeAseIgcf59r0b1BsnWwOn5i/xVrF26JgTFXv8uX7ta5rh3FXtfNAD5YQe4+99OuqAbchDAaQcgRGNvYa5YYhjuj+DF/x7m4sW99P8zt+nSO+TJAOj268b4LzMXYi+Ho1HsvOXNOpsQROAL53ipqLYfkysDD+7vUupIl7Y6OjKNjM8C1JcbFaNImjzWJ+I+QsJHkTwnHKGDg+7fwWsj4EZvPvdObrOQrar5CUBB8m/Eoi1SWDLfB7RmslD6bGIyvqaUCqcK5Zsx+UzyY5yXBECbUvVXA2MtePHqt75hNTOg7BGTcUkZKOdi4xpSS+YM5lL3YeDn2ielzdefzlFJC8AG5VHtGjv4/o+mECIIbjBT6+3C84O7ZHoPFOTe7805yNITPUIEqHtodtDXUm+25SbAuC6L3EFfR2m57rb8DYw/G/wTpjNFw+GMJoEJpjQP9ZiyppU9Xs/nTDjD6w1xVBd72DrjGomAfIJL5oNkeOdZe3xsZ4cq1tKvDXiJOIcE7SvqakrWp726VmE+Wfb4keAfUThYzWob2TAuS3icL6WD0jD/jvgimu52MxmIK1YZc2izA9AmCHc9uSJ32WvGWC5oqPj0o0B2KkIFDSw1j/YVjPCiAXCvBqdrhQkCMCT5cAdDaYXk44/z0ZLEo176aAi5d0bcdDoJSyndTmkWigrJtgAEYo/thByhpfwcC6fdjEsPYv7z73Pvn8M6YXg/p9neHMKdTY4ICB6DD+DIgLJQ4aX/fBGEco/HNQIS8u5Mhqx6fKwY6AbOAySs8uq4OIIyvp2eXfQw2PCLoNwpwZ853rIUAwVkOg8FclKMJg5EUvAgnu8Vq27aZLUXCXgoZ25G2KEsiwys6D7SCp8czXl+B5iJOj49wyrgFQtn5vu/Q1rAEoG8ZuZBNHHxASit8iDifT4gBs40Y1zQFujUPMfAxLQuGoqXXAjMWPvZ72CzuHb1WdJNXOufYoMtYhQGBxaRSAMEsWPaaoVZcezdOBdBhw+Ad1nXFw8MD6jdaYFQV/D//058QfMA5nRD9gloV29aP+x1/MNb+vzw+FoDux6EIECVa4wqyWk9mmQMAuWW47lDIEpnM3vdfcIRQo2EErPHZ4jkvaksAFF03/O6nL3h++oYlCt6uN6wp4KfPj/jy6QmfPz3h6XzGMrqDaseXh59wre+b4fzW8TcNhIU1AuqwRE7o2TUDR9UTHxas++qmOPcuCQRg0Y5t3sFBu0MBzej3reBSCspO9tVgEfBh2ibWzJjUEdGcHSMTGTX3lZgJJjkGNCN+dO7Q4k8T+LH5GNiS1mDXSevM3oD92rHfgFq5UJCNcfh6LaeI29s2tczOOdyuxVB8wePTOjdngTG9GuUmz08rbtdM+vZdEwxn1NP18cxJ0LN1phr30NoiA8i5ILeKzVGukpaIauDXvmV8ZIEBHoIA54C4eJwfVviU6OG1ZeTrDWKSjVyK3X9jQsx77+BCgg+KVkardYJAKXg8PJ5x2ysp55UecmqeORCTVXaHEASffj7j5RvPU6siJI/9hdIHveuXLPY8m0kLWgVqbnNTa41smOtrQc0N10smK+JGf4aUPNLiraI/su595t+lsbMYvwzwjgHjbkCMiCV8Vj0RAUIcKw7HctmbbSY6E4iHhxXOOfz0uzN++fOGt9c8K2Wwqs92y1jWCOiKVnYIOv7dv/l7fH35BblUOAfrEDmM9m28D7+1u+DXeYfaaZY+mJSj81duBa8vBV9/3VEzzfxHgnSsp/yfrvQU0k72YUxkMcBzg9G7zZugM4EphZJVZUEuF1zBSMfE1ogQ2b0pRFbZ2Nm0MSlPfA45j0YV9CPIuRsjEajNWFC5WpIKPDxResLgQfH1RfHzSSCB7DGnoCyrH9caI6W1IdLMOd8uuL5s2K6VLMkFWNcEIKN3+m1577BtGdp323AFvSjK1uBhXoiN8tiYAoG0rUwvHwHnQN4Ltr1g3zJ9Ck4J59OKEMJMOK63DdfbZlJQS4w9/XZqKdh3dl2lp6FCdQFA88voOiQQDHVOcVojYhSEoIgR9v5iiX3HaWXY3pVstLR4A2QUX3/J2K6FXnLKKn30Hl1YPR3eKFDB7drRZ+t04KcvT2it4+YLmwcUAuu19rmOzj8fD8Edm2ck+A4lF+smmZiQNeuy1SuEFl9IS0IpFTnTd6Tkhn0vUAAPjyuTXiWYFiLXOJcCwUpVhOhRakfJHeI6rhcWRlRZoXVOzNus43LNqIXsvRgD1jXQS2vhM2u9IwV2TpNe4bShlYKyE22quSK7gi4dp3PitXpBtAYg2hRJPOJGpl2zjpZuSKFbgwYm9HmveHm54XrNuN2K7TcJ4sgIk0CTYweyFJc1Itra7KOH61zzW85QBCxLMGPqhlqA7B18jAaWVbgueFhWpFMCHPD2coUrwNf0hsdIg2EfVoKYwr13dgSEEX61w0+JD6sOR4hn613v9A4ZgM/4rfMTxFQLElWPJHkE4pTZmO/YGK9jV7TkN8RwMF7vhmHw3oyGR4LMtV9hDGkb++PoakDS3cvHmGHIdKT672CoCarh3WeNxbY1SorEOSyJ3l+1NZRyL/HDlBMNqVgI3rzlRiLIyryISWqVJtveQLfWK1o3nxzzbuTrAS8RPp0hPtDEF0CXAWx+TB5kmtKrbRYjhNS7iS9yAIzDeF4sfqutIEDR6oaSr/AocF4nC2485+FxNQCl8T29YxZOATMS7w0B/QBdlCzC+86f43yhFc5FBEfZmLb+Dgxz0Nlbuitw23fc3t6wrBE5Z6ynFaf1BG1kFk6vHLn7HsAY6RbbRhaOcm1MeIyF2JXiFm/jUJxD8g6CAMCMyXM+xoIIVDwaPICABkETssBu+Q0QBx8i1L5La4OYWgOOUrqtFNSy47Zt3GvNB2gAVIp7+ZLFEkJp3uiOPMABEfr/MBfuBvRRmozh8yg/YCEJ4OKKLp7dn02y0rTCDWGjATSX3rBnFjqceSWWxgS8ajJaWkVtV/QPRrnDoPweVKYPW4dIZPdeeQTqK5p25AIEpRWE6r3qgv9trWJ072ydLH3tin3b0VvFsqzWGXtMhXuRE6VPwwtNAGx5x+MKQHaoPADiZ24QY8B5PRmTpsKFgNAqamvoZr/ivUdMC9bTCct5mIgv+PR4QgoBL9cbcmZX+Zo3bNZxdFzWKEzlnFFKge8drRRs+0bLFe+t4YRMmWJr79lfmJf6XpY8fI449ASqR3MRjuuK05o+gAkDrL/r7jp/xfXch4C0RGgH6l7egw+wXHHW2Kn08O7956ia7YkIYqQZfW2VslzLfwd4N/ai8Q2lHc8TAC5txXbLeFrru02GEkE5CoMC63bI7p1cXzvWxD112/YJwP3xjz/h815QasVty9hzxRoDrT28x5oiG8ao4vVP/wScnvD8fIJvxsACVTMEuDs0ePQYcMsFWgrEQKjbXuHCii03LMnjfAqInvt2B+NaSjJ15jnLuiI5jwQH1Hq0P7RrDwA8FK41iKmgBnifUqINkHfo9fAdjwuJK0U7pHYghGM/tb3ZCfe99XTCl58+s6HAlnF7fcHp/ITX6zc0NHx7fUXrBSkQUKu5YQdsHDjoO3D64xjDd4ca8P+j34lQsUBf2e/tnMY/x2exEzC99ioe0wn/rz/9GY/rit9/ef4AHnP/aQoSUQ5c18amx17CvI7oE85rxL//4zM+Pz9hLxXnNeHh4YQUI5IB5CQ2VYg2/NO3r3B+/f7CfnD8TQNhySWspxUCM4w3OcqoJLHV5vDmcUdAO1FvvY8H7x6U2kS3hN1ZS9/aTHpoNGh3fG5KcRpLchL0mYgOz7DRglr16MAXgsOm1WSXoxvHge478xrr/fAGcp6IubNAYd/ZhWPfLFnDQKG9BQ8ej8+nWeEruSDnimUNs5sPQMZEMN+KUo9NYUkRj4+KyzVj2y6UEPYDkKCcKaOb2WEXRw+uOzDMieDtbcPrr29YzyfENWLb6CHT6nszRh4eAJPbGOm9tpxW1K7TyyulCC9kNaWUJmtuVrosWCWoyGYFRRjIRD8CUpMOtDrk5JAEggbaIOLhg8lbc0WMDtdu4FFl0PBDdgjIYFkXdk7aLhtqrhDP8dfND+jbLzcAsKYGQFoD0hoRrctoz6ziMgBnXBRgba65p5LRpNRt+xAQk3klqFVlpSMEyuv2vcyOfwCmQbI44HyK+P0fntF6g/cdIZLW7JzDaBPsveL8sEAAnJdnpHPCnneoVc9nqy9b4LP5161rRFfzdbDEbiyjI1Uc7c6dsNnD7VbQMruo6d1tvmcvAMB+y/DBI2/s/lbqhXLjaowVGXPY/DvqITUdc1zEswrqOGZL7ciFv2sdxrZhUO09pcajUcfwUKqtIXo2U6BcuBg7BiiVAZk4wXpO+PRlxeu3CyQIalH8/g8nhODQZ2BBDzwP2BrgEKjNYvczTzCELag5TygTqzb3eY9qKbjtBa13LCY/lMbEzTkHDbz7g007EoHeab4O3adccQTJzip7KSUIYOadCqDhtAT02M1PxCOXjtH1ygkgXlDLSEiOiRO8IKaIGJz5K3rEBMTUmUx3QfSCUhXbVsl2HbJ38zRcFo+vv97w+m1/B6qLMCHrXRFCxLpwrS614fW2oasiLQk//ZzgBLjcHPaSpp9VSvTfKDYefjTfOS7dvI9c3x1ickiLx7pGxEQ25F4b8l5Qa0U8O3z++Qn7rWAwSra33Rqy8NnGRJYWvTVYNV/XZH56jgw873Dd6J1WSsftVhg0N0UTRVoYpOfcpvFs78DTI/fPNoJ6T/ar8w6hF8DMe4eZb2sKJw1FM9KJlesY3QSE963CO64bp8eIWD16pW/lft2h6KwE7wTuY3R4fd2Rc72bi1xBW200OYb5pjiCfCIE22pnorDvnWOgZGj0CIl+E5DOkoeBGzEFpOjnGF+WBTUVvN1eZkDnRNHyC9eDtEJ8omRc7oAfJfvLDcDFABinDbXR4HZXjxRliisnio8h0eDetISANdhaX98PrL06Az10gm1kS9paFgIueYdXIGHB4heYewB6BXIFHBKWkGy+AbkpcutIkWxt9GKALUw22uE91wPnAfENGLIx20d5HUowsB9BZDH2lvSDXV3BhLaHAPiAyWi14FqdAD6gdXaJS9i5pwYPcTS1z6UiOBYDa+/ovRrBgBYPaXiJAsakJLjio0NMAecF8L5PD6auASoJ4jyWZbGHIxBZsCzLTIqLblDNBAbvLt2XsAABAABJREFUpK6jA1+pBESio08OkzOH3nfQZDpjyx0hBDbB0IaTeeJ1K5wO1gfgoRpQ8lj/ga1mlO4hLcA1Ae1lafoc4vvQnXYgKxBXoANjqRoF1mCMnHmoQrcb6r6htIJ2LdOrKp5WXEtB7gUdhQWlqii9oKNTxjWsDCJZALkUlLbDdTPNB0HXr5c3nNcV0QHwBIdap89gaw3nGJDvxr32jl4yfM/wID+pa0ftFXvrg+TPPVc7nOezv10VqhubNpj8lbEHC08K65KnHNvRh2l0DjSUmqEdeM0VrQMxCBIGmMwYtzSyweheYbG1FXrGMxhHDEBwiujNOwwCIM68omRagWTzkgTqh1z0QrtyB0jgH85LWkGoOig6dm3IDQhCFptTjyAdtWwoJSOGiBSjFc07bRBkSNiOb6uNLLe97HAi2MtusTsVJz6tqArrxIi7xJmBVDX2YfSKLycuQiJv8BIgPiD3gr3fEEPA6k8oveDlxmv23iM4j+Q9gk9IidWh9OkZcA5hWfDp02cs68p9C4LSBb2S4e+Dw+3lgrfrGx7OZ0COJk2tNvS8Q7Rhrx1bbqiNrDutHVLpS9lUcc0Gat5V+ueybc+YwlMwVhTOI6cdodyxAwB0WSE9zM+Ao0Rv7JMTP+gO2tj1tpQO5wX5Wszj9ohhYvA4JQ+RY963RoCLoGGA9yafDgfDrULRc0e0tf2YaPThROd1HQWbu2sXwSkBSaw7rKrF+QDVJu/ZNs55SIgMrIWMu60UOFNPOLBA0+CxJJ5fKRv2fIGC8nwBY7ktN7TWcb1cUV9f8bs//BGPD09Y14jb2w35ViYDW3LHdruitQwfzrBqI6BAKxlvJeNVAP8ieDgtWJdojQdYaLhcA263guvbjqdPn/F3f/jjBBr5WZgjQPzIGypcr/Dw0x8PoHqgdtrAIDjuf63j4bQgANgL2ZLjzo1YJw8CjXY8fnrClivetgIND/jXP/0j9vqCf/d3/4b4Rlck160pkEmxG4umud7FG+/Go0OXw+OOqaOHR0NAnWy5+/epFd+LW+5PFqKKJBmiFc2aKkC4LjUrmqTokTXj7//4zL2gb/MjLDWEEyDd/Z17FYsBeXdoKGjqEbQjReAPP3/Cp6czfAiAO9RdI9/ns8zYK+BcRJKA9bbhrzn+poGwOVD/3+T9Z5MkW3aeiT5buYiIFFVHtADQJAEYh8YZUAx/A/84x2j3w1yjukbQ2AOSDYDs7iNKZGZEuNjqflhru0dWVTdwP7Zdhx2c01WZIVzsvda7XmEQfXtjnWSl2iWhOjcZjNafr4+6U2E3lLNCivIgGisJHMbI5NneTBEFyBIwyQdP6OR0FmWGFYXLnRbRKQqSvRWyBvrNeFyawViSmqx6ZTeJFKLvvaSd5ErnA15v3aiNczHN3FEK8yZJMsZQjfi1rFMUc+UinippLQxvg9D7Nems6zzBBbpQ2+lRBplhvh+5nAXQ2a4BQsm/Pl8Rrx/5nMss3kehc2Rkin29Llgcl6cFnhf8KIyweGOI75wT8/FiKUVAvH7oOB2OZApxWUlK4xY6q4CJKcn02XditJhzxVXITpL/TG6+RygbTijFGDGCT0WM7RubS4BHiHMmLg5nJa3QOymO0prEvyeVVwVQOysVw7xmBUmakWrEd26b5Ircbz9CH7h/c5LPqfKBdVokWUv/kU1PhtlGEfX2DOACOYnX1/F4pFRJ02nmrSnKYus7WUAO9x3zRb00bN08sWJSZpeVpck7kfGJT0ml6xxi4n9hqheZ8HXC2otLlIU6CAjnFfhrJqqNbRxTppiqU+IeH6RB8GSWOfPyNLNOSZPOWjEhjJNS2SbsSaWRqI/dOutGro+pdbKYBzWot94yp1WlzbtHRWOLglHvuiZDUQp5hVwMgxP52hwXxsFRS2FdBCSNccXbTu57bzFZ5SKlbgzPrOln1hkOdwJY1q4TmWgRr6fQBfyN/MtauUexOgnXptSHQImF0EtTWfT3u74V+cJsDJ0XABZIS2K+ztIQNn2+aRNwNt8nkTlZ1jVxuSySwqPysmHoSTkrOOipteC95XjqBKRWeWyMMoE1VZPQjGGKUvw34LAUNnr58dizxIhxFd9VrBdAbU0QLxCj+FsdTx3LXBmPHRW3AU/PHxcuLzuzdAP3AJcrzlScg2mNPL1cMU5AhSYxuTwl3s8CpMfU0sjU1FvB/1fUm0+feiNgUegFvHKbN5Fs2uuSuJyl0U8x0wXD8W3P228Mv/m1ML9+/T8/yvnPdSOsxFVTvtQ/qJnNO7+CgV6943748UzOla/eHHh+L4EjvnMcjoGuc6RU8d4w9A7reoKCaN5bhl5BzbFnHDtGZ4irSKYFYM00L5eUkgRuJENc0ACI3Q9KpF7QDyLhXBSQLllkKTmJTKdW8boMISvIKDLjlDPjEIRNlrMMBzph5VonsvBa4HyNXF4SSWXmTVYUOq9gnpMkSweQqSURY4Uk+3EXJOl4DB3TtHD0cg4E9JG9t5SMbHc76wKAnEkqjwohUG5MHI0fGJQxIQMM+Z3GnjBY9Zo0NCMGuB3EyfsIGVhSpk0VMKzJ6KwTU+n70OGqwZiiqYSfFTjbvysZ7wohII1RLSzqpVSKsClvf3/zI8PQOZG9bmmz5UYCrJ89291c3Dm3+Tq1gvWWRbE/MPv/zrmIFYPb5WZNAiqePlVlc3L/b75Fr4aZbIMb8SizbK5sugYZ/e/25y3Iw5iVZRFz+lZYl2LVd2vrXPU7K7NRfQjaPuW8x+WF5IX5V5p/UVEPmxJJi5w/a4QBHVzYUsdrRSQ61jIvkVQM3U3B31jH3jo6tRJYbyRWn4L0LalzY4Q1qZURiduyLpJCSuUwjhwOB0Lfcf7wxHS5yPOmDXdjldwmqrU7LMXM9bJQgqfXgbA1hm/u7mUIkQUowVi8qXQBsrfM66qfWdjZwjaHlKLUhYgfYUqRzjq99roeGznfizamMWUZIN4MsWNMxNRWJbm/S3kdppRrYVkj8zURs0d8yaVeqUYGEKmkzevGqICa2q6/U9nqDohZI0owvUNv7s89xfN2CG/q/qS2PxZ7FgXCbp5LSwUjtWXZUsPFY8upx5JzjqEbVN4rXm5taNQ+kwDrjSkq94cPwgqnyrA2rpKgHUIQI2yzOY6g2+MGGhSDKkBakIoOCJqXkulwTtJbt5rOCPMuuLaPO7z6+LYGt3OevCxMSUzKcY4S1YKmii9UKcIuXOdJwGgv7CqAqiFWt6EU7WFrgRj11VVqd/U+pL09Wh/ZFDm2iv9nW1eEtWSI8yqDC68J4VVsT7IOZ521hBDww+4nVksitbX+hqkl691reZmk4omCQEY+UhNiDb7rKCmzLovIq3/P0ZKIX8vVLUbfzzRz4YoMiCzUYl7VQrcEk9evXalGCSXNa80bQZRA1/NAVTl7ykX7Jvl97x21GuK8UIaOeSrMy0JMSQYxQM4rKc1SJwdhAJUVahapdsshKEXOVeN3+xDoQ4dt3w9Zd14uL5yOp42dtH0XIAqRUMCdLPWB7CktZE9YiI0lDLCkTIjSPxXSzXnWc2csXZDXSDmTbeWbb99Kom/+ntMv/oQ//vk3PN6fiPPMYeyIpmMhCAgrBY0A9GrZ9OmeKMWkeN7WuOBtxVklq7DzF263D1kGxA6nGrvt1bc8UF1S9P6wCmQVqt6PnwoT614mvQLF5PXM9r7OFGwVtUbBUqtl7MVfdopxuzfb/ZrVAiapTUPOme8+fOTbu+PnN+UXjj9oIKwbjGjhi0xIrBUZ3+4Vxrbpt3+/vkH2WOhW2Hnf0mNkMbN2b+QBBa2ceid5lRGazZi/TU7b61dlcjndGHOpQl/0kvZ4TjJxD97g1MS+VpkOL3mVhSI4vLOEsYMqzZsc8uC8ez/hnOF07MipqgQGoOI8eG+Yp4Whk8Y8OAlePpwG5kkfZFN4eZGkkeNxwPu2qcuDGrShGvrA5BJRB9uyaVam84w1lvmySpElTx9eDeeNgTUW5ilCgq63vPx4ZbwPnE4Hzi9XnZZlSlWqMWwG1847hqFjusyb/sI78ZKgwhozd8deWIBy9iUZTg31x6FTjxhHTosAMcB46FifEy5I6qALTlLWFGFMsTCdM10IpFUSTmqpkhiHDj8+aT5KSlQqiwGLFVCxFbLqV7RMCaplHAPTFHFhbxy210U2hlQUHKkeFwLLNEnKm0GLaQVqkhTxIkuTZq5JR4VhUdXsW5p1YRNJmqB1ci+9nCdtBgUA63pLf7RYTUkxVaOx14llyVRneHN/oh8EtDnnxHSNWOs4HgecF0P6eY06TdUplmtAhcM5aUBfPi44U5muifkcRW76arOtG6Bze1zPK9z4wtyu6M4ZuuA2X6+k6ZCV1niaV+whaytxXlnXtFV6zln6PgDiJ+iDwfdWWU9Wk+sMYhxa6fuA8xYXrXiY5ajNtxbCtTBdZ7DgsRyOI9+/fJBJazb0Y7+BDm3dKRVNuE3UmjdGqXVtfdsHA6UUQu9wRVP81B9nXaN4k5RKSgthGDefDwEzgzQOMQv4Z8xmhG2tfN9uEKZah6MaSHreJYhEpVdGwIhlmeV5rwqeOquG3tA5S3/XUZu0uTiYZypCN5/WTJ0r09TozgImxjVpYea4e7DMMyxT5XqOpFhkWKHPkUzrKyEIYG5dBSuMunmO3D8M2zr98d0EReTj6xJxwWPV10ZAHgtNBqONwk3HAkA/dnSd3/ce2+TJEtQAsjYXlZv3Y0/NAlJ//U3P+/er+mANpPwsnjRZ3kgGEsIErYBdJRV5GIKwn2Pmq7dHxiGwLhkfvEwPc2WZklyTsePuOFCjhBboEq9hF/I9x6HHG/F8lOfBklLkel05n0Ve670nnsUz7+ll4XAI/Mkv3uB0X1rmTDdK+mAzpnZWvq/vvIJlskc/fVyxRkJThr7TwkiHFBqiYazaBbhCrYllEWbb9bwyXTMfPiRiGTFkbBEPun7oVPaxX7L23ItHS2WeFnzoWLvMb56e+Ob+fmvsaq0knbLepnVZa/HGQjUKTMqL5xJFMpX1cxsDZE2sa/5UUiAHGzZ/LmmQZE9ogzh0mFWbR0/ZQdFaRYKCykM6TUBOKdH3HU2i8+owmVITWUfbrjpJfKtiil82FvouzwTofEdwAf9pwI+uNZ96iLQhobDvAp8dtSLxaSpN03PQWNzzKue7N/4VSCBvaZSd3MCsXY56+3VrrRvrt4EAEiSwm8o7KzEIKVaenxcBn4LDe6B6NenXxLRXH188GqlyT5f29/pDMgAQZqB1TpK9uk5SxqwOhRSQsVZCLZx1xFWGN97LKRL/Ps8lVoy32xoi4I365VmJjU85C2XZ2i82olXB2A2AURm71cFUUgpaY/8c744YCutyEX9JpZY1M33xgEw4u/vBAMQ1buE0S0x0wb/2fCuVOF/lvnCOXEV6ucRI72RAGYL4xN0qM9q1bwBrFzqcdRuoKkMMAeGbX29retuxprgx20Gu2xIjqYjfUAtyyBvrcb+nmhF+zs38+xOksQpjv6kHBHV39J2jD8pI+sTyo34KCAMaeP/6sEjQ9ueXVc9OkWTFCi50WNskxEbCCrwE5KQiwEK1+6bVGtKqC2PR/771tXIWSjFQqnjTtmWglWVG+2sjg9KqTBgZmtobsFq/jnU46ynFbAxxbx3FFA0d8q/Wru2zGMN0vRLXdVvTjZWQict14nqd2ollniVsoOt7bA6AYVnEN6oB0p95pBW1ydANsZaypf821mADv3pjN3nn7zs2+bO+nm2DDRq4v8sjU877fkAbItjtnqfWLXzldx1io+Pxfa9rhtU96fN77fcdSQExZ60oQtSrj5vv/Pd5PWOteLLpOQYtyY1YgWwgEMJyq1WGYXN8LTU2QFpW3l8+iO1JcMQlsY8xijDFTcEqc6nW3Xx+i2BG7tk5JkLwYnfig0p9dV0ohXWdiWkk5pXO9a/2w/aB2tqfsxBWnO6PzhqybQCc297XKHhssQoAvpYvNliiC4572/N8XVhi4u2bO3748R3v3n3P11+95Xh3wBxHHt+8EaAYw1oMz1NknS7UVKjV8tXbh90QTb/3GhO16j7j2j6iQNbfcS1tzQp+CyhGydua1F6jcgNwacyQ4fcDsG0NMgbxTf3SeyMKhGJkKNUwgpqKDJ1uWM6lJpytFPVH/yd//uf85n/99d/x7eT4gwbC7h48zx+jmKX3jhQNKYExMpHaNtAqlNZWDW8XrAq1NkaVqWhCZIlyoa0Vs3mr5vg5lY0V1ooJaM22wXlDyYYl1S0Vzznxeuo6S1qLgmZWJohFmAfBWw5jvyWwoA3orTGpsWKQa/UGbjeQt/DtVyP9YLmcIz98dyFfsxb8IqUqNbOmymVeZOPPmUPvWNfENz99yzzNwkjzzZQ/a+PRDNYraU7Mc1Sz2U+RXUOd1XupFNX4FwE7YiYlOX/rNbPMBW8z61rxvRPvmTW9Lqxr2xB2jxb1a8R5R2qsnypsiUbmjZ0wf4ahY40inzK2AUVVi6XIskZKTjhviUnkikV9wVrCUpv4lALLNfFiVg6HurFtvLe7+WL7wJ/sD8ZU9ahC5YeCXC8qg/ROik+RicrnyaVgq0z7vXf0ubBMMzllxsPAsiSO9yfWd89YLD4EhlHkHMtUiUsDOgRsauM96UGqskLE1DhFYVtgOnJaJeUtJZVhZTVwlAK872V6RYXpZUKKZ0nJKTXRBTGa7PvAuihYmCXMImvxHHphfdUubFP4dU68fHiRpn70XKfEOssz2x+8PndyYnP50uRuO9uvL4D63lrjCKHD9+IjKFIxASJacV9vuhmJwxYJaFXpRz90+OBYl5U1JfoSOISOEAJP74RaX0oVaXEn08HgLWtcyUXYdX3v6XsHRuSF1/NCtZmv3zxChfEQeH66kFMhxcR46hmOPSG0yYdM/5yyJXMuPD9dOPY9eU1UTWi0ndPzLJPd60Vkdpu5emqs0T3wQ4CuxoLdz6EMCoTFF4J4t7ngGA9h+863NVHWBLcuBAkGqCpPt4ZiHKa2psWQKnhjlUkonjYx91gK07qSk6SZeu80TTITvGUYRJZzuUbuHzqGwVCLYbkWlWsLQNHSyCpgfcW0JqBaei8MunlJjIPIRlzwvP/uA+ePhX7s6Y3F9Y6apXDt+7B59xQKtjpKzYSuIy6rSrgDXe+EFVe1MUYYKVGlxeILxGYWLEm1IsUNwdAPnnmO2BAwxW370OZrk+S5TUlCF8axE7lBXzgcej5+vLKohLtJv6tOfClF/IPGjrtjoOs803Vmui6UIlLun3z7yI/f/aj7mt38M24bRKtMzssUCd7hnGedCgP7XtWkukV91W6ZQxW5/4xrvm4if+97x7JE4rqKRJjK4RiU0WYIQa5hjJmPHy6cz4mXZ9nz5fNKgpV1TlN5G3AhkuNaJQCj69wGCrTi+kwh9IF1yqSq+56xFMM2LW8FcWwdqy5Fa1llmFUtvfVSvFfxdHJ2L9Qam8Y7L8wWhK29DdqqTDLzmveprmnuU/vRQFGrjWsIgVJXSklYq7J4dCBnkzLoZE2ttRJLwlSjqXI3NghG2DCVytiPAjp84kPVAJX66WaHNLrXa+XhtP8OoN47eauJMAbnO1wnaXdlWUir+MOJlM2JpKYNMPVebK9pzQ0MttVC7fMVKoVqspqxR9ZFwiAqVUyUvSbiYbb1yxll0ZvdgHxe9uRBeW/76nd2j5QKOLkgRbzfmt+SAPJeB6Hys8a2xFcZ4mVlyLbv1wUxIT70lslWrPcbKCD3lNxX1lryqgzYkiVE49OLUndQaHsNa6klcX1+zzqdxQvQObq+w1BJy1UHLq+vcUqyHziX1YNU251UWGOUhGy7N/htsGfqfu/UUhWQkUHmaeg1kMm9utdu77nGUGmn2jlHb/otqdF7h0/iR7jGdNO4No+7z0ozAZQ1cVb+t9iQEMsG6Lah1QaebBO0T08yCoYVqBnngwyug99UIa8PSbFrdWa7TvXmvwHWKp6GwVq17TB6D7QQsFanVqypOCveX7CHhgkLN+H9F8yqkQFbra2G3c+7fAwND7KvAbLbc1izQQyuFbTUmts5j20Aulp3OOuBnSUJFe8LPSL9qygI1K5HqxViZF0WlmXdUjiz+nkJUzRva20pWSxjdLiTy75mNbaWAB5aF5k99a/vvDD8U6YUYRO5T7638iK4BYb28/FlgCiXKtL9KkM6r/Yf6MouDPS0Eyv0c/rGaKv11Xs1tpb1nlC6bU21xm5gailZvuO66m99CSXfge18wwhrRvrtmqfluv3+7bP1+qVu7gH97K3euQ0fKLXgb3475cK8JFwtkEUymPU711JZp4Xg4Yd3L7z56sQyi4Q56zXyAfrgcD5sNYYwtRIpRw3C8Nt+EVPmfJkp1TJWS8BoTV00fG6/92NZ8VZ6nn1N0iWgyNVLKWGdx/sOjPaFKepzKL8jKiK77QU57YnGt+u+3POO0zgCEu5wfxp4+ui4Xie8dbx5vIf2/Ov9E9fI+9/+wMv7Dxy/+pqu9wzBwfXM8vQB7t5gnMPePTB0ZveU07VDCjL9frfrkH4DS8HW/GoZywj2oMsMplZcIyWZL624v/uoDUUz5pPban8NS8HYSlKVXCpV1xkZyJQq3FhhulVirvzm++9/l4vJZ8cfNBBmjEqHHIwHy7pCfJbJuywqQqvM6spWdLJhqt1Ah5wS3jiNnzWQq0iy5kzXe8LYSwrXump6mqSltfcHYYN1wYnEMKbNgwtks0c9pfohbJt9SmnztehCkGLH6UKkHhXrmrfkoqy0zhaTW6pILr2Hx7cdVPj4bpaENVPpBqu+NJ6YRNroOk/Ohcu0Umvg27cjv/j257x7+cjz+QmMeAEJy6SKAV1nFIgQRsbYO7oAc3HkKKCXNGoihaq6uMr5EcZeWnRKmx0lZ1wQmQaIH00/DMSYma4L6xp1qls377XjYcAZx3ydhearU7mc2RaYoOffWsNx7DgepSHIrQlCzovzQKy8TDN9Hwi952VaNgaOJASxUUxbQZGWwrUkri+RZVq5nqMYtNf95243Qud06S2y+HVDwNrCh48ryxzpOs8yR4ZxEL2zGkBvm5GCcusaNS1INr+Htweuz7IxVSSd7b47cT0vxFX+rOsDRqVxt8+Kcy1MoHC461mVpt0NnrgKC0QYGVY19JlqCs5D5y0hIGi7qbhOGEKkrCEQ8j7LErdUrmVJOvVdqUaM3Ic+KMtE2E2ptxxGYbS9ez8TV7lv+qPfJuDNFyrHpJGYNyv5/g3ZFk4DaEqMswLwBk1NXPK6b+aWDQx7vbBIepypbCEVKUYqSaekUtg9vW9pW1alY+pfFkSqLCCobtidI/SeFAXMjWum73tpQG1UunxbV+RaiCSq01RAAWZrtSLZUObDMmcgY3pEnq0FjA/Cwgy9F5m4+oI5L4xHjGeZMql4mbjkrKCbNHw5y46fcmWNGQ8M/S732yY5evpyM382DWSTtaEbOpn0eydAm64XzhtCMFuKY1aJR9db0mpZZlhmYTUKs9NjvaFg8XR0nazHMVY1mhfwaWtWUGmX0UkcRo18V6rxDFhNcpN/1iWTUqXWiAs9zJWnD1eWRSTjRQMqcimbZxYV4sacMuS4cv/NHS/PCzlWYkLlXDJRrSq3dgj4k1IhLpnrRUyZU5SpqMgJ6uYh1LzZWvJOMzOO6r93fpm3UJPpuhJCYBhEXpuUkVD0mawxYTsnCaA3gRrOwjAGfvzxPUvKWlRYTCnEmPHB8fj2KM1PKVwuC4dDz3DoZY8DyLIGdl0n7EZEVtnMkzfwpArDKYyeboS4RLy3OCPG+MbAdZ6pVdaMvvcSGuPFo+zj+4V3310xTsBlAcJ21ty6ZkDY1F3noDci89Yqzwev+28irQmvJvwuOOq0LwNir5C2gt4rILGtHzfLT/AdXlnSqRTWnAhWpIzOuF1CUc1G3/fOCwBm9vu15MKmdgKahORTzVtVXFeYVUZBy4TzPdYbqkwEqZVN/iO+lPtwzTlH0TXSKZBeSqZTkL/VKq+m+nUHwW6HYWL4X6XWuPWiar9/u85udBRZRNpEfptSayOLc7IGarO6JS82QI5CTMvWbJWmm0eGeM5K0SxR7mb7LAYp4l3Yn6f2f+K/aDZp3+t9XYGsBvDdRHaWkskpEWOixFU8s+KeCCqTbaklNk85I2zp27rBWsPhICDk9Tzx/Q8fOM+LyoH2GHp9JWWl1a2ZsM5yGA98+/VX/OSbb6GWLcl2k21ZQ1wjaZ2hJLwVyXRnK6fTkfX6tHkCtSOlIoPQUuk1pMO0Z05Zxs5aZboogFDFF8lZJ89Qlmtkb1iL27W9aby/eFS593K9kXBtEHFV0ECHM3JFZFDsmy3Ajf3JF3s0A85Q16ySZLluRdk41hhlPFV+F+Ahb1CoeSGuhRRXGUazA7rQWI2fv337ntXI4KmxkMUyzykAajRRU3zZcpFz2Qcnw2dTqFVkmjkLa8W0dcLcvtEO5FZTt96llrqFDe3Am31lCfPZV857ImfoNA3SipRPzrnUky1hrtXMuQiAKhI/MKNlaO+pz7vznmVZWGPkfL0yKxgmKp6qe4nhcBgI3hN89+r5lKGfEZZKrQpGWbxvwzy5L0otrHEhxj2ltt2PxiBrdr2xImmf8ZP7dq+Dblj6eraFxGBu7v291ffOSbKm99uwsJ2rrKzWXHUd0RAB54MOKyNpXcgpsawLREPOkWWa1FNaPD83hqv+P2OEGd5kZVAJodsYfXI738pv0cF02j2dt0fBkEpijbLvDoOw7VO+Tf2FUjNjP+CdsDCdFfaeIbBeLgTE+y4j1+10P1JS5NufnLieJ3zXqb2MmPVba7BBlDIb0O+0JqiVUvP2Z40pWUtlvs6si3gLhy5s7KJSCuuycjwdxSu7RMINGLaRwHVtSCnjfBH/Xn3OvfOkzePNQMnU6vf7xUmiL0YBTt2nS91l28chYMrK/WkAA7Mm+4Yu8PF8wTnH2AUBMGOEdeXy9MT7H9/x4bvfcnc6cjIFf34ip7/l/o9+zmALnT9qTWEwBK1JbvrE20u6/dnrP2k/rS0rqYX9oLWM0CBlt7Tyc7e1wu88akEjPBVsLORlwY+jYmSVYxdIKXFZ07a2CdlIBrKiKKt0TqSi9tN19nccf+BAmLKr9Mt2neVw9IqsgkgTDKYoG2itLNNCP3SbaaG34iMCddskGztIrr+BLM1UydIAGW4mA0bYFDJ5kbSEVY3+pPiS4qSxnkLwhBC24gT0xirNAwY1SkbTylqimYBTuVhKthgsYXBUW6nFkNZMPzi6zmLWSug9x7uevg9Mc8JguFwWpnlV0+zKtET+n1/9iuOhZwwDMa2UqulsruKCNJo5iaQtpsrLJbFEvWdrW6zZ2CFtqiuH/Dvd+Eh6b7FeFkJrK8e7k6SKTCs5tWlP1WmiIL1LWlnqshXynx4+WPWOqWDFJFd8RqCumbVkgrWkHOl7L/pya8lJPGlyzvgu0Pee6bIIawYFqLUQF4PTBMUwX6UJr7qx3jYK7ZANWMAn750YZetkMcZCjAveevoBcpTmp++E2mu0WLbOqmeDpVqpzNYlMR4OfPh4liIAmKYZyTIRCmtMiYom1yk634yunZPv8/zuivHSaNcStoV9Yz6Y5oFnlXmAUMcdxF58oaypGJ3kTUtURpSjnGemKbLGpCmHDudVoqgOraZK5HHvPbOF776fiItssiEE/uQf/hzr4eX5wvPTxKwsMzm55fMBl04m+mHQDS1rMyhVbQiWnB2+E0++WmTC0XxXbguXUuo+wbHinSOBA1oQbH5Ae3FA1ZRAZyT5kUpDSxpjMPROmWVF5HZV/UdmYaZ0CjTFWFguC5fLwuk0cPcw4FyQxMO8g6XC3CvkpTIvM6djj/NOIt6zMAqbN2J7LluhVvJCXCCXlXUVc9++c5+dV7k/Cigt2WqzIzJww7zs9P12GWotwoio4jvXDSLZWGZhTnW9pG2GzmiaotkmUpt3Yu/pOrm3cmtArNEkMmFPrrGyLJk1FlywCsSLZDiq3LcigI417RmVvcAHT7Be2R9acGYwpiclkSvXalimxLJI+qIkIUlzV/LukwQCHnad4/w8a6poIRdpWnyw23vUKqa41+tKShnvDmACznp8gDEYfMkEY8VPC5HsUK0a4u5rmzHi6RY6T1lXplkKO1BpvzZNjaySY8ZUkW5b/BZ6cDyJFN4Hj/fCGJ7nxHAQI9jxKHKLKnA80xTxwbMmScPzQZgtlUo/9DJQQICYnLOslzFJiEwWduLh7oADwhAYOoczRkBBJ2zHofO6Ju+ssY21WCv3b4+8PEVi1P1XWcrS6BRSlKCBXCBlw7ICNmH8ilukSYqrMMGP/kDfNeC9pXPexM0royCqn1YDxISN1WutoX5fKjlssjmj/nC17AAt6AAHDTOoN2uRMiiFLVK1KLwVAsohvlVlYxB458EZvLrPlmrluW0LIztAZJQ9oMvSFlAx9L14hPrwCqhoQFP7Ru3PjXktQatV9+JPWRRW9g2nDXwu4o8k/pluawhlYm7ZwSaZkLeExloy8Ubq00C+rF6HSeVrnXNYL4z9lkzYdWFjYYImglqVhJrd3wfk3KTmgaZszHpzTds696qG0/tjnRdcjptvkfxlJis7UewF5Atn8gaKbucQcD4wx8T//O2PuGHkf//zf8wf/8mfcP/wQLhp+Np1uP3ftVa+//57/j//6T/xq7/9W8a+4zSOsmbo8KKkyHJ9Zr6+QK2cxoFxHPBdYJnOrPOiSbdWgXhNkDTyrAcvAxejdW+t0Hfhpt6QtSDXjDM6sVfJ+xa2cAPOdK7TQWb57N65ZWNV6g2bSDDPlKQOdS4wDJ2uAXA+n7frZ40BowE2X2Ro3Zz7FqJEY4IpqKGDSDbg6PdLzhoIKu/ffLJU6vyFenG/oNAS6MahB1tA/f+cgsTGiNRpRa5n53cmnlzjjLBhd9Dp9bd8DYaVKrVtXOMWwrA9/+zX9EuMsvYdjQkU3U8bo7L9jjWWLvQ448glKYNJ378KS+elTCLTrpW704mgn3RdV3JKZA2PER/UtMvSkcGS0We4+e/edt3tnLXzLsFk7tX6XktlzfGL1yXrXiGln7kBRRqD1etgKyuriE0u1wZzRZ+9bVZrrbLDPNaFDVDbh+8iU8xbwEfZ9oaQMmvMezibfo6MEQ/luGzDgu37YVX2qNYxNyB/k+qWkvG+IOm8+wCgVPHga691C2zd3lelyvfxem4/82TT35/mCRdXFG/GGqd7kQyOAhaM7A3OB0wX6PpEKeC7kVIyJVV8OND3nVisYLf6tlboGVm5GVZUlZRvNbuGQ8wLxhrG4yi+yqXw/PQMBt68fUOthZJXnA1Ao0Dp3pOhUrAp4XMWFqQRxvcaV5yFzgfxL4wrxvSw3XtpB370Lt2PgiFzGHsOh4EueJ7PF2qtvJwvHEdJW52Cx+REvFwoCoSWnClRQkK6b78hzVdsLQRbuRslHbzWjHEd53nCGsOh77dP8HdhVe27V2DNTRqp6LCy79vA6PZoa9Pf49W3AVktGeM9Lmj6qi7dnXc8vUzEstIPA4P2fJ3+XM6JWizH3nB6883f503/sIGwHMs2Wc+p0g+O8QjzlIlr3or0VijL+qu6fY16PZ1Gke3FKBORBnBkYQZRIObEPK0kTfUw7FB+1WI0V2FOSFqkThTMnh4GuoivkpSiLHxKFn8r5zTB7qbIK2oeKxMTBSeyYQWcDYyDI8UqbIaYmS6RsfOcjj3GwtA77h8HTrny/DIzjEdSFB+taZJUj/N0YV6n7YFtSZg1WWoE6yUSNUbZQDewcJNV1a0Yvv3v26M9AMYIq0SGd4muCxqbrlRXELmMouTIWZNkioLKiD5ZWBEqr/cO5+0mXRQ5hizucY3MS+F4ECmGSGOkcL5Oi5rnG6JSpUsVaWtqeMfNP7UAeS+MPzMABrjZdI0zW/y2FOutsJOjyWGtVYPgm8lbmyA47zDJQDVM00J0WSdwheCFzSXTaGEh5WIUCLEq2dVmxBRykvO4ZEkLQ4tXq/HdJYPtLH3vFaCQjTKnjKWjVAlASAmMrRz6jnlJrEviJc2kNXO5rOIz5a02aZahd+JJVCW1Z17lNeOSKFUSDeMiN4s0+wVrK95JQzsceo7HXlNbly8vCCrhE8ZZJXuPsQrk1KzBFFn9caSpasDqJj0wKpHRBrOi7JXOqcfL5wt61MS7vu82ELGZg2/3fmuyjUyRQhCDzutVEw6NpWbx5kq5EHrPPEXevzszzxPHOzEx914ai83g38l69vHDGWMqx8NAXjJzrlLUWovvOlJaWZdlYwflUrherTI4LHd3TVK1b8itdy83xU/KasAf3CYrEb9EQ0pVvWKiMORMoes79fbaPRhdcJIK2YNs+jfeREbWl17BskplXiKXy8r1JdENnpQznU6trRO2m6iA5ZmLykKqRcFc0+BInaYGTxc856eFb3/ayXeyEh1uraOqOb0x6FS97Cw7pNB7ejp/dvvlXJjnpCwsnZBZufYNVHZO2HCGyvm8cH5ZeHwcCKOj5sLYebyxTDGSq8HbIGtH8+hppv2WDVSu6km1LOLp0xIeDUYlYI0hI9VIzTeJyE7WmBAc83XlcArExfFylrjzx6/uSTExXWfxj1si65rlGVsW1iWwrkXkeTkyHEd5JhYZ4qxLUhmDsG1SLLjgSVGaj16DOKYp8vbtyDyvsk6uZWNptz3Je8e6iLw7dIHHrwY+vH8WQDjLc2c86EhEnz31eHOGajTBNM3UPDNPFutRGZPK55XNkDc2zw4EbY0DEHzY9qg2M00lY3IWGwYgFhXkWWjeILVoKEnNmzfNbc3onRfQYPuzLzef7U/ba5i2bm0/YKk1b0CAqnMwKiEy7Ptde0VrjCQC3jRj7UjKikOBPbcBrdqI6UL3cBq383Z7yCRcPAJJ7edf/4y3co/GNVJzkkaIxsyo5MSrvdYoMCCStLqlSoIME7OaNAckVdo2dl01gMiImgcjyN7hVOJfy+tAIOQ3FOjfh6btqNSNOehw+pxKq1eyTg63zy3AZZM3VrcP+CRcovCbd0/87Bf/gD/7x/8bP/nJTzidTsq0fM0WeSUd1D+7u7vjJz/5Cf/v//v/5r/91V+RU+R4OGqtZck5Ml9fJGmtZA7jUXwf1TF5mhYqbpMQL/NMSZngnfqs2h3wqtr026qWHXrv57jJfUHuU+ssWCv3d9nPxdB1kqC4rvSD2Dy8ktU2VodegZ1ZqtdF2UO0YRYG78MGStzeL186Wr3oqsV8KXCiAvrnBjGF/13H5pnTQEdlJRsFzlvokZy3GwnmTd28eZmVyth19H3AUIRlUjNZ2RZWJZPO7s/r1nBWCeUIwesa8clX0to1172WbPeR0fXWYIQZ15geX/q+Ctph5LkVMPR1MmKpWYBhkzcw81YyVxGljTCfDBhRCATvMezDuwaUixxqV55shxF7AuMcaV13EERPShv0cnOujL5/Ayg/PRqgk3JS2ab9wj3VvDB3/7FSI4L5tpMgpAtJjd8TyK3zuBsWWzuaVLF9R+88tmtJeXYD3nJed2BV96b66ryYDRDd1qft+W0yzP3773sdN39vvgj8SuK8eTUgAFnrG8ssF6nvCyI57ryAFfM8S+quMroMmrCo58GZXUApa4583mWNLOuKU+lx1+1DG1ulfiulko1lcJ4UF1IUlrlR8H37sJXtfr+ViDrneHl6wTnHw/2dGL6XCJ+AYdBYYcKEG7ZQCPEPd+yBALfyXOetsL+y1qWV7fOJ6HBft+6PI2/u7jEVlphkYJgS87KQcyLNC0wL1UqCt6mVzlkO3lDff8/h0HN6+JqHb7/GdGGHwX0gVDBfADU/lUd+9vf63Hy+nop/tNEJW7tdat3/++86NnAU8U03yiLd3syI3+zYd7BEbK04ZO/BGoKXUJ+SPRXD9fz/B6mRVGmw1ijN2duvR2HwsEDdEexapQBfJmEbuVoISVK7nAukGFkWkXE4azEqCyq5sCwrcRUD8BzlErVnqaVQpJhYFgHjKtLIi0wK9YNRn624staiciBZ0JZVZGNOzROLbmJZGWay2OliaIVFsiyZwVtil6kuSxpa5wiPAupZZ9Q4XeQBzkEXPGSZ2K9rZOwDl8vCxw9nvLecDiOHUSZqLy8LHz5c6fvAcOhwQZgnlykS077otZTBm8Ho7z28aQwpqNUSvONynrbN0akpfo5ta5JzHJdmgvr50ylMBvknLplJQYK2cJdSSSWzroKwey+snK7zlCJFX9sUnLGkKiBpe08BJGVyfBsdT2OYbB/JbEW1gF/SXA2DI3TS/B6HgR9/PEsDj8UgYMIwdoynQYqIZo5bZCrZ9PaFIil8SWRzbf1KqZBjbjYMGNem9BljKsU5Oifnx8wQndmYVTlXLJoU2FYrJ23dMHhJgVyTmN3PlaEPbKwaK554rUmdppU1ZpY5EpVRl0sl14JTphjOahCCPI/PHycBFyxQjUg6rbBOrucrdw89fecIPnE46KTSGgHCqkgMKxWnfgTWWvp+YFUacQOfAJFcOZHQLgtazAqoJwtnUT8Mo4WGhFt03jL0XpJejd3ZSa3TNqjXhII8fjf73TZf9dloQOq6ZvWbAmqhpCxG47USgjJUszSpMWZiFPbisqwY22+soPbduqHj8fFOpqtRjftzxmY2AFfAXQEnGqU7VzW11Ybl09a01orzlsF2+6Re16ZkGwi+F1e+0+elyCTOmIp3DaDS/+2NyobL3rxg1KBfwF5rJcH1eOpYY2ZeEzlXrtfIdYo4bxjHzDB0UlB2llKLGDtXYYlsIQMK/In8S577oZdEwstllfsXMV/33ogMstSdCaKlbJvKUiEmYUvoSHBrwHJKdJ2j7yTG3Dqn94P4anXBcjh04h+XhcliqcLyHHo6F8hkbBCz76zNTPPuiTGzKgNGOSzyXbPIkrogEs/2fO8NM1sB5ryDWtRfQSWntgVGSEPuvKQUG1s3hoB1BpNAEqksfvX0Q2VdE95Xqi/40PHxwwunu4F1TaxLZFllKEWV9E1w2Oo2Pzepb4XZer2uPL4ZOZ9Xnp+eyRdD13lOdwF/1wmI4x39IJL2kg0hwFqirAUVXafluapFpoo5V70eEqjjvAXXMX1/ZjwFabbWzN98/wP34wjGkBHgrjWWVYdftlRMrgSnDYY+NaWl7RZtUo14ZdQms9YG3lT5J6vEsEny2uHc7l3YnkbJ7jWaftb2UKkFNlaSsZpcp4bt1lE1oWoDXJQN0CRlEvsu79UM2WNOpCKs3MaKlYFAM+kvmCI+ixvjVIcdwnD8NCdqH/Q0nyfnqmiMqrB2S1zovdUBodEhZGFehFXVhW4bFLVGwzRpHpmoa6UzZpOBNkjQWQG8vPUEP2ABaz1SPt+cebM3ffuAT4ME2o80EEpBhFvWhDC9lLlDB1WkztZmWvpoW2DbgKUduWYKRUFIy2VJfPXVG/63f/pP+eabb4kx8vT0xPF45HA4bN5By7Lw/v17+r7n8fERgGmaeH5+5nQ68X/+q3/F5Xrlh9/8mnVdBagqmbhcWZaZmIru3wICj+NIKeWmJgoYK8m+mD2sYFtXa1Wmi9Q+YUv3zJsEsiWcitzKKai/F4x7iqWcm1tAD9isQbZrfgNcGtNAbGXJVR0oGVlzL5fzVjvf/s5tU2ZMu/clvc6stzIhCbCS5NEs/7TBlvlcYtmawy81iFijbAyx6PBBmCPW6rOVRDqKAkC1VpZ1lZrCOjAyACgNPMdskvRbEKV9pqJonbP2s6a2scByUVBNwVSvYVLNJuS2ILhdo26fE+c83ocNPJE6Un+umk12ueRlA9QaG+eWaXpbr7mrAE5dyKq2yVtisrVWADIFZ3IjCSAyWN/3OBfkdzQ8oRZJLZVnsK14+v8Nr77np1LHWiU0xDQY/AYTlHXNbQCnJIzLgF084/bX5QYMsEaZ4t7RpO87uN7u+9c3l3OOYRi2+1/YZ/EVK/XzCk7/VOV+UT2wmjz6lcz/xthcGP1VlRXCyhUZ9m55A2wy3VwKqdwMZ9F6SZ/zdn1l7ZOarw1oxOstyX3UyRCytj1cv4tBwI9lTaxRakFrwSCAk/cC2Mc1CRDtpM4oxuBqaMgw3uqzVIV4AejaZDdmXUppk/ZfzhcejkdwsjcJGOYAf4uibr+XfNpAfIvZgC+p0zLoazurz2XZUOvtuWnpmbfX/fHhkcvlql7lZQNJnXUY55nVZ60bBkZruT8OfP144v400PUBFwKu70i3i1NOBKNNzidHeyQ+u4/Yh+NNEfcKFG4/ZfZBgOHLINgtONY+VmupZLuRgaEzhVQj1AaMyj5z6JX9a0Sy7qqoE4xzUD3VHTHrhenvSExtxx80EGawqumuLGqgLuwR0X+vKlNMsbDMUfx0jJgCi9wJJHFCmFrrEreJknWWZYnM80rOwroqxbIFKFUBEKxFUgaVXeKDxwevTVSLWW4bvFD1UylaOCpQk5qUUrrllIoCEJmkNGBjDNmKxMNpLnND84eDxvB6T86VuAogIQyjjAuG473DVNl8SxyEsVK0uUYaoTUV1iVxuc6sa6Rfg6YrVpx3kuY3J9k9Xj0/vw/uNbqQ7dMTmcCJWXXSSVApVannauZXpQDNKbOoVLKBhe3NvdL9vZfmwXeOQmVNebs2rYDrO7dJury3LKukIpraSSIOaCSuerLlljgl79emd82NssndDIZ6IwkAAWtcsPSD53TqOJ06xkPAGsPd3cg8JRzNn0RYbMe7URgbpoGLAoRGNRGWe0LSrMTQ3OqmbvTzG2lcvdmYFM4KG00KRkNVPybXCY3YOUPfO7pBTOnXOW7TpJIracnMc2SaF0KwDEMv0oEi17DzfpPqma2ZhtBJgRd6DZQwhqoRuO0eqKUyHnuGIVBN4fKU5Xkxbe4uPxeC4XDwuCDPypaW6bUwrmYrxL33GzDRlnPZhDVCnERFzsse9Q1dsCxLwXrE001ZPO1VnDF460CljFmnf9YJ0yKuiRZdDob1GsFCWuU+FLNyjaFPZU8kE7UIaVkxixYod9APDof4B8VVGK0Cpsi9IQwspwW8gZo5HkcoshGsKYI1ZPWQMtWo31xSUFfWIeckLMJqY/Z6KilSNEnL1JS5LL6F12klZGVylghRJjcCtBjykjWJVE2BlZHnrQDIpn13I+bOuVRKjsKOXb08l86SNGHVOwHPrBOvjjg3CWTleBgJwbMsUVl4WSZE1ikAabbEti44MZfvPCkX7h965jmKbLkKW2yNV0Jt8e1sk7wWid12+daY7VnyUiOFTpgv/SAFWopyzowRMCkEK75aOp2dLldiLEyXVaaoRZixKcn1ojP0KjdoRaz3CiIpGFrrtiKJBLIVK3Z3d2jfRWp8HbqUPRUrxUjojMrMZcJvLMQk/iy5CsPTKXja9U4aaWPoB8PlHNXLL/J8noSRrQXm4dBTMUzXlTUJk7u6Qi2ZoXfMaQGfuC6FrpPE1dB55peZkoXpXapIYkoRKWcpmWJhOARlfAtjb1mzgO5VmaVBAiy8eoB0IXDoA9MSlXFrxUdwMJzPV079QKpF2FylaGHb1hQBpVxRFuKNSTTszUsDm4xxapa/F81f6FM2kEyuU1X2rgZQVkHPc0mbPMUa8SxpLbuxFqtmwSVKsV4VFJCBhZf7Qw3cdwbXLWCvIFKsGzjSwmM238y6szCcs9iyS5IaqN181UT6uftwNS80hfS2Qlo898rGHr5lNyUFVXKRFMXt77ThFiAmS+qa+hFZI6BkpeCcF/8X9Q/xzmMKGKMNqNHnvjX2r9p9tnP1Suql11nCBQwNZTAGOm+w1UASEKzq+uWM+N7cMv1qqST2Ya3RJj9Vg+tH/uiP/4THxzf87d/+Lb/+9a+5Xq+8ffuWP/3TP+VnP/sZOWf+6q/+iv/wH/4Df/7nf84//+f/nHfv3vGf//N/xlrLX/zFX/Dtt9/yZ3/2Z7w8PVE1fMQgTfS0RNaUGHup8Q6nE6f7B87nKyklDuOBWk3r0wiawNsA808ZcS1dvcGGr/zlqDgXwFhSlHvw1itJfr8BQwqENXCkgYYNJKuSnCvnS2SaXRB2sFwTC1aYa60u3J6TV4DRLvRNahtQy42HB6jMScDegnqUlQZg65Kwizh+BwjG9oyUkqkaniM+mTefs1ZN+VW6LwImrDFTy0pFDNWtNRpK0IzWy2fvKeoXs7+3aX++X7cm396+qzb7t8nlLeSgXY/2520tldduLKXd21h/YVvzjIICueYNBNuZU7t3m0ESHr0Vf+eUg5rVq8+kkZrfwAaiuKqm2aFjGAZ8Y1dpzZOUoVtrgZLErwmzDWmrgpTUW3Z0kPdXlVBu+/0nJ3oH+N0Giucsq39RcBsas036VWcFAGt7t/i3Cof4NpTF3Rjltz+7ZUmmFDeJ8C2rFyrWB0pO243Z7p22n90eO1Pp8+ejgWxbb6PnevupDcBuoxU5cimvADqDBjmZFuCTX30XiwxpAKptVffrI8bCNCdV1IhXV1Ypdd8F1jWyVkmODZ0XhUKEagy+C9v92dbyuEZRuSj5wnm3WR6sccUXTyqwLivdYWhnRSQ8grbR9vWiQGvzrLIIKzKTdEB/K0E1YGQwYHPePMzQM7jLVRUQzYU3Dw+8f/eel/MLVa+fs4axk6C02DsufSDdH/E5M9jK/ann9Hgvz76m9LajAKYUbKtNbo4vgWDGyFdOZVMnbszX33X8vr+DNlzcT2v77/b6tbZACTAUMJmqMbrWoiFNbhvuW2vx6vubjcXYoK/z+7CJ/fjDBsKqofOBl+tELvD+w5WHx1EkYb0lZUOaCsss0sGc0uYHtjESyGIIvSaWRTYi54TtAntzX7KBlsaiKCSwTQjF/NRoNKt4gCVN3pnnFQysunCllLcHspkVL7N40uSskjFlg9H09FoIiC+NYY2JVIVlEDpJphyPHpHPiVHrNCVwhfvjIIwTG+jCgCmGZVm5M50Y6xZEXpkF+JjnpObdmZJXYhaj4HnOrIsk1DT/hNL0o6BF4aebhUpEjdYo1rAuGUxhXSX1pWRZYEOniVAaM44uCDkXbDXYGwaSxYjPW5XYbayAlzFlspq6yoRGmGeC/JstHrilUwXvtkKkaIPTwLB27fUSb6CYNLUqdak77iIStwb9ycYVguN06hgGz7JkbcY8NTdjRy2IOpEcxLgbWC5zZFUpUlpFJrsxiVAdQ2lTQWHU9J3jcAw4b4hrUYmXyGa8R+8VZS3VQtc7Ht+OOGt5/8N5M20XEK5qAqQUSDFGjE5DZHMT75cuOErthK1oDClKgWGd2RqcUipVtesg5/Lh8QBIAVhrlutddI+hQJUkvcPoqKawqB+V9ZbQizSpRvU+swKgLfOyMXcssmDLhu2wxmOR57tuPlfCmGxgE6VQjN0MHlMUID2EfVG1tNczxFUT4zpZoE0Vtl+OWbzmFCCPawMLte5qRVCpm8RQPG2kQes7SdFLURg1tarxetk3yW0yCypxtYx9J6mLa9rWG0MLSWjVqRSwzsKcE8WJh5f38vzYVowUQ9eLTCgruJyisCSGo7DFQBqQTjd7Y4X9FDpN7VUZiDUiEWsFVgWWa1VJeKVYCxauVZJMXdSEXr0OITjGYyAnq4CIACNtnVgnLWyMkWc6eKwCstYUgoNxCBxPA9ZbrpeZECzLnMWDygjTSXzF9qlsK2B2T5L2d5o4tXmNNODBMoyBvg/44LmWhVKSnhc0NMFhs8GounJdkpzXqkbd6pOVszTpMnU2slsbYWa1BidoUd08Kb03rHPGOEuzwzFG1rW4qneYTkx3SYgW9cqYBLOtu9M0M00rOZXN6/D+cWSZI8ZJYV9LppCIc+J6iVzPq4QLaMJoPxzohw7rLfHDRIyVoKbXpXmgma3qIaXCOHquV7uthU3mZIywbJelYiny+n0gJ2mCfRAJqkGAPN85jsfAMMhEIKXKPMu+EzpJc75cJpm2pspf/68fGQ+OrDLtvg8CzqlfkgrYN8ZLWy9bXdCaj1wFgDZV/Omoe0Ms65+0082ovT3TuWRskDXTajNjWgNeW6KdAgMYqtLOnfcSUhElEbluBukOYz1m8zzKCmztU2irLBCRBFZZm3Il1bSlKFcFrIRhsw9+rDWkXKkZUtWUtlQpaRYDaFNFrm4aaKvAk4IBBijBb0CQ0f3fOUeNshdHEzfJilc2iPgrasNVm0+j1CDCREhqLm51b7BQZXAorARhDFDK5pv2qtE1u/1Dq78aY0Wk5VWaGqzWBmLFUa0RILqq5w5izF0r1JbE2EDVWyBCJbkxw93DIz/5yU+5Xq/88MMPm/zscrnw448/cjgcSCnxq1/9ir/+67/mpz/9KZfLhb/8y7/k5eWFX/ziF3SdAAJ//Md/zC//639lemleOU3KkynVkgpMa+Kx7wEZtLhtqIOC/markVqd9Gl/0cCVltrZUlG3a26dnqeyN9TaHLe97HeZ5X/aoAObb6B3bms05ecqAiErK6ckoDRsaX8dFNQ1ZmMnyUvvyZvySMvwMBhLzNKw62WnBRGXbZ39HQ2gUYVCKRuTcE/XlWfXO0ftKsssa6c0m/JisckpqXgfhNFYG+Qo37NZCghYfQuMoKBjA54VbEdqkPwJyALsLMi6e6HtxvENYNslgnJNjPpi5Vev1dY2KTdl729A2Kd4R1OGrFECjXJOKiHe74O2RlhrpRbCYJyYpfe9eCeVnCXkJAqQXq3em8oIK3VnNLbPYIyR4aMW85Lw6yhlvRmI7GxFGUTt65HcYBVjmr2KUUlvZQeSpAd6bYYv/ssN1ARwRsDX1sjLvZpJaZU6MOfNr3JjQta997DOy7XLTRLAxshtvy/7e9rvEes+ewY3EFQBp+YdBg3supWCgq27/HIPIWgMRnm9lCM5G0343CdDOUvf07mRqkzSdsQUWVapk9uyk3NVokimhBu1g7K4pUesrBlJjff7QKbdk7LXWLWt8Ns/KUXyuoCrLPPMYew365TbZe9mVdJhaSL4JocUP9+izPT2/aVO26/H/j3bc+WpVdcsKl03cHfXcToeuVzOxGUmrosOfAtDHzj0d/R94PpyYX2+YGpmiZXDGjlfLsJW7DsSUJ3ldPewBxy9ev7avzcEW+7HRmLZeuAvHH8/vEnPwxd+db8Vtj9TEqjct0ZBf2R9a2tnqVlTOAH1qTSmQpr4/+X4gwbCgg2MvePlPLPGzHe/PhPXQt859Q2Tgi+mTI7CpOgHMWH2Xs13szxgMiXUhjOj5rY3V0clRBsQY1vzrM2Ks7gQ8J0UpBW2lJLrddmAAVTjXbVYaomMa8lbil9rTJxT81lvN6ldKXa7k0pVVouRTcQamcBWCjE6cs3qSyMTkrYbVlskVACHsRVwpAjPT3Ie46IJbLmwmqjmtuITljMU1NOiIddbdd+uzO0Op9NfbQJqEaNPMf7X5lwlgS1WHNhMutvUynpD1+3+PgZhL9QsSTU++A2RWs0e9dqozl693VLMRKTZbxIqHyTFL8UkXgUZhL20G5C29aoVXTugsC/ybFMz+Ufr8q25iykLUHXouZ6TFoo6PdX7QVhf4rm1zFE/l0Tcp1S42R9Ai3soOCdyxmHw9KOwdVIqmAKbcXYXWPwu7WsSu673jKNIZXOU6VDRKalB4tydE08C773Kmqp6zEjstPWWPljW1bPMaTMSN+3GqPLZUyrq5SYeJMsSMdpQltpSB+W94pqVQm7wFpYi4EvoA93QSQpfLRQNoqAIY6g19eJHpc+dkelxzis+WJzxWCuTpq4Xo3VrHX5wAszo/Z2zJhOmussydFcoWRbmoPKxFBM5ZsaxBz2/wYscJOfMOiHToAbOVQEotpds98kqIH0/OEIQE3YBy+RZS7HgXd4a2d2jTCZh4hEFwXhlZVmyExZe0UIoZwsJlQ0o60HZU9tYSEHsrB9OZOASdZ81UKRN7Fv9ZJWFczgaqFKwyHpmBSDVP7MO5mmV5rEqQOvV8B5Zt0qOyGojrz8MAWM6TeYVsMcYAZLmy0pa805N97JeNgPnzhsOx4Hj3UhMSeTuUxJGsBOZSRcc46GjtOTrRvffpuSfNoA3LDpTwVpcUCCsC2xgeK+JX94QFMyvBaoWpPO0UNXsdTgEiRAvZdtrajWk2NZZTRYyWmBrwz0ePFTPOs3EuFJXjbD3VsDdnHHiXy/hFbZSa4e1hVwsw+hZ5gWLxQYwiwCcT08z65IxQNdXTnc9h2NH11tyESPo62USA+NUhZ1akXTEqD6byLM4DI5+sNgm2y6VaUnU6sSgve4ysvEQuE8jS0xgUcafMESNM+r9J9/FdhawpFTodeWVpk/2hmHw9L0lZ7n3r3Om1oQL4F1hjYaXj1cA3v924uFhxBaDt5bjsefx/oQfOhlwaGFfdAiUtdlw+gDkknHGkmuBIpIe7wUIUiK3rnMWQ93AwA0Uac8e4GraG17bmpUm5ZBmTSwrpQuv5Qa02jyplA3R2pHKBoQJC1vTERXcSmizagzbrFobaSlONX0TowbelRXx10sZ5mni+eUJWwuHvmMsHQM9XQ37s2n34A08dKaTemsrtSyhC4QUBHC0u8dKLZWqidKyrRQBBEsDAtoz2qQ6ekqVFYwCh+0L7YyLtlntr9M+SwvJMNtuVrf3A7PtI24DirL+VAsDkPuz1p3NsoM22rwaTSbEMB5P3N3f8+OPPwLwzTff4Jzj3bt3TNPE999/zzzP5Jx5fHxkGAaenp741a9+RQiB77//noeHB8Zx5O7ujq7rmK3ZpJEtha9gWFOl74SBknVo0zfzZD0f7TNjWu1TqLd+rcbcrIt63kxjvAgDyJQb37sb8AFjSAWVC8uwzOi5biDDLsuX320AWkslTDcNucLJ0kyWTM1iidBAjCYRRiXMrYbdGmNkkNVeSeT9sman26/Q7iujg602C75pGVoVvPkrtX/YX6QAMct6YNvdoK9NMx1XcKELgeC9sE1qweC2e7A1zvIWrxEmY+R6OA9G1RdF5ow3YMsn3amCFPt53YXEzeOsgVLtWf4MTGZ/vtjAMPmojWEmss8dnKlUYo7URcJoeh82Vl5bhwQ0FiCyGod1QQfaQWWAC3Fdt7W5rYkGkarTmGCfHG0NLyWT2P2y2r3aAid2v7IbwJgGkGmAiT7rFfEFfuWr1xAF0xiweg1VDbGd1zYgUlBrXfZQFWpR5pHWorVotool74/l1ksGVSklNd8XKSebkkHWys9Zb/K9itSFqmJpbEJRQe3nUe7zCOzPbClZBURyr8sJRPwbK1swTAOIRaa9p3nK+TKtpdoeQPkumXWJBOc2Kwbpqd3WtDmr/qxhhzqKNHg0Swaj/bttQUQZcpFiaZqu3N8dsSFQaYMns11bo+oo2V8EaDVW5I9ZQdkNUNRBQSlCJJC9oe39Zrte1vptD+n7Hmszx+MB5xzzPPHy9MTgHAcLvTMMfYfzwmCbs6wXy48vzOeJl5dnXMnY04FsoYae8fBA6G5hPDnH7R9ZYwVcf30ffHZrfHKj/B1/f/M6v+tHjWHLIksVvDSECtzLm+glUFa5PF+RjHUOb6T3pay8St/+O44/aCDMGY81K30QE+zLFKlZkMBay8bSqOr14L0TGdrREzqjqLJ6yHhH1wWylea0ZuUBbjfG7svjvBXJGVXMzgWJEoql3WmIVmOjY5QH/XAIdH0nVG7MJnWLq0TzLnPS4tRoapqAdtbLw2y9pWZprA/HXtltYG4kmJIsAsf7jsNJJBEFQy2i816vC7UU3n79AHYRs0z1Dnt5WtR4XxtWU24eEJ1KldbIyePz+4/X+HmtsC5Ro3EBY3Cd36ah1rutwG0TMKtNVN8HxlEkS13w7bJAlYmzUyQ+WqOvLe8pRZPSw0vzWBCPKPHGkoZtnhLrrIbzBYT9t2/0rbhu36nmVng0UFI3zA3cMhqSALP6jc1zYhg8F+eQZB85D1aT2koRau/lPJOUEVNyk47VHQTbeiaRXECm7wOHQxB5aCmaWle3hkkYQFaTB0WO2veerm+JqQJGtAK36mQl6P3X7NFyEfp3SpnFJpwRo3XnhAJ+PHSsqxS/cRVATCSaWvgEu212aWO9tM+c6YOke6UkiYBOZZ7ABpKFsdNpXRYvI2MEtNDJvoB76rVmmqQNjKsbS8QEAddCqByOHTEKqGyd5XqNVGWWuwo1iz9TC1kQeaQ0wsE5TiehZudclN1W6ftOk7SsgnVV2Z5l9zpR8LQx9GpFZJMXaTh9sIyjZxgCRVmrOQtg7r3DFgGyFk3UPBx68dqyDhdkLXJePFOSFr9Fway4VNa6ymSoGqUZi+y0DRCM1RhqtGBpT7Jha6S9k/WhAUa1AgGqNbqPyrWTRMdEiYkmCxXPqypSdWcIGtDQrvc6R22ElSXiLV0vRW/fNyZOZVH5+C1IbQDvqvjYGQFeh0NHP3aszyKjvF5XghdGUeh2GV+Meq5y3Rov8YnZ4O/XK5wWsyI19oTO03eemBNdbxgOnRa4al6vAR4CpApLCQ3TwOzek17l9GmVws15g3EVTKEUy7pGjJVi/Xg6MQwio+17yzJL2IR4AiUpqvuWXCuyU2MNMa2Ax1u3sQaDTmvnOTHPUaWdcg2kUDMKzq5Qs0zYc2GZE8H7rTiWNVHW18vLzJoS3huqL1gbyLlwvYocqeskFXWZVw5HxzD0+M6xqHdOSVm99SK9NlQ5F5aYOPQDPvSETrwApVGX59NbBcSVwdsKPGsdXSfnGWs5n1emObJM4nGImoPHONIHz6GTJnQ3EmZrorMyiEEM87GopK9grUh4XUuN02LeGElNbt5zVk3sgQ0Uur3PnLNqhr+zyFpT2O6XWvImXaktNbLKn9fW1Opa37yGbgGO5rmTc8aZtpa6jXXgbCFb+QIqdseUjMFtTJP58sL379/ReU+MI9XoIKJWOrpNftKO1vS1/bP9ne88Yx2383NrrN2a6B2E3vfE25rj9n1K860yTgJ5nAG9Fypa9Ot/5yKyqmZM/em1MPuyJnu9tyxLhawypyrSpeY9mtUPEKThatP4qgDo7n8lgFlrsB8fH/nNb37Dd999x7IsTNPE3d0d0zRJ2unxuHmD/fjjjyzLsjHFUkrc3d3x05/+dGvcjJFB0bJEljVtjLcQAl3Xb2yIdl4tiod8cuhYZAfC9ETI/VVu/kgYZqYaqstb83zba1cMU4TOtGCopKxe8YJyzuGy20CJxqRoknAZpiYFF9p6nDbw1zkZJAtDtmjTWje2bPtGkogZIG3fTphAVnxC84Z0fXIi6g0MVfd+vd2SglN8cq4+OZM5F5YSUS7uBja0tytF2Lh9322Mk1oNZQtWMlCtQA1f6DJrrQqkG7xxGiJRRcaLSo0VTGm7Z7vfbxlYW627XQu3gduvvapev/cOyut5qe28ma3ev/156TPkD53KM4sC0k7Zot458SIwHutlvzXGiA/zdCWt63axWk3QEiUzWW/s1ydqT2DU9UYbcpEyyr3YACSj99EOlO1AQa07E6oRBToFMF1jRtIUCy2opZ2gGwnkDThbquxJRmV1ptoNwKHdKUpNrDmrn2Tdznl7vRvs+ub6VFo4EOwBO9s120DAz5mgn1/rNhzc2XOlAaVIGEth3y+pRgicBvHo033t9nAu0HWyN6W0y0drkZo4eBkEpyy1gndWHuOcNz/F9j2an1cpebMqSUU8U7vgCU7WCpwGNc0zKSW8D2AtBdkLDSrpNM3ns4IO8ayTbMrG1N8YcchAoVaj3orq63mTHNzWNelv2vVwHI/HbeB+OV/wQKDSB08IXnGGRCqF55cLy8sFT2W0hUPvCdYyvDkR+p7g2r1vtpujfaNKY03vm2q+WeN+92FuHu7fd498jhrUm3+3farIdiq2Am3AoftwVWa3sw0Ma/deezCBhk9/wQPtS8cfNBC2pohxIsMZciB0gVJhmmUaEFbx+2lod8qS4ueDJkUk8ahKN4WK81IgpZtomNYIOecUJVU5Uyli9l0NTptomRbu0cW1IrI0velPh2ErLqsyksR/7GYqZeVzBE1XE88UkQ6tWiSHwYGFFFskrGxiKYmpZxiMAEa1MM2V5RmWKWJqJcXI4Wffktw9a5Rm6OW9yF8agwNks60NVjWKeBehct96jOzH1iHc/J0i5nrD5lIpRouLNgU2bOevTdpBJAvBWw5jJ/5UWtg6TV+LayL0XtF+TffSAmjzGYnCZmgPjFHZ13oDTqVYmadISmVnrxmrC9FnVYUCAXv6Y/1kiWhSRKFuwrwUMf2eEs56mQA2Bo2xpJSIURaeGFeul6s+7C196vb99f9tH0u+7zh29L0n18J0FYAV9B4wKn9NmdA5TNTL0qZsFmUuGDVBb+CvMC66IeB8a9ClMJmnCKYSrKU7GGyxdM7TjR7vKym11Cn1/vLikWRVwpoinM+RpOmRDfhzvcibcq2kYohZfFdiks26ZqGppyVSc2YcjwgkCONREmmcNyrNE/ZhjC3GudJ1sg5Y6wjWcDiIP8DpTthSzx8nrlehOJdSMUnSYLcGsjbptIUsFPghyNqTUma+zsSU8T7jXNiSAoVNpeBecLIGaZHjg2ddJGkxVfBZmsdGBffeUa34GDaAJkdhaTaTcGdlM84pCZChVZxIneqWFJizgL6lSMJaCI6StalIZQPKpHBsflTqi+IMwUoKVU4FHyq2c+qxYCVsIimbtBooiMzRW9wigHsrQuKWGirFivOSVOqc1fth3YqlnAqmyBS41qpJwJ5ainhC9I7x2GGN5+OHMzlFQu/wHrpeio/QWfW3E7ZM14sJcgs4EFawYRw7nJciOMddTiSTsuZ10fw7oFYZEDj1JAHxVZP7BE73nlwqcS1bob2cI9erpD0dNbX4cl50nRTw2ltN+kMmmNbqPecKriRKGnh6WcRHxcOP3105nQLH40A/DHIvxcLz86JNuab9qbwRU+nGwPOHjxwOA9PVcDx2wtB0vU5lK8dDR4oz65oJwQpQWxCT3CwhMQZ4eBzJeaILfru2Rpu87bshIF5Khb4XkEGAtpXgLff3B0JwHO8GnIWYDV8/HEXykDKXS+Tj00ouIlkU6Xbm2Cs4o02Gc45cDdbuzxHsDVxQw/3qPdd55enjxPl5UUk3pFKZryudDjKOx4HHuyOjs1TXQHlZT6qaIhu7S4U2LyG9gLt8pNCSHVtBKKBJEtay9VhtTNG9qqq0XRo/Qwt/KEYaUWOluaBJrtyNt4z5tHRVljLKjEAKzppkWNGSPZv0zzs1/LV2A4S9KvKlWJZX86awGpHoHoeeN6eTmBqr7Kf5AqUs33Pzj7oFrYzUN9LMJk2WlUFCzplY4w2QtwMLUrAL4CoNqt18EIV5b7aiOqMML+fAVgxJBzx1bwhqUe/Wz/109tN4C4tx06yKV4yAjrmhIFs91VI2m5elyK3V+qJKkSRWGwJGfvXVV3z99df8l//yX/ibv/kbYWPXKgmtRZJaP378yDiOHI9H7u7u+Ff/6l/hnOOXv/wll8tlY45J1SP3WkxxO39WZbXjYdw8KKloArKw2z4FcXa5nNkafWPE0+32ujSQ2Dutz3Lc/L1qzVpZFqIxUJLaiSj7xLitripVEt3WdRVria7bQON2r+9+V3VDpJqPJiqNc0YCLBrjrBVRDVQNoRcmCCq1RepGZ5G07Xp7x+5HbZ6LDUjS22mbde395n7/KO3rFlwyKGCCZd1SWpUh6b0O1ox6od2+YJPlWbyrgCZWb+engTZaA9e9X3VGB41Gusf2/Lc7vMn/wJBSfMXU+bz+/+S81LY+7oBM3T6QAP4llfbxX/1erhmXHcmojE8X1xA8gxXvttANoN5zoQWSreLrdXvPGtTPs0nUS3l1/dtna/dsA/kMTVGyA37t7+We2UGZFtDV/ETF61Pqh+M4chhHnLHQ5NatPzStrqy73Y5+P6PXvrTnV0EwF3odcpR9OHLzDPy+Z1Y+6/7svJYdfwpmyeHV3kQsCj7pdT65E3ZFzO31FMKB+Dy7XZYPwg6sRoYTGEpNtGTO26/gvWMYOtZVhr7eC8g0L+tuf2Mb667K7fzqu8l7xnUlq09hjIlpSbqeG+6Oo4JhQjwRqw2xNPKlYr28dqn782GxOxij8kjnwwbyinVAI0mgdZD+h/G6h7Zrs5/DWg2bXQuVw/HI3emO8/lMzpnLNPN0vvL4GBnWyHxdqEU8Wp9eFj788MLYWf74qyMRSx86vv35N9zdj1hriCWTEbuIquCSfJ/bQYXuX/xd+NYNALVduC//wu96mY3jcbsOoHuIPm/o/l6r2i1ZxXdaLUZj2Fuq2yRcv++Db8cfNBDmR+jDwDRHwuh4OByYl8yyZua5kKJwZsRoueJ8pesEQDJOQAprVXpwM4VJOVNMwah/1iZjQICBaorWLgbfdZhSZdKpnkO5aeGVsj2OvUhXTMEFeWiF6YOmnjnhAVaoSq31Gwjm6AaRdF6vC2tMHO86fOcpRiSVLIm+g0pmOKg/jpViNRdhV3333YW/+e8v/MN/9ECJC0+Xq2y2K9wdj7zUF66XVYE02b3rDbKPJn5BJc7rxmix7kvRurrJWABhUmx4mr7KcOjE+whJ/QudpxphjpRcNA1SEtiO44B3jhiTAogVlP0jEiQ5Yoza/ENLQluWqEWJLG69eqnk68KySLHa0g+bPw7KfnuNVet/tQXLSPxta3TkFjIbs81uwmp936HjcKhcL5muC6xTgsbOSpkY5fsIGJnJqWoh2oop83qNKXK9URnZMMp5yE0iUrYlTIo0BS+sM4TOMzgFBvTvKwUfLP3By8ZchOWRBe/l0PcSMrAk8kWCGFIs+E4SDVMpJITx1PWe4B2miPTYGDChNSqyQeQsEsDLZWWZItO0chg75iVJseosMVXsKs9DjPJcGWvIsUiwBTIVmGLmdN8zjJ1MjWIkJ0m/c9ZS1PDaGPBeFuxu9HRegMZ5zRjvqDFvMriSJKVpyZlpFgAtzNLAD4Pl7nTkPEWWeWWaLtw9HBiHgWXNpOvE5bowTftzApa4iv+HdVpsaGNkrCXFKJtkgdBZQmjy6R1Qb54ofeiEIZYzg3MiiXRi6l/1Hm0AsDA/CmssLEtiWRPzlGQSpuy0kuW7Yh0pCQuIKuCR91qQIQCPSCEFfPVGAMiuc1AE0KtIEVizNEpUg60WbyreII00mXVKN5OvolNeMZNftFlyavqdTRa/OSvhGc4axqGnFPEH6E8jXeg5HkfO15m6JPWJEnaSDfIMp7jS9ZKu6L3lpz+7Y53lAZMUTQEWH+5GKBIekXJmjRaT0iYXaXPz2zIwpUpM8nz44ElrBG26cxGz83UVmfw8LdSa+ertgX70FCqX60yrT4fRk5fIugqjqbEXrLPgoNaVvGZqypyfEt1g+fDjxLffDLz56sD8tNANnuEQ8F3PuZuZ5ygTSSveijFF0pq4nleOw0AtmeAt1+uinhnCwl3XhHWGvvMEH3RwlBlDhzGJx4eeeZb16+6uZ54iXW9ZiqQ7pSypfuPoAcuyCss4poxRWczdccSYqqbpjrgkImBSxWQ4DI6UxV/vOidezjMgtgJfPZxY1iT2B1lk+OF0pNZIdZa0Zl6eJlrqoHMWd+cFHCmVaco8P80sS0Z8axUgPvRYA5eYeVkjS0ncWUlurtuVl4VWiq+6mS1DpSZtOn6H3GST/DdgqDWmzlHMLse59RMCg6RgCgurSXUqhS1m/GYHNgrkGG0AMwqi3TQJrdBMeZcGAXvxbgyYzOtp784qw1acabNky1dvv2HoBtYUucyTBre4V15QzjkFDerWFNVSt2o457zJrl9DTrr3VW3sdO9Cm/wWpuNxVAOlWmIuBOvBOYr1FOthkzrfnK/tOjXvnNu3fFWdQ1WevIFmEu+DIReL6XouL5cboLRqgyaFfWvWjDLXaxF2ZlwLdAJALfPM9Xrl4eGBf/yP/zE///nP+eUvf8n5fMY5x+Vy4bvvvuPdu3f89re/ZV1X/sW/+BecTifO57MyiDxd1/H8/My6LAJcIsm2EjAlDU/wjqEf6LqOdY3EmOh8kOeRzBKXbVBZS90Murdh7s19XHMGs/+Z3Kcqf0PThlsjbQyuFHwwGL9LoWqpwl6umWTrJkttIOgaZYDQd72ydKR2WzfwY0edfPAio0+xCQehXQNXcQ0YrvLEON9hVg2ksPK5rZHP3YCq1/BJG8G156axFrfbRAdUvPqtJgnd7q6iBuJt0OsMrhodzqNJrEZNoXcw5rbubkzqBgZnk7cQqlYTbKVjlT+noiphqSuCc6Qqz35MaQNmhMH/6pHg1q/rdx3yOW9rZ/1/pkn6GvpssAjw2RifzggwElOS+k1fr9lTOO/pxxHrPNd5YV5nat6N2BtopRdJ0+QEmDPtHrn5TqVWpmna7kOpEYJ6QMr3lSFEYQ82U4ax1vgSeiaArrxn61E6TsMICFjcpIVZU3gLZWv60fXCKyu01oq65wiw4rywiqyk3urDsX2ZLzMP5SQ0u5123+3hCfvvlNrsVPa9QJRO8j5ZUVSD7BfNd6w2ENg2f05D09a3dXxj0Jm6EQG2SspAqVGDVoR9l9Lre8s7Sxh7lcnCdVqYl8i8rFSC2mlkTK3b0KCd87bXxDXevJ98HpHe7qm4xopXWMlFvXylPe9qO90N2GPr8aruSTllaigq07Nk6yhrpIWGlVqgGJE4K9JVjHgk66Oh5+z235ZxHLm/v+fd+3eyftdKKoXLvIK5Eq8L03mS2rIU+rEnDB2rH+hPPeZ40npAroM30m9kPEJ3KexZy/s9c/uQNMCvtL5k+3x6H5pPfvcVg2N/jcae3e9EPsVO9RXUBkTXBFPNds9bI9YVXRBSTtQhO8aS/cin6Zt/1/EHDYSdzxOxT8QaNZnPsqwr1jq8QzbmKmwr61sxUjFOpuIpenIXAQER0lJYV2FmBGU6zNMKtRB8AFuJecUGx939I0/PL9QK3WHYGrRSMrlEpmlmWSSGvB88rpOHLuUoPl5GGmLrPA9vDqyzaLGu0yIToODoOk8/Brl7bKCSGQcZ67hOPHe6ruP56cIwjBgLw+BBJ3m5VJalcL1klmuiD5ZpmonLzN/8+gfe3t/p70iE/PW8iCTAqaeF3p1Fp5UYI1RDZxk0mWs4jFwvV9ZlkQa56sO0OZAjUw9u7nUD4yHw8DCSkkijRGaaicHKdalaZKss1DnLusoDkdtk2UsyXEOk17iKPAQBk+Ii06EQAoe7Az54jHOcn64cTyM/fP8dw7HneDgQhsw49Awh8PHjRbxHGoBUwRhli6H+cE7i4k37QsgqFoLjeAp0Y0ffaVJZHwjBcT6vPD/NAkD4RvkU4K4lh8a1adHaxsEGgkhYQmHPfJafDeo7Nq8rZAjebhK9lgDWdQ4zNIBQALHpuuKDl6JzjQK6Gi9Gn+qdVzSRsuRKsVr8axOwzJmxD+TYzNgzVRerlJuhqBWPpGB3s9QFXPXcHQw//PqFl5eFnCrXF2Hy1PMiIQN3wybTq7XuwQHq4VcU9AqDGKtO87SBfjJJk3NsQDbxlAidFYPtUaaraUksGhY1KyBXcqEPPaaxC00lr+LRYKuhFsv5EgljEHGqFjVLzFJ8F0OJ4jmXkvo6lKISOIOrToBKU3BdoFYB6wfncd5wvOsZRi/pkU1uqIB+M7Jdlrg13V3nqeqNlmsh1Uwsmc53DIeOeUpcXyJragwnI1LgJB5Bh95jkCTXuCYu5xWKhG84Y+iCeCA1X5Y5zvLZEQ1/LeKp0A0jpgfveta8CrslFepScRQ6byhjz3SNIl0oVhhjTgYDVAF/vYUpJe66owRkeJHUrjkynWfKmjgeeoIPPD8/ce87NTx2+M5wujsw9gFqIJXE9RqxTkyOQy/MMvFGrAyd5+Xlyvm6EmOiH0bSY6HvOsJgsYsUPi2AQWaA5tVOboBaDJ3zpLVs6+R0WbZJm7D4FIxcVr799sDx1IMzYv5vMs44+kPP/Z1nfpnkvkrCzGuAZU4iabpOC8NBTOBLWnnzOGApXM8zfScm9c73DEPP/f2BdV65XCaZ6sZEqYXf/u0P2FI4P11xwXO9Jo0VF+ZlXDPDEOg7z/WcqFn8AoNzXC8LwRvC4DHOspaMb4OgmHFWGtqWfrnJXVeVD5dCOo30Y+D+PohMcxHgMRvD89MMSZInnRfprOtE4mrPhnc/XrHOcTz0xLVyuSxcpsi33xxIUdKfu77T5kfkLE493DBGWLrLwnSVdOaY1Sa7NVFIsqzxhmla+Xg+cxw9d8NhY9e1xmWLXa9NtqRT3dJkE3uV16btm/TQWmF0wWdNZUvJaya9tYrXW8kZs0k+FFRvVXStN+/TStQdlPmS1A1kzbz1z005My0rXfAMRgF7s8vRbKkkJzWPMQgrrBiq93TjQKg9x7uTPGtVfJ+89ZuJOpWNQdmasZYIGWzYJFPGGkzZG9vWyMueoKbUpTU0woB21hBL2MDOYB3ed3vTxq25ettub8Gx+hr80j/ZWE4pC8BujKbtGa3R5O+X9YpIN4QNzNY0yPqdalaJn9kYi+taCB0MXcfTxw98991vefPmDc/Pz/zlX/4lP/zwAz/72c/4J//kn/Dtt98SQuDDhw/8u3/37/j222/50z/9U/7tv/23/Lf/9t94enriL/7iL7i/v+d//I//wTxd6UyRNb41owgbrA+ecewJoePyclH2bMDYTFxXlrjQeWFgVVuxxW7n7vacNZZMsGE7dyknAZOsU/DyFhgRkKvWyhoT481iWkqlpES10tCarcqSfzd2obGW4CThD2M2ADMXuXfa/WSMIWhiXAPVstpHLGthiRKY1YKH2v1gtTZbVmmkP4Nlt3Aog4AiN+AL6OAh6B4uEk4BT18DSM1EX+7XJsmVV9gZdJZ5qds6KgP3sp335vMEUnZb67GlbKnztSJNfakSbrF9zv31kkXYLE7WkpSSeFOt6w5i6NEkql8KOGj+u21gdvsUNV+w10tdgwob3aBJyfd7CwQQ9NYpK0rsMXLJxLTwcpV79xB6nA8yWCw76GoUdKg0YNoqALUft98vl4y6lyBp5et2ftvn2hQ/pnkn3pr5q4WOruF7UFqiBTPU9t3rvu9gDKbVrLT0VWUIGbZ7vaoMr53XBlq2FNF6c6cahGHeeorNe7k2oHTfM2queOfoQifgTs04i9S0tcqQWtcuQ5P6ydChsaNdcHjnN0BQklslRbeWIr345iGm+6Td1wUBxCIwbN+gnfex7wjOMy3rtpc1gLKWxBpnTNfjdS8upZCXjFl17UhJJMbO4Q6Ww9ARQuB0Okj4VYxbQrf4hgUwToc5jlK1nm9Xz+xSTrGIyBsrDBzO1VfPyGcsSSteYWgK+uvvq/9lIfjA6e6Ow3iU4Koi7NnLvBL6ke5wACO17Vc/+YrleqXrAse7ga7zeFe3gC6KgqpGevxb04H9+BTyR72NQXPMtNXXe3b/hvqhDRvVs37+OlVLlao//slyJANEgcLkXq6CQ7SBGojV1WjEI3VJK2ldSbngjz1Fh/x/3+MPGgi7fxx5eZo5ngZOp55331348bsL8yTSHkPdHlr5R6J/n94vvPmq1yLGsSxXOn+iH2TaGpMsQH0f1ARYCntjK8MwUKthHAf+59/8luPPRiqVfvBMV0lzCMGT+56KZRx6NSMfOb+8MC+zTHNSlanfm3uWy8L93ZFpWumyNMM2gAmWbuzAGZZFPIjGoSchDIpxGLheZsbDgaQAVt935BRJ2pyfXzIfP0Sul5VSEilbMJbvv/vA3V3P6TiSU+b8vOqCJABTxaoMzjRGMaC6dicPTUwZu0oCkXVeCpFawFicKTpVFFCtVEWUraGaKht0zvziT39Oionvfv0j03XmeHfgdDoxTyvLsghIpKk+Is9MZCxf3b/h6TJhrOHuNIrRexbUPwSZ2sfm+bKIGfjdGygp8/M//or3717wnVedeaREyKFw1Zhx63YT4uAlbdB7aTANAoKt61X32g5YMNbx7c8eyC02uRNWX06FdU58eC+N6DzFTWIHCF2aPW2x78Wwe4sJzjcbdMqfrFGyOvk+ELRci1G9YkrRkAWrZtXiOUetPL1MUJFGWjX6zjmGU8/Th5XrWYz6ZfO3OCcTi2VOFATgengYhHGVzCYbSKUQMJiW4NI7jPEyxfGQrzL9vh86zmlh7B3BDQxhIK6VOa48X1YKhvOHRQtBuZdKMWSdHFpTSVjWJdHfHZiWJ7ADp+Nha7A69Y6TZ1qa/9A5DseeJar3ErI5WWM4HDqu50WTZaRQD05AyrhEXB9YZzhfF1JNuGdL3/WEwbFOUQumyMPpge9/eMf1umqjKNdRngEBGZ1vBYDZ2FPifyHx6Icx4NXnbGMalopNApbWKuw2F6DkhLNSuFZriCkClnCwhMFScqDWhR/fiSG4MSL7kwnqypQFiB5GzzJFmch5K56GgwVTtmlqJuM7ke2+TFfejneUKoED2UfWKfLjDx95+/Udh1PPxx8ufHh3xofA3d0Bk1dyWnEhcL1G0rSwpoi1jn6A8dQRY8EPPaazDH0QP8eauX5MnJ8u9EPg5akj5kLXd8Q10feeSuHxYZSwC2PoAhy7gfNFzdajoWZDNYV+CNgK77+feP/jlZgK07zw+FXHyVku54lucByq57pYTGQz+i04LMJ0EszL6pMnQQEfP0zkGKklc//mCFien4QlOE+RWgvztPD2caRgCT4wHHppvFKkZIMNRtIDbTN3NZjiBTw0PfP0jOstoRtwnaXvWwpcZTxYhqPI4uOSxEC0d1wnwzolfG853h0YvnZcny6Mx4ECPH18IpM5HAZyLrw8z3TdkT44opdUWqMyZWcd1MDlZWEcOw59oPayrq+1kLOlo5KUFbCsST3ePEMvvnfOOYY+4EKHD8JIPR4dLy+Fv/qv39F3nvEYONx57u8GTicBs8pamS9ncqq8+zBRgcsUGXovcihkL+oHrbhEYAoUncxamdynLP4cxYCRwY21Vu5vfU68h/OyspYi8uSaOHSjsC40tvs2wes2Cao1RrLIiHmBrDXC7JNGYpcKGm7AGN1zrTIyt9dz0ty/aqaL+FIJPVmYKzmJvFtJThsI8SXCgAA6nxeNtTbbCGEdN5/INUoDHlNh7QpjHzA2Qok8nRO9Y/NmkfffJfG1VmKShNdmkLwd+r2aRHIDwrxcx1j3JEyrz1wqdZNcN6JN1P8oCLPYWvXHNGZrLm6Nvl9dJz0fqV2ELxytYXC+sb4FHGtg5TqdtyFQY84Z9qTNgoAfbVtvLKllSXzzswMfLh/51X//73z99decTnf8s3/2zxjHkcPhQAhhuzan04l/+S//JV3XMY4j//pf/2t++9vfUkrh4eGBy+XCL3/5S+J8ZRi6DcxoTZi3dks5t9YSU2IYBlnv2eWhpRamdZLvwI20tTaGTCYEDUOwIhFvTEbZi616Fu3AZ/PBSrmqn4uCB7aq1MUp2+bmuLlVBHyOUEQqOnQBEBbINKvPUy3bZ/LWq7XJDrzmUOhCoYuZZRWPoXYEJ9YJRY3FxSVDvn+h+f5I7SXNsINqtia31qrpm57Od4iEXgKs6s2Xaa+/BWco86yBYU1SXUzB1iJ2DJ8wecSL9nO5m6lVGRiqEmivVXcAqFSRkbV7UgAI+XhO5WblRqYpr2+3fz49hG1n+DhfOTj/Wa3q3N5y7qBA+1v5P69J6g3gaIekFgf6fqDvBxnATDNZh4AK9/PJkoLz3YYqWGRG77Leu19grchne82QiXHVYJEvhwIY7W2cC7Qv3cCd83RlWVd8Y+0qlcZsv9hYk2yD26ogl0UIAW3wm2sRplV7jj8B8611CNfxk/W8NJA4UbIM01KR/bm9b8qSwl1rt3mZCeCSb9ZHue9vQVADIs1s0lv9TM47TLoBDdmZPe3PQNf4m4+7S2lnrBUwzFpDHwJD1ylLP7KuUYfIUEoiRvUHp5IRZtuyLmJxUSF0skaF0KntgTzFIXjxKFWSwFokeGAYR6zvyBomlVJimq4UCsMw6t5sXjG5cqlKpLEb6C1eYU0+VDYfSXCbVD9noyBme2D2GsQaYTufjkceHh6IcZXP5BzrGllj5PR44nR3Iq8nyInwkwdCJ6y2ZYmEYDhfItfFYGsmdB39scN1B6gJ8p6yaLYdbl9yX0FkRjDmjIDSVtdD8+nv696/v8jr4bFu8RsYtjHFjAHcZ0O7igy9nNGaRfftxk4WlmwmzldZu9RT8O9z/EEDYeucWWPi66+ODGNPd5B42XUWNLAfPOOhBwPzdMU7y8f3E6UavvraC9LaSUpkRKjVMQpyPV8X5qvQwn2wFAyHvscYSKkyXRb+6E9+yjIt+M7z7vv3xDXShcD45hEziNmdMYbpuoBdKAlckAtzfbngXeZ6vpCL4TJPGFsZj8JwqhorLw9WJEW5oZ8+nvn620dduAR9XqaFh8d+lwOumWmauF4Kz0+F68vK8wcFuii8/eae77//SCqyiIhpfFGPLClecs4U9ZRsEdJdkIVPEF3L4RRYl0jX97x9e8fL0wvTNGHIsiBXpVSbVjTIdAAPl+vK6a5jGDp++/4J62AYB7wPdF2niYEiCbXOYqo2QSqfcR7GzrPOM7wNpBcBwlwYNNmuMB4HUtTId2N4+TjL+Teeu/uR8IPjeBzV5DxSilPPgiqSv5JJa8KYSncYON15Usr84hc/JYTAL//LX/Pxw5lSVrlmMdP3Yhw/HDqOp5F1ifzw/UdeXmbAYXBczhFTJN59ODie1yvHU8cyRSko8dw/DNLQU+h6w/UauVziq2Kw6fGN8TpUknQYKWoLyyzToWZ06b1lHIKwDnXljrEKE8kEPJ447RrxlASwWdcsDJTeiwRTJw9v3n7Ny/MzBct1jpSaOblOFiRdGp2mo/gg8rnpEukHz+HRYruO8d1AAs7XhA9weUmAIyeZOBidJue86mRGvq/4Owmo4buOnzx8zfVlIUaLyYVCZug67oYDpVTmtHI4DawlUm0AE/nw8kxeIXhhaKSYORw6SelctGBUI3nTGy1uj7icqCVRSyRZQzlXapz5yc8eGHyHcyNv3hSCF+8v8aypON+88GRaeHdyXK6JwzGwTpG4gB0Nne8JLlCTTH1ibUmbluIMyWT63tIfRYLbHw7UUvnww3uePz5zvBu5v3vDcOgJzrIi3nSHw5HrNVKK+HRhdOOfJXHxepEibjg4htFzOnm++eoe4+A8TZQqaX/WiB/b4dST5sKv/scHxtHw7scXxn7g7nTgcOjpusB46oW1WQ05adNyGLm8LICGLyyZy3kl9JnDaaAbPbnCtK6E3vN4GljXlXcJfD9gOwPBMV9kvb8fDhtbhWoYusC6rlzmhXfzmRDEf0z9ZoWh6xxxjry8TGBgmhbuHkdNm/Q8Pp6oJTGMElry/DTz8rwyXSolCSBrjYC0ku5keX6ZWVbH0/uFYZTm8nI+I8q3Quct998chDHaWS5zJAR5P6F9F2rNTJNIvMejpetl/UnJaMKwJa8ySPGjAee4O4wYNzNdI/f3HSUb1jmKvDF0xBRZ8wqmUIwAB8465iVTjMG6QE6RYQiEfhR2TXD84h88MF1X1nnFWpGLOAvxunCdEufnmQocDgJGhk6GOA9H8e1b1sx1WuUZQNiDBil8seJxZDF455muTwQ/ME2JD+8mSZe1kth6vawUxNag95bHR/Ez+tXfPLE+y2AghN1oflWAu+TK4ShguMgUteDKws6UQYMnxpUhDJu3yjprSmYHJjjuH3qyi/x4ec9Xh3tOh6MOOmUPbqCP904n7uJ54ownOL8zBhBCtbUa7+6adw0bU6JSMVlKyVyhc3ab9st7yHttTUhjaSUJ3DGmEvRnmvytFGHdpJT5pLbUZ3BnXNwezqlJea7751cJSUqFbKXJTory1xIpJbAskTqMhK5TRqTZksrkIrFV1s3suclnWqPprZhfr2WVX3HC/pI0XzlnO7tJCuSo62Wrv6sxHOy4me2HYDHeY/2e9pabJO2mE5Phz+dnqn1sASzlf9QGVigzJ64rKa6b12hj5lWqhtfYV5ZIObXkcGVoDR3fHkZ+++u/5T/+h47/4y/+gp/+9GeM47hJpW6vTzPLB/kc33zzDSklPnz4wL/5N/+Gd9//lrshbDVATklTgi3BOfqu43AYuV4v5JyZJqlFWrNrjGFd1/0aqUzXYKDszKDbVLaN7RELa1wpNW6AoHzOHZi1NeLMiu+c1HtqdZFzIqZle70GYm1yWSPPeiyRdVm1IXY6xN19jrz3eyBFtds91l7LWlEcHEepNX79w4QBgrWMytaOKZGyAAKmGqwp5CrPZ8WKB1pFQK5qNr+nlgSaS5a6GqOyogombz/X5Hy1Vrzzm0m6s44uoKFCiaThIwKK6D2gjba7oXO2e6TWqqBHW6t21seeXHrzOJb8imXWVBfi05c2qettYMHt09H8Ztv7fwp0O283sL/JJpsX5a2HlYBBRjwKlRFvjbCR+76n6wfQ+1Jkb2xNdpwXyrLKeviFQwbEwtbMzWZF76ds0qtzl9WcvoFKJYuf2WcsOH2+N+aikTW1KivF2aDstapm+xJQ4VS+19h9NxdQgCuzA2PUSi1JQWZ9E9qzYF9/mC8cLqitxSr3G8pYbexIKiq7lXU1KiCaq/SGt0MaufZhu17ync0rT8XmB2mtfSWRbGEpwgSVoJ2+C3r59rVNroMl55WSHMPpQB8Ca4zEmJnmdQvfwYhaIkakpnBif5RVxir1i3gzdoeO0HWIDY1IxjcvwZvDOrlGWMeyLHz8+AFjDNfrlZwzh+PKw8MjQ99ve3ADrmOMdCniQycSSe9ZloW+H3DObwxy2NVOxVuKApGNSdXUBBpgz+l0x9fffM35cuZyPlNrZVlmnl8Mx9OJw+lI6Ds8macPH/jhhw9M1yvOe54+Pkt/7Rxd3zOOA3cP8PjGMR5GCaMqF9pVaNFYhk+wbL09jbVgPVhPoWCq2PTIrXnDnDH7a1XMZ9e5Da9qZSPcyPvpp1BjfHlfPR9VAxiM2Wx0nBOfXymGVqzzMiD8HevAp8cfNBD24d2FN1+fGI9HfvO3H3j+eN0iZtsZrbWQlqhG4hkfQCb0C6f7EeelYWmJ2j402m5VhF8on95LAXu6OzJPKzFGXp4vHO8P4hM0R0mKO/asSRgbXSceNTkX1kXYZMMoRnq2c5ilp5bK+eWFN9++AYyaRgf1aXEyMYrCIpqukZfLwv3bhTV6fJHFxIbANEfAi4zjw3um64RzA84OLKvcnNYjN4gx3D8c8DZwfol0gyMl8Xuazqt6Iujkx0kajXg9yERnPPUsy8w8LZo0lHn343skKdFD9Vr4NvDCCdvB2O3GFwPpzOXlGe+Enu87T8lmS/5YSuXDu2e8dzw83vHmceTD8xVjYJ5XSs54F4jrSlwjl8vEdP2A7wOHcWS+RpF5IRKd+8eeZYLTnbCsTncj7394pgJff/0Vy7JSkcQaZ63IY52l6wecd/TdCPXCj9+/55uffM3Qe7759oHLeeF8vjKMHdOLeOrkNXL5sCpin0lLpdbEmiI+OMosxWFcI9Za3v1wJcWEMTNh6LleE87JtG+epEkOrsmvMs5VTA1kkyk5slylKZX0QgNVgga8N/hgcL7qvTXw8flKLpW3Xx0ZHwMH54gTVLtyvkp4QNdb+mEgdI6cK9cXYbVN16hsDvjwwwdCZ/n1rz8qUGP4+DQJk2QMdIOXZulqmFfpGnI1FCPeD8/nyP3DgXdPF5yXTcZIuJsaD+uoUiE1ozSJSuZ0ODCt4hU0n8/kRUBTNBmSLBuh6yyn44BfvEjful4m1a5SIiznRHjwdENHN3QcD4F3P068++FMiVIg5CLUcGctUT0FYKXiFCmurHPl6f1Ef/LcH++IM5RksYhvlkFik2OsBAvOG775yR3/4BT4X3/zQs2BWhO5CJPN+8D0VPnh+wvFZr752ZHh2BGMSMSWZcU4KWhSzjw8PPL04SNvv/mKw3jH/d1RDIaXTO88X709UBA5a4xSst2mOZWSybWnUlnWgvNJJq2hcjx2dL0wLKdllYTWAt5W+vuBCvz4/ZWaIum+cPcwcH8cmJaVaZqZphWqoesGrLUss6TbHA6BeUkii4uJD+8ih6M0Xae7AW89wTkkWVXkaudL4t4NTM8rL08Lp7ueNRaC3h8OyzIvGAzDYFlWeP/hSnCWt18dGdZO1zHH2EMXgpKvA11w9KfAmgoHKliIKRE6w1ffHOmHjg/vVi5PGRnwdZgaqVVis3M1zEtlPHRM10jVZ/Dxbc/prhP5mTfc3fd0wfHrXz+Ti2eJhZKRNFBn+MmfPfByNjx9XBh6WC6GHGX6lqJMAN9+dcR1jrgm/MMd/QhdH3h5Wbi7F6GRc7DmiVgSq/poSSMuicXHU89cskrXJbTl4c2J4MU1IqqprDAlDIeT4/5+YLmufPg4bbIKC3z7zR3TupLzwOE48vJyFaldbRNXL89lKYyD56u3d0zXK/d3b2Xunj3ZJZ5/iCrDhMt55XrJWJ8o1VJGWc/63hFj5PHO8uHDBNZvsvGYMpULzjmuF+iHI/3YCRscMMUwFWmerPMYm7GENqSnlsTTxzOPjyesq4xHz9ffHHh47KGsvJQLXTzzdfcIDkpL/0X9gIylqiGwxarvlpEJtaZYOi/JgV4nmc7sfkuNtdHYEr7Kz7W/u2Wegexjq7JvJVHO0CTxOZfdj6bsU952/9eKNvjyc96xT7FVRniZFzGrRRkPCKjsvQKLVkKLUk4YY0nmgIkXARXLiA89tkkoWnFtdGZctbk0bEEBBqNgg3y/lMsWdrKxCuo+WGteZm2wU2slZmH+jYcR8RnJrHGhGktvLdTwKuXONHaG/v7t5Hr/oZt+0xoB/mpbO7W5pLAsYk6fat08dEAYHc0TJqmRubCD97foho6u7+nHgSVV/sd/+3/49a9/zZ/92Z/xD/7hP+Lx8XEDQhtwsIEO+r9TSvzw/ff8+3//73l5euLrhxPHocNaw7Isav0RxdvROzplck3TlXVeVH6FDtDcK+bcFrjRZIbskkhjdp+v2/MKiEwNAT27LoBRILV1ePGKGe4++V22xto7rwxUdGCwgxUNkF7XlWaojCo/gppWe+c3I/9bSWeTLjd3jfa6wYtfVkt885pSKOtLIqYklAgHoMbmxmKz3Zho1WqjVitQlLmoJuolE+N+ftrn6rzfnn1rzAZMC3DYXqtu92Lz9vpyqIP8bMXoGtD+bMNQNuy3Ivv/p81uY6i88jQzn7Mpd3C2vjJ93y/m/p+3nonGVG1093s5pURGJKFd6DagoO87hr5nGEe6YVAgZSWLdGJroOO6gnpC3b65uWWj6NeRRroxRS3F5e38t/PSzpULt6zdBui1by2ft13LFg7SGFuHXtah9imN+RRE/NLVuwET2hqugGgDnQRgFxRhO6dWWEef4vghCPjTniGr94S7+TkBfVdSkfu0HZvEWRly5Wbd+VRivp9j8+p6t+dQBkVyD8szZZhXfZyceFWlRUgba8zUaiXMZ83k/CSgUVGj+3XBORlYdUYkjt6HfchRZfBng8NUYYR5LwOWnCM5iWWDDFe2WwVroHOGtJypZmFOcj0OhyMxJda44jrHEqX/9bwG0mopLMuk8kiRsw7DgFW5r/S/WVnMRvtmy7qdcmHRFh2q3W5Hjw+PvP3qLdfrhafnjxhjSDkxjh84jAcsht/88APf/frXXK9Xnt+/l9ogBEqtypyFvvO8efuGX/yjf8hP//iPBPRzd5Be+PRytueg7eDWQHFuC9wBSzUi33bEbSC376ntptAXqoZP/cNulxg524mKYzfyf/2hKhL+1mDD4CzRSCgOJVOyFczhS5O/Lxx/0EDY6dQzjIF1LVgfWBeZlGMEg1yXtCGCuVj6zmJcz3ReKVlSAq9n8UYy1VFr1AWkRd2DsQIgHE8dzjmen85gxNT0j/7oW959eOJ6mZiuwrIx9wfuv7pjmWYuzxPH45Fh8MRylvjTCufrmWWdscGD8Tx2jxyOBymUvRhGO5VAzPPCy7Mwjg6nE8Y6rDG8nC+E4DgMI+fzC7VafvzxTNfBuniu05HjceQweuLyBDVjnEStvnv3gvOWl6cLL+eEtfDjb1+4aHIWRSUZFk22FHTC2oCxcH46U8iMh4HjcaTrOq7XmZfnC2lZuKWIQ6FWRwFcrWCcmLTXxPEw8vHjmXlOGBz3IRCXxLJcpQnL4oEWgqQPRt1ccqnCBkKisaeXyHxduc6Jt2++Yew7LtOVNc66cMoE7XyRBMHn80zJhcNBpKX/4B/9jKenFw7HAyUnhqFTuVdQyWcBk8llFYAyWKbzM4+PB5YlkWJmXizTdeJ//upK6LuN2i2G6NLo5wI5FjAOqsekzJoWnHekuIsxrOnogsggL5cJ46DvPWTLV1+NvP/uTK4Qi1HJSiAXSTdyzktzWmSJKEVYjsPYETrH9+8+MAw93//4wunY83CUJWCeL8QlSSKcdyznhLChhM0DEl4wBjGzvl5WQg++6zgeO56eZtZYMU586g7343YOYhIzyMHC6OF8KZzPUnDmVPFUhuDoH+94YqbESEY9JrJuuEaFGbpiVqp4wUywzpG+F3q06z19HzgMI8E5zpeZaY0Yixgn9wFqJa9X0hLpeoMhc7wLDL1jjRFjEsZkklkx1WNN2IolSYj1lCr3pNzYMC/wiGW9Vq5mUgaKI+aVGOX5lSmKVRWW+F4ti+x+mUxc4XjydK7n/PEKxnJ4GFjiwprFF6XkTKmZbggcH3pC5/jN/zzzw7sLp8OJjsTx5CBAh8Pbdv0ib46G+ibw23eRXC22QrkpxlvSmXPig9cPXu4vZ0nGMsUsoQG9px8sznb89V994OVjJK7w9VdHYeL2QdIDU6LrpQmRZVjW1fE4ElfL9bpKiiki84xL5PI8EzrP1a0EbzAnh7HiCdSHjseHe4w1fPwwEde8hQLUCpezrN8lJYZhJHQ9x6NIyItGa4sHltzz0xSZp8jxTccyV8KhozsEul78cCjQHwYFqA0/PY1881Xmu9+c+du/fVIu9800tord7zyvGGNxOBKG6yVhPYwnzzgGSQmNhW7oWZeoyY4SCND3ng/fR0xvOd4PHE4BYzLTtLIswgh1XeDyFLnrPPMyM5XIYDwGuDuN2hwW5rXgbCHYQrJwGDxmlMY8rStxKnKdYiLFQgiDACOpCGAbHP3YMwwCpM3XREkz03Xhw/sra8yMyqAcOsNxGLg/HDnPC28f7nh6utB3nnkRKZx3lmodyyIJcG/enCgly37k4OWHlR9+ONMFJzKUWpmmiAs6uAmOl5cXgjP803/6U3748Znxu4mPT7MwTqsVNvcacLbig3iyrMssYJImAcdUiApyiyxZpJOlSqpr3wur9c03g3qdCLDSjTLRvZaF/9d//C/8o5//hK/uj696ji54ZX8gk/CNbmGgqk2DsRuo0PxqnHWkLMbe7QXFz0fT9bSJafewsW6TGgoIkQG3NWKtBkoa2tMO5xx9kOc65Zv0Pz0PAqbJYYxIxKCwxkX/EGmK/O7h09gDtRZoxtZZprHFCDtO7JleezCVVgxXabYw4g9GleCbrXFDpsAtfMjcdG+tPG7ymhZPn0vdXl/2oISxkY5xMyVvR2vWNslc/sIUecMgpB3IVRpwa6CsC2WdpYnPe2KbMPqLrqd2Y+w3BoZ4r9pXn8MaS0yZ+7s77u8feP/0zH/6j/+O/+v/+jfE+ImJf93PJQhAEULg/nTi/u7Iz3/yNb1tH16bVpp3mSN4j7NeU3kNOSbGvsc3Ly27N7mv7tcbNpCxOxDiPgFsG3C5n1sZcHadyDSzAi3WWdzGgmj3qWccRBa1rivzOn8GtLXv1Az8GzAGzZS80PlOJV9sIOrWvN9SHSqgn89bi7OGZV03ENh7MdAWZpohb4EDsm8KEC4AYS4q+735nC0coqWjtvMBbJ5E7TtkHbaZdj82T6fbe9Y2QHuX3LZjY6hYSaqvr4KfGsjVALXde+/TYwMM22c17bvkDdjd2FJVQc3Swra+fMj9IPePMzvAZ0wDc1W2mQt2MPRDYBwHhr5jHEb6bqRgmON645EFRDWhz/HVdzXWYtOqn12BQMBSyCmxrFGeB2sZ+kGB9PiaoSUnQ3/3M9GhMBNz3ME89bAD1NTbbefKWrOtB7cv3dYuScOzCsKyBR6Ukklxgar+aRis+9RrTZ6bmGSY6LzuRbXJnL1I2bynpl2qfHu9P01jbdLRdLMmtveX9/sdybo357+FwZznhfN1hYqyn8Uyx2AUqDUsswQJWSprThgK767XbcA9hoFDGHHW0XdWPGCnSLA9PnQbM7KBzliD7R3BCBM458wyX2Fbv/3mXeytxxrovd13qhp1eIImNiYOh5FhHITwUJOkxFa/A6O6h6S04n23PUM5J5EGfwKgGuswKqNue08z5K+tdtAjhMDjwyNPH5+Y55llWXh+fmaeZ56enkm58uHjE9fzC6wrjyfxh52mCdsNLAvkHPn/Uvenwbat610f9nvbMcacc621u3Nup+Ze6aoBIQRqQGDROzYJCIRpguMQlx1clQ8pQ8WpVPwhIZWGpFxUuVxJlatIFVQlFRrjGBNIMAaBil4gkEDtRc3Vbc85++xmrTWbMcbb5sPzjjHn2udcUL7lzqOtdfdea81mjHe843n+z7/xY0AZx+P7A1eHA8Nm0xLoPV6FD57IN4BCdeEhvp7rC/B9ZYFVKOiL7//SH4rmj/ghrwUSnqARUk0xmsloTlOht8v++i8Hmx881/9P7+z/zx6bq47T/Uj/yHPaj0xjaImBDwHxRRaRc2E8zC12dZmWFmqCzbZQTpnNtkNh0Br6wQjLpErE+6NnjzmNM+M4Y9C89/wF/eAZBmkgam0m2UHSF3MqHA4nDofM7kZzc3NDiIHr62uMscynyjhNaK2Zxokwzjx6spP0i5VGrrDOMp4iEMklcncb2GnDk5tnTGNAGc00J46HO1STDhjrePUicLgbmWfZmG9utnT9BmsdIUzEWHj2ZODzn3vB8TiTGniyXqi1rEaeRntizNgSmzeR4+mzR0zTxMtXd3S9ZfdokJvLFNYToJVCtUSMXCWh0dmeUhOHw5GPXj0ix0LF0vWiTT8dT4Qp0PmevhvQtmBdZdt79vuZUivTHLl5fMM0Tjx/98DxMLPrtpSc2O6uiCkKS2njZF0AKSqM7lAqEQqcjhN97+n7nmEzcBwnVFLMKTUT4wLEZgKtG209yQ1Ea662nnG+J8TQEt/kQ8c5SaPVjmNYtwAlIBgg6UpCvc5p8ZQRwCfFjO80w06xMT1oSQZ89uya5+8eRKY3yQ1famqp6OaQxN8kFsaTpCp6Z9tNUzNsOrQyeGf4tm/9Wr707rt8/vMTqjaz/hjRWoxGU5FC/fZu5HSSglCrxS9Nsd123Nz0xAYyemcpzUumc444C9PAOQMlUtUExhNnaQ6K7ri/m4inymlMPH46cHc7oat4mY1TJAWZHolBp8K2KYNMeCOqapQuYi6qoaSK60Q3f321RVfF8TiSinhC7a62dM6z3x8IKVJzZvd0QKuK6xTDtmN6McrurVqMe5tGLJ4dSiesKaSWHOuMeIPc7Hph9DjDeBK9/dB7us4xh0ipCesNh1OkNM+7GDIxSdmYk6wRrQ3vPb+jKDl2ylSyipzGwHZnKKpim2l9LYowFZF1psL+MPHsRhhax/0tSsG2l2a+pojaJB5fGXYfu+HlOxP3r0ZyFNPhnBKPrje8vp/QWqjhIiUUY06rxUPMWs3tqyM3Nxt+8edfUJQAnQXoei/Jo84zTpFpjs1vT+OU7GmvXp54+f5BmGretZTTwmmOXO880xhRWhNiZrvpW3EAKUFMwroQ6VfGO5HS9M5xdzixvx9xxnJzvaHvO7TWeG/Y30/MU8Raw3RKbHb9ur/lmtkMO8pTh9Yikd5tneTjak2YRk7HCddZ+huLbuClaiwPqqQFlouiMpfCMHhqOss+5iljvaZ/5tHGcrgbKVXz4v175pZkpI3inS/d8bVfb3j86AZcQZHJZSKEiVls/Ugl4HrPq/s7NpuNsE6DoyRZU9oorm8GTuPU5OKOnVGAlSlsztzvR0IoDNYw9J4Z8bYsMRNKEqN8r7FuSz84pjHy4r0D4xSIIRGzSHu2qiPGLB5gWhNqou8dh7sR74wwpb3FDo7OO7reM46Ju7sD0xi5PwSs0ZyOgZjE6y6mIiwpU4mxsL8fubnpcV4GRwtre3fVk7IMrI7HQAgJNwyk08Q0FwbjBdDrpCZYAKnFNiFFkYCmGNhuNTHJ95zT7Laeod9Ra8IoGQhZ16G0IYyZtz52xW43rLWFMeem8czaadKSVhqek90upse1UijnafsiqUIz54xRitKa3lJzS0ZSD+R1WklEu80Cukja3Lnpe1AHLdI2dW7Keu1bVLxaf27BFKzT4stZhE24+LtcJgYuE/9KpS8nlPftZ5QEjhRAt7Ruzg0/b7w3hWpANRfvo6yfQ6lWWJdKbiyShbXUuaUhqxCimGg3JpJzDpxrz/WGL9ny2m26vTx/+8bDQrLQmqYiDLj2IyKpbb+ixYOVxt4xWq/Mnjc9j7go1JVW7K5F3qJ1x3Ge0Mbw0bee8jUf/QjGOKzrcK4DJBhoGZ6lLPf9q6srtNacTkdevP8+NZ8ljSDNYWgm4lbLPWTYDWyvtrx8/lLuZ048C2utZDKasy/SwtIrzQxoBUnaQTJefFnCHMSQWTUWSKmksvg4XcgWlzWhFEbpZWVAW0tzmAkhPNhbWU9NSx9VZZXPPviZCgYj4U9oYopEYgMA3fo+3uzNNp3DoNf7XkzSjCndQm7OT38BXol3k1aNGbbQiJZl0xg9l+tt+ZxGi5G/baDFwiJb1omwOR8moK3LVy3M7ofPrYxuNQHi14oiLin2F88j/mCVswnww+tCX7D+1lTPpXlXhVq1sEKUIiZhZy1goIqZhsLK2jDmA+A/0MDt0kBcS4yVxfC967zUbN4JG8z2OG3Fm7OUBdGj5EyapwuWyXqA0NZCiev7yC3FOIS0Mp5LKWStsb5bf+8De8QHmv6Hjwfn4OKrt54ladLoxUj/IQj20L9Qvi6s0bqywc5rdfHagoV9p9aE4NoCns5g55kBKa93+dnOrDajZe0lDSrrFSO2Vfawc1iQ7HErKHy5PpTB2q69RxlMFwWZwjgF7o6B+7uZGKTWqEgyfK5n1qGY8oNTIit1ClwtqFJkmG0CQSs6Zykpi79zLfQbSwkerRporBeprfRUpcn4qTK8Ni3hefENSzGhgX5wbW8U5pk18jmnlLifA9urHVfXV2evxgVcv0SKoIVjxRWYE+VUOg9ZLq5xa5SQBqx9MIQ5SwLPq6rWSt/17LZb7u+61Ti/lMLxdGSaIm+/9YSfuX3NzdUVT956wrw/8O6LOzJG2BLKkWphTIV3332PaTrx+K1nXD96zLAZOOWOR25uNYAwvcQG5GL9a7XWAsubVE0Du7C43gS+PgzMWtbKurbrsrc2C6Z1QL8cX9lvtBI7G3kzlc5ZNikzTYGHsNYvDXz7qgbCAHY3W8ZpoiECwuBqF7jRzdBUa9FWG0NqaT8lFaacqQoeP9qw349stuKboppXg1aVaYxt46/84s+9Qypigv72xzyogemUmEbxE+t7T0qZ4170u5tNR+c6jtOBkAKFwjAMHI8jYcpMk2zQ8ySx05ttR82FvhNG0vEwgbI476WxsJbNZsP9/p6ntscZCxtIp8x0PGGdUD/nsUg6YawYa9lsejbbDq0NKcw4bxiGHcf9RMnw+uUoG2oDwmTaLEldl8guINOwAp1znI57oVsOYkh6uBO5zCVd+nJqo7SRBrMWclIMg2N/L9KilDUpFPEryzS/VplQdIPDmMIUEjFXHl11OC8by+H+hLWGfnDc3Y1sdp7Xrw8oXbm+Ppsav//irpkUClJcs+jnjNd0fdfkWRnVI1IMxF8h54p3EqNds+TgeG+Y5pn7+wOn0yiS02CEtq+rrMVyvilLsaAv7pCtoteLJCcCHZUZlMN5+cxXjzdoozkdRvGKK4XNled47whTQKpNg9aWmMTcM8zC5PKdbf4HUvCk5n1nfWJOM7Vorq6v+NznnrPpthgv0cT72yO6+QfFUKm1xTjTJpDO4I3FeUtGTCC1VsQpMewcrrPChJorthiUtmgDxnlyNqAD6IK3HSkGYolcX/fcvjyhdUJrTyrC3Fj7EfkQVCO3Z20ypTVuzp2Li1KyyBmdANzGGoatmGtqIwmjr17d4lzl5cs7lJJJrOsMkk5QeOvphvlUefVa/HHswkAr0vAux3PTe7mxFuiVxxpD7ywVmLN4bTjrxB9Mezq3IZfMprc8fqRRKrN/PXM8VuZxJraM7JhaYVErkxLZQLd1dJ1if5jZ7Tq0sYz3YqqecmYYLBm5/rZXj4ghEUpkDBPJZK77LXVzTgjqvJOlkzPX1zvu7vZYK5PsviukrIS5xpLOVrAGslK8eHfP/eHI83fv+Jqve4vXdyeurjUhVR411s5ma3nx/p2wVjuLc54cFeMUBZQKkgb45NmW+/3M6TSzu+p56yNbprnQdZYYxR/RWHBek5LGe4uuhmkWkMVah1GK8TARxsjr1yeudwOdF5l63wsDq5SOHMXvL8XMcT9zuB8Zth6j4b1373j21jMKldO0J85eTPqbvMa7jG1+ItIIJ7kxt4m6dQ6tWkHe9pXOO05xgqoJkwAlBs3xPvLuFw84L9K0eU7ECWxf0VWz3W149d7I2x97ijaFVKukznZSQHbdBm0tx/FArZnr6wFnRSpbgjQ7xmqmSbw0xNAb8XFo3o2mSQljkOsN5NzY5q2x2w2cDjOnUaGnyHhMEp6RsoBRgKnCWnZGCYgVEtZqroYtKsBuMzDOgYoESIhZOozzTAiZYWNxvaLLmuMhNCmGImWRBBjaZLxUairsDwFl5T6zsJWVqvS9QunE4Rjw3jJOge3VQIoF4+SaSqFI2p0GlACXuUnyUipY45mm2MBfRWmBJPMp03XN20a3PSllSirYTvPO3XM+9eTjUrS9wTKShuOCUaOb18UbDdaSjrQUxUZbYGl+L6b5K3glBboEbSyFIvT+7AO1vL7cc8UTZwEflkY759ISq2Req6xlCRKIUXxstBVJWMlqNW+uyLo3DVC9ZECJrLGs4NTyWACHD3IpHj6ssysQdsmQWTyQjNaElASIWn9u+Vm5py5yMaUUqZbze6TVHc34+1LyJQwx+VNqOgNZH1JDn6WZ7e+FdV+V93MZmCDHcHmIUXl73jem1dZajLUY7SjteWTdmCbnkevWN4lLTOIHKpvQOaHSWLkH1ZK5XJE5S1KrrhUDTQIp62F/d09ObcDZPKFiiNTcvJq0ZWF2XX6Wy95vYcN0m64B/xI6M2wG6lFqJ6XFK+6YA9Y4hm45NmqVH6aciI1tFeaAMQaLsChKC24AGYZZa8klk7v8YN1/mFRr6AexRGhrIEQBzxZAZmFr9U7sTBSGkC6AygY6ldYcai3efZdroTSJ/MPXPzOJ5BiypmAvDBxjzJpqefbXqk0S/fA15L221yuFooQ5e/k+FwPu0lQVWoNb/cqWOqAtHQWoSk6xschsA8DOIN9lDX8ZtiAS6rN8dpEEeuvJMULn1p/zVhQ1urGhFs+p3MD7GBerE9n/nbf0Qyf3YOdw1uGMsEVryehaUI11Sk6UFBugZpqCRaGta9eR1I0SmiS+0iGmB+EI4qEWV/Dvwx4LGLwm19UFeDqf3/NZF0+z9blTRDn5DAvwLs2+xjY2a2kDjFL5IAPQaDJehi5Nu5xrgwbWaxBSDCsfZ5F/y3qw60psZ1K+1+4JtnlWks6ti7pYIxftH5dA4SWT9uIHoMI0R/anif3hxGGcmeZMmBMllrX3LRgStrGGatvDIdSCdzDFTNdrul4RUub17ZEQIyllhs7z+NGWp483lBo4pcDr23tAs9sMeOPpejnepRbGOIG1dNbgjWMYBnznV8ZaiaKIUVav4JZt4Q6azK53KCQQyDRJslGSJklr+5bbngTiRfByzqpehktynHJukt5aiQokXVaTtShNlhZxAcMWn79cMtpoNhsJlVt6M6iNaWg4jSe01hzGiZ/93Jdb1pUwCHdXW5wTO6NcMoc5oo8Tw1XkE71ha2fuiiUWK3YUjbHstchWV+xpGX6VCq22fOOG0ACu+nAhgYCRnG+xDc9eF51C7qupcrYjWEHuyhIysLwPjaiLvLfrELI2VvwvEQf76gbCtNH43nF/P7O/n8UsTQG6pbEhE4fS2Dl5KpQyQ6kyNbHIBB1hPigNriUJzvMEuWB0ptt4jqeKMhar24KzoEwi5YnNIClbKSTG4wx09L0YInd9xXSe/SEyjYHt2wO3rxJxLuxfzcQCaEU3eDabHlS7ANuJHSeRMfmNYZyOFBRd32Gt47A/EmsmF+h3W3TVhHHmdJxJCYzt6PyGTe9QrmCd4vrG8fmff8F212O95Rd+/pb9fYuiNQ6yeFUoLcyikhcKd10Lp83O0g/iBVNV5v13XlPV+WazADDrowJV6I21pVgYq+mHnjAHUhKpY4rSQC7+JCg5x6Itj+IHkzSlGm5fnfBu4uXLA6eDbIwylVNoJvrO4/0Gaz0xBqydmfPUCnLoekXX7aBWTuOJ6+ttS1Yq4qORRXZljUZ1S+x0xjqhG4aQ2B8mcmM9mRY5vTTIVDCq0ejbBPVDNwWWazVifccweB4/3WCspBrOUaRI2iiGU6Dzhm6wdGPPOB7XpqbkyjwlnBcJo9ZiJppLIiZDTDDNM0pnTic55l3fY61lv5+5eWJRznD1dMv+dqS0JK5S4koxtc7LpuMdyhhiU/E4b+i3AoDsrjfi7YVILOUcKnxvSbHi6oZAIMdCCQqtPC9fvqbvOmrRGKtW1l1pN0Zd2/W8NA/V0PdGTMYBSma77TiNkW7QaOvIOWK9ot+K8byzDuMteei4f/WKjz59xOk0oZEUEucUd3cHrrce18F260kz5CABE1KAtFZOKd56csMX3nkpMtmQ6IzmajswTwHTqAIyHRYPJVEWSHDAfp+odSJHJSCBMjgLKYuERysrUdNM2F6x2Q5cPfIoHel7MSafYuDu+QGtLMPQo63l+kaoL8Omw1WwQYrKOQSMFcZlSoXDMdM5TXmyIY1t6lgq8xzZ7jYondAqsZjqKyV7mSqamsGpjqubjv39TBiDGPcPGjMYrh/JdP/2c01CrgwKCW+4v524vxOWknZiRtq5Sv+kZ45Htlcd1hdKFlC388L8medKSqCoHA4zIc0CVBdJb+16DxUG79jvTxwOIyEmnjze0XUGo3WTaBb2x4kpCnvp1fsnSjFop1e2hLMWchaviiCpn945rNP0nWUqia73XF1V4piIqeI7Q5pObaKr8V2Hs46bR5YwJUqIzMeZFylJUq0SqbQympwhG4VTmpvHA9SCdkoYbLmQaianxPVNz+ObLfNYuL2/JadJ9h0N220HaWKKAjDGkEU2Ost+2G0dpQXAhFK46naUCtMUua4bnLdYoxjHkc22k6bMGMZTYDpFpimJTLJzkkS4ESmvpN0pjsdZJsFtCq0xrcmLWK0Iy7zUKlytIl+MiV0/cKWkgTweJnJaPGNELuStSPVck2+O48yw8VQUp3Fqu2fiyZOO8VSZZik0pylgrIQLhJDx3pJTksTT5pdUI5QkBuopzhgngJKzDlzFO92MeKWGOB4CJQuD43AQL9K+8/ziy+d8+u2PYZTIRSTZrEdrRSKiSiFnkTfl2rhhy2Ck3QdEZtD2DBwpj4j020sNUyumnv2N2o+yyKYW/yZonnZrYmObnLap9JpaWETCq0pdm7GFrZarJjXQYikqRTZa1jvVCsRxboIWb7OlcVhef73H1QtJ2sX3L71mjDbYzq6fM8a4mi6X2jxf3qgtLp/PuyXRTW61ISdhNhdhTkhzkiFXMVSmNbbaofTZpP3cLH6FKlqdj+XyM0abZkItjbJ10vgYLeyKD8j63vA9qbXS9QNaW+ZmTi8sIdOGaHp9z5LODShJY1ya85qTJMHFiFYLOHl+xBippawMFOcc3dBjnWUeTxin14CEDwU5G8hy9lA6s6oWn67FGDq/AZxaaxtWWYXlYdWawqs1aH821l4a+EVCuTJR3lhPSit639N13QOAc1lrMcY1Qdo2QKVUMaoOMQhLLMcVkNJG2LG1ARHWWxkwlLpaMsBZDmZUaWvyUrp4CZSeoQejDQYjqX2U9m96/bNcv0qpltSXsNqsHngPlk57vdpSrS8fpRR0qdTm65vWa7Uxj/RZNlyoVFUoTcZVCyidG2DlKOUMRi9fFylqaaBT32m8cyjl8c4Rmzz48lwZLSy8xSj9A98zGqeVhIK1mtF7Cc2yTiS8br0+ZV2mGMkxCBjZJJWXj2WYvxz/BQSLKZ/3TH1mOFZaamJ5+N6Xh20DJGPO739h7l0yHVGgy9kXa7kAU5PFLZ9/BSzXZbXsoR/ccxaJOEruE3VdV8JU1EaG4W11UOoHRWhicXNmgMmxP/u9GdOA0guQa3l8JXDwEgzTWvYp6ZMKp9OJ2/2B/fHEcQzMIbV9mAvUY7lHmbPnYQptD67EGayBOilOp9TUBYq5+So7b1Ba1qPRBeMUu93A/eHE/eGAMpYueq42G6zWWKvJChnyttuvsxZvHTklolKkVIEokmOtiDmtA3lDhZyoKVCLQ5k2iGhno74BhqWcJdHdWowGZ3XzMD0PzhZZaEqtvzZmBZ6X05BzJsaysvyMNmw2WzabLdM0y+e3lq7r+NjbbzPOE3MIPH//FfenI4qKro6r6wYS0fYwrTDe0W02uK5DAnwrj3QkAFPp189XWl7uup7a/X4J4NP6oRR8fSGW811ZfM+Wf39zqS+3SK3P3/vglSi9bqa2ffhsxa+13NOWfV9VPohFfIXHVzUQFufEo8eWXMoapQrtAlXSfNYWjS7mg1I0xBypMREbKPHkac/93YxRipubjhgy42FkGDT9ZsvtfkYZxePHG5SCGGdSjCiVqRlCnqltspFiZjxIClsKiVI81okp8+l0oj96vNfcvZoQfCQzbHu893TDjvG4pyL+LJNSpBAlIUFrrh9d8f77L3jy9C0xPI4Z6wfCfMKsXg0Sbx9TZbAa661M6QhYr4mzaa9tGE9HSeTKDcTJUqT7XiYptYRz0asyFUfOFaUl+WLYWGKqdL1lfyvS1JLevHEvBb8c61JAFym+nfeyGTUG0DwXcg5UpbGdXyUwORXmaeJ0mBi2G25f7fHO8vjRFe+9u2eexAi1aCTxLxSGXprN+/vQimcDzRS5tKmy1ontzuGcgADee6ZpJkZh+dVS0IMYiKeUGU8zxplm/mzk+FvdvDFSg7bVehVLmkZDxaoU2EorlBG2mW43RqqRwgbVJLWSRBZDYDzNxJzpjKPzhkc3PfvbGesCjItEZblPygS66zq8twyDl8luEdNFra14eG280IWDZh7F0yFECPfS8NJYUuJdVgihtHVQ0F7YYNurgVRSm9oKu0drKXCLFnP/xTtGG2lktdJUJdTkMIuG/+5upKJw3hCD5bAf5Zi1KUEtMiFTWWSPw+DYbsVr79HjgfvbA92mw1pFr7ww0oxIQZeJXa1Zmuw0Y7VmO/QoE9nthAXlvZiH953h7n4khMTVznPV7zgdE/f3J0IobR+BmBOv9weUEbmeRSbox4PICo1SGOfFo0Fnyhxlc27+F4lKLY5SgnikdWK6b6wkC6FFduY66AbdaN6F7aYT5lYqTeqg0E6Kj94ZMpF+sHTOcX8c6QY5f6U0ajki79h1mrc++ZgwF9750gtSvOY0TaAqxlYeP93ReWHDpliIU+T2/ZGXzw/s7wPDpufx2z3H48hhTFxdWZHgaiSYwSh21xuMFllAmDKnfWC/H0klodt6L7nSWcvL+z39RqEd3AydyMSUwjvFFAIdFmql1ETXVWKWgioXSeOUwrYBj0ijdtwHnB1RuqfrDdurHrTiNAVOcxLpbsjkXCkhSnFgK3kU1pdWkvBptSStdr3DGk1KM7UktoOBXnP7eoQi+0KOwuKZpkQIe4xdZBBVgKgxYcLcmDeWGjLKarqNgJg5Z77uk4/IqZBiIiTxIsplSVkSNl1MobFge5wzhHlmHic2Xcf+fsQ6zWmcKKUyWIdzllACtWQShTFPaBRTKK1ZkCTTNEvEd0q1vYfM6TDJftBYPk5L0qGthpJnbvcz3llSqgy9kj1PV5xX+Cpm4J01GCeSaq011RmOU2iSao9SI11nOIQlNUmak5RpKazCXhtPtU14LTFHnBG2Q6mBWjVXO4hRC/CUWnHWGg2lhE1WskyjcxIgRwD/IAmOSuQcWkm4yjzPdGimk6Q9Vq+btCxyczNgimFOI9bI2jBKTPCXib3WknS4THXXou3N6u7B5PICKEKYL94uQSF1TZqUSbBCZbVK9XTRaxNvLpoU80CKcwbStEKYslw0SDKGZjFFl+ZX/NVqPTMocvMJWmRrIm/7l/vFPKgK2nta/J2W53DOneVKDdyQgebZI+wrPi4+M8sxEH0F8zTLER0WNoZuZckZhFitMr7CSyzNrlYKFsCv2RsY41pjUEQmC4RcKDWvwJMAWwKMvomL+a5j2G6AJeHZYo1tTXYDwrReiWSytpo5OawgU85B1okWv7zLR0mJkqROkUFwMyLvO47UtTmPIa6AwwLgrWCRXiSkIneMMa6AgMkGq+0FfUSOWeEM1i6v8eYlUMjEVB6EGAzDQIrpgdH9AtTJ05+BuUtQFc6ASbk4Bm9+FuXUKuUzVhjGVhtO84ykjFo6LyqP0phUqpyZlQI6FRKZmtOHwKYNtlgZQAqljAxLq179oBbJ3LLG0lJrtf1EcWYTluY7tzAlZW97A7hQMoRUSkKJQpJ0ZWECCpivWp2aSyGn2MIekAFczZi6XEsfxnRVLQlbvMy6rmveUoppOjHNEzjxVV2aVNT5dx+833bOnFEY5XAISG293LesMTjtsNqujMCYWj1VKkZpAf1WxYVazw/N363UNmTMC5CuGqj88DMpJLDAWbsev9SGGEu6ZGnDA/mjm0evWtf4+rF0bYb2l8C/AGIqK2BhFWmK5qxO/ZCHgmYNwkoQWD+nNizKBjmc6txuXTwEXDJtr7ICHF6Agcv7U/ohw0xe7oNPuErcOffcwrYLnKaZ+/2R/eEotVZepJrn870MlK3VGAVpSijUuh4FWMpM0wxK7D90qz1qXXwKwTmoqrIfZ7abjkePe7Y7y+3dyKu7gyh0xsqm79HW42xLsF/65VqxSixfVKnEnFuidBWriPMBFy5DaT4dOVNtaeBkvdiD1lsoNNBdWxnYi9e1BGeo84Gktnud0RZrHCnFByiRMarZg5yPtfeeru+oSjOFhM5VwEhj6fuemBJTmBjnkX4Y6Dsve3HOzDFRi6RLm83A7vqKt55cce2lXlpsJY2ayVVsRHI1GCWsL0UDxRc2mDoPydaF01bH5UMA6zdX9/mxAGAPjuEbD/n9SiniH4cShdpiQeGdlYDBtk++KSv/So+vaiAMFPu7E9MomyKLLVOT1a07VnssB7jkliyJwjjx1/nIRzYYW7m68sJWeWz4uq99xjBs+W/++j+n33puHnVMU2Ec92x9Tz90vHrvJdMpEEMzqK0Vaws5C1gUU0Y3A/GUC6f7SSZnTkAbqIzHma7zvHrxCqUz/Ubo7bbFOIU54TpNyZnHj7Zst47NduC4P3A6jnIxpUUbXqQBa9LGGAOnWRaOyxazsZwOM6XCaS+SOwooK+aFsJiuthtPihTONMNShQGVUiBMM7mKH9U0htXratmomxaFdezRpqApifyplILvPCWLHDHnzHgQD7Zc5EZirYOquXt1QGlJHRKAsaCUYzrFBzegUiBMmdfpiDaQMsQgMis55yIPqEqmRinBfj/T9zIdrlUYKaWck7KUEq+UzU4S6nKBOcjk3XnNdvCEMTO1TbqZiazHQq2edZWqBZQVg0TNZtszHk/CUlQLWi9MiBFhIygkAY5aG/gpzZ5SSiigVSQ+w7YH5GYf5oT1CtuJd5cxls46ihFZYtWG57e3bDc9cwyMR/GBefJ02xgiUBJYW9E6cTqF1RMJJaa7nXfMYcI5zfWmw/e6FUUW4y1390fu7k5MU6QUAbEKUqRqo6hJnssYxWGcIYl8Mc1C6a9Z0vQahkjXK5493fCxjz/h7u7I4yeenALWifeQmRPTnNBVYUoVrzab6LzHW0PvxQ+o846iAhtvSVlxf59EmqIU3dCx3Q2oann1PHJ/24BUVSlLDnSp7PeRUhXOGj765Amv93u5OSDyEqUtIEVaQ/RYjJZrlWl4DokwHonjPRjL9vGVRATUyjwdGfcT096Qn+7oumtQVgyym0TPD47dVUecpADpNxrrM9oaKrkxOKVoMVqTaiKFIvvJdsZ5yzd9+hPcvh94/9Utx+Mt9y/ep84bvulbP86270m5cPvyxO3rPXevR0rWDNtKCAnfOXbbHqUSzmqUbYWN1Vw96tFpYH8/c9zv2d9NhDFDFpp6zTPvfv5LUBXRKHY3N/SD4eam4+7FibsXR+5vD0yThJAswOiw6chFJEApV6oVcLnm2gJGNDnAMWeMmygqs80yaOi3jmor4XVg/3rP6e5IreCHK1KUfbooRZgLOSp8B10vsmttIGcBOIaNa2nAlZvHA3NIpCiBLLWRNUIs6ALOLuwRASlCzA1kAIxCtXtWPzicknAJbWTP358mjDdcbS3dINNKZSpFDWKu3ya5p9MkfnaqchgnngybVvDK3jWeJmqVoIgYEuMsgQTPnm3JMVF7ASxd5xk2G6bpjmnKTHMil4r3ls3QU6sMJWybEFtt2Dbz/9pSx0rNUtCos6+M9VaKQd18EY3marfBaU2/2bC/PzTJZZK91rYwCS2pm+IXVFq4ROLl+wc2W8XjR55hcEwz7HYOrUS2vjCOY87n5DstjOOYElRpHqiIBDcnchbZjnMKpS0xZY6Hwu2dJEt95NkV28E1g2rwg6HrBuqtSErtIk1bwBjkuvuQWu7DyhgJkAFMUeRybuoFQBHD61wbk0npxgCo1BJIVRqN3Lx1Psw8W77y8KtuHp4XLJqck4DzpnvjdxeGq75gKJybyKU2KFWtLJ/Lx8rsuXhrbzbwl6AasCavpSgWBR/GllgPoBJAkIX5VSRUwPi+3R8TvtTVMPpNzxyFSO+WCXIbX8l7F8hRPuMK0DWQA5ocS9iRJUeMlrpj9XltLBPxZxMpVNGsdcbyPhYwbfHPUq0zrWuKpnTCC/B0KUmS5nVpTmT6LtCHNCslC7O0XryeNsIwifNEmCdhSq7rIK/HEVi9nc6pa42BVc9smAXsMsY8aEDWJL7SJKAtARIE2F0ksWUJQ2iNt9GGrM/Ps4CzCwtnCYtYgLJ2skCdfYsWMPcS1FuOnbWWoR9w1jUgXEkaszr7OAnYIYzSGBNKLV5girgwpb7Cqjw/5BzQAGdnTJOknb3XlmtQkgHFjydX2WuVUYCh1MIcz0buqyT44ZXA0Pf4rmOaZ8zUjm8Wn6qiZG+VpOCyhshcvtdaMkUnAYkXwGP1LD4Dkt5avOtwzRC8lIyqFasqSYmHj2rd7eIr98HjIrWkaowdvfg2Nfm7N34FwVIS4HWRzi6prKVIqJYM76sgX7mgK6BUkxoK81abc2THen3Xs8+TNZah79j0Hu8sz18f5Hn1AnacwyLkOpS9YFmzl8fnzKg9P/Lae4ptTMka7FdK/mznVLEOM0p5cx9cru/2b6rKwPsNAHNdV0oG31obAcTfOCdGa1x727kUUn64upe7m9bNL6/tbaVWQozc3p/YH48cTyckGKSu4EcpMhA0SztYq/R9VWxbhCyWgYA2G8J8kJATBcrKMFQVCQQwRok1zgnmmDjNhsNpwnvDZujoN44nesPdfkSpgus1tiqc3bYhgoAkJbc1qzV4B3HxrZNr/01ARvAtkT0WY1BWPszKALx4LCEti3enUnJfVDmvvfYCQK9hCkqvHsjn86+EoEBjPyL7aN8PDMPAOAVR+yjF/jhBFRZ1TELu6HtRf1Uqp+lETeC0xSqNqRVHxtS01nXLQ6tKrjPgpWdBNU/BtuxqRdWM+hDfzQ9DvP5l+2SbXT081h9SPC2KR9WAHoUwG3PWpOLpfCWnRIkPLQz+VY+vaiCsVsU0ZY6H5nGlDTS63vn6XTDtJZlENoGyeEwgiWV9L2yGUjIxzVgr8o/jNGEsdB4679jsOu5uX6IVlGxIqRDGfN6ctEgLCDIxFb+NwjQqrBMacYwT/WDQzjKNAes0KUYOh4muM4Q5MfSNKqllcuedYTP0WL9lcy1R4zkXqmpJN0YvBgbUq4GcFDnL55lnoa3fuA1ziFhvOO5FinKe3knELFTiHGl0uqbRrW3SkNGqcn295Xg8kubEaZ7FR+2SCabkxq20aRtyow8LgL5u0qUIGm+tYh5FzjOdJMyA5gEzzyfClASccY5u4/G9p+aEdR7VGogLf2ByqeIngCSGyamWBkLRfDu0bOA5FY5pZhm1pphF/jN0knaXxahvt5NEmfee35NjQCvNsOlxXlOxbZqioGioYhDeuiGRN9DMGpXc+pdJXpiDTB+8kTDJWtFWY9zZh2DZREst3N2N+M60aYqTH1BiliwNleQviSl2RBIG5diNU2KMAVUL2iru7kZhl3WK8ZhQuhKDmMN6Y0havFjkxglaC2ilapHnUJpuaBNgA8ZZ8dNpA6S+c0ydZRxlIinFtHz+/e3IPNdm2CoTypjEKH2JZ64NBKtVGsVhcDx+MnB9Lf5KvqsMg2vMQsP1I0e9HalVpi9LouA8BaJW9P0WCmQS2gjgYJVhs9FoJaw1Zyw1KJSy6FqQBNT2gZaxXV1i72WdT2Em5USqmTIXrLNirK0kkatUhTEWZTQxBFKYCPOer/+2r+Gj3/jLKDmxf3Xg5/7pz2O7HuM7cpj43t/1Xfje88Wf/jwpRChD89A4G4E+eTbw3pcPzGHm5skV2hRKFb8MbxwYAUVRFaUrVRdQllQLfQdPdgNeW7SN/PRPfoHv/w//e3z2Rz/L4dVRgPQkjagMxjTGKZQWcIW2LqxR+E5j2xpYytspzkxTYBoTYS7CSkThvKKWyL/1v/w9fPbHPsuP/Df/lK5vEgireP3iju7miq//ho9i3FneUEvhdH/iiz/zDodXe1zft9RJ1by6LJpGqw+VaYoSgtBVkf34Dm3gcCfsqD/4v/oD/MKP/gI//P/6MVAbVCoo40hGJsg6V1zzwlJVfPZAGsEQCpve4ZAEvRQzw6A5HhMli7Rx8W9Ct0S1InK9mgHd1jcQp8w8BtxWZJpxFjP6aZwZrKQT2XbcNxuL7zpevdw3ynwmpcicZG92VuQvvrM4qwlBDGW9NzhvyEkRQ8Xoys1NzzwmTscTS6pdJRLmwjgl9ifxG9Gr55NikVHUCpu+Zxg6YhIvEK3FQ6OUglfC+sOwNs5zaNIsY9hstyK7LoWuc2x3MJ4yzgkjZQXCnKEgYFUMcpy63qGVSCSH3kG1bAYJVTDO0m1E5jSegsghGqBecoUMRlec05QiQxmlpTDNRUAv4+S+PgVhlnVeQNc4F7pOY60TRrFVIkW/aIwuq7eFmXBpgi1gSiWritZN9q2UDAbqAgAaKFLmlbaGJC16uaeqdv+UAU9MuQXanOVVy31YnavWDwBhH6ynBAirVZq0FMWodpHaLQyH9fkrZ9ZSFf+SuXllug+pLIWVfz42S6G6gBUppdVUe3k/wArunKWdud2XW+JmY2+UnFtCHhfDh/XFVzaEeZMNsjT7rRkuy9CiDRGkZjw3umI6vsgC61r015woObVjVLFmSUNrA9jSQhW0wSixfSitQV1BpgbqLbSMlenaPIUWEGwd1LXN8dyI1Oaz1kA0muw9BMI8r4wrpZqfWMmM89waelZZ2wL4retYSyKltbYNJeSDLedfAKu6enBdrqn1+Ro4VlQD+4wMdrTS6zFXSrXmsgGh5ZzwqJVeTetRD3351vO1AJxaWBOLd9PCDlvvnQhgu7yvxeUtXIJqNNCoQjUKU+R1spKfza0mS2UZzH64P9myAOS01vWYLkDOuvYWwIgGb7SexjbmUMqFlPPZOuSNYyyfW8IOtptNs+1YfKqi9CVFRJMrFgm8KSsEGiBbxWamno/hcu4XJpjIsOWZcorkLFYPQ+9xTS2BknuzOXew6zmT2ZVI+4wRZp6AWvJzzjgMRpKzY1iTWS/BSpRqaXwtrZ4irDIjNgQlJ4qFN9Ni1+O3XMuNUTJ0nk3fncF7zoC53CfNCvwJU/VhUuaDVNXL9VDPgCLt/Arj882lUmXo0QB6o+Ueg1JkzmB/rZUzN/I8SLBKatuHyKNpklrxplKtF3lwzh+AbEugBR/4OQT6oKLFEqfKdR9iYQ6SxJlybV6kpe1BZd0D9dm2rQFSy2tnqDO1Fub5sEok1xnKMozRllol4TnnIPWRlQAvn6Tu6LzDWM2TJzu8FRJKUYlTmSmp4rVYIIUYGZVm03VyH3eOoPIa4qEae/UB2y8ncpibvFCGr2Xx8FQP5afCTE0Y69uedTaBzxeDjEUWK6CnpZCFgLKuKbXWLMuj63u6fiDlV9zd33OaXEsKhRAEMO+Hfr2elFLkOUKsRCWhUyFKfahXo/vzvqCXM60ipTpJmlfynkJMUBVWZQRxvgirQXr3h3vUh2JjD1eVOv/sG1vFg595EyyTGbAhV0+n4mql8UvjgsnjqxoIG6fEPGeOp0guyOJtJttSB50Tm0AmzevUrMj/BjGCPh7FVyRmiW+9vu4Y55l5ntC24Lwsgr4XfyzXWdJUobYphKKdJUOpqiHpBYsC1Zg8yWBMACRdbrfpsAas15QsN6ilIMwN+tRa0XWWfnD0nUM5ScKJQcxIdSsABHip9L3IXE6HKHJRBGRYCrnpNJFTIccia7etFtUGKQDzNJOTaoh4uzSqoiIygFLFw+x4mri/GympMGw6Qlgo7BqUQYzcW3HQEH9NA4yUImd5Htr5CkE+t3MW602TxEykFNlse7R3oCveO0yLw9VWo7QlR4lfr8qAtigtfkhiiCmARdtNMY21orXIJ0stnMa5adgrzhqMleIs12V6aFZ9c4xFmAotXCC335GCrR2v9jqqIf25ispa1cUnRvhCIuHRjc0CysrNPIYkE+02DXBW1ohzFtdbYaU0WYm2jhQz0zHw6MkO16YUcSzEnDDZMAdpJMdpxruuJSJqYSalQkkVbSBMhb5zbR1GQhCqsDZiVq6UmEf7xjTrO2kKpxhQUa8SGkVqAJ8Uys5rrDXEnHBOUgplCivXoqRtSZOjNHhvKUXWg9aKYWO5vvE8etKhbGS7E9+pq92OkiuH04xFrhPT5D5zFa+VrIQpWciEONNZjbdLUw9X1wZVHeNRM4fK4T4S58DxmCRa/rISWPpKgCqS2cM4MkcB+0otmJToaqO9FwGRl+ug5EDJR77rt38b3/lvfAf9dpD3Vitf8y0f5Z//rZ/ktI/UlPjm7/kmhl3P7TsvuX//NSmXlnTUvBZKbY0ESEnUTLaLGCPnVFa/GpGLVnwPOYpE2XcGoyo3147r3TN+8p9Fvvt3fDfjYeKn/tZPoBRY71BKfOE2Wykau84yjjMpZ/qWjLnbeTaDo1DJofD8nQOnfaImtQKT/SCG3M4qpnHm1/3e78V6ww//pX9IP2jxawqJV8/v+PZf+Wm+/bd+B753xHlJ2pG96ROf+RL/+K/8CK/fu+fm8aYBEPWisZCbdU5ynOQ8K/E5qxZjZL/8vt/367He8Hf/y3+A3WwxzTCbKpPjJV0PpTAeKZRmg/eOw13C7qSYUt5QvMiZt1eV8ZS4ey1JciLvFlPRVBUaI3VDrlQl/o6qCmCqdCfm+XNqDDfVEgsr01EmlX5wDH7gsB+ZpsLhcCQnMcb3zrDbbug6Iyyi2tZL81xTWq7deYpQGvU/w2mcMVrTdY7DfmKaRVpfakUj5y+VirMCkMPSaEoTdJwyNtoGIlRiDBjrV6PTUjJzEMl6qQLC9YPc58Yp4zuPOgQ2245+kCCQGOTG1A8ebSTNzhgl0t/OYK3sw73XKCXyJd85ul6jjKFiyTFzfzsTRrnfagNUKQC1ToBmnjLKCDPcaJFo+96yvxUPP60dzhjmOXE4RbT1QnQOAroIALyA97RjJluE1goW/6/2/0ur8qqChbwgDcJipquaYf4i9ZWpsV6YTBeNs8hHM6FNzS8lVlrLcVA01jCtsb14vDnBloZQ9pGUQksqE0CJ5by/WZ0qYe7U1jidqoK6gEdnud3CuFmMwpfnWphGi6dTrZWhH9rwRdgewmyV+zVV2NglJap2aNfuscvwrXk2LayM5d0uckhjltdjXccPC2t57+IHqVaGiTZ6/cCXTW/JZ/Z3TgKELebTZ6bdRROwMOrafUS1/1znWvMqMlcZcskUXiTFS1DCRfKkWn5//evKumgfRvadXJjn0NhErRHWsr/lFInTtH6eS5nhJRvMGINzTlhaF6wWo8/g6MLCu2waF8BrBZzShUn8BRoTs8KIkab4eTZW2cLm/LC1t7xPsZc4H4/lPVsEWFx8wWKN5PhQ7pmbFcUCcvKhfkgSTKGbzHYZhhWj0RfhNubNa+PBe12A3AVIFWP9il2B3zelPAswq7XGarNapBitV2Dgw1gPC5ixGtMrJfflIvfR5T6ntQEnQFhKcZUuVRpg05gxepEdts+vq4BtnRO/xdLCKPIiu9WGzWYj/qsLU9ZYKmrd82hPZ9oQf/EPWwz15fsaq+S+kktuBt9Sjy2fa/GxU20NKGPQ1olPp/fCw5tnVAgPmYPtsawv3RpqZzSb5iN5GkNj37X+Sc7kxTltLEkjPd8l6+0sVbzY7zhf7+3/GtjQQCu1+DVqasprk1+VeHdRFUVpYfPV2kA/6XmUErm17AEFVXLzFzxLKAug8gf91B6smxUfE5ASrVZm67ou169SR84hMs+B0ziTmuy7VM4MzxWgfuP+o85HU/abhFK5MdEWybzUX6UUtHNY01OVsMHmGEAVAcE2HVot4S7CNLNOhnXOaZhlmDNn6ekdlq3ftPUt66l3rg0kmmJISRCSamtbhkRn9qAxIqPVxn5FlEdkjwmQ/Vy1gWMpdWUsLjegWipVy7WSdWrDsIdg2HkGZej7ThQ47dopuXB/v0dpxTgGvPPYNZxBenAT0xpcEuaZUnpcIzcs1kpp2UsVOA2oTMiOUvQaWBamIKE0/nz+lvemVWERfy6H5Suxs5Za6Xx//HAAbFkvH4ZlKwVKSwKu0tJrKFVJ8yw1zC/h8VUNhL16dUQrkbettG7E3wXVMJ72b+32KPXHAx+ryngKjVEm3hfDrsM4R9XnzcG2hJ7xOLPZbvCdJxxnuYm2Aq3RnVirnHbDtMaSq8jTQkhstw6ta0OxHdoKC6wu0rwCqW2E1mqKKvRbS0mFNGXyUVIsY0zEmMXzqS0pBXIBZaE9o4VqabynlsrpMAtDRD76+lDtuNWqyFkSZIy1KxC2rE1tjCTPVIgxM47CGnDerYWaNppcIC5FT5tmNUxQyjstxWLXOYlu12cTVusMu51sYCWJ1IDWEIZxJqmZR49uCGEWTxarqCGhqm7v24m3URR2U20+XYsuXrWpc6lFpDJFMedEjZI0aI2cR2Ms1CYBMGCqNH+nUxK6eW0Ap1mKDoVBph51+YwNQKsR0BrTKNbL5zXW4JxBW2EsiOdTIReRmTlvhHHTjMOHjcN6x+66ZzyID1BFoYpinkUu1XWWeRYTWI1iOgWmk2jwSylkp9hseq6vPd5q7u9PWCPvL8yZ7abH2IoKC8W7+QPZc6KJ1o2m2kC9eU5UhGX4IFpXVbreMGw7rLKEuwNaQT8YIhCdRCgvnhcLA00ZjfWi5dcGuo3h6qZju3OgA8703N1GlDLUHFFVfAZ2ux6/TPOy6MR1u/EXIlUlmWwb0zytjLCaqqGMhtvTkfv9xHjMzGNphuCcRyVa2HZVWXKYZYqepCBY5LeaxY8kr9dPrYoSM7VOfMOv/hr+O//eb+XuxT2f+YefoVL5yKfe5jf9wd9ILfCP/sqPSFHJUuxCTpl5ioyHidv395zuR4zVvL8RT504Rd7/4i1lDmyuJClzPkXCKIXccNXRbRwlZm7fv6MkmG877rojN4+u2W07udEie2nOsre4XEhTIIxh9aNxRlEypBgZU6ImjaEw7UeKyqRQ+NJn7wmTSP66QSaDWiUJy0gXngJKnmczWIyFeYqcDjObRzve/uRH+MJPfo4v/NQXZA/Smkcffcx3/Ou/CpTiL/9nf1lCIsaJ02GkFMU8RnLWaOdQLUX17vWe6XCSLJCaOdyNqw8GQC0ytSs5QgxoNZCTw3VL01rQVmOdFDbWGnKGcYxse49xArxoDTebgf3dSYYJeQHIEf+b0iaGBWGFKfHByLkyzZla4PX7BxSw6TuubyQ0Q2PQxa4gBbXQbzwxZuZ5bu9fgLeh7/BOJIohiPeLMQqjZTCjlPTtsRRCECbU6RgEaLKaeUqUXPHWEa2AaKkUUsk4JUzVmqX43AyOVANjlAS7XARMV0oxzTOJ1Ly2EjFUcpJmr1gB2Y2uEgSiRe7UD15M+b3lsJ8kidJYlK4Mm45h6/BO9qBaKjEUJg0lK8ZT5Oq6p++bF1jVHKjNr7NJRxogPlMYJ/EXy22K++ixGNNvNiL1PO1nwtxsAHLlNEZ8Z+kGi7Ji2kutWOuYQqD3vnk2IT5CzWyX2tJmlaIqOf7GmDXMR+71BZVrk4423yPOEeG1SgO5NE0r07CUVi9USf1qe/TZo6yZbiw9SCtwLx+lDWikVFoAqsKi8ZVG8dKD5o2mqFTqArBdfCs3qf9lcytT8LwODpcC/ZINE0IQJgfncIBliLAw0nJKzA1dWp5f3riV4qeBE8JGocmu7JnVuLzVpUG4aNKWw7X8RRoe86A+efD5lykeIinLKS2Yofi2Xpyvuvilcm6QS2OPe+9aM5uasX9ezZgXMELu32llg7WPsGyjcj6LyLUuj6kwRyV4IBWpEZQ1GCuDrVIvm60mBWwsNQDnmnG5sevzLudjPecFWQeV83pqII73EmaSVFrXm23+qAsTKxaEZd68y6yx4qVkWIHHS0noGyeBhb2zvOYCvAKoxqLIOVNjPYMnrcFe/lQ47/kXT64WwLF17hqFkPw1tcr9N7XffxM0WM7R4hO31KKlZGIp6JIFEFR6EXScX7mB5g99nN4ILLgEWpSiIIEZy/fy6pcjrNFV2oyAI1qfGZgxBgHFVjAjrmCaNjLINNpgtcFbj3PnRD6RFZcVoNptB2rODbRqQ3UaQFJkbLf4lVnrZLhtz3V5rbUl8mlSAyBKzS0N7rwPpiQhNwuqYoyl73r8MEgPVyu0RMQYoxj958VjTeSL1kqNa1TFajFQn4MMgc+b5grZrMcaeCAVTjkJq2e5JGpZ3zvt83pt1tpDUoUrS4ellUZbKwwwLkBOwTDk/i9dvwxSSkEVua8szy+gQhG2uVFSH38F4OuD6/RDAGfVnu9D9r6cM6dx4u5+zzhOMmzPlZAyMReRTTZfQd0sBaT/u9hvFBizXJMiM5UMHrO+/nINGu3QxhBzJBUJusg54axh6ETKKox4jfcKlOx7VAm78tqhiyWmwHE+EmLGWcdAx5QilUrnHLQ6+BIIs84xno7EeWrs2YyxDp86rBWPuoXk0C7b9VHaYFqtNg0aWh9l2r1+WS+2AdSmmeYvjNbLcyTXU6HvLJtNz+NHN2itCfNMiJEQggS7aUlZlZqzoqN4rfWbDmMsRWu2nWHj1MpULdA8tzLWCXMZwKhMroZa5R2Z1r+btocve6OquX2Vg1AWv2c+uGdfLDH5p/rGP/DwZ9TyPz6wTy74hZAojGuYQIn8Ei3CvrqBsHGMXF93WKOpRSafWTXMXQtjr1S9XnzL9PVcGQJVs9+36GgDdjAMmw7jDTFV5lCJURGjZporIYykUjnez7x+fSA0TwGFYilPpLZqxqZaiYF31fjBEObIzeMdp+OJSsUPHqUN4ymyTJ6oAnIZI42H1hXvNVnDfIjtplnY349QDf1gMM6RQ2I8RcZjEGCiFozSOGewVhhjMZQGVJWFOIFqtEsQiV0u6rI2lJ+pFdWSLI3VTKNIE7y3iFQsY6zFafE2GyeJKK5tcyhKo42MgxQiH1xAFGPMmmizRMA7Z9nuHCnAPLeGISSM8cwxYp8ZDocT1mtcAj2Jn4EqItvLJVNSQlXRwtdGCS5KImFTauTTXCELC2uOBWMrwegmR7JYJd8zVi5FY00LJhCwMoeI3vizt4dVJAy1eUJUlNCHmxzAbzpSjLgWrKCMohsczkvTnrPIXbadxTmNHWcAhsHT94acE512bLYe6w0pig7d+zYJCYnsW2JJqeQi6XApir4epchdYXPVsb12OK8YJ4VxElgQQyaXSucM3dDRbwzOeQl/SAljDbUkpmnG+U5kKknMysMsTbRphcc6nW1+ddYYnBc/kH4wpClLqp9bIqNp2v9MyoXOOHpV201H/H/Q0HWOmjXOw/3tiNGVJ08HSlTi1aMU2lnKUDlNk7AftZh4D1sx1E85462RFNCiyJPleD9z+2riuA/EKMdukcrIdS2gttWKVM1KvQ0pozHkNVlNJlbiJ7KYAytSnLG+8Bv/7e9juB74f/yxP8uXfuZ9rFV0V5Y//J/++/ya3/U9/Njf+NF1ql+KANphTuxfn1AVut2W67eeEKbAuA+MpxMlV55+8hmH/ZF5DhinuHv/hB92+N5zuA9Mp8BxP2H7jm7TkXPl3f0dn/3Sc56+9ViuV2hsyMrh9ojrPJvrgUdPdmhriHNg3E/EcUY7hbKWRx9/xsvPv8ejjz3Buo55Er+ClALTlMlJMWw9H/n6J7jeM40zaY5tX1Foq7i+El+rGESiszx+8m//BD/+gz/KsO0YT4HNo2t+4D+64bt++3fxg3/6B9nfHSgVds+u2FyLd9Z8DLx+5w6FZ9xPdG/vqIPjdJoYrgeGrBlPd8vOhlKQ48jX/7KP4TvPl3/2XWLwDNuuBbY19k2AWkT2mELmUJKAM34B8zO+1/ixyRBPmZxl7zBWYQuUJIC33JMsRsu0e387sbWaXILcf6xmt3WN5SyJQFUVTunENI8MG0dKAuaEeWYO4mVnGlM1pUyKCVTBOS+mvhRqFbZuSoW7u4lS4fbuxNPHG8bjhLSxBtc7Yoiyd9RCLAXfxsUSEKKbL5lpJsZyszC6gtLMKTHnzDQlYpS9fjEj773BWkXNSmT1uRmZ10yMtORBac6mOUrh5aBWK5P3apimTMmRedSMJ2EzWC9S/JQiw1YS57pOS41gJTU0hSxgXyyMKeEGzeA1u2sJUul6B1Wx2TnmIKbZc6jYqgmhEOZCZySOPmforWM/TWz7TgZQC1CwFgKsqWa1CDtZ2dZs1NoYPElqAdfRkBthUyEgjmpMjFoKVQoE8WSrWYyx27DiDDippX9gLUjqGzd0GgDSwH211i6yx62Nf3ss0kdo4NZFo7KkMkqz1GwAWq1Vmont2jAXYefQZnEL8MLys7UyzdMDgGx5X+eEM2HGLVN7AWSWhrWZXCcxBFZay/p3vkkPLw4LZzCOVjMs0l1o/pxa4bxHa2ExSxWgOCsNZF2rIjL8FGeMshfNkOKDR/58TEVmZps5vqJWqR5yTGjbrx2AUpImuJyDlVXWPscamnMhTTzLb2h+OIlSM0pbrJO04a6znA6H9f1extIv4GHnu1VitwJRijMg0w69uQBMFzmd1HYN0EgLiHd+7gUkXOwyLuWCi8fS5Wteron1OK5w2plRc/lYGGwPvZ3OyZirf5gSJo5tCXpnFks9MxkXbEKpFXS2RtLgQjOizm3xL+xN234GpM6xnMGTnFN7bcXCHj1fdnqVVZdaWdIfV1Causo6JdFQ1lpMCY2w3eYQBKBpIJVRzfWr7SdKa4x16BRRSdZXSBlUWde/MPpFFus7z6br8UYAgpLbGisCGmkt4FLf+dXLdAVPWXoj2qBU/iLvweCdX9dtKQWDWfedlBMxtRTQBoSVxhxKuZyHtd7h+w7fueXKoG8SzhCCJKlHYdB2nafr5DVFki2svpozMUzUImEuK1BRHpp9q3bOlu3H1EuBWJWbPed9TQYKdR04yrUra2VhEqt2rs/PvzyfpHuqheXR+thaWeXg2toWAtC8/VRa7W6W4/rhO9HlZ/qQf2u/VdsgtFbxr5vnxP3+wOu7O8ZJ2GCp1AcSS6MbcIOAnlkrkfe1QQYKdC0oMqVm8X2VzeX8Bkpu9zgrYVskUJnF7kiug8XoXWGdoR80MQqTy2pDLRVjOnR1KK051plTmok1tb21MIZAVYrOu/O9t+0DznlyzoQwt9dq++nCsK0ZMeBDaqyLtV5LIcWI1+ewkEQ+3yPa+S+qsZGNeHyrGBuuUM77W7OM0ErjnWW33fDs6VM2my0hzBxPI/vDvr1X8XV2WtNbx6YFoO12G5yRdPPrjWM3OPrOAzLQp1bCLEDY8vAmMqdKafLITe9Q2q4sV7kXX5AGLh4fgqGuP7fwJb7iz7yxLlfOkTr/gbreH5bhlvfNuzbEr/ykF4+vaiDs0eNr9vcj3jtqEX+n0op9VcXTSLcLTqFWA1PVGnVUxW8cVRtwGtNpNlfiAzZsOowyhPnIeMq8eh7wGwGhxnEmNn1yVQtiu0xyxQdg3VCUkoQeIOWI0pV+0zONQbzHtp7pmIi5EEMQGZwXGrBcKOL3Uqi43mAjXF0P3L46SMHf99SsxM+jwOk4NzN8AV5cu0FaK4CEteq8+kA8XIzC9216EisqN+mAWko9BWoxNjWcjhM5F2LIXN9siVFSzkSSoLksVpaNc9FPU6skeRTxdru67um8X5lYuu2BKScqtp0nRb9xhLkwbHpCHNarQDth6znnqDkCmTCd2s30vHGvU9tWFFZkal2LwjTZRUmJkCJVK7RTuCxAjXNiMl2RadH19Yb3XxxQVDoLQ++kwFCKVBXGC1iCUlTVEqOqTO13NxvSFNC6Mh0Di6q2tkmZaVJRY4Ut1w9yibrGXDqNkeSFkaG0mOGnMbTpFZICWnO7UUVCSKQkm7Sk1RT8TY/vDBnNNI8NdG1mzc2Uv1QwTrW0PMP9PEGNGONJpTLPAd9tUc3QtTQpaalQU8abc5GccuZ0mog24oZKOmScUxiLmGQrJeyUJkkTyrV41CyNk9YVVGGeEn3XS2PuHaiJWAK7Rzum28ocMmGMUlTJBU9FAAOlFNpqitLsjxM3zmAT6OQ43MPz9yemU1oldbJ+z0X2ssGGOQizoSVTLutccG9hReYQ2hTVYde1X+g2jm/81d/AT//9n+Hn/ulnefaJT7EbPO98/hf4x3/5R/iOf/3bKXntoVdQYzpMWGf5xu/8Jr79N/8KNtdbwjzz8//k5/mhP/ND+MHz/X/kd/Pjf+vH+PG/+U+wrjJPhe/8Hb+am2fX/Mhf+WGef+F9nn7t23zv7/n1PP7oE0oqfOEzX+Rv/OkfFAZOkoZBJJzSvH/kG97mV/ymX8HHPv0xtNbEKfDZH/sF/v5/+fcwxvAN3/Epfuf/9Hfyt//MD/Etv+5b2dxsCVPkH/3lH+HH/tZPcHh9oLvu+dR3fD3f/Tu+m0dvP+Lw+sCXf+6dtj+KPGK7Gxoj4mElViu8/YknfM2n3+b5F1/z3pfv+cLPfIFPfscn+dinP8aXP/Nlvvl7v5nv/h3fze7JFbUU7p7f87f/3N/m1Rdfc7w78Wt/93fzbb/hl/P63VfcvP2IL33mS/z1P/WDy/aMsZpPfOop/9b//AcIx5k/97/7L5qXT0usHQu1aJwv5Ahhjm3tShiC0TDOE9udRzfDdynSLgvaBdioZKRp8NqhkeKRkNnfK26edNw83mIsHA4jw8ZjFYScm5SpElPh+npAoRmtYlQifSq5SGpjFhn1wkgSbx95r9ZYtAqEMDHNEyEGci1cXw0o4NXtLJ5optIPXlhlpVKzAOHF6ZYQqphTRLvGWDGaEKLIsNIBY0wDjjK+a5PQnHHGsNk6jFXsjwmt5efGaaYW0MZTa5AmSElUuveaEgv724LrErVo5mlmOkngg+9Eqh2TNKHTODFsr9r+36byC5DSDML7QTPdZ3QV5u3tq4nrJz3jKbHZWq4fD6Aqh/vQ9oN2Hc4J13doY5hn2FV97n5gLQzP5/3c2JUiQgdz6SekFCUmYpobaN48dRbaQK1n36t2TITpEalFAjG8kz00l0oOwvhxRlN1ad5ii4fmufk4X1+1mXO3+8mF59elIbvIv87eTsaZlV2Sc1mbRL1MhrUkBJfWyKqqzolvLZUQBDzph541gbJKvbHIo5Y64oGvl1YXIEo5+3JdSOisFTmeNgbfdRjrsM5Lo9hAs8oCjrTmLn/Y+FieyxjdgIPltUHQ7Ha+W9poiYHQQB3bakxp5usKFj30oBIg0LombylQq9RSIiaTfWNh9AibHLFwXZgmK4MBFmuNygWAxPn8LUwo5xz90LfBkwzt5LOZJuWR9+acWxlxl+ypnEVSuKyJy/W0PBZGntYap1wDE89srMX4XhjwBstDX5llPeR8fp03ZZeX0trlvF+yKFapJ2dj/pTSCsqGEFZpY0WYu7139N61mqGeQehSP/AZtVZ0TpJdfS54a5iafcHCtlrAgNrOQyKt1//5mJ593RQLo1Otcud88R4vH6XtDwJcS/2cc+Y4jufPT0vJ5AL4hRa0JHKsVWpYJAmbN37WNGazd5bt0OOta3tiIsyRsnalSsy5rUg+L8HGM5An0syCIqEwC4CtZZhdETYYhcb6kXvPAm6jpHZf0jOdSDLw3jEMHd5p3AUj0Lme2PqpWsAZizOK7dDTb3pijG0PlL0gNI89byzaeTKy9y/S7cuHbixea897/XLMMwKkLV53RksPZi6GxFIiV6lTG/iTkwxGHg4ykBCDVeq19FdnNcUi05RQKxmgtrkJK5vsQ4CwryRbO8vslXjr1oUpWIk5MYXAHGZCiM30Hh7mpan1GrWKNjqolGKkB61QaCEeLWCsLp/3jYdcu45CQhmLzkXY51Vqic45SjAUrdAbGiCrmMaAc1ksk7J4J+UaKTUJuaKk8/5V2wCnnR1nG/ifM4mAdZ5+2JwHXfUNAKeKnFGAvIs9uUnGiz+znJXSAm9dMEhzzqSF1W1MY8pnSUKngm6SfXX2E+37jqurHV3fodDEnLi/v1/Tl2tOXHUDT28e8Wi7bQqlwtB3XO+2XA+Kq8HQdf6BbPnDAFGrg3iFlfNQamGXqjUg7rxH5bIIH99gJC49L/9qAOzyvVx+XXBSpWTN5aouvi/DK+cd6pQ++IQf8viqBsJiTMQc2Q49V9c77l7vycfxXNjV81VZAW1BG0nn6QZL1Yq3nl1hPVivULrgO8N2N9D3PfMpMU0SaxpDYb+f2Gx7Xt/OaARR1XoW9kcVc9QV1VBtI2mFSUpZPHoGQfz7bYexctN4/eK1GMRXYT1No7CWnIftzjBsnKRGtKIzzakZKcoFGUNmPI1opRmPYjg+eC+SGGvWrzIND2tSxfKoiJmqxPlKwVlrRS26/iwXuFYihzRzZpoCN9dbjNbkFPC+k6YqSzy4FEBL3LCch5iLmBQiKLr1hpIKV082vH65b14DBW0tvnf43hNnyGUGDJurHts5jEvc3x+5vz1ydbWhpChypdqMNBEkYZGUVNY8TAHq2k0mxowzurGtOu5e3rfirra8HJE2di16NqbK9c2W0Cdevz6KyWMDe7QW5D5XjXee3cZRK8wxN5mrjIuMhe2TgThHjvcB6y1d7ykl03WWbpACrOuspNyVQs2VMEdOx0StiuO++ZnRJEamkpJsvNMYCamgrKYWMVdcpaFFyv8wRwqZ4z5w++oICCB1tRGvl5vHHc7LlLM2xpfvNEkZYkzUAtZ7ck5Yb/CtuA9RWGghBmw7tqUowikT58xu57neeo6HCWU1V48tJRlyLJxOiW4w9BvZwGqVyHuRfRlKzgwbx2mMxCKSKVvblDlnvviLrwCF7zpCCFwpYaB5s3gGFY6HmaurnjglTodIP3QQFMyK5y/veHV3ovMG1SRkMrlcbt9SxB6PJ1lNWoqlipjhN1K6SCSaYauhRXFraWyrU3Qbj+sd7/zcu2KgiWWcMjdvfZy/8+f/IT/0Z/4Ow+YKrd1aFOQgKTDf9D3fzG/9d38bL77wgp/54Z/m2See8m/84X+T/cs9P/TnfogSM5/+rm/mh//SD0OKfMv3fRvf8Ku+gS9/5ku894vv89bXvc3v+qM/gPWWf/Y3foztoyu+67/7nQy7gT/3v/4zrN4zFXLIfOKbPsFv+APfx/Wza37un/wc037iW3/dt/Cb/p3fzLgf+bt//u8w7Hoef/wJv/6//xv4yR/6cWqu/Irf+iv5bf/ub+Hdz77Lz71/yy/79d/Kb/lDvxnrLT/3Iz9HrZVPf9enaR8PQKTmMZEzrOEEyB46T4nD3USYM27ouH56RZwjd+/f8eRrnvL9f+T7ef3ua/753/znbG82fO8PfC+7x1v+qz/xF3n5zvtsbjZ8w3d+I88/d8XP/5Of491feHdtmlHw1tc85X/4f/h3uHnrhv/6T/zXeCc+UbXQAFoAKzL8IAC772G7c/iuUsrIZmPFdL1Urm48r15ppjG1ibh4tBkLBAktODc9Hb0XGW3Omc1mEFo3icN+FMDbVnTzF6s5i1SchNaJq12HVXAaBXgttUg9oppBsZHUsZQrCit/VGY8zcwxYaxi03ecToFxjFJANPmh84arqw3TFEgxEYKS9GOVRYGmFExiwCupb5VUMqZUVA1MTYK/2TjxNKziX9n1jloLb711xTglXj6/ZzpFCnr1gDFefIN854U9VmUaPh4Dr19OHPczKMX1o54tlpzlPmu9wXrHYT+Kz4guHPaBeTrIXtt1sv+rKizpojgdJmrxTINjMzi+4Rue8oXPvqZm3+T4cm3nlMUzMVZKFibDu/s9H78WM95lmq/qcr+BhVl1LrabRF9Z8VGriHdTjoQ4Y63HKCON4FpOtHqiVArC6inNSFgajUU60wA4LU3LMgSsK6r+4XVUrZXUwCSxltDnJr0BBm17a2i/APRFtwbuAlzzTsIztK6rz2nlzAwRPzZh9tZcVznduvfQ5JpVr5KrJT3SNQ+X1XemFNJ8oiQtki3XksXUWUp5lsjV1YxbqQvfm1bI00Cny0O0sGHUslGwgC+N9VYK4rXkqMzt79I0q+bJKsc2tyGae3DMlRaAwlqLsZY1fQ6FdX6dhqgma5a04bIyM5ZeufXJgAydYs4ry0DeZ21N2wKcLcb3jjjPpFQxZvEoO58LGV7q9d8WYG1J71skhqscUS+ebnI+lvW/vGZMiVyb7LOcj6d4ZEpdtoAei0TuzXTM5XeWBts7vx5npRRd363vCyWWAovfWEgBWy2++HV9vwlunIrcw2Mu7IYOZ9WDz76u0XIGAJf345USQMwYcq0opJldtHClFGKO63NZY6mNbbywnmoVH15hnFnc6q92/vMBVpzSrcIVIDVnufa89/Rd146nIiXeWOENuGk+umqRDqszG3O57pbewFsnQFKzTVkAGPHzFUuV7XbDMAyU3KSu2Qhzq/lVKiWp2tI+V3Ix4n2FeCdSlFhd5ETKSZhcUSxYjF2sWRKxnRejJIlVEg9tA+FYfXtT1U22L+zamuXzxRRhkvOS2xBQNx8W5xzVNDP6WhsxoT64hs69UiHnDwGDVV2B82VQvigEQPZQAQlbYiJn8CknCTySoYBllZ6dT/r6VSm9sjGN0WT0CjouE115rsXqofUDl+u5nvcIGRColaFmdIMna23+ZIus9Rzisfg3pravusb4XJiVtqn0i1rWWbtD5sZB18JUNOoMxqwPbfCuJ5bFf04DFqNM84OSYfzW76BmOidJ1zEWOuuZjiODuaLYWQCq1v8mCkWJvYFur6+UkBfQimG7YxyPxCCBZgvbtOuGhj3UB2xLOdBiIl+rXU9RhXVwYJ1q4LgRYHMhjLSvS/DCEgJTGsFBt0HPUkYs6innLF3nRFJfYddtcC2hu3OWMk30xrD1jtPpiHNOGNlh5KmNXPcbutpRUyQrYdwrpRg69xClaufbkDlMFWcqbv2IS3FwgYLWVsd/BVnuhwJgy634zdP/ob8vNUCpEIplKhaNSHJ1G+g457E+fOjrv/n4qgbCpnEixUR0ic2m4+71YV1Ybx7p5SLTnXgP+d6x3488eXYNurC/vyeXwuOnO4zR7G9HpmMUEMCLAbOJmsNhoqSAMY4UQRmDMeJhYpvvgtZNNhfzSr6SGwbkmJjnwGbX0XWGeRSwIcwZZ4VRskxgnddsNgPUyjwnDIqbmwFbFS+PYno/ngI5B6yHvnciV1JqNZtfplGgiHOm3wy44UQ4nc0Ia67Mo6RvrMaYiLRUtZucGC0bMdpPmSePr6A22V3zYgpzbBJL2eS1Uusq1oo2NUkttrtSUxaT93EGamP9KGLMLcJWSVJFSxfqNx2ut5At73zpltN45KM3H+dFeNEmTmdE2hi5sebm/KeQJLEClBRJRdI2r66u6PsO33cc9keKqjgN3WAZBsuw6fBOZEjeOoZNz/HuFZ3VxFxIIRBiamyWAqVgbUdVEGJsIJhIDzcb8croB2HmGTtTlRy3fhBK95KIlUuWpsi6ZgJYeflyZDwl+sFSq2yEIQQssiPlZo5dU0C3ol8rSbUruZBJWG8ZdgKsTlPAOsvN477JnCSBrBtcMws/x3uXrjCdAqfDjHEOcYzOaG0ltUwoB4SYSLGQUbg2EQ0hE8fMpquUIFOcYdMxF8Vma7i/m9F6lol6SdRq0aoydKYBeYbFq9gohU0GVUD3WtjIynLYzzz76A6lFRvToa2hd9JEz7Eyz5VxzsxeDHt7N/D+OyfImpfPJyiWzdAxT2EFYpb1T9WENyPGkQkdtbDkz+b2nSVZSFhguTVgEgDwyW//Omou3L24x/pB1qYGiuPZxz7NnGauhx3vfPFn18IkpcLNRx7xy3/DtzEeRv7C/+kv8Pqdl1hr+MS3fi3f+du/kx/6sz/EZ/7RZ/g13/9rGa4H3vnZ1zz6yFNKrnz5Z7+EdYZv+w2/nO2jLX/1P/9/88/+2x+johm2Pb/iN32bFDmNQVmqXLvGGD7/k1/gyz/7ZT7zDz6DNZrP/dhn+YP/2/8Bn/jmT7TrSk7MP/yL/4C/8af+OjEkjoeR3/gHfyPbm4HHH7vhm77703SD52/+3/4Wf/cv/F2UNnz9t389/4s/+x+tjeY8BQqSrCvm2HLT73c9+/uR+5/4Etdv3fBrvv97+Kbv+WY+/1Of573PPedbvudb+Mw//Ax////5D3j+i++Rc+Hq6TVf98u/lm7wMnGtldvnt/zwX/ph/tb//W8y7PrWaILrHP/en/j3+cgnP8Jf+N//eX767/4Ub33iMUrLNWOtDB9yrBQnfiWmsRZ3V17kuhiZjMfEPgeMNnINFNnHFr8FpUVKrpUWaUgrjP1g0MZytesYp6mlqtVmeC9Sc40WADsnXGcIcaIfLGEUxs122zNPkWkMaG0YNpaut41FllfPxHmMHO5nJAzXUDPkWHn+/oFhozHVsdl0HMeRrhP5iOsU06TJqXK7n+EehsFQc6HzhpTqKi+yTsD7l68PaK3pO5EU9H3PMPQyUS6VFy9f0739GK1EOuq95TjJPenJk2tOx0CcK69fHnBtwGSsFJDOiaS5FrnPXF9f87lf/CLXTzu0NpyOlX6I3L1OxLmBKF7T94bHjx3D4Li/mwghME8CQg4DhDHgrJy7T3ziET/zM+8R58KwGdBaM00z05h49FiSNJUS4OHHf+FLDN+44e2rrTQzjYXTiEcCUDYPIZmC1hUsr6v5eWONtu/PMeGtYR09A5Cpua6MnbURl/JkfZRaxRhXL1dnPRekF4XmZSMUswACRhswYLXcU6yxwubKTWrLufGv5Y0it1ZqidD2/dKYKIsfFAC2Sd7UBdBSQMfmBXTBuskpr+yjpS6qiBl8bgyRheW0sI+992w2G6yza2N4DglYGlQaQKdW4Cm/+VlovlxaSeBOk2blfAaJUMJcXoAxpcSfNC4NZcqU1tBfyvUWgHEBjKxzDfA1zFEYh8p27dQLmKkXg+zWPCmlmvlC+0+x+iWd11hd3+ti9AyynwybHu8d0+mEsRbbmvqzSfX5vV4ysRaAMWUxXc5VahVd9BpSs7LzWmOz/G7KmZiSeAe1/2QtKAz5DDiN5xTEhbF4Kcv1zq9yTeccVQk4B5zBjmVtN4Qhl7NJvu89tlk0pJAuwgWgiwIcjzGx2wxobSlNur0kgZfUrlvK6lu3rgmENSWrTaONE6CqnqXFJZ+BtVXayyLhFCaxMxrfWFi5+b4tgPD5cqvtHqJXwJLKyrjSSoChGOMqUf7wh1wJWreaMakHJtPWW7x3dNbijGFJwF3BZi0NefIeqAzDAFWuc111SxQVdrWocZwEgqxSMUVVloJp61xAqRDD+ifnvO4lxsg5KsBcClNK7Kxbh+8LWH4ZYLCEPdRSCfNMTJFa0jkZlSaBNlqsS7xjbrYkch2c148AgGaVVYoNRl69H7WS/cQkGaabdszOa+S8CdsqyewLmKK13FtqkL5Qtb1Ta4XVHhZmJLI1pHJmx4kkXLz9zuEetOvijTNey+oxuawbYe8uQN9DRELALmGVA4Rc1mtuGAaMtYSUmZMcM2cMnXcNrD/vv0Yrcj4nZSoWYKjZ5LCksT58v7kUvBKlSi7iKdt502warHz1I5uhxyG+4ao6agl09YZUNffjRNcXrLdcb3q8tTzabuk6v96jYozt+Mj6y23QDrTETrk2jnMCEsZ5+j4/2Ace3Gfal1ILOQaMrmgl4WcKWuLzw/3ROcvQiY9XUmfLpDcxIms0Q+/QRmxjQggN9nDcXF3xaOio08hnfvIzHF7fEYN45PnO8zWPBthACYakFeRKMZaoXJMZq1Xai34IEylm9IUsskF958/NAup+uJ/j5TZUzwvh8sv6MA1CqBc/u7AgcymEDMeQmcJIToHxNDL0PY8fP6Ji1iTtf9XjqxoIY6GVe8ft3VHi2Wv7SKq0I9eOnkbQYKXpnOFwmFoan0Ebx12WTepwPzMeI6d94P71ifEUV8lf3zsIiWls086UsdYxXG3Ez6lzQlccOqbTzP72KJtLKngnZqjGGqyWdLvtMHC4fyUbTK5gDcZptlc92sjUMqXSvLk2XG1FPjSejgy9p9w8EeAkCRtpHGVKJxOwuhogp5gJp8Q0Cx1UteZbkucA5aQwzJlcz9NM1fwEtJFiTWspcHZXG4bekouAaKfTzDwH+rahOC8NXGrRwikmIUIrTaq+GfNlfN+RQuL+7khK0nDEFKWAzGUtkg73B5ka5kAaAyBeDl/3kU+RSmEYOo73p3auRSMvputnc1wpOh2qZhIy7d1sBh4/ecQ7X36PME+0ugJljDDvsky0+8Gz2Wj2R5hGkQ5d32y5vz/iTDPmL1O7iShiiDL1NOINVNp0Zhxnhp1n2HhePt+LqUC7L5oGIB4PIpn1TvwLck6kKBIYYw05Bw6NETaNEVe9TJ6UaO1rVWDEs8xqS9d3ArROgWLkBrfppbEbjzOPn+043J8YNtKo1nHCWicRtEpSgIzRFC0eGtNUiMGgB8XSfZ2bA9gNPd2Vp+ZIKplpTMynBFo+W9dVwpTobEeKgfsIzot0RVgzmkKmcw5vnQDKKUmqSREvCJHuCRtut+mZxpHNVU+smsPrmcP9KBMpp9nddNzceHpvMbVjvE+88+V7nHecTiPf/K0f4wu/eE9VBesVxkGJUkDZZogbjYWL4jAVDTlRS2LxNlEKrFYtTcmiLXTW0jlLJpFVZHvlxOyu/bzRCt+An1orY4zEqribJlJpppMoaoHN9ZanH3/K4fbIt/zabxFvM2D/cs+zr3mGtYbP/P2f4df9nl/Pr/zNv5LT3Ym3vv4t5uPE+59/we7JFR/99MfJKbO92vLrf+9vQFFJc2BzNfB1v+xr+PxPfUEaqhYa8dkf/XlefOEFn/pVn+J3/ZHv5/rpFf2ux3WuTRzPFP/j7ZFhO7C7Vty995o4R6zVfPSTb/Pk4094+aVXfPlnv8zTjz9lfwi89wvvsow4tdJsO8fr04QbhAFRG5Dw/X/0d/M7/8PfBTSA4DTz2R/7LP/Vf/IXGXYb/sU//ll+8cc/y/f9ge/jt/6PfgsV+MSnP45taaVL4VlSIYVEv+n4xKc+yrtfeInWmk//qm/k0cce8Vf/8/8PP/rf/ijf8O2f5HA3YxVo60kxkXIgTIkwSaOepiQgbBGj82meOexHkRrpSjXNA8xoAcJSolDp+45hsLweT9ScGbY9w9bjO0fvPSGfSCFia8fukadzmjIXoqr0g2LY9PR1YJ4D733pNU/f3qKQtM27O/Fjm+cjfe/Z7q7ZDBtiTuQEKcHhfmYaZ7y19J0hJwHDj5MkJr/11o6ULK/vJrwXpotWsN0V+kFTi6FkOBwnQham6ukusLvpeOvxhq6zfPnLr3nvvXuRNWWRkcZOczoltBJ/yRgTRnuOxxnve5y3dF3l9vaI7zylBHbXlmmUwIaSRYYa54yqievrHuOaL6XW7PdHnr59wzSKd5tSisNdovOVFCFFxTBYdtcd148HhsHz6uWMogFORq7dmiCFys9+5iXzlLh9cWoMcvGxM1kQp8Nh5jRWNo2pPYfK89tbnu52LMloOQf5vMasLJpaWYFA1cx5a2khKbprzYsUwzEV6D3WSIOgESnFZTO2lkFr9dh+VjW3ocVcmoXJ1Br5C9BnlfJcNLeLlMo1u4TLpl01+tFqfXDhAVSAKSz1kr8AiKTZUa2qPZuzy/XvnJNmPp/N2ZVSuOLavbRJEm2zH4gJFc97h24DoZQSOuv1+c9EtQXEObPDlFKgrXiGIrLSD51SAzlLwzyHmRgT2lic85R5lrRqLxK/eRolQSy1GgW17mMpZ2qY0a2xAQEZhckhoIGYnCsKFsMZNNXLsWpeMUVOwFrbrN8t5QHbP6XYgLTlGAjYcZk8CpeyU1kzcPYKexM8uWRjwRnUK7WsrKEFlFneXSmFOUbGeabkjNVqBayW89GpQmjnLcSW9tzAdQE1GojlPM46Flb/wuqaw7yy0px3KyvsMgjgUoaktUY5kfmuA6dS2TpQq89Vz2L0boxrIEChuoJ19pyK1+riWmpjPMnnts5hrEdru+4By3u00Tb7DwGhAgGVHqZ1nv2i2oCqlLWWTbkl6ymF0+drTc4r5CrekZLAl9fjcSljPf/CeYBnrTCIjRJQ0zph0Q59T991zR/3g2tCawmTSc1HTwIEMt46saMocswqkuqojWsg9SJvFdC+NI+7HCPTPMkayEVSRs0yGIDO2dXLbZwfsj6WoXgMMhTSrkO1a813AtbNJUo4QKlN+vxmKm4bVii5X+V2rmnnRxg5F+qZxo4ydjE6L6QY1v23tt/Pixx1+T1Fq2lbUnsMUnNbAdlUA8qtVqgqLODlUSqoLANbWGTpD8/vm0zKy3+7tPwwRqEvrpdLAKG8eb61ous8OyUs3KuUmObA67sD++O8/o5G9vsFXFvYZWVpzWkAm7wpkdLW8qGssJAiXWfR7DF2EKDGgPJi1+Odoest1RZux4k0gtXSB+taSaNYxvTbAe8tnXNcdVu2vqfkRG7g4rI3aqPERzcFUrz0mVISxBRl8DCFzBSSBIJAk525dpxpgwAkzThN4BSYxUtPXivE9MBbNIVEap53xlpKjctLPzivuYG9Etgg19A8zUzjkTJH8jRyut+jteZ4OGKsYXu1lSFzjoyHE5+PlaiPDJ2nGkvUhkc3O25uhF0nS+YhTLTtexY/CDlNGSTXlOUfFSJ+rpfn8itgYu0wCZGsnpewWl9lARMrucI4TcwxMs2BeY7Mc+I4Z8aYoYqP9cvXr1BVGMK/lMdXNRA2HcXs9+5uz9EkcmyUS7myUEpQSmtbikCbKM4xsx06lFYcjxPvvvM+rjM8fnqF1Y4YE6fTzOkYqEA3dLz9kRuqVbx490QIiTgDJfL42SNcJ8VX13l87zgdRsbTJBNLVVetvO4cvpNm4HQIbLcbahXJljKwveqhNfzVWEGGh45h51AGXt/toVS8U+SiKTVR6eh68QOqNbV0SxpQUFb/iFiKaI6jSGjq5cojC8NHA63xRsnkSqFQRtgvFQEOcy7cHY9cX12xP87Mk1yoIUbQmt509Bsxmp6nyHicmOfQzMehIpr+GALbmx39tmcKiZfv3wkDorNUFi8ezWY7EELgeBgZBi+sM2X44rvvMk+aORypRQMOVNs0GsVTr0lNi8xB1kW/2aC1Yr/fM89TKwbkZuKdgDKdt/S9RZlKLBnbgVUVa3usVtzd7gmhopQUvhJXn0BVus6x3fYiF6iyDl+93jOeAl/43CsePd6i1NTWKBzvm8F4zhhnoRUmMSmOB2EpbTYOhQQePH9vD0p857zuyKqi1MXmpAzKOLR1wtatQiveXcvkeTrKTfXF8zt2u6HJWRbZhyZMQmV3naTqKGuxCqY+Y7X4rEwtLnkpBKmipy8Ubm/viTFTizBqjNGcTpHt1vPs6RPxsysJ4xwxF1CRrtvhvMJ2MkE7HgMlZbQqhHlCUXHW8eLdicdPKo+fXbPb9sxxZpxmTneRHOF0SqAiMWeOJ8d0GPB0bJxHVctHP/6MEBPd4Hn+3shbb18zjolxFOPVJRHl0c2W65sNhcrr+yOHw0zNYI3ID3RjYqQsslCjFdfXPY+uN4QiYRUpJFKKhBy4//yB4/4AWtHvOuJ8otQqrMp5ZP/6XWqt2P6KlOa1+BUPnoq2hre//i3+td/3r61Mqlor83HGOM3P/9jP8vmf/Dyf+lXfCFrz7Gvf4of/0g/zU3//p/jm7/kmlFZsH+34tT/w6+T52h3nvZ9/j4986iN88We+CIB3muk48tFv/Cj/5v/kt/PJX/kpnn/uOa/fed2KpzMD47Kw1spwdT1wecfWzWvr/r077t55ydd+40e5fT3y4t1X6/NU4MXxCCXLFHHZg4B/+lf/CZ/9Z79Aipnnv/icn/8nP0dViqvH12AdpZ74Y3/lj2E7y8/8g5+m5Ho24ETO0eVQyOgGtspEgEcfFc+y7/2BX8df+5N/jZfv7klRJHcYSQeS6bYwbEPK2E4aBm00aSq8fjmjbGW/PzL0Hf3WS3EWCylI8miIiRwqQ9+x2XjmaSLGAMcMdBit8Z2js07uWdrTeUclo7T4L6kmadJGcx12TIfI48c75iIDGW0Kd7eSJBuDMI8xmqokcdKaIveOnNFeM4ZITJEUEzkZaiqkFEhZYa2n7wf2968pNYoNgIFaCt5pxlkMmV+/OPL65Un8K63m6Vs3fP3XDswhEEISpl+BkiUdzHrF4XhiPAS224HD7Yj3mlOtbLYblFJsr3qcF5D11fsTISRO95LQvN3Kfbvf+DX9dZ4l4TFpxZxnNruOFl7Eo8cDd/sEWuM73xi+Fm0Vyjq6XgIgXrw8YKxhGBMaSLGyufISUpMTIbYEvE4k77qKvNp5Q0Fxtd1IY6JaymsuOMfaLNPYL3qpQUJ+yORoD7meZA8y5qIo1GoFY8oaNCP3NUmqUnhrzwywdg9cGDklF7LKKxi2SnAaS8Uai7bCtkkxEVpzuUqI1892Br5yC2SR+w1k3WONXLhzkMblwe8AtYhXKzRmWD0PGJap+tJIAjjv1veh7RnAEYlKh+8kFEErzVSbyX6p5Cz1jsiSaPcokGSyBGrxOPtwwOcDD6XQymBNBS1MsNjAzBQDYZoZxxOpinwVQFV5jUpu0/6wnheRC4mp/s3NDdpqur5jjopYNCXndX/GSJr4B99iayO0FbPlhV24gpRNAhSl6TfG4Kyl8z3eeZRCrv/GQtBVDJtzKo1do1cAZ2FfLY9czgNTq22Tzfnz+uK89hZ5Wyllla8tgFlOIoVc19nFI6ZIiGGV6l6a8ZdSVqbQeoq0WtdLCme2z5spi5eHb/GuklOs6PyAdxZjzuCIMbJ/io9Xs7lAlBGrPLQKo1obvcrhneuwvsM16VWIkTDPMmi08tkeGNm39X95jS11oMj8/AogWFNx1rY95/z5hP2X2d/vBSBOWXxvV0D1zRW0gCJQlVoTVr11OHs2yN/1G7Z9T+c7bAM8F1B08QBbnm9hqo3jiWhiCz8B5zza+qbwuABMtVrXbAqBlCMpx9Uk3FiDqebB+4XWKDdfrIWFWHJZ99yUZJDrBlBGLA6Wddh1HcrZFciUz1PJcRZLHSUplePpeGaWGLGBURdHUilJFsxFobSwoJbAr9jIBCkGUglim1Eu2I6N3bl4OdZSyFHqxjU18fxCsoehzsEN7diZDzmzD9Z7C8hY135dkmUvWbAfApB+pUdDLjovEuNxmnBNYWONIbXE2UVqb7Qit7WsdCMbLOdRNbuihUWsilAZhKS0Pnrvmypni6mO3GwdwLb7gRyfOSSOU5RBijLEmLl2G8bjgaID06zZbTuKkrquxsoxH3HO03VDC/cQKefx9haQZPmchNFtfI+2HY+7DcfTSEqJKUSGlHFdj9LnPXKZN0litwxRc4oNbMuIkXm7N9UGElZhmtYi37PeEmO6oE41EKwIcL/868KEPB1H4jxyvL/j7WfPUCROP3/COsujp4+4GjxPdSQcTzx//5bAnqko9lNkKpqPvP2Yt99+RMjw9NEOY+Z1zXwAZKUKXtGsZB587wLoXIDNhZe0zmXOX2gY87neab93+ZnnOfLue6+JKXKcJlKqxBRQpmL7LdZ0GCXS+F/8wnM++cmvodhfGsT1VQ2Edb2hVMM8SVwozbhWL26iSNqDUobt1pCyoIi+N1hl2G48h8OJmBO2ajGVd4ZpioRZtLrWGa6uenbbDeMccFpRMxhTuHn2GGcV2koyw/Z6kCK5UWQLpXmmaCxGWGNWQ9HYQZGKNDe7G8+1HghzwDjDEp2+2fQ459jfj2LMXAqqVGIUf7Ivf/4Vu6stL96bcM7S9z2999Qlzy7DeGiGtSkRZgFknPeMpzPtd6GGKS0mhsviVEpjvaXfePrB0W8cr168pBTD46ePyKlgrUxljBP/F+cEoXfO4jtL33cir9hPHE8y8cwZtruOOQXGKdBtelKMDJudFHNVqPMp54Z4G4xyGAXTlDkcZ+7v5+bfkmST1eA7MUncDBtKkWajLBPrXKk1oK3EcqsKXS/pgVc3O25fH1k8D4zVGFtAL9POzDgm8dHZJ976yCPef3FPLlXSTLSmarBK03U9SmW8Vwy9TClylg35rWfX4j8RRI6zu7Ic74XBoBt7RBsr8jArN+d5mnjnnZeUKsEEN0821OTIpfDy+VEAy1pwStMI/KhmKBpOJ8LpKDNmq9lsek6nPX1nmOcgNGAFk5nZbDu5hqh03nK8H5nGAMgGTfMournZ8erlRA5BIpK1eAkpFJSI0T2d83zk7Y/IukNudN5XNJnOG+apcLqf2AxP2V7t+OK7n8U5Rzd40BFJvVHMc2AeZ6wGqyvGG3yn+JbveARAmiXBLoXE46srDseJl7eBcarkJDTqlALHY0RXz9B3lJS5vt6RYsbUykef3aCU5ovv3jHVEzUXijKEAi/vRl7dj6gWFNEPnutNx+ANu00naUVK8Wo/8up2JMyRKUSO48yTm0HYKkzcTQeyLzz6+DXz8UicAt/8Pd/EX/uTf53T/h7jB/Yvv8Tv/49/L7/x3/4+/o+//z/hiz/zWoAuuUDlPJ0mPvPDn+HP/m/+DNbpFlkux/dj3/iUw+uRz/3EZ/k13/9r8b1j2o/cP79r6bNSaH3xpz7P/+U/+D8LuKPM+grb7YC6SKUyRvMdv+07ePvr3uYH//QP8oN/6m9greZj3/wJ/tAf/0OtcFfrBFEpxdB70lxFOrKwRJo/zbOve4uv+/avZ//8NbvHPbcvdLshSiEaTpF3v3wHBfa3IzFIg/Ev/tG/4Md/8J/x5K0brh9t+a7f/Mt4+f6R8ZAZ33nN7/mf/QCPPvaIP/57/jhf/hdfpBb4ff/x7+cbv/MbZfJaG9NjmayXSp5TYxUWfvJv/wR/77/4e/yP/7M/zB/+T/8D/uQf/b9y/fiGmGauHz9mmkbmKSKm60VYxxScsqgKp1OEoiFaugE6ZxhHaXhlkLAEp8i+Os6BFBbj47KOy+ZT4MnbV/jOEk4BVSKmWlJjDCUAVTBGWKrGKtIkcnjnLK9fn0hR0J/jcea4nwhjpB88tuvQKjH0sNttOZwy+TBTSHQbw917M7vBcDgWtNUMGzGxffX6FdYKKFar+OEpI/umc4Yv/eLd2tSHUADD6xcnnj3b0V15lBKfv+NpFlBslkGNs4qQKuNJ3p/MbqZWEFusM2y2nhQrw0ZYsDqJv5S1MpjJJbPbbej7LbV6lBbPx/F4YpyECRNjousdbz/boCpc7Tw5Vb78/p5h05HLSUJBGviYSyYlaXJrLtSkiKqjlInOiyl9zYrTlAkZPv7RG3IufOLxNR9/9OQBKLx452glRv+qgU+11JbkdgkKqAdsJGMkiWzpTRa/pZQTIYXWfMukXaxtxA/x2dVu2S2EwZByazrOjdHScC+gktX2AVMghrg2i6tsqwEbtvkCVUSqkqnkNlCTUl9hEQuFlHIzYYecapNTSXOz+JCUnEXCqM/MpoURc8laWz8UnJtWrcgxY5SkGy8NsNKaOVUyhe3gsY1tIt5DTZLWrkndGEmlXgIPDx8ybZdAA4m91w04KQv1jhRn5jgTYnjQgFYSFJGyCkNdHlrplizZgKvGJPbOMyeasbQ0A0tzKf5bH3x/xso+HEJq1ghn9oLvBnKKnA570sKOWcCLAtNcWphOEnBYs4KnOUtdsqyDyz/Lul4AjgUwehMEO5/PSlxqudVLh5UGsJzPN2WZy++vz9W6qCVAp1Zh3xpj6Pt+BdNijKsn1eq9U/IKXF163i2fZ2XFNcb5pQG/fNUN4LDkFCg5obXCe/GPLRcgR61I4I2RECdJHgRHu7emRDQiM8slr6/nnW9p32cm3PL6y4B2WURLYMMUUmPYtM/ZztsCLk5BhtC9l6FBeXOd1zN4pZWia4w7rRVD17PZDGw3G7bDht6fJWTA6uF2mbzZeS+AZJPbLj5fCkXXDc3nTxD+y/2ygqTwpbiGIyy1rTBlFtD/AghrDCPvDF0ndbto6+R7zrl1mFhrYg6B0/GEtYbr3YbO9TK4XTyeVBUAWiuMsewXOaRSzdNMBuW2sXyXVGGlNNp4OmubncECRFeMMxgrxuVyeclaKs1AP+dIXCxdGkJg9Nlfanksa01rJcPVmFDUBrSfOaNyQi/EiM1P0qgGIjfGnUhtm42MbgnQb153cpCFjYYi1ty8786sOWctqu+hVjrvWw/BqqYxShOY18+jKvj2vxdGvSgs5bimkhq4DlWsSBs7zbbgCCDL8MkoQ2dNG7bKk06zMK+HTvYz1/bv03xq/aES+SGaauT6o7Aek+12hzN2PYbLtamsAtOB9XK+S8Ea8Uye5sAcI7YbVgToDNiDVgWtUhuQRUxxjTTR2G9qEZyqi3VQ0FqGwhlRySzn5U0QbHk95yzPnl6jn2yZxytevP+Kl++/4vrRFd3Q0w8SMra72RB05ezsq7QAAQAASURBVPb+yO04Urotfthy1Xv63lNK5dWLV2w7y3Yna0amSJcviACqF+/84fp5+Pfzijl//bDR0wKINRvR9TPf3x+5vTvy/Pkt94cT2+0W1ym6weE6jx+uwA3sDwdSSFw/fcpxTnz2C+99yKt88PFVDYQ9efoE5QzvfuH9VhwW0brWxUxOIRMciyJzc9Ux9Janb+947517bu/HFscqRaWxBt9Z2MuEdTFOTLlSlGbYDZR3DyhduRo2bHY92hS0Aj9YfGe4e3Hk7tU9IQb8xtIrKzeqUvHO8fjZFdubntPxyDtfeIeu7/noJ54yjYEUesIkvllKNX+AlEhTgoZIzyExHpqhJh1hhmHosVYKiWksLElIMYq0BITGqYrh6vGW4/6V3FSVIk5hXbQlZinujGkgmBNfrk6TamaaMpvdhq7rmKe5FbwBZZt8cNuJVGTKTNMsU30tbLkQZ5QSyaTW0HlH13tJD9ufSAWmKUgq46OtSIa8pJ3FqJhi4nAI3N2NzK1JJoGyMGx7YhLD95srTwoJ5aT5H0+xafCzAJhK/HqM0RxPgSdPt7z33h25gtHC/Ki5UrVM9FznyLUSQuJwOPGRjzxm2FpUS4RCw+7JltM44pphqFYVVxW+t2x2PafjBBq2Nz1VwekkqaMxJvqhw3pFDJV+6HHeYJw0SWEOUAubYeDu/ogqDuc2uN6R372V90yVFBTtUMaiaqXQIrJLgZqxnWG3G+h7R84wTRNPHj/i8dNrQproB88UTnS9GKse70/MU8RZgzMQ50gIhavtlqE3WFt49/lLtrstG9tJIdp5vNuSU2F77YihcjwFpjmQ8kTXwdtvPeHR9Y7plNkO1+SkOI37Vc6LzuKnk0UCd9gHYshsB0fXO/qNNE3L0KWcMlZrPvL2DTEiQOUpUnJdKfYWxeaqR1XH7fv/X/L+LNa2Lb3vw36jnXOuZu99mtvUrSqSEiWqsdWFsinJcYw4ihRFBpwOMAIYQQwFMBA9Jq95ylsAB4gTQAkQM0jykABB4CSW1USibUmWEMdUKIoSKXbFpuryNqfZzWrmnKPNwzfmXGvfWxXptZBVODyX55y991pzjjnG9/2/f3NGa3h4mMQfbtMT94m7l3tyFg+4MEcoEiMclk1egXeKvjdsOrtOGl/sezESb14Lm40HCtZp5hBFRkDBO4u10FfFOCd+/md+np/61/8E/8K/9sf52b/8syil+NZPfIuf/HN/jO/90qeUIBHuq7mq0jx++cgXv/EFv++nfoI/8qf/CL/4t38BrTV/9L/2x9jebfjV//wXef0jt/yDv/lz/PE//y/yo3/4x/i5v/5znB5P3Ly+YTqM/NrP/jr/pf/uv8Kf/rf+q/yNn/4bKK345u/9Fn/sz/0k/9n/6W9xPo/r3qoQo3LjLM4a+s5x++Etf+Rf/cPcfeMO84+fH4xKCViaUlmp9DkX/sn/65/wI//cj/JT//pP8Y2f+Ca/8Lf/MZt9zx//r/8LKBS6paTe9lu+LI+8ezPSas/1dfdiyze+/YpS4ekhcP8mcnyMaK3odl37+QqU4lu//1v8+B/7cfptfym+GiNEJtkavQxLgPEw8Ut/7xf5a//rv8af/4t/nj/zP/gz/Ef/+58hpcKLVzfcvbyllC0xzJyPE+OYsFbR3VhMVZxOic6Lv0mcRsI4twm9TPFLFlAlJGnUrTbi9YHs4cbKlHm42VJiJqYsss6iiONMKAVllTT0WZp/NBij6HtHRUCxfnDs9gPv78/oKib/+5sNBRingPUdttuRU2J3E+m3ktSqlWezkZjup4eR3b5juH3BOTxRseQk3mBiaC3JV33v8N5x92rg7vWGN58dKbmSY8X0mlyzRNM7R5ojuhp0a/xjTMxzpmiYU0Ibxc2tpDA6WygFHt/NHO5nck4Mm24FZ7TVOGfovcN5w/FhJA2RWmY++OQVSlUe3gt4H2PGeEvfe85jYJoSD49jM9UXc+PFkHsp9EvV5FypSHMRcZgshui1Ba14J1P/81xILRnuNAZSEabsBVRqQKgR+VUxhVwiqoBzFmuFGSYT8Qujoz18q2cKsMquUl5SwwxzzM98C1MpTM2TMkZhtmqt6JuEiIUVpZQY1H+fl2o6lb7vn0mplFYN/KrEJnmisPpKLS9NonMyXKrtzJRJsCQmO2ukoEZdGBsgZzVVGMgt7eqrrwUEoTazd+uaX1pew5EWaV4oYpTdOUvnHbkq0uqRdJGgqPX//OBXTJHCwrBMK+tHq8bcbxuMdd2zeyi2Fnn1T025YFrjbpR4/gm4IWBJ3/WMoXBt50CVEAS7JKyVy9663K8FJNVKrUmS1+8j5dQkecJqUqo1hyjOp7HVuQ5qXu/JKkksYo4txvrSKsQYVybcIvtdwJRcxMepqkuzrJSs/03fSw2KyMjUMu6vV6xDBUaZFaxcTNqXe74EC8j1bVKzfAGSAI6HIwtjcGVC5ry+b7js/V/9b+k/xdet6MLlgFsYQxIcNY0jYR7lWjqL7/1qrg40f8jaDNwbW4krxqPWGA1Gyb8JMWGNmMCnFBmncW3Cc84rQGgaw3H5bDEJUzxdS0iLWIpYYyklM4VJ6rgrHzgx35dgk5gTuTX1C/BtkGe76zy77ZaPP/iQ7WYrAMHy9S3U4Np7bdkvFuZglztMSrIfFEHBS4woK0Fcz589YcvkxpATme/FY+hyNzSKsjbW4gUsg9iv+lpdvnXbZ5vZ+cJWWn4ni6xLUzFNlr32k1dA7DJVUOYiC14+9wXZvbzmaRR55DKEaEOFRcIsYJjsIwtDS9bHV9ry9vW+86wJjs3c3yiR7i4/uqy+X+09lcI4BZxXK5CkBAFewxHQS9STWt/HVMQew2hNLHIWlapWFq2qFUNp3tGQnQDy3nsoy7mhv+Zfef1a6rLlI17LezXQGfDOUdBsvMIauS/TOeO8xt32DN4LeywXnk4zuVS8M+z7gd722J3l4enMMHSUGrBNcroEVCwgqOwliZIjtV6f480Lz4pPdVHNm1FJkJozGqMKqmZqiVQtvYOzy3BAauOKA6Lc9ywgtazz67NYr8B3SkmCfUrBaEtpNGpJ5vw6f1k83xK9U3jbsdt07HYbXry65YvfeYvJiadz4Bsbzft3R0qc2W4Huo1iuLnh5uUdoUDRhvfvn5imyGbTsd3dXVCry2QeNOt5qq7ezTUT7BkYVr8Ojv2gl+I5CDZNgV/4R79GzGJX8tHHH4ItWCckAGstzilCnim5cDjOvL9/5PHpyNPh+M/0M3+ogbDdyy2gePXxC57eH5lOc5vWLVulohSFtZlcFMfjyDd/9BUPDwe5fVoxh4zTms53DJuOrnNYZ8X0Nwug1vWe7cYT58AwOHpvKVU04B98sGMeA5tNR8lCl6dC13Vsdz3OGU7HmXnO5JxQWpp+3znefP6GWhWnp3Pzi9mw3TmqAq0y1khBcXe7kaj7EBkPhRAKOUWRTGqDMZYYEhYBv0qWgjjnQt859lvPeS4Yazk+nnDeMew6xtOE6weZVhZaE6DWojOmLGbsvpMNQncMG2G2hSlxPiRiKKjKml6RS8F6Q9eb5k9WSTFLvOssDVopMM+JwzGCTpSSuL254+bFXsAvZzmdJt6+OQjI2DU55tO8JpEBYJvxadcx9ELBfbqfsFbx8qMdc8iM5yjI/RTXSZTWCt9p0UGDhBbMYnifqxhUdr2AANOcmKaJUiKvX92w2w0cj9JYgTCYcw58/I0XnKeZ8SQ7QM6FcYr4vkM73wqoyO3LDdRM0Ilhu4U08Ovf+R7bTY81htuXPcOg6HsvbB9g2PSkLFPtd2+P3NxsmSe5Z1hJDDEqUbM8zhJFoKj1EnLQD479vuN0rOz2G8ZwZhs9poM5TpzPI0ppnNdsXwwcnxTv3p948/aAsZpXL7dsdopPP71nOud1khRSZt8JoyLljLWacYoYZaHKAeGtxVkxorx/OjL4gbubHcfTie9+/g6FavHyhXkSxsN8qoRz4XTOlKzY3gygNCFFwkwz4dd88f4L/uDv+/386q9/SogQUmmmxll8D5Q8GyUX5rk0LwSZRJ3GwNv7I5++feKj17e8fX9iCk78Tqxe/XxqqaQQeXrMzOcD292GmDOPp4lpmgkFfG+5f3+ProrX5o6sjbA1qpEIbYOkpNbMX/lLf5WPf/wT/sK/89/nz/3bfxaAD37kNdNx5j/+934Gpzq2ewntANDW8tkvfo+f+d/9DP/G/+Tf4N/8n/6bfPmdL/BDx8c//jH/0f/hb3I6nsk2cf+bR37jH/w61v8+/uHP/EOmLw/87m9/wuPDkX/w//x5PvzRj/iz//af47/wZ3+SOEc++vGP+PQXv8d/Ml4Acd38Bn7j577Dj/7RH+O/8hf+ND/13/wTaKPYvdoTpsiLb7xsjC75GqUU/TBQioCTsvuKx8F3f+m7/PhP/h7+zF/4s/zUv/ZTlFp48cnLtlYVvnNMobDvd5gPPGOTdSyvWjUpKB4eJj779JEYK0VBTJr/9P/8d/mX/tt/ir/4v/mLPL174uUnL4nnSH/T44duLfZqO8i11TLVXGtWaZb+yl/6K3z7D/wI/+p/77/MF7/xBd/7pc84n0e63vHy5S1hFpZVyRJzbrQWX8PBsd2Ir9U8tSGE8YRZQUlUL3h0rglVpPDzRlizOSes0+TiSClSMZynhCuF2jwYtZXEqxSLFFXOc7PZEOJMBvHD8yI1mUKWtCyl6DvbPKXgdBjRVhIgnRFjfq0LXS+sjg8/2mIwwhKZEr/xm2+4/cCx3TmMUc2nS5LHOt8z9DLcEY8X2Ow6Hh6FjxpDZZxmjFbMJFISH4s0R0LQ7PcdH3285aOPt5yOkffvRmJ05JQZj4GYFMZl+t7w+sPtKofsO9u8ElshjoSoPD1F7u62jE+R03kSGbeTUBOAUwv4iEEm4EJQ1NSWXmaNhtq8OLUiRgl12e46bm4G5mmiJGGXa+0wVvyHdJN4DEPH73n9IU/jiZfbm6vqRCbPwswQfy8pni12mfyuhfBior08fxeAQ5pfgzKGjbZY12RmdQYlXpQVKTKfzhO++aJIkQ2xgQ5Ga7RtqYntjNd83YF3YceYxmyIOTHFxBwljTC25tQZw3Z47gWla0Rpx+L7lHOR5GHAaL/+y3rVNObGQrb+IlEs+eI7tQBczjoUClWajGRhEaWECmoFAgB65+Tzai0+m6WiqgQZmcbSUWZhol0Ame/3WoCGlIrIrmttdYLUNbVJEXOKz75unONViIzUkdZoMVueE0UXtPfoBojkWolzvQBEl+5bgCotARt2vX7LvbqSRamLnG5tTkohTKM0e7mglcJ1Hd2wAeDweE+cRgY3EGNc5YYLqwgFQz+s4IeYjF+M0r8KhCyeV5frJ01+7zy602Ks3xr3EMKl4QRsY2Yu7KxONzVBYw8tPjwppQtTjedg0fK6ZoIt4F6KaQU/rhvdEMQrSoqlBOj1OVjA4zVJNSfCNBLmCYAwKcIc8L0XoMIYSm2J5E6sJkqjOWglRuipZhQFZxXODoQQm08QxCRpnotkeQH7aq1kdTHlFpbdxTahNI87xcJgk4vaN/89Z6xIp688C89h4hACU5jYDVs6L+npvvmz9n3PzW7PbruVAAojyaYpxtXvLDdm03JNSxFWsTaGcRpFDq4NNTWItyR0kST5Wg3oFmqVkzDCGpAjgQIX2WtVhoSoL4wq1Jplw7ySxn6/V4oRjEVpuZed79bk2NVHroFRVPm+KYp3W1hkildPY0VJzRdTk9GZtm4v631ZW8ZYcort2ZH7a53496Y0k3NEoeW9KfHoUu1gaXM92akbK44g9YOuAqaDnPfC5pJnP5SWJry8H6Vkzw7i2WoX8E9dP6PCSFo89ZaETFdBebP6867XQhusFqZQaYCYN5qh69hutszz3NhCrEym7/dSV1uvqJZkoLEka2ol9gidMVfAp3zukuH4lETGrSPGAZ30w/thYOu2pJI4TSdSnlemZQgjvR8EXGpgsG0gKbVd6+Z7mEvBO3mm118UYekrCbPwGyecLb2c45FUFDVC3y0hXwoaCaRU2au0kcCzhd0aQyJXBRiSgprNyiZVSqOKIlFk6P61K1nFgyzOHOeJzSB+fsK21uz3NzzcP1EJfPfNE9PbL6kpsd30DF3HfP+et0+PKN8RlGWMiEy6FkqsqBaWd/2D8+JhrJrqgQub6/sBXl8lMy/8zvLsT+Rlv1KWaKMpzvDlm3d885OPef36JXMamcKJaZo5nh45nWemOfLl+zNv7s+cpxljNVPbp/9prx9qIKy0Q0DMbKXgk2nnhZ5ojFBuY1Lc3nTsGxvL3nleuxf81vc+lwKhAUrTlIght7S9IsbNFabGrNLGUFWLLrWa6SnywUd3vL8/4zuHdYbbVzfSnCgIU4C6IMTCChs2PfM8YaxhnmZeffCy0YEr3htEWmdIMfDweGSz2VCzIiULKssEsjGqQPHuzSNhyhijmUdBnRdfkmQgV8Pd3Ya3754YtsNqQH5zd0M/iCF5mKIkOE4zcysMjJFkqOk0Y50Cmzk/FV5+5FBa8Xh/JCc5BHMqvHtzFA+Z3tL1uzZJ1HTDzNMX9+R8OTAOhwmtNTe3PUoXtM7cvbjFOse7L+85HE5ihukt0xg5nUam6VJsdpsNJQa2L16h4sTd7Y537x6xnWw4IUrz4jtLybUdhFqaSyOHn7KZaao4Z5AaSzfKcGKcCufxJIizN3ivJQSgwPsvD+QY0Qa2mx6UbBSbweJsZTydqEXM7ZV15DlwOpxFwjBnzmcBRfveYRn59jf2aGuY5kyOAb3r0I6W0FnxzvLipSUnOJ4Cb94cibHSDV4mQ0pMBLVpkbJFJra6eXeUIiywYaMkGdTAbr/lcHxiQ89m14tsVSWM6QghtzCBTg7+MfPFFyMPj80LLhR22y277UDXX2LXY4zimUabnGnothbveqxRhHAmJmnk0JGshCH1+HjAesNub1qxaloxDkNn0LVwvD/jX20xnSecK3mq6F7z6tWHfOe331BRnM4i19zue3KM4rGjNSWJ75kxCXXpO7G9YQqVWOHTLw8siT1UTQtwWl+1HdTVKFIIzKoQZ3m20ZZh6Nl/MmCV+Lkc50CqYhiaF0Zi5zFDhwrwl/6Hf4k//ud+kp/4F3+CWuEf/51f5G/9H/8TNJ4PXr8i7yb+P3/150g5c3x/5MVHdxzeHvjp/9G/x5/4b/wU3/y9n3A+jPyNn/7r/OO//Y/4+Mdfob1m+N0b/uHf/Ad85+//Ovffe8t219P1jtu7HcdP3/F//Z/9+/zaf/4r/PP/8j9HyZWf/Q/+3/zcX/n7/N4f+4Tvfu9L/uOf/pt8/iuf8ePf/ITPfvUL/tr/4i/zE3/q9/P6Rz7g4fN7Pv3lT+m2HWlMbDcDv/Xzv8n/43/+f+e3fu43uR0GlLF89iuf8Tf+t3+Dd999x8sPX/HFd77k//bv/Pv8wX/pD/Kjf+jHOL478It/+x/z+kdfc3x74PXrl9z4nnMXefHylpoiv/Vzv8Hp/ZHPfvl3OJ8i3/vuA+MYOR5mtPGkKkyDz37jDf/uv/W/5E/+t/4EfvD83f/L3+Pp7RN3H93y8Nk9w6bn1372V7n/7B1f/MZn9HvxmNJG85f/3f+Az7/zGS8/viPmyk//j3+aP/nf+VNMhwmqyKRRhRjFe+j2do/RQodXKGKS1MTNYMlZcbPrm9zA8Tunh+YbJ8240roxU8F7zYcfdoSiKUoavXmeOI+SeDNsL9T805TBgNcGUsGkiaQFzJ9zYXyaefFyS62Vvnf0nafTmqenkfcPAWMgl0TXe3a7Dus1IUpiou/E5+xbH77g4e3IuzcHkYBUqFHLc5CERaKNABAKRYqKGKOcDaFgvEPrINPuJiPKsfD4eF7l1r5zOCdF+DwlSUSKMPSep/cz2ghQnrOAbFTISYtfz94xTwHrxBg2BKHKhznS9Z53788oVdjddIRY+AO/9zVffPHYfo40FnNIVKDresAyxxMygW3T3cGSU1l9PXJMbDeS1DWOtTHMHVo7GY7MiV3xGKX54v0jr24KvevY+K5JUMQgPTXzbK1k4r0wRGpjPcSYVrBoARQGb1t/J3K4zhiMtmg0tiiqlWrTmoJa/KEqWFqDFGTfU6tB/cVba/HE+UGeWLoxuBfZE0igwP1h5jSmBoTJt7zZOvYbh3cWpcAaOd+N1peGvMkev9J7camqpdEPUZFLZjpPK5iSiwCfQzespuaoK7mKEuN83/kVKJHpvWlSJ2GBDoNnjM3SNydSjBgUbgmr4QKcfPW1MLNqbc/AAuCVKvKf5VOkuH7mlGt71i/f0ywemklsGgzCrvTWYpxjnCLO9yj13ND8Ik/UaC0smlrkbDRGrQyCXC7Jrdf+OyllqjLkGqEWrF5YVtLwphiRcNKyMqYWj7ZSC866lfm1MnWu2EcLQLYwOxbT/EUGvABrtdYGijQ2U/MnXKS5CnDey0BgkZbx/FpopVfwYWFqrABovrC7lmsi1+I50quNGJqvDLtSVp8yUJjBiHdTCF9JgmugRMnkdDFnr7US5iCfp4u4zoMSwFUbLRLOBnovDIqcIinOlLIYTCucE+88rRzO+hXcW+S2CygpyZEtiGphbLZ6a3k/tZQm7NCUahEQX8CpRZpqtBFvOSxDirIWvYS2bDdbtsMG7xzb3UbSFLVotRWinFFaobNGJ73e3+Xap5hQjcEiDCdprLVe1ixQRfClqmlMpEStwka6lkYLEGnRxmHbUEAsxTIlJZSOKBWftdTLID+lRGzSU9NYX7L2hWVSiiQClnRhobEwRyvMUdaEVpfArVoUsZEMshIwwNqIb2DaPNKA1wQ1shSbxhgBJTWARitHiCIxr1mhcatBfamlMb3k06jmDxhjJJSy+spdSxRLuTy/wnS9rHlnDKys5wVck7523YXrRep6uQftuc+B0upxpaWPVfqS2izPphID+u0Go9SalLzZ9EJ4+EEvpTDeMVhDmGbyWVJ4hZVVVsmmhBDIOu6Ua5+xEkLBdQpnFNuNk7VaDTFHTuOJ4/lA3/VYl1aWusLg9ICqmhADCt/SysVuJOWMM4aM3NP1GSuZkiNaST8h7LkkIFF7trWqeHvxB1uJVFWhlKFUtYK8xlpqlTN+AcMl/MVQi2Mcx3XgoI3FpEhBkZ6d3RVNweoKnefKbg+jNdN5xjknbO5UeHp/TzyN7IauyUbbd8mZeD7xNCfOsbC9vePdl2+53Tn2N/3KhlxeMUxoI8OlZSWqr7CRl3W1EiaXW47cO9kXJfxFtZRbrcQb7LpWCDFxt9vwW7wDa7A9nJ4i9+8fGceJXMWz9v3DifvjicNxkvWXKv/Kf/Ff5u/8rb/5g9dfe/1QA2HzORBCZDrNxPlygF72h0JJIhUDSevLMXE8HPnGxx8LerzxAloYQ0nChHCuQ+kEKtN1FmMNzltqTBhb8V507kop3r97FHO72gpADWmOzNNEipGSRJrpemGI9ptONPNKsb/ZCetHKdCW8RywxnJzs8V5xQi4XhohYxTxrMhV8/h05MXtBucs0xTIuTCdAs4bOZDniNLge4exipAy0/1JzASnwO52RwyR09OB/W0vQErS4rlhtGwWqtJvfPPfaDpyK0DK6TiTk2K723B8OlNK5XSUaXw3OLRVlJrE9DKqNflpeQml3ND3lv2uZ44SW69VYR4nTseR8TijtExSSynEnNvoAHY3O04nSalLcWYwUaRPVnE4TIK0P4rZvXOauWSZOlWFdVKIWQePjwFjJb1os+vFl6iIsW1BQEnvBUxyzuBMx/u3Jx7ei4TMNCNu34knSt8busGS08zpIEmaQ5tGno4jpWSRSSoJEfj4Wy8Yeofb9Lz5/J5SFIenEWplPEZ8J4BjqoV5jjy+PTFOlRiFWWesTGVQwmpLjS5dlZxwSlVQFaULxilu77aklHl4eCQmIxOps2I6J2znZIpgNakkQfqVTP7VICDd+RylMemb95uTw3qhnOdUcNYwhUSIma4zOF1JcZImsxZSyNSSJIQATdd76qPi/fszH3+04eXLPTEWxsOZ7c6LP53VqFQZz4EYAt56QpJUuOP5zLbb0vc9nZ3ZDhrnFP3tQEptcp8qp6co8mcUi54+pkqytJQ3KYByaYrS+nwzVkrhrME0Wd1pCuLx4yzb3os/RWmpQEo299TSLnMOVFWpxnP74hWhSU1/+T/9FX7pb/8iORdu9luc3fDqxQtevNgwdIq3v/6Ox9NEt/W8/GjPPI7klPiVv/UL/Ox/+J+RS2G7Gfgjf/L3cJxHjHb4Ows1oQ9PfPLBnh959YoX2x2f3x/YdB3Uwvd+8VM++we/iUJxd7Pjj/3B383NfsPtzZbp197yUjlevNjz4YsbznHi07/3y/yTv/7zKAVb39Hf3PBis+En//Dv58u39/z23/kO2+rZ3GwYx5GuOj79+U9xOLavt1QNIcz8k7/7T/iFn/kFOqvZDwOn+o6b7cDxZiCjqMZwOkV+/x/6cT779C1f/MJneByvPnxBiIUwFcxivKtlI9Hdhi9/+56/8r/6D0m54LznfAoMuw4N3H30itP9mTzN9J3m5kdfo43GGfjtn/+ODARe76XQHCt//6/+gjQFg5NYcAPKZqiKXITt660UYi9vB7YbGXj0vUH5V7x9957plNh0HTUVckKYHFqK0aIQefQofmOpjnTecDiMxBTpvMd1mmoNuihUKevXpOY15LsNu52XJi5CSJXTmOm3PfsXGWYBk8MYuH25o+s35JKYxhmnK7sbj95vcXak4rC2EuaI9ZaSNF0ve4kGjLVNZic8phwL43lkPEecM+SQ2N70HJzh5rZjPM7UqhgnCWWxWgD9WkX6Nk+gdEX7KozhkPGDo0utqK6BGIWNfXgI5BwpOWKMMLNrKcxB2LXznDg1dup+53j/dmLYa96+PTeJriGEJLCKksl3TlEkDLCqXrTR7G86Hu9HpKmolKoIIYoH6NYRYyYEaYyUgs4bYso8Pp343kPgx76VOI4TnXf87o8+QZvGJmrnntW6JeW1dDKj0bqiS4U2gc+lrJHktZbVrwwi1l1kiraFuehwMTyuVViPMQOtoKR9xpyrWB4o+WwXm6bnEjbxyyri09JeuRTGKfHuceY4JuaQmYN4YE7BMSWD7wxD17HvDR2mSRelljJa+MliUyHn0UXBJPVaKYU5LGCZWhlrUsLVFZTRVym1y5evpvpOkgQXNoxqwGM1nn77kng6E+dZmvZ2YZYGN7fv//1eYrhfm5RVXQC+WLBKjIKLKoy1rFPx9XqyePAojJJU0tp8GIX1p8VGwSg2w5aQG8Bp7cqMSzGu/moLkGmaHMRaJQqA1oQvkv1n55ZRpCU8oArbyloJfAhhAlUYhp7SmFrLdbfermysxQj9WoJ67Qu13qcsFPblz7XWq2fZamqvuDC4KhRV5Oe0tYKxF4+oq7P3+nss1yGX5+9hXRZVPHFzk6UuX+ecww8ea8XeoIbahlTL10tDtmi5lq9bfcIokhRd68Un64oNl5J4IGpbWZR/sQFZy/NdUiClmZQukrm12dW6maazynwXhpEAYLIGC0sSn7oYxSsBNnKVbuernk9ayRpsPxDQWOt5cbNDW02tSeSaRkzQO9/RD10DmeVZq9RVmrv6B7Z1uQKSy75TqjDhcxLPWrc8kwv01yz2lAys0ZC1Ii7NtFINTBTAThn/rCBTaLQ2pKTFfy5FwhSIKre9sK7AjjaQtZAm5iDeuMv7FeDw0jcu785ohXH9lZQSoJ3LMRFiaqDtAsBWqCK3Ox5FjuX95VnsbEfXdcIeq7V5rc2EEEnrPix+heI9vFxnYT7DBWC7BooXeXgphZCi+Lt9BUiH51L7rz4r16D2BcdoAHtO1JyoOQsTrNkFrd7LtF1ciVTw1c2Gbe9JjSmYyozTimtJd7kCa9SylrSWZ0fLGbTb7YQUoBeZrhV/7dXyqDYWaGnXTcgYRheUkv1l6HrZn0vENTaqUgLsl5oJqVK1bWC/xXlHzIkyFZyx7IYNSkHNLdWx5La/pvbfMnCimgYqyv02ymCNbddPekQBqBQVTSqgs6zLxUu03VB5xlImlMKoNd57XN+jTVMQIAOVvJwtyFBFtweqb+Exp3EkhsRnv/OGm5tb7u8feHh4JGHZvXrNdrBsO0tnNcaJz5Z2htcoDqdJGKqrFUMAPNdImLeN114EXylolMroHzBg+z4rb1ll1Fpk31KN/feVACGtNW8eT+Ra8X1HVRq0ww43GDUQp0SqI6lKTSZ+hxJo1ff9P9O7+aEGwp4ej9QsBoe1TS+1uRhfLqlG1yLld29O3N7echoDWjX6o3b0veV8OIMuzFPGGovbCAPLeYvzlinKzfOdISeJVO77nuPTyItXYpwb5khKkRxzM4kVDwHrKoWI0pkwzRil2O021AznMQgrKxS2215YYbodVkZjTKVmOB0nut63ZBJDKZXpHMTA0cF4mkhRGnFVVEOhhT3QdR0hRlJNnI9n4hzJpXA6jezuPNDAnslyPo7kVgyXVJnOMylVmYgq8J1tII2AbRJZj/h6Dbod3gjNNLcCSapPrDXc3vR8/PEth+PUwAKRGX3x+T3G2PV+ymdRsvCVxB5TA+NxRJuK7xSnw3u6fS9snfYM5pwliS8WYQSWLBOjakhR1kPOorXWSdH3Hb2WdLAl8YVlmq2WSQF8+t1HzsdJItRbosd2P0haJgLY9V0vn6FEYizMcyDMEu1ecmkMCwF45nNk82JgPAasd+Rmqnw+BlItWK/Zbj3WG3LKnE8iHSoFtG3dMZW+twybAess8xxk2pVaYl4DL6Vwdjw9PVEpbLYbDk9SEBwfAx9/e6Dr20GUIsZobm62PNWJ6eGM1Yak9LOJ4rAdSM0HxilDroXxGIlV8n5UXYx5a4vwFi8KPwyEWaK/X7++xdrC48OIs5ph47jxMrU7PGbmc+Acc5vQRZSClE/S0CENwrSvGK252W14OByF2t47XrzeME2Rd2/FFDsXkZd6rYXVqcX7LjdZwcKiLEtsKrJRa63oveN233Ozc4xzwBTL02kik1HnuaWptmK/yhQjpoo1oI0Y6qqUWlEAdy8HdBYD/tttj60G/21PypWqCudJZKE5a8ZzQumJ/d6z7bd0t7CNjmmaubm9xe0s+25DmWC/7zAWfmL7CXebHZ33YkqtHBvXYbXiw9sdNWZsLylf1mlKgm7oCctAwciE7/bFhm999Ioyt8LbWWKueGsot3te3O25fzxJsIJR9P3AvnM8TiNjmGUPtMKCHYZCmQM9ibu7PTd3t+xvNKEUjlOgFEUKhcc3Z3x1mM5RlOJ4PjGeTsxTxiAmwVlJA+icoSphzHQbzcODOLuVDBiLdq55OSg6b3CdEwZoJyDs+SQhGF9+9ojvB86nQAaGncV7h7MFo8WvpussD+9OdK5Da00qmYIlxMKUC+HxC+YpEOdK11mmkZaWpFpxLk3lMUTGaW5+H5noDErDbtczDN1qMhyDAq0kNXWcKTXTuQGFkjCEL4/sbjccTxPD0HGeEn7whAJPTzNQGU8zJVsxbPUKtfcMfY81nhgC5/MM1WKsakARaCUF9vEYZBBkBNQIIXE6TkxT4OlpZrvtyKliesNmYzk/TWgjTJeUmneP0hRdV6lBrlBTplMeamXYSopYqUbeQ2gykpI5HEY++PCWeRqZxhGUGEPnKHt9TPKwKSUsVWOFJRhmkedqVym9xhjxjTwdZzIFaw0WTS7IwL7CZuN5vJ+EkaOlqX18PNEPvZyjaLRRjeEFXWehQFViF5tz4hyP7LavSCQ0TqqO2qShtaKNnEfPTfUlbTOlTOfEy0fYHIac5d8tUrDFjJy2MylthGFUFzbOpYm87nlyXmSYC1NGzmGl6wpsyFv9+kQ35cLxHLh/EiBsSSaMOYM9k4yhzx2hASmbTU9BkkqzEaagRmwHBGhY3/76M0OS895bs74XhRKDYq6uV718HfW5MXjJYhSvjZiOa9/O7SKNl7EGky8eS0viIVz8pr76qlyYbEoh3jcsDAhwqhBrpoSJNJ8pOcv5kQvWiJlzqY1N2Nh5uf0c5ySdTGuD9QPGOFQWpri8R4HRliZzMVCXdSDMEvG+EvVAbEwc1IXmkXPmPI7EGNDlwuiwvkNbJ0mS7bMtteKzD8+FZbXKHrVqMiIJElgYYYuf08IaXZLSl+u6rOHGA1iBFOfdGkiwBDJYY1fg5/laTM8kkAvYsazblNKFyVgv7xnFCtKkkNr+0YIKGntmebZq+TogWts91FqjcWsXX2tF5QsrbQGq5ZJlcppXgBpE/hfDRIwzsQFhC7vRFsuSXIiyF4ZOvYQVLGywXEWM5IxZWUTSiBdySTgjWemxZOYY2+BGrRJNlKFUjTKOzWZgsx1QukIRaaDVYnXivBOQErXKFJ9JX+vza7Q8t9o4cggChGlFzRIasfzzyzO1fCcBdztnRbIORNWmkdqwoIrP1ieX3aRWCeiRPiMxJ/lZtkkgUcL0iilLWnNjq2nV/IU68Q5VqFbzt/1nHUo8/5wyu8jPwGnFBadzLfVdqYox4J1nt5FhrTMOlLC7nHPimRkiKRVqyYQobKSl+lwSNpf1f/1mFtlsWZ6DhUp9tftf7svl2n91bedc2uBlkQ63sJZljaOp6pIMWFmkuHVNq60gvenWs815ZcDfv/uM4rUw39ryC+X6ml4Aus451HZLzJLMOibFfmPw3mCtkRTnXvaGeQrEsQgRZq6EIN7CXV9arQZD57l76chJsw2ebXeH1g5UWCGB0v5XlfiXppSwxj4LkaFArWm5IGITREWpS6KNeL0BWPkZXFhhRWxGG9AlPUhKCmOF4CKgt/iYU5ucOwhZZrPZSEiCETZkyRXbfuoKQan2JLT3u0j5KYYXdy85jyMhJ169vCXGmW3v2faOm43nw33PtnfMpXJKhbkUzuPMfB5J6cSXn1pu7/bMIUoir1LrIGkZ9hiuQGW93NXLS7VWddlu+T4epcsQS/J1JFRlAXStNXzjwxd88s2P2WxvyMWC8ljX0yuHsZlcFd0442xH51nX5eef//+BWX6YI9aKJ0YuBW00w9Cx2fbiQfV0Xg+xlDLH4wRV2CDdYMg10XnN4eFMNwh7ajyeCKFizdAKEPFm6TeaMIvU0nlDSXB4Ojftd2E8Byq1RdFLc62NsJK63qNo5pRT4nga6ZykfQ27gTkcOYeZkqXwPI+SoCUHpSFMAqR4b+m8xzvxfKltqhlnQW9r+2WspGjVkokhNI23GL6ixNMgxoixsgnlJKa/2iumMQqLJgsLibr4JRSsE5Ds2szfGI3q5OAoNTONws7qixeKea5tCtrMDqPooftNx+PjREUm3MfTSTa3UCgpE2NpRWTzakCJP0vN+MEL88wIdT/MkcnNIi3tHKUEakptVqAbu6dQa2BJxZymyotXO84naX763uD9Ejogh/A8ixRr8ZjKSWjwamERFbmu0zihlKYfeii1Mchksnk+ngWkKxVrHVqLtCfOhc0HHus8KZw5HUb2+w27mw3aGt69eWAeA/1gcMpQi8J7t05BVFUsu473lloTvrMMfc/ktYQvxArN4HKeFF98fmiTGcv5GPC+F7DQKqx1MgWzmtielxRnzqeJ42lGKQHS+sGRU8I7JwkwrmMOQVKrciEmSfFcAglAEXMmRcXW7NFKUUrk8fHU2JeeD15uubvryEzEFOj6QaYah5mnh0jOFeMkNbUqWhoUzcMPQjpLAxzkgAkJ1JTI9xNUaGUhqIzECrHKVkoritvQs7HBBCy1RkBkZwzeCaNjDpXTKTJnaQqzKsw1iPxSy3MQYxKATInBKDQz47aeh03HzvbC+HGKUjR3+x3ayjTm4TBzOIvxp7UG62SaK0Mozb4fOGvHy/0Os+l599mB7dbhnWbnO171O7y1eGuwSpGAfS8MqXGOqKFDbRSu76Q5SIm5VkyVsIySZbpZqGhj2AwOtzGoxpxdpl8lV4pyvLx7xedffsrTKRBjIcwyBFA0+UnKsvatF8NzNeOd5TyeyWhSqJzCE53eEmPh8f1ZmmJr6a0n+8LRhFYoKJa0LVoDp5URHwOlqUpAZeu9MD6qREdoZYShpZIcxka8yYzWjGOQFLo2ZV+CVuTnCYCrjaKqQiXjG1PcOkOsijlVxikSw4xRVjyJjMF3npIjubCeUaVkeUbKpaDoqmK/d9y+GLi5Ez/BWgvKW3RjF2rdfF56CWQYp0hVlcfHEykV3nzxSM56baC6zrHdCcMTkgwVikwTU8gkNbZCvUIbPCgM2ojZc42F82miZNd8MzW1Clv2PAZiqoxjRBvFeIpoY0mpsOltk0fLHpBLhcVstywTUkOKAkh1vaMWxRePR/FyVICSBnCaZ+7vD1grkvY0Bmpjc7qqGAaF0pWh98JoaT2qbg69XW9RGsYxS/JwA/SsFTmCKFukEz4+yUBJ2cvEuSLhD9a6ZnAvBX2YmndSS6ZKKTPObZihMkklHK0YbkyQqlUrlsWDUrX3qJSwrau5+MuYFpSxvBYfEZQwFaSybLKu0hq2WtdGY3ldMzBqufz92tC0BuraL2l5ruQbyL7lGpCcczMcrxlVxNj9dJZmu7SJ7qa/wVsvz6lSzc+niAypXlgHug3oaqmEkGW/Xcz8a13P/AUEWACDpflLre5SbQAFi3SpEmPEOgFpQgicjkdQWqR5K4NmYXnIpF/SbWtr8sq6Vy/yDeoViFdlit3QFlIMpBjkQFLyc7VSkmBepbk2ymK0wmppPOX9Gvyww3hJudZGi0wvJ1SWn2Ga6fnihSVy2lXtKudW631zkmTEZQgZQuR0OkNpJvVX9zk1A/l5nqA6TANaFsbb8u+W67AER7UtcpUNrmBklcZNN4ZDpWKrXf25chGW12J6v8pbm0xdNkMjDCeAZpy+fP92p9pZffnanDNzmDFK/MoWj97rdbOETSyf7ZqJJX7A9tKkIp5VAqJeJHrOGUmsbRdcEpsrRZUVtLN+AbPk3ZYS2x3SiB9QaoBmXsN8oCW3tqEei7l2qaQiwN8C5olkrLGElBbGlFIsUraqpFbRQEpRmFKlGcsvwB9yva3zOCdJct3C+kLWjabiu+alp1raa7lOPVXP1sn1SwBFC6ZJEpWiai3pcgsLqIFguv1eQdiKWlJ0JYk4y3mpNHyFIXJ5DJcBawPpSlsjy7rM6krm2zyo1AL8y8/rO7ETsPbinSWgqnzP8zjJNWdFjNd7oNq1z23Iu3z+YRjkzahC7y1DPzCsiZnX4QxiIyD7YaLmZl6vxItONWN6WUOX4WxDE+RnV2E/olSTTpu1zgDW93X9UkoYyhWFKgajRW55zYBcXsIkzW0vlv23ZgkNqe3fGqOxQEFRVMG7NnAh4Yyi90saagM7oihunq0bpXBaY/u+9RCa/WCQTDexK1FaPLYukmJaGEZZ78scMn3f7oWRe2ycwakea7sLOL5CsMKiDEuyZjubfAOAlzu1EDlKSTJl1UbsdmSy1ZoHxZL0CJcBi6wTdbl/ILXX0nc3iaHW4r0Xm6/c4jGac5YBmRFChlIKwzLIqah65aVHY4sqDVYzbHoJHCgFbyrkiG0DvXOBJylxCTFxnGbGOTKNM3FOHKbEJ8Dbz9/y4sPXnJMAxyiFuArUta9ZAOKlj6K2M+qqlljenwS6Ld538uemLcyKBP/kWrFKQqKcMXz8wUvGkFHeC+EoZnIS4tHpPDOOM0Yb9pstRhnuHw+UUvny88+/tv6/3+uHGgjLaTlcDf3QUXPBN/ZWiJcIXirEkAizpuscp9NELpXNtiNnMSh1nRwqMUbCXAgt5tZ7mSKGKRHmhPUK5w3jaSaEIgtTK8ZzoOscRltSswl03tEPnUzFc8EqAbJCkMSzcZzoun4tCBWKMEfOpwljFClG5jlQmoeBVpKglZfo6FJFctaSrYw17cASZDlGmQRHazA2rqg9Vei3vsH+cS7ESZqFRYaQS0FlhUMKtNqmBtoIBZUqkpIpBpnmetckMIV+2wl6XEUWmUKbCNWIVYLuHw5ibhemQKlisJxian5eCqX1hfJJXov9fvB841sv6Tcdx9NJrkeUAsM0Q8Mci4BXMVFTm6yuVHsNWEJIWGvb/ZH7VXKiaIM18vNzzhgNIRfCFMWzq7SwYiOxt8bJhjhNM8OsMfoyHYpzXE10fdex2WzQxvB4f24H3SXpxjsxqndeiWG/ymhViHMip0rJsL/ZYmxgHCNhbiw3pNlRSkC63dBzdztw9prDYyDMDYCdIzEEtJFrWkth2PbUoug68M7Ie1kmdUoxjjPnUZI4UJXOi2ePRIxDiaVJIivKLIlwoYFgdkX0jZZJv9WWMY/kHKmp0A+GUkTe9PKDgSllqoKaK97r1hiItBHN6oMijD211gYhZKKqksyHeLSEWAhhoutco1tn8aKrFx8GqpZYrtZwlbLWOrLmkKLdaCg5czyOWGN5OgVKS8xJsZL7RH+zEe+oAiGHdiCplkZa6bQWYBdp3Pvet0Mvc54DT2bkcBJ/nAJ0vcV6YWt5bzBOGvRd1/HK7XBp5sPthi/PJ7pqUEmhnWJve27MgFECZuoie4vRCm8t51nkrd55qK35boXeWlDSgMIqTX6Ikm7otJZps9bSiCqFNxVrErc3HSEnQtSElDBArLSmx1BTYw3ESjSKmAxTHgnZNsaaRhdF7zryfGKaAyYVKWK8JPU5G4gqCkgELb1Nray2lBTDIEa/2khYQ8mZFCtjTZxrBSWg6v5uh76DYef4zq+OzLOwjZQ21Fam1SJuDCVL6t1+33Fs4FJMiXzKqEmGBSEU3r870HlJmo0pooBucEKfP0fGURqjruupNa+FtHWGrjNst56ubwlYSMERY6JWe/msSjFPWfy3kiRPhjkyjzNxlv18d+sZBo/3lmFonomTFGVhToxjEEBdyRmR44xWGt8p3r8RgEzOjyUKPeMaa806zbDxaC3pqIss3zi5Zl3n2L8YGE8TpSh0qTIUSLKPzXOU65o9rvOktBRE7bnWqoWXSMF7Op0aKALKQIgSb69NYWON7EvNF7LfilG1sRpnO5SR524O4hkhHkUK5xbnV1kzNWsxhVULCCqAeIwZayt936GVYpom5jmgFPS9Fw+e5m0TUqRWSywJ+V9A67oCLqo2X7DGGhJ2dWOvF2n6Ysor8PS8yWznV6nNUHf5s4vUUcpsKXYWAGwJM5DmXe6f0cteV6RwbTKilUFTm2F7A/UXSZVRUHIkhBFrNL2zzGMCWwlTJJbM4Dqi1lhkOh9iYDyfqTWgWJLSxL/IWUPnRV6Rms9lLLL/LywM1ybz1lx+LQ3bwvpZCuzF+2lhhwl4GMXUXCmc73HDILJAQMr4BiLU6/qAFTCQxrg11w0QWf2nWuEPokjIMTaUkXYPGqdDXZrmtqWuv5Q2WCeTbRTNsL3dj5LamheG5cJSpwF1MaS1dgihNEVBYJznyxpSihhm0ny+SMy0EjA3zIQYOU4Tp2mUdFGt8datDdwCBFlrMdWQSmPR6yURcWmMnpuELx55i9xvAXJzYzXqxYBeX0ldFSjTY10D/GKgNpBTXYG5pZY15GARn657WY6rl5ZuYNECyqnm0fbspQS4WGSgtSpSaYMgLsCwUhXXUvHkfRSKLut7U0X+3Dl3ScBcT9LlV6sp2s80tfmUNU+qlZlTlNiyIIPWJYxAKZFBan31Sy3+cIVYRUJrFiCsSei8MatMUvzzPM4PWDfgu46u88+AIQFtRfVi2plTec6KKrWu1x9YAer13lPWJNyljqgrONn2qiuwZWmel8F6LfL3mUqqSngvX7l3CyAeYyTljG+egWiDypXSQDxhzMneY4xGabfuc0ZrSa/3bl2Ty/dWQEjCrFn845aXsHNU2/+bPDdnaECveCUKc6jzPZ3v5Rm68pwzxmCrlUFArdTlXFDi6bmABEolUGX5weuqooEJpQoAZZRGOwdarFlyKeua+urrwnbTGK0oSqFKfnZP1n/bQDfVmpoFLBRgXG7KcqbkWqlZ+swUIyUs4LjCqsVnEJQq69cqDQYJsNJK+i7lHGNQOCsklFoUMVbCXNBJ9sQFhJMzvdU2YWGqyaBcGeiSRStRT5U4S+gPCa/dZXCSIiFaNr3FWY+3Iqu7vmIgyiKRGrTF2PpUrY1IGP1FPpjzxT9R7nvzVlPL39dVZaWVx9qMNjMlXgByal3BMO/kOc3tWdPLwV6XgeolNCeVyjhL3zmniNWGm/0GlQM1t+F0Y7+9j4GTEZBe/Jvldz/03PWyB9y/uWd/d0Pt7QrHppxl+Nye7eX5bHZ2lAUIu35u16mNrOLSzlF1ta6W9V1rJSlFNQ5TC7vtwOf37zm9+5KHw5l390+cz2MLIzLsthtevbzj1auXfPblW54eD+QUeXp8/Nqa/n6vH2ogzDjDNAd22w6lRTKRkvgwzc2kHpDWsghVfLfbUutMTIXjceZ0Cux3w4oUW+eZ5okUA9oYPKLZPx8DYZJivR8sj/cTJcth7ryCqnHWS/JUKhiSSGucayb0AedgniQqWSvVQKy8AkvQitFSCKlwPJ45HU9tZSj6XmFNXeOprRWj3BQzxlhM3+KNW3FXSiG2RBmTxeQyzEEm/pkmrYxYJ4lI8xzF6FLDZtszbGValNPixVDZ7j2HB5HdqEqj8AsN1lqzPihhSsQqcj4xpmxFlYEwznz+3beEmJmnCFoJ7T3IhNx6gzHC5JNJljR83mn6reejb7xgCoFpFrO/za7HeYtqKZ9xiuJFtRRzXGi5WgFKJBNaK4ahk0l3SIQahS3YCwPCecWwlQ3TWsPjw1mubyMWlQYUbHcD8zSLRHQQyajIjKS5NsZgvRRascn8us4Isw7ZNIdNh1JFIpezRMNaJybbwtBReC9G0tMkIJ4yMjn3nUibUswoDfu7DdVUxjGzxASnJH5CORasE6aDQqQk+1vxnKmZtskatC5rIWGtHCbDIKyIkrMAkNqgLWgr/57lIGtFKMje5p0Bq6lkcmwAk+oA1dIcAyUPdJ3IXyVKXA5xAUXL6gcSU2IZSxt12b4qTY7VDI2NMqxmjG16q6/eF/LTqdRmfvncL6euZ51uyW2KlLP4n6WMdaZNx6QQjyUSUkSjyQ3csNbKdCMFiqpo00FVrVHX4msQMrbXPM0jUxJmRL/p2N3KXtL3lqGz9M7QaUtnLR9sdgzacet77p9GXu83jCVilGZrOjFarZBjJLb7Upu5c61C1R+6gZglJazkdq3bhVTX1zRmolZ4bcRAtLRZXpuIeT8T88h26BlnMRJNxTNOmfsnkT2J3EWKw6wTVVmmmEkVxsMMiPeaqooXNzueHgP37x8w1tNvJYCk7zy9n0ldZpwnjNZNumjxTuO9YjCOimE8Z2puQQWlMBZJM9VGSQCKBaPEfHy7FZDjfA7UKmajSkswBkpo2SJVh37jePXBLe+/eCRmYXkOmw2FQpgTFc0UEqkq5pTotKTd0ZqwJgrCNln7Arh7Z9bCK8WM7yybrUPryvEgQK/WbShjFfOciUGYd6jK4XFq9VnFOsX+RkIuSpNZWWvpOznHSqmESVibSyIaWjNsHff3B6ZzwhhhN5zHggkF7zSbLbhOfv7N3SBsTKsJIfLl907kGsVAtyLTdW2xWuGdwVnN6TRyOk+ASNpTBl0qJeS2Txb84JmT+II472TqXAqxxY3rqhBWb6FzGusVXedkQNMarCXpzTpLTJMwXa3COHn/qkqzJTJKczGlT5aQJHGr0hh4XhgqnRPvkGkMxDnge3t5UCooLT5RITXGqspEIn0756sy67NFKVSVKUoYHhfjdylQQ0r4bLkQvwqqFowCmlxuZbNeFZnXbDClaLK7y9tURq3+Yxd/HNDLh6gXvyOjTWMcS9NkG5Ou1ExOEWc8vvm5ZB0JU+LhcOLHPvioMTokvfr+8cibt/ccR2HOQxH5uzdrmjWqyplSC8U49nZYEzOrWqSjdm0Erj2ZFqBqMc5ffgcBTXIRcAhlcK5D65ZSdzWdX0Hvr7BbVDvLVpCigRF6+bpFTtm+LLZhXL5KScsNUHOmMTXLIl1lNY4xxjYZbKHNm1iQg9r+2SK7Lxo0Vx4qSq1ckZQLMRdQUoOlIgCCM5pcM8udXr425yS+gWFeOg+GYaCuzUhdz7eKeG3mqhoTHnKrDYympQbqNkSqz34pJAFVOxmQLGDHksK43C+tLV03QA1UrmSRy3HdbtmyLi9CO9qzUBqQyHqOl7oMiZe0OZ43Zg1IlfpMGJy6JW/LM3YBsEwLIpKasjHG8hUgxoWxuH52tbDSaO9BAWYFw5JO6/sDJdeVImyLNvQw2lDMoinSGG2xbbColZxvpERq69/IwyF1XPvcRrfgCGsZNht8v8W6DmflbDVWt/skda7RXNhvy5OyALSXy/bsM15LaJXQVq5AZlh8C7WSoe3yjF2/FoBMwBEBaawST6WUhSWyLIvFv6rkhLeWTSeEA2VkGKKsbbhxFauaxrJZJp2ijJBwpIqWAcP6vaFiVil/SBJWYRtLfdnLrbWXHiMnKEWsbNSyBiCEhFbxUk/qCyBijSUpYVflXOS+Kk2lfVYy5IKqYqCutAWlJbAht3NzCWMxtsnrmsVBC5JbmG3XLwEqqmw27Xo8Y3/qNlZpgyFRtbd9F6mr5ExY9rTW7xQB5HPO4n3WzvVrMO7iiSXPl14CXcrF2kYhgGYp0mNWJVhgmAqu05gmzRbbmoWZuoDXihRhqplhWygJrAflMmGGeQxYVbG9Bc0KpM8x0PuBrutx5mq/aK8lmRXkDLgw9UTe7lzH4B0JSGXZB0sDWGGxNrgwxJZ7JP2TdR3WzlQk5XCRi4cQJNjIeenLjFnZfkrptWupKKi5AUtyTeYpcB4nUkg4XVElUUta709tw5BzKeuAcO8U3cajux2xKOZpJk4zp6cju66jNMhoOWsX8G1dW5cj8VlNIleuLgfcquBf9pLvB8IWbUFZiqqEUvns3YEvv3zP/dOR02nkfJ7EZubuhhd3t7x89ZLd7S2HcZK9q+Q13fef9vqhBsKWxlsbIwh0e/DLFJo/l8Zaje9aGkRMvH69bYBXz3e/+1amJs5KKqADYzcYa4lRkiONls3udJALmpIwvVSbNCwmvgswpZTQ+bS2OGelmcyZ83nCecPh4cz+rqdzlmQlxU5AImEdOCf0/XlKnA4z05gadVnAC+ek0bCubRRKUum8k/dk3bBSY3PJDWxrJt5JNsnFnynM7WGqlX6hRyuNLg7vHbv9hn7wQpWMkZIKShWUEc+AeLXqwxxZfB5yEoAtxcI0CshUZXRBSOKZhTayqVcBNGmH/yLhUK3xA0k81FrR9RZjhV318PDI+XjCe8uHH98QsuZ0XOKI29agZIoXU5RqsSKRFPIfAgp0FkImzJkQJereVTGi752j856pK4xuYhwj0xTEK6RIU5JzwXnNdtehlyajsB4mcgjINZ8nuRfWNlZFm8xTK513YOQ9UCuu+cBZ6yilcjwE5ikSQqbqgraWmxtL1xl8J1PubDO+NxgrP8N5KZa00aQojCRjBOTLEbxzaFNxTsppaTyVUH5VblN7J7Kj1swJDTlTmk9FKZLyEtOSoCNU4SVVS35+k9npQuetFGYZpnFu0xwBhF/sNhJlXuF8jOLXlCq5meyzNCXNy8AYe8V+sIQYRZ3Spqdd70gxcRwDMm1bJtCy6Qr2sBR8mtwmbKjnm7jW7XNpzdM4tTUqDZRzllpnDi0V1DkvybEvBrqhY5xmnh5jk0II+FBKZQrNZ8BWOm8JU+Vm2DBPAWUUthcAZhgsG2+563r2Rlhcg3csx/Cu63Cq0mWHsw6VFWMOjckBnfUtjl0+W+ecMF5yYaHexxTZ9p6YNONhFOaa0jL1UZUUFckVsm0F6TxhXdd8doSRYo1l6Jz4W6WKtwLQH05iQG51WxdJZGKhZHKG8znjrKdamY4Nm4Hz2dP1PYuM1RnN0DnOzhJcImQBOrx3DL34ONZaxFDV9RyPJ0jLxEr8z6o2uMHQbeSeKWA6Z+xry6YfiPE9NWUsVeTn3lIba6RQGccRrQ3breO9KqQoSbRaO6YwM8eE830rAAs1C+MmoVDKNGmANAYxCjMwKwGo+s5QcmE8RWqRRGDvPaUsCaqJWiO+k0J/jomSFeNZhj7Hx0BJrci0Feel2YopEsKMMpbtpscozXieybnS9R25FjadxnrD4SmQo8SAx1TAVHKUiWzxhX5wKzPLWM1m1wEQe8M7NxJiQZVCiJHD44gEYbgm51fEpBinZe/rmENmmsQw+/Q08vgwCkDsDUYpYXXPkRikaakpU2NZLQNqNTgKw9aTYkvqO8z0255UliZcDPmtq3RDk7pl4dtpZeRzIuCh0QZj27DEiFxpM3g0ajUp1m1/00YCaFyRian1WgiqVczxpxikCVWVosxlz1G61Q2X5mORrAk7Rp6vUjLWudYQALUVnaquf7/4Gi4Mi1zr0qtcAK+lB1JIotPXa01Wtkfb78QDyqwVrUbRe0vnHbuhxxvw1rDf9nSdoajExneMIYiEvNUpx/PI23dPfPn2ifdPT0xxXocim8Gx23pukpM9qbMCqOie282uDWLUyugxxojHlzbPwK6LzOjC5KiLd02p1NrMp1ffLb1es7XLZ2EkLuCFvvxd++1aTscK9kjTVYuciSk1M+58xjjxhIxJjOBBre8LpLZZmATWe7GMKIlaFilUuyELyKcVqqpmNaBXAMwYLQwaYJoTaIvvpL4tOUKu7LYbVJxWsMouflE5omqhc2Ie75zIyRWiAKA0aQ+tmc6yhy7XZLGGoBZqzgLqX62vxTdMPu9F8roMoxavsVorOQowbDiTSc/Yd1qbS9e0eErX5R5fpEdUVobZwhTLjYEpgKL5mon4wt7KKWOMMHIWMMCYi3xW1szie9saWd0GCbkxwiorMCqMvbjKLi+A0QWw1Vl+LWb9pTE7ls9kzRI6IYPY0PqbZ49wA8v01f4hFgoXFpnRFyax955hs6EftljnVsbewuhRSpiEVnJdGlgk96yue8XlPaz39AoEuwaUxbRfi1VAA/bVClQ+BzLX+61Y9zrdBpBag9WKkEWRIf6wFaMqnZNBxWbYsvi8WSdJdjHkpurQZCtMsCVFWIaqMtwPZXnYW/3X7kXI4llUmu9dVQZtHFJQSM1Zq7CfUs4tgVBSHheFQZqlHnDBEjvPMAzrcyKAlQDNZklEbftaKiK3LM1/ySqRi4q/cSLFIJLIpe9sa3+R3KYl2bKIL+/zl+yNQv4oK3BG+9mmhWQsa6rkdl+rDKaK6AfXB7JUOZdiUzClNrCOTa67BBzJvq1k0GYuX1tqU4IgSiVR52tyBS3YPiDqC63l72uFWgRcVcbgfOu5FuC5VlQxkL30Y0bqyCnDXAq9BddUjaVUQkyEWDBb+exyz9fHTK5rbUNzrVDaSvCNMtDOJacVul3bojW1muY5/VwmuQChMpTKVCzGOmzXocfzeh9yFmujEALBB7o2DKpcPC3l+4hX2cKw0saw2QyisKqVt/ePaAqDbUnMCmIIlPOIiRGrpCa2pmPwHovCbAY+fxgJ75+oJfH0cGDYbVDWQVN16Qq5Xlrry+pa1nf7vS5S/roC6As7+ge+lHgYVhQpKx7PgRBm7u+fCCFia0WXQm1BVJth4ObujtvXr/H+O+v3FjbnP/31Qw2EpTmJv0Y7dHOSkVqtrEyWYbBsd5KuOM0T1mpevtrw8uUNn/7OG5yxFAovXnYYrZhCS35BfJnO58DpOJNSZLPtGEeJ+gaaXKm2+GmZoqQk0g1vO6yxxBiJMYtvUM5MY+Llq4794DFFEcolcdIuzIAiEfNhTBjdsd/fUEpaCy7fiQH0dA7UUiXRkkrJkuCltDBtchFp3TxHYRW1wdLCsMqpQhWEvesdg+mIOYmGO5c2qdegCr63pFgYTxPGKuYWLz2ewjo9SymLUaR24DUpCvJcSmlGs43qvkyp9DJphprFc6c2cM9og3P+Im9VZeklxLB+DpwPZ7b7gZcf3PL2/RFjG+Jv5PCUzX2JfTZoU1rKh3Q7OWWc2zCPgZxhDoV+IwlRzhn6rgOnKSlwSLkVdNJQqKpwpoGdJdLvNuQo8idhekkTnZJIbLSWgsJ7y81Nh3Ea31nG8QwausFjneJwPBFjxmn5t+ILVimPE+fzTAwZ02tKgM1g2O56SoVxTAzbDufFI8U7mbpHk+gHRcoi7xXfIsT3yVk6D9XGdepXGjPIathuLF5rwkYKtRgKVsGw6YixUlCcZ1mDi6dTTJNMuEshRGnsloLeGi0m08A0BQ5PZ4wTMAhg4x06Z54OIv+MIYt0q2YyaZ1eoeR5WXpK78QboTYZsTIiQxKQipXZIE/tMu1aDIubaXaVqdRicK3U+k9ZaPgipZGNfZ6DsP22UkhWiqQCOY1zhlevb9rUuErKZYzMk4QQSKKewneGrhOg03WGmiuud00+JKwV2szHoqUY0ooUxc8pp8yN66nAbhD2yjRNpCCeTc5q6C1V1QaCigdHzplxmlBWt+bIcrvfcjhP6FOg1Nbwa5kIFiohRrxzgOY4nrAxtulma9uaWbbIbmehK+8ksSXEDFX2rzmcqcbQuYFxTni35eXdLSklQpAiSmnNqw9fEkPGWpnOeSs+bd7BUBy6c+Qi91DYADBNka3b0PWe+TwLMGmHxgoC5wu+GXCHc+IpToQP9tSkKEX8C10nE/JCZUqJOhZiViid8S5jHOz2wiLNxZGSJMDGmBv7sIHQV83Bsh+l0pi4Kq8JXqYBtuM4U04R72VKr7QmzDIxlKaotul2Jc2VeSqcTpHTIYhlRdsbpbBN7G4G4lPgdJooOAFstGmpplI8GyUMnf2tMDFvXw3M84GaluAH8aWbgyQm7s2ANYbxPDP4js4Lc6nrLecxoJRI9WPI9F3z4soNMPaKza5ZBVhDOMg6SzFxeJw4HmeMhRd3W4a+Ywq1Tb4lvTEmMVw3xaBUBCoxKfo+rHImXRLWNWlcBWMbiK8rw2DpO0XJhlI0KcD5MAFyjamz1LQonLVYa8lJ5HoxHQVQ6yQhUYCwIomQSrHde+EVaTiNAedGss8EY9mYQZirdQFAzAVoaXuZgjWBdkk9kjXvxN+w7UO5ZOocCCGvRebyWmZSiwfaAtYsD2itkFVdgbOl8VsntWhheTZ7gZqXXCoYvOVu19P516gqlhOboSNTsXZJAYxsnIM48/BY+PyLe968eeTwNArTvPmYxJSZYyKWzETEKIObMvvBcjKBcRdw2nGz2axSLzmanjO+SpPJgQxdVvkgl4Z8MX5e2F2XqfOl8V8AlYs/jlwwpRdZ6QIk6PW2XZ0iwuaIcj9Ki0NTSCoZVV3Ybctk/KqBMVbqh4VNLbVO4+i1vX5hTyygUF1/+mWSXtqZZKxDt++fFGhV0NstNUXCNKGUout7nLOM5xFjDHe3dyIr1UZ62xRBWWmki9QS4m8YBPg3z5M7pUEuKOWesX1yukpcTLWl3hZwFt2Ao6VpX6SuJ47NZ8te3XcuaO/iAVVbIvNyzar8udKq+YEi1gV1YXyIX5d34tMmZ6tZPdnCHNZwKvHME2sHaxS09OwVG23/sQx9V/ZZKSvzXIZ1uflpXhggy2thwSwgb4qZmBuDawGyahUvnbp4mzX2jVrUDXVlhUltZVYZc1pqngVMbmymruvY9D3DphegXakG8l3WkyRHyjXUrXhapXRXz9cC/F2D0tfMH2HrSE1gGnW10vCT9v9d5L4XUE2p5VlXAjjQUlcbsyZn8WWtSuGUp3ixQfBDt/7sYePlTK6lWboo0FIfuSaPFzl2bGCY7CO1WcIs6qAYZXiZqzQoNchn1hSW0IzllRvZIbrE0HlJsa2XvxNwKjX7Fr16ls0hrKoRYdjUFbAVNUchqSJDZSMKEmGQRanVlzqjFGIM5JzW8/J6za3/tZ4LeT0zSgO4FKxr6RlDpxXD6/1qAxnDRZqbskj7x5bMm0thRlIMO2vWNZuS2M24BsinHGSAXWVwEGIhZ9Uk0JKCrKnyXGfpQVZ5qZP62bi2VxphXdaK9CrGQ+qJKjJlAYKMMZIAnSrOynoXIE+CR0pTjsRUwdDOleXS1UYSEBKHUsLS09quzC8LYIQ3tzxHabEyWs+ky/UU0FoUXc55nPNM47juiQphheWcqa4xCnOSAcTV+muQNSgZ3Vpr8Z1YFI0hcjif+aBJG53VhHGmjjN9FTzBWIsylglHrAo9R97cn+knYVedDyeODwf2w04i25Wk1y5nz/d7fb8/b1sTS7DP0mY9X6eqpcSKl+vxOHM+Htl0Du8sFogBbvc7sZHxFuscw3YjoQp9t5771B/w5r7y+qEGwnQzywxzEKo+tem3ZTP13tL3HqUqzmu6YeCzz574oz/5DZzz3N11nE+yG+Qc2G63nKfAOM6Nimg5nye+/OIRbzTnY2SaImZpcL0VglFJVKXpvLCzFJnO9xhrxBA654ayVw6PI+83J2wtbHYd09MJBdzebeVBzKLvj7OwAZz3pFTQxqJUJoSJ/X6AqtnsthwfR3znmoG4LCznLMUUiWhVGmMbIl81Tw/HRiEXj6Tj08Qn39owbHtJi0xJmksjB0PKEW1hs/fNI23D6XDmeJjY9T0xxiv2jBQoYsS/UPClQexaklMMCe0cThtAY52T6UcRdl01agUiQpCIYilEFMpUvDccnw6UnFGtGE4Vjg8zhUKMM13vCcEQjnMzaVVgZNJVlaFmMYh3zqGrWfXaMt1pMtpUGEug5sJpnDgex6uCSQ7nfugoKTHsB1CaGDM5yrSoVmRiZ8ya5lJrwVrNZnCMszA1jk9PpKIxXlI7rTOcxplu8BhrSUWa3jAWcmL1brMdzFNg/3JHOM/MU+DmrseYiu8dJVWsS6DFe4xQqE6jtFCbfVfovWK7c5K+0Ytfl8mZmjI9lc2No3vVkVJlzhlhH8uk6+FhIqPRbVJijWVwnrfTE9ZLmZB1WXc5YwzFSspZyZmHd0fOp0BImR/58RuoisPhiFdiCHk8RqYpyb1bi8nmT6E1VJlS5nadl6jf3GKN5ylS8hGlm18Ici+sNrBMklgmVFKMXprCKw+M2lgaubbpljQmMRRCTGhT2FnHpu/YbsV/7+7lBu+kmXBWsdv3hGCJSRh58zzTbxzzLI2+yG5k0iWsB/C9wS7+cdoI8wtDTIkp5PUdOiMFhe9to8ELa0AhTaCwVPLlsxTxBjBao5rkab8beHg6E2KkayzIzlmsrVRdiDEzh4QxYkhZKsxhaj/HrgUVbQqqtENVYTnWTcUnaapP40SME/NY2XqPU5Zh2PDNjz5gnmeOpwMlzXIftexDzkmDpo1lGLbiHegmcoU5SVG022zbNCxxPEWc98xzYNg6hr5nO2zlfkQBdyRcopBy4OkxcDie6LzjNAVUS/FTmsYoME0W7Ol70UM7r3FOcXqUIcA8RuaYBJCtoJWhHyzo2mTNtYEKmpqFaYauaCvsKuM9xNKCK2R9nedISjKp9c7Q93KdpzERY+H4GEUqYCy2ExN3ozV+Y1eJsLEiA1MGQopk5BxCaeYknpbH8wg6cXM78OLlwPEwY2ZFCC15aEkta//TKFIUg/PXL3fEFHFONymNTO9yrkxzpBs6xDsElLFYJ82qNHWZUhePL8uwEZ+WYeO52fXkp4DvbGOaNh8spdf9VytNSYV5DIwBNtsO3/vWqEsjXk2mtiTgznfUIp5MxigeH2disihVqCmTikzbaxFEsdTCPCZSymy2wgyzTjxlqBDzxDxHstW8vBsISWwFJp14Opw520DvHWbj6bRhgYzlmLw0lBfykWLoO1wS5pnWmr7vWxMs+19MsQ1VMix+fu3s1VrAQAH49bp2rl+1IGm+yIS2Ll/fft7CYl58O5b36Z3hk1ebxZGSirCMT9NMUYppPPL6dsPttuc0Bb748onvffaWp6fT6jO3sHSkJpCwBxx0TtM1cPo4Bn77zVte7W/Y9sMqc18Ap6LKyj4IMRLmGa0ttjUlsk9odL0kVwMtpGYVga7N9vIZV08WoNZFanSR7aEu4MCFjbTcS/kHYmSescazwDHeCvislCKrvIIHpVYcNN8gDSVhjSPrSq356n0qluRqpb6CfAIpV3JJMpVPz/9eK5GyOu/Z7HZtnYhk3zlD8Y6aG3iw3OuSqeXiCzjNgYenEyGKZ5EAxGbdD4wRhlnnLatM5uLy0daXMPLEIqCIQ2tjnMUY14ZvadqLypicsM43BveyZ9QGADTgrF5YY1dP1vo7LGvakOdIKAFqxTUbh8WkvyIBV65zCPs5UasYjxdncf4C7l3WyEVKdv1ny/3VRl/2orbOniVZtg5RG42WopTaptTijSXXLiYBNFLOIsVvA70FmHW14q14sbrG1lvAjGXdLkEHfd+zGQaGvmPTC0tcnqXFRJ918HVhwnylTVWXPaI2q5NSrsGvBbNU+G6gNnsSs9DX62VN1HVC2VicSwvcQLCYxbT/2o/Mao2tzZQdyNqStCW3+m95EyV//VkptaKr1OClqMszraBW2Qxz1cQ0y/pv3kwxSkDIAmIIewtYntNaW2Mvqebi6ZTxXnydnoH3tTKFsNogSOLhTE0yGFsAuGtAX+rShRzAeu/XZ6wuXnKRklMLSSgrCCHv+StSX3njbR22ntGAQmpO+W/FFGYWxvAVZtnuY2lD48ZGbt89UwkyFaDQQread3TODchGrT5/y+cstTKHwhTETkbu4MVHte8snW3KK6NxnSi9jFWUBDkKI3phG1qr6b2jZkM1ifOUOOZI55rkMEaMNngndjM5V2J/YdCVUom1gBP/NRCWuGmDrIqwxr7KtUOJ6EjCA+wlLfcKNL6WS5ey+NfJ8M15GTantIRtXQXMtDNMsQQ71au1tdgaiG9XLgXvBUxS1nCcE31J3Gx7Oe+KpDRvfMd2M9APvRCArGGwluN5RgO3H7zGtJ7hfDyznwJFKaoRgsla+/9TXqUsZIQrMH29Fld7TIWiNBWLSpV5znz55kvCNDLNke1uR5pnrDG8ePUCZcQX1GrIMTCejmw2PQsDdxlE/dNeP9RA2GKcHebAbtPR7Tp56JuDm1ELuFBRkyGkyDRPnA4B10VevtyT4wmlCqWI7MRYSykTIQS0Ek+jwVvCOXA+C+jjrKYoxcvdVkzPkSJj2Q4EyU84Y3Atwc8YYcRUFJ/9zgOnpzM/+rs+4HSK3NztiEma/uNhagejTAxFPldb8X6m7zSP9wc++MYtyxQjRmEDqQq+eR0oLWkdlMrpOAsoo1uiTRF5kmpF5M2LHefzTEgiY5xHMTz0vWXYddzcidxymmYxsbY7dvstD28eBYwsmmYwJSa5pUBoU1ctBv13r28oSJLYNAa63hPHzDQG5jmvSH5pRtghiCxLG2HLSBx34XQcudnvREr3eovRhl/9R5/SdY4QClZ7uQsy4GvFg6ZWTYygEL8Z8chSPNw/EmMAUtPCi79GOidKCVhTsLay30kSqcjFxC8IRHpzPsxM4whAyZnNpqfrnfgVNJ+bnEsrpguH40TVhRRFT951HmU0pxCwDbxNqXA6zyhlSEHS1mKErCWhpRsMcQqY5lXV9Yaus6gGSk1xouQZQ8U7SUzpB9mAdjvP613HN17dMljHGEZKiVAKc4K3bydiLDyFgvPNX8kabu82hJB5uJ84HkZe3O34+Fsf8XA68+bdAw/vDqSpMJ+lOfbeXBLQNFStmXLCWcWrux2boQEI1sr1Nz1jglRpcqciz0Lj0WqjUdW0qaih9ciEUJoh7BIjXQlzJsXSTD2lce68Zdt1kNskv1Tx/Wvm2CiNWRqOKmyXlCup1AZqavreMI0ROoezkow2HQO+2xCjZb/TknhaRBKoNfS9a2yPirWefrAcjiPjGNgMDu0kjGIx2xUrm+bxs0hUSkVbmSDXomUaUypzEuq/aweldw7nfJvIX+LllxS2mhu7oMnQhBVoeff+SZhozR+hH3p0jSQiSbVUmSzTo6phmgX0NapN6Fp3nXNhnBMhFwbfMXQemJlDxGrNtt/iQuTweOTl7QtMLTy8f8/rFy/5kY8/4Is3b+XanIUNlmJufjyabtjihwE3nTmfJzpf2G69mGRXmGPg8d0jm90W5y394OmcYbvxdN2GFCpD13N3t6XqGdtrfufzz/j8yzf8yLe/zXfmN1Q0/dCx325wnSSFeV/ZbD197zg8nrFe5L7Hw0k2GWWo1VCVsLeGzvH6gw3WVp6OZ56eQpvQLoluAoZJMSdApiql+ThpatGEmJiOs5jMW03MhRAklTeMmYe3E1UpXr7csL/pxZfOSkMVc2I8zWw2HRVLreI71ncdKbIOcXIWFsP5LImHH3zjhsf7mffvZ5ylyTZUY0Fp5kk8fkrzmjudRqxXKGvY7z2nUzP5VRCTTIg3Wy8gZZY9PE4is+86zfkcMN5wehu4ud000M5htPh2eG+YZ00/+LVoXiaJJcu5ME6RvuvZ7Tr2Oy/vLbepcs70G7++d2s8w9BxOh3IUViZpcK7Nyc++uQFMQLKyTCqMRQ3G8d2K2wX24Yph5OYETtvCDFxOp0ZNh7lZBhyruCcTLEPSthhW99RlSGVdKkcFcL8kQ5YGJetSVk8SAQEufJwUcI8z7nlfIAw/IzIjQXYqY0RzRVYUxuLqhWgZfERk6bEXiVVCjFpARjkLXW+Mau1ZaHieuc4h8S+VyvTUhm42XWrNEc+5vXMt72KpMkqJ/LQkgufPR3YJ4u2ju185m4Y1sTUWoWdFEJYv3dKEev0pb9rRbWw+XKrmxCJdGtIVbte6/XlusO7XM/l3Fj82GBp4GX9L6b9tVZiCOLXWipGiR3GcybYpfgXxlGTRppFgicWA0v9tL4N1OppWcoFSPzKZWxppAFq4qIfLKia6fqBvt+gUJxPB2pJaFVFGpe6NaFWvtkFEDxNM6fzxPvHI/eHIy9uttxs5WyrpTQGixcfJ3Nl4t1ACoyltsAQYW5J4lotjR2pRN4u4PmStC5p2CknGWjBRUrJYkUhzJpcG9voir3yHJgSUMZag7UZVRbJojS6RhuR4yt9AY5A6iC0DAHIDfxhvQ+Vi/z2mu21nKm66nXtPFs3uV5Av1Ivkld1GTBYjRjDFzFoTzkyx8gc0upRtwzvlmAj30zY5Rl5nnbabgfee7abLZvNhq7rWo0gTHSjM7noJplSq7H+93uJdLExlxo4K71TAUpjBILWHt9vien07NFabCFK21WWa1dVabLuZuGiYJ7PDC1t0Dk5x6hXiaFKQAgDTKUwx5YWqmXfX8z6YfGka4l0z1hrV2tXECUUAgKHeWae5+ahuoD5i6WEsG7KguzR5Ohat3CbSkiR3UbReX9ZB2Ux3pe1OM+zMMJSEoCrPUOlFHIt676Um0JgQVm0XrygZT2lmNY1XzFrH7qwSEVx8xwcVAoMskeglFhmaFFIWAVoxTHOUAsFQ109sZbnROSpz15aU7VhTnMjAFTO43wZyFRJT1TKojANhLwC2RrjL2UZTE3ziHcytKR41K7isFA1BketivlciXPBdQrjtNiPKNjtHJtuQ9aJcYLzcZbBbAszm0NsQInDai/DzSWxtn2uUhM5KYzz636+Av5ALQkSrZ9sATdKkZVuTCmxVIhSWDRj/+feiAsrrDYfW+89pinJbGMEXw/PlNYY48Qf78pX7RmQTPOfdLT9XwL5UinMSUDF/Ytb9s6wHzo2Qy8hczkzTRNhDtxse370I03feZ7u31NS4ng4cXsa5UweepyRHmkBw9R65b7/a7EaoYGoX2ODVfk3MTtSBm8yp+MDb998idXiYb0ZOtQgARdGazpn2G8HXry85W5nyCVADtLnbndCTPlneP1QA2HWalKbmDtr2N5ueHocZfJkYBwnYUAhiXalFmKJbLYb+t7xzW/vGY+FN5/fc9xveHp4h3EKZ4UGr5XQ7sZSsZ1jPgdAinzXW25vt7x7/4g1ipIKx8N5RW6LThhv2WtPGDNhCigr8ptU4eFp4uZx5nxK9PvaNuvM+7cPouPvu5bCKKXNNM3CYqkapQce3j5y93JHRdHvRFbnnXgKTVNEV+iaNKxuKrnCuy8PTNO8ZJWSiuJm5/Cd4/H+zJsv7jFazGmNNWyaUXTJIgv0nUi8usGy3+44Njlimpfl3zY8tcRba4yRpDFFoes9x8ezmBTHRNdZQgBUkVJASRFOFWmekBd0O/yE+qsUPD48cnvXM82Jh3cTD/cj+5ue7a4HJY3YMAg9OTc6bZziSkNVSlgf8zyjamToFBWDUk0Cp8SroHMWZw3jORCTaLe9Fx+kFy9vOBzOHI+B03FqwErh1ctBPNy8ZdgbQsyEMeCtZrsfiCGLRFVrwlTIUeH3jhgFFNwMRgrE1hzNU+J8lBht0zeKsCqUmKkhcLyX9W200OL7Tcd5HJnmmW6jsUoMbb2V9KBaCh/dbZnTyHSe6bcGowo3uw1ee07nytQpRp1Q1kk6XpzZ7Xu8VxxPmWmObeKuBfCyipevbpi6zOkQeP9wIswCYkmQSiXlSMkRZz2dd2y2Pa7vSTnR96mZBxdqk4TFWATMaVp9tbIVFM0SVuQg7Tktua676uIPoq2l6sqSLrw00JqLhEgrxWkWphDU5h+lLlPqZbdWSxqoMAGdBe96hsFzsx3Q1hIJFJU4noKkgDopsrvO0fc9JSvevQ18+fYdzsh0M4yJF3cvSfMk5u4x4Kxvkhn5e5I8sikl5hSpxdJ7h7VyPXKpxKmlZaGoZGKd0cqiWjJRIq2AlXFiOj2Os4AZVkyVvXdUbYl5kQoVqqryi8IcEjFHtBET2eMUyLHgrMc48bQqaFIWcHKeRm53A945xnEipyRyE2epVmTAWk9s+w4o/PpvfSqTbuP54JuveHo6cDocSVFYD90A+/1WivUKitom4ZVhcOSDvJeakP3QdyIXsq4doBpvPUPvMBom84gqit/9e75FDoqbfc/hKGtuPxhqDVgjSWsxprY/FeY5iRS509y/H9FGZNzVWIwTU36rYdd3Lb1LMc+F0yFS6oVxI/L9Rb4ld856xelwRlnVvGybMSwi2Ytakn1sJ7LQYbC8fD3QD5Y0JT7/8i2987x6ccOcArFWlDHEEHgaI85syFn20hiSTOlmSVAuuRBzxtrC+RhlUm0NJWtSlIGLYpEly7rTDVgVRm8z9+4tNUvqrSpBJKFofGfIyVBLwvWWu5cbYoLB9Dw9zWtjKAzMTNf1mPMs8uUsbCDnLNYqwhw43GcwsN2IvH3rm1S9VvreM54yD+9Hci4y6RwUMQfmeWR/48gPAWMt3/xdLwlzZthYxlPAaJFz7Ldbhq3l9Uc3AqaNUUBwBdqKt5XS4rdhvWU+n1Gqoxs8c4LTPPNkz3ywv6H38m9zZZ36L/NR2aOl0dDartNdaQ5aM7QElLT0M5loXcpOkQFrScwNUlQvFIzK4mXVPETa/ZMgCCna1dKJtJ9bvhb3zrpHLlWv0Yp9b4GFnVbxuvLweJTGa+3Fl1nwVYNmhVE0hcgUJOFqt4Ot70lZBmMZYf5cs30u3INl0tV+QmNk0fZoYW1JyAStJpPgguuJfGPHXU+kkWf8Agpe2Eq1LjKntDKTqIVSk/jGKgnDyV/BEuryHpXCaAEunJWkwkXCISnnz6fXSqsWEPCcffT8H9GarYAIJwu5Kmqe0UbjXIf3HU8P7yg5YppaQhjwGmM7AajitLLhQLwkz2rixd2WD17diocsDTxt54i1VsIRls94xQ6oiFpDK01CwI/FqP/aV8pYadzLOihk/TcgrKi1eWznsrD8y2oBcm1sXUqr9Zs5tXOWvm++aKnVFG3pqAVM6nwLnlrcbsRzUsAweY6Wz7wuP1jljcuaU19ZR5f11JhsLf0dmo9VET+pxetXVwmIqkZTigSKlFJIOTcGyGWtWi7go2prW9ZJXsHbBeTbDBt2ux3DMNB13Xq9tFY4ZbC1rmydH/y6gLLL510AOHkWLvWXKop5PK710lfv6fJjFjZVbeBpyfDu/onbXc/gvQD81jd2U0HTEkBbbbyyGGNYpeI1VaZRmNWLB52A48LkWbw6Zbu7hugvfmu1gYI5J2xjzgNNQrxsvS2AqMhaE9mlwy0sOgVjGKlk/HKdCpxTaFLy3O6rTCv01Tu57MSsDDsZkNqW/rpM+BdG2/e/bwsb01r37M+1lnrPaSg5NcabrK3OOTZdxxQCq+nkD1jX1z+n1iYvTEXYyEHSa0NMK1N5Aeb06sMo7PGYZOgrTgPSZ+Zpou88RrXUeauJs6RBVmexCXCWvtP4rtWqbT93Vga8SYs3cK3SW03Hia6xWo2zzCrS2cR2O2CtYfD+ChRPyLl27W/WHv+r61FKIkWYjWJKHtdZysLgXQ3216/82qVcvQ5JaC3e3MNmQI0SmuAakBpilN67820d2saqf86MbTesAbOGfrNlf7NHffoZVSnmlNnserY3G3QQFnvpZGBkWvqlUhJ0oErk8995y9PTkVoytzc7jocTH97coFoYmWoAbr7a+7/6ugbL2p9gdQsc4jlAW6vGqcRgpOmpJVJrZrvZYbzmdT8IA9lYvLXcNBVOSgVVKp11/K5vf8yrF7d849Urvvji3f/Ptbu8fqiBsPM00/Udd3c7tnuP78FNivlBaNgxV2KUTbPQY0xh24u/VtWWX/+1I/NcqEozzTNGSxR0ijJ5r1l8EUHS9gA5OHtH13t859n04mM1jTNd53HOtCmSHE5YYQyUkpnnREkZbT0Yxdsv30tam63cvthhjOH2bi/eWEVMcWVAo1E1c7PvyVkYGykVHu+PQMUZzbbvJPlwqhgcpWZCi1CNKXKeZLrBFZmzVtBWSxONJJ6UWkkhkUJi9Irt7DDG4TrR4lvl6PtBwKFYiZlmQG+gRVcbY9jtBoaNl+JKK/resd92UArn88gn3/iQMM0tsjWy2XhiENPC2qZmShdsL/T/glDOd9uB2xd7Pv7mjqenkcMp8Lt+34dM5xmlJWa1qkQtCq0kVW6cIr/x6/eiGWeJVk8yHSqBXA23N4PcXqVxzbC2945SpSAx1jYKcsE7x+P9CW0U86kZybanfJ4zd3cb0IppTpLCqWSSfjzMpChSnf3tlvE0c3g80/mOd+cn+o3He0kWzLVyPJ6ZRvFRsZ1In/peDG3fPxzxWnM+nBk2PSA05NoOHWuh31mcF8NwkS8YVAanKsPQMU6RTz/9bX7yn/+ITWc5nyZydtQq8oFhsPh+oBtuub3riblwOEXZYHvH4+EEStKq+r1mPsBm8JzOkeNhYpwTs9GSSqTFd0lkvoVpPtMNFesrxjqGrebzzyech9/67hPTnNCumatXSYxbhve1AQcyq5IGTxpB2/zohC2hUhET3+b9nFLhGBJWK253Hbc3PfcPI2q+RCKnZsSvVIukbglz2ohePaZCLRlnDDfbge3G8fb9iZsPerSXgyfUFhc/VbyH7a2n2zgOD2dymdh2ncgqdeU8ZabTmTAHAc5UJhVJg9Xo5j3TJtK1+fthn02JrlPJTAsO6F1j0NBSe9KVuXBrhCVJMpGzou968XhDkUpci9ScIUfZ+BYpSUzi+1UUhFo5nc9YM0NpniTGkJM893nx+ENYZTGLPNRZx2E+UnLgt7/323z6+RuMFf8F0xhxIchzr5yWuOcysdns8MYweEn61dZSlePd/SNDN3BSEzmB6zW9Gxg6T2ct2ir63tMZT4kjc4ycSBgjFPlX39gynmdinNnteqy5gOPCmGhS71JFHprhfIpN5iB7vdXigWe1JYSEuuv4+OaOx8eRaS6cj4nxIEahxmlcZxi2HTnkdZoeoyaWiM6GUoR9rKswIY2u9J1Fv9hRSqbzhhwr3okPj9Jwc7djPJwxVVGDoZqMdQq38Rin2e02GDRffP7AOWYOhxPf/NYrCo5aM9/+0Vs++/SRMAWmUcDGxa8lRGl4ttuOzcajdSXmSrdxTOcg6YlFsdl0qBLZ+cK5pWnWUgljwnlFv+lXM+1PvvWaXz98JgVlEK+hQ8h03sv+Wwqn80jfefa7Hm0ElMypYqwiNOlBSYrzaaSiGXrHY8nUmiUopU3RMwWlK9Y7Tgc5L6giY91uJKAm50rfa2qxbPce6zLOwu3eMLnKp6eJeR6pFaIRc+lYhal2+2rg8ZQxXcc4jpScOZeJrfPkIkxkg1k9Q6hQtRhD05hgVmtiAz5ibo1xEfPtGGMDhpamu64DO2pts4RmqJ9ja5QaC7w18kKWr2063wrZZZDQ9hMxqgdlzdcYUUvx+n1EIa1xNWx6x3bTk3JhDlGk2ctMQVW0bsOo6sBIE6xNxTtNzJlPXr9swKG853Xa3Qr81fOr/f2yFar1PUqzN40jxgac96v3qF6aaKVW4OarQBg0xsMiyVvZP6x7QPu4bTCg0UWhS8GU5nn6la5ArB2EiWS1wRonTS0LyLWkWV59jdYt+Eh97fst35Oqrt5PAwDTxDQeG9A+o1DM51GAD+8ppTJNs5gOW4uzSkA0I5LglEVCeLffrWD9Yt5+/VqudUpZ/PK4NDy1NOmYEils5ZIYt3pOrZ9TraBfXqZWLNe6gUfqipXV7kcueWVficeQGKCnxgbMOchndlZYYEq19D25TuIzptfURFUuXl45CwDlim0pzHnp3QW4MAt7w/xAQ2ZjTAMqW4J5Y+AqJczsoheD/iYYasCMWxMh84Ut016lVrknRhIGUZe1IddU1pTWst6HYWC337HZbOj7fg30+vpa+r4fYf23yz37qt/Z8rWLx1qdHMobScVdwKqrV6kXKHu5b2X9Bbe3N8JSqoXSbB6Wh1zGKZefXyhkUmO/CqtG6rRCufKSwig0Zf15MuC0Ime+Ave0KngTwFpKSuw2G3JOq//gsl+W2sDYXIg5yFBYe7zu2kBjGbpGxmkktCHHAuevqb3tk13uY1MfIDXd9T0Qv0T97Pr/IOD1wlLULXDrwprUi7G70QxWk2JgjoGQ4vrerxdE5xyhKL6ivF5fy3WJMTKOM8fTmdNpaiC8qCBka5F1LiymqTG3JCk1JFpdWtE9GAybakXK34CeBfAusYi3LUZESKo2hqcVb1ut6L3h5kZjbS9BbafmiV0kjKzUilca7yxzTJznkU/2H2CMFsKB1ijVWHZcQGWUwGPX10feWyKG5pvdtz5SK1RB7JM0THNY1/HXX7mdxxJa0nWeh/unFWOIMTCHGTO2AZaxgmk0jGDxiVNXe0GolqIU1ncMQ0/XkofJ4vc8z5EYArH5YzrnGqgt/XjOhaenA19++XY9p/qQmKbA6TCuBvumSambeOXZayGXLr9fg2WXvbzJwhuoZhXYtncVYLvp+IO/73e1wZ3l6RCIubLvHTkl5vOZlIqog5Tm9naHqpmXd1v2dzc8HM4/4Jo/f/1QA2EGxe3dhlef7PBebm7OzXDUSPRu1ZWY6kpb77uO4yHhOsXiM1SxTGNlt2uFRYZUJOkvB3nQrDOYWkk1s9v2hCi6WaU102mk6z3DZsBZw+kcqFU8nZaDC2AaJ7xTeCNmbqdDbOyVE2FMdF0nk528yAoW/wrLbj+I8aB3vH37yOHpTOctfW/JSSb2fT/IFM4owpg5H2bZCJ1hs9lweojtymkxaO8EIfjs83u2247tbvEpE+q/NtJsKGuxnWW73ZJiYL9VvE/iSWI1hCyHXjUOqjR1N7cb7l7smVtIQa6VuWTmKbG/3ZJT4eWLWxSOuxd7nh5PWFNIeV59nzY7z+2rXhgRSpIpz6eZ3d5zfy8+Wvu7DeN0Yrvv+Ikf/xF+5dd+k847bm533N3uAc1vfOcN/WBwznH7csf9uweM0Rwej9zeiqHgPAU2mx7vXfOa0zjvJEmSjNGSGBJTYBoDvnPEsfl+FNmoEQshAVGsplciXQ1TxnSOlGb6ZlKfkzActrsdU0ztHklS2X1rtPre451MCbrOCTsvZd68eRS/BGeYp8iLV1uUkvSaKWamKXI+R2JQ9L0wi1KseB+52RlO50d0gRebD3hR9lgrjLSYCmNIHOfA8XxmiIUXLwzawBdfHHg6JZ4ehUn2eBxxXvHp5zO1QPpUJnr73VZkDi2t1BsFGuY5iezJiufZSOT+fcA4xdOj5Zd/6R6QxLtUCpvdwOuPXpJi4fBwlgSgmFfNPNrhnLBHyBltoPfLASHNmtYGkmqMOSR6XQnTJuXCF2+OwqrxUrDGKKbFUqC0dKdmluxaUxhjYZoC5wkSltNnJ17ddeQijLzOO2qjzTtrxfy3MVdPx/Nqpt4Pnhih6xU5Fry1hHnGd0uh3iZrpUhzUqRpV9pjW5pKSGnlSEgU8zIdao95LevktLQoc6VUm8bAkiyllGaKE6lkKQSspM6U5usCCm0X+QWM50DJkvaT2wS6mEoJM0VpXN/hNjeMpzNfvntEq9rkNLYZCGvCHBiGnnE8U2vlPM/UCRbmxNv3T1in2W46hk3HZjfQOwdVsdvvODwd6AeRwseoudvfoK0h7xNzmKgkDk8j3YsOZ1tCay0UI03857/zpTB0S8cnH3zEaTrz4u4G7+ZWCHmZ8vaaOQfinLBV47TlME+MU2SepSzqOi1TyAbkxZxwbhBT8c6TNxVrDyxlgNbgrBRsrrMMm44UCjlHxtNMLDPjNLPdDOzvdqQUeTqPOOvoOsuLlw6rLbUm5jEhJDtDQRNC4lwVv/ybX+B7y4vXvQwQNj27jUdZTYiFp6czXecpdaDkwjyduX8bsE6z2XToT0QmEEKTGGuN7zy1KuIsaa7GQ0nyzL74YItRMM+F3dBRq+Zwmnh8nIWhrYQZ6XyHMTIZzjHx9vP37PaOp8eZ9++OHJ6cDJMIzH2UmO9amUPEWMV229MPAizVWkmnytM58e1vbTmfj9Qia3meM/t9T04tRGRrJcWy05ScCWPm/ZtHXn5wI+byJbHdD9hui66KYdDidagzzmmOT5I8/OGLLYN35JL57u88YHuD68Q0N9cdvc+Mp6mlWDdmSU6ELGCB1WY1WKdCNopoNDonAd5bM5yKpHC6IvVAbB5ki0eiMVJ+GiPeMWtNpKHEFlCjDdpeGkmRNNW2HyxeW40NWy+tmrMStLH4kFx71pTmd7l4gF7vNwsQ9erllqI0b9957p+eKDUzBWlWF0zOOTHlV4096Txrel0phZthK4yp9t5SvkhK17Q7a1emWU4JrrycFrmhKgrvvLCN6mKCfzF8l6b0UsJff1a4+OuUBmbUxtoxWoMx5Cq+pKXktc8ZBruGTFyDBkZprDJoxDus856u66U5NfqZHAqaz9fzP/rKq6VNXqVeymfXGOuJYeZ4eOKQH2TIYDoZvDYz9iVRkxzpVcRZS4iFFKUp3gzdFUj4dQAEJPzgNAlYYBTruqstkKk0kBiad5VqzJomxUlJZJF+I8yHPOWv/YzF7qCoxRgfhKUlwEBuHlrzHJ9J32JMrYlLAp43NlmtklonafGezjnxHGzgWkWue6ltCGVbwnkpUCQMy1jTEtx4NpRa73UzRV8+t0iqvvIcpeYhu6y56zt7xbj6KqNiSZNcpFZai6eQyE/Fy9Raj1GK/f6W/W6/NrrL67mMVNg0X5eWXlhgX5WfLqB4ZbEzUaAM2oPy4lOE8hffubbeLqyw+sxsuzbPvYU1eGGkXoMHF85aKYVUl0CPCixSZbFWX96jeLLJnni5J8ISkuTdy+cqOTHPM+ez+KWCALpzmtteXp8Bqbl5r177gD1/CZiZ8vM1/VX2zgX/lrpvATSUWtaOKIa+KjFXSsDlUupV7SdMeOkdZV/IuYj9SkNyF3mfpEpe2LypsQ+nEIhreMiyhlm/9hrfFBBMWF9D37MJmYeHI850jHOSwXzbw5cVHOLUlDmKXCwpy8DRm4zK4tetlAR+XO/5C5DrvcdqjVZXHlmltkAgRT8M7LoNRVdKFrCtktHWiiJrDhQU3heqV2SkvtBac55HtBIlkNGiIFheprGg8vfhPsUYOR2PGN/RNSkiFsiVaizeX/aBZ0MAJed4SgpjCsZa+qFjs+2gCnO/lMI0T2ithNGp9YXRWqo8X/oCGodqWlo5bDYbPn79ms8/eM33fuczBmUY54ClcustWmWeno6cTmdCCCglhILNdsPt3Q0vX71oNhGRw9OBcRx5vH9i31tMJ73lMuT66mVZhnTrWqZ5Oj/7N83PmIq+Or+1kuCQm91GnvAq4SHj4UyZR+4fRM1yHmdSVfhh4HDa8f7hkbu7G/7IH/oD/Nqn73g6Hb92r77f64caCNvsO/Y3PUrBGCJhilCkSNNIsTIAp9OZeZr/v9T9Z7Rt2XXfB/5W2uGEG16o8CqhChkgBIAAKYokmMEMglAgRUVLlqxuy3bLsmxZ2R726NHq1pCj1JIoUmJQSyJF0pbUsim3BAIkSGSIIIhCKBQKKABV9dIN55ydVuoPc+1z7ytQtr9ij/GAeu/dd8IOa835n/8gC61dY50FNCGBtnJzyU1Xkl6STEjHKTCNUSi5CVxtWdQNU4h7L666rXjh5m2uXjlEa/YR8MMk6PNszKe1Ynmw5PjaijBGjDbsznakrOm2I8N2wuidPAQr8eRSaJbrJQeHS6axYxgH+q4nhInHHrfc/EJkeybeVFprmrahshWqyBFFelgmWVpjqho19szzFOcM9aLm+Nqa3XkviR7GECZo2obVQYOrLHUtSXNt23Ll2nEBe045urLk7u2tTJTnJttalsuW5apBKVlorTVklYnZo+3AnZsbmgcfkESWGBmDBwOxGENmSgTssuH4yhrI9P3EOHpspTk561guWs7vdiL7M7WABEommTEnJj/RDR2r9YIHHz4ghMR63dB1nurBq9y+eUrT1vTDxOgDD904klTQTsDNqnG4WtGP8r5Ns+ChRypSVGw34v/UTQGU0LCNEwbLonWcnPQ0rRO6b8hUVUVIslD6yrA+WLBY1ijlyvRYNvLlUtLtYohMU/EFyIqgMqjAGCKH64aDg5Z2WeHHiclr/DjStJZmWdMsHDlAbjKm0hgnvgXjbscK0V4rk7nx8HXUZKjdkj4I+2kMmX6cEHNqJZOOGNidZj79mVvcvX2XwysHHF5Zse09aQdhCngvHmwqK85OpWGcvU6mSdhTzXJRnqcRPwyQUkkny5x7Aa9737FYV6wPWozRNI3l6Maa5hUPcff2hi88exOdLXdPzkhEUhBGQCKjohIWJ/PkXrw8TEm2S0nhsy4mltD1QRg1MXHlaMlyuWDXjZycb4TNM29YitKIB0YfiClTNZYpKrpxZNFolB4JKHR2DP0cMiEJnabIrK1TVA2cnUiTrrSiXVoqU3G0WkEF/SSyruATN0/PODxaUCmDRcC9mGVNmA3vY5RCXyvNME6M3pPyzG5L9zSGWhsBT8iEKFMSYSZYka/EQDf1tHWLVZJg03XynVXZgJuqIXgBs412+GkQU2kLubLUlePkdEsYRxZWmI9hElZAXTlW1mJtxTBlhrGG7Mm5+O6lVArTRNdHtDbstiOZxGLZUBkrRXXU9P0g/ocxc/v2OSmL10ecNNcO1/RDy+2TU/pxwi8DPkR00BiTmPqebtvx0U88y2tf/SjaVtS1o24cJ7df4HB9wG63JfvE0ZWHGaeRGLe4KuJsZgwT4xDxY6KqLTduHHF+PuCskXhvBQtXUVlH9AKok6UIaBeClGtNYUYi8sQKNufn4uPVOPwYUd5gjMhCrLFUVpWIcjAeDq/WPP9cx2q5EP+KnFktGprWcb4Rj8v1qsIPmWVjcMqIPw6aacwlijzQto7Foubm7Z5F7YhR/K1ikAKybirqRiRIAu5IGMfZ+UjTmBIcYKmcJXrPQa3YnG/wPrHrPOMYWSwWksRZkkONcdSVwShDspZxFxnHVNgimq7LwEDTVlSVY5qCMHpIGBMl/CPXKK04OlCMY2RT5HjbzUDMgfV6gTWWxaLB1bp4BUnT2W09m+0EpckY+p6qMigNiyZjVUO1zlin8ZNmu/EYK2ENVVXTHMBms6E97bh7csq169eo3ILdZigyIU8unou5FNnjNBHTyCX86J5DmkRpPqriRzKFDNmjU7gwgC7NnbECgsUQJGRhnrDGS+BLSoVJYC+a8HThGxgC5DwDPLPf0OyFVHxUKH5EiFeN9wIUVFwkGs7KNGHlJI6WNTceuM7zt++w647YdQNnmx0hFoZ7hqwS6CxNoEp0XrxR28rxyPVruCLnUYW5dtnQ3miNqyq0EXkIZU1fLxfC0igm7FDAucusGbhnXd8PHUtzEkNmmDymqlguG6Zx2jP45j1Ba002Zt/MpRmULc2zPFsKU0jy8r5q73U1pwVaK2lXwpKtCHHa3wPyPQ0HyyX9UDwGL90v+2YqUyRg8yWXf+9cTZg8m7Mzum5DCJ7r16+xWi9JWaN1R1U5msqiQyJNXu7TccJPnpShbmowszm+NDQhylBGPPMEVB9LIILVYFRGxyReZMZSGSPy6iRJe5dljLqYGQcKyPlbYAkiWcx86bnbfOKpz/Hczbu0TcVLH7nBE4/e4Gi9Ytf1vP9jn+DJpz7Hq172Eh68fpV/8/FPc+vOyf51DtYrHnvofm48cI3D9QKwhDjRDxPOaknxFeRBmJRobt455YvP3aStG17yyEM8f/M2H/vEp+nHkVe9/DGuHh/x4Y8+SdcPvOm3vYrf8aavumAeFluEi2HTfN/kPeiTyxcOMfL8zdtiDWA0r3ziMa4eHxaWjDx/Mc/MGi1p5YVdqBD/SB9KanHOstYZw3q14ujokMVisf8sEBDG/wW7aAYqc87cvH2H937wI/zaB/4NXfG9BXjFSx/na97423jVy1/K4cF6vybMzFa5J4FqBoWEdSWM1EhKQRCvS3fxBVBVQNlyXwku/WIQrNzfpP1Q714p58UatffJm/9NSvjgSTahowBHcZaKp9kMPhc2zHDPWjN/rz0LLRZrk8LSUsYyS/6+7Lj08WcwzHwZaHYxbAjFt1Zr9W97HF70ueY029k/cvZ81GUNDFDWmxjTPe8bSExkcgykApBNMaK8Z5r3ECUMXa0dWr8oSRIuMeQgxIldN9API03b7BmiMeUyqri3np7/fSo1rdVSc1ujsEbqo+xFgTDL+auqoqqqMiy6WNAVlER0kVXK0NYQCRhVU9WGzdlYhkfyHapWYSpNUomYxWd3NvTvhkzbQFPJ8NSowlRNUjMrJBTgxXBYiIF+t5Hnz1XMPp0ifb7XYw0uWFFk6ZdiVBgr3pvLRcsw9Hv/N4BxmuiGUXp5LSB6SsVDN0mSalCWUO7/hkzImUXTsly0WFdx2g/Sq/vClA+efrujHwastRwfH7Jcthgrlir9NDD0g/iDDyOoO8QYWV49gFwkzfNt/KJjXhruAfEV+yCHe2/m+Z4WAGw+U/OTbOa/DIHbt073Q7UUEzEEhhwZphEfEp952jMOA2PMnG42v8WbffnxFQ2EHR63DLsBlUeMq+h7TzdkSJZ20bBYLvDesz3boEmSxpI82jXiDxQlhrNdm/1CkYrR9thH/JjxQ0bliDWa4CJ5koWzcWICPHYjlZJJ2zhMdLsRbRVVJY2E9xnnamLsyGiWByv6u1tWRy06Z7yPpUCUBbKuHEaJnl1ZSR8adxv6wbPd9hwdrRmGkc15y3m/hRixWrNYL2RK5eZY6IDyAW3klhonzzAIgEMaqVrZHF0lXgVaKVarBX3vUS6gTGYcA5vNAFrhnOGLz36RyQ+sV0uapuLubUFbZ+pjLg1p3dSyOKa0NzAkg1EVV69e477r0jj1/chms2Oz7QlefE32UgwlMrVhGAghcffOhkVTk7TFKcv5+Ya+F7S8qSsOj1ec7jYEhF2DhikEtrueaUwonbhz85Rm6VDU1LVls+nwY+Dq9RXbzcA4BIZ+4uHHHmKxtISpw5JoXcbqQNWsCdGwXq84Pz9j8pISlZLQs6/UC7p+5P77hGUQQqJpZCoaU+LafQc4p+l2I2engVe++mGe/cKW7dmWxaImTgmqLBHaQSSHrnbUC4epNLvNyG7jadqa1hiGIXL/ShgOTSPXvtsEQo4MQ4Axc3DUsF5XJFE0MoXIwaJimjzaJ8By3ns0imHKjCFgnKVVFf0wshu2tOua4yuWmFa85o2Pc/f2jideuebZp14ADOMwQYhipKwuTEqLGZf4RY27Mhm8+KsQZeNBeWmmygJ49XDNlStCS1ckVBhY1PDYI1c5Ox8wbl28AEvxEDNZUwrDOcGr6N6NmN2qKBN+XVbllDP9GMSs2Goqoxi1lmSabMqEApIFnwJTYf9ooyEpagvVQlNVCtsKw2G5bBkHmR5O3lNXHm0sftrR94kQNeuDBXrby7mIEYywDc9PNhw9fI2hG5iGibqpscpy1DQcFfn1NBU/By6ZZ2uR1PiSsIIKoP2XV1HRM6kL34yUE0EpbLIsqgVKKVbNirZtMM7JBD0nlBFplR+n8t1gDIHRTwQvLLQxJvCdnD8nsk0/jTJOJ5dJvKI2wiqyTpHyjr4XEHy5aIR1a6W4v3MqJrv9MNI2NdZYjBWZ9enpDmcVB+sFClgua05Od2y7CaUMpzFy4+pVVqs13Tiy6yJaD7TDQKhlQDCMMj083yUeurHifNtzdJC4dnyFpz//LKu6xcSacdMTUuD0dEvKIwcHNTlFmsrxkkevsNmMeB9YLCsOD1pSlEIrjh4/Wc43HX4YqZqKw/WCfpsZdjtcY2itIvlA8sLANCpzdNwy9JOYkFZCBRl6T1NSKlUBDbSygGJ9UJN8giRr+MmtLe2qIg4agyFFKdb9EOlRtEtHiJHdboc1hqa2VLVhtxsZupGTu1valeNgtaBuDD5kzs8GKEOlGIQR2fUDTW0JwWErcI0DFIcHLeMwsRs6ut6Ts/iuLZc14+Tp+0iMxfvOe2KSpM9hl3AO2kXL1GeOjy2bDZyd9mQSbSv7a1bSKLicsVamidooXBYPxG3fc7huGaMnTJkHHlyjrWIYPDklus3ENAgLxVnD3d1IOKo5OKjotgOmqmnruqxPMvwSE++MycKczJkCQkuhf7A+YOgC3fY2de2wzhCzx2ldmtdi/pvZ+8Pd075lJUzVS0dlDJrMlDPT6DE5XGL7SKKhJGYnAb5Sxi4kIEPIF/M7ZCjhM0pJ0T9TsuYpbbw0ok05YwoopihS+yxraM5iWxBL4nKIChXntV78PmcsASKbbosxmoP1gsPVggevHxdZtxS6MUvSibWGmANT8LK/54DVppz//OUF9txL51QYEa40fJIOWS8qYXRME7N5sZa4NTl/egbwTGngMjGL3Fkpxd3TidPzEetq1qt7G3eZrwh4trdWUF+ObE4+ftnyO5u+U1gerqrEVzCBNmL8nJNIJoWhkzDWMQWpD7/sNJT7KOfiWxbCPX5mKUb63Zbd5oy+72hKMphSWsy5tSrpZgGrEueTv0damJWhGwIhCQBXWQGTZy9UCX+69/KEJNIho8Apke81lfiAjnm6h0Uye3hZZ4U/rV78DeV49rlb/Ktf+SAve/mr+N4f/CEeeeRRNptz3v3ud/HP3/lrvOmrXskjN+7jizdPefJTT/PyJx7jY5/4DP/9//A3LkzrM3R9x4c++EHe/e5307rM61/zUg4PloXRMjEVwMpUtbAks+Jf/8r7+dN/5s/ymaee4tnPfoqPffyT/Nm/8Jd54IH7+cmf+HGeu3WLf/8/+o/55m/5Nt7+Pd/J17zuVRfnPyVc5fYhNeQLRgiIp534IUZu3j7hF3/lg/yH/9Gf4vz8jH/40z/B7/zebyPO4KvW6DTn7ZVnrNzXWiuGYeTZL73Apz/zDKOfeONrX8VrX/EEBwdrjg4P92ywmTkkDMgZyJp90QSsef+Hf52HHn8F/9U7fvie63D3zh3e/e538d4P/wJvfv1redPrX0vbNOVa5nKPq4vnTKn9zZG1ABMZw62bN/nwRz/G05/7AleOjnjj617NQw8+MN8YzCmR/3swkABhaX8u4YKNmqEMAC+Aulm6GkMkMqei5hJqdPG6Lwbc5+8hHlsCGlpbGGEv+kwv/rTzZ5u9s6bZG05fyIxlGSvhJuoiidYYgynXTKe0Z9R9eY6BPIuZEgphBND1RR3gCwsuJUWM9zKRhEUq68z86UPOqCihFXuJcGFPGvNvhwqqChaLluUqYJ3jZLPlfNvtoaIYL7OoxJ8tzQOOECCHfQDLzDaTQYLcszkmkfrmiLo06JYkVlVCpBTWOaq6EkuOGHnoxiv4whc+L6zhLKEQs2+g0hqfIolMrSw5JaZRADGyIQ8X+6gpvmZZlyFUeabHIGm4s2wvp0zwEymMYiuQQan5814w17TmHm9BuR6IisZC5WoODg5IKRajfTm8l2FFXdciBzVWBjlJEjojhlh8M+t9JIXsYfddv8bpZsuVEDk5O+esn9h1W6oUaConAW91xfpgyXKxwE+ez33ui8QYZWBjDeM0lRCjit3ZGUFB29asGvFWi/mC8aXgy+5XrSQI7d7npPxC1o/LcHJKudQLcp6GcZJQrEl6hql4i2qt6buRcdpSNw2WzKbr2fnEsq3/rfft5eMrGgiLQeKg+8HTalXQ2lEQZLMAhSQCGkvwIvVbrpegI4eHNV3nMdrypS+8wHK9YLFs8KNQrIc+EKYMqSy0RnGwXhJGMWDt+5HJB2xtuX7jkGmYcLWh1lLsukp0330n6UjOOUlk047d0NPd7Di6egX6iSYkUigpJPtpijzo45AZYmS766kXFmNrDg6P2W53kBWjz2hXmAeK4ikiVMbJi656uWjI5x1tW9Hliew1ComWTylx9+ZJmSQ4MU8PjoPDluPjpSTL1RaDpRu31O2K1XLJeRhYHzVsTgdM2fOMReK5qwpfkp2cs9i6wujCLqgt1bJmeyrIdNM4+l6kNtM0o9/C2NNGs1g2oolOqkiyIie3OgITgx9YLGpSTlR1TbuwXL/viOdfuENMkbatJVUKuH7/ilvPnbDrOnIKbLcd203HclmDMhir8DGzXLVoJkI/MAwDOWZWq6bEyzo+/8wt4jiwOD5gsajISZIJc1JMPrFYtvSD3/v7VHWJdtciDUJBVSeGfuK5587EzNsIK5CU6bqJOzd32MpJ4plV9LuRcBKwTmMXhu2m5vAKHB4oYuc5fnBNDOKPcPe5EZ21BEiZjB8jk1HUlRE5lhPJZ5giy/qAm3dOSFn09l3vSRGUMqRk6IeIbcUP7ODQ4JNCu4B1Anq+6qtuEKeJWy903H6hp98FctbFjD1KIlVMsscZvfcZyGXBFCp/uWdzJBMhVXs5xdyAZaBZVLQrjWss7i5020k2RZ+ghCqIH0ksaWiGuqlkCpS0+PJRotYuSWHatuLq8Yp+O/HYjWNu3nHcPtmwSx3JKqqmRiVL3AVypEy3MilkDg4aQgjshi2rgxpnDXbZslrVDEOPsxeTeq2EMXf1aou1GaPFaFgjRuPtasnQD4y7gfWiIVmhZ9vK4pVi14/0w1TYkrN8oIQmFEBMHhuFUjWzsbD300V6m8riByNRauTsUYVB4GMQvxjn6MaRfiiTIydG3jqBViIRiUk8IGrn2A3j/hqlkEkKKucwBiZfmGkk+lGYA7YfIStiuCieU0rCsMi5yBJGlFEs1o62qdBa4b1H5cRyIUzT527e5fqVI7S2rFYL2mzArnj+i8+yyz1uUdMayzBGum7HojFcOa44ONDoOBIT3LojjNJp9LzkoYe5+cVbXDk4ph+2+DIzJUVaY3BmQasMZ1O3Z2G0raNFC3utm7h2tCbnxCZ5umHg6HBFXRumKKb0lbUopBhuXcX1B9acnO+YRi/MvqQ5XKwkxCBNDLsBW1do2+CcJCBnJZHqz33hFGs1tXVEn6QpTZnYyzrwwIPLfdJRigJqMU2oBNM4cX7WUy1WTLuRRdtirWUYJ6yL6LViebxgtxs4O83ik2kho6lay9KpfeLdUHzSUvJMo0z3Xe248+wZ1mp8qtDGlEQkQ84Sjx6ykTTdFLl9a8c4RI6vHnCee0iJK4eNMJBiFJ+pyF4yoq3h+HhJ3wWOjxclPEHzzGcnNIpKV4ScePrTt0R2ZvV+H8hZmHghJY6uLlkuGwljiJkUEoMaWa4asoLN2YCZJ+4qi2FtEHbW5D1tW5GTFkB0CmilqWqL1U5kVAUIm9kOMeWLxivPvjYCPlEYIy+W2SRl0FkYpLYSD1NT5DkO2W/DFC48lsK9jVyKgVBs1OfUuv2h1P7/Sjkuz3ESholWimmfTpWL/C8j5epFA6VUSUw0whKKqTAdKb2wEiP/2ta42UOHAsbnCa0tdXVAU9csqwarJXZ+9KNM5C/5U4k/TxCJSxKwyFq390oxRiwQrBMWe0gZVzcoa4lqNhC3KCVpqmnPPhH2QkzixemcKzXmvfLG+fzEGIl+IvpB8MbSQAsjS+/ZPvtTXTA1ATYUVe1oVwuscyhlmEIBhgoTLquE0oZp8nvGzr1HMY/PcS/DVcVVKQJ+HBj7Dj+NIt9MkUTx3IoBbWQdytPArh/pZtZZAV+yMviU6YfArhOGmCvhSZXV1E5feH9pRYgzUCt7+2rRErJjKkbxd7fn2AzLtt2zo+bDaEP8LTgWd07O+N/e9X7+kz/75/m+7/8BtFJsthvadsEPvP0d/Nqv/gp/92//TfpnvgBK7dlmSsHb3v6DbLcb7t65Q8qZuq552w/8IO9/33v5uz/6t3ny05/jLV/7OgGUdTFVR9EFSXnLGba7jq//+m/kypUrfP6zn2b0U2G1KHZdz8nZeWnaxcttGqd9oiSIIb6oT7hgdCoxPVfa4mPkdLvj+bunfOu3fjt/7N/7E9y9c4f//r/777hzcspytYD8ojtJsbeHSCkJoy4Ebt094Q/9u3+MRx95hP/oP/iTfM0bvorVcokxdu8LpTX33MupDMTmI4bI+z/8G/zlt/8evud7v49nnvns/u8ODg54+zt+Jz//T/4Jv/rL7+Q3P/Fp3vT6ryqy4fIaRph/dm7yy/edQSqU4uOffprjBx7hD3/n2/jkJ57k3e97D7/vHd8PgA+FFXQpoe/y955ZbXNQhdbmgmFYmuVY7GrmkyaATygslAuQbv7zkGZGrPgtxZT3ksGZZeVKsmuMotQwxtyTVjq/pn0RKyxFkeNK0ry6WA+5YAOlAoDFcl1cSf02ez2sAJXzrOTyKcmZfdrvRdqnune9TIlpmmiai3OaUiYEGdbK+ir/1lmDyrKyX/Ywk4TCXMCrtP/8M8NrlqeHIGuwqKM1ad6LVJFhhtmf+eKek31rZuzO3+FCfp5NAUi0uZcJhgAlMRQ2tCmBCGRQ4sX3/M2nSCSs1SxWFqtaOTdOo8owzmoNTc0cSpFL3yE2HAI+Vi7va6n5MFo8B+MenpYjhkjygaZNDGmOkbn3EIbYi2YoWTzlos+YqqapG65eucbp6QnDOBQ4y+yHFc6Zfb0QlQBgCUs9m+eXa6jLNV8vl1w5OmK367iqNbHv0VZTpUBrJSm9aRus0bRNzQvP35I+KgvusVwtuXr1WMLTUsJPE2ujJRW13Hu6gFphZgHmC281LrHDQPaIffBEubGloij+jznjSw1ltKYxBg1M/YBzlvPzHbvtQNcN7LqRfpyoneWxhxc89OB1Fq96nO3o+c3PfPG3uAJffnxFA2G77UhVW9ZHFQeHC3Zbz/lJL5tRkpSWnJI4PSg4OlwRo2dZL9htJQGyqqX5Sxnu3j6XTd2LL4oY5StUSWRqrcbWln7MTJNne9qJFNKJGXjwF3GmMSbZCK0mpVGm0MqgsmVk4srxMf04sNltWa4W6GTY7Hbc3ZxhtKGpK2FnKMNumOTPmhoFuNqxVAucc/S7gW4rsoNhGBn9VHS5AgYoLYthymImarSmXi65cnUlsh8fymRJWFSbbYe1lqOjFUbD6Z1z7nvomGwmHFJkLhYt5yeDSAl3nugTjROqt6RoCBNGVxbjLErJFLVywrzbnO9Eo904xslx/f4r3HrhlGHIe2q/LKiSSFFVMHQ963XLVksRfXpzhxh3W65cPUQpxendjtPTjTSdlSsL57wBRaq24uBoyclJT4gNu20nhVCInPlAVVnuu77GmiwJPz4y9CPOWY6PD6ibli89e5tAIowjSkWGaZDUPSeyh3YhWvzgI/0wMk6RpmkZx5HzU4/WlAQ6Q9d5yBPjONDWNZOX89Qsa+pFRd24fcy6LY1n9AMxnRFSCzmzqAzDbsA4w8ntjpCDxEdboZiPfZkoJEV94EhZo7IFKvpuIvjIfQ8ecfvmjnHK3Hp+w9HVBYlESIG6aakXDttZXGPZbc4xRuPHzEM3Vtw9jQRfEb3F6YFp8PhY5kzaSNOUM8mLYfKe/KDyHo+aafYqi7z05GSLsZlFa/f+QqvDZbn/FZuTDb5spqZWKAwxWkLogIizlsoaVAHjtK5Ewvei9aNuHDElbt4+5bUvu5+cM+uVIaaa89vnTDGClaCMaQoslrWs+TGRoxRIlalYu6s0dVW8TCJ+mqgqw9Fhg1KK881A33nqSnFyci5buQZTmjxS5uzkjIMrR6QpkOtMU1U4pdidD9zeDfhxwlSGo+MVcCFJmCeOulD786XEqMsyFKUuItf35ppRgtvnYjiEwPN379yTDjUOE0qLN1ZK4lU0+RGlxKdkZmj4rAhjEPAvJoIJ1E6RtAQkkGRNikHAUkpRZa1l1/VULuB9ZL1qyTmxaFqqSphpd7anhGK6ao2iqgSQu3s6UNU1Sln6IWAbT90uuH3zjLpuyWhhuGqoq0r8s7pA7ycOVyvunk3cDBPH19agatAJo4T9qjR0/YTVCuMcwXvOzwZ8iOKxpjVjShytD8kkFm3Doq5wwEGViZWhqWqJb54UOllWiwb7oKJqKnIWNlw/TJxvBhauol7WZK8YhsDmfCLmxFiLEag14lFj3ezzJExmGy0pRKYS2DGGRL3K6CKbM8agbRRj4aSwygGWmBQpQNNWhADTBHmCqYvsNmORtFtW64bN+SS2AdaIJ5UxGJNxlZXrGhLWiccOSjz4Dg4afIjUlWW9kqSfrh/xwdP3Ez4kAUzGgLEK6yynd3a0jTBRxxCxFWiVMQlc2Vdn/7+6thwcO0w2ZYASiveiZRomYsqM52MBC5IwxypXgjugqqUAb9oGP45oI8+OrTSTn1CjYlFbqsrRDxAiZDxayfrd9T05y724XNYy9feBRa7KfS5Ahi6DsWEaGPyINSW9sEy0E4mchcWtUOyDEFFYlfdM2XnhnJ9rawuTJmdUXbxbrCoDP3mRlFKZGI/Mvjnz2jE3ebPni7Niip5iLozRSCZJE1R+fpZ5aa0xuXixlmCZy0dKs9Rw3n3n9UoK25QiOUacsywWbalpqntkQ9JYhfI5NfmSH0xO8hqxpANmKwO3+X3EjmIi5UTdrjDOiTxybtzUzI7Qe5lG3g9mpAmrm0panEsSMrkqGUPGqgxaGNTiB/u/E9MeIeRIVLLeu6rGVQ1N0xZJpEiBqtrtv6PSlljAX5GpJC7S7th/plnqKp8LlM6oJM3r6D0+BiIXPl0iX/UMfY/KSRjSaKYyfa+cyDWnpBi6iWGKbHrPVJ7/pq5paoebBEjIOWHUzFCWy97UjsEnotFMWaxBNlNiqaHyfv8dU0wXwE6+V8oP8J4Pfox3/O7fw/d8z/fxa+/5FX76p36Cz3zmM1y5epUf/MF38IO/83fxQz/yB/jLf/HPs1yt5fkotYS1lg9+4P38lb/0l9hsNigFf/jf+aO843f+Lt76nd/FP/+Fn+XO3S2TD3zyM5/jC8/fBITh8LpXv5QrR2uODw/44R/6XQTvuXH/1XvrhzxLfuQzD+PIP//Xv8rJ2ZY3vvplvPKJR7hzes6Hf/NT3D095xWPP8KrXvYSlsulMMzjSDeOfOG5F/jE08/yp97+Q9y9c4dr16/ze3/kR/jQ+9/Dm17/KnbdwCef+hy37pxw37VjHnvkQXTT8LkXvsgXn7vJrh/k3kXz8EMP8cRLX0aIkXe990N897d/E+MUeN9Hfp1f/9iT9MMAwOtf+2q+/mvfxIMP3HcJQJHvsuu6vXT3D/7+H9lL+rRS/Od/7i/wbd/x7Tz1mU/zzLPPcN/1q3zs45/iPe//sJjKG8OjjzzMd37rN/H4Y4/yvvd/iHf/2gc4PT/frznjOPG2t/8gjzzyCDdv3uSLz9/kl37tA7zypY/z7Jee45ff9yG6rgcUD9x3lW/7hq/jwfuvC8if7gXy51TYe0BVY4jJS2otZUCvZMg+M+y0UgUcnkpiotRtMWZiUntvVvGGtvv1whi9Dz6Y15nLx72Mq4tkaFNVl38IZ6wAWAXWCSEVGx29B9lIkRT9PcDli4/5u2h9wfbKea71TPGOmxNUZ39W6QO33cjppifERFsSjQ+XNZXThXVYfBAV+NEz9CPDFOgHCYUTZpwwtiYfmT3tfEzstiOhDH66fioAY/GwLeuN+EJJaEROiRQywc8DNl18+DRVZRkAa2dZfYQsiqmchdmndMIUG4KUI0YlYjLkMTOFAWMN7cKgkiFG2ZsXqxrTKLTOkBLdOBbmmAChVovdSwzgyRdIyXx+i8+jUveaxKeUiZMMbRezzYAV8cd8KQVLl4HJPgwiC2aRQiaVdFCtNVVTF+/ejFLmAsiMFJ/KipQMKkaWuSdhSOrepMvKGpZty5WDQ4ZuoLKGyRpq07A20FjxEU8pM46eF27eZpo8jTas6pqmrVgfLPjiF29xvt0xhUC7XKMKc48sdUsh6t3DBLsMtCdqYprQ9UqCS9KAyhf7Zs6ZKck1vJBK6/0wcRgnFsuW813P579wh7PTrUj5fWBRO64fLmhbR0qB+5qKWmnWzW8hWf4tjq9oICymhKs163XL6GNpNitCyOy2W7rtrlAtI4vWkUMiaSXFt5EkQ2tsMd+FmBNGFeZIymgy1ihcLawoH5MkNC4bTk7O8bVF5cz6+hrvAzkEQkiFzglKS+FYVZq6MqWoS1y7ek2i0EOkcRXbsw2r5ZL77zug60a63hNC5Pxsuwf1yNBtoW0WQtE1Fru0hNFzfO1QUPccMVnvExSM1ZDF3FspxWrVsjkTWVbd1CxWDWd3zzi6upI0iH7AGsPBumWxqMTDqFW4WiRNWmu8j5ze2ZBT4qFHr9G2FTe/dC7BARa0coWqLxVbjIGqMqwWNW1bsduNdNsd1lW4quahh++j7wbGccDfTKXYloXSGpER3r2zo6pdmV44hmnDfQ8c4qylLdG3203PNHnqpiZnL9R9J3TOu3fOOThYcXi0wo9SgJ+fnXPffUf0/UhdVewGTz+MdH1PDCJNEZP6qkwa4Px0V7xnAlVjMV6mbNYYtFVYJb5r1mnsumHoHOdnO7bbLdZI0tzZWU9Vy8+c3DkRJsYwMu4GtLUok0GDi8WvRUMKnogh+ETfj8QcZCo+ZY4Xh+xyRxoldcvZ5sJgfYoonamq2TdAo6Kiz5nDlWWchHo77cBPimwMttLceu6cYCKLlWIaM2OfWKwXtAdihO8nQT9euNVROU1TVVw7GGlNzXgWGINiOyampKVtSAlCkk0PpODNyCakMtaKOW0IF9N4rQxkYds46zBUDDsPMfPYw1c52QzsdhGVjfg/ZC/yHESmeHy8ou8C/U68AfdT9XuHjDhnWK9bXrh7Rl1ZWmd57MYBg95y+3TL1I+kJJJlV7xO0GCtFCCLdS2pc4ctKQQ2m4k5ZXDyMuMIXtFtA7tNT4pga4dxCW+EbTVNgdXxkYQV+MhBVNikOTnZcnqy3XufrQ4a6jZiC8AlX0kMhJM4gha2hmWWSybmxk++vzTHZaqHsBGjysJ80WWKl8VENqZE1pQEq0TwAR89OWuGIeKNgHA5JfGdsYZsNBGIWVFpTVs2ommMDGMx3tfgJ0naFeBYJBZNa6QwK4DnPEoKwdN14tWnlGa5XGKNous81nTFvFaRuw6FgGxj35FURTeIcfhqUWOc5eT8jHop13K9NMQ4cOv5U8ZXBNaLFdvNFlM0P4umJgRJ+/Uepimz7cR/qC4hFHfu3mWxqDFK41VmyJmDxhCmhKkUWRtCFqnqwYFlrRzDMDGMkkysVeT64QKVNOlsInlPHSPrqmI3JUKAkzOR9qECWomM/uqVFcnPDBV5ppSzbHcdyujixxdoF5m2rjDWydTNi6H/4dWWuhag6/TOwPFxQ7eVwYh1Fq0MVa0xRpjXwxAwNjJLM52tWK0aOr2DZBhHMdiexsg0ilTOOZHKzilZRim2/cT5adxbEGRkTwEp6lM37JkmVWUZCzPJaoUv0j/xG4LUB9CJ5aJlmgIheZRqUTYRu74Aw0mA32yYckRNoaSS1iyWFVpJczMOCWPkuUhBTJDruiWG2VRYfPYUGR+mfbqsdZrcR1JJrp0mMQ6fmwnnHCElhmmiHycqW1Ebh7rEcEg5obOWxi6LpFIDjZbJcURsFubJu3ipWLzEue4bNVc5WEEVKkIIdNvuAoBSs7RzBrrynkWTszQg0swgKbv7JCfuwblyLubxKZfzpfe1WLok8bTl8VVk8YvKGZUMYFC5oOfkPfYRvCcpTSCguZBwz2uWSIkuhX4wm+uDJqKVJUdhOwlYPzEnFF5m2Sml9mvL3LfOxt+zjZEqDJAQ0qXG+QIxE+ZVKtPrCzf7mfXifdozNeZBwfz3OWeU0RjjSEmY5DlLsqGZZetIszjzaozSKGf2EkjKN5ifK7G2uNjatIJpGpmmkZDkSjZ1g7MWHwJ9P7DddhATtTM4q5mC7B05i0duCImpPPfDFOjHgLaJrCwxi6fkNE1yDXKiqQxNZTnZDhhtJNypERDPe2jqI6wKMqibJD1YmRJ0EFMJpLkXWHjuhdt83/f9ALdu3+If/sN/QMXEW9/y1XzuC8/zq+/5ZV728lfw1W/6Gl7z2tfx1FOf5p3/+l/ds8FP08TJyQlf/9Wv5enPf5HPPv0UZ2dnPProYxxducZHPvZxApq3fud38Tu+4RuoqpqP/cZH+R/++/+WN37Vyznf7vhzf/4vcXp6wrvf+b/hw/P3Pgz7hwJcXfPt3/M23vKWb+ZP/LE/yv3Xj/k3H3+K3/6Wb+Ut3/Qt/PW/9le5efeEB6xlDIHdOHK+23Hz7h2Mq/iGb/xG3vOeX+Eljz/Od3339/CP/vE/4qWPP8zJ6TmPPfFy/uSfegd/78d/lK4faeqGdnXAd7/t6zm+coWf/qmf4q/+P/8aL3/5y1mt1/zET/00/9PP/xyffOoZfuV9H+Trv/Gb+NP/6Z/l6PiY8/NzPvC+9/Ku936Ql73kYd70216LtRdt4GXg5eT0lP/bn/hDVM7xc//sF/nA+9/Hq1/zGl75ylfx9Kc/yb/8pfdw/f4b/Md/5s/w0I2H2HUdn/jEk/z4T/9/+IO/93fzT3/xX/FX/19/nV/6pX/Na17zVRijOTw84tHHHuP+++/nxkMPc/36dd71zn/Fr7z/w5iq4Q//kT/Ga177VQB8+EMf4B/+g5/mW37Hm3np449SObcfAM7DOl2A4mka9587JfGzzPvvBCH4YgCvioSz1EIpEMO0ZyrFZMlo6S3qugTgyEXWe1n1hc/fzBQTgKnIH0t95oxF5bRnnc1/JtK6AlTMgNkl6WG6FDDw4kOp+emfAZW5Trp8O8q67VwlIFTM9IPYOIxTUQtNkd4nfMzsOk9VLGzWC0dlJTU4KPEl3Q3CGA1BBsK3T84kvAQZ8sQg+0uIER/lPEpImwCAVuaGF/sOF755+6FESlLfaUXlyndzBp8VrjFlL2HPsp5PwDygiVGYgjI0gN5PVNbuwzjapmbcCTCojdQSeTIYBV3wmLTjsFrLgH4e1iSNDxdvl8lgwGTpA/YBE+XzZ6XIITF0I8NCwo4WBYcZYc8Gn4EiVfZYsuzsKuciY437EA0BRysSaQ/65jzXQBoDLLQELUFGl6Cuy/eEGOAbDg+WnJ46zk+2pODxZLw1VFoGaEMvPmDjOJImz1HbQBb/3rvPvYDveuIwsDg4LIFLW0xd0TZV8c2T9zMatK2kNi2qoPnQrin1iCMrh8pJzoOaq321Px9uTsYt7ERtNP0w0Q+Ba1cPuHHfodzL4yT+lFpLEmY3cH53w0M3rvHc9aMve4Z+q+MrGghr65pxDCLpCiVZBknvMWZeKAxMUgRevXbI+dkWlWUxrGtL8ArnhH1ROXm9GKQQPb52wPX7jrlz8y79ODKkERUzV68vycAweOrDlm47MHQTq1VFu3CEkNjtJvreU9cSAW+tIXhPTJHlYsk2bKiaimHXixdJlPhgW1XYkInR7027Dw5WpMIwCyEQx0DMUVImteLw4JDJD9Ttgq7rykKoGYaJsR+oa7dvhBZtRQgCgIRJ6Kzb7Y6xF8pj29Y0rSuG8yOJQIyaEDSr1RprFNNuQwhRmBQkbt3cEHYCEkrTkcSkf4KsMoOV9LcYpbjMKWO1YdftREblZHHMxNLIS3Ln9nxkHHYMvTRZtra064bHXnKVnBzrgwXBJ7747O3SVGU534TCGFJUtWW1XkqTgGZ7NtJtJhTQ7UaMgdPTE5QIkRn7gCu+Un7yVHXFYtmKIXm/IwRhpjWNo82aqp4ISabUzin8FMv0aaRtHMfHS3bbAe8TSkv6Z1UbFsuWbrtjGEas1sSsqBuRcrniQZByJowT2/Md1kjC1GK5IBRmQd0YPvvFW1x5oOHqUUOOlm4XxVtHRbQRw2dT2GQ5wflmZLRiCO3HRLcLrB464Lba0C4S8WqFW+hCQEhkJf+ttEb7KLKkpuK+J1q++IUdajQcHdVUR47tbsQWBuPds47bZztONz3DKD4jezuaLP8jAJj8oRXTH/yY6LuJ5aKmcq5EcEtCqVGK9eECdODxJ445PRkZhsjZWUZlg7bFz89aJi/SvISBpLksh5yPVNhU0xhYLSr6fsTWEnhxeFizHUf8eYR8wQpwtUFlhVHCZmpXDaYxDFNg6AZciXYepkDE45wl5FyigxUhSIJVs27QqmGaxOcnZpE8Hq7XKK2YvKxrm11gnLJIWcZI3weW8+46N5Plv+bkJooUKudIysV8Us3bzOWiSdKvMpTmWp69KcxJQpeKLq0wzpbpl8gdfTFJdsZcyFmVbMeKzDAKoO+sQRlN3erSwBU/EYRyPvpQPKfE72+77dFGYVGs1gvWi7oYsXpCEOZBSMLW1Foo/cdHh0yR8sw38qm1MJj6UUIFJh94/vYZjyyuc3y4xtOx0If4ceT2rS1GZXyRZZKFDXe22XH37hm77XjBdNGZvM0cH684P+uotiPHhw3aLgk58txJx7XjQ2KKksKbMiHLDNQZiYvWWnH9yoop1Sx0A1GJkX0MHASRn531I90oXkfdMNGNAsJqizDk0iwHMMIGSpFN13PeDbStDC6M1jRNw9B7NtsRV1vGIVBXjbCltaJpDcOUuH5tgS7ehtZaNBXg5f5K4KeI1hmjFZXN6JhZLCqUTuStZbudGLpJwOWDRuR7zgrYmjKTT0xDJkUBQsfRM44SjGKsAV38/pD9exwDZAmfsdZQ5SzgWmUlfVebwm4U8GG1bMlJoZQjTGOZwsrENykB9ZyzkgCtFdbJ/Z6CyPZTFpmP1SJPaRrH2al4VCYUPgR8jsXANlPVmra1nJ2Ocr9aJfekSpL4W7kiSddM3tMNvTRXxqIdwozkovnMheGZYiYZAZG00iSlUSrtgY9pmvbSqNkrR+kLMMxaC4NIs2KQNUCALnPBvinFvlKlcSuyQKUUxJJSpmeZTYmwySX4Qc8gkqw/OUMqoFGI4h9VObPnoPmUCMGTo0bZqiQYCujjR79n1exTBQsQJmt0Kp48FwzYXFYhU8AmraVxiymioiIIlV+GkI34YpEv2F3zZ78sOcwZhikQEjhb4ycxIBaGnKwr+8n9DH6lRI5yL2hrSUEkWPdI/L582ylyXfH588Vbc28+TibEgDUikZRGNu6ZheR8cf5V+SwpSoIac9MmPxNi3EtzJNBCUndTylTWSJAMME6hhDsJsxSlJYk0ZwafxKcsZWwGivfdrh8ZxmkPYLnCAtt2HvBMyXDV1OA93kuAhFYRqxJaJbTyOCsAt7BFChutqkhoRu8ZfeKRx17Chz/0Qe7eucNLblzh6PCQjOKpZ77Iv/yXv8h/+p/9WV75qlfx8Sc/zs//o5/k6776q/i1D/3GxQ6n4Esv3OL2yanc31qRU+bsbItyDT/yQz/M97/tB3j285/nfLvhB37wHdx//4P8l3/lLxBC5PWv/23cvHmTf/H//ecM44Vfz4uPlBJ37tzh677+G/j+H3g7v/HrH+CzX3ieP/WWb+ahhx8iFDBi0/f03rMbem7fucs4Jb7jO76Dg4MDfu7n/gnf+Ja38Ad+/x/koYce5s7pGWdnWx554tW86avfxM/843+ETr14ShnHSx5/ghs3btB1HU8++XEOj45QSvGJJz/OCy+8wGef/gzf9T3fy+//A3+Izeac3a7jiSdeyite8Up+6Z3/io984L3cd/UKjz/2CC+2np8fiuPDA+kRNjv8NKHKcHsYJ1796tfw9h/8nVhr+PznP8/x8TE/8vv+AJWr+Gf/8y9wvtnyxje9iZe+/GXcuX2Hzz3zjHg2aU3d1Ny+fZvPfOYzPPf8C5yenPOX/4v/hAcevMHTn3mKpmn5PT/8IxweHfFTf//Huf/aVY4OD77sU6YkKahaG4zNe1DqMgNJ2LrFYD/PZFWRFcfgmcZBfAazsL+dq1m0LYuS/jeMA/taq9SBqnjg6QJ6hSDWEmbPUMuQNVVJg/VBZPUzq+3ie6hSwcm/mdd2MwM/l8q1XICSnJOEAuS899kT5owMMMQz0aN1wlrFdkjcPd2w68biyyu2NbGA6CgBZ7rB0vWO5aKmdmbPPp1iZIqB0UeRYufEFOUziMn7hTH+MIpaII4jdR1ZtjVtUzFOJTQtsX9PlYtEUGkSFKBH7sSYIXnpG5LK1AUMk/MgA5gLIJC9DUjKEeOFBJJtFIZ1lt5aWY3feeIoPo7WmsI6E+JGSplVtaCympwiIag9y+ny2h1T3KdtwrxvSY2jEvRx5O7dDZWzOGdpjCLkuZ6+WJf+betIigGyk7pcG5RxmMKc2gtsc8RosKU/yloRkiGpObnm3tfVRtE2luWi4fxEWHhTSpwGzyYGlB+JJRjG+8CVRYtRJSBnnKhrx9Vjx9UHHyBry6REAZd8xDSJ2szPHfJ5koJSnykk+dqawmQGkp5lm5daM1UYesoUMIx9baONYrFseOCBY/FZzgmVi+pP3rQM+LOoc3ziue0566P1b32iX3R8RQNhkBgHTwqKFBHd8xjIGZwTn4ZxEP8PY1SJgVdMQxDwy1n8GKnrimHwBJ/xk0TBai3xyjJFK9POrBinWW4lQNNqVdPvRqbB0zSGxaqGksQUo7AvjNEYq4g+Mw0jrnJSYMVIVUxTldYobVE5iIGsSXgtrxNCRGs4vnrA5kxSI5URb52qqrh7+64kORzK/W+t3U/NjRU5ojZC+z7vJ4w1DJ1I/sYiHXLOYYGqcdjKYpxCaXl6U4ykkLBWaJpV0Sdvtz2utkAm6UxOmqQkxtwW/b4yhqp2+ADdFKQuVJa+H9hse64eLgstNiCJSboYyyqGQVLSUJYwBWkAYyAHS9ZJJp4+YmymtWIWXNc1PsBy4STAYPRcv/+IYUhMQ2S3G7lza4sPgaStLMIxUzsr08sQUUrOgdWZRVvR1A273cjZ6W6/8dR1xemdc7SxkDXei8xwtx1ZrpwwcRpH2zpC9GQF3RBwTmG03XuLxZg4OGjl/lJinKxt0c3HTPSQgviXOZs4OKyZRvFwMcbRHkha5tlmJEwelQxV5bCVQZssv7QiRcMUFHfu9uTQs91MJULccfv8Dv3UUdUKV2lW6yWjj/hJQKVGW9rWsAk9cap44PCA47rm+dxR2QZjHQtd8fCD1xjHyK8/+Szd4IkxozQYp0hZoYIAWimBna0dyiRJxUKJLQ13SI5uBJVGlm0G41A6oStPTnD/AwvWRxW7zcTBkeX0zkB3XiLSp4BCJHkqCzB1oboQiYwxihADxlpiymx3kclnYRIME7swkKMqiXyqpNCKl5lzBlteI4aEsxWb055pjCRnCWMQU8s2s1xpoWavJUGy2wySgpdV8Q/JRCUR1EZrpt4zFbnZZjsw+iQ+N0YAjxAz4yTP4LzbpWL8KuygCWPKTEgJgIURmrs1in26kJLkGWvMvmhUWmML+yFGWSv1Pm0PpiTr3pwIWt6AWJrDnDJZeuoCsnsg0i4qFm0tyVzse0iMLXHmo2YYEa9AL/JtAREqrNFFeqxoWkvXe6YhMnkgh30qm/ceVy8I4ULKobSiqmxp3hK7Xvysau3KRjuhs6Tcnm8HDlqF9xGnDClmkTOVCedYvHqq2lLVTsJTQqRpXWkgIz6J58iu96yPhN6NluuWkkxJF0vLGISluOsmrt23xKkKnTWNcSybBTlmhn7EnpzTVpp+8igV0abaN8VaK0ljXVhSnkHTDh8luKOqDItFTVXpUiTK84wSBpYfEvWRFJf1woGOZF8AI1WMeQvTxFoB00PxSFHKUxlb/JMgFRnD5AN3Tzfcf98RdSU+VkqLTNOPItFYrFqmMZDSSOqF/ZuSyIRjVFJMlqZ+sa6xxokEU0uzMU6DyD1iZkpJkvaSZpoyV+4/xI8RfTYyDVY8WpDktZASKifqpqFdOjLCZAyxpPEpGWaMvWdxvGQO7wvlOZUifyIGj1KZpvhdghjphpDwPqNUQhdmi7V63+ynHJmCZ/KB2iUxxLfS7aQkZuE5Z5ISBlVSZl/LaqVIqD34pbSCIAV+8EGeoz3Io/YyQqMNGFCl8ZgNpCShTGSHLlnxwEGmrz7GkqhWvEa0FN97v7k0m2vL8Ep+6T0zaW40zQw4ZQGsfMjSBBb2mywE7OWdQDHnLyy0wpjTSphglKYnxXTxM5Q0PnWR0CdAnd4bhBstEuHkHMbaYpdAAQLn9EzFFMpANclrTiUhOMULr6CZAZEL2LVvapMAYUopVIqsKyvrR0xfRupQ2mCdK6b484CFIt/Ve3BOzTCiUojfpvzWKFXYXxfSVkj3jDdiCWtJM8BY5MxyfgOkROWMgFAxMU6Bbpg470amZMhZs2glTTekiZiK5XJm34CnkvSXc8ZkS0L2kSCXAO0l7CdFJJl7ErBBq4zTGWuySCoLq8JZizGeqCacNZxvdrzyVa9msVjw/PPP0zYVTdOQUaxWK+rKcefOHeq64dFHH4MM61pz7fFH9kDY4eER3/TN34Im88rXvZHv+u7vpW1bPvKRD/PJT32SV7/mtbz1u76LT33qU/y//8b/SIiBH/l9v48fePs7+Mmf+Hv8+kd/nbpuqKrqkr/exZm+fGn95Hnf+95H3/d823e8lX/2z/4nSZd89at58jd/E13g234a6aaJYRzZbDtSrvj6r/8GnnnmGd7//vfxuc9/jj/+x/8E3/4d38G/+Of/E6tFK6qVphHZnLZkJUOnyjmqqub09IRf+IWf4/HHH2e5XPCzP/uzvOqJx7i1PuD3/PDv5fT0hJ/+qZ/khRde4OGHH+btP/gO3vw1X8sXnn2W93/kozz+2CPyLM7MpRmYT5l/8DP/lJgSDz70CF//Dd+IqxzPfv7zdF3Hcrniuee/xC+/61188pOf5Oj4mD/35/8i3/iWb+Jv/o3/UVjedc3zu46//+M/xs2bL3B+fs63fOu3cfXqVT7x5JN8+APv48FrR5yenfHGN72Zd/3SO/mxH/1RtNH8X//9P8nrX/8G/sfz7d7AXWTABfjnIlFW/PVEEeAveZTFwhaapbtz/SFMVQEdQvACKinDermgaVoOV4dlzwt0/ZbLQQPizSasTYWWPVKLfY4t4ULyXhqVNTbnAkCr/fq5Z9bm+dktLP1Zig178H9/v6UMKuF9YJrEt8s5i0szK1iGnyEGchLgbRgjZ9uRm3c3pZaJJVlzhj7Fzwlg8pphtPRTZLWQWtMV0/cpRnwujlhWWL3KQ0yydsgz7FgtV/TDUBQoE2rRiKH6SrNatuJZFkJh6YkkNCVIwTD0ImfPORK4YGKNY5A6pS4XNUu4gNHS48cQIXlCCbwzxtA0FaHSJSAso5UjoVDGEEPCdwGyF6/b2hIXck0MDrIkWvsgDMJ5t5OaWheGchkQo9DZCACZk0gmM+IheOo4Pl6TbbG4ucQevrQj7K+AIqPLgCrEUAYkBq2iBBmowkjMhRmvIVsDRlhwcfbtfNFbSFRBLDVhhbV6/2NjzMRJWLo2ZZZNw8FScW29ZL1saZqaZtHQtg27YSJUC7bDxLTt2W62VJVj1Wiq4knv57qERKYEhWhhzOn9EEpY3FYHIO2vdc6z1FKGvKW92A9+FJrVqqFd1PL8zmFBIUCOoGV4h9JMPnPnvMfoiv8zx1c0EBaCpPNYLYbsWmlylDQ6W0nxlnImxkk0zSiWi1bQXAUpCBqpi2Gfz7Jxo4QRFIIkQVrnmIIUNTFmNmcdYjwNXdfvvXgSYoIduPDU8JMn26I1z9BvOvJ6QbcTI/Z5Ws5+8Sy0W22wxgrV33sWi5kdk8XIVQvgNRV5m3VOKIK2wqeIn3xpCotp9hTISqGdwdlZWpUx1mCtFIkSP6oKtTgIbThlnLLkrAk+MRUftF3fk3LioGpRRqOKgXrOEWsdVe3K9F0mn7vdiDKaGHwBLEdSSLSNBqNZLCtOTzrk8ZQGNCVFTAZlQCGGsjZGjNMYp+j6Huc01x9YkjN0W4/CosaAc6K/ThnGPtJtPad3tpye7Bj6ETCYCtbrNTdv3aapNTkKEGq0pXYOaxRaWXa7ic15h1JC+a8ahasrkveApu8npl58oZYrh3OGYQyMw4TRUjCGILIGpRR1PU9/RB57dLXFT+zjyIdhEqPfOJvXymYboidME4tFRdfJpmGtJvjMlCM5JIySQqFpHK4SD5cYNd0UGIbE3TsDdePoh3PaZc3996144ewuicDhakXuA+enW0xlWCxrnNEMO4+OCZcV60XLsm4YdonGNOJ3YC0GTVs7coTaakgFiELuZa8SGUH8VZEYoTUqBaK/AG1mFsM4SIPrdCS3SSYgThFzwOCobYVea5rWsD6sGbuR8RSiF+ArK1UaLo1mbjiEmSm+fZFu7Jm8TMS7rmexaNnt+qJRF7lNTWYq4G9jHT6POGeojADlBOju9JydbbBVhTaOfgh7OaN14nNQVRZSZruJDB6apS5mmZnBB2or3krjGNh0nqkPjKMUOxkYp8T5VlLzVsuKg3WD1YppynSjZxxkYhdCAbCUpq4NdS0Gx7QO2zpha5SCjVzivAFfuAMXAJqYKUuAbWlyU75nIxd/oMjg5QLOxao2As6NBdwWjzsjDJ4MPggonZUUyrMMqWlaYhgZx4HJB3ZGvLpQM6NFpj5tYwlhkhU3X8gVnDWFUROFNp8k1MAoYUYZU9E2ByQPMUwyATMK41bsdgONdmw6T5sS1ozCdAsybFivYIph5m+XQUZGGdk/xtEDHT4KADZ6j7IVlRUsLIbMEDxmAuUsFZI+lAJEI6EvxkDtDMuDhr62xBRYxopuCkwx0Y8DJ2cb8WxrNK622MZx96Tj7KznfLfl2vU1R8cL6kbWYD/JvTGMkvijvMaPkRwUY58ZOk/TOu67uuROzty606N0ph8yVRUEyLKqgKhF/jAlfF2JD0iUQAWQqV3dVlKOGXneZq+S6AeS9zSLBdZZvPeFYWf3hZsF6kbvkwyNMRdmwLZMeUuhHyMsVpbuZBCbACfm5/VC4UfN8ZUFXa2ZxpHJewl7KI0/ZFYHFZDpO/F9UwXTmYaIUXJ+VfHEDDERp8g4CRC2WjXUlaWuHEMvr9c2AojWlcM5AXKtUeQoUoWshLHng8dHL8xRK41SId+U5y/vn8OL50ztGz1hRBVvqCJzno2+ZxP9i+d4NhBPhAL6+SDnbwaBJFRjTiwT/5iZCaD1xeso5Pfqkh9UBrSap/Nyv2otPxvjhTxQl8lwLoPBkEOZ/srAC6X2DZr3QZhBVu9l6CRQ4cKwev7s87nJhSUFAhBobUodZcV42s7G1mXYpAoAV4C7KSQ2u4lhTMTiU3m+HWkqhSagVfFjKc3r7M0VQyQGabSNyfvvVNVGnospEnOxykiXr6WYpYs3q4CElOZXEOhZMhhLXVgALSgAABe/L+e6qF/3fzeO4x5ANNrQNs1elWBKklk5tcQUSxJwwme5XyKGkI2knaKFfYbINOdzLV+IAjRLjeNTRGOoncjDRRbsGcZRvCIzGJ2xOmFU3AN/1shEIxTW5+npGTceeghjDH0/kLKinxKbTvTgPoLL0gy3C6n/Dg/WGKv2dItXvvJV/PF/7/8iwUlNi7GGf/mLv8g7/9X/j6PDQ9705jdz9eo13vXOfy2DF13z1Kc/zeHhIa9/wxv4jY/9xv5LXvjKlfW/gIDzgxpT5Pbt23z0o7/OG7/6q+n6kW/+5m/h+rXr/P33vZf1qsHVlbBrvABhoHnooUd4xSteya/8yi9zdnbGdrvlk5/8BN/7vd/HP/wHP82qhAsUekSpZUT+P3/PyXu+8OwXmCapG7/w7LN8zW97DV/1Va/jiSdeyo/96N+h35zxyH1XeerTn+TDH/4Qb33rd/LAjRt89CMfYpbsxhgLPCJf6i/9lf9CJPnAw488wkMPPcz73vtrfP6Zp1E58eEPfYBnnvksy+WS173udVR1TYyR9Xq9H0gB3HzheT7ykY/wule+lJvPf4nTkxO8nzg/O2e3OeeR172Kj3/6GaZx5Nq1azz88EM8/fTT/N0f/Tvcd9/9PHjfVZqmlqFZfBHjEnk+1CwbM9LPOCd1gFIJ48DGtFcfzJJIlUV23rhixaAUtTW0tcNYSSo0ZIL3AiynGTiSwJYci3l8CWCySjwt5Tmfh4VSX0nwZKmRkrCyfJE/Xl7x52Tii9+zX9dyAfW8n9fxSD959CAKF/HZm/ti8azshsDZZmSzG2VgEyM5Jxk2lYHXDEbHkuKe8fu1J2WRP8uARNaTOVDAaEXdOOZgN2sE8HHOkosqyBgZzB8dLKhr8V0MIQi7OkRGbwhBJPLOWbZdJ6zwS3K6nMtwXEe0U1ROAE9VvBFTlqCb4DPojK2i9Nulfw8RKNYDShfP6uQllV7MP7HGULmEd4nawhhmC/yZcSYDXq1lzRLmn6wJKSGySISRp4AcM2OIDEEY70rJQChdAmXn5WO/mpahj4TVhH2QymwLYAtOoZB7OxotUKyk8EGaLgqJsm9IMmgEZNCyWrYslwuGbsAnIfzousEuWlaN43jZsHaGlZPAgKOjAwlDUooum5IKPrFLCr/rMNpwdNiybGvp7eZtlovPIV/twhlfzX+fy0BeJcoWWAZpMrzXShI25d/M/1Zf/JnNKCw5GlII5YXLddCwPlyyG/g/dXxFA2E5i7QmJ4rXl4AL2ef9iXdOM/YihQxTpF04KifGzzkIyl4V1pSos9SeSjmMgV03ijygIMFZK3bdhDPiD5TIDGNhU5jiJzJPUykTtKRolwtoYOgGxmES9PtSUdWUmM95wilSJWGJQcI5V0zWFX6cOLh6KJKbGFiuliijhM2WE9FHhk404fMG6lwubCdJLKqbihgCtlpjnWYsMqZWu+JxIg/kMEx4r7Au07aBuqmZdgN9P7FatgJeWEFic5QHQaJ8DVUlMhRhFim2m60w4pzwIY0RhH5x4Fiua4m1Rc69mOYrwZSVBmUkxl4ZtIFxmtBG0y4q2lYzDhN9L3RJY5PIYKqKGDXRiynz9rxnHEZcZQheNhwfAgYDqej3i/eHNQqrpaDs+7FMhgN140RK1AeklDT03U685FwBj5zl5GRH1/WEOGGsLUk/GbJmsajwYaSpHYqEqy1VrVk0DeebnmkayVoAwZzEN8s6DUo8wppWggziFCBpmfhag60MKoXSZGq8T3ivGEcYB/F2qhpLvXRsNz2WRDJzUWwwdUWdSoJLVhgMOcD2fCAMiqvHLSpFhnHi7Gzg7HTEaJE35aj54gtnWGPZ7kb6wTNOUZrIBClp8cxLSrx5ShjC2HXCtCIVQLY0q6X50Fo27hDFdHyaAk6BGRXaiqTJVOIBFVtNlzMhsffZyQVh3jMVCksoRLBBwKC+HwWoQtH1kt6pyuQ9xYzOoLPCKoNSlTRQWtFUNVMIjMPI2E8obYg+CItUB0mg7bxMQ4wmq0SIXky0jWYYR7QWAFppUE5CFrreEyYxGy2LAikmdt3IMHr6QSQaPgjTZ9uPZbIvm7pY4CucU+LhVhv8qiKnhuWiQhdp2Dz9nb2MZO27aE60UWRVKPD3FGd5v6nNnjZGXXgFCeNMieFoadqnMZB0kkAEX1i3RpNzknXCigR86HbcvnWXmDxdGO8ZcAlNGlaLGlUKMpA0Rom/FsNTCUHKTIW2nxGmZeNqdNZFRi2rS4gBRmGKxRCxxnJ23jOOqbDuQCuZMOIV4+QZBznP7VK2T+sMpjYyJCBjK0vMCpQhlWlcTJlNL6wxUwl7xFnNbjdRu0wcE7rJdGpgtaiKHMBBUESlSF5ALGPkeVcGbCOM5W3nUVp84Q4OF1hrWC4c3hfvDJ8ZegHd1yvHoqkIUyIRGXaRxbJivajYNZbKabSVgn0chQ1iCuMLMsYCSpieow8oq9EFSKmbivvqqjQmqrCBCnMxS2GpyOV5FwngXj+XpaGutHzfDMLyLkl44iWoaZtGku9ClsRAJ2lSXRdIJJrW0iwcB2tL11m6nWG37RlHYZtKal5Ea8fYi8wxTRGjSuqXgmkKaGXZbiJWZUKRosSQiUEGUFUlXi8xevwkRv1N46hr8Y6TsB3x/NNGUzVGGHVhYoyOCitWAmFGnPI+6ELu88IOSqkUf/cmJ0qyXRmgpYz3vsTIm/1zGLNc/xATPgZ8jPtkrPl9KOwSX+7dmaUwSxLni+P1RTLZ3LopFLoYwCuly94v/z/7PV7UNFJMZ+aGbV4/VGG0BiYfS1z7BcNtv8YU2eZcL73YrDpnSfUcfUKZMoTTiqqucVW1T5K7ADPyPel7IYhfDgUMVIMMUl1hNM6N5t6PJkTCFPBTIMRMDoWpWc7pnHqmivw/lkZ89s5xlcNZW6SU7O+98tH2571c4ov7gnuPlIQxnBMFsFOFuXVxnYUhUdPUFWOOeHJhXlwwakY/EbPsgXKPSfrX6BOZMmlHyeeNeT/0UKU+c8aw2XYyhNayvzijGMYgaatxErlMLul1CPtRyW+YCkAw+pEq1fiYePqznyWEQNsu2HYjd057lFmQY+J8M9CshCV6dnZG27bihxbV/vydn5/zwQ99gGmc+O7v/h5CDPz6r/8bnv38M7zmNa/hsUcfpalrXvL44/zwj/zI/p4+ObnLjRs39tdAKfb1QFmq9uDRfGiteej+a/yv/8u/4Ju+6a/y27/u6/j+t/0Am82GD33oQxwfLHBNw+hHcqk5nGt485vfzAMPPMD9993HH/53/ogktU4Tr3/9G3jssZdwevf2fPXLuVZzv1dq+zmZ7YKhopRi9J77bjyItZYPfOADvPqJR3jNy1/Kcy+8wM0XbjJOE8vlcv/5Z7nXZXDvJS95iTxX48RTTz3Fe9/7a3zuM09RqcSyqfDe87rf9npe8YpXFJaMYb1esze0L+cnBGEcvOplT/DCrdv790SBsZbjwwOuHK745//0f+YNX/3V/PDv/RHunpzw4Q99iA9/+EMsF5JqrLUuwzi+7JhrGa0UdVWjtSvD/CQy5MuATwh4PzGNJflvDgTQqiTZJVKeyFn6E20MoR/238sWM3fpkeJevqxUK7XRl5F+hHlvi9m+AB1qD6bO95NSF1L5S0sbc8jAMHjG0e9ljT4mWXvKuip1sxAZJNQlMk6RbvAMk5jIp5JCqQsYntR8rWYgIhUpsyQEhyDyeZFzyjWbmaZt7Vi0FctVJSBfFMWNDEIpAypRFLStAGaxeNBKjzXvVxprLGTDM1/4AlHoTfOpk5+PCh/KcEfDclERg8dPXoKBKNYrqZjrKMUUJs52W5xuy7VSxGz29hIyLA3s2cwl1CQZSYMcYsBGAfbmYVSmSDtJoO5NDpXTKGwoC4QMofh4XQbSU7ycIF36rxnEKXtdDBFl5iRhW8A/AcNUOTEzaJ1LvSBqDQEwL66ngGDzsVgsWK2WnJ1uRIVihD29WLYcHSw5WFQsjDCbnTVkpfnSeU8IiZvnPaebDlfX9FMi9CM7q9nsBtarmtrd82hL2Ufeg+kvPlKebVkCWpUe49J5UiqhXrzhcQEeSpqoAm0JBQCeJs+uH7FOQqC2u/HLX+C3OL6igTBrjCwIky8SDCQS1MjmnKKczFAmp9tNR0yO1botyLrAvFXlyuuUxSEJrX2cPLvt7LmVxPkmgU+Z1dpx3/0LtFV86bkdk5cFTYwI/aWiVqR0i9ZhtLC2um4gxFQmFtLkit5cUYalkm6lXCm8RJIUQ/GbmaJEuI8epTVV7Rj6oYwIsyT+xShU+P0EVx4+5xxGK1YHC6m/U6LrevphLA1UjTHFPFc7YpzYbXu0mTg6OGK5WIKCw8MVde3Ex0yDyqqg3pLC6SopRuvG0S5kx37++Tt0/UCbnchtrCakJI1/FLDAACZJHHVGfLes1fggTKecFFo5whBwrUhUxmGk2w6MvcfYJABAJcWBSBGkGfNTKHIvqDCECKcnGyorGvvD9ZKUJwk/z7k0XCMgQF7KE96PLBcrpjGRk8X3iRQi9aItiVDCwGlaJ+e1m6jqXMyUNYu2Zn3QcOuFTnxv6gVVaYxVcbzNZVIj5rhpPznPlOu1GSCLEX7bigwyJYPO4JwYo09TIETYbT19Lx5JOcHyQHwPmqUwMWJOHB+09ENgDMKYOr5ygPeQ0yzPycSs6EfF2c0zTpqeW7c7XrizQ6E434wii01izN2PgX4UP6dZSjIDsgK6iNlziooRjXWyAbdNRSLirCzOVWPRxLI5B2JQ5BzwKmGVonUVYGhtw41jje02VHrivJsYfSQWFCUXmfAsJ44xYrVitWxEEh0STWPZdRPeywadEsVcVYqrGVCwldnHq4txZcJYRVM5iJmpn1i2LbFyktg1ZYKKaJuKFBOOljWuEuPi0gNL85UL5T0KwyFnaTxMkQeGST7rdjdSOcNmN6BLs0E5xUabsgllpikyjplhFOlWjJnJi4yyrS11Y6SpBGpTFcDw8i9k8nypSZ9/RutL/m4vTqdEJGEq28ImKPLNKOvt5AU4qOeUtKxoFwtc5QjecXC4xloBCodhEsp78Xbpy/WqnUOhhQ1sjCT9hp6mrkrqkGbMMwtRF5ZnhdOZlC2ZRN0sipuZYr2QJMfj9YLbdzb0Q6RprMRkGwEIRy9yX4NcD22Feq8AWzl8yiwXNc2ixtnilFZAhRwlXSkGcF78HskCkKXRc/es564ztO2OIcp3Nlpz62TL+W5kmDzdMJJVoGksCkuIke2Z+DqsVzVVteLooBFmUq3pdhPdbiKHUphaS9tWHBwsxCfnZENIIrfalWS41VKSiaeY6Dpf5JSq+DHJa0gKk5PGniTydCeS0bp2jP0g08+5xi5SAqctKkm6qbBYBGSQckmRyr2gyXs6kkLRWFeKuyx+KMnQ957lpHGVJUfFnTvnHF2txfB3aVkva2yVsJXspad3O7o+iu9FyHQ7z9RLGIEJGZ8TVaNoGwkzmIof0OHaFSZTprKOpA0zyylFCuM84ayibSuaVoDycbcTdmDMGCfPwFQFej9iRmGTZptxxqGSKrVqKQC1QWuDT1JzSFLnbJ6eIQm4kVIiqljWOGlaZnniME5MvjRNSeqBGby4/KzOYNfsDybm52IjMTfFUv/M8oTLwDQoIk1tsUakiM4KCzsWmbsqTCKtHboUtkpRPM2k1hqnsJftKDUzoNT+M7K/Qy6DAUUWWVhnKSWpvcIEFlbakclobYuHyyVWj2LPykg5YorvnbR48n7WapxRRYpY/k0WsEYsC4SJ770nRcgqloGgLOiltxYQTSuEfqJwlaSB12Wd8iEXxpwSyVt5aGavoYum6xL4UY5UruvcTMcs9WYobJG97NCJb5yYUl8YcacsDVdMnsF7YjbkHIW9l4UtMDcnJLlFu96TSfiikMiKvYJh1w/ElPe2B60z3PUiPYsxoLFUZThjlCblEv4w34MxkMaI0oa2XfDhD32Y8/NzHrzxoIQ0ne1w1YrtdsMYEo88+ij9MPDZZ55hfXjEra2kq4eyLz355JP8N3/9rxOCx1rLd7z1rbzspS/lyd/8qIAzSI11dnbGzZs39+f1p37yJ/jNj3/8Xink5XtyvvkvPQvWWF750sf4pXe+k7OzM37nO34Xb3zjG/nkJz/B7du3uO/6EyhrSJOC4t97cHCdN7/5zfhp4uGHH+aHfuiHy7U3NE3Dd33Xd/PjP/5j+/fUSklC8OgJM/OIC3/Ay035HAgBMAxDAXvKgEtfDpC4FxC+fPzdv/O3uXblGKXgc599mhQjjz38IO1qRYiJV7/+TbztB97O+973a3z8Y79JVVfc/8ADHBx8uZeXnMJ0iQE1/5mAz5XV/IN/8FM887lneOyxx3jsJY/zB/7QH+LVr3k1P/a3/9YerJrvabkE96BF+z+zTobCQgwoVhDOzsiASM+CZ+grBusEUPH+IrFx/oRZnt+6rum7/uLZLCwnVyxo5vc1Tu/BujmQaD60nq9HsR3AXDDUYiKU501duq8Usj76ENjuBjbbrlj/yBofMvgEAfZ1toISsCY+WCGWNMwowrlUQChhrF38v3wH4YgKPpPuSZqV7yAqBlsJyWHR1izaCldZlFFM00BWkaFTRWllcJUt1hryvE3FQgYlAJO1rgx4NClZSZBOYqVirQCVOSesElYrZY0zWpOU+NlmsXeDfUCJJgbxNoxes2xbpihDvZRkIdXz+yaD0RmVNSFkumEkafGJhsy6aWjqWuyNZioSMihQSO30YrQmk4nI+yclPe18KFWGCnG2GNj/xd6+JSOMuBgDzjrqymEL+cMYfTEpKft+1rlICE0hbJR7ruyzl+2RrbO0i5a6qRnHCYok31ixODnvPCxqrLI4Hzm9eYun75wzxMSEwlSO2hni+Y5UkonPtx2HBwtq50hJ1BtGyxA95UIGKrWCJF/e82QQIkXeXPYoNdeEs6D8ou7Yly/3DI3kfumGiVt3zvnSrTMODtbses/dsx3/Z46vaCBsRkSnMBJHobAvlnVJYkvFWHmOt05op9hu++J7YdjQU1UGZyqqxjEN4sU1N5IpToyTTF7F58sRg0w722XF9fta6kWF94mz80mahuwZx4lUknAozUMIEVtX5CxpNs5VRCYoE7y6qfZUSZFUGXCqFOSCmvtJTGdd03J6+xSUYbGspAgcp31RGOfY8WLaGJEi2FpD3VoWyxprNctVS7/rIQtd1VUGMYmPjH2kaizOtkx6ZBonpmni9O4pADcevEY/9Jze2eJDlM+bFMYZ2sWiUJmhbi11bem6Aescrq7FU8hn2qUh5cjZ6cRuN+7BEuc0Kgr6bowuprRiqDr0HqUsi8WawZ9grWHsNbudBBGopFguVzRNRdeJFEUp8f7puqGw1BTaatSESEZyBjTtoiaECw+OcfL4UNgiMdG2lURxo4jRMvaas+2GopynaYQp0PcjwQeqqmaaPEMfUChWS/GVkY04Mu4mrlxdsViIR91uN5BSxFVSAKeYpYDOcc+eUCj67UBTNWQbMTqiqJh6ARnsQYXSGT/GkuBWUt6M4YU751y7foi1lvUS+q1slMZoMfvNYJzG1SXeOJsiwVHshsQLd7acnOzwPnN6NtAPgckHyQY2DqU0mW5+OGG/1l/ova0TKWmKnqaqAaG/1rVhuXSEJBtk9BPBe9pGimxCRjlVTJTFAFVXDdnD1dUxzaIjrjM67ZhCFCq3ONRfKhaleRjHibatWC5qhj6QUZyd7S5khQWY9ARpyhFz715PtEome0Yp+t2IawyVBT/VdJMnhoDO4x7Y1Vr8BowWin3bNrSLFq0drWrYbQYq4y6kN1GKGGFOyH8rg3i6mMx2J15Vm91IjgI01kZEMpUTSY5WRY4b1X7zHyYIm8h27DkcRg7XNYe2xRVT1Eq61jKNlPtOlEmmbOuXC7uM0Zmc1f78+igy9coZ2qpGZQmeCDFKe1ka3JhTCV8QY+8wJcYhslhpdtueaZxYLFraxlENFu/FxHnRSEE1G+arlKmrhroSCaBCETO4WtLXrDUMXiRDVWU5WDUcHC6YJgtoxmmiQVNpYeY0jWUcR6yV18oxkKJ4+IXhouFc1I5lXbFcOHZhIAVAJcIYyCHSLJYcHa0J4zk6iTTAaYXOHh0S0cuvxYHBNg6l5Tm9eWfHbhxYrg3nYcd61bJsG75094y7dwaZFKqIsVKIxpw4P+84HUdcm0lp5IH7D1g2Na6aijdSott5VNY0jQS5VEZhdGaxXrDbyP7nJ89msyX4KIlxQyAZxKcBg9YiL1FRErrahSSlhiB+QzEmmmVD8EGYemGiqpoyAZeCTuXS3CPOKimWCWDxEQRZH5Qx5DL4MUamyU1dkXNiChfT8BCjmP63DrTZJ8/VlcVWsofY4v8xDgGULnUATEPC2LSX6ykraaUJGZxIWqqmqRw5m/0a1S6rMr3VUmxHaVes1VgrrNyqckQvA4zgJVHLJDA20jsvQw0j8o4QPctqgclO/GpSQmP2zICYsjwrBUjMpZGbUyPnpLK5tZRETbFv6Ptxv/dJOXMvg2UPJBWWkdHyzGgle6KPgbBv8i5q/f1goxxaicwI62SryhefMSbKmgLauFJbzbIcKWJDuaY5c0963czCmT+rKQBkIpUAgbS/R2YgTGUBWbMKjNMEdV38cMprFvaSnI9iKp3zxfXTkBEp+3Jhqayw+eeacM/eIO/tI2ZAZd7nRHKeL3wU95UqZfpui/fsvYEnZWZTJEZ2/71m+be8erlu5d7wIRa2zcV75QzDNDH5aQ8eSINvid7jx3HfLMUkct/Je/ppFK9OZTG6kiZJqcIWDHtGW5cvGmcQeVRKmW3X048TzognS1sJSDBOEyElctbYSrFaWprKklJgCtzTbGcESDDKYaoKayqeeuopnnjiCR5/4nE+89TTfOn5L7Hrdrz0pY/zrd/6bdy5c4ff/PiTVIsDvni3wxlTgpIoe2Dmvvvu493vfhdveONX8/Xf8I08+fGP86lPf5Kbt25yfn7Gr77nPfz8z/2T/V3yspe9nOee/9KeBTPvxTFfNK/7K1JOhTGa61eOuX37g/zGR3+dN735a3j0sUf5Z//sn7IuYU0zq8QHScu98dDDPPLIo3zwgx/kQx/6gDTC5Z5v25bv+u7v5qd/+if3ksUHHniAZz79JOeb29x34xEODg7L8zF7U5XkWKDre774BZFLvuUtb+GjH/6AgD/jxLVr16mcY7fdiuwpJWIuDfQF3sev/uqv8v3f8c1cvXrMy9/yO1gvW6xRfOQ3nuTq9fv52t/+dZyc3OXHf+zv8rnPPsP1++7jW7712zk4OLjnntwfKe6ffV3uyfPtlk995rOErHjssZfwrl96J1/64hd55JFH+a//7/8Pvu/7f4C//tf+GmEGwvKFT1guHzZzkcQHhdlVQlrmz5FnjwWlgBIeVi5hihXsuv3rq3teSxIknXMzAkrTSA1XV44UBRBXWlE3YvPgJy9JivONMjPjYhJ5XvljqzVZa3zOYuBxCQhTBaz3PrDtBrphYpjShRk5lIFDFkZoLkBjYWd7L5JkOUXSB1MGmxd3dSYjvmf3XKZckprtzIRSpS8Te6GmrViuGpbLlqbQgHwIqFrSkOs67fcUkkUbUWoZq0pgXKKqhRWrtcH7QNd39H3EVtJnWy/7t9UWCBwsVlw7OmbbjazampQyfS9hI6ebruwfWQAdFEEnhiFhUotKlhhHVDbUdgbhEdudnNAFXJ1GSQjXW9AuU7Xwsvvup64qAd5S3K98AgpeMDG/7FYnE+JEDKE8k7kwcOXq6zJ4YT/gmdeVAhbnIHWQLd53rtn3PjnP8koBXJUurHEl+9vl62l0Sbrfg52KxaJlsVyw23YSuoR4jW5jR/QJrY5ZWc3tW7e4/cIdzrc9W+Do+jGPPXCNwSdu+klq4mnizsk5i0XNsrkCKCptSgq9qHOwcxcVRAWm1D3Lgw/iJ1nPUdMXD46wMsmX7thy5D1pEFD4CNvec/Pulk9//iZ1fU7McHa+/S2vz4uPr2ggbBxHXFMV1FAKr7qWk9yfjkxTQmthvkwhsl60+8Y3RE3uJ/oxUi8WgvLXIm/ozMSUL1JGpODSaJWIRJwTU3FjElevL4ghsT4duXNnR1/SdMQE3zF6T4rCzJhGCD6igeVqjTKRbtPJzYxmGsN+g50Lj0yRGlorrzEFpqlDqJ6epkJkFDEx7AaJQ1dqn3iEEh+wxarde6odX10xDIHN2YacMuuDA27fOWO5aJjGiNJQVcLuEv+0iCYIQ6PruXb1CKEhG2GwhMzBwYKumwp7pZhgKynId7sd1spiYK3FVbag5JmE5vBKzZ1bG0kOQ4rRGCdpoLV4Kxld0iMw3Ll9RtUoFsua4DPHV1ecn3doFVitG46OV9Lg40m7wDSKfEUh13J1uGTsPK5RbDcjxjiUkaSiphKpTds0kBK77Q5V6yKDSZydbjk7jShqbt3aCp3cBK5YQ9O4Mv3I0lQ7S123DMOIsxpjLH03ceeW30/bbWWIXsRsk5+IyXNwWAvTp4/0W9lUq0bS00DYJ1kpup2ksGXVsduMLNc17bolYPFR03UTCsv6YCHRxEjyxpXjlu1mg7MG5zSbbY+yFbWzkn6pNWiYxsDpZuLkdGDsA10nfgOyiBXUFg14QO2ne/tjRu1TKTCyIpCZQtHRJ2mL28bxwPU1JZAYCjXdd4pK1TRLI74m+cK/gpSxJR7aasPgRxaLik03XCpmSqlUANZcJigS/BDw3uylzPPCrAqIYoz4Ec3+liFG/G7ERwEVJj8yTZ777jtkUdVsciRHT9eNxWg5sVovsNaJP5aVDX5KvjA6YOwC4zhRGwnkqBuZgM3FqCqMs5wkjdFWFtWJ3DmEJBM1A00lgRRNU0sKqdGEmPFTLCb6BcwLgk6OaqIzGmMtBwdl87EXzZYklEFMCpLQxEOZrCqtsMrKs5VkQqijyFCtcbS14/DgADJ0SpojH8VfQymFrRy1baTpd440TnsgZLcbqCtdGi/xtfJBGC3DFDBFflQ3FcvlEusEQFyuGpwy9FNivazIQYqETTeBFvZa1RiW6xrTifwnJdB+ou86VteOUFqzXotX2KJpGSfxgdRWo4zBJk3jDMumQitYNhWb7SBFbWFyurJ2ZJ+IQSRy1hqmnDBkamsJUaR2KSSZRhpDu9BMcUKpzNH6QDy6xkBmIuoiWQmgbSYHxTB4UpTQkytHS4yzxAjKWCpj2fQ7VDk3tXP4CZxxHK5aVusKZWAaBq5dW/P5L90tjXGkairu3N4yjaNYBriGyjmSluSfaEQ2LoOcsseokhbVT6icGDKFuZxYrpwMbyaRwdpKWDop+NL0lwZmP2jNDJNHGaiRf6OLSb8iF3/JhGtqqsrQ7zyLVQtKc3Tclom4xtWGUIZBIpmN5b108XaS5MraWnSdioG77JPGieehNgaM4s7dDlNJupQukpjZS8XHIJNMIxJgZ0VqPfUT243sxcFHTJK9cG4qnDOMYUIpmIKn1W7PIpB9IZU1omKfsrSfAl8UtMZYjHFyP6VMLoliuTBZZjbEi0v1eaK+lwtqxaKp0Fom7KkAfLMHymxWmzN74+kZEBT7BlAFmIrhkmyxUJhkiDgzK8NejiKs/Fg+U2GxzEAjF0yEylV74C/Po3guwL3LgJkmM4bA+WbLkb7wm7t4E12ahRkYFACsrgzjlMiqYrWoWNSanCRsIef5+xc/Ggqr0U8X7BQE3KxrxzjdK8eYW06t5oTLLNPxwpIIQYCBVGRfMyD44v1UqYtHJeVUGuu0/4mcZ4npnP41FUlZSQP2YR9I4ENkmia23cCd0y1n2y3DlHC6AQxG10yTpG/PVh8Xt19mDiIQ6Y4jZrGyEPABnDP0k8eX5tE6R9PAcmExWrHrL6SblEGJngOWEEDhypVr/It/8b/yH/6Hf5Lf+3t/mJ/5mZ/l6aef5pFHbvCt3/ItPPrYo/zSO3+Jz3zmaV77ujcU2XPYJ7oJyylz5dp9/PpHf4P3ve+9fP/3v403f83X8qEPf4hf/uV38x1v/U7e/oPv4MknP04IgaZu+MN/5I/y4z/2o3z0ox8tTWkBU2bA4dL12N+LSPjL/Vev8KvveQ9/+s/8pwTvedcv/RIPPXg/bduQkpi677qBg8MrvOlNbwbgF37+n/CB9/3aHszq+4Hj4yN+5Pf/QR584EFu3rzJbrvju7/7e/i53ZbN00/zqle9hle+8pV86UtfwhrDwWrF0PccHx/zile8gs8++yU+97nP8elPfZLveOtb+c3f/E0+8NEneejGQ3zV617H2dkZn//cM9x/33VmllXOuaQQXzxPb3jda6jrqtgdFEmbNfQxMI4Dx8dXeOkTL2O5WPKa176Wl77spSVV997DGEPOiWXboLJ4LN248SDtcs3HPvUMX/3mN/Gf/ed/np/9R/+In/+5f0JMkc12Q7e7YHRcftZzyiSdyMoSUdQqXTDE1Mx6u+DiFEXeBZBR1k9X9rdQVQQ/3cOWm5l2KEm5dMnhnGO5aFm0DZWV7ySBK3lfB/hCnhC/1OIBnWWwnlKQYZBW+9pUK4UqcnBdAP+cE2OI7LqBrhuYRs8YFD65vZxahiexJNuK8f8s85YgFV/OW7FYURLaJoNpJYzQJFAMKu+DSara4MwFY1/bvP83OcngynshmMxAqmCMxRvTCbiUktwvIoXXhd0WC5gvvw9hoht7Nt2OOIm/otLsvY+1Mazbhpc/+igPXjnk1umO44MlRis2u55bdzc8f/uU8+2OfuhFZeU0rXNFpplBBdZ1S2UtVeVonGPygc2upx9E2h5TlhTNDHU2xKigVbRlCJdmyxgljCdtL6wK/m3HNA34saNuRbkiYCXMzD1VgNUZCBMQLImnqTZUxL0fY86yvvgYC5iWBfRUaT8ok3TFGfgq1zXLfR7jReJt0zasVkvu3D0jjBNqCoCibRsWbUv0kZN+4vS524y9DEiurhpWOhN9YOgnduNA14+4QTH4icpZlk3N4WpBzoHGVpQyAmMgzB6Wl37NR11ZnJXn5NJud/EduPznZS1gHlCUn9aaum5EIh/h/PScRduw6br/3Ws0H1/RQJitBKhZrhsBfLSlqipCEGNtnRQqCTWwnyaZXDeWGAPLI4cfNSfnWw7HkcPDFbFKLBY1GzfQl8XUVQbnLMZo2qUj+EzTaK5eE4Cj24wslo71uqJdaj7z1J0iZRTEG62I0aN1TfSeXTeyXDZM08By0Qrttp84O90hAFhguWyJQSREh4crDg9atMo8+4W7nJ6eicGcEcq/tpbddtgv3CGG/QJfuVLwqUhTN/R5YLcbeP65u9S14/TuCQ+/5BEWiwWLpoUs8pcUE8GLdKh1mn4Y8VEYVePgadqGg2ULSDG7WjesD1Y4N8q5Lxt6CBG0wTrxP9PG0J3uOKxWuKZiGkZi9FS2xVaW4Dty0igjPjWqpEIYI+CDdmBMFhabMVxfrbh184zVsiEH8QYA8cHSSuSR06Q5P92xPR8w1qKMIQQBKXabgZQCziqqWjMMHmMaDqqqFOMarSxhSnRhIiaNNiucdex2gZQDymRiEKB01w/suk6ov2Qqp1gsLIuFLILbczFah8zhwZKz8y1GQ7twhGjpB8+6bUXz7iNjjDhtWR4YbCUb0vm5BCJsNyN+kibs1s1TAUIWFXdunRWppWV9fIBzTpgh5x3GWQ6PFqQYWDYWn6NMflNmvVjAJE2jVZpbtztOT0dOT0funo5cDNYvL1WFfbSfjGb2cWtq/p+5qUGe0cKSdFoCAA5WC9Yrx7XjFYvWCvhMKkxJSXoL0eOnCV25ElctIQopQWNrul3PQ9evsznfcfNkR1JKAhyK74j0ThebuTEG7zPnZ6MYc15aZZ21pWCSrSmI7kUYJSmx2U6cbUfa1nF0VHP3bMsLY+b+6wecd50AB6WZbWpJPswhMvQT2WaqxhXfnsDmfODu6Sk3Dq6xG7bU1rBoa4l3jolcJu7WaOrKUlnNVkeyEq+tuqppaiQWuW3QFq4cNhgnDeDQR7rOs+0mhsKYJSsmr7l7d6AfE7ut5/hKS9NmiWO2FlOAthCFXj/kyKQDThtaY7EYnHXkHFDKkpP4Uw27SGUdV9bHDFNPGDxjnCCzN/W0TkBy7wPRR6ZBmq2u25UGLtPUYoorCaYVy2yL3FFx9eqK9cGCum4Bw7jr0Dpw39VDSfnJil0fStJvpq4lDlxFzfZ0YhhGVusFbVOx3SVyDgzek/vA4dEhR4drbjwwcrYrDMcMOUWc0yxai0WSkiaVaSon3yV5ckpUraXvJ3R2GCM+ciJJE5+wXMCdqgQVxCgAf7N0+BCELZoTPsCUPdGIxCzEiB9AWYWymThPIsPE+mDJdnfO0dFKQIoqcXTQohUMnSQiWyOBIyGK74NPcOvWGTfuP+b0dEvTONqmZtWs+eJwwjh6kS6nCeMTZENIWmjtpnQUZFaritOznnEKaGUwVuG7kRACdYwoXVNVilhbopZ/H4In5YSxltm/LyUp1pWSYk9lmajmnDFOAKkYxZ8zR/HClClz4uxOx3K1oG0d166virn9xLYbSTGx2YyQM84Zthvxd1ssaoI3VC7TtBXeRwqRhxwEOLXOsqg056HnfOepWstiVRXvrsjg5b5WOmMqYQJpBbvTHZuznqH3eD/IPW/FrzFnqSd8G8WbRRW/LJtQvgBeIZK0DMuUkWkxlKYeqaKF2WRJWaN1hTaRlC7YSTnNAI80ajMUPjeKZt/sSTMVk7A2Y4gMoy+MFWGlX2ZmiX+JrN/WGhpnS+MMkKjrpkg0w97fUGsBR0wxDE5JgNIQkwz1fMSVNMd54NjUFSmL36lWWpjeZUBwmdk2JzbuAxZnWkjKexsJ8S4zZCyZipwdMevCgLlY+KvK0NQJZSzLtkLruAfR9g3MJbsLyMTkS9qjAFyVK3YDF6NqOQdK/Oe0MjgrIQvOKFSZsrjKoIwmFwnfZZbbZbBoz2hRss3OCXb3MsIyfd+XxF75rHXdEJMmBmn6Jh/oB5Gdn207vnTznM25Z7ubiKknePD+wvw6xeLXai4aP2tLXaw1TdvgKlv2hMIwCIl+FMAbBZVLOCshOeMkqcpaGy68nSR0wZiaYQpYo3ni8Vfw8z//Czzy8EN8//d/P//1f/1f0XUddV2Tcubd7343P/mTP8UDNx7ag4epDI7u3LnD2fkGbSpGr1kfXuVd7/plXvayl/O617+er/u6r+cjH/kwP/sz/5g/+u/+cf7m3/o7bM7PuX79Pp5/4TliDFhjON9s2Gy2uMphrGHX7dhsNnvQqNt1nJ2fkUlshh2Pv+QG/8v/+i/4U3/6P+EDH3g/zzzzWZ547HdIQvskz/w4Tjz00A1e8pKX8MlPfpL3/uqv8Lvf9l1cPTokpcSTn/4s73rXu/jdP/TDfN/b3sZP/L0f58Mf+iBf/w3fyJ/9z/+cmOKnRAyB3XbLarnkpY+/hI985CN8+1vfyl/7b/5b3vXOd/K3/tbf5O//+I/z7//J/4A//xf+Infv3uH4+ArD0POzP/OPeeapT/E93/HNcm8Xk6XrV6+y2+04PT0tYHlZK8p9rBQ89OD9fOxTn+V9730vf+gP/xH+4l/+K3Rdx2q95vT0hCtXrhZAE07PztjtdhwfHuCs5vFHHuJse84Xv/AFvva3/3b+i6v/Jf/yX/4i/9sv/iLf+q3fzg/+rt/F69/wBrq+4w1v+Gp+7md/hsqVXmdO78jF0yxDQJGUodUXiYsz6/PyYYr0eO6ek1I4o8nWkLRCL1tirNBGleAaU767YRjOcJUMK+q6oqqcDAFsRV1ZMmKjMvqRYRzKcyhAdWWMMDNzkbbmXFK6L9AAYzTKuPLfwsKK+0VE7b9zQhGLXYYAX5FcJK/ynBV7Gg1OJXzS9MOWUECQKYkfcl1XtIum+F6LCspYRVM7Uo60q4owZo4Ol5yd7th1g3wAU1itVuNcCcGJYuye4jzQUBhlWBZfxpgjxkFtHadnW4ZxwhqDDx1ZdWSgH3u6vmdVXdnvb5Jo33L/0SFf+7pXcuPqMQ7PjWsTp51nmCYO1o6D9REP33iAk9Mzzs43KAVXDlZsdjte9sgDpJS5cf0KlTOc74YSyBK5e7YljCOTSgRy8X2Tnm/RSM24XNWypiOUDdDiIWe+3BvstzpSSgx9R9M02Ga5Z4ORZ4/GeT8puZFZlAe3757y0AP3iSF+COjKEMn4NPsGz3L92S4nl8REUwYK4dJrg8KQtYCmIKEEVV2B1uz6EU1ivVzibIUhsjk9x1rLnbMdOkeurBccLWSNv3PzBNWU8zKz0ordiZ8uvPbEv/RiCGc1/1b23Dxsm73ZXwx8zWDYi48Z2FYZrDKSZJ4U144PQcHd893++v0fHV/ZQFiZojknE1uyYhoT4yhgTNtY+sKgsNZCMpxvM81KtEfLZVNMkhPdrscYy3LVUtW7MjFQHBz//8n7s1jbtvS+D/uNds65mr323qe9fTUsFotFNSSl0LYsyaJCK44kdwEMJw8x8uBHBwYsIDCCJCIgJIgAK3Ec2Y4cGErckAhkyxYdR5SpJpEtO5YoS6KoUlFVxepuc7rdrG42o8vDN+ba+5x7adGPRCZxWfeevc9qZjPG9/2/f9Px9J0L+v3AxYM1FOgPA/0wsHnsMQ7Olg0pBoboaFpDitA2GmsLynoyGl0sUwoMvcgtm8ZxvhFjyaZpGIapeoHIBK/rbI1tz/RDwOjMFEbReJeM7zzWGW5vxWsKZTnbNOz3e0IUdoagwyMpFna3W6EHl0LbNvR9zzhNDMPA2fqMtm0JITL0CesUrrViSj+MpJQ4Oztje3tg0TXkEunHCW3EI0wYJAVtoXWOY78nbCNKaZz3EluuFY13PHiwAXN3YxulOexGbm+PkgqpLaFPWAtd56qvScS3MoVZnhnCGBkOI9vrnhgy4xDY3h6xTvP0nQ0pJo79xO3NwM31wNXLI9OY6boO3/lqNq3pVp6bLXSdwTcNjTd4Lw9lTDJZOR4C+2NEi9kM7eIJ03jk6vpDhnFi9k+JKdN1luEorAXfSCPddi2bzYLrq6MsSKUwjuKb0bauTto07753iXOG475ntztQYsIp6M4cq41H68xHH29JUUGKpAzjmLi53rFYOmJI9IeRxapjCpmQE48fXXBxsebVqy35Zebi4QLnDbe3W3yjGI89D58+xoTE0ni++e0rhrEQx8SrV32V4c3m+XfPnVavx7VrLaCUsK4stWNhnnbM/hNWG5TKNMZwuVnzYLOm84bHD9ZszpYCco49UxgwRphjIWexC1Iip9Li1o3SmpfbPefNgtFmdFGs1gs+/95DQk58//kNU7hvqCwbbCmJ2bD3/mY0H/0w1ufTMpuCzzKXu8m7ou8Lh8OA1SOmwCcf9ujKaChaksE+2W3x3QHjaxoMwli1XiTKxmvads3n3nrA9nsjP/TuWwxDZHiY+eTqluvtgRSFpj4OhWOUcziFDEamqg82lraxGKNYtA6QIICcEs4qtBbpjJn1PQoijlgS2+2RfLPnybDkeJ44Xzc8OF/Vwi4wxcBhGJjKCA6CNtwOB4jwcL1Cm4wpgIEUVGUAJY7DHkXBO4MLRlixWSZe05Qx1tAfJ479FoLBOEXfS1hJKRlt2hpr7VC6XpNRIrcXC8Ny0WK0RZfE2ablertlvz/wufce8/z5jlSEAfz0yUYmsiGT8sQ4FUkBNoZu2dC2LTfXL3n1qzc0ztd0KHh0seZs2XLoE7HAohXW45QC3mlyMiKftZrd4YBtFMYp4hjJARrX0rQdOUsiIRqyLgw54BvLxaZjnIR526y0JFO2mn2fYDdw7jtiHBlDgqywJjOpkZQ1RAsTJ4byhx++gJJZLFbSTBowykJNl1quG45b8T00xgmLzVkePFhzfbsnF/HI3O16druR4zZgvME5z343iHdKbc6bxtJ2DcrIBFoDi66hIHsvCSgChChV8A5yktRW7SzaKvIgrJrDYRSQSxVykOesGEk0tnUirI38eSoJVEY7ARBDTJRYOOxHUpTQktW6rRKtI1blGtAiqYzjEAjTzHKSyPX+mFgtNDFMVV6ApPwaxXLtZE8wiuMQ2B8Ci7oImpOfeBb2s5uZ5JbGWz75/jW31wM5z4wEkY7N/iLjkMhZZJTKyHoRc5L7Wc1muenO00YWHNkrtaYozWz3UyqlYE7Bll+t0qEia2+q/y2pqfYkrZtfVuTKEoBCZXzNMiRj71gRcwCGIpMr4+O1iXjJDHFi3XQi/wrCvNdG0q/vmBzVp6UIk6htWhSqyvIk+dVZe5L1zHYPp7e5R+sotak0mBNzAxTTODBNCWcdWhnAgnbUCFxhBdZ015llYjUsah3gvSWnWC0TqIyZKiEqsyGH7Eu+ERbENAW8u5PlAczm/iDZxdZY2QOhelWOFGVOwJe1VkyjT9e83H1nqoNZEe/BmTh839dJKYUq5ZQ0Pv8ZSuGajuM0sT0MTINIdkLOXO8Hnl3vudmOwtyymt1uZNG1NfnvDtVL9xC+aRJPpUUndWMqpdZNAmJd744ii6/fIwwB0zlKgRgiIURylrAY+ayGnKYKVgZKsRjf8eUf+hH+tX/tj/Pzf+7n+cmf/EmePn2L6+tr/spf+Sv8l//Vf8XTt97h0eMnwtQkszvsMc7yv/7f/GG+893vknXDq5sR7zb8jV/6u/wf/9X/E5//4ANub7dYY/gz/9F/zN/8G3+T3/8H/wBd2/Gtb/0cf+JP/F/40hfe5+23H/Hv/3v/DofjAe8VDx6e8wu/8PNY67m+eYWx8Of/wn/G1//e11gsO672W4Y48qvf/jbDMPCf/+d/mcvLDUMYUJPc4zElvHdcvXrBf/Cn/h/0xyPvvfOEy/OzWvtnvvDBO/x/fvY/4l/9Y/8KH3/8MQ/O1/zJf/vf4u9+7Zf53Oe+wPF45Gt/55e5ub3h8uKSL37wPl/+4uf52T/9Z7i8uOC9Dz7gW9/8Bv/93/k7+Na3v83/6n/5L/OP/N6f5PGjx1xfXfOX/tJfJPQHfs/v+AmePHpYDcxlCfnx3/LD/Pk/9/N8/e/+Hd55+8npGVf3/nl4ecHThzf8zb/2/+WPfOc7/I5/+HeilOKv//Vf5LDf88677/L5D96l5My/9W/+cZ598owvfe4dVosFXbfg5//f/yU/++//e3z80YdorXn57BNWjeVf/l/8If7Jf+qf5is//FVA8b/9Iz/Nz//ZP8s/+ft+ktViUdnq9fNU43JVlAAEMaHc7JP26abZOQFySxZbljwnGnv/2jNWqs8y99hjEuDhOB5HYUjGglYT61Whbc9kaKEUYxzvMcGMDLyQvufuuVFM4Q6kBhnEfpaduDGGtsoASwETZxP5UteiN6S6SlNIpKIoWmNsJsTptdfM1RMqpYRxmovNhq5rcF6Ld6+X3rj1nuvb4+uM2lxOQWgAwzDWkJWMhNnc7S3OeJzzZKRmevbsisNhIJWM0dLbGiPWKyppGttxtlwxpokpir3NprUsu4ZHF+JTtzuObIciFhhGi0F+hsY5nj5+yFuPHkhYmobH56sTi1oCDRSXZwuGMTKYQC4LnNWcj2thQeeMMuKvuFw0LLuO1nevA14qs1COqER++es5jv2AbwaWrhOgCnXqO042JDIppiT5s3eePj7dkzFGsBJGIH1WZW8yyyk1AuOIpYLWhoQWxvFMkFQCsM5e4VLLNfjGYxsPUTCTY38rg7EQQBuyMjxpHatFS7fsiM7yYN1guo7zi0umEIhRwlC6xuEbCaUIMZFHcN3dfS9P5a8NhJWagqu1gRxO3/Ez/8692dD99s07x/tPH7BarTiOgS9SmMaRP/Wn/6O/73X6DQ2ExVRwXjNNiaWTVMHDYaiJZArlxNQYIMSAc+CtxruGsY80vqVtG/a7g6TJLT23N3uRkVVddJgi/b7HmoLSgbPzjtvriev9jsvzhyzWsLu9wXjLo7cW9P05n3x4YDiWaiQvJu1KZ16+3LK5WFCKTNmmMVTfk4mLizNACgzR0jooWryt0sB6vaBpGmDPNAWUHch9wnvLuvWcny3ZbXegRd42xYC2UqwZk7HOM4yxgjs973/uHbquq8Vvwrea88tz+uHINI44r4l55PrqhjBNtGcNy2UnDZDW+LZlHEb2twPdokFbi0mBphXfH5FwTuSc6RadgHrK4Ewh60KcxAhw6GG10sQpClvCObzXlByIcSSXxPJswZN3zpjGkW9/+yPee+8xS7Ng6hOXD9Z8+5ufsN4sxFg7FK6vjly/3PLR924Yh8JqtcR7S7fqiCFIcMJwpGvFuHaxUpytNY13pJRoGqFAJzRTlo2WMGKK59WL7zGNUmyqympKRQzeD/se6xusStLk5czxcAQk2KBtZCFsvEwe5vvj5ctbzh+cYSszbaNachB2FkoRgiKlgrUyqZmGicMhMo6JzXkLSOR4Sonb6y1TiNjWc36+ZhxHwjiyXHgWy4Zu2XA4gFIWbTy3Lw68eC5MvKuXAjjkymIRw08BWeelbI6Hvo/Zzx4mzIt0obIizSntRxvFsmt57/ElDy7OeHy+YrXweGtYNJovfeE99v2e4hpSClgCH794zrObG44xkudptALbGIZjRpfM1W5H3E8cLwZCjDw+3+C15vHlmnwWmYZA3weGkGTz0L56B0oTJQWEbOB3G2fm2E+nbzhv77MwU3wHK6OCQMGiqXJgK15VIRXGIZOHBASUkmJBhjeKceiFbeot/9nzr/H0csPf+saHGK358gdPsdsab60rcTpXWFFV43IjqXJTyCIRt4qX12P17kLA+EUjqYhkSbQtUgj1MYkf1aKRJswoVKP57rNbrnYTnW24OexpO8uQAqkkWmsxSqEazy6OfHxzy+e/+JC8Kxz7CBZKEKbf9nbLctFQtLA5rbYcYs8hBbzzuCIAgLdWelQt4QhNI+EMh/3A2XqJRF5LOmGMkWXXcrZsUBmePn7Awgkj58Nf/IRlt2YcA8YochGGTIiFtm2FseA83nseXp7RNkb2iRCIKeKtBBv86vc+4eJ8jdYLrm56ukWLaywhC5uu8U7kXRah+qeE8dWfKN2FBwyDME29KXSdxTUWGxOM4u82hsAwJho0Pkf8wvPo0RnxxTXGKLY3exbn4t/Wb4WNiwJNpuRAmCTR0rcN7aIlhMRuF1i/tYKESAK0IqFQKvPk3UvGMbLb7fE2Qol42zAmkTe0jUGpju/86iu0tQKgVAaYMTXynUirHdrI0CPmTFGaxhq2cU/jlxgDxjSgRA517EccHm2gqF5YL0AYK7BjLQQwqpBKBCVmuQLAyPNSmGUuSrzWTGF3O3L14kb+/tmaYZjQtvrj6cLNzZ5hyHSLhpvb/gSCGWOJWrwmtYbtbqBphA10tukICwnEUEamtt45Sir0OwEPzFaAIedEvrE8E+li2zpyKjx7tmXXTxzHIAa7Wst+kwvLVUvTOTLCqCtJUTQcY0+MkTOzQds7YMlYKWxLvkt9kmn7DJbJWijXKpMqODXLK2O9trr6Bzkncu/ZxiRiAAClVElEQVT7zeQUIiHUVLCSMer10AuFMJnsPUP6OanptH6eDN7UaULsrEZrSypgbWXR5SzeOSlXQK6Qo7z/aYJ87+jaxWtsNKhJiEgTTP33gjDNZf2W5pYie7xIlKRVKKomc1EBtCQBSimlyvhXdMbivEbV1LP7x5tG4mqeYNfm0Dkrn0Up+fcs8kFJqcs19MTgG49vPcYYhnFCeWFrWS2S0Pvg4inNrMxuSHLfSpyxgpMMtt4zWpPJhHFk7ha00rRNRxhHbq5fcXN7jULhjCVmzc0+MQS5mWYZcdOYKkd+3YB9vi/uM/JSSlLrHXuM0cScmLrIFAUo0yS8F1nxq6stSsn6t691eowyoBRWCTifUYx0rafvE++8s+InLv8hXr18wZ/8v/073N7e0LYdT5485bf+6I/LUGUY0EXTBxkgnj9+wp/6M/8J2nZsVueEmOlDYLF5m09e9ry6/jusuoYnT99lvfRst7f8n//V/wM32x1PHj/mH/oHfztn645+6Hn5/LvEnNlslpxtFhwPV+RSOD+XxPR+2PONb/wyb7/7hF/629/ixYsr/rl/7n9G0zT8G//mv8GP/uhXOPQ9x3GsA9OIayxj3/P97/wKl2cbfvRHvixgi3EYY1ktl/yz/9Tv5/mL7/OgM/zAP/wTbPcH/uZf/S/5T3/uP6ZtPO++9Zinjx9yufb8yO/7Sc7PN/zz/9N/lr/2N/5r/uz/6z/hR7/6w/yuf/C38/t+z+/ka9/4Bv/FX/zzfPf7H/HWk0f82G/+EX7wi59ntVzIM119sBaLBb/pK1/m4+cviNOOf+af+Mfwzt1JcuutYI3hKz/weZ48esDX/t63+L//23+CECJf/PwHPH78gDzc8E//wX8Ui+bjZy/44PGGJ5cb2q6joPmp3/UP8K1vf4c/93P/ITFlvvzFD/hn/uA/yrHv+cW//bf4D/7Un8Jaw2/7zV/ln/+f/I84Wy5ObE9V6yE9++aVagr+Gffq/ePkJ+gU2WXiEFGSg3UCJYZxYoqJYZgqUCvP3c3NgZwL2+0RpRXrVSfek2GSpPhFewoZmVMtX/8k89NLbfb16bn+zN+595m76jsGsJ0mVEyiB6tyyzfXzYLsnyiDytOnnllrHdoaFmdiL4BOJB0w2pKVMM4WjUUpWK87dtsexrvPcyLnpELIkYDIQrXVeC+J0Vop+mmUddkU+mNmsz7nrUdLYg0bktAzYZRtD3uOwygsVGsxOuIZeLB+wttPH3EYByZgN0AKiRwn2RdzhYP0nf+bUVBOALwcKWWwwsAnC3to2XZ0vpEk5ykQswTW5ZTQxpCK2GAo48lxAgpN9b7yWdFrCSn4tfCw+e3HaWLfj+hmouvsa78vAXYJTTnZAdiqSEFOMSEkvI04Jz6iM4O2AEVLjSB5KjJIkpA7Q8nxtedBzfVPDEBhueo4P18xDD3TGMTXtCb8xpRYeI+/fIhatqw3DV/9/GOKt/QFMJZUDP2Y6IeBw+FAClP1ihafVGtFEjkDyjFTgVvD/WAPdWKu6Rmxo2hDjsPpPJyg7XsAmP7UMyb7X9t4zHHkbNlxszvQT5+WaX/W8RsaCGucmNAftyP9biKExOq8ZX3m8Y1imgq7m3RiRAijRNDHkgvHfc9i0UKCcQg0Pp6aXpDrEqbAzfWRR4/Xsunu+4q8w/44EKaWxdqy3wYGM0paXxQ20RQkrc94w343sFx7rGkoSeEaW9MiLev1kqZtyFmYRDllvHdkJyak1syMKrlcxlppwqyYSXvnySHhjEd1jq5T0vwfAxlB6m1nWDjLmdX0x55PPn7GcegF/W8bzjZLxkmYOMYqdrdHhj6ilabrFiyWC8I00B8GFsuWfnvANS3Nwsp0wYBbdjUJU1hCCqHvhmnAmg5rHdmIqa22nlwyvl1xPOyJAXJQDGHEGku3cLRdS9bCqBjHwKJr+eIX3uXm1Z5j3/P07Q0pFc4v1tze7GnaysgKibFXPH7ykG7RUYp8n92hrwv8Uui5IfDo8QXb6x2aA2YjwE0/BHKuppJaZBVaKY7HIA2pCZRYsE4MARsvgQntYg3AMB65ub7CO8vlwzNKnZbMTcoUJj744H2+/Z2PsDUs4aPvP8NZWaDc+YLt7oA5ZFTRYBTKOm63Ize3PXESY9O33tswDoGnb53THydevrjFtw3LdUfMSdI0rUwO1suGbtmxvekJY0uOmuefDAyHI/1RGpJ4b/pT5t38NJiewaD60zIbPVa5TBFD7Jzmtk2fFry2cVxsVjy5OON8veCDJ+d8+b1HWKs5r0yOEHqePriERsDp7333V0kxYVCYnHA5kkIRJtw+cLMv3FztpakCvvfxjpwVv6yeo3Pk4mLF+YMFF5cbDrvAi5fXjMNEGANTotLI5Tu1TSPeLuPEMI6nBTjXSd1sZDmDfPK97oyoM5lQEiVmSX3Vs9l1lTMp6qhRfjulSUAG7dhvj6Az0WQsmpvjjq9/TwD+5cpzPEaGQTZ25zQ6SSpjQRrD51fxtFYJoFewFpFTW8gjYIQ+fTyOxJxQRuGdJLcqFIcpsQgR1RRyk/jeqxesXMPN/kBUGe+0mP9b0CqxWQJ4dntJ4jHekqfEcJBJTogTL0rhB774Bcgjccy41Yp+nE4bWtd2qEYxTiO+NadghWlIOO2wpiFMAvZqDG1T5ZgovLVc73YcTWbVtDx59IhvfONDiIXNesm7j1b88jef8fLVkeUqoNihlebyYsNmvSQli3GOy4cPGWPiwSLirWH5+ClX11tyyMSMeMHFxBgz3kvk9tw4iB9N4eZqoukMiyV0i1q0lsLLlzds1h3tQrzClKreEno2apVhTc6JEpUMRGKgOzdo7SRNEgHAfevpVi0pJqZewHNrIOfAatnw9tNLCdgomcNOLng/Brq2IU7Csk0mYlSgaxZ4bfm733jOF79wznknjUXbgPcZlBdZ/jARYuI4jDgr0tRhGGm8OTGhYkzV2FsR00TJGmu8UOydIqRCyRPaSepnjIVhmjgOE64mAWurBRyK4qOVc+bs/AytKxBsQvXhsljnKvCgOLtcEcaI75rKjAlY63l4ueSagt6NXF0NjENkmkr9bAa7mD1wJExgKFlCXRopKpMp4inZGp7vR4YhME2JXIdjIp0RCV8Bzs5alIahT1xdHZimSLdsSGPE2QacE7Bx4bFOc3078PzVAecs62VLYy2UiUn3tGYhz3KVOZR0N81XwgOS/Uepmm9Yi0kUIUdhi8ZJgMoiz6Kt8rOSC5g54U/fk07IubBO47RlDBFnRPZiqw/U3EjFVNgeBsYp0nrL1W3Pw/MlbWNRZEiF3XEntgZ1kGh1c5IsJSOTeYXId5JSjDnhlJak0yozKjPr6VSLCdsrl1wDbOJdkVzknjEV7EtJ/EYmrekWC3zbyvm8t96X+XvPU/n6LtpK+tlsNnyfXDKzmsv8AyWJVjmnE6usFPEJMtVjU/YMKEpLEvR9c/8i/qilgK8fIOVEmvKJdaEVd76ZlR0nkiRFCAKSzUbISik6b5jGmlhXP/dqvWKxXKG1ZhwHdrsbAbm05zAobo+Bp5cbvvPRtUh0lEJr8Zt7s9WQ9ElhccysQZSEP40pEo7SfI1T4GA0lfAIFHKO5BRRCHgm3o8iwb+56U8su/VZx7NPtoSYefBgydsf/AA/8pu+zLB/n3/I/gNcXjwk58x+t2UcBz76+CNevhKGvZoUJRUeXzzkfL1BK0MIEvTSWdm/lZFh5L4fyQUuz9/ly195i3fefRuNJoySNDhsR1Aty25xek6Ugk1XWd91oMVagVbc3Nzyld/54/wL/8L/nPfff5+f+Zl/n5yhP3imoQByXTGJoiPdwnO5WvNwtcZZyziJ2sNZSSq+3Kw5W/hT7bVaLnn76eP6/Mq16JZLuuUa50R18YX1e3zpBz6oydE1UIPMV3/oS3zlS198jUkpYPCdnG2W5BpjON+cYZs6EImRUgMZ7t8NxhgeXV7w6Cd+nN/1Ez9e15hEcf7kXG9y4cHFBkr1d0yyr66XC370R36IH/uRHzp9llIKi8WCn/rd/zA/9bt/p8i4cq738p3noFK6BlnPaXKl2pv+twNhcxmr6vc1zqCTkYkhAlh89OwFYcocj2IF0g+jSHz7SUKhkOCdKQj4cxwmjLacrScZROdIirn6aEm/Keyyu4VEwWnQfHfIeo+6A9xnWXQpNdFW5ZOkXX6W70mny+lLKqBdWWIsaNtwcfGQw2FX12Dx+8sxiUep0zXZL0pPXKp/6sx2Fl3daW3T+s4XS+4fWYPm3rTzLTFNKJUZRmF/PbhY8M7lE9aLJUvfkCsrMmXxMxxD5OmjTU09FPuRpvHoKrlWCvb7A1p7SkrEYYCc79hOFHRKYAQEIydCvAM/5v2tFMU0St+klcZpSFqSKWfG3rwnChOvw3svoH1IOKVYtUaGKkCbYTKaoBBQ7jPuvVxgmDK2ieIT7T1uTsCmiG9XKeh7ITGn+rIoIf/lRIpB8IuSmf3jdKl738wKVIqs8ukZTul1OwQ5VxpRJUXapuHh5TnHY8/1zS3GKtbrDmcuWHipY5u2o1tf8DBeEWr4SjaGojTKOaxSqKy5WJxzvlpAxS3u3o86rKv7/b1ACGGZ3x9OgamgWSmFhDuxmksNh1CloMtd3fPa812fleMw8t2PnvHh82uWXcft/v8PPMLGSVLdrBfKqwpCmdTGkIupU93AYtmyWDq226GyVoAgjerqcsHUyw15PAyIWaBimoTW771ic+ZJYWLsDU/fWbPfFcYXikXXYJxjOAYOfQGb2Fw07G8jYZhoPaCgax2rzjGFiWGYUNYCVqZnk3iCHfYD2iCJhkqLYZ4ynK2WpCIpTje3O0mQKIr1ZkkKifX5EucamZ4XYURMIRNCIMYJhRiVpmrS3B/2rNcrbq5vWG2WdF3Hy5fPWa2XvP3uY169umG/77EJ2rarKX9iQnh+viRMO2IY2e72rLXBW0+xBavh5mZgvRbp5OwVZk31BImJbrGgaVu01UyjmD2/fPZSJElDICd5iPxK0S28FJXK4VvHy2e39PsDUGhaz8XFAutE1tofR5mwHsUQ/uLBknc/eEjbLOmPkY8/fMk4BpbLJU3T4JwwDi4uPN/99ivGY8Roz7Pnz6rU1rHsGkqB/TEwThJmcMqhnSPGKTx45Li+OhJCZKMdx8ORMEwsuo5u2aKNZThGSspsLtakKWKdJUyB5arh5asbLi7WlBJxXYvSqqaOSnJajlL8FxTWKPEKQxbqt56e1/QUaXrefmdT2VmaECaaRtF2hrZp2W17Xr24IUbD80+2hGg4HIJMmRWnZl0YAkk2cAUyMpPXhLpZZGlEJOXJEBI4JYuWpOvoyuTQPH1wxufeesD5Zslm0bDuWh5ulpwtG1pfp+gafCPJLO+8+x6XFw94/vy5sOCUwWtL1hHtFESL9o5mkHMeaoFS8NUTBjKOF7cTyno6P9D3E/PESAuF726SpqSQldhti5oCb6bo3D/UnHFcj1JZVjHHeo7k9Wfpyv1ebv4XhakgiGa1WaFtpp8CxgTaZcPIRE4tV7c9xiqalWE4RFKJKAPtwhPHWnCdPpdCaXAixqfx0oCP43QC5MapJswlcI2AMZuztjYmI+3CY5zh0fkZV6+OfPJqC6awWFjONi2+61BFY1QRWnsKjH0kTJkcMnrlWLPk+99/jtKJ9dmaH/mRr6KVpR9GbnY7rq5vePbiFdM4ctjv0Voz9BNd44hjRqNwTYOxFufFy8KYQtdYSShKkTRO2BhRXUtQhX4Y+dy7T+m6lpQyLhXee7rhc+88pB9F3qiVYRwTr653tI1jGiNnmxUPLi/5+re+ydrDWYg437G9HbnZHTlTBaUSOSeGPksKZhHzbGPvmsEcC2koZFvw3siELedaXL7eAJdSOB4nchYgyBfo+5G2MSw6uWbLxVKi0qdRit/O17ARhTED++0eFRULZ5jGieXCE1OiH0eefXKLNlrAaTRaaWLa0XrN2XKFUYohjpydOW62E9avUVguH1/wK1//iOXK00cjYTIlYas/jHg/ZYYx0C083mputlt8W5s1FUlFpuIPL5fc7m9RxUj6m29oGvEQsz4wjpr9PhJiT0qyP9hGCtY4ieTSmII2EEKQAA8nE+yUEt2ywTQCaA3HgeWqYxojxsBuL+Dh03fWXD7ecPWypz8G+kNkHOJJ5rxYeFxjsFYxTCN+0dI2iTBBLBPGFG72EhqgqxxxLuxyENaTKhpnHCoYWqdZLhq2VwemCmBZa+mWHVPMXF0fWSwN3cJBgZevjuRo0Ax0reXsQXcXfVa9ecq9XqkgRa9FgKz7QwtnLTFZYo7i9ZVnr7BMrpLGAhhlxBcH8YubAyyU0hyGCaqfn7OGpvqvzpnuMWVu9z3Pr/Yc+qka30va3KPLNbOPh1ITrWqxyp7Ml+f1yVorU+2anCbBMnX1rl4eKSVZf5WpcsZ7DCmE1SvruKy9yogtgan+KBIsZFDqdaaZDOdUlQ9KAa6NpvOSBJqyyGONgRgF6ZgZnlCBsJQqA0sCNFRlIszNS+Fe7sPp73HyoZz9KW21v9DWkN6Iky8z26MOL+qOIt+8sknmfecuPQzC1JPjgKIwDD05ZrQ1Vf1wZCyZaRqlwTSWmBRjTSTfj4XFcs00TXX/D5Q3vofRGl/lTKma9M/MUDQ0RpIwY/VDyjGh69heKUUYJ3b74U46WqjAckHpu+TY3TYwTonNpUOZzPc/+ZCPnn3E5fmGL37hC1y6C77w1rus/Q/y7Pk1Tx8+AZ0ZhpHtds/zV1co4OZ2y/7QS8DR7Z79sSeGxDAMp3O43fZszi/5Hf/I7+bLP/hlfvGv/SKf/9z7XF6c8/LFC9q24cPvfUgIgbOzM169es5+u7tbyxGZ/+3tLWGc2N7e8rd/6Zf4D//D/4A/9q/8K/zoj/0WLjYXUEQu1DiN1o4pOUoJss5Ze2LWlTISY5B7uRRSTSPUevY/A6MLWENjHd1ixXK9eu2+ON1HlWV7AoDfuKDzn7/JKAJZj0uR8BBVn+tP/9anj9m2YhbsndiKJdfhT30mkM+jT7WUksFPBXXmkJPyRkjD/Enuf+aTlPw+k/KzPtwb31PXAA81Kfph5Nvf/5hvfvc7jH0FDFQN2igzAFdtPhSsFuJR14+R7330AmWoyqMKeGrJuSs50rVe1jojbKpyD7w+XQvpLsi5MARJYs9llmPLN1JaUVSR9SkkcppOvlxvHmFIYrPjFN61dK2+q1PjvC5CmIT1ySyZVwqlxO/Jeyup0Wqu/SVQR3GPNYwkX/rGiYetaSrrcYDsWXQeo4Qd7K2T0BSjsYiP7tJICIrOEjQlCeOyFuPsCUTJZFT9HfUZ96JWswdVOUkWhbFc8Nah0MRwL0yBuQqfBw31z+o5aJqGcQw0TUPjHHq1IsVEUJpYGZKZgp0C5jgQFXDWvf6hlCahyWUixkQMdXCuQBmLKuEuOfjeFypALNV3uR6SGitsvhxFxVCU1Frzs69Pg56MNZms5LlA37MlAPLsU0bh7GzNo4cjYQocjkdRejlbDfmlrv7Gd7/HumtYaEhGYUvm/PIM13iKEjKSjoZ9TJxt1ndf/w2sStVz/to1mDe3+j+63PlrSsACFdwtHPZHjFKVIclnHjEltvsjHz+75pMXN1Cuq8Lu73/8hgbCjFY0jePsTJKjYtX6hpBxSOpEjIU4JZI1LBonaVIUUIUhJD765CXeiTl7yoHbmyN9H+g6T9c6lEqMATqv6FYd213k9vbIk0dLHj5esL2JdJ0jjhOvjgOffHzg9mai68SPaRwnioXlysEusD47J0V49erI2arh2bOR73znEzZnSx48XOO8YRpG+qMY7WqlmGIUn4JWfIusduxvR5q2ISbolo7b6yspctoGVKBX5Q6pVmLGOO33jGPibF344P13ZPrbuFrsK/a7I23X4pue6xc74lS4eLTAWbAmsmg6Wi8eUOvN+mT0G8fI4XBkeSbshzRPQlB1bi1GrSGMLFYtKXIqJobDwDhGvLVMRQxatVLEmLl8sMFazYvnL+kPAzFK/KrWmaa1LFdtXcw13hnGY6jGnoUUJ+g8RSVSiiwWLd16TbdoCGOPMxZnMk8erxmPmefPt1AEZCMXdvuRYcwVaEmnhlYopgXrHJrC7maiaTzicyKSqMvLMx48OqMozf44EEPEOinYtSk0xnEcD/jGiMl1TOiy4OblgdW6ZbFouDw/Y+gHjodAkxwhJoyx5FC4vR548eLI8092bM5blC6cnXm6dkkqiZubLdZqnNf0/SjJLiiurgb2uwmVHWEMNOYe4Yt56n2nLafMm0o8JZEpDCmJHnsMGWc1ndPSuOQR5w2ff/sB7z0+53zd8cW3H/ID7z6UxJMoTYG9J3O8vzWlXGjbBevVgqePLvno47VMCow0VSGL/n9Mnt3xBoDWO5R1HA4DoGujJIX4zfWe3luRsNZNWFZfU0HUBClRtOFss2C3O9J1jdDiFZSYTomS92yCUWqeVNQUqSIFEMyhELqaGHM3hryrH0A58ROrzYTXlvMH4heYwojSsuA/8Y4YxVMQDE3n6DrPeEzghaE4+/U0jannShIRf+Wb11gP5xcNpih22wG0pE9qI4xYY0Sy6huRe7WNh6wIQQo47x39NOCsofOaMPQ459HWsVh4jgdZp07nvcqirNGsFh3rxQpvGlmXU0KXwmqx4K2vPKRtW25vthyGPVEd2W63XD0/ULKh6zyr9Yrbm1tynGgsNE3Hk80Z1iiOh4FpCgx9z81xD7pw099IdPYAZ5eW83XHzW6PKokcFWMSH7tDP/DR8yvWi45xDLz73iP+ez/6VbaHG/pxYBiPLLsO/ficMA3EFIihr0MVj6qMt2Mvht+NU4QpU7yComh9h9Oe1rd4JxP5Oa1tlkM47zA4tLY0jaHfjbz97gVt67jZRj5+/hKKSOuttaxWHcuVFNSqBKbJgVIM+yPPnylS/h6Xl0vOzhzTmMVXQmXGsScly+ZsxaMHK9aLlnEMXN0KI+nhw4aYLSkpPveFJ/zS3+goxWC0wZmExuOdpP0qrXCNxneWrvM0jbAV26ZhPxwpJRHiROMadrsdMQQeXlxy2Pdi1hsT1IZhc+7Yb0dyFBPunBMpSKJt1xq2256zjWFzuWa3k+CQXGCaIsZoHj1e4xthg9/e9PjWsLvt2ZwviZP4Nu5vt4zBcXMtqWPdyoHV7K7HylrUNK349lhnuX51QOuCzoZmAX/nl19ysVlwdXPkeAjC0NEKW7QMcvrEcqlIIbPuFry8uaXvR2HFVgbDNCViHkQmrzNjSBTlMDWVtR+PeKsIu5HrpuGtiyWomvos49xTA3efOaGUBFvMfaLRcs1yKRgrpX2K8QR4zQwkaRqdyNWVwXuLs75OUo8UVSobTNgvzsr9G3JiConjGOjHQD9NGANNo0lkjiGwbFq+9up7/PCDxzRNcyrQZw8UVWV/3ntSjKQ4icTSKoZxqHLmLJ5hqq3r5p3s8n7zex/UmtltIQqbv0AdAvR47+88hdTsNTYDePN0fZYfZhlQKAX1s5wqceYiXmOM7FgjwoiUJD1OzDn9RpWe3whj0UZjnIT2GCUbg+AFdyy0OYDg5FtU0mlgleaEuJxOjJ6cAilOLNo11zcCylCga1rW6w3nlw95+ewjpmnAWY/3LeOU8TazbC2tMyycoQ8SHDFOMug6pY9VT7X7LOoZCPNGDPLbRQNFBqKKjCLjrWIYxD8sBwGuYyz1O8o9JoEHEe89OTswE91SGNHGUYcGhUXXctjvuL59RYg9XbukazvsSrFpLujajqZrWS3XTCGQMkzjxHEYOPYD19c3bLd7tFJ88uwFf/frf4+b263c/ymTY+Cf/Mf/cWEupsj7778NFL7yw1+uKIw+7fezD9Udsyrz8uUL/qv/+q/ysz/zMzx89JA/+r//33FxfkbKmanvubm5IsXINA0M/ZH9bstw3J8YSqfzmhI5RlSW50ZjKCqfOstSnwttHFQPwvsg0Ot+ejCzBe/XJJ8FgM0MsVSb4Nk3TKwZdIW3fu3jZFKvNKo26jI0FfZPvCMpyvfkDpwTEOyNFyxz/yKgM3o2Bs/3notS+71YmTBzeIecA4Uwvfp+qEnwTQV0PU3TYLQhZklmHMdEGAzTlOljpJIwMVrS2p2tRuSqoKymMZZxjNweBsYgSeGH/oizWnxES0YreHC+ZE5Ybb0TU/bKLpzJXJLGKGz5nAVczm+eEJVpvGMMoaLg/y0XIwsIpLOA8955SXkuMI6SVB76RLJCumiaeXAr4SWmMp+HYzgxv+aByJtvm6r8/mJ1RiiB/XGPweO9eGeu2oXIxc28DssXN8aBbdBG4VISH21V92NrmGa8BjDKQ5igZLHxqIAiUK1/tEjGUWDAY5lCwmpek/u/eb9SwCDDntnruWkamralaeFwOGJMZeqlzJSKKFSMEVsDbRjblhgi6eYopJymEVmMseimoxjLOI60jQyctW3QZcRoEHuNUgPC7vYZWWTmxqEOtGKsFgUabSylPqdayf6QU5bXnINyjCWnAUqm3KMna1VISQDPxju6rsE6Q6hJy2Tw2jGMEylk+mHka/2eaZp4vGz58HrL08cP+dzbT1g2SnqCrHjr4SXmc4rVeoX9DIN6pcQn83Tu7/35fNxfkoyW5vT2Zseq62isZdf3EuChFLvDwDgG2saxWnZ4Z4g51z+PdN5hjeV5f/trPyf3jt/QQNj5eccwRNqFwzrDs49uuX4pZpkPHm3wVhLzrNU0rSTgDEPgbLPh1ctrrClCA/UeY6VAGsZIfwyopcYX8Z5AQ0iQimZ/c8AvDGTLr35jYBgiIUic9mymKDf1SMkNzjbEIXN1FJADBdYXHjxYU4ZMnHrWS0FXJUmn0LaeGAd2+wPeO7qFp1GeptVsbwZub7YUCtv9kZgXjMMoKHHOtekUaq5rXG3AqoFdgcWiZX8YWK17Vmdr+nFiGnsohuNeifwkJTaXK7z1jMcJ30EIR4bJzcQalCq8enaLtw3Xzw40vmE6ZopPQkdP1U+qxrrGlBjHAeOULGxKM/WTFECpMBmDyWK8mEum7Txt58kp47zHukjbeZzJdAtHiIHDfqzFtSWlzFvvnrNYe9rGEEJke3skZ1NTKOumXgrL5RJjLPvbGz75eMvLl9sak17IvVDUrXFi6qhr8UmhZEtIEULBu8TmrOPpOyvRdyuAQrdqAcXV1QH0HQpeChyHyHg48uDBGmc1y3XLYT+Qc+Jme4P3YmiorWHKELIhZWE9GStpLUpDu9TYCZm4Gs14PHI0FdhwMoGJsRCDGEAPZFLUdcOFOMXXyaXlzh8rhkJJdUKr7qQgWhVKqtN8pUlZsfAepQyN01xeLHn6+IyLZcvbD1d86b3HPNmsaKyALdVLH1uZBErp1yiuJWdi36NS5OPvf5unjy54/PCS3aGnrRNRHWQKNh4P2Cx07AfnS5aLJR++3LE/TIQQqmY+M2SZ4AvzQKjdIUu08+xJh7WEmHn+6lYYfwUJVNCGpTZMMTL0A6E2B3MzqbUk64kXz/wtEgLLmkrzvje9FCIBoHAa8ZPQIitrvKVpGz75/ie4WkAYq7jd7kk5sVi2WGfIsdC1nvVC8/yjHSXeTQTHUXyjZkp/00RWm5b1WSMyKgvDcaxhHQPWtSLBdpa3P1gzHiEFMFmRVObqdi9MnZrW2HhP1znZTLMmTwWtDG3j+N73nvPo0QPOm47zxZrv84L9oUcbx3K5FNNlpVBF03kptodh4Nnzl9jGsThbsbv+hFlR5A14AiUHbvcHOm84X7dSCCmD86YCeJbdqy0xKnTquL2ZcEbTjyNFG5wVwG+cCtMo18JbJQ2+kr///NkL3n3/kmfPb0BH2qbF+wanC4es6HNguWhwdXIfYmK1aPj6tz4hRgkKaRvHOEY2F0v2+yNGaxZdg9KSvieSaDG3DSHinMbaTpoNZbl4vGbcD2itONt4rl7cCotRweKyJYXIYSvsuWmacF48PFCOaQLnLdc3R45HzSfPdqxXnrY1bDZLtLIYp8g6kLQhG1ljpzSxPntI32diUnz7G9/m4cMlORv6Y6IfMhRPP+9pBTGAr2DAOA04C3kU6WVMsGilgHp4tiSmid1uj9aGYjSpFFJI6KRwTlUDYiupovMipKSw3r46Qm7ZXCxpO0+fR/a7kabxrNeVMl8iwxBZLAw5G5z3HA9BvCcNPH36gBfXI+1iZBwSt7eDGNUjcojV0mGdIiXD2GfKNDEeR5brFq0d5xee737nhnHMUKSBLzkxFBmCNI1j7OF8I0a268WCa71F62oGDxz2BdckfEkobSToxIsnmXcG6zSkQpyysNudp8RMSInDMNAacwJW5LyL7AGUsHbnVafMA68aCoQ0NjpL855TJqdCUoViOb1GChmlNW21KRhHMYORda6aoytOLPpl27B4uxFT9JzEX6/xnK/O0Erx3sVllSjeySOqueGJCSaeZwmlZjZTROT1qb53ro19/RAnAKCcPluKGWXl/ClVTlYUM2wVYqLrOrquq99VGiZhuMm0eWa9qMpYonqUKC1mxrnWIlL+KTCaPJ/PGMhxRJGFpW10Pf3ShGgj1hU5lxMDcWaDiVpBgABlDCrLvT+fc9+IT5TSwkBPMQjjzEjKqsiRcvW5FIlsSgIkib9MOQFY0ti1tI3UnVprjG9ovUflidYbnI6UfMe4jUURiz4x4FKSGiDGRAiRGCR8StJdpYlLZWarKRojDZZRhZhdNaCeKCHjjwPjJCy5EDKQ0TrhnKmGzJ7WXdCsNUZpGucllToWpjRxvB14yRW3bgcFrLE8efiIzdONDLlyYbVa07R37IxZFgvw/Q8/5G/90i8xfm+PtRmtAx9+/F3+9M/9J7z37rv88Fd+iN/2W3+Ud999t96jM2BRgRXluRuJifcnKKzVvP32U/6JP/g/5B/7ff8oSlWpFZXZVBTH454YA7vbK4b+yPOPP+J73/57OGeq9y8n4KhEAT5nbz0ZRJjTPeScwxovPKITMPf6IQDb3X+Id1C158h3IN79480/k+dD7rtS5rH2r43AFEp9doVrwwy+F94AuuRJzVSbmnsg2xyGcUqQ04gvWAX1gLrG3j1XBRjGIMFc+nXgo+TM/nCQsAqlsW0rcn5liCRCTGx3R7bbnhxliH7/tKQsbPchBubAr+kq1XtcjO/HKXDoe653e5w1TCFgjaJrPKUYvNP0kxiKOyvegCEkxhBrKMh8ngrPr3Zslh0PNktyLnz5c0+EfTZMxCREjljXhM+6AsoWyBqFSNsb78ALUB9CwloZApHu5IWS/DgSYhF1xrKrWFtl5dTrn7LsTTNAWFQm5cgQFLt+j/cOhfiCrc8dq6bj0eaSdbtE3WO+zoAplWWntfitaq3wtdafqirD4inxnkqjUBUcghUJMeIO3NVKg4FG6ZPP42dJ6e7unYKp4QKu8adnsR8Gbm62bHeHSi4xdN6RAdc4sf6pPr3DMHF7u+NwOGJ9gzJyTjebc6wWc/9hmsglcnl5Ttc1J2sFVYPjUpR11tSBjS6ZXAdBJWdyilCcsPmMvWNPzvtkgZQ02WjMvLdoLXL0U5qvnHZdFKXI/uKsY7Ho0De3XO+2lFxYNUt8cYQcBegs8GCzISn4oS99gacPH2BciyOJaqxkbH0enJH6XTYN7pgOSldvT15jgt0996//9+yvuepaALyzuMlwszvw8fMbnr28Fc/gVVeT1oUVOqZM17a89e5bNA4+mJ7wn/7C//Mzr//94zc0EHZxecZ+P7C7HchJGjlf420pmuNRjLKnKRJiZrlqePVyy+3t93j89IwwBTGDrY3Fy2dbpiFgjCZMkaPKNK3h5jrwzgeXxJQw1tAqz9XLnl0o7HYDIRViyDStTLytUXjfiARSF7QRKYP3hikkhsPAcrXg+e3AsU8YlWjXjuE40DZLrNOszlpca0Qz7SU9I6XMdYzVo0EW5mmUhml9tsZoxX63J6XMar2i7Tpur27phyNDNTy0pqPtGrx3FDIpTqQ40p49wDjLYTdAhvVZRwqFwyGxXHc0zpCDpnVL0iSG3TkmLi9WfP/bL9FYzs+XXL/aireT0afNarlsKQoxDo5JPEQQ1FdrI81tUTjjmJIUdrvtnhwDpoI/m/MOZxXrhQWrOR4PAvipwnqzkiQOkqRfHCbGfqJbJZarJUYb+mPPcr1ke3XDO++/wziMbG/2vHxxIJaM1lW24IxMcXMh3wM5lCpYU2gah2+MeAKExCef3NAfJzFRbOzJAL0UCUnoFsJYHMcgTBwMV9dHHj5cMlRJVD+IHOTm5ojzcHV1gzVLNmdnKG0Z+gPaKNpFx9lG5KpTnwljkOmrhrYzlPodcknEpDgcEtvbyDQlStFcvTiIUTSOKYGtZtSn0RRzFHuu0ziZhGrt0Vr8U7QyGDQKi9WKr/7AU85XHe8/3fCVL7zNZtnhrcGqhCaTimKc2al1yidT4Alj3enc6pyIyvD8W9/kmAYWmzUPNmfcbLa8utnhrSROOZvZrBecLxe8vDmwPwzcPr+lHxIpJlIC60zV3ReOIVKmVBscaVROm3K582Po5+JTaUzMJ5+eVMSYWopQoe5KwSiIsLVOEtKqB1jOiaLvTDFF/iGhCrX0w+iCN5GsfVWdOsbtkbZtagNa2Pd7XKtxpTIpWpFEOWsYh8DFRcdxd+chlHNhdbagxEgKgTEXlMriX7VqWZ4tuH51IKUbKXC1BTI5B2JcVP8vKCNYbcEWzh90dXIk3jTOOMJYUCVCEBmsYWS9WrByLfvtkU2zFmP5pmG1XLJcrBj6keASyWe0Cpw/esjHn3zM7XbHb/ktP8zl0ws+/NXvsDhbQo60rWccxlNirdISXR9z4rgTI+XNZsVud4AMfR9RRaawThumIbHd33JxvmazWtP6grcj/RA4DtXTorGkPFFC4JNnz+twXcCuYToQx8yxF7ZQ0xicUXgtk+F+TIRJoeogRVlH2zasVh3b7ZEXz685v1gIg8oaSk2hahtHsgpnFP12wrSFRXdJYeKtty+YpsDHHx9w3hOnhDaaRdcBmRBG0IXF0hOmyDQmUtb0faA/RnKOUAzLpSdMiTBGzs7O8Y0DnUXKSUA7xWazZHvb8+GHV0Jtd46QMm1r2O0m2pViddayvY0cj2K6brSVe8AZQkzEKRCmxLYfOA4jbfWG2JwvKFmzXGxqAy/T5WmaCNOIc5YwSVCIADbVB6Ua1d6+PBCSxdnIcT/QdpbGGVmKVCJFMZl3VmSNOSZWZwturo/oaSIAfu0ZR/FDWS5aSu7Z7QKHY4CiWC4blFXsd4GzTSvfJUVMoxmmiWEcTg20sYZSNDHPz3yt8VLh+rqn5MKHJdAsoWk9i2Xh5nogRiMFehEEfDaZb1rHerOQ81Lj62MKjCGyO2xZ+Aat5oQnKErYBNaYmoKoSbMvSLnzkpEhRwXA6mfXShrI2fjZ1OGDrr8zhXxiWDROmJspBMmcqrIYAW4krXbR1MIcKDjQcn6skYHN2nY4a9BKM3uaKRQ5RfGlSdXA917jbo0lWzENziW/0bTUsBZqY1+3qpRBpYwxwkJRGlK4awybxrNcdyyWiztPEpRM34mkdBcvf18GP/vIlpROwJx838prV5pc0t0wsJrWv5ls6ZqWnCLjcXwNNhAgU1fAt8oKS/UrqoyaxovUOKdIirEG1qjTP7kUYson6YhRmmwtjXOy/0WRxyqVWS4XtE3L8bBnv7ut59ugagJmzHc+MvK/Rpjy1D0OD6XUIWaAmn7qfLkDLJXIhHJKKJNQqiFmRxJ4s7Knc/XkylijCVXyVZABnDaW5WKBtw4yrHyHsSKhGsOA02IHMhwHLJam8VhnWZx3LJeL07VzVuxQXjNj1orb2y1/+b/4K/zNr32TG/2U/OCnsJ9/n0ftZcXfE5/sv8/zb3+Tv/xX/12++vm3+P3/2O/hyZPHvHj+gssHj7HW37sO83Gf2SDXz9qWu7bqDlRZLJdQ4PLyIeM4EEPio+9/t94Ps3xR6s4UJmGxI2tIzqrWypK02vi2GlKbk4n8p475+59kUXJejDKkEKVOkcLmU+DpfTDsTsanq1H9XB9+GogR9lAg67vzlHkTBHvz3OXTMziDYLmCLVhDzAWmcGcvoF//XtRPdweyvH4+hI1lyCfgW9JbjRZFQN+PQgY4mWq//veNtYgkW5ijwxhQBPp+OJ2fmCLDOBFDZH8cRPHgLf0w8dF4QFGYYhRPKBTDOBJSOA1W58/dLSR5L6pMtoqzRcOvPn/FqvHkpOiHiWmc11HEV4zKIiQzMaGjovMeO7OOU2GhHG1jKWWSGq8a+qccT77FKYLSuZ5nSVq+vekZhknuFZVkza/nSBtbFSSBohXeWRZdh3PQ+pbHF+dsugVPzi/qfqZOpzYr8YtKGIwCUxTpdJ9W2aHWmKDJxLv7o4K41OHF7K+u7t3rpYBWFm1B2cw0/n2YjMjnMtUIPyWx8Tkee4Yp8P3nV2QMm+WC9aJliKMwwnPAWEPjG4hw2B642e+YkmJ3DGiVsOZDmso+/KhxrJZLHl5e8Jt/5Ac4O1tSoL5fJs0PiQZbkSJ16lcEDEsxYp0TsNcIyD73MAXk58pV1pzFGEfO02vPs+zpQFGEJAmiy+WC9WqFMYbj1LMvBy6WG55eXHIz9LzTPMVqzXEcOD9bs150eGtl5G88JUWmFBiGgc1m8RrLa94A51qgzus+tZK+dk3qGiQWELXHMc1Jtvniesc3v/eMKUYaZ1ksWtpFR9u2nJ9vePLeW2gjypRm+Wu9y+vHb2gg7PrVjpgk+nuzOcNai3MFay05C2XZOpEM+NbjGkF0NxcLjvsRZTJlGFEXS3xrWZ8L+jj2kbZztJ1MuK2tnh1Fpr1jn/n4w2uUEkNK34iZ+mIJSmX6YyAnjbWFaRwwRrNYOXl4DfhO0huM04QE1ElNKpkwRkKNlddaiWkuhVfXO6w2bLd70IrHTy9I1eR/c3ku7KssQMbUB7Zhh/USU5sRT4eu61hv1uxut/THyO7Qk/PIoydP6JZLXj27JoxCCx6PE03nOH+44DgMfPx8y2/78a/SmA0ffvySvg9sb48nVH8KEyp2ksDkHWEK9MeRlBMhhAoQamLMUCLeN6ScJJ3RZw708uCXmmgUArc3Q93AoVu0lK4j5szh+ki3cAzHiZAS2+0g1NUxoVRhuXC8/f4lzcIzHCO+sTSNIodI2zaMh5797sDVi6NMupct3mnahRiv77dClc7FMENEwn6RSW8ce5xtxBdAK5pOTPqHXWC59qQiU0DxZpF/zs4XGCvyoptXO/b7I69ebNmcL7l4sKBkOH9gxC/DiJeEaTR5FK+C/WHidp94+PCcq6sdem24vd6yPwwYK5MF31hKEQCyPwzcjhL1HKMiRkhJmABWi4ShZDHoVSCG0DnXtCuF1u6uidDiBaZrAmBrG37sy+/greEnf9sXWXYdzjlaLxMLECpxSKoWQaUu5KEW9rLApyp1pYi8xJbE1faGrDL7/oitUfbjcGSW2sSsmKaINpnH52uubw5sDwP7fpTUqlSYwuxYI5N3Zw1OW0KWZtSo141fpQatSSxRAMBcIkUZRBJBffbriJJEKSLNEq+4ai6TpWFMOdZvqE5pMII1KowVyVHTeoYQTml3tzuR9sQUcQ46B671aGPqhldwjaHowvZapHrWKlISs+9UFN3KEUKh1ZZWLXHekpGGS1dALiVAif+P945c1xBrHWfLSw5ph9KZh5cbrAGtM6gskq8YMeXOONpiePLgnKVteO/RY65vjkDht/7mH2boR87Pzgkh8ezFS549f87xeGTRLZgNP7u2Yb1csbveslk3NK3BuwX7Xc9h18sQwNkqMVSSHpkSHfJshSCNVUqFGCZiyLSXZzinabs1Z8uORbugLBRdK3HgUzhCzuz2R7zReK/Z2BVT3tMYw3G4Ba0Yp4TzBmvkWShKEQosfcPFpuPJg1d8fHWL9wnrFCFKMZxTPHmlpJQopnrreDFuvr1JHLYTqIzOluN+4DC8IAwbtFY8erJkPCa2t0ecErmK85rO171pDKfmpRRhHYaQKRkeP5FJ7s11T3+YuN1OLJawXBl843BeTO8XyxatFWnKXN/0vHh1yw995bIq0RLHfaJbS1hDykv224Fcqr9eEb/EXCmewxhYLTq8E3bk9rqnaz3Oy1DAWnm+pkmGUm3RxJHKMgrkHE+m2SkchblUi92hjzincN4yTbF6/TWsVy39cWIcIm1rOe73fOGLD9lf79neHNHAq+sjyira1tIfdZVSpNpwSlP04NGCaRQ/ldttj9biTVmUZhoj1hoWnaJ4kcFOgQqK10msSvRTT+MVOSmcdkxToukc6TihVakBCdS9jRODw1lTm4N0AgUO44jzFl+kLIsZrBJIaWZJoIWhNLOy7xtfxxhwVmoRjTQnSomPSzhJc+/kdfO6h6qg9qgpSpIpFQKs5ZPZ8/yeIkUx1tTaRNV7tKFrGhor/lfz+lpQtVav7CuhZqHKXRqmMRJSE6KwbGdgr9JQ6utU1nKVHFVly2n9vn+kGGjaBcbO3jcyTChK9qWc79KC5xdwVS6aQgWT7jX6Oefazdd3LHNYTMZa93pTXveyUkSC7rwM1igypDLWVlN+QwmVxa1m0FFJ4qbSHI4TKc0x8vqOUFzmay7vpY3BFE9MwuYQjy5h2mlj8E3DOPSEaSSGCUtBKYdWkqA+e2YqoYy9djLnc+S1xRoxlU4VPKFATJGYBSSwRhpQpZwMhebrVkSqPcXIOKV7n6+AyjjvKvO/MOaBlALnkycMCd9k4hTZ93u5Bgp2t+LRtT5fs96scdbfu8Yi8WnvdVrf+NY3+fk/9xf4vvo80+f+x7B4C+wCZf3Je6uUQmkuSZsvE9/5HfzNT/4q3/2//rv8D37P7+S3/tiPiYzrU63bzDy6b8xtkJbqjor15r3ZtpJcnnKhaEvMqno6waprUMZSKgiqjEUbg9a2slAburaj6xa0rdRGtjJL7h8C/L7+YJykl0VYPHEaau0g7MM32WAnAK2yJmUdE8A2lyRrd5Xm6lm2qJjdNE6vUco8gPy1Dqkvy73whVRKjUeVZ048kuQ1jJpT5+ovK3n/rl3Qev+pV/fOsexaxnFilkdPU2CaJm63e66ud9xcHxiH2Wv2jUMrKBpK/Xl97lIW8D5GYcbGKJ/RaE0IiZRKlWFGkZ2XwhimysbLJ/BTW2EUWmdoVx6rDY0zTClydUjogoT3xEIIhRjvhh/GFKzVGK+ISWGiJuXMmKKsS1hRKGgBzdqmoXEdfTNyvc0MU0SpmU0EBo3RjhQKwzhyux3YHybI0reIx5cwEmWQA7poUIUxjJjJsrAtl4sNVlsenm3wdT+YmZS6SstDsQQsKk0QCo21p3PvnOX84Zpv/epzYN6n5vtZFCuFDHWYxD2QTe5bkTNqparfd/qMC3v3+9aKdUpOkZQUYwgnVvaQEmMIHIaAu91itSaRCCVinDC1ScK63u+PTClTsmLVOhaXDdZCGA+EQRHNSDgcWHzY8KR/yKJp0DUdeh5clfkmVHCffSlS+Ch7mtboIun0rz1wCGAmDaEC7VBm3qte/87SyWga17BaLjhbLzk/W8taHSK745Hz8xVf+OApYRB7j9WyxRmxmHp4ec7Z2VIsGsKAIXO2bE+y/s8+2W8A2Kd66Nf4/fvrhgWvLK9ud2SSYCdTYjpGwhiJYySsRqZp4MnjR1ilpY4Mh1/789w7fkMDYbvtxGLVsVw5jLWkHGg6jzESy5op+Ea03IfDCEqa6N32KMlrKtF0mqZxYtpZi0tBxmsh4wzG6SovjBL3enOozaOhbVuG/sBqvaqxtZrFSkHWEpudMyEGlmeemAttawkGbq9G9ocAWTankhJFF3xjMFZMZg0gA0jFNEaOYWIMkc1Zi3EO3yq6taD/cQr4xrM+X+G8+KAYayoLqWEaA4fdgN1rMdnTkKaBR0+ecPHgAZ989IyUC03XykadEt63LFcNMYx0jUcrzdX1lt3uyKsXB7Y3R0k1c6LNPx4GUs5oLwVoSgLENN6Ss8TIe189UlJhtxOvmpnWPPSjmMImja4Mj1KESZXqpBbluLzYkEvh+mZfZRCGELIwz1LGKM32asAfU72e8Nb7GxrfoaLno+9/wsvnAiLFEOh8y/nlAl9Ns3IqpNgTSkEpgy4KiyysyopB/3AcoEC3buT75ILzdw3werVksWjROhNDYCTx4K0z2oVhd3Pg1dWOELOAFUXhvQBNkMgYSuY0fZYUqUio0c7LZVP9SURWZ52uvi+WaUpiDn2MxLqB5oSANRiMvptCaRcJA5ALWksMPKUICw9hfyklTaS1mgfna7743hMerRf8xA+/j7eai3VXvdOAEkQxAELtBeSEzg2Mqok/wjTQFGkQ500MMCqhG8eTp09IwItXV2K+qmRBPxxHrm96ud/GI03rmG53LDvHmERWME+8QNK6QlIoUyVxp+nnXWPz5gRjTvjCGClY88weqOvDaYqqIUfmVKB54iFvf0dblhShCiQgn2O+T8J0QFsHxeLbGTgrp+L0cDhWEFuA46lP9P3EYTuwXDT0aWLddahcSGpkTJl21daJPUwhM1wfCVNidzMyTZmmqaClUuQsUvAYR37lax/yxQ/eBx1oGjF4bWuIQarDJ+cCKUvT+HS1oTGevMhMKTFPwJ89e8HjRw85W6/ZHwa+9Z3v8uLlK7yzDMPIatVhjea9d9/i/GzD1775MZebFWMI6JJE3/9gzSYtCanUZ0CaAWsdykgqYp1Tn1KCtFZYZ7i8OKMA3sp1kULZEWLL7jCiiez2PaPWfP7th3z3ex/jbObs7YesLjYUJX5OORdJT6vBK05rtLKMY+bRZslHV1coJTKrpmvoD9JcOGew2ghwmsUk/ORJYVr2tzuKCmwaRw4Zb4W5cnm54m//7efkpGgbL0loWsIRmkbAy34YGYfAcT/J66bC9kZCFb71jRuGUZhaxhT6Q8B7kQ7GKLBwrGyq8/MNFstu/yGLhWMYIsrCYuXRNlLIFCUMnXbpxfeRXKUiNfVSCQtD5KeRy4sVx36sDOzExjuMaaDEysJrMNpyGEUGKso7SymBEDKNVTStJY9i6pqzpB/fn/jqakQ8TYlhkJ/JcCrQLjoB/HNGG0PjpUnslprLh62wv2KRqXoGbTUqJpSBxVJCWRSF4z5zPEpYyXLlsMpVSfHsaSYAxmq1IKaAMTJRjiHTdo7jMbBcyT7RVdsGaxzOSeNqtAT6DIe+Sh0E2ZnCxBQbnJeGWs++VlUCl0tGl7o2a1X3NgVR0pS6ep9l1Gm9kUJfAKhUTcXSif0xF6PC6LFanxKs5kEC9bm+WyulcXDWoIwhFodGGmVra2Li/DdOzbVCW4fCVxA3S5JiLdC1qqwNne8YLorTe86Lb0nCM9KzXKoCeZ+y01HQtS1t9SorqgJy939Ha2xNo5r9P08f/I3jlIhXK/dcJZ5aa9x9IOxeoT8DN3MNqZWhaR3WOUBqwxm8ubu/uecfJHK4MjMRgdlSYJaOzmy+XJtubY34qFpDxlVWfmacBmISCapRcybDGyI3beCen86bzBqRIM3edVTAQoCnewoq7sIN5O+nLKbLh34k1PVdgAQZUuUxEdMRrQqrpcG3inEYabuWoR/ETL5Qh1DCwI0x0k4tCoV3vjKFjEiA6mcruvCr3/4Of+bn/yIftz9BevibUMvHKONPn+2172pbsA00a9K7S164S37uL/6n2LbhN//IbzlJpl6/STTSQs1BOeZTr/3mMTe9CpEnTUlS7padk1qzegNpLZ5Xxjq0MVjnRLLv/B0rqv6fPUluhTVyeq/P+gClCEu1ZEoFMpUy8lwyA1/VgFvr03Nx2sOQZM6QMjFEYasiHl6pVNC+HhnFZyr4PuOcoMXXcAqBFIWpcg9PrOC1QiV1Sl+mAk+tb2ju+QHev0JKKbyXdUdrRYjCXNkfjjy/uuWTFzdcbY/0U6hJzbN0XI7VomFKMnSZJdgz8zKlKEzW6peXSjm9Rq4ywn6cpBeKrydFWqOxtT9D15GtBtMIM6kgr5WSsNAKAiim6rEntYkWC5fqoTav66mmUi6alt2UyVlXwobBOQHfpjSRiVU9knBKfIRvb0ZuigTMHPqeGDOta/HO4b3HOYezTvYibVk0LUaLHYezhocPH/HOo0ciM/Syl5hTsEjFFQuEImEzcxiDUua0IsUkSptZMiv3Y2UX5rt95W4wM3tgziCYvGYuIp23RtX659PHrATSle1YkiSV7g4D14eD3OdJwE41Ss2TSWSkblD1NbSGKad6DRSpGMZjpF21qK4QxkgiMgb47iffZbfb8uDsgsuLC5bL5afW23twEVD7jSShGsbUc4KqqfQVICyzVD1jlEEbiy6JFD/rIawDMOtYLVY8uIhc32y53R24vt6zTwOb8xXx48j5ei1eplPkarvnyYMzLi5XtE2LpqBbi0X8W389x6numD/Wr/HXTjEG1WpBG03XNTx8cMZxEsuSXEFIpap8OmcWDnIeWHctbtF99ou/cfyGBsKU0qQiMhzfNICqMcSJdtHQZM3Nq71ICafI7vZITplxKDht0E0hU2haQ9MaDrsjhUTKEW0amtZivaZbtSgkrWO/lRQ6Y+uCbBMuW6ZxlM1Yg3OaomXjblt3iskudUOfxsxuOxGmSNtqSswokmzqVlg6VJPZKSRSyOwPoyDzxlGKYn2xEm8vBSVGwjiiELNqt1lQkAe4lIx1jnbhKCURw4Qxju1Nz4O31sSQeP7sJcMo8oxV6+m8ADLGKkpOJ/PrOAmd+vb6wM2VTOm2tz1t46oRnqKUBEWi6qXxnRiHwHLlq9QwM429/DOMUsRZR8zUSTFIs5EpJVYARDOGQrsQUKhtWva9pFw0XguwUKQw9K1jdzvw4uVBfLVazWJleWDXoAy5lyYv5Mz+KKakbetOxbXVhq71TGOkDDW9Rct0PObCOEyUknFWihCKGOzv9YQysjlrbWi9Z9E5tA0IEwFQhWmaQAvQ0XbC1MjV4NAaRUbT3/YY4yQhQ1dWWVYsOo9WEkU7TOGULGOdFyPNPpAq8GWMFTPqUk3ulUxwjAyAkUIanFGSAFIK60UrSStGM0XxDkopEYsYNZ4tPJerln/wt36Jxyt7zxj43rT89GzKUE/MgtNpQmmqR4pWr9U5MnFuPE3bULSm9Y7lesUH77zFy+trXu134ktD5NmrHSjN9XbAOsPirGW1bCkZrl7tOOxHcrW30XU6WrJs+lJQvL7paE0Fp6i/A1pG3FBk29NaPB+MgeNhrP3hPCWuwJu6R/2dT0eRKU1BkZV4vIw6oMJESHtJPCvikeBaSbjRSqaKIUb6yhKxzqKsIQwj6IxtNEMKOK9QutB0lnFK6NZhqkY/JWGYHvYTx4Ok712cLfngnYfcbI9MJRCjJOptVmuWi4EpTnSdr+bbGmMVOU7ECGeLFQtvTv5Vj9YbSWAzmpvdnmkMaCtshLOzlaTkjj3H45Fj39P4NSlHdvsdy87jnfhnTOORhVas1guGMbFqPVe3N2hrMEkKvJnSr7UiTIExIgm8QNd4+jGQcuR8s8AYSymJVDJDP6C0eOV0nWNz1hFTpmsEvDdKs1l3GDRL1/HkrUuubl+S8p6kM0Z1WNVgjaKxmnXrMcrwrG14dL7iMB1PMiqtNcc+EKOwlLtOEuxyLsRUGIdCGjMUYWKUVBgPE2frljRpXh0Gdtuew+0IiAz71KRrxThFpjEzDJkY5XULme3tAGRikjUKYNFZjn2hW0rxHkKuYGYmOvE1whasN7gEw5hYemgWlmI0IWRy1FhvKUHVyfFddHUpEv7hnQCqTeMJSRh78RBAwXqjsUZAiLZrpPnLiqt0JExAkXAVY+Ra2a7hfNPQDtXvqaTKFEqAFEFd62lbx24rgJvW/gQ0dF2Hd55nn1yfnpmUAtZp1uuGUjR9nyl5hALH/Z3vi7GatvPEELl6uQVkLxJQUzMOEVXjyalTdl1BqnGMMNU4dMA6i9aWbAUwaxqHsxalxYR6HKdar8vwYQqAkjX3OE4oBc57kbjlfJoAS+06J0VJE+W0PJ9Ky94BVEP3uzXuzli+ToJrByHrriVFkenoNxhBr6/n1UDfGZyTKX9WXhp75ilzqZ5S5WTOPzOhlBhm1ibmLsErVpmiMebevT6/67yvKOYgFzG1rz8tkmY5M+rme9PoebhpJck0K4mbPzX78v/mtMfTW9XN6M0zcMdGu2OEoUQWj4aYBTTViPogx3haE2aZnrFawEBtKbP0RX3aXF9rLVJ7hMVhrYAJuZQTGF0qI3dOG8w5Y62Vc6HEjD8VS9s2sm9QKltZ6jLq95mvuTaKrC1y4j+9l795D6DAOIVThnIorzUyb7LjQoj0wxz4Mv9AmmitDSmLL+/V9ZEQPBebJXohjXvTtIQY6LpOILDKjJYhrZOwqJxpFktsu0A7BxUQ2t3u+IW/8Jf5qP0x8tPfjmovT1IykDpo2cCy0bzaZabM6Zqo7gH5rd/OdRn4i//FX+PBxQPee+99nLtjHGkiBhnGRCy/HhBsPqx1uMqez7nKno3FGAs5VdC4oCubxmhh4Xjv0Uafwgvm58V7L9LmMDLlLMnGn/G+4kEmq4Q15uQDV+r9rJRYOKDMif0zP5fqXq0nHnpzyqM61TulCFCpzWwTIeAQSEhN691rINN8v5xM76dwuk9k3ZNrcmJZ6nlNuTfMrQPDMQSoyXytb4j1cS2Ash6nNahMInGYBp69uuZ7H1/x4vbArh9P0jSt5VlVSlQ6jbcQI2ESMDyGRJgSKU7EJDXVbHWeisyBxcMv4owEajgjknanHbPCxVotg3cNIcp3Tkn+ntIab2prXo3rb3aDEAacGJPkXPCYKnMTUL5kCKMAesuuoFVm3SmcVXincVaBylgng/d0mwkhYbRjqAPkEOQzlCy+ZEppipPrM8tztdXCzEuKkg2UjDFwtlxycbbhfLORwBQKcTwyh69wqh0KOU7kHNC5psyWfPK9ymiGcGf7Md8nWmwAJYxGzyb5uvpeSVJ2Ob1HZc7VPudTzwJVQq1VtS2Qe1/STQu3+57tYWCcIjHJ2ptSISdhQiqdsV7X4Cl5xRPgpERMH8ZEbgvrxZpjHFn4huN05DZuGfqJ42EgJMVT27DqpAdTskG/9llzzqA1IQXSJNJ/q0ytC8rdnjZb2pzYdxqdDYnPTk6cAW9nnRBUjMY7wRcOh56r2x2xbTjuD2zWS5z3TP3A7e2Op28/ZAw9RhWWja0AodgW5CLr690Vl39T8+es/wjDuf5U322v9y6SgGB69pOD9arj7ScP8N4xjBGnxadtnAJGKRaLlsvNQlQJ1oif7K/j+A0NhFkndG1b9cqlTjZlUZbmcwafxjFwby0n58xq2dAsXEWWxVBfzEgkut1YKfoWy4aUEmMfGHphNjU1Nl5rjW8aSs6ESYrlpmnFi4FIKSJvlIsVGfrM0CeGIQKZrnN18YXlpsG34ikTpkQIdfLdB8KUUUVXphl1En5n9mq9UEtTjCJJcQaTYAyJaRxwzrFYtkxDYhwCxjVMY2Q3CIsLbWUxpTCOE00jdF20wjeOOCWuXt0wDhOH/UjTzowSWai1VqK1T0fW7QatrcgnlCRAgmK56uTv9zuU0gxDxASREU41NtpQcE5QfW1atEFMqQ0oZfDW0jnL7SGzWrQ0rUdpzTiOpJxpFy0vXxyJY0X3iyz8++1I1ypyKKScOPZzRLg+MdS0VrjGsly3siErhTGOEDN9L1rrUKfSXje1GTJMU2Sx9OQiQKQY14rsqlm46kUQ6Q/HamyscdbTtpamFb8CY2C5XlJK4bYmnZGhJNDaYJ2naxuRd8QoAJWoDOgWrm4O0uysVx2jDezSQJhyLbbVa+BTKYoSFWed48tf/Dy73YH3n1yKJCMGPnq15eYgiU1zIa2B958+5HKzRufh13wu98NQmXpLjPOkMkK+a2Co/iLOCVDgvMEbh3Meaw2hwNCPaK1YdZ63Hl0SiVwf98QyiY79kDn2ka6zPNxc0C4livnYjxx7YTSqIqkwIutLsvIqRca9VrLmXH04jNzzKQVS9dC482ORRs4YhdGQ0xzkPDtDVkNZNTes83Hv36r/QlYCpLbOUwpMQZIIQyx0jdCLUxTvjKZp8Z2nIM34NEXahaFtHfv9UJtmTdNZmdo6gybhXCPU4UFi4+Mkzdp60fBw3dH3A1Y3jEFX5mDm7GxFTCNKLcQcvs53jfG1CbasFytU6TFasQsDDxYrmdA3npITRmla5yUUIUVWneeDd56wWS3ouoacM+tVR9c2TNNYfdcC2sCDsxWpKHJxTDFwHCahg2tpgMIka4PRwtCdJgkA8U5CEKT+zmg1YY1iTBILXYCiRD7x+OEZ52crhn6q3kbwIEZiFFDB6YbWdBwYavEHXaNpvae1imUjxfyjizNe3NzUZEmhrY/DCGS8E+DIOYO2Umi1ytC0iqU2PFh1NI2jazz744hXlg8/2fHy+sh+21MyLFctxglzZL8dKBVEyRmOx7Em81rClCiqMPYBhKWPUrDsGhTSVIegsUFjETaiUuLXmMLIbtczjgljOxbI8EKYIZFDL6C+9yIDloJXM8XINAamKdM2WhrwIRCOUQYIudAuRaYRs7DamkaagZnh5b2kyJZSWUBil0TTeRYLxfEwkVJhmmSgk2OmaSzeOYYx1/VO1z1S0jVzyTRdQ9M4uXbKkEoUsE5rKIaSE7syMgyB42Hi4mJBQvZzVU3xx1EanqZxlY0iz3HJ4m/SNqbusYrjkDj24illTKprtYRIpOqJ5ayrTG8wtjbbdQ0OQUCMfoiMOhOSsABa0+K0P9XE0tTNUnNFUdKkaqD4hqgUcRpPTa0sODPTqHoQKQVKkqcykEMQcCkEtLXCvonxUxWp5MZRv4vF2YasLAqLLneeTKVEQoonhgQI2+vEBOaukZ0/15xUh7r7nPeb7vl/JSkxy9paAaRS7ti68/soJUCY0SI9LcwslXuvO3+/09IsjIL5O37KfLzcfW4B0+p+ah2mSnfmhj6lRD9FvL2Th+ZcQMuEHmUEEFav+7udfMzunbs57VgZ0KWIDCvEEyNl/v5zQzeNEyGGmh4qwImv8xxrNAqH1eJ3J4xOkUdGNEoZGRCdWHxze393mubBW6nenwJsz83f6+mFIA2lGIkPJ486qm2EnNZyOgf9MIl31VQIQ2SzmWhaGW5bZyrzTtgunW05v7wQe41SaLoFvm0FgDYigf3rf/1v8O3dOeVLP4HqLoX1VI/GwleeaH78PZF43R4Sf/bvBrb3ShrdrFDv/A6+9/WP+G/+9te5vHzI+fl96V1BU72saKjFBb+ew1qL9w3WSNJz40X+r5Wu9fYC6rqotcZYi7f+lLQ+n7uSi4BkVpo+lTUYhcoiL8x3jxozo7JUaaquoGiZZZH1Sotn0h0QNh/zdZrvcamFxAt17rNAhlUZSfeLMZ4GsfbeZ79/SI0VCNNUBwl3st/7QZVKKcwbjfL8zEkNFU5/1nhPyvcYj0oYuDIdzIxTkATcKXAYR/p7oUO6qLs1DejDnVF7ynPwjUgjcw2SuDvFhZIjSovFCrMXX4rYe/2V1CgCFigNWauTfY2kE0oSo6nrwsw6G0eRrVHkeXZOPK1STOQkgEAuBa2skCC0mPo7p9C6eh5rSa53TkCkFAspzMnAPZa2Kl9Ork4VqCrCitIKk4ww2lCkbIXI4SQxu2lEwmtnJqduTtvRLDdPuVCS1AmnAUPJ5CJ9uNGK1lqGGO/WQqVOIPA8ZLeztBt1N3gv5W5wcKIj1mE18jszcCRsMKnJbQXJk0wgMEqkdylLGEtKpQJiVNWL4AQW8ZUMY5xvteo3qySMp0QOfS8hSVYzjpPUazqy2/WEpIW9rM+EwVxqIaTunsuQs3QZWfYoZy25hlhRVGUGi2JKKchJ13RFqRGS1qdz/+bzg55fV56btm1wzhJj5OZ2J2mM257hOOC9I0yR/W5PjImmadFU0k6dodT2h/zmo14H2VQAUtc/1LMF5v05E1CUJuZJLGfuHd5ZHpyvWHaeGKUeVVQVgFI4Z3F1+KiBQ99/6nt/1vEbGgjT5k6agdbik9TKFH0apFhPGZpWvA2GY01FysLy2ZwvaJctx8NQEckMqojJcSPJUM6bk79EyhPH/UjJkjylkIZYJqKSUpFTlZN0QueTwh8o0B8mUiiEsZwofZtNi23EuNrVhiOmzNhHhiETJjHiV9WMW2thtBxuj6SScV5AqG7ZCWo9TShVaJxCNx6OmW0/oNCcnW04ml5o+QZePNuyWHi0taQYWZ6foSgMfU/TdCIVUdDognWZ26uDeKdUiYdCGBC6+hTkXCdL1cdEK5k+ay2+VTHKYjeOAnoN/QQqYLSlqMKD8414eJSE8R7fOFIKHA97mURbMWoONUrWaIW1qhZBjpwTuW6kOZc6olGoIubyukxSvCHpmr4x5KjEd0fD8qyFyv7xXpJBUJp0DKdi11kDKoNO0ohYSd9aLkWC612VSiiJAG8aw1ACOQdJXYoRpaSoaRcN3mm0FiBlTpg6O1tLnO3tUZL2uoZhyNzcBs424hlnvaHxhuwcKcH1lTzw1lg252t6b0QOXCdQ83FX8MwLkubR+RlfffuSJ+dLxilxszswjBP7fiIp6mS9cBwDswfYm+D9/XVv3w8chokn7eoUG0wJp4JfK5HLdq0lpcRq1eG0sAoLYs4bx4FjCrTW8vjBJS+2N+hRJtFNW7jdyfkfgyTw+JzROksSW2XRSSGYMbUIL1V2WFS5m8RX0ColWVTnSWPOiVzuTSNLJsSIKuKhk3UR+dYpUYoT63M+w2+eIK011gkz0zV1gdcZvyiUXSJMgdY1jMNIIeO9wzuPtY6YxC/FGk237BjHSIxCUXdeV38gh56LtphPpuoaSTHUSkAjZ+V9tRYW3uHYc7vdsVx5tIniU6fB1uLMGYu1mphFAuJ9i1aZmBNTigJyzq+tFbaRzcg5Tdc2fOnz79GPE1TGiCLz6tUrukVHCBM5BZxrWLQi/YjFoVRmvz+wPR4YJ2FhpiTDA9P4ui5XALkTtqTRUvA1VkCoEiRRdooCVOnZx2BtSFGGFTErDsfAEGC/O3LcH2lcw8OzDft+JKYJVSaclnQ9a6QAe//pQ77/0UfcoIh5bmITrTf1c4iPUus9y6ajMVbMXlOmq/LO89WK4xjZDQeOuytePTswTInVsvq/NBKucjyMpBJP95BS0HWekhWpsrBSDQ6Uok4mY9ZqQgiEoPHZoVJG13UpFwHYbm97cpYpY0oWpRXeW0KoUjSlabumAl8DSksBKM9HoR8zORZinCp1X9bfiwfiVzZMUw1aMKcmqqiM84ayixIqqGQPizFLCrQ3+EbkChqNM4pxCoxjRh0C6hjIqWCtw1ZJ4jQlptO0PhNKIoVG7v3FgmkSyU2YTWZBinqrxZfPW/r9IA0jwsS2zkixZaVptEY8R1erluVK2EBXNwdpkHLBaDBGBlvrs4ZhkKTMnMSs3ltP03qMUSL/sZacMsu1ZwqRPBaGMWKNoW9HOtPidPUcUuJFmMrccMs+Syk4X70ES6nsrjskXusqS5n9DgVxQuUMBEIYUSlhnKQVRjXJEEHdrfOyppXK/pICW2tHzgI6zVKtUlQNF6keNlqfEhUptWk84XT6jglSvbC881Vm/wYYVu4WV1U/h64LbqmL7zzVn/ciXYuuzwTXlPgSGWaJ2gw8CUvzzaZh/pzzQEma3GqgXwM0QNhtOUsq8X0or5Qie4+xohqooGpKmVQ7AW3moe3dwGgGL+e9SkAyaaxTlvM5T/WVUgxDzzAcKSXjncc7B0RSDPiTzxWElAlVTmKtrT4/+hRvn2YwM6UKjFDfv9RQg1kGf7fH6XqP3j9iTBz7UYaI9cIIo0PSYXOZn8UCOTKlwj5D3w/s9keWy5bHjx+J12zjKhvRsVqv6BYLkfVZCcax1Z5Da81ut+e/+Vu/Qnrnn0G1D7gv+QR471Lxo+9bzheaj24zX3piuRozv/C19NrvKX9Gefd38cu/+qf5TT98xXK1OtkalKIrA7PwmTFo/y2H0qbK/GWA7838nAh4Y52v4EupNadI0vS9pO0ZlDLGyHCjZDTC+lMqExLELPYU8z1ISsxRelrpmu5apcplllXdAb3zNbz7ea7gRZUimc/+zjM4m+MESjHFclcXn36pnNarGMbTunUHWdx9T+B0j88f7b4cWWtF66yETwA5RbyxFaiaK1U5E6l61qW6zqfZ80HNLLYsg48kg8PtbUSrQoiREEod1MkgQpC5O3bevZ6+1pK5sowSc6s922fo6lMr6ahOmHT1b8eYSb6yYwuIyY/0uxLMJOcuxkTOsu5PMYsSxGow5cSGEi20sFa9sSe81jlRvsQg4Ik1CpTFYiqLKtNU+4xSUh08TtLL1XvCW0e7avFaBvHjMbPsRIoWc5HgM+UYcsKrfBpcKj2vFVV2X8FYBViEmaW0AIEzEGasrfJFRaoyxrvEyHorKAFPZ2nq3QNX9zwlai2Q58xoLUxMLcBRQWT/ClkXvXWEKIy9JLNYeUZ13QWKgqxlz5gt7kp9D6VoWhmWxRxEFhlFcaSUfMZhGnh1+5Lnz1sWRtE+qN6ROVd10d2zIHOYAjkJi9PIfq5melWeQydUlU/KHqln2fQbe9prgHqRe6WpslfvJZzqcBg4rEYWKOIkeMoQA2MMDP3AYtmhbb1379Hu9GcsCwVRdpR8B4zrSkzgPmAPdb3+tb0Fmwp2zT9V3A3H5Nma/wzsr0+t+d8NCPvDf/gP89M//dOv/dmTJ0/45JNPADmpP/3TP82f+BN/guvra37iJ36CP/7H/zhf/epXT78/jiN/6A/9IX7mZ36Gvu/5vb/39/Kv/+v/eo0s/u94zEUXwg6zzmK9YRwnpn5k6EWmt1w1lKIwRtEfJuIgaPT5ZkmxhqE/yvS9+jxZ5/CNxFGL14v4mUxjYn874lsn8gOlRCdfmSRN0zIMAkgoLRB1yjLJ11qRYkHjSFm8xowSQKNdOHKO5JCZEgxDZOgjKQgCnat5sGz0Mvk+7HowiqbpcFYkLHEM1UwSocN6AQXHfhDPlMYxjRPWWbbbgeN+pOsEwU8xsugajse9AEGNq8Z3BbTFWigcAMPZekHOmWEIhBjwviWnjG8sXi+EgVMN7YzVlAQhCNPsFP2sNTENMsVvRKpzft4Rpkg/DFgvbKEYA6WIzt95y27fV48WRSYxDAlVaeXaaDF/V4rjMJJKYrFsWGUpPGXRl8mCcxrnFCXlythS9MeJYGQSoIzCGS1svDBKTLpVQuk3VKNKS7foWGowVmQL3lnCGFHMnjoKpYxI/iowmLJ48SyWHqUyu92REBTbm56287LAaEV/CLVZsxyPkeubQLfpwCka5+mGyBQ0N9c9wzBiNCwXDU/fvmSs0knqpPneI1MbG4XRlpAUKQV++J3H6Jwwq4ZVo/nkes+rbc8UM8ZYUs4c+omPnl/zW37oc5QiG33m04uIt46p+tIUqBR/+ZnWElPsnEaXQAwBjVCtQdh/xCifWIHvFjSN3F8GWCw9Dx+dgR7Z7Qqvbga2hwPKFdqF+GcorTFWiriUS22MOAFbmIIy4vsmNZA+FeUpR2F1WFMLQE5FIDWN0yiwtjYuVGZmlc+mdMdigNMeXPeqfDKYNVoxhIS1cLYRicd+1zONck4gUZZgrCRImdbROoMhY3RGJXBzeENKTGPEmQavNVOIjEMQ09ZYZG1spcCwzmCaO0nPXGgOw8Ri5U4pf0aBKqp63WSUMVAUYxCm7RgCj9cdfQwsjSMnmT6WAm3jWS5bGq/FI8muWIYqmUqZw/7Afrtjc37O4XAQAKF65WgNm9ZjdUfnwJjM9lCYYrrbzLOYMzfOUUqmaxra1lJKxhpTTWqtGLY7xxQiWik6q+iMovMa0wkDZgzSeDbKMY0D4zCwWDouNku61rIb5PW6tsFqueeN1jx5cMbbD8+57o+stCLkQNe5OomTqb+zls63bJYrGmOJ00QKgZn5sWg7zlaW/ELYS2EqkCwpZaYxsth0aJcY1SQhBSURQkRrS9tKOqRSmuNBAJ2iCs4aGqdYLoSxGkLPOBqathBDJJpS90PD4ThR6mBCpFyqPqPyzDhvSEn+W1soIVNUwXsxAY8pcXs7J1HlUzWjjTm9f04J5UxldYlkTCkE6DJCpTfGVCeAQj8EhmNgURO0VkuR6e7UxHGYOOwlKVcr8dNzbSHEzPX1DucsFDjsB4pSNG5ksXC0jRhqD1nMilUFHtpWBl0lRrSS0Im5YddWGoycMqbRqNahrQCr63XDZtOiNHz40Q3jEE9FuhSBGWsVi6VnOExM00QeZI9u0KQYCSGwuTyThsIbdtdHrBGz/RAih37gzC/JJyaBZs5UVPdYX4IpzZ50Uq3HEMAIYGWtrxI+sZFIdQovk2tLCJOIumZPICN77qkQrcyS2ZNEBl4JEBm+ch51ktQJKKazMJ6cFYbhbNJf7Y/qPpRPXjb3TbrNm8yRyqooWZgsJ2Cr1GZk9ktSp1Ny8mxR9Qfq/g9Pvzt31LLO6ZomNw3ja14+MDfHIk8xtRmXeyOSgFZ7CgVTJMxk0Yrkb25YS71G2riTgb/IG8sJdJxBLYmYr/L8+55HtdYVICwJS14pCUOqyZLT1DOOQmuy1tJ4BxTiNKGUKA1iziepDygwBp3nND59ei+RXEqqqyrSYMwG4bMR6H0gLKOrv9VcY2TGaeJ4HITFMp/HAqlWR/doRJzSzwrEUNhtxd7gx37sXWIMeO9Zny1Zr1csl0tJaF10PHn8iK6TRDGlxXfpV77+93gRVuSLL1V6xt2hFfzgY8PlUvGffW3i268y/8gPWn7vlx1/6VeEZX//UBdf4NX3z/nuR8958vghm7Mz+ZwoUpnToX/9IJjcw3cBEXEaKTXx974EURhs5aQG0NUA+94jVJPRZChNirJnWwMRUomoynLMKGGD3ZPr6hrKgFL1Wawporkydk73QD7JfPPMPPnUV7pj7ZzuhxlgKuKtfOcxdtd8pxhIQQJmZsD9xPKcGTGl3Eng3mCUzZxFraHznjHEE5jcukIq6bV0SwGMxNsrhMAwTcQU7wD1U+lWUDFSlGIMsnalLOElM1GtKIuyGohSGyLAepxhxArUz3vc3ZFQal7JZVjQzD7UJZNJaCvrWlJgSwQlw2FjtCgRquF+TOJJJetbJiOezFYVWiVsQ2VUfe4TbeMoaAoS8uS9pW2F4e6dJZfudI6cMbz1+IEM5PcHVsumrikNq0VH5z3rxYLz9RltI4Oc3W5g2S1IeQZi6zdOmkKunmdi1aO1xhRQ1CCTklE5o3OVmVY7DFtr89mvTrlZyi4euEa/zuDVavbSFKDqxArTurLIRIGjufPQpILzRd158y2aVryx3Ih3gdvdeCfDr/ev1uX+0jXflFivych96xqNSaBKroEsUh9OIWAUDP2eDz/5CK8062XHarkUhpeawVlR+chrzzLiO/P/gnx+6ppS6pfJOaOUyKyNuWP0v/7Mlnl1qJiBpWs8y8WC1XqQOmWKKNtWpqVhPEI/RW63e5pFw3K5RFth/yvuyHKfgrCUrAk5CDhucKDnMJt7v68Myrj67Fhy/Gxp45vsY6U4+V9+FhD39zv+OzPCvvrVr/ILv/ALp/++T5/9o3/0j/LH/tgf40/+yT/JD/7gD/JH/sgf4ad+6qf4+te/znq9BuBf/Bf/RX7u536On/3Zn+XBgwf8S//Sv8Qf+AN/gF/8xV/8lH7873eknAVc0Lom9cl/T1NgCmKybrSqyVOOx09X/Orfe86QMjFIYs1xCmhjOOx71mcLuNgw9mI0vt8NtJ1HO0OImbFPhFFuMLvy9L0YBBqjsdZXuYSku4WYmKYghUuMUmhZhTaFpjPs91J498dAuxCPK+sM3ntKmZiGTNYFi2LKsd6IgoqPYWIcJ9Hil4XQZC3kkCi1SZiLDO8tbddQsmK73VWGWSLGgnWWvg90K5kq5yg0W996fNMgJpags4BYMkEpLBcNxhmG4RrjRCYiJuJUCjJAxhqhnvZDJKWJprGkVJtE71FmB1HAD2sNRY9gRMpYyv+vvXcNti0r67t/Y4x5XZe9zq1Pnz5NN2l4WxrsRkmjjYjBUiRRIGWZSiqISFXyQRMxdIhRE1JlklLwUjGphETKxEpMiAVfMEVSFQo0pCMvIFRDR6QVUdq+nz59ztl7XedtXN4Pz1hr790XpbGl6bfHr2tVn7P2PHvNNeccc47xPP/n/3jaVspjqrqiHo8wxrBaDdRVIV1ZMsmoDF1LjyEvCqq6lHrlbY0Q0iVr63+yrRk2SokHj7MMvaK3cHCloyw0g7XkpQQUu146vFV1TlFkBLLokSJ+MXvTEyg9EJDAgxwD8W3q+kEW2krKbBWxi1nTMZ3tkSmJsl96dMNq1VBkGefOn4rm94Zz18xQGK5cbvBoqlpjg4+NHmAIns2mxfpAXsjisyoL8ky6WPa9XDfbTIbcjMKuC2SW5xgFkzqXkignx2taFZw/NeGBSwsWTc+2Y5YCCFIuFry0QYfH30ROTcdMxhKO985SZOKPYL2Xkp48J6BYLleUeVxsFiZmui3b+n079PTLBZumlQwCijIvueqq09STNZcuWoZYprWcr1FGJkdFETMKPsSuVluPFx8TijJBM0rjlQRVrT/Mxmcmj2b1VswgtQQupFlGAK3ItKixTAwsaiP3CO+HnYIi5nBQ0SPQO49TYnaJtrjgqLOcIpZ4b0wX5ec5w+BoNq2UXleFNKQoDaFraRopddbjwHre0G56COLx0feBxbwV9VguHnSZ0fJw9R5HoDcFHoXzcs3qLGbFovmnioEwg4oqhgxjCnKdHZbl+oFARaazXWa6qnK8V1RlTl3lKGUJQfyitJH9a4cBvGMynVLVNYv5PtNRTQgujh/N3kTOYdvq3SRNaXlaamTfvJOgcz8M6FjK0XU2LticBMOKjDLL8NZjopozz4x47RlDwOB8S5EFqjJnMzIslwNt56krKcs1RSbJBmPYbDYMXY9WA9me4drz59jvGlSmuHD5SiwhFGWvBOSyXdA50xk68zTOstz0jItSSiOblnFZoDzkpiQzA36Q54+O9ygTTf/brqdr1zjXk5ucotLkhZixo/p4LKR8V2kJera9ZGKbRoKeo1ouTVFUSdnjctmgtEywtC7obQ94qtrQbhxdt2FwfqcMyDLxLmpa6QRHLJ8uC7lnTsYFeSFKLo+Xcudobu99EPn6LGe51LiFi/UKMg6VUvSDI6xlUepOVNE4WToOd01PQK4lYxy99Tgn97qqksm6c5J06uuBIgdFTplrhi56T3qF9QFVyyPCDwFrWvZmNQ8/OMcHyHJ9qLbJNFmpyMnIjEIZ8VGs64LpKGez6rfpYryXhVXbDUymOZmpWa8Ug3M4C0Pnsf2A8wOE2K3RwNBb9k5M8KHF2oFN12F9h/UGE7LdAlGaGGyVBUc7xolCzuc2BtI1SmUoZXadppSXrLkLoh7Q2oCORuOxO66KJrvORR+gGC/Su1iSeAB6O2AtoLYJou05MTvfnG05lNFKFtdxkh7YKsHsLugk25ljyg8V1Sreiapuq5B5rK/WY9l6Gyk8W/XXNvC1SwrtFr9RYWZiqVgIu/jMY9kt+LfKjaEneIUvjywwONLt28viLyixWDDm0Fczhozi4heUP1SyW+cPj0Hcfhgs682GZtPSRW/Evb2JLD6sox86vLNY28djIA10gvPx3n+oYA5+a5SusT5nWy57NPixC+KFqJ9QsbO53ypotr4/xPMn38jGxKJ3PtoUxCoMJfMw77dNdI4d2N0fJaQgaG246aYXcf3111HXFadOndipmLa2Ckc93lRUdnzpD7+EO/syUIcquC2jAs5ONf0Af/CIo3fw+Ycsf+0bC2a14vLqsSff4E+/hHsv/CEvWa93gTCZRUhyCA4VRX8i22Ma5xl5ZvC5QQUXmz+onefV9jPyssIU4psaUFFJJOXWVVlJSSWyKPdab+u4CTEIFmB3/rdr3+3nZGbrixqDI2yzpNtA5/bcHja2OIwVhWP/3/rUHX1vtx8mO/Z38bazuGEQlXcMLtgYHJZA2LZEMpY/xbI3ca6RJku7cmslDUL0kaCnJD2jiCDOw6x1rNYtbdfRtA1t18VgXVTUHOm6obUEC0PcH7/7vjH5GSRIvB2jmckoTMFy3cdGfvGGGUK0bNj+7m3peAx0GvHPrOqMEHrsENiGmj0e71rpekiIc58gA0RLggoV8FqeScGJIXuu8nie2f1faUXvbFRucpgQig1v9iZjBisVH73rGdUlL7vxRVjvuTJfMNuboJVBK8RPtq4Y1zVlkccqJre7Z3jndnP97XNrEyszggK0wmQiXCEmmZVXcg7i3M7G50Jh9M6/Te7p8bA6JwlpfdiZne2ZVgNaBUIwcKRJgYrPOqNNVA3FwBKiUA1KupJORjLfc97TtD2LTcdgl2KXEwOt1tldYPkoJpMOm9Zb8Dloz9B1oAK50XT9wNDbXZdx5zzdxuJsoKpKrjt/DdPxWJqhZYdekjIOFQS3k9WGbcRn23QlJn9cTLaH7fjTMj/eepjtVGDxfKFkHjKZjDh9Yo9N19O07U5VuBosaMPVZ2bM6pJmkHL3vh+oaof3Ot5vDp9t/mjEfvvHcMTfUkzexPcPRZCLFEx+ZAxm+CfxNzvGTgkWvqIgGHwFgbAsyzh37tzj3g8h8K/+1b/iHe94B9/3fd8HwK/+6q9y9dVX82u/9mv80A/9EPP5nF/5lV/hv/yX/8JrXvMaAN773vdy3XXX8Ru/8Rv85b/8l5/SvgQ8znqyMmM0rlitNlhro8pIk2XyKKhGitNnJ2QY7osLhMH6aFbn5WBH36LJZEqw6+idIvLvrPDSlXKQ+t2hd5wcFzSbTqSq3tN3nslezuxkQZYr1suO1Vz8Y4oyk+5dzjPYlhOn9lguNMtFyyzfKowMZVWjlKboZSJkrWXbkU9rFeXT0oWQoDGFju1Ot8EXTVGJkkk6AErtsncwDBKYsy6QF7lMWvNcJj6xc1bbbaRcr8iiSSYQordZJwNYIXLDYB2jUcX+fEV+ckxR5NKdw0m0WswbbSz3k85BzmX40BG8ZzKRG5iPTQGUCrELmJaFkJKSI1Cc2BvF1t1uV34Jir5z7E0z8kyzWDWApx86urbFZJItDUDTdFRlRt86hmEgL/O4aNU4Z2hakU1nFgYG8eEZerreAorxuKTIJXCkjKaqAsuDnuksxxhP01iyItC1Hjs0FIUhKySYMT9YA5oTJ8dRfiwZkrLIWBwsY2fNkqB6dGyyYJ3FZBK8y41hPM44cdJgHdho3tg0lq71eKOZTQtGsVSqyDK6bqDr+ti1NE4W5aPxQZHnBZPJlLqq6Fdz9pfdrvOMd54ig9m4Ym9UUhhN652Y2RtNcB7bSwB4O6PVSsdOrVvZvWJS5mS5lOMRBgmIBIcNOvrQsPNusc7Jw8yDNtuFiAcsm/WGrvOMx1MuLudkWUldDwx+yemTe+iQc/nggGXTsj5oKCrpsDf0HVtjZblcAiGaihptCUFjnXRozXNNsE4yLl5Jnb6LvjQaykzUkZumZcBiTE6e13TthsFJ5tXEDN4uBh22RQnS2WUriVeIp1fvBnRsm610Tll7spUBb8izGu8DmQ4xiyTKUx8ChZEOdJkWlZftpUSta8XLYj7fsFy2lLnG5FJeVhYF+EDTNAzW0/ax65O10ijBBepxEe+pxAWbwYSYIctLyUq7gLcOTaDOC4zJ2MtLNs2Gosw4fXoWfUsyVHBcvniRrJB/W+RirL1YLFmvlgyuIy8zurZlXGZ4N8hkqoe2G9DI/W5UFjhvUT3kRjwCvfO03YAPsDcZgYrdo6pcPEe2wc84YVAxq5znGXkmCyjnvChkrEOqVC2jKmez7sSHx8nzwDvPZrOWyZlzFMbQdC2XDw4Yj2v2JhMureacu2bGfuyimxXSoa8fLGUmajqdiSfiqulp2oEylhOYTAJXZVFw+uQI53uatkOHwGbeUY2lrN+rw8y0956iVGSFIs8lyZGZnCtXFmQmoyoUBLtT0G3Ni0EWE5cvL3cB0G1Xu6GXbqSzMKIbpHRdZY48C7gebD/Qdp0sQPOMvBSz9izT2D7EzKx8Rj3KmIwqvJJSdO+k9XvTWoZBVNrKe4xR5Dn0DlQwUcHmYncr6QQ8X1iqCmwsP2g7H30ptwHvjE3fi4dK31HkjrrOUcEwqiuyLJAFhY9j0zkYBqQRjlF0bQ+DxleestK0nacsYgAsqNh5L8RSXykTaTtHP4jBbZEbyjyni9csQZJFznratmU8GTPRNU3rpByibfGDw2SSvTWZdERWGlorXnld35NpQ+86Cp1RZKWUJVmP49BuwETz7hCVOtlWGb1VuB5ZkMb1B16JVUCIIQelY8e4AMMgvpkmK/FBPDHdtvwpbPUXR17B0/ctEpgodsEm5+V6iHNslJJ7YPBH/KfCYQnl1kdtmwjddcVTsVTRxTI9dbgoeCzH3t96AsXJ/nYflNKiuAqPWazH4FWAGDRjt26VxIiJZYJyHLYvawe2Sh5jTLQAIAYOFRiDUnKf0Xi0Ot5IQD7P7IJzSimato9/jiU8cT+XiwWPPHKRK1cO0DrjmqvPUlc1dV2zWa/o9le7xgPAzqdns95g++Hw+0Yl2zB0NL2hC0YCCd7v/NqslSYq3rMzk7a2xw6Ovt82YBLV9U7lowLae0lCd/J5bTtIx7sQYmDVP/E5PHK8Qzx+IcBfeP55rj57iptvfhF1XYu9SdMSggTTD/+5YtthVaG4ePEi/to3sPV5Ajg5UkwrxTV7mjMjjfVw/oTcF0+NJRH6smszvnTZseoCF5dHgnN7L+Dihc/SNM1hdCh48Ha3B5j8Tw2GBbZlp6IgraqS3EhSVpvDIPB2bCilqesRJs92AeDMaDKtqeuK0WgkZUzBxrG9PYYhBoDi+fai6vRbFdKR4wUyDwsqELalakfYBuasD7syS3bBrMPgx3YMbD9/26EWYvn0ke8l15iLnluHiksfA8eHFwK7e4p3AaUkgemDx8dn6jbRu/Vi3i7FtyXa3TDIPdkH1k3Lxf0Fl/aXrGOAFnwMFh/6DaIgxN+NZhcQ2CZUJXiwDSbEMmHvCVoW4s4NbEvRd9FHZC2B2l4z8vuzPKMaFdSjjL4bMDEobVH0Q2C56aUJETpaMIRdgEHM9Z0olo1UPJkg11FRiILQeekIqaPyr3UuBoGOdt4U78dRVZAbQ2c7Ft2GIi954fPOHgZi4n9mV969vWfYXcmmifdKFxReHRGEeAlI1WWODYFKldIMLIDvWgnwGAUuxpYRoYso5nJCVCtrJYlQueAPS1+Pjh0JGPVy/8pzBifXfZ7He50KUd0s17QN0mBCedCZZ1yX5MYwGVWg4NED6R6pY8JOgj5hF9BXsaGBUpBXhtEkZ3+1IVroxTm/NBPaNC1t20vVRlybZ8YzDJfZNB1XFituvfnFaJOTqWyXnN7dQYKMBes8uQ7iIallXRZCiJdc7KS4VdrpKBbiaBAs2kMoYrI5Z1zXuBMzNt3A5csHdMNA23TMO2mmpfOMMtP4rmOxbjjV9kwmXhr/OEeI4aTHxMDkDCmPUgGTaYZ2wDqLdfLlpMxYPMWP3XtMtIXY3ZOO/vmQXbm4jMTHpD6+PJ5yIOyLX/wi58+fpyxLbrvtNt75znfyghe8gHvuuYcLFy7w2te+drdtWZa8+tWv5uMf/zg/9EM/xJ133skwDMe2OX/+PDfffDMf//jHnzQQ1nUdXdft/r5YLAB2nkpaKZpNy2qxkW5dlWFvrxKllZaJpsk8tnOcOFFzcHnNppVAQ7feoDRUVcHBpRWDlXIiZxV5plEYmrUYNjcbmSgGF3YXnYkX4amz9ZEJkWewAe8VhNg+Wytp0Z5LoCfPC7ztotoBINB1HXkunWHKMtstzNuh22Vd87Ik7/r4wAixIBqaTYdSUMcODn1v2ax7FouO9aaXQecd40lNVSuKTLyypienNO1AQFrOTyY1w2BZzJcxoJQxP1hxsL9GBcXJvTF9VF5oBWevOoFSgaLMKLOC5WrD0DnJgoR4sw2SMZHGLiLv77oVIciCIM8kkLJa9fS9LNS3k/OyNDArJXhnoYjGwuNJJfutDfuLNQHQXmrZnbNkRlHXOQHoW8eVSyuR0mYaU4hcu93IDVwHjcnBu4HxiRpjDPsHm2igL9nTYlQw2B6jQesStCyiV+sldtAS8c8VfeuYTCbsnRgz9B3rVYtzgeW8ZX9/TVUbtNFs1g3TvZLVQjK5fvCMT4/YrKVcbjzOQAUcEhQzWkf1l2O97mlbUUGcv/YsRWE4dXpMs+po1gOLxYa27QGN1vnuoWV9IM9znOvJsoy26fDA/qqnd1Bm0aDTwmxUctXeiIcuL+itSMzbtufi5TkPXrjC8689A0Cuc+pS2sJ3XbvzPsgyjVIxrxVERaRFg4MbAmHbzSPoGLyO8mdrCEb8kLxVjMuCITge6h197ykLWURnruDkpOTMbMTJ/ZLf+8MHcINl1VpGdUWZaQYtmbvMSBkoyqCURSsphVKZIc81VanIY7bJWwlaDU4Wl4Pz0vZd610welqXtIOL5VmyiOj7gRA9CyT+sM3HKsRUYOtVI3L5PC8pMvHb6wdpy3z11WfoO8vQBYZeQ4geLXHuU5RGDIWtBJZRmsEHdGbwvufK5WXMHirckQegMuLnkQ2Gvu350h/dg7WBfugYx4YgwYeoRrVkJmNajsmVoekt2mTUZckwDKy6DYUOLFZrZpMcXcpibPADeS5ZZq0yrjz6KH3XikpObtLi82Aymm7DaDSiWR2wWSywzKmKKnotWZqmoyjEw2Irf++KQYJZWRaVJCEqpRToQJVndFZM7a0VpUkWon9RLH3KjaEqC4zS9N5hvQSLlJaM1KjOqCtF0wfapqdZd+yvFjvvHwicmE6o8pK+n5PlOTdce471fS2XDg5o24HxpGQyKTBB7t+5Fh+8Pk4OnYsm+gYOlkvqusA6z94op8oMq7Zh2UojAB0Miyst3dDjkPL6QhWoAvGEqwqC8pR5QbVX8OgjV6hiNzIdJ+VlVaGViR5WmuAV62XL/sFafLkGRwjiveedp2+l4UGszGHoB4zK8TawWQ9UY0VuA1mRMZkYitywPBiY7hWsV72oK62n7RxFpSFkDL2iawO99MxAazFTVlpRTUrsfINH42MTGOnOJM/hi4+sRAEYZPInpUse4xQ4hS9FDdn1FoWW4JdRBO0ZjSuyzEeTXSmtM0bKda3r0TqjqDNC5dA+sJh3aK0p8xKCxmN3C3dFiGXNcn9YbVpGZc7eNKft4NErUtKonKKsMmwv3mLeSyfjvnesli1ZZhiPS7kPxCmct4GqqlivVuRZyeAsRW7p7EBtJPuM95Kw2paMmJwy7pt3jqHvySZTCfYYjRyocMS/61DhY52ni8bqzoHD70zfY+5LFlFHDDZ2pXleApESIIF+6CCEaKMgwZtV07A3HslCGR+THHIv3JbLS5QsBr7iwtzowy5PW3UJilh6dJxjQT51WCK4XQgZk8UMtAO2WeZt11P12F8mGXVix8/O7EpqTPRsMVoaLYQg6jRnrZSgIAbX5jEleIcLMlGbGK2iz5yOyZKwC2gG5LpUR4ITEGMtiLXGZtOwWKzouoHxKMc6x2bTMp1MyYuCENyuLBLEK7SqKvqmkwDnVrkTvRYH6+kGQ+d6fOxqvVU9rzcNznZoLZ5mRZZxef8BqWrQI7I8B+Xo7cB2YaJsJh6aSosHoR3Q2qKQcQuHvj1HKz/k+2bEDjSyXbySTp7c4+SJ2W77zMSgrffHgl/SKOGwrHO+XKL3znNUsvY9N+d8100ZZ8aH1/Rrbjq+/Ln9O0pCCPzWlxy/8OF2t+TSk7Os2uHQ/D3ESffhmQLXE7KSreLqidiWNXlrMVoxmUxQjKNfjtn9fOvRlhclVV3LWFCxmU8mPmlVUYiHb5BC08Pzu1XP6OjpFg592aSmDzSiDtVyjW49Drevo/u7/b8LAasAFCoErLV0XR9L3TVFUYoHcOzs6p0ni/vTDO3O78o5twsmbbtKSnBM1gXeH5Y/xyuErVJRrg1xzDKZpqAgz0T9JNdxVKXE8s2h72m6NialHI/uL3jgkSs8emXBuumiZ5H4NR8GYuXPdnCHXmc+GrDH4ymloy6q/2OJMxZrh6g+ChBsnP7FmyoedAdKvFnzIqcsDUURxQ19s/N/MrmmrnKsbXYG49Kt8Ig/JMRSZEdwcRwY0FFBtzXP2gY9rLXxSpVnt/h5egnoIZYgJuRM64LMgVOB82dP7y7v7b8NIUgTMhdLZkMstd8GCr2oRu0wMG8si+UK73o2bSe+aYjPYD2qOX3qJKcmY+rMxC6DSnpPRf/ETX+45s/J8IOVTuJxl7yS68nhyFUebYGir2iW0w9i25Ar6dhMPB2SGIxVHt6Lei2AFG0rgtRsUhfS6Gw6qpmvJVGLt7tGVkCsOtOY0qAz6K1lf2PxW6FqkAxcs+nYNJa2ddI87kgcPQRP23Vopfi9L/4he3sVL77x6w+fgbuTcPi8UTbDZLkoJFU04rGWEJ8jLprGqnjf0Lt7pz327JRjIgq9siqZGc2mGxiPRvj1ikEb2q5lXFtW64aqyLAhsGo65ss1k8mIKq8On3VPcP9TAF4UfMFobAhoJ/MlHzQYMMqjw+HzTwRi4v/o7SB+3NrI/XNX7hyTr/F7yrd6fDD/y+EpBcJuu+02/vN//s983dd9HY888gg//dM/zStf+Uo+//nP73zCrr766mP/5uqrr+bee+8F4MKFCxRFwcmTJx+3zfbfPxHvete7HudNBtA2lpNnMpplS1YZmlXPZtORm4rxpGDvRC1KpsGRZ5qDiyt0DqfPjNg/aLj7rgfJixyjAybvY8cJOZBSQibm+2KKKv5iATnZy/marhUvE60VXdtSlKICss6xWvY0G8t4Ij4k1SijHomc+cKDawhiqtd1UgpmB0+eZ0xGEzahZe7XUW0GwfXYTqFqqclt2k4CP9pgh4AeKfavrLF+YDyqMMqwnG/YrFoxadVSKmCto21azp8/jXOOLFfszSrUfstysaauRlIu6D3ksnjq1h3WObrOSTvWvODK5QNGo4o8N1x39iyrdUPT9PTK0XZWtlMGZ6VbnXMBa6UBhFKQK8irAtsHTp89KRLUdUuzcQSkXbiNC8+qyjB5TlUXDINi78SYzaqlbWRyt161FPUEk0k5UtuuRakQ939oJfK+HBz1RDpNZAcdRZHh/EDfd2g0kzKPJo6BapQz9SWjURbNE6GqC3Lnmc9bzp0r2Wzk85fLlqFXXLd3mlVoYnYZhrZnte7p2ui1ocXU/MojK7KypG97fG8Z1TmqNlhX8siFhrywGG3ItKeqFKNxRVFljCc568bQx46Is1nNpUdXaBUk6DuGthlQJmc93zBENRsoTC4BnPVaJlhFUdK0KzJTEHzGF+97mE/9/ojbXnQ9uZYMx6jMOHdyzEOXR9KlLig66/jS/Y/w8I3nueb0HnlRxrK0QNu3kpUDrHcx2+RkEUfsqIKS55wTxU6eifdY6ANN00mragzWe/KyQmmF7Vp63zAERds5Dlb70f8zw9kGb6FtG2bjnFE9ZbVs6QYIzlEYaUFeVxVVmdP1Ui7ddjCqKupKU5UV47rCxLKnTTdQGcOjV5YcrMUDQCZoYqKqjaYuFfP1kjwro5xX0fttO/MQ5z6PqWEHcqOoRxmjmabcywk+Z73s6ds1ZWWoxhknpmP2L62Z5WNs1+OsY71oMJuWfpMzmY1FnbZqWK1b6rri3vsepS6k9GY0HmFyjR1aukYertVI/PU2DSw2LSrkrFcb9mby/uzkTAKl/RptMoyTUi0fM7B4T9NucH4gLwLDsKEoPZOipOs7TGZoe/Gb6vsercTDRs5xPA4x650XOcEXhKFlefkC9UizWEsgcL1udqq5LJPOL3lmOLE3QSHZzbYfyIxmY1rKLKMsS8o8hxgQGI9GLFYr1k1DYQx1VaKVKCXrUhQ0xmhGVUnbD6iqjFMMhSZnXBc0XYezco1OxmOUBuukYcZ0PCJThuW8YbVuqGcVuTL01tMNjjOjjDLPJQjvAwxKOgyT4QJM6goNdLZj3W5ESp+JgiqUHfV4RNXk0qHYShm0DprOtgQVKEfSyMUO0mVtbzqBPpBXolrMtCQA8lwTlKNre4pqxGRaS0Bx02N7T1UVeOeZTEpG45LxVErvA55Ci5+VsprZ+T1Wy4H9yxvJXmYG50TBW49yxiPDbFLRtT2jq0TSX49ymlb89JwVj7m26+g78Z7K9LbDn+KqcydY7C9kceMrQmcIWYbOFAYJZAzeYUMQZaUSU2icQiMJphCiWkJnZFoz2IG6yqKXZB6DawOZUZw+OSI3BfPFEh8Um42Vsq1+oN10rOcDfeep65J6UpJlBm8d7SAZzbKU4Pm66bmkVjgHQSuKQrNp43UfCqwNnCxGkgDqeuraMB5P2fpo2V4WUOvNCuWly9doVEpgyor+oO0snR6wVvZVBU2mFKWRaLtqY2ApKqucHVC7hVdg60msosQpeFm8XlmsmK/WUg7vxci6GyyToqB3cWGgw87XceextVsUSuBHgszSKGFoGwlU4KiLLC6MRB3ngSwrMUY8BEVJchjAeGyga9dUJe7AYxuPHC3HkvEcF0BGRz/WGFTi+KJ6mzF+LOqo30g43N4gKmVnPXaQ0kyNg+BiEFP8evq+jwqvQ3XMoQJGlGRS2CYBBLaeaSqTuZZWEE2qt0G6XdDSygI736mCJLm4mC+4dPEyzWbD6dN7oqg90jnPGEPXij/dVol3aDBu8LogaIMOEuCV8xLYny/Z3z8gzzKqMsP5QFUWjKoJfbsGt2I8O8V4PKJZr6XjXxhwtPG6hTyrOTmtaLvAZJKzXPVYC3kmycRhsDFwevScm6igi0cggB089Wi0UxSBdMsLcaw/Nvj4J3GygtIQO+vJZ5gjQWLnOUzujv+EX6QNu07RIbArrcODDpKEpeD4Yiwqr6IlhWcgywx7s1k0wBd88LjoYSXJ8FIaQWXif6u13vllScdHUbMoBVlMyul4/jOjsUgJtDuirvJB1OByHOR3+Rh48DvFJrvjglI4oner2aoHXfRU0oeeQMNA0zUSIPBBvMtyxaVmg4vWMOao+lFLN0yZV0nzB2stKLUrUT4WFA4Bh8cGK+bc1uDYGsZL19Eh+uaJgtHtFI7eB4bB8uAj+zz4yBXafmtfwfHvuj0PXhSoTm2rSlTsHgjDtuzPNigGtM6koYkq6F0vykA3sPVjEo+27S82sug3Snw2cwWInYasxA8Vs0op6rrEzUa03YC9tIy/aauikTVS6CzKSrI3MwGtRfwR4jGWagKHxVEUcrw3m55cy3pJxyTPYIdo8m4ZVzm6YBe83K55RRIYDsujt0Mi3pdUDFh3IVCUJf2i4Uv3P0DwjuV6I99LS+CnqgvmmyXD1We5em/GOM7N5LspnJIkovfbJJg8W40ud2b6eGJ34OPX7XEkgbgNim/nHYFA7734xFmLQrruohV1PUIrqRrKOi2eiiEwrXP6DoahByTpnRtPnntQGU4FQu5i505FVY5ZrxzNOtC2gU38XRqpjjFGU5fS5Xpbbq904NErlzm/3OeqU9tYyjbQ6Hc6NOcHnMvZNk/aKSet39kTeefxOvpix7JW9yTHyRhDPaopXMGJbuD0qRlt1zOeaEadY922zIaR+Kw3He1ohFeaddOgfC/zWhWkaYfKJBj7BCgtjQblehGfMILsa/DhWF8TpWRu4uP9f/fSh4H/baWNXDjb5+efcyDsu7/7u3d/vuWWW/iWb/kWXvjCF/Krv/qrvOIVr4g7//hJy5NlSL7cbf7RP/pHvP3tb9/9fbFYcN1113HqzBSTadSoYDVf03cDeaEpSkNWGPJSJhdFYcB7nv+8E5zYG/HJj38JgKZradqOoshRDExnI/JKuv+RBTyO1cYyqir6PrZsNzHJN1j29gpMljGd5bEbhWG57CQYNkjpR1kXjKc1SotSo+8HRlONdxVlrdksB5wFZWRCuFgvZZKvFd5ZFIa9EzOme2OMyWRig0zwvQ80fc/mQos24sVS5CVlkTN0lqH3KC2dx9quRynF3mzM7NQJ2nbBar0ihAlFkTOeVqw2S7J98csY+kGaBeQGtwpMxyOC9qzXHZPZVKLPSEZhtWk5uCxmxVmRS4cwtqaHgX6QbmVivCw+Duv1ijIXOeTQWmlfr2RyWTnp2BVCoKxyppMS7x1FmVONcpbzDQ//8UNcf8O1EMR8EaCqSvHQsYH1YhMj4Apr5UbaXZIbnjGGorSQQ15kBAa63jHKSk6emko2wGcMvccNDufh4KCRh3SuuPvui5hMOq0srog6LtOG5aKLii/xZhrjcYN0iCzLkvWqZ1TUoHPuf+AR5gcDSktAdDIpmU5KjBFPIx8XDOv1mjwvKAqN0TnWdxRFTd9KGYbJFNOTJSdOTlgtWtxizXSasVwYmsailEyGeud3CwbnHCdOzmjaFtBM6jGDh4sHS85MpK13XeScnNScGtdcLlcsm57xuOLWFz2PLFeUZVy8lTlXn9zj4Ssr/sP7P8hfe923c9XJ6S7rHYL4wqE8hCwGhAJ9zCoODmwAk3dkuaYPij6U9K1DBY+1Adc79DCQa0MX1O5hACKfHtU5fVegTWA0LRmpjOmJWszBrUNrw6gqKQqZVO9NaqajEh8kEz6bzKiKGX3fcGpWg7c8ur/i0sGKK/MN+4sNi9WGpulQSvPoYoPJA7O9CVVhaNqOC5cO5IG0uxkLRb4ttQlM6oy9acX+ak45K6hHNYv9Fu8ceV7Td5aqrshyxXLeUJhcOvdopEsl4vm3d/ZEnDQG+s6iyek7F7s+Zpw+s8fFC4/Qtx3aKA7mMqEzWlHulfTNwOyqim4zSJOF5ZrJeMJkfEYWab5m3Vlcv6TrOza9KLCyTFQyo0qzaRQvPNFRFiWbrmHTtDgbM7suqgLFTE4WHEFj+4HSyYTLqEKCYzowq6cx+C0P7WEYGKwETNWo4uRsRFUWdH1H2Wc4D0VeANI0Issy+q6LHbQ0XWMgL8i1Id+agGsJQBht6Ae7M2NVwYJ34qejFXVZUBhN0/bMryyoZzUnrzrJJB8TnEy0nfOMJxWh2dD2HdO9mtEyBx12i7ahl4yybS1Gt8zGU87s7YGH5XrJqlmzXG7QOse2HXvjnK4LGOfJtKHNC3RmUDpj3WzohgEXfJywGroiZzyqGSuDxTEpCs5Op5w4NcIqR7PppcRUK1wPi8sNQy8T9PPnT/L/vOhq7rnnMo9eWothrpYJ42Ra0Kw2GB3YO1PQLsDicCGw7VrWdwNZVjLdG2F7hykLyjpnebDBaGkC4wZJVoyntZQAlQWD3XDl0pLCwHRaU48M+xcfFWPYAHWR0VtwrkdpOb8EMUYvMo3ODKM6ZzopYikGrFcdZZZLgqPIaJueagLTyYi26ahKxZX9hrbrqepcEj84/vALF3jeDTOKOueh++dyrz0YCD6qWWNnR4IETjdrKRcbT3JGoxKlFE1nKXLN2XNTDvZXEDPR3ksjFWM07cZSloWoLrdlCV4CJH0jasu9aYmOavKm2eCVtLPvBktrevl+TmGdItcKXeQYpbDDQFYUh/dCa6UrbVyku6hccV4836y3NN2GRy5f4sIj+0xGNcv1BqUM9Ui8NQOe8WhMUWtOTMbSaQxJABS5oci2HZ1AoSlNLlNP2+O8YlxXFFVNZ1t8tPd/bDlc2KoIlBiGD3bYBaiUUuR5zuzEjGEY6PueoR9igPExi9UYCMtikEih8EqCdCZm07U+VMWxPf6Pcanajune9vFzthPsWArjPSh2hvKieLFoY3DW0m9Nt4Hgw65j+FbJksfOv6JSC2JsbqTcZ6fYO+LtdPTfDjHIpoLizOnTtKMuBt48e7MxActmPccOw2GjJqUY1TVFPWW4dJmubSD6tymtUXmBySGPXmS5CfRWggnz+Yqm7dnvloRo8FxVGXUlSsa+bcjLjBtffCND3/PQQ/dzcGWfU1edY71eMvTSqGWxXHN6MqVUGVeKhuW6p+vFv9HaThSvuwYNeqck2AVfgavPnaGsqmOBSmMMT+Ay9gTExXs89XUharyHF477DzwnKs2Lzsqqqxngt++1XDVVfP3VGZMqe9yvevzyZBscPtw3pSHTRTzHuyuaYxb3atuxTubq24BpCNIZXnwlHVVdUtYVJjOHgd4jAUEF+ODog3QyzOMnScMAcE6Jf6KXst+jjRAk8Cf+qahtN9fDYKmooET1onVGDqybjfhPZpl4zT1GPWadeP5lmcYoTTf01HnF3miCHaLK+Mi86HBRKwpR56JtSVEcu1ds/aOc8ljsTvE29B3z5ZKuG+gHy3y5lnPZ9hR5zqgqZZ2x6Tl35iSX52suXVnQD/bIGOPYmtlvuz8eGYt918cwhD6e3FTE0sBenlfKRMVkQR8OlUz+2IeoKKqQ6z7PNWWucEPPZggUefTPDbHhiVIoI8HPvCoZvCccsaXyAZm7KAcmIwS5L5dZTlCicnceaVwW111GS/Ih1xlDN4giTMmzwTpN0ykqXXByr2Z/foVTs9Pi6zQMRxqTPPEafxuMyfNCFN4hMJ1M+L0/+qNj9+5xlWPdQD+0ot63nk7JtSOdh2WMaGNick86nNalJLWCc4R47zLaHDY3OTLMXLTHQGW7oRrCtpHKYdl+ZjSZKdHaUNWj+GySREpZVZxSsGoGRqUk7YfBMW1Kmq6ndyJKCDqQF4pCSZAIrclyxVUnr2ex/8es5ltlb0CFQRSBeYHSHpUrslEmlWHByTVgpNnT9piZqNgNSJDQh4BzA9b10Q8z211bR9VRMq5iR/csJ8vKndr0ydBaM52MGNUTgr9E0ziuOjHloUv7XLoyRyMe4Zcvz+k2LUWmKTPN3rimripMbpiNx3zdDeeP/2LFLlY1qmcxUbW7ggBR+mK0JI2Ul7WUARv0sf0L7kniRSoq8A4vgy+bp1waeZTxeMwtt9zCF7/4Rb73e78XENXXNddcs9vm4sWLO5XYuXPn6Pue/f39Y6qwixcv8spXvvJJP6csS8qy3P19e4FYN9BtNF3XMZ+vGY8yJtOSemLIjafKPXtVYDQW6aUdNPODFWWVYYyid5K9aDtDUWzLmhznrp1Q1jnzgxY3ECV5gaG35L0hMzCaGK6+9gR5VDl5D8tlR/ADQzQ3NJnGDgPNSjMa56zbFtcHiqqAoAjOYLRls+wpxxlBBRR9NHqXzNXQddRlgQpgB1EwDcPAfH+Nc56yyvBOMkG+VISRmOEToChzjCkwxqK0ZrPZsNk0rFdLUNBvAl09MBpVosAoDF3bEoKc20xnzOdLVosNSilOnJiIp5D14huV5zx6+WCn9DrYXzIaV4ynNZmW+moxJ5YabJG0e2wQkWfb9Vy8cInJtKYsC8oyx7sOrTJ0Zmg2HV3TcrC/pKo0RSkZ1KIQo+IHH7hIVRd83ckZ8+UaDSznHUM/MPQSAPIhSKQedop2ZZ10cfSQ5Tmb9ZJgDGU5ZrNZY3KDjx47zkuJTtcGlstOSu0KxXIh5XuZEhP3+XKB1lk0VAw88vAlNs2a0ahgXO/hbGC1bNA6o8qgyjX94AleQ5bRtQNXn5vG61oy93kmHYH8rqW75fRsQtu1ND5w4tRUHtato1mJIvH0mTGFMqyWnSze3EBA77qyhSCS2cViju8DZV6yXlsuHrScnjZMS02wPQNwdjbithc/jxOTks/f+wh/fPGAj33mC3xTfx2nRjUvedG1XHp0Ttu2hOBZLDf85v/7Gb7tm1/Kyb1RzMj5IxMOuxu/PsC6s7spbdd1XD5YoLKc9TBw74WLXFku6QbLQ5f3eeDRi4zKSkrvtKbKt6oDxGPMyER/ZJTIp7fZMOcZnJMJFVI+dTA/oMj2KIvAYKHrDujbOUYp9g9yjM7IDZw/VXHuREHbTXjokQW//6WHmK8WjEc5GE3XHVDnU05OatYbWYSslktKE/Bk5EVFbkQNYJ1nud6w7jesbcuiaUW9U4n8+uIDF1CFlFaMJhWut7jBi4psXOJzsEFMiBcHC5TynDt/kkuPLGRMDZa2aSnznP0rl0X1NK6oqoJRbMaxXLY01nLmzAkMiqVZ0TU9fTOwf3FJ14r5c1EUW10Ce9ManUm3wBPFiCrLwRqMt6w2G9ZRnbpeb8R3I0RD+1jGmGVGxkgswwgKciOLdzd4GtuRh61iTtMNltWmRakQjYQlYNXEBX6RF2SZom272F1RFA9iEi/lq6IE0VKWuel2xsrOewkiRf+4sqhwOExuUEazWjbY2M1XZwavYNM2VG2NKcaEENhsWpxzjIqSyXjMfL2mMjm1yQGP7XvajWI6q1gctBiVyUR306CKklFZU+RSRhK6gSXrqPjIuXxlIdfwqGZ2ckLTtXT9wKzM8VWBDZ7OWQbvOFVPODEqqPOCOs+wfWBx0OAINJuBtpXgvguw2iwxmZZy8UKzv7/mS/c8xHQ8xruKQfU8fF/PdTfkuMGj84yhH9hcqcSUPwYYJaArQfC26Vmv2iiEkHNgjGa+WFPUGd3G0vfSYbkocrpNx9C0KAXz9cDgPONxzrXXneT5N5zld3/nPpabeezLoaCTJIbWUq5tnKYIgcEoFktHZgJukERP13YolYkaQxU4OzAaGU7s1cymU5yVBE67GTCqQaG5/vqZNItZ9zjn2L+8Ek2gyclzA8HRNVYymIWUsmax+YGzUtLvvafrJFg2Gmesl11UAIgSoW17JuOK+WJNcIGyzAgEhi52Azaa9WbDlctw6tQenkDfdShVs1xt8L3FTiyTuqbKS0LQNB0o7yDPUWqgiob5zlqMc+Q+0A2Wpu+g7wnKS0AaGLzDe8W4mkJY84UvXIidrXLm986joglGI8WZ05oXXn89k/GIMi8IKqO1PnaNjZl12JXJwHax4RkVgWGrAt5OWG1HUDb6xQ1SFuG35eW5JKycJwTLUDqWq9WufMpGrx93pKXf0UAY0UgcRFlvCifqQ9WgLBgnfiMhlv4NQ3/cGNsYTJbLs6Lvdqochdhv9H0nqoFoUG27gd46rJdys2612QV0RD23TThZycqH2Mm36w87JhqHyTx5DDRaZXf+tiABNbtTtLhY3uhROhCwsROfYhg6rNEsFitW6w0+eIosxwdD11lWqw378ysUxYiikDLsdhgY/CClxjaWqdnA5SsHrNbrWOokpXVt2zEMPW0Lm81KFtNZxbXPu44b/sL12K7j8sVHuOrsWRaLJYuDfTabDQdXDnjk8pyD/QNQB1R5y3y1lmCrl+PhnJdyPScL0iLLd0qdrXLQ2YHVarVTB9rYrCXT2a7T9FECgbNnr+Ly5T9iGJ3fBaqMG2jXhvsuOD76RcepseJMkZNpePDA8/6P97zmpozr6ozCw9CsduGLrHmISSHNEZbL5eM+Uy50RCh2BO+cdNzcrgIR246h27Bardg0zfE9j6VFRSHNeqx3co+z9vjCLxxRo3F4wEwI6CAJxGFwrDYNrfUUpShHJLBqcTEYJDPKWIoaPzvblvBGGwM3DDTNitV6GRNU0fPuSAdUrbcqVIW30WlMZXTW0cXGCU9keR2CKLr6fmCI9hhd3+/KIInfbnBeytWimqjvBzaNiBiathXlbCvloiHkXF60POrXVGVG21mWyw1NO7BYbZiv4tzCSyLWIxYJg5UuhHlmCA5yk2O9JLiBmFQgekVBngWC1ztFGkiiOaiMvKhxQ8e2y6tEUkM0M5dqGW0Ugx1ou5Yh3gershBhhwLaAVOIyrtrOrJMk2eBLiZS2MZ+lI9WPcRnggQxrR1oh548lnHWVY2PPlfWWXrXxwYbA+uVo806bF/ifQWrNac3PcpKAwAVAkPToXMpVXtsEMLH+7QyOXlZE4C+6ziYL7nvoYd35e677dHYAMvVkktXrpB5QxE98rZre23EG8z1Pd5oKflrt53HLTgRC4Rw+BwwOqPICqy30U4CiPYGRbb1wsx3an+toMwliBSUxisjPnohBoy9gqLguvMnMVmGdYHlYg1I44HVekPTdbRdz7rpGPqevMvJygxswxe+eA9XDpayTgmO3Dgp0VQBOwSyXDxom3XLkGdIw5GcBx99mBcuXojrHQpHlWWovCCgsEcCil030JWWIi8l8eV6nB3I8nKnTvZAYQZGI4uzjq61DLZ7QmX0dkwO1jMeV0ynU67MN8xXC5x1qCLQDWJTVRY58wOZaxeZ4fTemOuuOcO52RlOTsvdemiH5M9Yu4JcN6JgPTLKjYHcasxwXP8tcwCOBd23f94GN4+rAQPisCfvbffjyRWDhx/0FdO2bbj22mvDP/tn/yx478O5c+fCz/3cz+1+3nVdmM1m4T3veU8IIYSDg4OQ53l4//vfv9vmoYceClrr8KEPfejL/tz7779/u7ROr/RKr/RKr/RKr/RKr/RKr/RKr/RKr/RKr/QKQLj//vv/xJjSU1KE/diP/RhveMMbuP7667l48SI//dM/zWKx4C1veQtKKW6//Xbe+c53cuONN3LjjTfyzne+k9FoxPd///cDMJvN+Nt/+2/zD/7BP+D06dOcOnWKH/uxH+OWW27ZdZH8cjh//jx33303L3nJS7j//vvZ27U0TiQSXynbkuM0phKJp4c0phKJp5c0phKJp5c0phKJp5c0pp55Qggsl0vOnz//J273lAJhDzzwAG984xu5dOkSV111Fa94xSv45Cc/yfOf/3wAfvzHf5ymafi7f/fvsr+/z2233caHP/xhptPp7nf8y3/5L8myjL/xN/4GTdPwnd/5nfyn//SfjnWS+dPQWnPttdcCsLe3ly6yROJpJI2pROLpJY2pROLpJY2pROLpJY2pROLpJY2pZ5bZbPanbqNC+NOKJ782WSwWzGYz5vN5usgSiaeBNKYSiaeXNKYSiaeXNKYSiaeXNKYSiaeXNKaePTxxj8tEIpFIJBKJRCKRSCQSiUTi/2c8awNhZVnyUz/1U8e6SSYSia+cNKYSiaeXNKYSiaeXNKYSiaeXNKYSiaeXNKaePTxrSyMTiUQikUgkEolEIpFIJBKJp8KzVhGWSCQSiUQikUgkEolEIpFIPBVSICyRSCQSiUQikUgkEolEIvGcIAXCEolEIpFIJBKJRCKRSCQSzwlSICyRSCQSiUQikUgkEolEIvGcIAXCEolEIpFIJBKJRCKRSCQSzwmelYGwf/fv/h033HADVVVx66238lu/9VvP9C4lEl+TvOtd7+KbvumbmE6nnD17lu/93u/lC1/4wrFtQgj803/6Tzl//jx1XfPt3/7tfP7znz+2Tdd1/OiP/ihnzpxhPB7zV//qX+WBBx74an6VROJrjne9610opbj99tt376XxlEg8dR588EF+4Ad+gNOnTzMajfjGb/xG7rzzzt3P07hKJL58rLX8k3/yT7jhhhuo65oXvOAF/PN//s/x3u+2SWMqkXhy/s//+T+84Q1v4Pz58yil+G//7b8d+/nTNX729/d585vfzGw2Yzab8eY3v5mDg4M/52+X2PKsC4S9//3v5/bbb+cd73gHn/3sZ/m2b/s2vvu7v5v77rvvmd61ROJrjjvuuIMf+ZEf4ZOf/CQf+chHsNby2te+lvV6vdvm53/+5/nFX/xF3v3ud/PpT3+ac+fO8V3f9V0sl8vdNrfffju//uu/zvve9z4+9rGPsVqteP3rX49z7pn4WonEM86nP/1pfvmXf5mXvvSlx95P4ymReGrs7+/zrd/6reR5zv/8n/+Tu+++m3/xL/4FJ06c2G2TxlUi8eXzcz/3c7znPe/h3e9+N7/3e7/Hz//8z/MLv/AL/Jt/829226QxlUg8Oev1mm/4hm/g3e9+9xP+/OkaP9///d/PXXfdxYc+9CE+9KEPcdddd/HmN7/5z/37JSLhWcY3f/M3hx/+4R8+9t5NN90UfvInf/IZ2qNE4tnDxYsXAxDuuOOOEEII3vtw7ty58LM/+7O7bdq2DbPZLLznPe8JIYRwcHAQ8jwP73vf+3bbPPjgg0FrHT70oQ99db9AIvE1wHK5DDfeeGP4yEc+El796leHt73tbSGENJ4Sia+En/iJnwivetWrnvTnaVwlEk+N173udeFv/a2/dey97/u+7ws/8AM/EEJIYyqReCoA4dd//dd3f3+6xs/dd98dgPDJT35yt80nPvGJAITf//3f/3P+VokQQnhWKcL6vufOO+/kta997bH3X/va1/Lxj3/8GdqrROLZw3w+B+DUqVMA3HPPPVy4cOHYmCrLkle/+tW7MXXnnXcyDMOxbc6fP8/NN9+cxl3iOcmP/MiP8LrXvY7XvOY1x95P4ymReOp88IMf5OUvfzl//a//dc6ePcvLXvYy/v2///e7n6dxlUg8NV71qlfxm7/5m/zBH/wBAP/3//5fPvaxj/E93/M9QBpTicSfhadr/HziE59gNptx22237bZ5xStewWw2S2Psq0T2TO/AU+HSpUs457j66quPvX/11Vdz4cKFZ2ivEolnByEE3v72t/OqV72Km2++GWA3bp5oTN177727bYqi4OTJk4/bJo27xHON973vfXzmM5/h05/+9ON+lsZTIvHU+dKXvsQv/dIv8fa3v51//I//MZ/61Kf4e3/v71GWJT/4gz+YxlUi8RT5iZ/4CebzOTfddBPGGJxz/MzP/AxvfOMbgfSsSiT+LDxd4+fChQucPXv2cb//7NmzaYx9lXhWBcK2KKWO/T2E8Lj3EonEcd761rfyO7/zO3zsYx973M++kjGVxl3iucb999/P2972Nj784Q9TVdWTbpfGUyLx5eO95+UvfznvfOc7AXjZy17G5z//eX7pl36JH/zBH9xtl8ZVIvHl8f73v5/3vve9/Nqv/Rpf//Vfz1133cXtt9/O+fPnectb3rLbLo2pROIr5+kYP0+0fRpjXz2eVaWRZ86cwRjzuCjpxYsXHxeVTSQSh/zoj/4oH/zgB/noRz/K8573vN37586dA/gTx9S5c+fo+579/f0n3SaReC5w5513cvHiRW699VayLCPLMu644w7+9b/+12RZthsPaTwlEl8+11xzDS95yUuOvffiF7941wQpPacSiafGP/yH/5Cf/Mmf5G/+zb/JLbfcwpvf/Gb+/t//+7zrXe8C0phKJP4sPF3j59y5czzyyCOP+/2PPvpoGmNfJZ5VgbCiKLj11lv5yEc+cuz9j3zkI7zyla98hvYqkfjaJYTAW9/6Vj7wgQ/wv/7X/+KGG2449vMbbriBc+fOHRtTfd9zxx137MbUrbfeSp7nx7Z5+OGH+d3f/d007hLPKb7zO7+Tz33uc9x1112718tf/nLe9KY3cdddd/GCF7wgjadE4inyrd/6rXzhC1849t4f/MEf8PznPx9Iz6lE4qmy2WzQ+vgSzxiD9x5IYyqR+LPwdI2fb/mWb2E+n/OpT31qt81v//ZvM5/P0xj7avFMOPT/WXjf+94X8jwPv/IrvxLuvvvucPvtt4fxeBz++I//+JnetUTia46/83f+TpjNZuF//+//HR5++OHda7PZ7Lb52Z/92TCbzcIHPvCB8LnPfS688Y1vDNdcc01YLBa7bX74h384PO95zwu/8Ru/ET7zmc+E7/iO7wjf8A3fEKy1z8TXSiS+ZjjaNTKENJ4SiafKpz71qZBlWfiZn/mZ8MUvfjH81//6X8NoNArvfe97d9ukcZVIfPm85S1vCddee234H//jf4R77rknfOADHwhnzpwJP/7jP77bJo2pROLJWS6X4bOf/Wz47Gc/G4Dwi7/4i+Gzn/1suPfee0MIT9/4+St/5a+El770peETn/hE+MQnPhFuueWW8PrXv/6r/n2fqzzrAmEhhPBv/+2/Dc9//vNDURThL/7FvxjuuOOOZ3qXEomvSYAnfP3H//gfd9t478NP/dRPhXPnzoWyLMNf+kt/KXzuc5879nuapglvfetbw6lTp0Jd1+H1r399uO+++77K3yaR+NrjsYGwNJ4SiafOf//v/z3cfPPNoSzLcNNNN4Vf/uVfPvbzNK4SiS+fxWIR3va2t4Xrr78+VFUVXvCCF4R3vOMdoeu63TZpTCUST85HP/rRJ1w/veUtbwkhPH3j5/Lly+FNb3pTmE6nYTqdhje96U1hf3//q/QtEyqEEJ4ZLVoikUgkEolEIpFIJBKJRCLx1eNZ5RGWSCQSiUQikUgkEolEIpFIfKWkQFgikUgkEolEIpFIJBKJROI5QQqEJRKJRCKRSCQSiUQikUgknhOkQFgikUgkEolEIpFIJBKJROI5QQqEJRKJRCKRSCQSiUQikUgknhOkQFgikUgkEolEIpFIJBKJROI5QQqEJRKJRCKRSCQSiUQikUgknhOkQFgikUgkEolEIpFIJBKJROI5QQqEJRKJRCKRSCQSiUQikUgknhOkQFgikUgkEolEIpFIJBKJROI5QQqEJRKJRCKRSCQSiUQikUgknhP8f8BnysOGuww7AAAAAElFTkSuQmCC", + "text/plain": [ + "

    " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "MAP_FILE = 'target_intersection.png'\n", + "bg_image = io.imread(MAP_FILE)\n", + "\n", + "plt.figure(figsize=(15, 15))\n", + "plt.imshow(bg_image)\n", + "lc = LineCollection(trajectories, color='b')\n", + "plt.gca().add_collection(lc)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Clustering Step 1: \n", + "\n", + "### Calculate Hausdorff distance matrix using scipy library\n", + "(Uncomment to run, time varies depending on machine)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# import math\n", + "# from scipy.spatial.distance import directed_hausdorff\n", + "# from itertools import combinations_with_replacement\n", + "# from joblib import Parallel, delayed\n", + "\n", + "# def hausforff_distance(u,v):\n", + "# return max(directed_hausdorff(u, v)[0], directed_hausdorff(v, u)[0])\n", + "\n", + "# def timeSince(since):\n", + "# now = time.time()\n", + "# s = now - since\n", + "# m = math.floor(s / 60)\n", + "# s -= m * 60\n", + "# return '%dm %ds' % (m, s)\n", + "\n", + "# start = time.time()\n", + "# dmatrix=np.zeros((len(trajectories),len(trajectories)))\n", + "# count = 0\n", + "# total = len(trajectories)*len(trajectories)\n", + "\n", + "# def compute_single(dmatrix, i, j):\n", + "# return hausforff_distance(trajectories[i],trajectories[j])\n", + "\n", + "# out = Parallel(n_jobs=10, verbose=3)(delayed(compute_single)(dmatrix, i, j) for i, j in combinations_with_replacement(range(len(trajectories)), 2))\n", + "# dmatrix = np.asarray(out).reshape((len(trajectories), len(trajectories)))\n", + "\n", + "# end = time.time()\n", + "# print('duration:',end-start)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Calculate Hausdorff distance matrix using cuspatial library (GPU)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 MULTIPOINT (95.387 326.899, 97.281 326.106, 10...\n", + "1 MULTIPOINT (99.380 296.802, 100.572 296.408, 9...\n", + "2 MULTIPOINT (674.339 272.198, 674.399 272.657, ...\n", + "3 MULTIPOINT (587.832 240.090, 588.061 240.461, ...\n", + "4 MULTIPOINT (823.491 240.381, 822.564 240.276, ...\n", + "dtype: geometry\n", + "\n", + "Hausdorff distance calculation by Cuspatial in GPU takes: \n", + " 3.345 seconds\n", + "\n", + "The complete Dmatrix calculation including data transitioning and transforming takes: \n", + " 10.564 seconds\n" + ] + } + ], + "source": [ + "start = time.time()\n", + "\n", + "# Prepare data for GPU\n", + "# Concatenating all trajectories\n", + "trajs = cp.concatenate([cp.asarray(traj)\n", + " for traj in trajectories], axis=0).flatten()\n", + "\n", + "# `offset` denote the starting index for each trajectory\n", + "offsets = cp.asarray([0] + [len(traj) for traj in trajectories]).cumsum()[:-1]\n", + "\n", + "traj_spaces = cuspatial.GeoSeries.from_multipoints_xy(\n", + " trajs.astype('f8'), offsets.astype('i4'))\n", + "print(traj_spaces.head())\n", + "\n", + "start1 = time.time()\n", + "dist = cuspatial.directed_hausdorff_distance(traj_spaces)\n", + "end1 = time.time()\n", + "dmatrix = dist.to_cupy().T.get()\n", + "end = time.time()\n", + "print('\\nHausdorff distance calculation by Cuspatial in GPU takes: \\n {0:.3f} seconds'.format(\n", + " end1 - start1))\n", + "print('\\nThe complete Dmatrix calculation including data transitioning and transforming takes: \\n {0:.3f} seconds'.format(\n", + " end - start))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A complete AC search takes:\n", + " 1.151 seconds\n" + ] + } + ], + "source": [ + "start = time.time()\n", + "agg = cuml.AgglomerativeClustering(n_clusters=10, linkage='single')\n", + "agg_result = agg.fit(dmatrix)\n", + "end = time.time()\n", + "print('A complete AC search takes:\\n {0:.3f} seconds'.format(end - start))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A complete DBSCAN search takes:\n", + " 0.835 seconds\n" + ] + } + ], + "source": [ + "start = time.time()\n", + "dbscan = cuml.DBSCAN(eps=20, metric='precomputed', min_samples=2)\n", + "dbscan_result = dbscan.fit(dmatrix)\n", + "end = time.time()\n", + "print('A complete DBSCAN search takes:\\n {0:.3f} seconds'.format(end - start))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualize AgglomerativeClustering results (all clusters overlaid, interactive mode)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "efdf46ea819a448cb3b66d002a596f41", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(IntText(value=2, description='n_clusters:'), ToggleButtons(description='linkage:', index…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def visualize_gt_vs_pred(n_clusters, linkage):\n", + " print('AgglomerativeClustering')\n", + " agg = cuml.AgglomerativeClustering(n_clusters=n_clusters, linkage='single')\n", + " agg_result = agg.fit(dmatrix)\n", + "\n", + " labels = agg_result.labels_\n", + "\n", + " print('#clusters = ', np.max(labels) + 1)\n", + " img = np.copy(bg_image)\n", + " plt.figure(figsize=(15, 15))\n", + " plt.imshow(img)\n", + " for label in range(np.max(labels) + 1):\n", + " color = (random.uniform(0.0, 1.0), random.uniform(\n", + " 0.0, 1.0), random.uniform(0.0, 1.0), 1.0)\n", + " selected_trajectories = pick_traj_with_label(\n", + " label, labels, trajectories)\n", + " lc = LineCollection(selected_trajectories, color=color)\n", + " plt.gca().add_collection(lc)\n", + "\n", + "\n", + "interact(visualize_gt_vs_pred,\n", + " n_clusters=widgets.IntText(\n", + " value=2, description='n_clusters:', disabled=False),\n", + " linkage=widgets.ToggleButtons(\n", + " value='average',\n", + " options=['complete', 'average', 'single'],\n", + " description='linkage:',\n", + " disabled=False,\n", + " button_style=''\n", + " ))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualize DBSCAN results (all clusters overlaid, interactive mode)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5cc70294b1e84c04b567c5024440a8cc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(ToggleButtons(description='eps:', index=8, options=(5, 10, 11, 12, 13, 14, 15, 20, 23, 2…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def visualize_gt_vs_pred(eps, min_samples):\n", + " print('DBSCAN')\n", + " dbscan = cuml.DBSCAN(eps=eps, metric='precomputed',\n", + " min_samples=min_samples)\n", + " dbscan_result = dbscan.fit(dmatrix)\n", + " labels = dbscan.labels_\n", + " print('#clusters = ', np.max(labels) + 1)\n", + " img = np.copy(bg_image)\n", + " plt.figure(figsize=(15, 15))\n", + " plt.imshow(img)\n", + " for label in range(np.max(labels) + 1):\n", + " color = (random.uniform(0.0, 1.0), random.uniform(\n", + " 0.0, 1.0), random.uniform(0.0, 1.0), 1.0)\n", + " selected_trajectories = pick_traj_with_label(\n", + " label, labels, trajectories)\n", + " lc = LineCollection(selected_trajectories, color=color)\n", + " plt.gca().add_collection(lc)\n", + "\n", + "interact(visualize_gt_vs_pred,\n", + " min_samples=widgets.IntText(\n", + " value=600, description='min_samples:', disabled=False),\n", + " eps=widgets.ToggleButtons(\n", + " value=23,\n", + " options=[5, 10, 11, 12, 13, 14, 15, 20, 23, 27, 30],\n", + " description='eps:',\n", + " disabled=False,\n", + " button_style='',\n", + " ))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualize AgglomerativeClustering results (clusters in separate subplots, interactive mode)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4515b2288e19426f956838c986335e9c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(IntText(value=2, description='n_clusters:'), ToggleButtons(description='linkage:', index…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def visualize_gt_vs_pred(n_clusters, linkage):\n", + " print('AgglomerativeClustering')\n", + " agg = cuml.AgglomerativeClustering(n_clusters=n_clusters, linkage='single')\n", + " agg_result = agg.fit(dmatrix)\n", + " labels = agg_result.labels_\n", + " print('#clusters = ', np.max(labels) + 1)\n", + " plt.figure(figsize=(15, 15))\n", + " gs = gridspec.GridSpec(1, int(np.ceil(n_clusters)), wspace=0.2, hspace=0)\n", + " idx = 0\n", + " for idx, label in enumerate(range(np.max(labels) + 1)):\n", + " ax = plt.subplot(gs[idx])\n", + " ax.imshow(bg_image)\n", + " color = (0, 1.0, 0)\n", + " selected_trajectories = pick_traj_with_label(\n", + " label, labels, trajectories)\n", + " lc = LineCollection(selected_trajectories, color=color)\n", + " plt.gca().add_collection(lc)\n", + "\n", + "\n", + "interact(visualize_gt_vs_pred,\n", + " n_clusters=widgets.IntText(\n", + " value=2, description='n_clusters:', disabled=False),\n", + " linkage=widgets.ToggleButtons(\n", + " value='average',\n", + " options=['complete', 'average', 'single'],\n", + " description='linkage:',\n", + " disabled=False,\n", + " button_style='',\n", + " ))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualize DBSCAN results (clusters in separate subplots, interactive mode)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "76422cb1e1964509b8228c1cbd8b5781", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(ToggleButtons(description='eps:', index=7, options=(5, 10, 11, 12, 13, 14, 15, 20, 23, 2…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def visualize_gt_vs_pred(eps, min_samples):\n", + " print('DBSCAN')\n", + " dbscan = cuml.DBSCAN(eps=eps, metric='precomputed',\n", + " min_samples=min_samples)\n", + " dbscan_result = dbscan.fit(dmatrix)\n", + " labels = dbscan_result.labels_\n", + "\n", + " print('#clusters = ', np.max(labels) + 1)\n", + "\n", + " plt.figure(figsize=(15, 15))\n", + " gs = gridspec.GridSpec(\n", + " 1, int(np.ceil((np.max(labels) + 1))) , wspace=0.2, hspace=0)\n", + " idx = 0\n", + " for label in range(np.max(labels) + 1):\n", + "\n", + " ax = plt.subplot(gs[idx])\n", + " idx += 1\n", + " img = np.copy(bg_image)\n", + " color = (0.0, 1.0, 0.0)\n", + " selected_trajectories = pick_traj_with_label(\n", + " label, labels, trajectories)\n", + " lc = LineCollection(selected_trajectories, color=color)\n", + " plt.gca().add_collection(lc)\n", + " plt.imshow(img)\n", + "\n", + "\n", + "interact(visualize_gt_vs_pred,\n", + " min_samples=widgets.IntText(\n", + " value=600, description='min_samples:', disabled=False),\n", + " eps=widgets.ToggleButtons(\n", + " value=20,\n", + " options=[5, 10, 11, 12, 13, 14, 15, 20, 23, 27, 30],\n", + " description='eps:',\n", + " disabled=False,\n", + " button_style='',\n", + " ))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.10" + }, + "vscode": { + "interpreter": { + "hash": "9b5f88c7073171460d55d234ac5b3db481f62c8cb2d152ecd077f1aa65102652" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 959cfdb88663dbe0b639516698b79f7cb4647d54 Mon Sep 17 00:00:00 2001 From: "H. Thomson Comer" Date: Wed, 26 Apr 2023 16:15:44 -0500 Subject: [PATCH 04/63] Binary Predicate Test Dispatching (#1085) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes https://github.com/rapidsai/cuspatial/issues/1046 Closes https://github.com/rapidsai/cuspatial/issues/1036 This PR adds a new binary predicate test dispatch test system. The test dispatcher creates one test for each ordered pair of features from the set (point, linestring, polygon) and each predicate that feature tuple can be applied to: - contains - covers - crosses - disjoint - geom_equals - intersects - overlaps - touches - within The combination of 9 predicates and 33 tests creates 297 tests that cover all possible combinations of simple features and their predicates. While development is underway, the test dispatcher automatically `xfails` any test that fails or hasn't been implemented yet in order to pass CI. The test dispatcher outputs diagnostic results during each test run. An output file `test_binpred_test_dispatch.log` is created containing all of the failing tests, including their name, a visual description of the feature tuple and relationship, the shapely objects used to create the test, and the runtime name of the test so it is easy for a developer (myself) to identify which test failed and rerun it. It also creates four .csv files during runtime that collect the results of each test pass or fail relative to which predicate is being run and which pair of features are being tested. These .csv files can be displayed using `tests/binpred/summarize_binpred_test_dispatch_results.py`, which will output a dataframe of each CSV file thusly: ``` (rapids) coder ➜ ~/cuspatial/python/cuspatial/cuspatial $ python tests/binpreds/summarize_binpred_test_dispatch_results.py predicate predicate_passes 0 geom_equals 20 1 intersects 11 2 covers 17 3 crosses 6 4 disjoint 9 5 overlaps 20 6 within 14 predicate predicate_fails 0 contains 33 1 geom_equals 13 2 intersects 22 3 covers 16 4 crosses 27 5 disjoint 24 6 overlaps 13 7 touches 33 8 within 19 feature feature_passes 0 (, ) 14 1 (, ) 22 2 (, , , , ) 4 1 (, , ) 14 3 (, , , Date: Wed, 26 Apr 2023 19:14:09 -0700 Subject: [PATCH 05/63] Fix a bug in segment intersection primitive where two collinear segment touch at endpoints is miscomputed as a degenerate segment (#1093) Fixes #1091 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1093 --- .../cuspatial/detail/utility/linestring.cuh | 22 +++++++++------- cpp/include/cuspatial/geometry/vec_2d.hpp | 3 ++- cpp/tests/operators/linestrings_test.cu | 26 +++++++++++++++++++ .../linestring_intersection_test.cu | 22 ++++++++++++++++ .../tests/binops/test_intersections.py | 8 +++--- 5 files changed, 67 insertions(+), 14 deletions(-) diff --git a/cpp/include/cuspatial/detail/utility/linestring.cuh b/cpp/include/cuspatial/detail/utility/linestring.cuh index c64dfdc1c..94180a5df 100644 --- a/cpp/include/cuspatial/detail/utility/linestring.cuh +++ b/cpp/include/cuspatial/detail/utility/linestring.cuh @@ -137,36 +137,40 @@ __forceinline__ T __device__ squared_segment_distance(vec_2d const& a, /** * @internal - * @brief Given two collinear or parallel segments, return their potential overlapping segment + * @brief Given two collinear or parallel segments, return their potential overlapping segment or + * point * * @p a, @p b, @p c, @p d refer to end points of segment ab and cd. * @p center is the geometric center of the segments, used to decondition the coordinates. * - * @return optional end points of overlapping segment + * @return A pair of optional overlapping point or segments */ template -__forceinline__ thrust::optional> __device__ collinear_or_parallel_overlapping_segments( - vec_2d a, vec_2d b, vec_2d c, vec_2d d, vec_2d center = vec_2d{}) +__forceinline__ + + thrust::pair>, thrust::optional>> + __device__ collinear_or_parallel_overlapping_segments( + vec_2d a, vec_2d b, vec_2d c, vec_2d d, vec_2d center = vec_2d{}) { auto ab = b - a; auto ac = c - a; // Parallel - if (not float_equal(det(ab, ac), T{0})) return thrust::nullopt; + if (not float_equal(det(ab, ac), T{0})) return {thrust::nullopt, thrust::nullopt}; // Must be on the same line, sort the endpoints if (b < a) thrust::swap(a, b); if (d < c) thrust::swap(c, d); // Test if not overlap - if (b < c || d < a) return thrust::nullopt; + if (b < c || d < a) return {thrust::nullopt, thrust::nullopt}; // Compute smallest interval between the segments auto e0 = a > c ? a : c; auto e1 = b < d ? b : d; - // Decondition the coordinates - return segment{e0 + center, e1 + center}; + if (e0 == e1) { return {e0 + center, thrust::nullopt}; } + return {thrust::nullopt, segment{e0 + center, e1 + center}}; } /** @@ -192,7 +196,7 @@ segment_intersection(segment const& segment1, segment const& segment2) if (float_equal(denom, T{0})) { // Segments parallel or collinear - return {thrust::nullopt, collinear_or_parallel_overlapping_segments(a, b, c, d, center)}; + return collinear_or_parallel_overlapping_segments(a, b, c, d, center); } auto ac = c - a; diff --git a/cpp/include/cuspatial/geometry/vec_2d.hpp b/cpp/include/cuspatial/geometry/vec_2d.hpp index 5580baec0..c7e765de4 100644 --- a/cpp/include/cuspatial/geometry/vec_2d.hpp +++ b/cpp/include/cuspatial/geometry/vec_2d.hpp @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include @@ -58,7 +59,7 @@ class alignas(2 * sizeof(T)) vec_2d { */ friend bool CUSPATIAL_HOST_DEVICE operator==(vec_2d const& lhs, vec_2d const& rhs) { - return (lhs.x == rhs.x) && (lhs.y == rhs.y); + return detail::float_equal(lhs.x, rhs.x) && detail::float_equal(lhs.y, rhs.y); } /** diff --git a/cpp/tests/operators/linestrings_test.cu b/cpp/tests/operators/linestrings_test.cu index 356a115ed..86c8133c4 100644 --- a/cpp/tests/operators/linestrings_test.cu +++ b/cpp/tests/operators/linestrings_test.cu @@ -133,6 +133,32 @@ TYPED_TEST(SegmentIntersectionTest, IntersectAtEndPoint) run_single_intersection_test(ab, cd, points_expected, segments_expected); } +TYPED_TEST(SegmentIntersectionTest, IntersectAtEndPoint2) +{ + using T = TypeParam; + + segment ab{{-1.0, 0.0}, {0.0, 0.0}}; + segment cd{{0.0, 0.0}, {0.0, 1.0}}; + + std::vector>> points_expected{vec_2d{0.0, 0.0}}; + std::vector>> segments_expected{thrust::nullopt}; + + run_single_intersection_test(ab, cd, points_expected, segments_expected); +} + +TYPED_TEST(SegmentIntersectionTest, IntersectAtEndPoint3) +{ + using T = TypeParam; + + segment ab{{-1.0, 0.0}, {0.0, 0.0}}; + segment cd{{1.0, 0.0}, {0.0, 0.0}}; + + std::vector>> points_expected{vec_2d{0.0, 0.0}}; + std::vector>> segments_expected{thrust::nullopt}; + + run_single_intersection_test(ab, cd, points_expected, segments_expected); +} + TYPED_TEST(SegmentIntersectionTest, UnparallelDisjoint1) { using T = TypeParam; diff --git a/cpp/tests/spatial/intersection/linestring_intersection_test.cu b/cpp/tests/spatial/intersection/linestring_intersection_test.cu index d0bf58b11..c91d7de43 100644 --- a/cpp/tests/spatial/intersection/linestring_intersection_test.cu +++ b/cpp/tests/spatial/intersection/linestring_intersection_test.cu @@ -278,6 +278,28 @@ TYPED_TEST(LinestringIntersectionTest, SingletoSingleOnePair) expected); } +TYPED_TEST(LinestringIntersectionTest, OnePairWithRings) +{ + using T = TypeParam; + using P = vec_2d; + + using index_t = typename linestring_intersection_result::index_t; + using types_t = typename linestring_intersection_result::types_t; + + auto multilinestrings1 = make_multilinestring_array({0, 1}, {0, 2}, {{-1, 0}, {0, 0}}); + + auto multilinestrings2 = + make_multilinestring_array({0, 1}, {0, 5}, {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}}); + + auto expected = make_linestring_intersection_result( + {0, 1}, {0}, {0}, {P{0.0, 0.0}}, {}, {0}, {0}, {0}, {0}, this->stream(), this->mr()); + + CUSPATIAL_RUN_TEST(this->template run_single_test, + multilinestrings1.range(), + multilinestrings2.range(), + expected); +} + TYPED_TEST(LinestringIntersectionTest, SingletoSingleOnePairWithDuplicatePoint) { using T = TypeParam; diff --git a/python/cuspatial/cuspatial/tests/binops/test_intersections.py b/python/cuspatial/cuspatial/tests/binops/test_intersections.py index a3bcb0cd0..37891366a 100644 --- a/python/cuspatial/cuspatial/tests/binops/test_intersections.py +++ b/python/cuspatial/cuspatial/tests/binops/test_intersections.py @@ -88,9 +88,9 @@ def test_one_pair_with_overlap(): expect_ids = pd.DataFrame( { "lhs_linestring_id": [[0]], - "lhs_segment_id": [[0]], + "lhs_segment_id": [[1]], "rhs_linestring_id": [[0]], - "rhs_segment_id": [[0]], + "rhs_segment_id": [[1]], } ) @@ -122,9 +122,9 @@ def test_two_pairs_with_intersect_and_overlap(): expect_ids = pd.DataFrame( { "lhs_linestring_id": [[0], [0, 0]], - "lhs_segment_id": [[0], [1, 0]], + "lhs_segment_id": [[1], [1, 0]], "rhs_linestring_id": [[0], [0, 0]], - "rhs_segment_id": [[0], [0, 2]], + "rhs_segment_id": [[1], [0, 2]], } ) From e9923291076f5662110b03802eb8304a0937dd9c Mon Sep 17 00:00:00 2001 From: "H. Thomson Comer" Date: Thu, 27 Apr 2023 10:52:33 -0500 Subject: [PATCH 06/63] Pairwise Multipoint Equals Count function (#1022) This contribution adds `pairwise_multipoint_equals_count` to the column and header-only APIs. `pairwise_multipoint_equals_count` counts the number of times that each point in the lhs occurs in the rhs. ``` auto result = pairwise_multipoint_equals_count( {{{0, 0}},{{1, 1, 2, 2}},{{0, 0}, {1, 1}, {2, 2}}}, { {{0, 0}, {1, 1}, {2, 2}} {{0, 0}, {1, 1}, {2, 2}} {{0, 0}, {1, 1}, {2, 2}} } ) result = {1, 2, 3} ``` Written while pairing with @isVoid. Authors: - H. Thomson Comer (https://github.com/thomcom) - Michael Wang (https://github.com/isVoid) Approvers: - Michael Wang (https://github.com/isVoid) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1022 --- cpp/CMakeLists.txt | 1 + .../geometry_collection/multipoint_ref.cuh | 1 + .../pairwise_multipoint_equals_count.cuh | 108 ++++++++++++ .../geometry_collection/multipoint_ref.cuh | 2 +- .../pairwise_multipoint_equals_count.cuh | 74 +++++++++ .../pairwise_multipoint_equals_count.hpp | 74 +++++++++ cpp/include/cuspatial_test/base_fixture.hpp | 2 + .../pairwise_multipoint_equals_count.cu | 115 +++++++++++++ cpp/tests/CMakeLists.txt | 14 +- .../pairwise_multipoint_equals_count_test.cpp | 91 ++++++++++ .../pairwise_multipoint_equals_count_test.cu | 157 ++++++++++++++++++ .../cuspatial/cuspatial/_lib/CMakeLists.txt | 1 + .../cpp/pairwise_multipoint_equals_count.pxd | 17 ++ .../_lib/pairwise_multipoint_equals_count.pyx | 43 +++++ .../cuspatial/core/binops/equals_count.py | 80 +++++++++ .../tests/binops/test_equals_count.py | 123 ++++++++++++++ 16 files changed, 897 insertions(+), 6 deletions(-) create mode 100644 cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh create mode 100644 cpp/include/cuspatial/pairwise_multipoint_equals_count.cuh create mode 100644 cpp/include/cuspatial/pairwise_multipoint_equals_count.hpp create mode 100644 cpp/src/spatial/pairwise_multipoint_equals_count.cu create mode 100644 cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cpp create mode 100644 cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu create mode 100644 python/cuspatial/cuspatial/_lib/cpp/pairwise_multipoint_equals_count.pxd create mode 100644 python/cuspatial/cuspatial/_lib/pairwise_multipoint_equals_count.pyx create mode 100644 python/cuspatial/cuspatial/core/binops/equals_count.py create mode 100644 python/cuspatial/cuspatial/tests/binops/test_equals_count.py diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 1996f5918..7a5b8acae 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -122,6 +122,7 @@ add_library(cuspatial src/join/quadtree_point_in_polygon.cu src/join/quadtree_point_to_nearest_linestring.cu src/join/quadtree_bbox_filtering.cu + src/spatial/pairwise_multipoint_equals_count.cu src/spatial/polygon_bounding_box.cu src/spatial/linestring_bounding_box.cu src/spatial/point_in_polygon.cu diff --git a/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh b/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh index c4f8c9742..5d4e8eeeb 100644 --- a/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh @@ -15,6 +15,7 @@ */ #pragma once #include +#include #include diff --git a/cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh b/cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh new file mode 100644 index 000000000..f6d4f46c1 --- /dev/null +++ b/cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace cuspatial { + +namespace detail { + +template +void __global__ pairwise_multipoint_equals_count_kernel(MultiPointRangeA lhs, + MultiPointRangeB rhs, + OutputIt output) +{ + using T = typename MultiPointRangeA::point_t::value_type; + + for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < lhs.num_points(); + idx += gridDim.x * blockDim.x) { + auto geometry_id = lhs.geometry_idx_from_point_idx(idx); + vec_2d lhs_point = lhs.point_begin()[idx]; + auto rhs_multipoint = rhs[geometry_id]; + + atomicAdd( + &output[geometry_id], + thrust::binary_search(thrust::seq, rhs_multipoint.begin(), rhs_multipoint.end(), lhs_point)); + } +} + +} // namespace detail + +template +OutputIt pairwise_multipoint_equals_count(MultiPointRangeA lhs, + MultiPointRangeB rhs, + OutputIt output, + rmm::cuda_stream_view stream) +{ + using T = typename MultiPointRangeA::point_t::value_type; + using index_t = typename MultiPointRangeB::index_t; + + static_assert(is_same_floating_point(), + "Origin and input must have the same base floating point type."); + + CUSPATIAL_EXPECTS(lhs.size() == rhs.size(), "lhs and rhs inputs should have the same size."); + + if (lhs.size() == 0) return output; + + // Create a sorted copy of the rhs points. + auto key_it = make_geometry_id_iterator(rhs.offsets_begin(), rhs.offsets_end()); + + rmm::device_uvector rhs_keys(rhs.num_points(), stream); + rmm::device_uvector> rhs_point_sorted(rhs.num_points(), stream); + + thrust::copy(rmm::exec_policy(stream), key_it, key_it + rhs.num_points(), rhs_keys.begin()); + thrust::copy( + rmm::exec_policy(stream), rhs.point_begin(), rhs.point_end(), rhs_point_sorted.begin()); + + auto rhs_with_keys = + thrust::make_zip_iterator(thrust::make_tuple(rhs_keys.begin(), rhs_point_sorted.begin())); + + thrust::sort(rmm::exec_policy(stream), rhs_with_keys, rhs_with_keys + rhs.num_points()); + + auto rhs_sorted = multipoint_range{ + rhs.offsets_begin(), rhs.offsets_end(), rhs_point_sorted.begin(), rhs_point_sorted.end()}; + + detail::zero_data_async(output, output + lhs.size(), stream); + auto [tpb, n_blocks] = grid_1d(lhs.num_points()); + detail::pairwise_multipoint_equals_count_kernel<<>>( + lhs, rhs_sorted, output); + + CUSPATIAL_CHECK_CUDA(stream.value()); + + return output + lhs.size(); +} + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/geometry_collection/multipoint_ref.cuh b/cpp/include/cuspatial/geometry_collection/multipoint_ref.cuh index 0ebe2f71b..86d50e3c2 100644 --- a/cpp/include/cuspatial/geometry_collection/multipoint_ref.cuh +++ b/cpp/include/cuspatial/geometry_collection/multipoint_ref.cuh @@ -26,9 +26,9 @@ namespace cuspatial { */ template class multipoint_ref { + public: using point_t = iterator_value_type; - public: CUSPATIAL_HOST_DEVICE multipoint_ref(VecIterator begin, VecIterator end); /// Return iterator to the starting point of the multipoint. diff --git a/cpp/include/cuspatial/pairwise_multipoint_equals_count.cuh b/cpp/include/cuspatial/pairwise_multipoint_equals_count.cuh new file mode 100644 index 000000000..f15617c60 --- /dev/null +++ b/cpp/include/cuspatial/pairwise_multipoint_equals_count.cuh @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +#include + +#include + +namespace cuspatial { + +/** + * @brief Count the number of equal points in multipoint pairs. + * + * Given two ranges of multipoints, this function counts points in the left-hand + * multipoint that exist in the corresponding right-hand multipoint. + * + * @example + * + * lhs: { {0, 0} } + * rhs: { {0, 0}, {1, 1}, {2, 2}, {3, 3} } + * count: { 1 } + + * lhs: { {0, 0}, {1, 1}, {2, 2}, {3, 3} } + * rhs: { {0, 0} } + * count: { 1 } + + * lhs: { { {3, 3}, {3, 3}, {0, 0} }, { {0, 0}, {1, 1}, {2, 2} }, { {0, 0} } } + * rhs: { { {0, 0}, {2, 2}, {1, 1} }, { {2, 2}, {0, 0}, {1, 1} }, { {1, 1} } } + * count: { 1, 3, 0 } + * + * @note All input iterators must conform to the specification defined by + * `multipoint_range.cuh` and the output iterator must be able to accept for + * storage values of type + * `uint32_t`. + * + * @param[in] lhs_first multipoint_range of first array of multipoints + * @param[in] rhs_first multipoint_range of second array of multipoints + * @param[out] count_first: beginning of range of uint32_t counts + * @param[in] stream: The CUDA stream on which to perform computations and allocate memory. + * @tparam MultiPointRangeA The multipolygon range to compare point equality from + * @tparam MultiPointRangeB The multipolygon range to compare point equality to + * @tparam OutputIt Iterator over uint32_t. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable. + * + * @return Output iterator to the element past the last count result written. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_multipoint_equals_count(MultiPointRangeA lhs_first, + MultiPointRangeB rhs_first, + OutputIt count_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +} // namespace cuspatial + +#include diff --git a/cpp/include/cuspatial/pairwise_multipoint_equals_count.hpp b/cpp/include/cuspatial/pairwise_multipoint_equals_count.hpp new file mode 100644 index 000000000..8dca3185e --- /dev/null +++ b/cpp/include/cuspatial/pairwise_multipoint_equals_count.hpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +#include + +#include + +#include + +namespace cuspatial { + +/** + * @addtogroup spatial + * @brief Count the number of equal points in pairs of multipoints.. + * + * Given two columns of multipoints, returns a column containing the + * count of points in each multipoint from `lhs` that exist in the + * corresponding multipoint in `rhs`. + * + * @param lhs Geometry column of multipoints with interleaved coordinates + * @param rhs Geometry column of multipoints with interleaved coordinates + * @param mr Device memory resource used to allocate the returned column. + * @return A column of size len(lhs) containing the number of points in each + * multipoint from `lhs` that are equal to a point in the corresponding + * multipoint in `rhs`. + * + * @throw cuspatial::logic_error if `lhs` and `rhs` have different coordinate + * types or lengths. + * + * @example + * ``` + * lhs: MultiPoint(0, 0) + * rhs: MultiPoint((0, 0), (1, 1), (2, 2), (3, 3)) + * result: 1 + + * lhs: MultiPoint((0, 0), (1, 1), (2, 2), (3, 3)) + * rhs: MultiPoint((0, 0)) + * result: 1 + + * lhs: ( + * MultiPoint((3, 3), (3, 3), (0, 0)), + * MultiPoint((0, 0), (1, 1), (2, 2)), + * MultiPoint((0, 0)) + * ) + * rhs: ( + * MultiPoint((0, 0), (2, 2), (1, 1)), + * MultiPoint((2, 2), (0, 0), (1, 1)), + * MultiPoint((1, 1)) + * ) + * result: ( 1, 3, 0 ) + */ +std::unique_ptr pairwise_multipoint_equals_count( + geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +} // namespace cuspatial diff --git a/cpp/include/cuspatial_test/base_fixture.hpp b/cpp/include/cuspatial_test/base_fixture.hpp index 8f8344896..a2beffd2b 100644 --- a/cpp/include/cuspatial_test/base_fixture.hpp +++ b/cpp/include/cuspatial_test/base_fixture.hpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include diff --git a/cpp/src/spatial/pairwise_multipoint_equals_count.cu b/cpp/src/spatial/pairwise_multipoint_equals_count.cu new file mode 100644 index 000000000..71e2b6d2b --- /dev/null +++ b/cpp/src/spatial/pairwise_multipoint_equals_count.cu @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include "utility/multi_geometry_dispatch.hpp" + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace cuspatial { +namespace detail { +namespace { + +template +struct pairwise_multipoint_equals_count_impl { + using SizeType = cudf::device_span::size_type; + + template )> + std::unique_ptr operator()(geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) + { + auto size = lhs.size(); // lhs is a buffer of xy coords + auto type = cudf::data_type(cudf::type_to_id()); + auto result = + cudf::make_fixed_width_column(type, size, cudf::mask_state::UNALLOCATED, stream, mr); + + auto lhs_range = make_multipoint_range(lhs); + auto rhs_range = make_multipoint_range(rhs); + + cuspatial::pairwise_multipoint_equals_count( + lhs_range, rhs_range, result->mutable_view().begin(), stream); + + return result; + } + + template ), typename... Args> + std::unique_ptr operator()(Args&&...) + + { + CUSPATIAL_FAIL("pairwise_multipoint_equals_count only supports floating point types."); + } +}; + +} // namespace + +template +struct pairwise_multipoint_equals_count { + std::unique_ptr operator()(geometry_column_view lhs, + geometry_column_view rhs, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) + { + return cudf::type_dispatcher( + lhs.coordinate_type(), + pairwise_multipoint_equals_count_impl{}, + lhs, + rhs, + stream, + mr); + } +}; + +} // namespace detail + +std::unique_ptr pairwise_multipoint_equals_count(geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::mr::device_memory_resource* mr) +{ + CUSPATIAL_EXPECTS(lhs.geometry_type() == geometry_type_id::POINT && + rhs.geometry_type() == geometry_type_id::POINT, + + "pairwise_multipoint_equals_count only supports POINT geometries" + "for both lhs and rhs"); + + CUSPATIAL_EXPECTS(lhs.coordinate_type() == rhs.coordinate_type(), + "Input geometries must have the same coordinate data types."); + + CUSPATIAL_EXPECTS(lhs.size() == rhs.size(), + "Input geometries must have the same number of multipoints."); + + return multi_geometry_double_dispatch( + lhs.collection_type(), rhs.collection_type(), lhs, rhs, rmm::cuda_stream_default, mr); +} + +} // namespace cuspatial diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index c3201e373..3ec61c6ce 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -48,8 +48,6 @@ endfunction(ConfigureTest) ### test sources ################################################################################## ################################################################################################### -# Column-based API - # index ConfigureTest(POINT_QUADTREE_TEST index/point_quadtree_test.cpp) @@ -97,7 +95,11 @@ ConfigureTest(LINESTRING_POLYGON_DISTANCE_TEST ConfigureTest(POINT_POLYGON_DISTANCE_TEST spatial/distance/point_polygon_distance_test.cpp) -#intersection +# equality +ConfigureTest(PAIRWISE_MULTIPOINT_EQUALS_COUNT_TEST + spatial/equality/pairwise_multipoint_equals_count_test.cpp) + +# intersection ConfigureTest(LINESTRING_INTERSECTION_TEST spatial/intersection/linestring_intersection_test.cpp) @@ -133,8 +135,6 @@ ConfigureTest(UTILITY_TEST utility_test/test_geometry_generators.cu ) -# Header-only API - # find / intersection util ConfigureTest(FIND_TEST_EXP find/find_and_combine_segments_test.cu @@ -207,6 +207,10 @@ ConfigureTest(LINESTRING_DISTANCE_TEST_EXP ConfigureTest(POLYGON_DISTANCE_TEST_EXP spatial/distance/polygon_distance_test.cu) +# equality +ConfigureTest(PAIRWISE_MULTIPOINT_EQUALS_COUNT_TEST_EXP + spatial/equality/pairwise_multipoint_equals_count_test.cu) + # intersection ConfigureTest(LINESTRING_INTERSECTION_TEST_EXP spatial/intersection/linestring_intersection_count_test.cu diff --git a/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cpp b/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cpp new file mode 100644 index 000000000..1d2923e4b --- /dev/null +++ b/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +using namespace cuspatial; +using namespace cuspatial::test; + +using namespace cudf::test; + +constexpr cudf::test::debug_output_level verbosity{cudf::test::debug_output_level::ALL_ERRORS}; + +template +struct PairwiseMultipointEqualsCountTestTyped : public BaseFixture { + rmm::cuda_stream_view stream() { return cudf::get_default_stream(); } +}; + +struct PairwiseMultipointEqualsCountTestUntyped : public BaseFixture { + rmm::cuda_stream_view stream() { return cudf::get_default_stream(); } +}; + +// float and double are logically the same but would require separate tests due to precision. +using TestTypes = Types; +TYPED_TEST_CASE(PairwiseMultipointEqualsCountTestTyped, TestTypes); + +TYPED_TEST(PairwiseMultipointEqualsCountTestTyped, Empty) +{ + using T = TypeParam; + auto [ptype, lhs] = make_point_column(std::initializer_list{}, this->stream()); + auto [pytpe, rhs] = make_point_column(std::initializer_list{}, this->stream()); + + auto lhs_gcv = geometry_column_view(lhs->view(), ptype, geometry_type_id::POINT); + auto rhs_gcv = geometry_column_view(rhs->view(), ptype, geometry_type_id::POINT); + + auto output = cuspatial::pairwise_multipoint_equals_count(lhs_gcv, rhs_gcv); + + auto expected = fixed_width_column_wrapper({}); + + expect_columns_equivalent(expected, output->view(), verbosity); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTestTyped, InvalidLength) +{ + using T = TypeParam; + auto [ptype, lhs] = make_point_column({0, 1}, {0.0, 0.0}, this->stream()); + auto [pytpe, rhs] = make_point_column({0, 1, 2}, {1.0, 1.0, 0.0, 0.0}, this->stream()); + + auto lhs_gcv = geometry_column_view(lhs->view(), ptype, geometry_type_id::POINT); + auto rhs_gcv = geometry_column_view(rhs->view(), ptype, geometry_type_id::POINT); + + EXPECT_THROW(auto output = cuspatial::pairwise_multipoint_equals_count(lhs_gcv, rhs_gcv), + cuspatial::logic_error); +} + +TEST_F(PairwiseMultipointEqualsCountTestUntyped, InvalidTypes) +{ + auto [ptype, lhs] = make_point_column(std::initializer_list{}, this->stream()); + auto [pytpe, rhs] = make_point_column(std::initializer_list{}, this->stream()); + + auto lhs_gcv = geometry_column_view(lhs->view(), ptype, geometry_type_id::POINT); + auto rhs_gcv = geometry_column_view(rhs->view(), ptype, geometry_type_id::POINT); + + EXPECT_THROW(auto output = cuspatial::pairwise_multipoint_equals_count(lhs_gcv, rhs_gcv), + cuspatial::logic_error); +} diff --git a/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu b/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu new file mode 100644 index 000000000..5bf3407f6 --- /dev/null +++ b/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +using namespace cuspatial; +using namespace cuspatial::test; + +template +struct PairwiseMultipointEqualsCountTest : public BaseFixture { + void run_single(std::initializer_list>> lhs_coordinates, + std::initializer_list>> rhs_coordinates, + std::initializer_list expected) + { + auto larray = make_multipoints_array(lhs_coordinates); + auto rarray = make_multipoints_array(rhs_coordinates); + + auto lhs = larray.range(); + auto rhs = rarray.range(); + + auto got = rmm::device_uvector(lhs.size(), stream()); + + auto ret = pairwise_multipoint_equals_count(lhs, rhs, got.begin(), stream()); + + auto d_expected = make_device_vector(expected); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(got, d_expected); + EXPECT_EQ(ret, got.end()); + } +}; + +using TestTypes = ::testing::Types; + +TYPED_TEST_CASE(PairwiseMultipointEqualsCountTest, TestTypes); + +TYPED_TEST(PairwiseMultipointEqualsCountTest, EmptyInput) +{ + using T = TypeParam; + using P = vec_2d; + CUSPATIAL_RUN_TEST(this->run_single, + std::initializer_list>{}, + std::initializer_list>{}, + {}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, ExampleOne) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}}}, {{{0, 0}, {1, 1}, {2, 2}, {3, 3}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, ExampleTwo) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}, {1, 1}, {2, 2}, {3, 3}}}, {{{0, 0}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, ExampleThree) +{ + CUSPATIAL_RUN_TEST(this->run_single, + {{{3, 3}, {3, 3}, {0, 0}}, {{0, 0}, {1, 1}, {2, 2}}, {{0, 0}}}, + {{{0, 0}, {2, 2}, {1, 1}}, {{2, 2}, {0, 0}, {1, 1}}, {{1, 1}}}, + {1, 3, 0}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OneOneEqual) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}}}, {{{0, 0}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OneOneNotEqual) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}}}, {{{1, 0}}}, {0}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OnePairWithTwoEachEqual) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}, {1, 1}}}, {{{1, 1}, {0, 0}}}, {2}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OnePairithTwoNotEqual) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}, {2, 1}}}, {{{1, 1}, {0, 0}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OnePairThreeOneEqual) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}, {1, 1}, {2, 2}}}, {{{1, 1}, {1, 1}, {1, 1}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OnePairFourOneEqual) +{ + CUSPATIAL_RUN_TEST( + this->run_single, {{{0, 0}, {1, 1}, {1, 1}, {2, 2}}}, {{{1, 1}, {1, 1}, {1, 1}}}, {2}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OnePair) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{0, 0}, {1, 1}, {2, 2}}}, {{{-1, -1}}}, {0}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OneThreeEqual) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{1, 1}}}, {{{0, 0}, {1, 1}, {0, 0}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, OneThreeNotEqual) +{ + CUSPATIAL_RUN_TEST(this->run_single, {{{1, 1}}}, {{{0, 0}, {0, 0}, {1, 1}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, ThreeThreeEqualMiddle) +{ + CUSPATIAL_RUN_TEST( + this->run_single, {{{0, 0}, {1, 1}, {2, 2}}}, {{{-1, -1}, {1, 1}, {-1, -1}}}, {1}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, ThreeThreeNotEqualMiddle) +{ + CUSPATIAL_RUN_TEST( + this->run_single, {{{0, 0}, {1, 1}, {2, 2}}}, {{{0, 0}, {-1, -1}, {2, 2}}}, {2}); +} + +TYPED_TEST(PairwiseMultipointEqualsCountTest, ThreeThreeNeedRhsMultipoints) +{ + CUSPATIAL_RUN_TEST(this->run_single, + { + {{0, 0}}, + {{1, 1}}, + {{2, 2}}, + }, + {{{0, 0}, {1, 1}}, {{2, 2}, {3, 3}}, {{0, 0}, {1, 1}}}, + {1, 0, 0}); +} diff --git a/python/cuspatial/cuspatial/_lib/CMakeLists.txt b/python/cuspatial/cuspatial/_lib/CMakeLists.txt index 4ffbfc7dc..6a0f0d012 100644 --- a/python/cuspatial/cuspatial/_lib/CMakeLists.txt +++ b/python/cuspatial/cuspatial/_lib/CMakeLists.txt @@ -13,6 +13,7 @@ # ============================================================================= set(cython_sources + pairwise_multipoint_equals_count.pyx distance.pyx hausdorff.pyx intersection.pyx diff --git a/python/cuspatial/cuspatial/_lib/cpp/pairwise_multipoint_equals_count.pxd b/python/cuspatial/cuspatial/_lib/cpp/pairwise_multipoint_equals_count.pxd new file mode 100644 index 000000000..5af573bd0 --- /dev/null +++ b/python/cuspatial/cuspatial/_lib/cpp/pairwise_multipoint_equals_count.pxd @@ -0,0 +1,17 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +from libcpp.memory cimport unique_ptr + +from cudf._lib.column cimport column, column_view + +from cuspatial._lib.cpp.column.geometry_column_view cimport ( + geometry_column_view, +) + + +cdef extern from "cuspatial/pairwise_multipoint_equals_count.hpp" \ + namespace "cuspatial" nogil: + cdef unique_ptr[column] pairwise_multipoint_equals_count( + const geometry_column_view lhs, + const geometry_column_view rhs, + ) except + diff --git a/python/cuspatial/cuspatial/_lib/pairwise_multipoint_equals_count.pyx b/python/cuspatial/cuspatial/_lib/pairwise_multipoint_equals_count.pyx new file mode 100644 index 000000000..aea144568 --- /dev/null +++ b/python/cuspatial/cuspatial/_lib/pairwise_multipoint_equals_count.pyx @@ -0,0 +1,43 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +from libcpp.memory cimport make_shared, shared_ptr, unique_ptr +from libcpp.utility cimport move + +from cudf._lib.column cimport Column, column + +from cuspatial._lib.cpp.column.geometry_column_view cimport ( + geometry_column_view, +) +from cuspatial._lib.cpp.pairwise_multipoint_equals_count cimport ( + pairwise_multipoint_equals_count as cpp_pairwise_multipoint_equals_count, +) +from cuspatial._lib.cpp.types cimport collection_type_id, geometry_type_id + + +def pairwise_multipoint_equals_count( + Column _lhs, + Column _rhs, +): + cdef shared_ptr[geometry_column_view] lhs = \ + make_shared[geometry_column_view]( + _lhs.view(), + collection_type_id.MULTI, + geometry_type_id.POINT) + + cdef shared_ptr[geometry_column_view] rhs = \ + make_shared[geometry_column_view]( + _rhs.view(), + collection_type_id.MULTI, + geometry_type_id.POINT) + + cdef unique_ptr[column] result + + with nogil: + result = move( + cpp_pairwise_multipoint_equals_count( + lhs.get()[0], + rhs.get()[0], + ) + ) + + return Column.from_unique_ptr(move(result)) diff --git a/python/cuspatial/cuspatial/core/binops/equals_count.py b/python/cuspatial/cuspatial/core/binops/equals_count.py new file mode 100644 index 000000000..80f63027e --- /dev/null +++ b/python/cuspatial/cuspatial/core/binops/equals_count.py @@ -0,0 +1,80 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +import cudf + +from cuspatial._lib.pairwise_multipoint_equals_count import ( + pairwise_multipoint_equals_count as c_pairwise_multipoint_equals_count, +) +from cuspatial.core.geoseries import GeoSeries +from cuspatial.utils.column_utils import contains_only_multipoints + + +def pairwise_multipoint_equals_count(lhs: GeoSeries, rhs: GeoSeries): + """Compute the number of points in each multipoint in the lhs that exist + in the corresponding multipoint in the rhs. + + For each point in a multipoint in the lhs, search the + corresponding multipoint in the rhs for a point that is equal to the + point in the lhs. If a point is found, increment the count for that + multipoint in the lhs. + + Parameters + ---------- + lhs : GeoSeries + A GeoSeries of multipoints. + rhs : GeoSeries + A GeoSeries of multipoints. + + Examples + -------- + >>> import cuspatial + >>> from shapely.geometry import MultiPoint + >>> p1 = cuspatial.GeoSeries([MultiPoint([Point(0, 0)])]) + >>> p2 = cuspatial.GeoSeries([MultiPoint([Point(0, 0)])]) + >>> cuspatial.pairwise_multipoint_equals_count(p1, p2) + 0 1 + dtype: uint32 + + >>> p1 = cuspatial.GeoSeries([MultiPoint([Point(0, 0)])]) + >>> p2 = cuspatial.GeoSeries([MultiPoint([Point(1, 1)])]) + >>> cuspatial.pairwise_multipoint_equals_count(p1, p2) + 0 0 + dtype: uint32 + + >>> p1 = cuspatial.GeoSeries( + ... [ + ... MultiPoint([Point(0, 0)]), + ... MultiPoint([Point(3, 3)]), + ... MultiPoint([Point(2, 2)]), + ... ] + ... ) + >>> p2 = cuspatial.GeoSeries( + ... [ + ... MultiPoint([Point(2, 2), Point(0, 0), Point(1, 1)]), + ... MultiPoint([Point(0, 0), Point(1, 1), Point(2, 2)]), + ... MultiPoint([Point(1, 1), Point(2, 2), Point(0, 0)]), + ... ] + ... ) + >>> cuspatial.pairwise_multipoint_equals_count(p1, p2) + 0 1 + 1 0 + 2 1 + dtype: uint32 + + Returns + ------- + count : cudf.Series + A Series of the number of points in each multipoint in the lhs that + are equal to points in the corresponding multipoint in the rhs. + """ + if len(lhs) == 0: + return cudf.Series([]) + + if any(not contains_only_multipoints(s) for s in [lhs, rhs]): + raise ValueError("Input GeoSeries must contain only multipoints.") + + lhs_column = lhs._column.mpoints._column + rhs_column = rhs._column.mpoints._column + result = c_pairwise_multipoint_equals_count(lhs_column, rhs_column) + + return cudf.Series(result) diff --git a/python/cuspatial/cuspatial/tests/binops/test_equals_count.py b/python/cuspatial/cuspatial/tests/binops/test_equals_count.py new file mode 100644 index 000000000..120cf0f21 --- /dev/null +++ b/python/cuspatial/cuspatial/tests/binops/test_equals_count.py @@ -0,0 +1,123 @@ +from pandas.testing import assert_series_equal +from shapely.geometry import MultiPoint, Point + +import cudf + +import cuspatial +from cuspatial.core.binops.equals_count import pairwise_multipoint_equals_count + + +def test_pairwise_multipoint_equals_count_example_1(): + p1 = cuspatial.GeoSeries([MultiPoint([Point(0, 0)])]) + p2 = cuspatial.GeoSeries([MultiPoint([Point(0, 0)])]) + got = pairwise_multipoint_equals_count(p1, p2) + expected = cudf.Series([1], dtype="uint32") + assert_series_equal(got.to_pandas(), expected.to_pandas()) + + +def test_pairwise_multipoint_equals_count_example_2(): + p1 = cuspatial.GeoSeries([MultiPoint([Point(0, 0)])]) + p2 = cuspatial.GeoSeries([MultiPoint([Point(1, 1)])]) + got = pairwise_multipoint_equals_count(p1, p2) + expected = cudf.Series([0], dtype="uint32") + assert_series_equal(got.to_pandas(), expected.to_pandas()) + + +def test_pairwise_multipoint_equals_count_example_3(): + p1 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0)]), + MultiPoint([Point(3, 3)]), + MultiPoint([Point(2, 2)]), + ] + ) + p2 = cuspatial.GeoSeries( + [ + MultiPoint([Point(2, 2), Point(0, 0), Point(1, 1)]), + MultiPoint([Point(0, 0), Point(1, 1), Point(2, 2)]), + MultiPoint([Point(1, 1), Point(2, 2), Point(0, 0)]), + ] + ) + got = pairwise_multipoint_equals_count(p1, p2) + expected = cudf.Series([1, 0, 1], dtype="uint32") + assert_series_equal(got.to_pandas(), expected.to_pandas()) + + +def test_pairwise_multipoint_equals_count_three_match_two_mismatch(): + p1 = cuspatial.GeoSeries( + [ + MultiPoint([Point(3, 3)]), + MultiPoint([Point(0, 0)]), + MultiPoint([Point(3, 3)]), + ] + ) + p2 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0), Point(1, 1), Point(2, 2)]), + MultiPoint([Point(0, 0), Point(1, 1), Point(2, 2)]), + MultiPoint([Point(0, 0), Point(1, 1), Point(2, 2)]), + ] + ) + got = pairwise_multipoint_equals_count(p1, p2) + expected = cudf.Series([0, 1, 0], dtype="uint32") + assert_series_equal(got.to_pandas(), expected.to_pandas()) + + +def test_pairwise_multipoint_equals_count_five(): + p1 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0)]), + MultiPoint([Point(1, 1)]), + MultiPoint([Point(2, 2)]), + MultiPoint([Point(3, 3)]), + MultiPoint([Point(4, 4)]), + ] + ) + p2 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0)]), + MultiPoint([Point(0, 0)]), + MultiPoint([Point(2, 2)]), + MultiPoint([Point(2, 2)]), + MultiPoint([Point(3, 3)]), + ] + ) + got = pairwise_multipoint_equals_count(p1, p2) + expected = cudf.Series([1, 0, 1, 0, 0], dtype="uint32") + assert_series_equal(got.to_pandas(), expected.to_pandas()) + + +def test_pairwise_multipoint_equals_two_and_three(): + p1 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0), Point(1, 1), Point(1, 1)]), + MultiPoint([Point(0, 0), Point(1, 1), Point(1, 1)]), + ] + ) + p2 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0), Point(1, 1), Point(2, 2)]), + MultiPoint([Point(0, 0), Point(1, 1), Point(2, 2)]), + ] + ) + got = pairwise_multipoint_equals_count(p1, p2) + expected = cudf.Series([3, 3], dtype="uint32") + assert_series_equal(got.to_pandas(), expected.to_pandas()) + + +def test_pairwise_multipoint_equals_two_and_three_one_match(): + p1 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0), Point(1, 1), Point(1, 1)]), + MultiPoint([Point(0, 0), Point(1, 1), Point(1, 1)]), + ] + ) + p2 = cuspatial.GeoSeries( + [ + MultiPoint([Point(0, 0), Point(2, 2), Point(2, 2)]), + MultiPoint([Point(2, 2), Point(2, 2), Point(0, 0)]), + ] + ) + got = pairwise_multipoint_equals_count(p1, p2) + expected = cudf.Series([1, 1], dtype="uint32") + assert_series_equal(got.to_pandas(), expected.to_pandas()) From 021c1f2635fbcba9225e8f5e05c46b881c78fc90 Mon Sep 17 00:00:00 2001 From: Ashwin Srinath <3190405+shwina@users.noreply.github.com> Date: Mon, 1 May 2023 10:29:47 -0400 Subject: [PATCH 07/63] Revert to branch-23.06 for shared-action-workflows (#1107) Authors: - Ashwin Srinath (https://github.com/shwina) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1107 --- .github/workflows/build.yaml | 8 ++++---- .github/workflows/pr.yaml | 16 ++++++++-------- .github/workflows/test.yaml | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 71167e635..25a77b783 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ concurrency: jobs: cpp-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.06 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -37,7 +37,7 @@ jobs: python-build: needs: [cpp-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.06 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -46,7 +46,7 @@ jobs: upload-conda: needs: [cpp-build, python-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@branch-23.06 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -56,7 +56,7 @@ jobs: if: github.ref_type == 'branch' && github.event_name == 'push' needs: python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.06 with: build_type: branch node_type: "gpu-v100-latest-1" diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 7dac4b254..7e14bc978 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -20,40 +20,40 @@ jobs: - conda-notebook-tests - docs-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.06 checks: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@branch-23.06 with: enable_check_generated_files: false conda-cpp-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.06 with: build_type: pull-request conda-cpp-tests: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.06 with: build_type: pull-request conda-python-build: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.06 with: build_type: pull-request conda-python-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.06 with: build_type: pull-request conda-notebook-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.06 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -63,7 +63,7 @@ jobs: docs-build: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.06 with: build_type: pull-request node_type: "gpu-v100-latest-1" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 137f47496..eb3cb4d94 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,7 +16,7 @@ on: jobs: conda-cpp-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.06 with: build_type: nightly branch: ${{ inputs.branch }} @@ -24,7 +24,7 @@ jobs: sha: ${{ inputs.sha }} conda-python-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@py-39 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.06 with: build_type: nightly branch: ${{ inputs.branch }} From 50c579adef0f41a6b2814313062b29592db771f5 Mon Sep 17 00:00:00 2001 From: Jake Awe <50372925+AyodeAwe@users.noreply.github.com> Date: Mon, 1 May 2023 12:52:15 -0500 Subject: [PATCH 08/63] Enable sccache hits from local builds (#1109) This change passes through the value of `SCCACHE_S3_NO_CREDENTIALS` to our `conda` builds, enabling devs to utilize the `sccache` cache that's populated by CI when they are reproducing build issues locally as per [these](https://docs.rapids.ai/resources/reproducing-ci/) instructions. Authors: - Jake Awe (https://github.com/AyodeAwe) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1109 --- conda/recipes/cuspatial/meta.yaml | 1 + conda/recipes/libcuspatial/meta.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/conda/recipes/cuspatial/meta.yaml b/conda/recipes/cuspatial/meta.yaml index 8a1a05050..d39ace7f7 100644 --- a/conda/recipes/cuspatial/meta.yaml +++ b/conda/recipes/cuspatial/meta.yaml @@ -31,6 +31,7 @@ build: - SCCACHE_S3_KEY_PREFIX=cuspatial-aarch64 # [aarch64] - SCCACHE_S3_KEY_PREFIX=cuspatial-linux64 # [linux64] - SCCACHE_S3_USE_SSL + - SCCACHE_S3_NO_CREDENTIALS ignore_run_exports_from: - {{ compiler('cuda') }} diff --git a/conda/recipes/libcuspatial/meta.yaml b/conda/recipes/libcuspatial/meta.yaml index 672e1012a..f43882c9d 100644 --- a/conda/recipes/libcuspatial/meta.yaml +++ b/conda/recipes/libcuspatial/meta.yaml @@ -29,6 +29,7 @@ build: - SCCACHE_S3_KEY_PREFIX=libcuspatial-aarch64 # [aarch64] - SCCACHE_S3_KEY_PREFIX=libcuspatial-linux64 # [linux64] - SCCACHE_S3_USE_SSL + - SCCACHE_S3_NO_CREDENTIALS requirements: build: From c713325f2bec667d4ab7d71752f08f8afaef89e6 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 1 May 2023 14:31:16 -0700 Subject: [PATCH 09/63] Pin cuml dependency in notebook testing environment to nightlies (#1110) This PR pins cuml dependency in notebook testing environment to nightlies as required in the CI environment. Authors: - Michael Wang (https://github.com/isVoid) - AJ Schmidt (https://github.com/ajschmidt8) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1110 --- ci/release/update-version.sh | 18 ++++++++++-------- .../environments/all_cuda-118_arch-x86_64.yaml | 10 +++++----- dependencies.yaml | 10 +++++----- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 120018bfe..cae29e22e 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -41,14 +41,6 @@ sed_runner 's/release = .*/release = '"'${NEXT_FULL_TAG}'"'/g' docs/source/conf. sed_runner 's/'"branch-.*\/RAPIDS.cmake"'/'"branch-${NEXT_SHORT_TAG}\/RAPIDS.cmake"'/g' fetch_rapids.cmake sed_runner 's/'"branch-.*\/RAPIDS.cmake"'/'"branch-${NEXT_SHORT_TAG}\/RAPIDS.cmake"'/g' python/cuspatial/CMakeLists.txt -# bump cudf -for FILE in dependencies.yaml conda/environments/*.yaml; do - sed_runner "s/cudf=${CURRENT_SHORT_TAG}/cudf=${NEXT_SHORT_TAG}/g" ${FILE}; - sed_runner "s/rmm=${CURRENT_SHORT_TAG}/rmm=${NEXT_SHORT_TAG}/g" ${FILE}; - sed_runner "s/libcudf=${CURRENT_SHORT_TAG}/libcudf=${NEXT_SHORT_TAG}/g" ${FILE}; - sed_runner "s/librmm=${CURRENT_SHORT_TAG}/librmm=${NEXT_SHORT_TAG}/g" ${FILE}; -done - # Doxyfile update sed_runner "/PROJECT_NUMBER[ ]*=/ s|=.*|= ${NEXT_FULL_TAG}|g" cpp/doxygen/Doxyfile sed_runner "/TAGFILES/ s|[0-9]\+.[0-9]\+|${NEXT_SHORT_TAG}|g" cpp/doxygen/Doxyfile @@ -62,6 +54,16 @@ sed_runner "s/VERSION_NUMBER=\".*/VERSION_NUMBER=\"${NEXT_SHORT_TAG}\"/g" ci/bui # Need to distutils-normalize the original version NEXT_SHORT_TAG_PEP440=$(python -c "from setuptools.extern import packaging; print(packaging.version.Version('${NEXT_SHORT_TAG}'))") +# bump rapids libraries +for FILE in dependencies.yaml conda/environments/*.yaml; do + sed_runner "/- &cudf_conda cudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/- cudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/- cuml==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/- rmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/- libcudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/- librmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} +done + # Dependency versions in dependencies.yaml sed_runner "/-cu[0-9]\{2\}==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}.*/g" dependencies.yaml diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 71950145f..a428c0b6d 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -9,8 +9,8 @@ dependencies: - c-compiler - cmake>=3.23.1,!=3.25.0 - cudatoolkit=11.8 -- cudf=23.06 -- cuml +- cudf==23.6.* +- cuml==23.6.* - cxx-compiler - cython>=0.29,<0.30 - doxygen @@ -20,8 +20,8 @@ dependencies: - gtest=1.10.0 - ipython - ipywidgets -- libcudf=23.06 -- librmm=23.06 +- libcudf==23.6.* +- librmm==23.6.* - myst-parser - nbsphinx - ninja @@ -35,7 +35,7 @@ dependencies: - pytest-cov - pytest-xdist - python>=3.9,<3.11 -- rmm=23.06 +- rmm==23.6.* - scikit-build>=0.13.1 - scikit-image - setuptools diff --git a/dependencies.yaml b/dependencies.yaml index 6b79c0959..f078c3716 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -56,8 +56,8 @@ dependencies: - cxx-compiler - gmock=1.10.0 - gtest=1.10.0 - - libcudf=23.06 - - librmm=23.06 + - libcudf==23.6.* + - librmm==23.6.* - ninja specific: - output_types: conda @@ -94,7 +94,7 @@ dependencies: - setuptools - output_types: conda packages: - - &cudf_conda cudf=23.06 + - &cudf_conda cudf==23.6.* specific: - output_types: conda matrices: @@ -170,7 +170,7 @@ dependencies: common: - output_types: [conda, requirements] packages: - - cuml + - cuml==23.6.* - ipython - ipywidgets - notebook @@ -200,7 +200,7 @@ dependencies: - output_types: conda packages: - *cudf_conda - - rmm=23.06 + - rmm==23.6.* specific: - output_types: requirements matrices: From 8c6698856669eb09931ba3d97f1d0473a759119d Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 1 May 2023 17:31:53 -0700 Subject: [PATCH 10/63] Fix a bug in point-in-polygon kernel: if the point is collinear with an edge, result is asserted false (#1108) Fixes #1103, current algorithm tests if the test point is collinear with an edge of the polygon, the point is asserted to be on the edge. This is not true, because for a point to be on the edge, the point also needs to be within the range where the edge covers. Collinearity test only test if the point is covered by the line that the edge coincides. This PR fixes this bug by adding additional tests to guarantee that the point is on an edge iff the point is collinear with the line where the edge coincides as well as the x coordinate of the point is within the closed range of the edge's x coordinates. This PR also fixes an additional bug where the col-linearity flag is not reset after each iteration of a ring. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1108 --- .../detail/algorithm/is_point_in_polygon.cuh | 34 +++++++++--------- .../point_in_polygon/point_in_polygon_test.cu | 35 +++++++++++++++++++ 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh b/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh index ef40f714f..51258e05f 100644 --- a/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh +++ b/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh @@ -23,6 +23,8 @@ #include #include +#include + namespace cuspatial { namespace detail { @@ -39,24 +41,12 @@ namespace detail { * @param polygon polygon to test for point in polygon * @return boolean to indicate if point is inside the polygon. * `false` if point is on the edge of the polygon. - * - * @tparam T type of coordinate - * @tparam PolygonRef polygon_ref type - * @param test_point point to test for point in polygon - * @param polygon polygon to test for point in polygon - * @return boolean to indicate if point is inside the polygon. - * `false` if point is on the edge of the polygon. - * - * TODO: the ultimate goal of refactoring this as independent function is to remove - * src/utility/point_in_polygon.cuh and its usage in quadtree_point_in_polygon.cu. It isn't - * possible today without further work to refactor quadtree_point_in_polygon into header only - * API. */ template __device__ inline bool is_point_in_polygon(vec_2d const& test_point, PolygonRef const& polygon) { bool point_is_within = false; - bool is_colinear = false; + bool point_on_edge = false; for (auto ring : polygon) { auto last_segment = ring.segment(ring.num_segments() - 1); @@ -75,11 +65,19 @@ __device__ inline bool is_point_in_polygon(vec_2d const& test_point, PolygonR if (float_equal(run, zero) && float_equal(rise, zero)) continue; T rise_to_point = test_point.y - a.y; + T run_to_point = test_point.x - a.x; - // colinearity test - T run_to_point = test_point.x - a.x; - is_colinear = float_equal(run * rise_to_point, run_to_point * rise); - if (is_colinear) { break; } + // point-on-edge test + bool is_colinear = float_equal(run * rise_to_point, run_to_point * rise); + if (is_colinear) { + T minx = a.x; + T maxx = b.x; + if (minx > maxx) thrust::swap(minx, maxx); + if (minx <= test_point.x && test_point.x <= maxx) { + point_on_edge = true; + break; + } + } y1_flag = a.y > test_point.y; if (y1_flag != y0_flag) { @@ -92,7 +90,7 @@ __device__ inline bool is_point_in_polygon(vec_2d const& test_point, PolygonR b = a; y0_flag = y1_flag; } - if (is_colinear) { + if (point_on_edge) { point_is_within = false; break; } diff --git a/cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cu b/cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cu index cd85f11f6..d958a9a97 100644 --- a/cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cu +++ b/cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cu @@ -14,11 +14,15 @@ * limitations under the License. */ +#include +#include + #include #include #include #include +#include #include #include @@ -374,3 +378,34 @@ TYPED_TEST(PointInPolygonTest, SelfClosingLoopRightEdgeMissing) EXPECT_EQ(expected, got); EXPECT_EQ(got.end(), ret); } + +TYPED_TEST(PointInPolygonTest, ContainsButCollinearWithBoundary) +{ + using T = TypeParam; + + auto point = cuspatial::test::make_multipoints_array({{{0.5, 0.5}}}); + auto polygon = cuspatial::test::make_multipolygon_array( + {0, 1}, + {0, 1}, + {0, 9}, + {{0, 0}, {0, 1}, {1, 1}, {1, 0.5}, {1.5, 0.5}, {1.5, 1}, {2, 1}, {2, 0}, {0, 0}}); + + auto point_range = point.range(); + auto polygon_range = polygon.range(); + + auto res = rmm::device_uvector(1, rmm::cuda_stream_default); + + cuspatial::point_in_polygon(point_range.point_begin(), + point_range.point_end(), + polygon_range.part_offset_begin(), + polygon_range.part_offset_end(), + polygon_range.ring_offset_begin(), + polygon_range.ring_offset_end(), + polygon_range.point_begin(), + polygon_range.point_end(), + res.begin()); + + auto expect = cuspatial::test::make_device_vector({0b1}); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(res, expect); +} From 2d020731ca9a5b98fc484a374b52562d65397f6a Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 1 May 2023 17:32:35 -0700 Subject: [PATCH 11/63] Column API for `pairwise_polygon_distance` (#1073) This PR adds column API for `pairwise_polygon_distance`. This PR also adds `CUSPATIAL_HOST_DEVICE_EXPECTS` macro to help error assertion in `__host__ __device__` functions. closes #1053 depends on #1065 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - H. Thomson Comer (https://github.com/thomcom) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1073 --- cpp/CMakeLists.txt | 1 + cpp/include/cuspatial/assert.cuh | 35 ++++ .../cuspatial/detail/utility/validation.hpp | 43 ++--- .../cuspatial/distance/polygon_distance.hpp | 44 ++++++ cpp/include/cuspatial/error.hpp | 29 +++- .../cuspatial/range/multilinestring_range.cuh | 12 +- cpp/src/spatial/polygon_distance.cu | 113 +++++++++++++ cpp/tests/CMakeLists.txt | 9 +- .../linestring_polygon_distance_test.cpp | 0 .../distance/polygon_distance_test.cpp | 149 ++++++++++++++++++ 10 files changed, 404 insertions(+), 31 deletions(-) create mode 100644 cpp/include/cuspatial/assert.cuh create mode 100644 cpp/include/cuspatial/distance/polygon_distance.hpp create mode 100644 cpp/src/spatial/polygon_distance.cu rename cpp/tests/spatial/{ => distance}/linestring_polygon_distance_test.cpp (100%) create mode 100644 cpp/tests/spatial/distance/polygon_distance_test.cpp diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 7a5b8acae..b13d53cfc 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -136,6 +136,7 @@ add_library(cuspatial src/spatial/point_linestring_distance.cu src/spatial/point_polygon_distance.cu src/spatial/linestring_polygon_distance.cu + src/spatial/polygon_distance.cu src/spatial/point_linestring_nearest_points.cu src/spatial/sinusoidal_projection.cu src/trajectory/derive_trajectories.cu diff --git a/cpp/include/cuspatial/assert.cuh b/cpp/include/cuspatial/assert.cuh new file mode 100644 index 000000000..c5e13d6f4 --- /dev/null +++ b/cpp/include/cuspatial/assert.cuh @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +/** + * @brief `assert`-like macro for device code + * + * This is effectively the same as the standard `assert` macro, except it + * relies on the `__PRETTY_FUNCTION__` macro which is specific to GCC and Clang + * to produce better assert messages. + */ +#if !defined(NDEBUG) && defined(__CUDA_ARCH__) && (defined(__clang__) || defined(__GNUC__)) +#define __ASSERT_STR_HELPER(x) #x +#define cuspatial_assert(e) \ + ((e) ? static_cast(0) \ + : __assert_fail(__ASSERT_STR_HELPER(e), __FILE__, __LINE__, __PRETTY_FUNCTION__)) +#else +#define cuspatial_assert(e) (static_cast(0)) +#endif diff --git a/cpp/include/cuspatial/detail/utility/validation.hpp b/cpp/include/cuspatial/detail/utility/validation.hpp index 7fe5742ea..1a4bd2001 100644 --- a/cpp/include/cuspatial/detail/utility/validation.hpp +++ b/cpp/include/cuspatial/detail/utility/validation.hpp @@ -35,10 +35,10 @@ * [2]: https://arrow.apache.org/docs/format/Columnar.html#variable-size-binary-layout */ #define CUSPATIAL_EXPECTS_VALID_LINESTRING_SIZES(num_linestring_points, num_linestring_offsets) \ - CUSPATIAL_EXPECTS(num_linestring_offsets > 0, \ - "Polygon offsets must contain at least one (1) value"); \ - CUSPATIAL_EXPECTS(num_linestring_points >= 2 * (num_linestring_offsets - 1), \ - "Each linestring must have at least two vertices"); + CUSPATIAL_HOST_DEVICE_EXPECTS(num_linestring_offsets > 0, \ + "Polygon offsets must contain at least one (1) value"); \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_linestring_points >= 2 * (num_linestring_offsets - 1), \ + "Each linestring must have at least two vertices"); /** * @brief Macro for validating the data array sizes for multilinestrings. @@ -57,10 +57,10 @@ * [1]: https://github.com/geoarrow/geoarrow/blob/main/format.md * [2]: https://arrow.apache.org/docs/format/Columnar.html#variable-size-binary-layout */ -#define CUSPATIAL_EXPECTS_VALID_MULTILINESTRING_SIZES( \ - num_linestring_points, num_multilinestring_offsets, num_linestring_offsets) \ - CUSPATIAL_EXPECTS(num_multilinestring_offsets > 0, \ - "Multilinestring offsets must contain at least one (1) value"); \ +#define CUSPATIAL_EXPECTS_VALID_MULTILINESTRING_SIZES( \ + num_linestring_points, num_multilinestring_offsets, num_linestring_offsets) \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_multilinestring_offsets > 0, \ + "Multilinestring offsets must contain at least one (1) value"); \ CUSPATIAL_EXPECTS_VALID_LINESTRING_SIZES(num_linestring_points, num_linestring_offsets); /** @@ -84,15 +84,16 @@ * [1]: https://github.com/geoarrow/geoarrow/blob/main/format.md * [2]: https://arrow.apache.org/docs/format/Columnar.html#variable-size-binary-layout */ -#define CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( \ - num_poly_points, num_poly_offsets, num_poly_ring_offsets) \ - CUSPATIAL_EXPECTS(num_poly_offsets > 0, "Polygon offsets must contain at least one (1) value"); \ - CUSPATIAL_EXPECTS(num_poly_ring_offsets > 0, \ - "Polygon ring offsets must contain at least one (1) value"); \ - CUSPATIAL_EXPECTS(num_poly_ring_offsets >= num_poly_offsets, \ - "Each polygon must have at least one (1) ring"); \ - CUSPATIAL_EXPECTS(num_poly_points >= 4 * (num_poly_ring_offsets - 1), \ - "Each ring must have at least four (4) vertices"); +#define CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( \ + num_poly_points, num_poly_offsets, num_poly_ring_offsets) \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_offsets > 0, \ + "Polygon offsets must contain at least one (1) value"); \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_ring_offsets > 0, \ + "Polygon ring offsets must contain at least one (1) value"); \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_ring_offsets >= num_poly_offsets, \ + "Each polygon must have at least one (1) ring"); \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_points >= 4 * (num_poly_ring_offsets - 1), \ + "Each ring must have at least four (4) vertices"); /** * @brief Macro for validating the data array sizes for a multipolygon. @@ -116,8 +117,8 @@ * [1]: https://github.com/geoarrow/geoarrow/blob/main/format.md * [2]: https://arrow.apache.org/docs/format/Columnar.html#variable-size-binary-layout */ -#define CUSPATIAL_EXPECTS_VALID_MULTIPOLYGON_SIZES( \ - num_poly_points, num_multipoly_offsets, num_poly_offsets, num_poly_ring_offsets) \ - CUSPATIAL_EXPECTS(num_multipoly_offsets > 0, \ - "Multipolygon offsets must contain at least one (1) value"); \ +#define CUSPATIAL_EXPECTS_VALID_MULTIPOLYGON_SIZES( \ + num_poly_points, num_multipoly_offsets, num_poly_offsets, num_poly_ring_offsets) \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_multipoly_offsets > 0, \ + "Multipolygon offsets must contain at least one (1) value"); \ CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES(num_poly_points, num_poly_offsets, num_poly_ring_offsets); diff --git a/cpp/include/cuspatial/distance/polygon_distance.hpp b/cpp/include/cuspatial/distance/polygon_distance.hpp new file mode 100644 index 000000000..4b1a291c9 --- /dev/null +++ b/cpp/include/cuspatial/distance/polygon_distance.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include + +#include + +#include + +#include + +namespace cuspatial { + +/** + * @brief Compute pairwise (multi)polygon-to-(multi)polygon Cartesian distance + * + * Computes the cartesian distance between each pair of the multipolygons. + * + * @param lhs Geometry column of the multipolygons to compute distance from + * @param rhs Geometry column of the multipolygons to compute distance to + * @param mr Device memory resource used to allocate the returned column. + * + * @return Column of distances between each pair of input geometries, same type as input coordinate + * types. + */ +std::unique_ptr pairwise_polygon_distance( + geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/error.hpp b/cpp/include/cuspatial/error.hpp index b1190c8ac..d2973349f 100644 --- a/cpp/include/cuspatial/error.hpp +++ b/cpp/include/cuspatial/error.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ #pragma once +#include + #include #include @@ -76,6 +78,31 @@ struct cuda_error : public std::runtime_error { : throw cuspatial::logic_error("cuSpatial failure at: " __FILE__ \ ":" CUSPATIAL_STRINGIFY(__LINE__) ": " reason) +/**---------------------------------------------------------------------------* + * @brief Macro for checking (pre-)conditions that throws an exception when + * a condition is violated. + * + * Example usage: + * + * @code + * CUSPATIAL_HOST_DEVICE_EXPECTS(lhs->dtype == rhs->dtype, "Column type mismatch"); + * @endcode + * + * @param[in] cond Expression that evaluates to true or false + * @param[in] reason String literal description of the reason that cond is + * expected to be true + * + * (if on host) + * @throw cuspatial::logic_error if the condition evaluates to false. + * (if on device) + * program terminates and assertion error message is printed to stderr. + *---------------------------------------------------------------------------**/ +#ifndef __CUDA_ARCH__ +#define CUSPATIAL_HOST_DEVICE_EXPECTS(cond, reason) CUSPATIAL_EXPECTS(cond, reason) +#else +#define CUSPATIAL_HOST_DEVICE_EXPECTS(cond, reason) cuspatial_assert(cond&& reason) +#endif + /**---------------------------------------------------------------------------* * @brief Indicates that an erroneous code path has been taken. * diff --git a/cpp/include/cuspatial/range/multilinestring_range.cuh b/cpp/include/cuspatial/range/multilinestring_range.cuh index 04c280e04..18a30a2bf 100644 --- a/cpp/include/cuspatial/range/multilinestring_range.cuh +++ b/cpp/include/cuspatial/range/multilinestring_range.cuh @@ -59,12 +59,12 @@ class multilinestring_range { using point_t = iterator_value_type; using element_t = iterator_vec_base_type; - multilinestring_range(GeometryIterator geometry_begin, - GeometryIterator geometry_end, - PartIterator part_begin, - PartIterator part_end, - VecIterator points_begin, - VecIterator points_end); + CUSPATIAL_HOST_DEVICE multilinestring_range(GeometryIterator geometry_begin, + GeometryIterator geometry_end, + PartIterator part_begin, + PartIterator part_end, + VecIterator points_begin, + VecIterator points_end); /// Return the number of multilinestrings in the array. CUSPATIAL_HOST_DEVICE auto size() { return num_multilinestrings(); } diff --git a/cpp/src/spatial/polygon_distance.cu b/cpp/src/spatial/polygon_distance.cu new file mode 100644 index 000000000..8d3192e13 --- /dev/null +++ b/cpp/src/spatial/polygon_distance.cu @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include "../utility/iterator.hpp" +#include "../utility/multi_geometry_dispatch.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace cuspatial { + +namespace detail { + +namespace { + +template +struct pairwise_polygon_distance_impl { + using SizeType = cudf::device_span::size_type; + + template )> + std::unique_ptr operator()(geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) + { + auto lhs_range = make_multipolygon_range(lhs); + auto rhs_range = make_multipolygon_range(rhs); + + auto output = cudf::make_numeric_column( + lhs.coordinate_type(), lhs.size(), cudf::mask_state::UNALLOCATED, stream, mr); + + cuspatial::pairwise_polygon_distance( + lhs_range, rhs_range, output->mutable_view().begin(), stream); + return output; + } + + template ), typename... Args> + std::unique_ptr operator()(Args&&...) + + { + CUSPATIAL_FAIL("polygon distance API only supports floating point coordinates."); + } +}; + +} // namespace + +template +struct pairwise_polygon_distance { + std::unique_ptr operator()(geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) + { + return cudf::type_dispatcher( + lhs.coordinate_type(), + pairwise_polygon_distance_impl{}, + lhs, + rhs, + stream, + mr); + } +}; + +} // namespace detail + +std::unique_ptr pairwise_polygon_distance(geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::mr::device_memory_resource* mr) +{ + CUSPATIAL_EXPECTS(lhs.geometry_type() == geometry_type_id::POLYGON && + rhs.geometry_type() == geometry_type_id::POLYGON, + "Unexpected input geometry types."); + + CUSPATIAL_EXPECTS(lhs.coordinate_type() == rhs.coordinate_type(), + "Input geometries must have the same coordinate data types."); + + return multi_geometry_double_dispatch( + lhs.collection_type(), rhs.collection_type(), lhs, rhs, rmm::cuda_stream_default, mr); +} + +} // namespace cuspatial diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 3ec61c6ce..4f9533537 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -89,12 +89,15 @@ ConfigureTest(POINT_LINESTRING_DISTANCE_TEST ConfigureTest(LINESTRING_DISTANCE_TEST spatial/distance/linestring_distance_test.cpp) -ConfigureTest(LINESTRING_POLYGON_DISTANCE_TEST - spatial/linestring_polygon_distance_test.cpp) - ConfigureTest(POINT_POLYGON_DISTANCE_TEST spatial/distance/point_polygon_distance_test.cpp) +ConfigureTest(LINESTRING_POLYGON_DISTANCE_TEST + spatial/distance/linestring_polygon_distance_test.cpp) + +ConfigureTest(POLYGON_DISTANCE_TEST + spatial/distance/polygon_distance_test.cpp) + # equality ConfigureTest(PAIRWISE_MULTIPOINT_EQUALS_COUNT_TEST spatial/equality/pairwise_multipoint_equals_count_test.cpp) diff --git a/cpp/tests/spatial/linestring_polygon_distance_test.cpp b/cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp similarity index 100% rename from cpp/tests/spatial/linestring_polygon_distance_test.cpp rename to cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp diff --git a/cpp/tests/spatial/distance/polygon_distance_test.cpp b/cpp/tests/spatial/distance/polygon_distance_test.cpp new file mode 100644 index 000000000..1bea37f43 --- /dev/null +++ b/cpp/tests/spatial/distance/polygon_distance_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include + +using namespace cuspatial; +using namespace cuspatial::test; + +using namespace cudf; +using namespace cudf::test; + +template +struct PairwisePolygonDistanceTestBase : ::testing::Test { + void run_single(geometry_column_view lhs, + geometry_column_view rhs, + std::initializer_list expected) + { + auto got = pairwise_polygon_distance(lhs, rhs); + CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(*got, fixed_width_column_wrapper(expected)); + } + rmm::cuda_stream_view stream() { return cudf::get_default_stream(); } +}; + +template +struct PairwisePolygonDistanceTestEmpty : PairwisePolygonDistanceTestBase { + void SetUp() + { + [[maybe_unused]] collection_type_id _; + std::tie(_, empty_polygon_column) = make_polygon_column({0}, {0}, {}, this->stream()); + std::tie(_, empty_multipolygon_column) = + make_polygon_column({0}, {0}, {0}, {}, this->stream()); + } + + geometry_column_view empty_polygon() + { + return geometry_column_view( + empty_polygon_column->view(), collection_type_id::SINGLE, geometry_type_id::POLYGON); + } + + geometry_column_view empty_multipolygon() + { + return geometry_column_view( + empty_multipolygon_column->view(), collection_type_id::MULTI, geometry_type_id::POLYGON); + } + + std::unique_ptr empty_polygon_column; + std::unique_ptr empty_multipolygon_column; +}; + +using TestTypes = ::testing::Types; +TYPED_TEST_CASE(PairwisePolygonDistanceTestEmpty, TestTypes); + +struct PairwisePolygonDistanceTestUntyped : testing::Test { + rmm::cuda_stream_view stream() { return cudf::get_default_stream(); } +}; +TYPED_TEST(PairwisePolygonDistanceTestEmpty, SingleToSingleEmpty) +{ + CUSPATIAL_RUN_TEST(this->run_single, this->empty_polygon(), this->empty_polygon(), {}); +}; + +TYPED_TEST(PairwisePolygonDistanceTestEmpty, SingleToMultiEmpty) +{ + CUSPATIAL_RUN_TEST(this->run_single, this->empty_polygon(), this->empty_multipolygon(), {}); +}; + +TYPED_TEST(PairwisePolygonDistanceTestEmpty, MultiToSingleEmpty) +{ + CUSPATIAL_RUN_TEST(this->run_single, this->empty_multipolygon(), this->empty_polygon(), {}); +}; + +TYPED_TEST(PairwisePolygonDistanceTestEmpty, MultiToMultiEmpty) +{ + CUSPATIAL_RUN_TEST(this->run_single, this->empty_multipolygon(), this->empty_multipolygon(), {}); +}; + +TEST_F(PairwisePolygonDistanceTestUntyped, SizeMismatch) +{ + auto [ptype, polygons1] = make_polygon_column( + {0, 1, 2}, {0, 4, 8}, {0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0}, this->stream()); + + auto [polytype, polygons2] = + make_polygon_column({0, 1}, {0, 1}, {0, 4}, {1, 1, 1, 2, 2, 2, 1, 1}, this->stream()); + + auto polygons1_view = + geometry_column_view(polygons1->view(), ptype, geometry_type_id::LINESTRING); + auto polygons2_view = + geometry_column_view(polygons1->view(), polytype, geometry_type_id::POLYGON); + + EXPECT_THROW(pairwise_polygon_distance(polygons1_view, polygons2_view), cuspatial::logic_error); +}; + +TEST_F(PairwisePolygonDistanceTestUntyped, TypeMismatch) +{ + auto [ptype, polygons1] = make_polygon_column( + {0, 1, 2}, {0, 4, 8}, {0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0}, this->stream()); + + auto [polytype, polygons2] = + make_polygon_column({0, 1}, {0, 1}, {0, 4}, {1, 1, 1, 2, 2, 2, 1, 1}, this->stream()); + + auto polygons1_view = + geometry_column_view(polygons1->view(), ptype, geometry_type_id::LINESTRING); + auto polygons2_view = + geometry_column_view(polygons2->view(), polytype, geometry_type_id::POLYGON); + + EXPECT_THROW(pairwise_polygon_distance(polygons1_view, polygons2_view), cuspatial::logic_error); +}; + +TEST_F(PairwisePolygonDistanceTestUntyped, WrongGeometryType) +{ + auto [ptype, points] = make_point_column({0, 1}, {0.0, 0.0}, this->stream()); + + auto [polytype, polygons] = + make_polygon_column({0, 1}, {0, 1}, {0, 4}, {1, 1, 1, 2, 2, 2, 1, 1}, this->stream()); + + auto points_view = geometry_column_view(points->view(), ptype, geometry_type_id::POINT); + auto polygons_view = geometry_column_view(polygons->view(), polytype, geometry_type_id::POLYGON); + + EXPECT_THROW(pairwise_polygon_distance(points_view, polygons_view), cuspatial::logic_error); +}; From 2509fce6be981353da18697ab3f14fc7ccd4fc05 Mon Sep 17 00:00:00 2001 From: Mark Harris <783069+harrism@users.noreply.github.com> Date: Wed, 3 May 2023 07:50:09 +1000 Subject: [PATCH 12/63] Reorganize cuSpatial headers (#1097) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/rapidsai/cuspatial/issues/1080 based on the discussion in #1087 - Consolidate each major set of features within common headers, e.g. `distance.hpp/.cuh`, `intersection.hpp/.cuh`. - Consolidate point-in-polygon APIs / headers and DRY up implementation - Rename some headers/APIS that were inconsistent across the header-only and column-based APIs, e.g. `points_in_spatial_window` vs. `points_in_range`. - Update Cython where needed to account for above changes. This PR does NOT yet reorganize source code. Update: Compilation Time Results --------------------------------------------- Compilation time is not changed appreciably by this PR (<0.5% faster). This test was performed by disabling `sccache`, erasing everything in the build directory, configuring cmake (including building tests and benchmarks), and then running `time ninja`. My machine has a "AMD Ryzen 7 3700X 8-Core Processor", and I'm using Ninja's default parallelism. #### Disabling `sccache` when using the cuSpatial devcontainer ``` (rapids) coder ➜ ~/cuspatial/ $ cd cpp/build/release (rapids) coder ➜ ~/cuspatial/cpp/build/release $ rm -rf ./* (rapids) coder ➜ ~/cuspatial/cpp/build/release $ unset RUSTC_WRAPPER (rapids) coder ➜ ~/cuspatial/cpp/build/release $ unset CMAKE_C_COMPILER_LAUNCHER (rapids) coder ➜ ~/cuspatial/cpp/build/release $ unset CMAKE_CXX_COMPILER_LAUNCHER (rapids) coder ➜ ~/cuspatial/cpp/build/release $ unset CMAKE_CUDA_COMPILER_LAUNCHER (rapids) coder ➜ ~/cuspatial/cpp/build/release $ cmake ~/cuspatial/cpp -GNinja -DBUILD_TESTS=ON -DBUILD_BENCHMARKS=ON (rapids) coder ➜ ~/cuspatial/cpp/build/release $ time ninja ``` ### This branch: ``` [201/201] Linking CXX executable gtests/LINESTRING_INTERSECTION_TEST_EXP real 10m42.845s user 122m28.077s sys 6m7.935s ``` ### `branch-23.06`: ``` [202/202] Linking CXX executable gtests/LINESTRING_INTERSECTION_TEST_EXP real 10m45.573s user 122m52.896s sys 6m9.357s ``` Authors: - Mark Harris (https://github.com/harrism) Approvers: - Michael Wang (https://github.com/isVoid) - Paul Taylor (https://github.com/trxcllnt) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1097 --- cpp/CMakeLists.txt | 7 +- cpp/benchmarks/hausdorff_benchmark.cpp | 4 +- .../pairwise_linestring_distance.cu | 5 +- cpp/benchmarks/points_in_range.cu | 2 +- cpp/doxygen/developer_guide/DOCUMENTATION.md | 5 +- cpp/include/cuspatial/bounding_box.cuh | 82 ---- cpp/include/cuspatial/bounding_boxes.cuh | 179 +++++++++ ...on_bounding_box.hpp => bounding_boxes.hpp} | 37 +- .../cuspatial/column/geometry_column_view.hpp | 3 +- cpp/include/cuspatial/detail/bounding_box.cuh | 90 ----- .../cuspatial/detail/bounding_boxes.cuh | 185 +++++++++ .../detail/{ => distance}/distance_utils.cuh | 2 + .../detail/{ => distance}/hausdorff.cuh | 0 .../detail/{ => distance}/haversine.cuh | 0 .../{ => distance}/linestring_distance.cuh | 0 .../linestring_polygon_distance.cuh | 0 .../detail/{ => distance}/point_distance.cuh | 0 .../point_linestring_distance.cuh | 0 .../{ => distance}/point_polygon_distance.cuh | 1 - .../{ => distance}/polygon_distance.cuh | 0 .../detail/find/find_points_on_segments.cuh | 2 +- .../detail/geometry/linestring_ref.cuh | 2 +- .../cuspatial/detail/geometry/polygon_ref.cuh | 2 +- .../multilinestring_ref.cuh | 2 +- .../geometry_collection/multipoint_ref.cuh | 2 +- .../geometry_collection/multipolygon_ref.cuh | 2 +- .../linestring_intersection.cuh | 6 +- .../linestring_intersection_count.cuh | 0 ...inestring_intersection_with_duplicates.cuh | 3 +- cpp/include/cuspatial/detail/iterator.hpp | 32 -- .../{ => join}/quadtree_bbox_filtering.cuh | 2 +- .../{ => join}/quadtree_point_in_polygon.cuh | 2 +- .../quadtree_point_to_nearest_linestring.cuh | 2 +- .../detail/linestring_bounding_boxes.cuh | 73 ---- .../detail/pairwise_point_in_polygon.cuh | 136 ------- .../cuspatial/detail/point_in_polygon.cuh | 120 +++++- .../detail/polygon_bounding_boxes.cuh | 86 ---- .../sinusoidal_projection.cuh | 2 +- .../detail/range/enumerate_range.cuh | 2 +- .../detail/range/multilinestring_range.cuh | 2 +- .../detail/range/multipoint_range.cuh | 2 +- .../detail/range/multipolygon_range.cuh | 2 +- .../{ => trajectory}/derive_trajectories.cuh | 0 .../trajectory_distances_and_speeds.cuh | 0 cpp/include/cuspatial/distance.cuh | 302 ++++++++++++++ cpp/include/cuspatial/distance.hpp | 369 ++++++++++++++++++ cpp/include/cuspatial/distance/hausdorff.hpp | 100 ----- cpp/include/cuspatial/distance/haversine.hpp | 56 --- .../distance/linestring_distance.hpp | 123 ------ .../distance/linestring_polygon_distance.hpp | 49 --- .../cuspatial/distance/point_distance.hpp | 46 --- .../distance/point_linestring_distance.hpp | 102 ----- .../distance/point_polygon_distance.hpp | 49 --- cpp/include/cuspatial/hausdorff.cuh | 105 ----- cpp/include/cuspatial/haversine.cuh | 79 ---- ...ring_intersection.cuh => intersection.cuh} | 4 +- ...ring_intersection.hpp => intersection.hpp} | 0 cpp/include/cuspatial/iterator_factory.cuh | 13 +- .../cuspatial/linestring_bounding_box.hpp | 55 --- .../cuspatial/linestring_bounding_boxes.cuh | 73 ---- cpp/include/cuspatial/linestring_distance.cuh | 50 --- .../cuspatial/linestring_polygon_distance.cuh | 48 --- ..._nearest_points.cuh => nearest_points.cuh} | 0 ..._nearest_points.hpp => nearest_points.hpp} | 11 +- .../cuspatial/pairwise_point_in_polygon.cuh | 112 ------ .../cuspatial/pairwise_point_in_polygon.hpp | 87 ----- cpp/include/cuspatial/point_distance.cuh | 41 -- cpp/include/cuspatial/point_in_polygon.cuh | 96 ++++- cpp/include/cuspatial/point_in_polygon.hpp | 49 +++ .../cuspatial/point_linestring_distance.cuh | 47 --- .../cuspatial/point_polygon_distance.cuh | 47 --- cpp/include/cuspatial/points_in_range.cuh | 12 +- ...spatial_window.hpp => points_in_range.hpp} | 44 ++- .../cuspatial/polygon_bounding_boxes.cuh | 82 ---- cpp/include/cuspatial/polygon_distance.cuh | 47 --- ...nusoidal_projection.cuh => projection.cuh} | 14 +- .../cuspatial/range/multilinestring_range.cuh | 13 +- .../cuspatial/range/multipoint_range.cuh | 13 +- .../cuspatial/range/multipolygon_range.cuh | 12 +- cpp/include/cuspatial/spatial_join.cuh | 8 +- ...derive_trajectories.cuh => trajectory.cuh} | 47 ++- .../trajectory_distances_and_speeds.cuh | 76 ---- cpp/include/doxygen_groups.h | 34 +- cpp/src/join/quadtree_bbox_filtering.cu | 2 +- cpp/src/spatial/hausdorff.cu | 4 +- cpp/src/spatial/haversine.cu | 4 +- ...ng_box.cu => linestring_bounding_boxes.cu} | 3 +- cpp/src/spatial/linestring_distance.cu | 4 +- cpp/src/spatial/linestring_intersection.cu | 5 +- .../spatial/linestring_polygon_distance.cu | 3 +- cpp/src/spatial/pairwise_point_in_polygon.cu | 153 -------- cpp/src/spatial/point_distance.cu | 4 +- cpp/src/spatial/point_in_polygon.cu | 90 +++-- cpp/src/spatial/point_linestring_distance.cu | 5 +- .../point_linestring_nearest_points.cu | 6 +- cpp/src/spatial/point_polygon_distance.cu | 3 +- .../points_in_range.cu} | 72 ++-- ...nding_box.cu => polygon_bounding_boxes.cu} | 2 +- cpp/src/spatial/polygon_distance.cu | 2 +- cpp/src/spatial/sinusoidal_projection.cu | 4 +- cpp/src/trajectory/derive_trajectories.cu | 2 +- .../trajectory/trajectory_bounding_boxes.cu | 2 +- .../trajectory_distances_and_speeds.cu | 2 +- cpp/tests/CMakeLists.txt | 4 +- .../join_quadtree_and_bounding_boxes_test.cpp | 2 +- .../join/quadtree_point_in_polygon_test.cpp | 2 +- .../quadtree_point_in_polygon_test_large.cu | 2 +- .../quadtree_point_in_polygon_test_small.cu | 2 +- ...dtree_point_to_nearest_linestring_test.cpp | 2 +- ..._point_to_nearest_linestring_test_small.cu | 2 +- .../projection/sinusoidal_projection_test.cu | 2 +- .../linestring_bounding_boxes_test.cpp | 2 +- .../linestring_bounding_boxes_test.cu | 2 +- .../point_bounding_boxes_test.cu | 4 +- .../polygon_bounding_boxes_test.cpp | 2 +- .../polygon_bounding_boxes_test.cu | 2 +- cpp/tests/spatial/distance/hausdorff_test.cpp | 7 +- cpp/tests/spatial/distance/hausdorff_test.cu | 2 +- cpp/tests/spatial/distance/haversine_test.cpp | 4 +- cpp/tests/spatial/distance/haversine_test.cu | 2 +- .../distance/linestring_distance_test.cpp | 4 +- .../distance/linestring_distance_test.cu | 4 +- .../linestring_distance_test_medium.cu | 4 +- .../linestring_polygon_distance_test.cpp | 2 +- .../linestring_polygon_distance_test.cu | 4 +- .../spatial/distance/point_distance_test.cpp | 4 +- .../spatial/distance/point_distance_test.cu | 3 +- .../point_linestring_distance_test.cpp | 4 +- .../point_linestring_distance_test.cu | 3 +- .../distance/point_polygon_distance_test.cpp | 2 +- .../distance/point_polygon_distance_test.cu | 4 +- .../spatial/distance/polygon_distance_test.cu | 4 +- .../pairwise_multipoint_equals_count_test.cu | 5 - .../linestring_intersection_count_test.cu | 4 +- ...tersection_intermediates_remove_if_test.cu | 2 +- .../linestring_intersection_test.cpp | 2 +- .../linestring_intersection_test.cu | 5 +- ...tring_intersection_with_duplicates_test.cu | 2 +- .../point_linestring_nearest_points_test.cpp | 4 +- .../point_linestring_nearest_points_test.cu | 3 +- .../pairwise_point_in_polygon_test.cpp | 2 +- .../pairwise_point_in_polygon_test.cu | 2 +- ...ndow_test.cpp => points_in_range_test.cpp} | 24 +- .../trajectory/derive_trajectories_test.cu | 4 +- .../trajectory_distances_and_speeds_test.cu | 4 +- .../cuspatial/cuspatial/_lib/CMakeLists.txt | 2 +- .../cuspatial/_lib/cpp/distance/hausdorff.pxd | 4 +- .../cuspatial/_lib/cpp/distance/haversine.pxd | 4 +- .../_lib/cpp/distance/linestring_distance.pxd | 4 +- .../distance/linestring_polygon_distance.pxd | 2 +- .../_lib/cpp/distance/point_distance.pxd | 4 +- .../distance/point_linestring_distance.pxd | 4 +- .../cpp/distance/point_polygon_distance.pxd | 2 +- ..._box.pxd => linestring_bounding_boxes.pxd} | 4 +- .../_lib/cpp/linestring_intersection.pxd | 2 +- ..._nearest_points.pxd => nearest_points.pxd} | 4 +- .../_lib/cpp/pairwise_point_in_polygon.pxd | 4 +- .../cuspatial/_lib/cpp/points_in_range.pxd | 18 + ...ing_box.pxd => polygon_bounding_boxes.pxd} | 4 +- .../cuspatial/_lib/cpp/projection.pxd | 2 +- .../cuspatial/_lib/cpp/spatial_window.pxd | 18 - .../_lib/linestring_bounding_boxes.pyx | 4 +- .../cuspatial/_lib/nearest_points.pyx | 6 +- ...spatial_window.pyx => points_in_range.pyx} | 26 +- .../cuspatial/_lib/polygon_bounding_boxes.pyx | 4 +- .../cuspatial/core/spatial/filtering.py | 6 +- 166 files changed, 1780 insertions(+), 2471 deletions(-) delete mode 100644 cpp/include/cuspatial/bounding_box.cuh create mode 100644 cpp/include/cuspatial/bounding_boxes.cuh rename cpp/include/cuspatial/{polygon_bounding_box.hpp => bounding_boxes.hpp} (63%) delete mode 100644 cpp/include/cuspatial/detail/bounding_box.cuh create mode 100644 cpp/include/cuspatial/detail/bounding_boxes.cuh rename cpp/include/cuspatial/detail/{ => distance}/distance_utils.cuh (99%) rename cpp/include/cuspatial/detail/{ => distance}/hausdorff.cuh (100%) rename cpp/include/cuspatial/detail/{ => distance}/haversine.cuh (100%) rename cpp/include/cuspatial/detail/{ => distance}/linestring_distance.cuh (100%) rename cpp/include/cuspatial/detail/{ => distance}/linestring_polygon_distance.cuh (100%) rename cpp/include/cuspatial/detail/{ => distance}/point_distance.cuh (100%) rename cpp/include/cuspatial/detail/{ => distance}/point_linestring_distance.cuh (100%) rename cpp/include/cuspatial/detail/{ => distance}/point_polygon_distance.cuh (99%) rename cpp/include/cuspatial/detail/{ => distance}/polygon_distance.cuh (100%) rename cpp/include/cuspatial/detail/{ => intersection}/linestring_intersection.cuh (98%) rename cpp/include/cuspatial/detail/{ => intersection}/linestring_intersection_count.cuh (100%) rename cpp/include/cuspatial/detail/{ => intersection}/linestring_intersection_with_duplicates.cuh (99%) delete mode 100644 cpp/include/cuspatial/detail/iterator.hpp rename cpp/include/cuspatial/detail/{ => join}/quadtree_bbox_filtering.cuh (99%) rename cpp/include/cuspatial/detail/{ => join}/quadtree_point_in_polygon.cuh (99%) rename cpp/include/cuspatial/detail/{ => join}/quadtree_point_to_nearest_linestring.cuh (99%) delete mode 100644 cpp/include/cuspatial/detail/linestring_bounding_boxes.cuh delete mode 100644 cpp/include/cuspatial/detail/pairwise_point_in_polygon.cuh delete mode 100644 cpp/include/cuspatial/detail/polygon_bounding_boxes.cuh rename cpp/include/cuspatial/detail/{ => projection}/sinusoidal_projection.cuh (98%) rename cpp/include/cuspatial/detail/{ => trajectory}/derive_trajectories.cuh (100%) rename cpp/include/cuspatial/detail/{ => trajectory}/trajectory_distances_and_speeds.cuh (100%) create mode 100644 cpp/include/cuspatial/distance.cuh create mode 100644 cpp/include/cuspatial/distance.hpp delete mode 100644 cpp/include/cuspatial/distance/hausdorff.hpp delete mode 100644 cpp/include/cuspatial/distance/haversine.hpp delete mode 100644 cpp/include/cuspatial/distance/linestring_distance.hpp delete mode 100644 cpp/include/cuspatial/distance/linestring_polygon_distance.hpp delete mode 100644 cpp/include/cuspatial/distance/point_distance.hpp delete mode 100644 cpp/include/cuspatial/distance/point_linestring_distance.hpp delete mode 100644 cpp/include/cuspatial/distance/point_polygon_distance.hpp delete mode 100644 cpp/include/cuspatial/hausdorff.cuh delete mode 100644 cpp/include/cuspatial/haversine.cuh rename cpp/include/cuspatial/{linestring_intersection.cuh => intersection.cuh} (96%) rename cpp/include/cuspatial/{linestring_intersection.hpp => intersection.hpp} (100%) delete mode 100644 cpp/include/cuspatial/linestring_bounding_box.hpp delete mode 100644 cpp/include/cuspatial/linestring_bounding_boxes.cuh delete mode 100644 cpp/include/cuspatial/linestring_distance.cuh delete mode 100644 cpp/include/cuspatial/linestring_polygon_distance.cuh rename cpp/include/cuspatial/{point_linestring_nearest_points.cuh => nearest_points.cuh} (100%) rename cpp/include/cuspatial/{point_linestring_nearest_points.hpp => nearest_points.hpp} (98%) delete mode 100644 cpp/include/cuspatial/pairwise_point_in_polygon.cuh delete mode 100644 cpp/include/cuspatial/pairwise_point_in_polygon.hpp delete mode 100644 cpp/include/cuspatial/point_distance.cuh delete mode 100644 cpp/include/cuspatial/point_linestring_distance.cuh delete mode 100644 cpp/include/cuspatial/point_polygon_distance.cuh rename cpp/include/cuspatial/{spatial_window.hpp => points_in_range.hpp} (61%) delete mode 100644 cpp/include/cuspatial/polygon_bounding_boxes.cuh delete mode 100644 cpp/include/cuspatial/polygon_distance.cuh rename cpp/include/cuspatial/{sinusoidal_projection.cuh => projection.cuh} (93%) rename cpp/include/cuspatial/{derive_trajectories.cuh => trajectory.cuh} (61%) delete mode 100644 cpp/include/cuspatial/trajectory_distances_and_speeds.cuh rename cpp/src/spatial/{linestring_bounding_box.cu => linestring_bounding_boxes.cu} (98%) delete mode 100644 cpp/src/spatial/pairwise_point_in_polygon.cu rename cpp/src/{spatial_window/spatial_window.cu => spatial/points_in_range.cu} (55%) rename cpp/src/spatial/{polygon_bounding_box.cu => polygon_bounding_boxes.cu} (99%) rename cpp/tests/spatial/points_in_range/{spatial_window_test.cpp => points_in_range_test.cpp} (80%) rename python/cuspatial/cuspatial/_lib/cpp/{linestring_bounding_box.pxd => linestring_bounding_boxes.pxd} (78%) rename python/cuspatial/cuspatial/_lib/cpp/{point_linestring_nearest_points.pxd => nearest_points.pxd} (89%) create mode 100644 python/cuspatial/cuspatial/_lib/cpp/points_in_range.pxd rename python/cuspatial/cuspatial/_lib/cpp/{polygon_bounding_box.pxd => polygon_bounding_boxes.pxd} (80%) delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/spatial_window.pxd rename python/cuspatial/cuspatial/_lib/{spatial_window.pyx => points_in_range.pyx} (54%) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index b13d53cfc..804bdaf95 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -122,12 +122,11 @@ add_library(cuspatial src/join/quadtree_point_in_polygon.cu src/join/quadtree_point_to_nearest_linestring.cu src/join/quadtree_bbox_filtering.cu + src/spatial/linestring_bounding_boxes.cu + src/spatial/polygon_bounding_boxes.cu src/spatial/pairwise_multipoint_equals_count.cu - src/spatial/polygon_bounding_box.cu - src/spatial/linestring_bounding_box.cu src/spatial/point_in_polygon.cu - src/spatial/pairwise_point_in_polygon.cu - src/spatial_window/spatial_window.cu + src/spatial/points_in_range.cu src/spatial/haversine.cu src/spatial/hausdorff.cu src/spatial/linestring_distance.cu diff --git a/cpp/benchmarks/hausdorff_benchmark.cpp b/cpp/benchmarks/hausdorff_benchmark.cpp index 8ff80c331..10ffced0e 100644 --- a/cpp/benchmarks/hausdorff_benchmark.cpp +++ b/cpp/benchmarks/hausdorff_benchmark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include diff --git a/cpp/benchmarks/pairwise_linestring_distance.cu b/cpp/benchmarks/pairwise_linestring_distance.cu index 8abc97f96..e8f7258d5 100644 --- a/cpp/benchmarks/pairwise_linestring_distance.cu +++ b/cpp/benchmarks/pairwise_linestring_distance.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,9 @@ #include #include -#include +#include #include #include -#include #include #include diff --git a/cpp/benchmarks/points_in_range.cu b/cpp/benchmarks/points_in_range.cu index f9c6d20f8..b9bced1be 100644 --- a/cpp/benchmarks/points_in_range.cu +++ b/cpp/benchmarks/points_in_range.cu @@ -18,9 +18,9 @@ #include -#include #include #include +#include #include #include diff --git a/cpp/doxygen/developer_guide/DOCUMENTATION.md b/cpp/doxygen/developer_guide/DOCUMENTATION.md index ef71ce79c..2a83c3dd7 100644 --- a/cpp/doxygen/developer_guide/DOCUMENTATION.md +++ b/cpp/doxygen/developer_guide/DOCUMENTATION.md @@ -475,8 +475,9 @@ from the [doxygen_groups.h](../include/doxygen_groups.h) file. } // namespace cuspatial -You can also use the \@addtogroup with a `@{ ... @}` pair to automatically include doxygen comment -blocks as part of a group. +When a file contains multiple functions, classes, or structs in the same group you should instead +use the \@addtogroup with a `@{ ... @}` pair to automatically include doxygen comment blocks as +part of a group. namespace cuspatial { /** diff --git a/cpp/include/cuspatial/bounding_box.cuh b/cpp/include/cuspatial/bounding_box.cuh deleted file mode 100644 index 78c213f96..000000000 --- a/cpp/include/cuspatial/bounding_box.cuh +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -namespace cuspatial { - -/** - * @addtogroup spatial_relationship - * @{ - */ - -/** - * @brief Compute the spatial bounding boxes of sequences of points. - * - * Computes a bounding box around all points within each group (consecutive points with the same - * ID). This function can be applied to trajectory data, polygon vertices, linestring vertices, or - * any grouped point data. - * - * Before merging bounding boxes, each point may be expanded into a bounding box using an - * optional @p expansion_radius. The point is expanded to a box with coordinates - * `(point.x - expansion_radius, point.y - expansion_radius)` and - * `(point.x + expansion_radius, point.y + expansion_radius)`. - * - * @note Assumes Object IDs and points are presorted by ID. - * - * @tparam IdInputIt Iterator over object IDs. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam PointInputIt Iterator over points. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam BoundingBoxOutputIt Iterator over output bounding boxes. Each element is a tuple of two - * points representing corners of the axis-aligned bounding box. The type of the points is the same - * as the `value_type` of PointInputIt. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-writeable. - * - * @param ids_first beginning of the range of input object ids - * @param ids_last end of the range of input object ids - * @param points_first beginning of the range of input point (x,y) coordinates - * @param bounding_boxes_first beginning of the range of output bounding boxes, one per trajectory - * @param expansion_radius radius to add to each point when computing its bounding box. - * @param stream the CUDA stream on which to perform computations. - * - * @return An iterator to the end of the range of output bounding boxes. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template > -BoundingBoxOutputIt point_bounding_boxes(IdInputIt ids_first, - IdInputIt ids_last, - PointInputIt points_first, - BoundingBoxOutputIt bounding_boxes_first, - T expansion_radius = T{0}, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -/** - * @} // end of doxygen group - */ - -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/bounding_boxes.cuh b/cpp/include/cuspatial/bounding_boxes.cuh new file mode 100644 index 000000000..157a6e06a --- /dev/null +++ b/cpp/include/cuspatial/bounding_boxes.cuh @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2022, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +#include + +namespace cuspatial { + +/** + * @addtogroup spatial_relationship + * @{ + */ + +/** + * @brief Compute the spatial bounding boxes of sequences of points. + * + * Computes a bounding box around all points within each group (consecutive points with the same + * ID). This function can be applied to trajectory data, polygon vertices, linestring vertices, or + * any grouped point data. + * + * Before merging bounding boxes, each point may be expanded into a bounding box using an + * optional @p expansion_radius. The point is expanded to a box with coordinates + * `(point.x - expansion_radius, point.y - expansion_radius)` and + * `(point.x + expansion_radius, point.y + expansion_radius)`. + * + * @note Assumes Object IDs and points are presorted by ID. + * + * @tparam IdInputIt Iterator over object IDs. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam PointInputIt Iterator over points. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam BoundingBoxOutputIt Iterator over output bounding boxes. Each element is a tuple of two + * points representing corners of the axis-aligned bounding box. The type of the points is the same + * as the `value_type` of PointInputIt. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-writeable. + * + * @param ids_first beginning of the range of input object ids + * @param ids_last end of the range of input object ids + * @param points_first beginning of the range of input point (x,y) coordinates + * @param bounding_boxes_first beginning of the range of output bounding boxes, one per trajectory + * @param expansion_radius radius to add to each point when computing its bounding box. + * @param stream the CUDA stream on which to perform computations. + * + * @return An iterator to the end of the range of output bounding boxes. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template > +BoundingBoxOutputIt point_bounding_boxes(IdInputIt ids_first, + IdInputIt ids_last, + PointInputIt points_first, + BoundingBoxOutputIt bounding_boxes_first, + T expansion_radius = T{0}, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Compute minimum bounding box for each linestring. + * + * @tparam LinestringOffsetIterator Iterator type to linestring offsets. Must meet the requirements + * of [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam VertexIterator Iterator type to linestring vertices. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam BoundingBoxIterator Iterator type to bounding boxes. Must be writable using data of type + * `cuspatial::box`. Must meet the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be + * device-writeable. + * @tparam T The coordinate data value type. + * @tparam IndexT The offset data value type. + * @param linestring_offsets_first Iterator to beginning of the range of input polygon offsets. + * @param linestring_offsets_last Iterator to end of the range of input polygon offsets. + * @param linestring_vertices_first Iterator to beginning of the range of input polygon vertices. + * @param linestring_vertices_last Iterator to end of the range of input polygon vertices. + * @param bounding_boxes_first Iterator to beginning of the range of output bounding boxes. + * @param expansion_radius Optional radius to expand each vertex of the output bounding boxes. + * @param stream the CUDA stream on which to perform computations and allocate memory. + * + * @return An iterator to the end of the range of output bounding boxes. + * + * @pre For compatibility with GeoArrow, the number of linestring offsets + * `std::distance(linestring_offsets_first, linestring_offsets_last)` should be one more than the + * number of linestrings. The final offset is not used by this function, but the number of offsets + * determines the output size. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template , + class IndexT = iterator_value_type> +BoundingBoxIterator linestring_bounding_boxes( + LinestringOffsetIterator linestring_offsets_first, + LinestringOffsetIterator linestring_offsets_last, + VertexIterator linestring_vertices_first, + VertexIterator linestring_vertices_last, + BoundingBoxIterator bounding_boxes_first, + T expansion_radius = T{0}, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Compute minimum bounding box for each polygon. + * + * @tparam PolygonOffsetIterator Iterator type to polygon offsets. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam RingOffsetIterator Iterator type to polygon ring offsets. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam VertexIterator Iterator type to polygon vertices. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam BoundingBoxIterator Iterator type to bounding boxes. Must be writable using data of type + * `cuspatial::box`. Must meet the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be + * device-writeable. + * @tparam T The coordinate data value type. + * @tparam IndexT The offset data value type. + * @param polygon_offsets_first Iterator to beginning of the range of input polygon offsets. + * @param polygon_offsets_last Iterator to end of the range of input polygon offsets. + * @param polygon_ring_offsets_first Iterator to beginning of the range of input polygon ring + * offsets. + * @param polygon_ring_offsets_last Iterator to end of the range of input polygon ring offsets. + * @param polygon_vertices_first Iterator to beginning of the range of input polygon vertices. + * @param polygon_vertices_last Iterator to end of the range of input polygon vertices. + * @param bounding_boxes_first Iterator to beginning of the range of output bounding boxes. + * @param expansion_radius Optional radius to expand each vertex of the output bounding boxes. + * @param stream the CUDA stream on which to perform computations and allocate memory. + * + * @return An iterator to the end of the range of output bounding boxes. + * + * @pre For compatibility with GeoArrow, the number of polygon offsets + * `std::distance(polygon_offsets_first, polygon_offsets_last)` should be one more than the number + * of polygons. The number of ring offsets `std::distance(polygon_ring_offsets_first, + * polygon_ring_offsets_last)` should be one more than the number of total rings. The + * final offset in each range is not used by this function, but the number of polygon offsets + * determines the output size. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template , + class IndexT = iterator_value_type> +BoundingBoxIterator polygon_bounding_boxes(PolygonOffsetIterator polygon_offsets_first, + PolygonOffsetIterator polygon_offsets_last, + RingOffsetIterator polygon_ring_offsets_first, + RingOffsetIterator polygon_ring_offsets_last, + VertexIterator polygon_vertices_first, + VertexIterator polygon_vertices_last, + BoundingBoxIterator bounding_boxes_first, + T expansion_radius = T{0}, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @} // end of doxygen group + */ + +} // namespace cuspatial + +#include diff --git a/cpp/include/cuspatial/polygon_bounding_box.hpp b/cpp/include/cuspatial/bounding_boxes.hpp similarity index 63% rename from cpp/include/cuspatial/polygon_bounding_box.hpp rename to cpp/include/cuspatial/bounding_boxes.hpp index 942df4dd6..9229eb7c2 100644 --- a/cpp/include/cuspatial/polygon_bounding_box.hpp +++ b/cpp/include/cuspatial/bounding_boxes.hpp @@ -25,9 +25,38 @@ namespace cuspatial { /** - * @brief Compute minimum bounding box for each polygon in a list. + * @addtogroup spatial_relationship + * @{ + */ + +/** + * @brief Compute minimum bounding boxes of a set of linestrings and an expansion radius. + * + * @param linestring_offsets Begin indices of the first point in each linestring (i.e. prefix-sum) + * @param x Linestring point x-coordinates + * @param y Linestring point y-coordinates + * @param expansion_radius Radius of each linestring point + * + * @return a cudf table of bounding boxes as four columns of the same type as `x` and `y`: + * x_min - the minimum x-coordinate of each bounding box + * y_min - the minimum y-coordinate of each bounding box + * x_max - the maximum x-coordinate of each bounding box + * y_max - the maximum y-coordinate of each bounding box * - * @ingroup spatial_relationship + * @pre For compatibility with GeoArrow, the size of @p linestring_offsets should be one more than + * the number of linestrings to process. The final offset is not used by this function, but the + * number of offsets determines the output size. + */ + +std::unique_ptr linestring_bounding_boxes( + cudf::column_view const& linestring_offsets, + cudf::column_view const& x, + cudf::column_view const& y, + double expansion_radius, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @brief Compute minimum bounding box for each polygon in a list. * * @param poly_offsets Begin indices of the first ring in each polygon (i.e. prefix-sum) * @param ring_offsets Begin indices of the first point in each ring (i.e. prefix-sum) @@ -54,4 +83,8 @@ std::unique_ptr polygon_bounding_boxes( double expansion_radius = 0.0, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); +/** + * @} // end of doxygen group + */ + } // namespace cuspatial diff --git a/cpp/include/cuspatial/column/geometry_column_view.hpp b/cpp/include/cuspatial/column/geometry_column_view.hpp index 1c50cc253..f872c4d37 100644 --- a/cpp/include/cuspatial/column/geometry_column_view.hpp +++ b/cpp/include/cuspatial/column/geometry_column_view.hpp @@ -25,9 +25,10 @@ namespace cuspatial { /** - * @ingroup cuspatial_types * @brief A non-owning, immutable view of a geometry column. * + * @ingroup cuspatial_types + * * A geometry column is GeoArrow compliant, except that the data type for * the coordinates is List, instead of FixedSizeList[n_dim]. This is * because libcudf does not support FixedSizeList type. Currently, an diff --git a/cpp/include/cuspatial/detail/bounding_box.cuh b/cpp/include/cuspatial/detail/bounding_box.cuh deleted file mode 100644 index 7855ed91f..000000000 --- a/cpp/include/cuspatial/detail/bounding_box.cuh +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -namespace cuspatial { - -namespace detail { - -template -struct point_bounding_box { - vec_2d box_offset{}; - - CUSPATIAL_HOST_DEVICE point_bounding_box(T expansion_radius = T{0}) - : box_offset{expansion_radius, expansion_radius} - { - } - - inline CUSPATIAL_HOST_DEVICE box operator()(vec_2d const& point) - { - return box{point - box_offset, point + box_offset}; - } -}; - -template -struct box_minmax { - inline CUSPATIAL_HOST_DEVICE box operator()(box const& a, box const& b) - { - return {box_min(box_min(a.v1, a.v2), b.v1), box_max(box_max(a.v1, a.v2), b.v2)}; - } -}; - -} // namespace detail - -template -BoundingBoxOutputIt point_bounding_boxes(IdInputIt ids_first, - IdInputIt ids_last, - PointInputIt points_first, - BoundingBoxOutputIt bounding_boxes_first, - T expansion_radius, - rmm::cuda_stream_view stream) -{ - static_assert(std::is_floating_point_v, "expansion_radius must be a floating-point type"); - - using CoordinateType = iterator_vec_base_type; - using IdType = iterator_value_type; - - auto point_bboxes_first = thrust::make_transform_iterator( - points_first, - detail::point_bounding_box{static_cast(expansion_radius)}); - - [[maybe_unused]] auto [_, bounding_boxes_last] = - thrust::reduce_by_key(rmm::exec_policy(stream), - ids_first, - ids_last, - point_bboxes_first, - thrust::make_discard_iterator(), - bounding_boxes_first, - thrust::equal_to(), - detail::box_minmax{}); - - return bounding_boxes_last; -} - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/bounding_boxes.cuh b/cpp/include/cuspatial/detail/bounding_boxes.cuh new file mode 100644 index 000000000..2e2e3f6e5 --- /dev/null +++ b/cpp/include/cuspatial/detail/bounding_boxes.cuh @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2022, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace cuspatial { + +namespace detail { + +template +struct point_bounding_box { + vec_2d box_offset{}; + + CUSPATIAL_HOST_DEVICE point_bounding_box(T expansion_radius = T{0}) + : box_offset{expansion_radius, expansion_radius} + { + } + + inline CUSPATIAL_HOST_DEVICE box operator()(vec_2d const& point) + { + return box{point - box_offset, point + box_offset}; + } +}; + +template +struct box_minmax { + inline CUSPATIAL_HOST_DEVICE box operator()(box const& a, box const& b) + { + return {box_min(box_min(a.v1, a.v2), b.v1), box_max(box_max(a.v1, a.v2), b.v2)}; + } +}; + +} // namespace detail + +template +BoundingBoxOutputIt point_bounding_boxes(IdInputIt ids_first, + IdInputIt ids_last, + PointInputIt points_first, + BoundingBoxOutputIt bounding_boxes_first, + T expansion_radius, + rmm::cuda_stream_view stream) +{ + static_assert(std::is_floating_point_v, "expansion_radius must be a floating-point type"); + + using CoordinateType = iterator_vec_base_type; + using IdType = iterator_value_type; + + auto point_bboxes_first = thrust::make_transform_iterator( + points_first, + detail::point_bounding_box{static_cast(expansion_radius)}); + + [[maybe_unused]] auto [_, bounding_boxes_last] = + thrust::reduce_by_key(rmm::exec_policy(stream), + ids_first, + ids_last, + point_bboxes_first, + thrust::make_discard_iterator(), + bounding_boxes_first, + thrust::equal_to(), + detail::box_minmax{}); + + return bounding_boxes_last; +} + +template +BoundingBoxIterator linestring_bounding_boxes(LinestringOffsetIterator linestring_offsets_first, + LinestringOffsetIterator linestring_offsets_last, + VertexIterator linestring_vertices_first, + VertexIterator linestring_vertices_last, + BoundingBoxIterator bounding_boxes_first, + T expansion_radius, + rmm::cuda_stream_view stream) +{ + static_assert(is_same>(), + "expansion_radius type must match vertex floating-point type"); + + static_assert(is_floating_point(), "Only floating point polygon vertices supported"); + + static_assert(is_vec_2d>, + "Input vertices must be cuspatial::vec_2d"); + + static_assert(cuspatial::is_integral>(), + "Offset iterators must have integral value type."); + + // GeoArrow: Number of linestrings is number of offsets minus one. + auto const num_linestrings = std::distance(linestring_offsets_first, linestring_offsets_last) - 1; + auto const num_vertices = std::distance(linestring_vertices_first, linestring_vertices_last); + + if (num_linestrings == 0 || num_vertices == 0) { return bounding_boxes_first; } + + auto vertex_ids_iter = + make_geometry_id_iterator(linestring_offsets_first, linestring_offsets_last); + + return point_bounding_boxes(vertex_ids_iter, + vertex_ids_iter + num_vertices, + linestring_vertices_first, + bounding_boxes_first, + expansion_radius, + stream); +} + +template +BoundingBoxIterator polygon_bounding_boxes(PolygonOffsetIterator polygon_offsets_first, + PolygonOffsetIterator polygon_offsets_last, + RingOffsetIterator polygon_ring_offsets_first, + RingOffsetIterator polygon_ring_offsets_last, + VertexIterator polygon_vertices_first, + VertexIterator polygon_vertices_last, + BoundingBoxIterator bounding_boxes_first, + T expansion_radius, + rmm::cuda_stream_view stream) +{ + static_assert(is_same>(), + "expansion_radius type must match vertex floating-point type"); + + static_assert(is_floating_point(), "Only floating point polygon vertices supported"); + + static_assert(is_vec_2d>, + "Input vertices must be cuspatial::vec_2d"); + + static_assert(cuspatial::is_integral, + iterator_value_type>(), + "OffsetIterators must have integral value type."); + + auto const num_polys = std::distance(polygon_offsets_first, polygon_offsets_last) - 1; + auto const num_rings = std::distance(polygon_ring_offsets_first, polygon_ring_offsets_last) - 1; + auto const num_vertices = std::distance(polygon_vertices_first, polygon_vertices_last); + + if (num_polys > 0) { + CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( + num_vertices, + std::distance(polygon_offsets_first, polygon_offsets_last), + std::distance(polygon_ring_offsets_first, polygon_ring_offsets_last)); + + if (num_polys == 0 || num_rings == 0 || num_vertices == 0) { return bounding_boxes_first; } + + auto vertex_ids_iter = make_geometry_id_iterator( + polygon_offsets_first, polygon_offsets_last, polygon_ring_offsets_first); + + return point_bounding_boxes(vertex_ids_iter, + vertex_ids_iter + num_vertices, + polygon_vertices_first, + bounding_boxes_first, + expansion_radius, + stream); + } + return bounding_boxes_first; +} + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/distance_utils.cuh b/cpp/include/cuspatial/detail/distance/distance_utils.cuh similarity index 99% rename from cpp/include/cuspatial/detail/distance_utils.cuh rename to cpp/include/cuspatial/detail/distance/distance_utils.cuh index 87efb0212..71ee9d5fd 100644 --- a/cpp/include/cuspatial/detail/distance_utils.cuh +++ b/cpp/include/cuspatial/detail/distance/distance_utils.cuh @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include #include diff --git a/cpp/include/cuspatial/detail/hausdorff.cuh b/cpp/include/cuspatial/detail/distance/hausdorff.cuh similarity index 100% rename from cpp/include/cuspatial/detail/hausdorff.cuh rename to cpp/include/cuspatial/detail/distance/hausdorff.cuh diff --git a/cpp/include/cuspatial/detail/haversine.cuh b/cpp/include/cuspatial/detail/distance/haversine.cuh similarity index 100% rename from cpp/include/cuspatial/detail/haversine.cuh rename to cpp/include/cuspatial/detail/distance/haversine.cuh diff --git a/cpp/include/cuspatial/detail/linestring_distance.cuh b/cpp/include/cuspatial/detail/distance/linestring_distance.cuh similarity index 100% rename from cpp/include/cuspatial/detail/linestring_distance.cuh rename to cpp/include/cuspatial/detail/distance/linestring_distance.cuh diff --git a/cpp/include/cuspatial/detail/linestring_polygon_distance.cuh b/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh similarity index 100% rename from cpp/include/cuspatial/detail/linestring_polygon_distance.cuh rename to cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh diff --git a/cpp/include/cuspatial/detail/point_distance.cuh b/cpp/include/cuspatial/detail/distance/point_distance.cuh similarity index 100% rename from cpp/include/cuspatial/detail/point_distance.cuh rename to cpp/include/cuspatial/detail/distance/point_distance.cuh diff --git a/cpp/include/cuspatial/detail/point_linestring_distance.cuh b/cpp/include/cuspatial/detail/distance/point_linestring_distance.cuh similarity index 100% rename from cpp/include/cuspatial/detail/point_linestring_distance.cuh rename to cpp/include/cuspatial/detail/distance/point_linestring_distance.cuh diff --git a/cpp/include/cuspatial/detail/point_polygon_distance.cuh b/cpp/include/cuspatial/detail/distance/point_polygon_distance.cuh similarity index 99% rename from cpp/include/cuspatial/detail/point_polygon_distance.cuh rename to cpp/include/cuspatial/detail/distance/point_polygon_distance.cuh index 0a244aadc..1729b6775 100644 --- a/cpp/include/cuspatial/detail/point_polygon_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/point_polygon_distance.cuh @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/cpp/include/cuspatial/detail/polygon_distance.cuh b/cpp/include/cuspatial/detail/distance/polygon_distance.cuh similarity index 100% rename from cpp/include/cuspatial/detail/polygon_distance.cuh rename to cpp/include/cuspatial/detail/distance/polygon_distance.cuh diff --git a/cpp/include/cuspatial/detail/find/find_points_on_segments.cuh b/cpp/include/cuspatial/detail/find/find_points_on_segments.cuh index fcf7a6283..dfda0b8b1 100644 --- a/cpp/include/cuspatial/detail/find/find_points_on_segments.cuh +++ b/cpp/include/cuspatial/detail/find/find_points_on_segments.cuh @@ -19,9 +19,9 @@ #include #include -#include #include #include +#include #include #include diff --git a/cpp/include/cuspatial/detail/geometry/linestring_ref.cuh b/cpp/include/cuspatial/detail/geometry/linestring_ref.cuh index f18fab4d8..37e4bb5aa 100644 --- a/cpp/include/cuspatial/detail/geometry/linestring_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry/linestring_ref.cuh @@ -16,8 +16,8 @@ #pragma once #include -#include #include +#include #include #include diff --git a/cpp/include/cuspatial/detail/geometry/polygon_ref.cuh b/cpp/include/cuspatial/detail/geometry/polygon_ref.cuh index 35374e23c..882ae22ae 100644 --- a/cpp/include/cuspatial/detail/geometry/polygon_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry/polygon_ref.cuh @@ -16,9 +16,9 @@ #pragma once #include -#include #include #include +#include #include #include diff --git a/cpp/include/cuspatial/detail/geometry_collection/multilinestring_ref.cuh b/cpp/include/cuspatial/detail/geometry_collection/multilinestring_ref.cuh index f3894515d..7a76f92b8 100644 --- a/cpp/include/cuspatial/detail/geometry_collection/multilinestring_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry_collection/multilinestring_ref.cuh @@ -17,8 +17,8 @@ #pragma once #include -#include #include +#include #include diff --git a/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh b/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh index 5d4e8eeeb..23346d9e0 100644 --- a/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh @@ -15,7 +15,7 @@ */ #pragma once #include -#include +#include #include diff --git a/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh b/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh index d033722e2..78920afe5 100644 --- a/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh @@ -1,9 +1,9 @@ #pragma once #include -#include #include #include +#include #include diff --git a/cpp/include/cuspatial/detail/linestring_intersection.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh similarity index 98% rename from cpp/include/cuspatial/detail/linestring_intersection.cuh rename to cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh index 984e753e8..db9b28075 100644 --- a/cpp/include/cuspatial/detail/linestring_intersection.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/cpp/include/cuspatial/detail/linestring_intersection_count.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_count.cuh similarity index 100% rename from cpp/include/cuspatial/detail/linestring_intersection_count.cuh rename to cpp/include/cuspatial/detail/intersection/linestring_intersection_count.cuh diff --git a/cpp/include/cuspatial/detail/linestring_intersection_with_duplicates.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh similarity index 99% rename from cpp/include/cuspatial/detail/linestring_intersection_with_duplicates.cuh rename to cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh index 3971ba085..e240acb88 100644 --- a/cpp/include/cuspatial/detail/linestring_intersection_with_duplicates.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh @@ -14,8 +14,7 @@ * limitations under the License. */ -#include -#include +#include #include #include #include diff --git a/cpp/include/cuspatial/detail/iterator.hpp b/cpp/include/cuspatial/detail/iterator.hpp deleted file mode 100644 index 05b8a7aa2..000000000 --- a/cpp/include/cuspatial/detail/iterator.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once -#include - -#include -#include - -namespace cuspatial { -namespace detail { - -template -inline CUSPATIAL_HOST_DEVICE auto make_counting_transform_iterator(IndexType start, UnaryFunction f) -{ - return thrust::make_transform_iterator(thrust::make_counting_iterator(start), f); -} -} // namespace detail -} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/quadtree_bbox_filtering.cuh b/cpp/include/cuspatial/detail/join/quadtree_bbox_filtering.cuh similarity index 99% rename from cpp/include/cuspatial/detail/quadtree_bbox_filtering.cuh rename to cpp/include/cuspatial/detail/join/quadtree_bbox_filtering.cuh index f7a39fd9f..9ba8744d0 100644 --- a/cpp/include/cuspatial/detail/quadtree_bbox_filtering.cuh +++ b/cpp/include/cuspatial/detail/join/quadtree_bbox_filtering.cuh @@ -16,9 +16,9 @@ #pragma once -#include #include #include +#include #include #include diff --git a/cpp/include/cuspatial/detail/quadtree_point_in_polygon.cuh b/cpp/include/cuspatial/detail/join/quadtree_point_in_polygon.cuh similarity index 99% rename from cpp/include/cuspatial/detail/quadtree_point_in_polygon.cuh rename to cpp/include/cuspatial/detail/join/quadtree_point_in_polygon.cuh index 54977fa7c..2a9594317 100644 --- a/cpp/include/cuspatial/detail/quadtree_point_in_polygon.cuh +++ b/cpp/include/cuspatial/detail/join/quadtree_point_in_polygon.cuh @@ -15,9 +15,9 @@ */ #include -#include #include #include +#include #include #include #include diff --git a/cpp/include/cuspatial/detail/quadtree_point_to_nearest_linestring.cuh b/cpp/include/cuspatial/detail/join/quadtree_point_to_nearest_linestring.cuh similarity index 99% rename from cpp/include/cuspatial/detail/quadtree_point_to_nearest_linestring.cuh rename to cpp/include/cuspatial/detail/join/quadtree_point_to_nearest_linestring.cuh index 3ac8a6338..a317758d9 100644 --- a/cpp/include/cuspatial/detail/quadtree_point_to_nearest_linestring.cuh +++ b/cpp/include/cuspatial/detail/join/quadtree_point_to_nearest_linestring.cuh @@ -15,10 +15,10 @@ */ #include -#include #include #include #include +#include #include #include #include diff --git a/cpp/include/cuspatial/detail/linestring_bounding_boxes.cuh b/cpp/include/cuspatial/detail/linestring_bounding_boxes.cuh deleted file mode 100644 index cc88c3053..000000000 --- a/cpp/include/cuspatial/detail/linestring_bounding_boxes.cuh +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -namespace cuspatial { - -template -BoundingBoxIterator linestring_bounding_boxes(LinestringOffsetIterator linestring_offsets_first, - LinestringOffsetIterator linestring_offsets_last, - VertexIterator linestring_vertices_first, - VertexIterator linestring_vertices_last, - BoundingBoxIterator bounding_boxes_first, - T expansion_radius, - rmm::cuda_stream_view stream) -{ - static_assert(is_same>(), - "expansion_radius type must match vertex floating-point type"); - - static_assert(is_floating_point(), "Only floating point polygon vertices supported"); - - static_assert(is_vec_2d>, - "Input vertices must be cuspatial::vec_2d"); - - static_assert(cuspatial::is_integral>(), - "Offset iterators must have integral value type."); - - // GeoArrow: Number of linestrings is number of offsets minus one. - auto const num_linestrings = std::distance(linestring_offsets_first, linestring_offsets_last) - 1; - auto const num_vertices = std::distance(linestring_vertices_first, linestring_vertices_last); - - if (num_linestrings == 0 || num_vertices == 0) { return bounding_boxes_first; } - - auto vertex_ids_iter = - make_geometry_id_iterator(linestring_offsets_first, linestring_offsets_last); - - return point_bounding_boxes(vertex_ids_iter, - vertex_ids_iter + num_vertices, - linestring_vertices_first, - bounding_boxes_first, - expansion_radius, - stream); -} -} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/pairwise_point_in_polygon.cuh b/cpp/include/cuspatial/detail/pairwise_point_in_polygon.cuh deleted file mode 100644 index 14951b711..000000000 --- a/cpp/include/cuspatial/detail/pairwise_point_in_polygon.cuh +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2022-2023, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -namespace cuspatial { -namespace detail { - -template ::difference_type, - class Cart2dItBDiffType = typename std::iterator_traits::difference_type, - class OffsetItADiffType = typename std::iterator_traits::difference_type, - class OffsetItBDiffType = typename std::iterator_traits::difference_type> -__global__ void pairwise_point_in_polygon_kernel(Cart2dItA test_points_first, - Cart2dItADiffType const num_test_points, - OffsetIteratorA poly_offsets_first, - OffsetItADiffType const num_polys, - OffsetIteratorB ring_offsets_first, - OffsetItBDiffType const num_rings, - Cart2dItB poly_points_first, - Cart2dItBDiffType const num_poly_points, - OutputIt result) -{ - using Cart2d = iterator_value_type; - using OffsetType = iterator_value_type; - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < num_test_points; - idx += gridDim.x * blockDim.x) { - Cart2d const test_point = test_points_first[idx]; - // for the matching polygon - OffsetType poly_begin = poly_offsets_first[idx]; - OffsetType poly_end = (idx + 1 < num_polys) ? poly_offsets_first[idx + 1] : num_rings; - bool const point_is_within = is_point_in_polygon(test_point, - poly_begin, - poly_end, - ring_offsets_first, - num_rings, - poly_points_first, - num_poly_points); - result[idx] = point_is_within; - } -} - -} // namespace detail - -template -OutputIt pairwise_point_in_polygon(Cart2dItA test_points_first, - Cart2dItA test_points_last, - OffsetIteratorA polygon_offsets_first, - OffsetIteratorA polygon_offsets_last, - OffsetIteratorB poly_ring_offsets_first, - OffsetIteratorB poly_ring_offsets_last, - Cart2dItB polygon_points_first, - Cart2dItB polygon_points_last, - OutputIt output, - rmm::cuda_stream_view stream) -{ - using T = iterator_vec_base_type; - - static_assert(is_same_floating_point>(), - "Underlying type of Cart2dItA and Cart2dItB must be the same floating point type"); - static_assert( - is_same, iterator_value_type, iterator_value_type>(), - "Inputs must be cuspatial::vec_2d"); - - static_assert(cuspatial::is_integral, - iterator_value_type>(), - "OffsetIterators must point to integral type."); - - static_assert(std::is_same_v, int32_t>, - "OutputIt must point to 32 bit integer type."); - - auto const num_test_points = std::distance(test_points_first, test_points_last); - auto const num_polys = std::distance(polygon_offsets_first, polygon_offsets_last) - 1; - auto const num_rings = std::distance(poly_ring_offsets_first, poly_ring_offsets_last) - 1; - auto const num_poly_points = std::distance(polygon_points_first, polygon_points_last); - - CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( - num_poly_points, - std::distance(polygon_offsets_first, polygon_offsets_last), - std::distance(poly_ring_offsets_first, poly_ring_offsets_last)); - - CUSPATIAL_EXPECTS(num_test_points == num_polys, - "Must pass in an equal number of points and polygons"); - - auto [threads_per_block, num_blocks] = grid_1d(num_test_points); - detail::pairwise_point_in_polygon_kernel<<>>( - test_points_first, - num_test_points, - polygon_offsets_first, - num_polys, - poly_ring_offsets_first, - num_rings, - polygon_points_first, - num_poly_points, - output); - CUSPATIAL_CHECK_CUDA(stream.value()); - - return output + num_test_points; -} - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/point_in_polygon.cuh b/cpp/include/cuspatial/detail/point_in_polygon.cuh index bf841391a..ecf6dd0ba 100644 --- a/cpp/include/cuspatial/detail/point_in_polygon.cuh +++ b/cpp/include/cuspatial/detail/point_in_polygon.cuh @@ -32,6 +32,21 @@ namespace cuspatial { namespace detail { +// Get the begin and end offsets of a polygon +template > +__device__ auto poly_begin_end(OffsetIteratorA poly_offsets_first, + OffsetItADiffType const num_polys, + OffsetItADiffType const num_rings, + OffsetType const poly_idx) +{ + auto poly_idx_next = poly_idx + 1; + OffsetType poly_begin = poly_offsets_first[poly_idx]; + OffsetType poly_end = (poly_idx_next < num_polys) ? poly_offsets_first[poly_idx_next] : num_rings; + return std::make_pair(poly_begin, poly_end); +} + template ::difference_type, + class Cart2dItBDiffType = typename std::iterator_traits::difference_type, + class OffsetItADiffType = typename std::iterator_traits::difference_type, + class OffsetItBDiffType = typename std::iterator_traits::difference_type> +__global__ void pairwise_point_in_polygon_kernel(Cart2dItA test_points_first, + Cart2dItADiffType const num_test_points, + OffsetIteratorA poly_offsets_first, + OffsetItADiffType const num_polys, + OffsetIteratorB ring_offsets_first, + OffsetItBDiffType const num_rings, + Cart2dItB poly_points_first, + Cart2dItBDiffType const num_poly_points, + OutputIt result) +{ + using Cart2d = iterator_value_type; + using OffsetType = iterator_value_type; + for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < num_test_points; + idx += gridDim.x * blockDim.x) { + Cart2d const test_point = test_points_first[idx]; + + // for the matching polygon + auto [poly_begin, poly_end] = poly_begin_end(poly_offsets_first, num_polys, num_rings, idx); + + bool const point_is_within = is_point_in_polygon(test_point, + poly_begin, + poly_end, + ring_offsets_first, + num_rings, + poly_points_first, + num_poly_points); + result[idx] = point_is_within; + } +} + } // namespace detail template +OutputIt pairwise_point_in_polygon(Cart2dItA test_points_first, + Cart2dItA test_points_last, + OffsetIteratorA polygon_offsets_first, + OffsetIteratorA polygon_offsets_last, + OffsetIteratorB poly_ring_offsets_first, + OffsetIteratorB poly_ring_offsets_last, + Cart2dItB polygon_points_first, + Cart2dItB polygon_points_last, + OutputIt output, + rmm::cuda_stream_view stream) +{ + using T = iterator_vec_base_type; + + static_assert(is_same_floating_point>(), + "Underlying type of Cart2dItA and Cart2dItB must be the same floating point type"); + static_assert( + is_same, iterator_value_type, iterator_value_type>(), + "Inputs must be cuspatial::vec_2d"); + + static_assert(cuspatial::is_integral, + iterator_value_type>(), + "OffsetIterators must point to integral type."); + + static_assert(std::is_same_v, int32_t>, + "OutputIt must point to 32 bit integer type."); + + auto const num_test_points = std::distance(test_points_first, test_points_last); + auto const num_polys = std::distance(polygon_offsets_first, polygon_offsets_last) - 1; + auto const num_rings = std::distance(poly_ring_offsets_first, poly_ring_offsets_last) - 1; + auto const num_poly_points = std::distance(polygon_points_first, polygon_points_last); + + CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( + num_poly_points, + std::distance(polygon_offsets_first, polygon_offsets_last), + std::distance(poly_ring_offsets_first, poly_ring_offsets_last)); + + CUSPATIAL_EXPECTS(num_test_points == num_polys, + "Must pass in an equal number of points and polygons"); + + auto [threads_per_block, num_blocks] = grid_1d(num_test_points); + detail::pairwise_point_in_polygon_kernel<<>>( + test_points_first, + num_test_points, + polygon_offsets_first, + num_polys, + poly_ring_offsets_first, + num_rings, + polygon_points_first, + num_poly_points, + output); + CUSPATIAL_CHECK_CUDA(stream.value()); + + return output + num_test_points; +} + } // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/polygon_bounding_boxes.cuh b/cpp/include/cuspatial/detail/polygon_bounding_boxes.cuh deleted file mode 100644 index 0d4844329..000000000 --- a/cpp/include/cuspatial/detail/polygon_bounding_boxes.cuh +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2022-2023, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -namespace cuspatial { - -template -BoundingBoxIterator polygon_bounding_boxes(PolygonOffsetIterator polygon_offsets_first, - PolygonOffsetIterator polygon_offsets_last, - RingOffsetIterator polygon_ring_offsets_first, - RingOffsetIterator polygon_ring_offsets_last, - VertexIterator polygon_vertices_first, - VertexIterator polygon_vertices_last, - BoundingBoxIterator bounding_boxes_first, - T expansion_radius, - rmm::cuda_stream_view stream) -{ - static_assert(is_same>(), - "expansion_radius type must match vertex floating-point type"); - - static_assert(is_floating_point(), "Only floating point polygon vertices supported"); - - static_assert(is_vec_2d>, - "Input vertices must be cuspatial::vec_2d"); - - static_assert(cuspatial::is_integral, - iterator_value_type>(), - "OffsetIterators must have integral value type."); - - auto const num_polys = std::distance(polygon_offsets_first, polygon_offsets_last) - 1; - auto const num_rings = std::distance(polygon_ring_offsets_first, polygon_ring_offsets_last) - 1; - auto const num_vertices = std::distance(polygon_vertices_first, polygon_vertices_last); - - if (num_polys > 0) { - CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( - num_vertices, - std::distance(polygon_offsets_first, polygon_offsets_last), - std::distance(polygon_ring_offsets_first, polygon_ring_offsets_last)); - - if (num_polys == 0 || num_rings == 0 || num_vertices == 0) { return bounding_boxes_first; } - - auto vertex_ids_iter = make_geometry_id_iterator( - polygon_offsets_first, polygon_offsets_last, polygon_ring_offsets_first); - - return point_bounding_boxes(vertex_ids_iter, - vertex_ids_iter + num_vertices, - polygon_vertices_first, - bounding_boxes_first, - expansion_radius, - stream); - } - return bounding_boxes_first; -} -} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/sinusoidal_projection.cuh b/cpp/include/cuspatial/detail/projection/sinusoidal_projection.cuh similarity index 98% rename from cpp/include/cuspatial/detail/sinusoidal_projection.cuh rename to cpp/include/cuspatial/detail/projection/sinusoidal_projection.cuh index 03fa2128c..24ec762bd 100644 --- a/cpp/include/cuspatial/detail/sinusoidal_projection.cuh +++ b/cpp/include/cuspatial/detail/projection/sinusoidal_projection.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cpp/include/cuspatial/detail/range/enumerate_range.cuh b/cpp/include/cuspatial/detail/range/enumerate_range.cuh index 4143bc8a5..6dbaf0f55 100644 --- a/cpp/include/cuspatial/detail/range/enumerate_range.cuh +++ b/cpp/include/cuspatial/detail/range/enumerate_range.cuh @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include #include diff --git a/cpp/include/cuspatial/detail/range/multilinestring_range.cuh b/cpp/include/cuspatial/detail/range/multilinestring_range.cuh index 775037c42..5983efc00 100644 --- a/cpp/include/cuspatial/detail/range/multilinestring_range.cuh +++ b/cpp/include/cuspatial/detail/range/multilinestring_range.cuh @@ -24,10 +24,10 @@ #include #include -#include #include #include #include +#include #include #include diff --git a/cpp/include/cuspatial/detail/range/multipoint_range.cuh b/cpp/include/cuspatial/detail/range/multipoint_range.cuh index 3caad3a1d..7e9c18cb3 100644 --- a/cpp/include/cuspatial/detail/range/multipoint_range.cuh +++ b/cpp/include/cuspatial/detail/range/multipoint_range.cuh @@ -22,9 +22,9 @@ #include #include -#include #include #include +#include #include namespace cuspatial { diff --git a/cpp/include/cuspatial/detail/range/multipolygon_range.cuh b/cpp/include/cuspatial/detail/range/multipolygon_range.cuh index 6f9cfcf2c..85781e55b 100644 --- a/cpp/include/cuspatial/detail/range/multipolygon_range.cuh +++ b/cpp/include/cuspatial/detail/range/multipolygon_range.cuh @@ -18,11 +18,11 @@ #include #include -#include #include #include #include #include +#include #include #include #include diff --git a/cpp/include/cuspatial/detail/derive_trajectories.cuh b/cpp/include/cuspatial/detail/trajectory/derive_trajectories.cuh similarity index 100% rename from cpp/include/cuspatial/detail/derive_trajectories.cuh rename to cpp/include/cuspatial/detail/trajectory/derive_trajectories.cuh diff --git a/cpp/include/cuspatial/detail/trajectory_distances_and_speeds.cuh b/cpp/include/cuspatial/detail/trajectory/trajectory_distances_and_speeds.cuh similarity index 100% rename from cpp/include/cuspatial/detail/trajectory_distances_and_speeds.cuh rename to cpp/include/cuspatial/detail/trajectory/trajectory_distances_and_speeds.cuh diff --git a/cpp/include/cuspatial/distance.cuh b/cpp/include/cuspatial/distance.cuh new file mode 100644 index 000000000..6f7da67d4 --- /dev/null +++ b/cpp/include/cuspatial/distance.cuh @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include + +#include + +#include + +namespace cuspatial { + +/** + * @addtogroup distance + * @{ + */ + +/** + * @brief Compute haversine distances between points in set A to the corresponding points in set B. + * + * Computes N haversine distances, where N is `std::distance(a_lonlat_first, a_lonlat_last)`. + * The distance for each `a_lonlat[i]` and `b_lonlat[i]` point pair is assigned to + * `distance_first[i]`. `distance_first` must be an iterator to output storage allocated for N + * distances. + * + * Computed distances will have the same units as `radius`. + * + * https://en.wikipedia.org/wiki/Haversine_formula + * + * @param[in] a_lonlat_first: beginning of range of (longitude, latitude) locations in set A + * @param[in] a_lonlat_last: end of range of (longitude, latitude) locations in set A + * @param[in] b_lonlat_first: beginning of range of (longitude, latitude) locations in set B + * @param[out] distance_first: beginning of output range of haversine distances + * @param[in] radius: radius of the sphere on which the points reside. default: 6371.0 + * (approximate radius of Earth in km) + * @param[in] stream: The CUDA stream on which to perform computations and allocate memory. + * + * @tparam LonLatItA Iterator to input location set A. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam LonLatItB Iterator to input location set B. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam OutputIt Output iterator. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable. + * @tparam T The underlying coordinate type. Must be a floating-point type. + * + * @pre All iterators must have the same `Location` type, with the same underlying floating-point + * coordinate type (e.g. `cuspatial::vec_2d`). + * + * @return Output iterator to the element past the last distance computed. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template > +OutputIt haversine_distance(LonLatItA a_lonlat_first, + LonLatItA a_lonlat_last, + LonLatItB b_lonlat_first, + OutputIt distance_first, + T const radius = EARTH_RADIUS_KM, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Computes Hausdorff distances for all pairs in a collection of spaces + * + * https://en.wikipedia.org/wiki/Hausdorff_distance + * + * Example in 1D (this function operates in 2D): + * ``` + * spaces + * [0 2 5] [9] [3 7] + * + * spaces represented as points per space and concatenation of all points + * [0 2 5 9 3 7] [3 1 2] + * + * note: the following matrices are visually separated to highlight the relationship of a pair of + * points with the pair of spaces from which it is produced + * + * cartesian product of all + * points by pair of spaces distance between points + * +----------+----+-------+ +---------+---+------+ + * : 00 02 05 : 09 : 03 07 : : 0 2 5 : 9 : 3 7 : + * : 20 22 25 : 29 : 23 27 : : 2 0 3 : 7 : 1 5 : + * : 50 52 55 : 59 : 53 57 : : 5 3 0 : 4 : 2 2 : + * +----------+----+-------+ +---------+---+------+ + * : 90 92 95 : 99 : 93 97 : : 9 7 4 : 0 : 6 2 : + * +----------+----+-------+ +---------+---+------+ + * : 30 32 35 : 39 : 33 37 : : 3 1 2 : 6 : 0 4 : + * : 70 72 75 : 79 : 73 77 : : 7 5 2 : 2 : 4 0 : + * +----------+----+-------+ +---------+---+------+ + + * minimum distance from + * every point in one Hausdorff distance is + * space to any point in the maximum of the + * the other space minimum distances + * +----------+----+-------+ +---------+---+------+ + * : 0 : 9 : 3 : : 0 : 9 : 3 : + * : 0 : 7 : 1 : : : : : + * : 0 : 4 : 2 : : : : : + * +----------+----+-------+ +---------+---+------+ + * : 4 : 0 : 2 : : 4 : 0 : 2 : + * +----------+----+-------+ +---------+---+------+ + * : 1 : 6 : 0 : : : 6 : 0 : + * : 2 : 2 : 0 : : 2 : : : + * +----------+----+-------+ +---------+---+------+ + * + * returned as concatenation of columns + * [0 2 4 3 0 2 9 6 0] + * ``` + * + * @param[in] points_first: xs: beginning of range of (x,y) points + * @param[in] points_lasts: xs: end of range of (x,y) points + * @param[in] space_offsets_first: beginning of range of indices to each space. + * @param[in] space_offsets_first: end of range of indices to each space. Last index is the last + * @param[in] distance_first: beginning of range of output Hausdorff distance for each pair of + * spaces + * + * @tparam PointIt Iterator to input points. Points must be of a type that is convertible to + * `cuspatial::vec_2d`. Must meet the requirements of [LegacyRandomAccessIterator][LinkLRAI] and + * be device-accessible. + * @tparam OffsetIt Iterator to space offsets. Value type must be integral. Must meet the + * requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam OutputIt Output iterator. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable. + * + * @pre All iterators must have the same underlying floating-point value type. + * + * @return Output iterator to the element past the last distance computed. + * + * @note Hausdorff distances are asymmetrical + */ +template +OutputIt directed_hausdorff_distance(PointIt points_first, + PointIt points_last, + OffsetIt space_offsets_first, + OffsetIt space_offsets_last, + OutputIt distance_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Compute pairwise (multi)point-to-(multi)point Cartesian distance + * + * Computes the cartesian distance between each pair of multipoints. + * + * @tparam MultiPointArrayViewA An instance of template type `array_view::multipoint_array` + * @tparam MultiPointArrayViewB An instance of template type `array_view::multipoint_array` + * + * @param multipoints1 Range of first multipoint in each distance pair. + * @param multipoints2 Range of second multipoint in each distance pair. + * @return Iterator past the last distance computed + */ +template +OutputIt pairwise_point_distance(MultiPointArrayViewA multipoints1, + MultiPointArrayViewB multipoints2, + OutputIt distances_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Compute pairwise multipoint to multilinestring distance + * + * @tparam MultiPointRange an instance of template type `multipoint_range` + * @tparam MultiLinestringRange an instance of template type `multilinestring_range` + * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). + * + * @param multipoints The range of multipoints, one per computed distance pair + * @param multilinestrings The range of multilinestrings, one per computed distance pair + * @param stream The CUDA stream to use for device memory operations and kernel launches. + * @return Output iterator to the element past the last distance computed. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_point_linestring_distance( + MultiPointRange multipoints, + MultiLinestringRange multilinestrings, + OutputIt distances_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Computes pairwise multipoint to multipolygon distance + * + * @tparam MultiPointRange An instance of template type `multipoint_range` + * @tparam MultiPolygonRange An instance of template type `multipolygon_range` + * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). + * Must be an iterator to type convertible from floating points. + * + * @param multipoints Range of multipoints, one per computed distance pair. + * @param multipolygons Range of multilinestrings, one per computed distance pair. + * @param stream The CUDA stream on which to perform computations + * @return Output Iterator past the last distance computed + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_point_polygon_distance(MultiPointRange multipoints, + MultiPolygonRange multipoiygons, + OutputIt distances_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @copybrief cuspatial::pairwise_linestring_distance + * + * The shortest distance between two linestrings is defined as the shortest distance + * between all pairs of segments of the two linestrings. If any of the segments intersect, + * the distance is 0. + * + * @tparam MultiLinestringRange an instance of template type `multilinestring_range` + * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI) + * and be device writable. + * + * @param multilinestrings1 Range object of the lhs multilinestring array + * @param multilinestrings2 Range object of the rhs multilinestring array + * @param stream The CUDA stream to use for device memory operations and kernel launches. + * @return Output iterator to the element past the last distance computed. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_linestring_distance(MultiLinestringRange1 multilinestrings1, + MultiLinstringRange2 multilinestrings2, + OutputIt distances_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Computes pairwise multilinestring to multipolygon distance + * + * @tparam MultiLinestringRange An instance of template type `multipoint_range` + * @tparam MultiPolygonRange An instance of template type `multipolygon_range` + * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). + * Must be an iterator to type convertible from floating points. + * + * @param multilinestrings Range of multilinestrings, one per computed distance pair. + * @param multipolygons Range of multipolygons, one per computed distance pair. + * @param stream The CUDA stream on which to perform computations + * @return Output Iterator past the last distance computed + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_linestring_polygon_distance( + MultiLinestringRange multilinestrings, + MultiPolygonRange multipoiygons, + OutputIt distances_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @brief Computes pairwise multipolygon to multipolygon distance + * + * @tparam MultiPolygonRangeA An instance of template type `multipolygon_range` + * @tparam MultiPolygonRangeB An instance of template type `multipolygon_range` + * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). + * Must be an iterator to type convertible from floating points. + * + * @param lhs The first multipolygon range to compute distance from + * @param rhs The second multipolygon range to compute distance to + * @param stream The CUDA stream on which to perform computations + * @return Output Iterator past the last distance computed + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_polygon_distance(MultipolygonRangeA lhs, + MultipolygonRangeB rhs, + OutputIt distances_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @} // end of doxygen group + */ + +} // namespace cuspatial + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/cpp/include/cuspatial/distance.hpp b/cpp/include/cuspatial/distance.hpp new file mode 100644 index 000000000..113707b72 --- /dev/null +++ b/cpp/include/cuspatial/distance.hpp @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2020-2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +namespace cuspatial { + +/** + * @addtogroup distance + */ + +/** + * @brief Compute haversine distances between points in set A and the corresponding points in set B. + * + * https://en.wikipedia.org/wiki/Haversine_formula + * + * @param[in] a_lon: longitude of points in set A + * @param[in] a_lat: latitude of points in set A + * @param[in] b_lon: longitude of points in set B + * @param[in] b_lat: latitude of points in set B + * @param[in] radius: radius of the sphere on which the points reside. default: 6371.0 (aprx. radius + * of earth in km) + * + * @return array of distances for all (a_lon[i], a_lat[i]) and (b_lon[i], b_lat[i]) point pairs + */ +std::unique_ptr haversine_distance( + cudf::column_view const& a_lon, + cudf::column_view const& a_lat, + cudf::column_view const& b_lon, + cudf::column_view const& b_lat, + double const radius = EARTH_RADIUS_KM, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @brief computes Hausdorff distances for all pairs in a collection of spaces + * + * https://en.wikipedia.org/wiki/Hausdorff_distance + * + * Example in 1D (this function operates in 2D): + * ``` + * spaces + * [0 2 5] [9] [3 7] + * + * spaces represented as points per space and concatenation of all points + * [0 2 5 9 3 7] [3 1 2] + * + * note: the following matrices are visually separated to highlight the relationship of a pair of + * points with the pair of spaces from which it is produced + * + * cartesian product of all + * points by pair of spaces distance between points + * +----------+----+-------+ +---------+---+------+ + * : 00 02 05 : 09 : 03 07 : : 0 2 5 : 9 : 3 7 : + * : 20 22 25 : 29 : 23 27 : : 2 0 3 : 7 : 1 5 : + * : 50 52 55 : 59 : 53 57 : : 5 3 0 : 4 : 2 2 : + * +----------+----+-------+ +---------+---+------+ + * : 90 92 95 : 99 : 93 97 : : 9 7 4 : 0 : 6 2 : + * +----------+----+-------+ +---------+---+------+ + * : 30 32 35 : 39 : 33 37 : : 3 1 2 : 6 : 0 4 : + * : 70 72 75 : 79 : 73 77 : : 7 5 2 : 2 : 4 0 : + * +----------+----+-------+ +---------+---+------+ + + * minimum distance from + * every point in one Hausdorff distance is + * space to any point in the maximum of the + * the other space minimum distances + * +----------+----+-------+ +---------+---+------+ + * : 0 : 9 : 3 : : 0 : 9 : 3 : + * : 0 : 7 : 1 : : : : : + * : 0 : 4 : 2 : : : : : + * +----------+----+-------+ +---------+---+------+ + * : 4 : 0 : 2 : : 4 : 0 : 2 : + * +----------+----+-------+ +---------+---+------+ + * : 1 : 6 : 0 : : : 6 : 0 : + * : 2 : 2 : 0 : : 2 : : : + * +----------+----+-------+ +---------+---+------+ + * + * Returns: + * column: [0 4 2 9 0 6 3 2 0] + * table_view: [0 4 2] [9 0 6] [3 2 0] + * + * ``` + * + * @param[in] xs: x component of points + * @param[in] ys: y component of points + * @param[in] space_offsets: beginning index of each space, plus the last space's end offset. + * + * @returns An owning object of the result of the hausdorff distances. + * A table view containing the split view for each input space. + * + * @throw cudf::cuda_error if `xs` and `ys` lengths differ + * @throw cudf::cuda_error if `xs` and `ys` types differ + * @throw cudf::cuda_error if `space_offsets` size is less than `xs` and `xy` + * @throw cudf::cuda_error if `xs`, `ys`, or `space_offsets` has nulls + * + * @note Hausdorff distances are asymmetrical + */ +std::pair, cudf::table_view> directed_hausdorff_distance( + cudf::column_view const& xs, + cudf::column_view const& ys, + cudf::column_view const& space_offsets, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @brief Compute pairwise (multi)point-to-(multi)point Cartesian distance + * + * Computes the cartesian distance between each pair of the multipoints. If input is + * a single point column, the offset of the column should be std::nullopt. + * + * @param points1_xy Column of xy-coordinates of the first point in each pair + * @param multipoints1_offset Index to the first point of each multipoint in points1_xy + * @param points2_xy Column of xy-coordinates of the second point in each pair + * @param multipoints2_offset Index to the second point of each multipoint in points2_xy + * @return Column of distances between each pair of input points + */ + +std::unique_ptr pairwise_point_distance( + std::optional> multipoints1_offset, + cudf::column_view const& points1_xy, + std::optional> multipoints2_offset, + cudf::column_view const& points2_xy, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @brief Compute distance between pairs of points and linestrings + * + * The distance between a point and a linestring is defined as the minimum distance + * between the point and any segment of the linestring. For each input point, this + * function returns the distance between the point and the corresponding linestring. + * + * The following example contains 2 pairs of points and linestrings. + * ``` + * First pair: + * Point: (0, 0) + * Linestring: (0, 1) -> (1, 0) -> (2, 0) + * + * Second pair: + * Point: (1, 1) + * Linestring: (0, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> (3, 1) + * + * The input of the above example is: + * multipoint_geometry_offsets: nullopt + * points_xy: {0, 1, 0, 1} + * multilinestring_geometry_offsets: nullopt + * linestring_part_offsets: {0, 3, 8} + * linestring_xy: {0, 1, 1, 0, 2, 0, 0, 0, 1, 1, 2, 0, 3, 0, 3, 1} + * + * Result: {sqrt(2)/2, 0} + * ``` + * + * The following example contains 3 pairs of MultiPoint and MultiLinestring. + * ``` + * First pair: + * MultiPoint: (0, 1) + * MultiLinestring: (0, -1) -> (-2, -3), (-4, -5) -> (-5, -6) + * + * Second pair: + * MultiPoint: (2, 3), (4, 5) + * MultiLinestring: (7, 8) -> (8, 9) + * + * Third pair: + * MultiPoint: (6, 7), (8, 9) + * MultiLinestring: (9, 10) -> (10, 11) + + * The input of the above example is: + * multipoint_geometry_offsets: {0, 1, 3, 5} + * points_xy: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + * multilinestring_geometry_offsets: {0, 2, 3, 5} + * linestring_part_offsets: {0, 2, 4, 6, 8} + * linestring_points_xy: {0, -1, -2, -3, -4, -5, -5, -6, 7, 8, 8, 9, 9, 10, 10 ,11} + * + * Result: {2.0, 4.24264, 1.41421} + * ``` + * + * @param multipoint_geometry_offsets Beginning and ending indices to each geometry in the + * multi-point + * @param points_xy Interleaved x, y-coordinates of points + * @param multilinestring_geometry_offsets Beginning and ending indices to each geometry in the + * multi-linestring + * @param linestring_part_offsets Beginning and ending indices for each linestring in the point + * array. Because the coordinates are interleaved, the actual starting position for the coordinate + * of linestring `i` is `2*linestring_part_offsets[i]`. + * @param linestring_points_xy Interleaved x, y-coordinates of linestring points. + * @param mr Device memory resource used to allocate the returned column. + * @return A column containing the distance between each pair of corresponding points and + * linestrings. + * + * @note Any optional geometry indices, if is `nullopt`, implies the underlying geometry contains + * only one component. Otherwise, it contains multiple components. + * + * @throws cuspatial::logic_error if the number of (multi)points and (multi)linestrings do not + * match. + * @throws cuspatial::logic_error if the any of the point arrays have mismatched types. + */ +std::unique_ptr pairwise_point_linestring_distance( + std::optional> multipoint_geometry_offsets, + cudf::column_view const& points_xy, + std::optional> multilinestring_geometry_offsets, + cudf::device_span linestring_part_offsets, + cudf::column_view const& linestring_points_xy, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @brief Compute pairwise (multi)point-to-(multi)polygon Cartesian distance + * + * @param multipoints Geometry column of multipoints + * @param multipolygons Geometry column of multipolygons + * @param mr Device memory resource used to allocate the returned column. + * @return Column of distances between each pair of input geometries, same type as input coordinate + * types. + * + * @throw cuspatial::logic_error if `multipoints` and `multipolygons` has different coordinate + * types. + * @throw cuspatial::logic_error if `multipoints` is not a point column and `multipolygons` is not a + * polygon column. + * @throw cuspatial::logic_error if input column sizes mismatch. + */ + +std::unique_ptr pairwise_point_polygon_distance( + geometry_column_view const& multipoints, + geometry_column_view const& multipolygons, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @brief Compute shortest distance between pairs of linestrings + * + * The shortest distance between two linestrings is defined as the shortest distance + * between all pairs of segments of the two linestrings. If any of the segments intersect, + * the distance is 0. The shortest distance between two multilinestrings is defined as the + * the shortest distance between all pairs of linestrings of the two multilinestrings. + * + * The following example contains 4 pairs of linestrings. The first array is a single linestring + * array and the second array is a multilinestring array. + * ``` + * First pair: + * (0, 1) -> (1, 0) -> (-1, 0) + * {(1, 1) -> (2, 1) -> (2, 0) -> (3, 0)} + * + * | + * * #---# + * | \ | + * ----O---*---#---# + * | / + * * + * | + * + * The shortest distance between the two linestrings is the distance + * from point (1, 1) to segment (0, 1) -> (1, 0), which is sqrt(2)/2. + * + * Second pair: + * + * (0, 0) -> (0, 1) + * {(1, 0) -> (1, 1) -> (1, 2), (1, -1) -> (1, -2) -> (1, -3)} + * + * The linestrings in the pairs are parallel. Their distance is 1 (point (0, 0) to point (1, 0)). + * + * Third pair: + * + * (0, 0) -> (2, 2) -> (-2, 0) + * {(2, 0) -> (0, 2), (0, 2) -> (-2, 0)} + * + * The linestrings in the pairs intersect, so their distance is 0. + * + * Forth pair: + * + * (2, 2) -> (-2, -2) + * {(1, 1) -> (5, 5) -> (10, 0), (-1, -1) -> (-5, -5) -> (-10, 0)} + * + * These linestrings contain colinear and overlapping sections, so + * their distance is 0. + * + * The input of above example is: + * multilinestring1_geometry_offsets: nullopt + * linestring1_part_offsets: {0, 3, 5, 8, 10} + * linestring1_points_xy: + * {0, 1, 1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 2, 2, -2, 0, 2, 2, -2, -2} + * + * multilinestring2_geometry_offsets: {0, 1, 3, 5, 7} + * linestring2_offsets: {0, 4, 7, 10, 12, 14, 17, 20} + * linestring2_points_xy: {1, 1, 2, 1, 2, 0, 3, 0, 1, 0, 1, 1, 1, 2, 1, -1, 1, -2, 1, -3, 2, 0, 0, + * 2, 0, 2, -2, 0, 1, 1, 5, 5, 10, 0, -1, -1, -5, -5, -10, 0} + * + * Result: {sqrt(2.0)/2, 1, 0, 0} + * ``` + * + * @param multilinestring1_geometry_offsets Beginning and ending indices to each multilinestring in + * the first multilinestring array. + * @param linestring1_part_offsets Beginning and ending indices for each linestring in the point + * array. Because the coordinates are interleaved, the actual starting position for the coordinate + * of linestring `i` is `2*linestring_part_offsets[i]`. + * @param linestring1_points_xy Interleaved x, y-coordinates of linestring points. + * @param multilinestring2_geometry_offsets Beginning and ending indices to each multilinestring in + * the second multilinestring array. + * @param linestring2_part_offsets Beginning and ending indices for each linestring in the point + * array. Because the coordinates are interleaved, the actual starting position for the coordinate + * of linestring `i` is `2*linestring_part_offsets[i]`. + * @param linestring2_points_xy Interleaved x, y-coordinates of linestring points. + * @param mr Device memory resource used to allocate the returned column's device memory + * @return A column of shortest distances between each pair of (multi)linestrings + * + * @note If `multilinestring_geometry_offset` is std::nullopt, the input is a single linestring + * array. + * @note If any of the linestring contains less than 2 points, the behavior is undefined. + * + * @throw cuspatial::logic_error if `linestring1_offsets.size() != linestring2_offsets.size()` + * @throw cuspatial::logic_error if any of the point arrays have mismatched types. + * @throw cuspatial::logic_error if any linestring has fewer than 2 points. + * + */ +std::unique_ptr pairwise_linestring_distance( + std::optional> multilinestring1_geometry_offsets, + cudf::device_span linestring1_part_offsets, + cudf::column_view const& linestring1_points_xy, + std::optional> multilinestring2_geometry_offsets, + cudf::device_span linestring2_part_offsets, + cudf::column_view const& linestring2_points_xy, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @brief Compute pairwise (multi)linestring-to-(multi)polygon Cartesian distance + * + * @param multilinestrings Geometry column of multilinestrings + * @param multipolygons Geometry column of multipolygons + * @param mr Device memory resource used to allocate the returned column. + * @return Column of distances between each pair of input geometries, same type as input coordinate + * types. + * + * @throw cuspatial::logic_error if `multilinestrings` and `multipolygons` have different coordinate + * types. + * @throw cuspatial::logic_error if `multilinestrings` is not a linestring column and + * `multipolygons` is not a polygon column. + * @throw cuspatial::logic_error if input column sizes mismatch. + */ + +std::unique_ptr pairwise_linestring_polygon_distance( + geometry_column_view const& multilinestrings, + geometry_column_view const& multipolygons, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + +/** + * @} // end of doxygen group + */ + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/distance/hausdorff.hpp b/cpp/include/cuspatial/distance/hausdorff.hpp deleted file mode 100644 index 27f4aa600..000000000 --- a/cpp/include/cuspatial/distance/hausdorff.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include - -#include - -#include - -namespace cuspatial { - -/** - * @brief computes Hausdorff distances for all pairs in a collection of spaces - * - * @ingroup distance - * - * https://en.wikipedia.org/wiki/Hausdorff_distance - * - * Example in 1D (this function operates in 2D): - * ``` - * spaces - * [0 2 5] [9] [3 7] - * - * spaces represented as points per space and concatenation of all points - * [0 2 5 9 3 7] [3 1 2] - * - * note: the following matrices are visually separated to highlight the relationship of a pair of - * points with the pair of spaces from which it is produced - * - * cartesian product of all - * points by pair of spaces distance between points - * +----------+----+-------+ +---------+---+------+ - * : 00 02 05 : 09 : 03 07 : : 0 2 5 : 9 : 3 7 : - * : 20 22 25 : 29 : 23 27 : : 2 0 3 : 7 : 1 5 : - * : 50 52 55 : 59 : 53 57 : : 5 3 0 : 4 : 2 2 : - * +----------+----+-------+ +---------+---+------+ - * : 90 92 95 : 99 : 93 97 : : 9 7 4 : 0 : 6 2 : - * +----------+----+-------+ +---------+---+------+ - * : 30 32 35 : 39 : 33 37 : : 3 1 2 : 6 : 0 4 : - * : 70 72 75 : 79 : 73 77 : : 7 5 2 : 2 : 4 0 : - * +----------+----+-------+ +---------+---+------+ - - * minimum distance from - * every point in one Hausdorff distance is - * space to any point in the maximum of the - * the other space minimum distances - * +----------+----+-------+ +---------+---+------+ - * : 0 : 9 : 3 : : 0 : 9 : 3 : - * : 0 : 7 : 1 : : : : : - * : 0 : 4 : 2 : : : : : - * +----------+----+-------+ +---------+---+------+ - * : 4 : 0 : 2 : : 4 : 0 : 2 : - * +----------+----+-------+ +---------+---+------+ - * : 1 : 6 : 0 : : : 6 : 0 : - * : 2 : 2 : 0 : : 2 : : : - * +----------+----+-------+ +---------+---+------+ - * - * Returns: - * column: [0 4 2 9 0 6 3 2 0] - * table_view: [0 4 2] [9 0 6] [3 2 0] - * - * ``` - * - * @param[in] xs: x component of points - * @param[in] ys: y component of points - * @param[in] space_offsets: beginning index of each space, plus the last space's end offset. - * - * @returns An owning object of the result of the hausdorff distances. - * A table view containing the split view for each input space. - * - * @throw cudf::cuda_error if `xs` and `ys` lengths differ - * @throw cudf::cuda_error if `xs` and `ys` types differ - * @throw cudf::cuda_error if `space_offsets` size is less than `xs` and `xy` - * @throw cudf::cuda_error if `xs`, `ys`, or `space_offsets` has nulls - * - * @note Hausdorff distances are asymmetrical - */ -std::pair, cudf::table_view> directed_hausdorff_distance( - cudf::column_view const& xs, - cudf::column_view const& ys, - cudf::column_view const& space_offsets, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/distance/haversine.hpp b/cpp/include/cuspatial/distance/haversine.hpp deleted file mode 100644 index 3e66610cc..000000000 --- a/cpp/include/cuspatial/distance/haversine.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute haversine distances between points in set A and the corresponding points in set B. - * - * @ingroup distance - * - * https://en.wikipedia.org/wiki/Haversine_formula - * - * @param[in] a_lon: longitude of points in set A - * @param[in] a_lat: latitude of points in set A - * @param[in] b_lon: longitude of points in set B - * @param[in] b_lat: latitude of points in set B - * @param[in] radius: radius of the sphere on which the points reside. default: 6371.0 (aprx. radius - * of earth in km) - * - * @return array of distances for all (a_lon[i], a_lat[i]) and (b_lon[i], b_lat[i]) point pairs - */ -std::unique_ptr haversine_distance( - cudf::column_view const& a_lon, - cudf::column_view const& a_lat, - cudf::column_view const& b_lon, - cudf::column_view const& b_lat, - double const radius = EARTH_RADIUS_KM, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -/** - * @} // end of doxygen group - */ - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/distance/linestring_distance.hpp b/cpp/include/cuspatial/distance/linestring_distance.hpp deleted file mode 100644 index 051f016c3..000000000 --- a/cpp/include/cuspatial/distance/linestring_distance.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include - -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute shortest distance between pairs of linestrings - * @ingroup distance - * - * The shortest distance between two linestrings is defined as the shortest distance - * between all pairs of segments of the two linestrings. If any of the segments intersect, - * the distance is 0. The shortest distance between two multilinestrings is defined as the - * the shortest distance between all pairs of linestrings of the two multilinestrings. - * - * The following example contains 4 pairs of linestrings. The first array is a single linestring - * array and the second array is a multilinestring array. - * ``` - * First pair: - * (0, 1) -> (1, 0) -> (-1, 0) - * {(1, 1) -> (2, 1) -> (2, 0) -> (3, 0)} - * - * | - * * #---# - * | \ | - * ----O---*---#---# - * | / - * * - * | - * - * The shortest distance between the two linestrings is the distance - * from point (1, 1) to segment (0, 1) -> (1, 0), which is sqrt(2)/2. - * - * Second pair: - * - * (0, 0) -> (0, 1) - * {(1, 0) -> (1, 1) -> (1, 2), (1, -1) -> (1, -2) -> (1, -3)} - * - * The linestrings in the pairs are parallel. Their distance is 1 (point (0, 0) to point (1, 0)). - * - * Third pair: - * - * (0, 0) -> (2, 2) -> (-2, 0) - * {(2, 0) -> (0, 2), (0, 2) -> (-2, 0)} - * - * The linestrings in the pairs intersect, so their distance is 0. - * - * Forth pair: - * - * (2, 2) -> (-2, -2) - * {(1, 1) -> (5, 5) -> (10, 0), (-1, -1) -> (-5, -5) -> (-10, 0)} - * - * These linestrings contain colinear and overlapping sections, so - * their distance is 0. - * - * The input of above example is: - * multilinestring1_geometry_offsets: nullopt - * linestring1_part_offsets: {0, 3, 5, 8, 10} - * linestring1_points_xy: - * {0, 1, 1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 2, 2, -2, 0, 2, 2, -2, -2} - * - * multilinestring2_geometry_offsets: {0, 1, 3, 5, 7} - * linestring2_offsets: {0, 4, 7, 10, 12, 14, 17, 20} - * linestring2_points_xy: {1, 1, 2, 1, 2, 0, 3, 0, 1, 0, 1, 1, 1, 2, 1, -1, 1, -2, 1, -3, 2, 0, 0, - * 2, 0, 2, -2, 0, 1, 1, 5, 5, 10, 0, -1, -1, -5, -5, -10, 0} - * - * Result: {sqrt(2.0)/2, 1, 0, 0} - * ``` - * - * @param multilinestring1_geometry_offsets Beginning and ending indices to each multilinestring in - * the first multilinestring array. - * @param linestring1_part_offsets Beginning and ending indices for each linestring in the point - * array. Because the coordinates are interleaved, the actual starting position for the coordinate - * of linestring `i` is `2*linestring_part_offsets[i]`. - * @param linestring1_points_xy Interleaved x, y-coordinates of linestring points. - * @param multilinestring2_geometry_offsets Beginning and ending indices to each multilinestring in - * the second multilinestring array. - * @param linestring2_part_offsets Beginning and ending indices for each linestring in the point - * array. Because the coordinates are interleaved, the actual starting position for the coordinate - * of linestring `i` is `2*linestring_part_offsets[i]`. - * @param linestring2_points_xy Interleaved x, y-coordinates of linestring points. - * @param mr Device memory resource used to allocate the returned column's device memory - * @return A column of shortest distances between each pair of (multi)linestrings - * - * @note If `multilinestring_geometry_offset` is std::nullopt, the input is a single linestring - * array. - * @note If any of the linestring contains less than 2 points, the behavior is undefined. - * - * @throw cuspatial::logic_error if `linestring1_offsets.size() != linestring2_offsets.size()` - * @throw cuspatial::logic_error if any of the point arrays have mismatched types. - * @throw cuspatial::logic_error if any linestring has fewer than 2 points. - * - */ -std::unique_ptr pairwise_linestring_distance( - std::optional> multilinestring1_geometry_offsets, - cudf::device_span linestring1_part_offsets, - cudf::column_view const& linestring1_points_xy, - std::optional> multilinestring2_geometry_offsets, - cudf::device_span linestring2_part_offsets, - cudf::column_view const& linestring2_points_xy, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); -} // namespace cuspatial diff --git a/cpp/include/cuspatial/distance/linestring_polygon_distance.hpp b/cpp/include/cuspatial/distance/linestring_polygon_distance.hpp deleted file mode 100644 index 62b84e432..000000000 --- a/cpp/include/cuspatial/distance/linestring_polygon_distance.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @brief Compute pairwise (multi)linestring-to-(multi)polygon Cartesian distance - * - * @param multilinestrings Geometry column of multilinestrings - * @param multipolygons Geometry column of multipolygons - * @param mr Device memory resource used to allocate the returned column. - * @return Column of distances between each pair of input geometries, same type as input coordinate - * types. - * - * @throw cuspatial::logic_error if `multilinestrings` and `multipolygons` have different coordinate - * types. - * @throw cuspatial::logic_error if `multilinestrings` is not a linestring column and - * `multipolygons` is not a polygon column. - * @throw cuspatial::logic_error if input column sizes mismatch. - */ - -std::unique_ptr pairwise_linestring_polygon_distance( - geometry_column_view const& multilinestrings, - geometry_column_view const& multipolygons, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/distance/point_distance.hpp b/cpp/include/cuspatial/distance/point_distance.hpp deleted file mode 100644 index 0a5af08e0..000000000 --- a/cpp/include/cuspatial/distance/point_distance.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @brief Compute pairwise (multi)point-to-(multi)point Cartesian distance - * - * Computes the cartesian distance between each pair of the multipoints. If input is - * a single point column, the offset of the column should be std::nullopt. - * - * @param points1_xy Column of xy-coordinates of the first point in each pair - * @param multipoints1_offset Index to the first point of each multipoint in points1_xy - * @param points2_xy Column of xy-coordinates of the second point in each pair - * @param multipoints2_offset Index to the second point of each multipoint in points2_xy - * @return Column of distances between each pair of input points - */ - -std::unique_ptr pairwise_point_distance( - std::optional> multipoints1_offset, - cudf::column_view const& points1_xy, - std::optional> multipoints2_offset, - cudf::column_view const& points2_xy, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/distance/point_linestring_distance.hpp b/cpp/include/cuspatial/distance/point_linestring_distance.hpp deleted file mode 100644 index 4f75cabe7..000000000 --- a/cpp/include/cuspatial/distance/point_linestring_distance.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute distance between pairs of points and linestrings - * - * The distance between a point and a linestring is defined as the minimum distance - * between the point and any segment of the linestring. For each input point, this - * function returns the distance between the point and the corresponding linestring. - * - * The following example contains 2 pairs of points and linestrings. - * ``` - * First pair: - * Point: (0, 0) - * Linestring: (0, 1) -> (1, 0) -> (2, 0) - * - * Second pair: - * Point: (1, 1) - * Linestring: (0, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> (3, 1) - * - * The input of the above example is: - * multipoint_geometry_offsets: nullopt - * points_xy: {0, 1, 0, 1} - * multilinestring_geometry_offsets: nullopt - * linestring_part_offsets: {0, 3, 8} - * linestring_xy: {0, 1, 1, 0, 2, 0, 0, 0, 1, 1, 2, 0, 3, 0, 3, 1} - * - * Result: {sqrt(2)/2, 0} - * ``` - * - * The following example contains 3 pairs of MultiPoint and MultiLinestring. - * ``` - * First pair: - * MultiPoint: (0, 1) - * MultiLinestring: (0, -1) -> (-2, -3), (-4, -5) -> (-5, -6) - * - * Second pair: - * MultiPoint: (2, 3), (4, 5) - * MultiLinestring: (7, 8) -> (8, 9) - * - * Third pair: - * MultiPoint: (6, 7), (8, 9) - * MultiLinestring: (9, 10) -> (10, 11) - - * The input of the above example is: - * multipoint_geometry_offsets: {0, 1, 3, 5} - * points_xy: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - * multilinestring_geometry_offsets: {0, 2, 3, 5} - * linestring_part_offsets: {0, 2, 4, 6, 8} - * linestring_points_xy: {0, -1, -2, -3, -4, -5, -5, -6, 7, 8, 8, 9, 9, 10, 10 ,11} - * - * Result: {2.0, 4.24264, 1.41421} - * ``` - * - * @param multipoint_geometry_offsets Beginning and ending indices to each geometry in the - * multi-point - * @param points_xy Interleaved x, y-coordinates of points - * @param multilinestring_geometry_offsets Beginning and ending indices to each geometry in the - * multi-linestring - * @param linestring_part_offsets Beginning and ending indices for each linestring in the point - * array. Because the coordinates are interleaved, the actual starting position for the coordinate - * of linestring `i` is `2*linestring_part_offsets[i]`. - * @param linestring_points_xy Interleaved x, y-coordinates of linestring points. - * @param mr Device memory resource used to allocate the returned column. - * @return A column containing the distance between each pair of corresponding points and - * linestrings. - * - * @note Any optional geometry indices, if is `nullopt`, implies the underlying geometry contains - * only one component. Otherwise, it contains multiple components. - * - * @throws cuspatial::logic_error if the number of (multi)points and (multi)linestrings do not - * match. - * @throws cuspatial::logic_error if the any of the point arrays have mismatched types. - */ -std::unique_ptr pairwise_point_linestring_distance( - std::optional> multipoint_geometry_offsets, - cudf::column_view const& points_xy, - std::optional> multilinestring_geometry_offsets, - cudf::device_span linestring_part_offsets, - cudf::column_view const& linestring_points_xy, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/distance/point_polygon_distance.hpp b/cpp/include/cuspatial/distance/point_polygon_distance.hpp deleted file mode 100644 index 97276b581..000000000 --- a/cpp/include/cuspatial/distance/point_polygon_distance.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @brief Compute pairwise (multi)point-to-(multi)polygon Cartesian distance - * - * @param multipoints Geometry column of multipoints - * @param multipolygons Geometry column of multipolygons - * @param mr Device memory resource used to allocate the returned column. - * @return Column of distances between each pair of input geometries, same type as input coordinate - * types. - * - * @throw cuspatial::logic_error if `multipoints` and `multipolygons` has different coordinate - * types. - * @throw cuspatial::logic_error if `multipoints` is not a point column and `multipolygons` is not a - * polygon column. - * @throw cuspatial::logic_error if input column sizes mismatch. - */ - -std::unique_ptr pairwise_point_polygon_distance( - geometry_column_view const& multipoints, - geometry_column_view const& multipolygons, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/hausdorff.cuh b/cpp/include/cuspatial/hausdorff.cuh deleted file mode 100644 index 6fe38a006..000000000 --- a/cpp/include/cuspatial/hausdorff.cuh +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @brief Computes Hausdorff distances for all pairs in a collection of spaces - * - * https://en.wikipedia.org/wiki/Hausdorff_distance - * - * Example in 1D (this function operates in 2D): - * ``` - * spaces - * [0 2 5] [9] [3 7] - * - * spaces represented as points per space and concatenation of all points - * [0 2 5 9 3 7] [3 1 2] - * - * note: the following matrices are visually separated to highlight the relationship of a pair of - * points with the pair of spaces from which it is produced - * - * cartesian product of all - * points by pair of spaces distance between points - * +----------+----+-------+ +---------+---+------+ - * : 00 02 05 : 09 : 03 07 : : 0 2 5 : 9 : 3 7 : - * : 20 22 25 : 29 : 23 27 : : 2 0 3 : 7 : 1 5 : - * : 50 52 55 : 59 : 53 57 : : 5 3 0 : 4 : 2 2 : - * +----------+----+-------+ +---------+---+------+ - * : 90 92 95 : 99 : 93 97 : : 9 7 4 : 0 : 6 2 : - * +----------+----+-------+ +---------+---+------+ - * : 30 32 35 : 39 : 33 37 : : 3 1 2 : 6 : 0 4 : - * : 70 72 75 : 79 : 73 77 : : 7 5 2 : 2 : 4 0 : - * +----------+----+-------+ +---------+---+------+ - - * minimum distance from - * every point in one Hausdorff distance is - * space to any point in the maximum of the - * the other space minimum distances - * +----------+----+-------+ +---------+---+------+ - * : 0 : 9 : 3 : : 0 : 9 : 3 : - * : 0 : 7 : 1 : : : : : - * : 0 : 4 : 2 : : : : : - * +----------+----+-------+ +---------+---+------+ - * : 4 : 0 : 2 : : 4 : 0 : 2 : - * +----------+----+-------+ +---------+---+------+ - * : 1 : 6 : 0 : : : 6 : 0 : - * : 2 : 2 : 0 : : 2 : : : - * +----------+----+-------+ +---------+---+------+ - * - * returned as concatenation of columns - * [0 2 4 3 0 2 9 6 0] - * ``` - * - * @param[in] points_first: xs: beginning of range of (x,y) points - * @param[in] points_lasts: xs: end of range of (x,y) points - * @param[in] space_offsets_first: beginning of range of indices to each space. - * @param[in] space_offsets_first: end of range of indices to each space. Last index is the last - * @param[in] distance_first: beginning of range of output Hausdorff distance for each pair of - * spaces - * - * @tparam PointIt Iterator to input points. Points must be of a type that is convertible to - * `cuspatial::vec_2d`. Must meet the requirements of [LegacyRandomAccessIterator][LinkLRAI] and - * be device-accessible. - * @tparam OffsetIt Iterator to space offsets. Value type must be integral. Must meet the - * requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OutputIt Output iterator. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable. - * - * @pre All iterators must have the same underlying floating-point value type. - * - * @return Output iterator to the element past the last distance computed. - * - * @note Hausdorff distances are asymmetrical - */ -template -OutputIt directed_hausdorff_distance(PointIt points_first, - PointIt points_last, - OffsetIt space_offsets_first, - OffsetIt space_offsets_last, - OutputIt distance_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/haversine.cuh b/cpp/include/cuspatial/haversine.cuh deleted file mode 100644 index dc1436fde..000000000 --- a/cpp/include/cuspatial/haversine.cuh +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include - -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute haversine distances between points in set A to the corresponding points in set B. - * - * @ingroup distance - * - * Computes N haversine distances, where N is `std::distance(a_lonlat_first, a_lonlat_last)`. - * The distance for each `a_lonlat[i]` and `b_lonlat[i]` point pair is assigned to - * `distance_first[i]`. `distance_first` must be an iterator to output storage allocated for N - * distances. - * - * Computed distances will have the same units as `radius`. - * - * https://en.wikipedia.org/wiki/Haversine_formula - * - * @param[in] a_lonlat_first: beginning of range of (longitude, latitude) locations in set A - * @param[in] a_lonlat_last: end of range of (longitude, latitude) locations in set A - * @param[in] b_lonlat_first: beginning of range of (longitude, latitude) locations in set B - * @param[out] distance_first: beginning of output range of haversine distances - * @param[in] radius: radius of the sphere on which the points reside. default: 6371.0 - * (approximate radius of Earth in km) - * @param[in] stream: The CUDA stream on which to perform computations and allocate memory. - * - * @tparam LonLatItA Iterator to input location set A. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam LonLatItB Iterator to input location set B. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OutputIt Output iterator. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable. - * @tparam T The underlying coordinate type. Must be a floating-point type. - * - * @pre All iterators must have the same `Location` type, with the same underlying floating-point - * coordinate type (e.g. `cuspatial::vec_2d`). - * - * @return Output iterator to the element past the last distance computed. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template > -OutputIt haversine_distance(LonLatItA a_lonlat_first, - LonLatItA a_lonlat_last, - LonLatItB b_lonlat_first, - OutputIt distance_first, - T const radius = EARTH_RADIUS_KM, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/linestring_intersection.cuh b/cpp/include/cuspatial/intersection.cuh similarity index 96% rename from cpp/include/cuspatial/linestring_intersection.cuh rename to cpp/include/cuspatial/intersection.cuh index cbc7c03dc..331e6eb0a 100644 --- a/cpp/include/cuspatial/linestring_intersection.cuh +++ b/cpp/include/cuspatial/intersection.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,4 +92,4 @@ linestring_intersection_result pairwise_linestring_intersection( } // namespace cuspatial -#include +#include diff --git a/cpp/include/cuspatial/linestring_intersection.hpp b/cpp/include/cuspatial/intersection.hpp similarity index 100% rename from cpp/include/cuspatial/linestring_intersection.hpp rename to cpp/include/cuspatial/intersection.hpp diff --git a/cpp/include/cuspatial/iterator_factory.cuh b/cpp/include/cuspatial/iterator_factory.cuh index a409cc6da..1f026512c 100644 --- a/cpp/include/cuspatial/iterator_factory.cuh +++ b/cpp/include/cuspatial/iterator_factory.cuh @@ -16,7 +16,6 @@ #pragma once -#include #include #include #include @@ -24,6 +23,7 @@ #include #include +#include #include #include #include @@ -35,6 +35,17 @@ namespace cuspatial { namespace detail { + +/** + * @internal + * @brief Helper to create a `transform_iterator` that transforms sequential values. + */ +template +inline CUSPATIAL_HOST_DEVICE auto make_counting_transform_iterator(IndexType start, UnaryFunction f) +{ + return thrust::make_transform_iterator(thrust::make_counting_iterator(start), f); +} + /** * @internal * @brief Helper to convert a tuple of elements into a `vec_2d` diff --git a/cpp/include/cuspatial/linestring_bounding_box.hpp b/cpp/include/cuspatial/linestring_bounding_box.hpp deleted file mode 100644 index e39177c52..000000000 --- a/cpp/include/cuspatial/linestring_bounding_box.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute minimum bounding boxes of a set of linestrings and an expansion radius. - * - * @ingroup spatial_relationship - * - * @param linestring_offsets Begin indices of the first point in each linestring (i.e. prefix-sum) - * @param x Linestring point x-coordinates - * @param y Linestring point y-coordinates - * @param expansion_radius Radius of each linestring point - * - * @return a cudf table of bounding boxes as four columns of the same type as `x` and `y`: - * x_min - the minimum x-coordinate of each bounding box - * y_min - the minimum y-coordinate of each bounding box - * x_max - the maximum x-coordinate of each bounding box - * y_max - the maximum y-coordinate of each bounding box - * - * @pre For compatibility with GeoArrow, the size of @p linestring_offsets should be one more than - * the number of linestrings to process. The final offset is not used by this function, but the - * number of offsets determines the output size. - */ - -std::unique_ptr linestring_bounding_boxes( - cudf::column_view const& linestring_offsets, - cudf::column_view const& x, - cudf::column_view const& y, - double expansion_radius, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/linestring_bounding_boxes.cuh b/cpp/include/cuspatial/linestring_bounding_boxes.cuh deleted file mode 100644 index 62e18f3cd..000000000 --- a/cpp/include/cuspatial/linestring_bounding_boxes.cuh +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute minimum bounding box for each linestring. - * - * @ingroup spatial_relationship - * - * @tparam LinestringOffsetIterator Iterator type to linestring offsets. Must meet the requirements - * of [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam VertexIterator Iterator type to linestring vertices. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam BoundingBoxIterator Iterator type to bounding boxes. Must be writable using data of type - * `cuspatial::box`. Must meet the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be - * device-writeable. - * @tparam T The coordinate data value type. - * @tparam IndexT The offset data value type. - * @param linestring_offsets_first Iterator to beginning of the range of input polygon offsets. - * @param linestring_offsets_last Iterator to end of the range of input polygon offsets. - * @param linestring_vertices_first Iterator to beginning of the range of input polygon vertices. - * @param linestring_vertices_last Iterator to end of the range of input polygon vertices. - * @param bounding_boxes_first Iterator to beginning of the range of output bounding boxes. - * @param expansion_radius Optional radius to expand each vertex of the output bounding boxes. - * @param stream the CUDA stream on which to perform computations and allocate memory. - * - * @return An iterator to the end of the range of output bounding boxes. - * - * @pre For compatibility with GeoArrow, the number of linestring offsets - * `std::distance(linestring_offsets_first, linestring_offsets_last)` should be one more than the - * number of linestrings. The final offset is not used by this function, but the number of offsets - * determines the output size. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template , - class IndexT = iterator_value_type> -BoundingBoxIterator linestring_bounding_boxes( - LinestringOffsetIterator linestring_offsets_first, - LinestringOffsetIterator linestring_offsets_last, - VertexIterator linestring_vertices_first, - VertexIterator linestring_vertices_last, - BoundingBoxIterator bounding_boxes_first, - T expansion_radius = T{0}, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/linestring_distance.cuh b/cpp/include/cuspatial/linestring_distance.cuh deleted file mode 100644 index c6f0de964..000000000 --- a/cpp/include/cuspatial/linestring_distance.cuh +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @copybrief cuspatial::pairwise_linestring_distance - * - * The shortest distance between two linestrings is defined as the shortest distance - * between all pairs of segments of the two linestrings. If any of the segments intersect, - * the distance is 0. - * - * @tparam MultiLinestringRange an instance of template type `multilinestring_range` - * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI) - * and be device writable. - * - * @param multilinestrings1 Range object of the lhs multilinestring array - * @param multilinestrings2 Range object of the rhs multilinestring array - * @param stream The CUDA stream to use for device memory operations and kernel launches. - * @return Output iterator to the element past the last distance computed. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template -OutputIt pairwise_linestring_distance(MultiLinestringRange1 multilinestrings1, - MultiLinstringRange2 multilinestrings2, - OutputIt distances_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/linestring_polygon_distance.cuh b/cpp/include/cuspatial/linestring_polygon_distance.cuh deleted file mode 100644 index a1adf9222..000000000 --- a/cpp/include/cuspatial/linestring_polygon_distance.cuh +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @brief Computes pairwise multilinestring to multipolygon distance - * - * @tparam MultiLinestringRange An instance of template type `multipoint_range` - * @tparam MultiPolygonRange An instance of template type `multipolygon_range` - * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). - * Must be an iterator to type convertible from floating points. - * - * @param multilinestrings Range of multilinestrings, one per computed distance pair. - * @param multipolygons Range of multipolygons, one per computed distance pair. - * @param stream The CUDA stream on which to perform computations - * @return Output Iterator past the last distance computed - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template -OutputIt pairwise_linestring_polygon_distance( - MultiLinestringRange multilinestrings, - MultiPolygonRange multipoiygons, - OutputIt distances_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/point_linestring_nearest_points.cuh b/cpp/include/cuspatial/nearest_points.cuh similarity index 100% rename from cpp/include/cuspatial/point_linestring_nearest_points.cuh rename to cpp/include/cuspatial/nearest_points.cuh diff --git a/cpp/include/cuspatial/point_linestring_nearest_points.hpp b/cpp/include/cuspatial/nearest_points.hpp similarity index 98% rename from cpp/include/cuspatial/point_linestring_nearest_points.hpp rename to cpp/include/cuspatial/nearest_points.hpp index 17c022be5..640a1c9b6 100644 --- a/cpp/include/cuspatial/point_linestring_nearest_points.hpp +++ b/cpp/include/cuspatial/nearest_points.hpp @@ -24,7 +24,11 @@ namespace cuspatial { /** - * @ingroup nearest_points + * @addtogroup nearest_points + * @{ + */ + +/** * @brief Container for the result of `pairwise_point_linestring_nearest_points` */ struct point_linestring_nearest_points_result { @@ -45,7 +49,6 @@ struct point_linestring_nearest_points_result { }; /** - * @ingroup nearest_points * @brief Compute the nearest points and geometry ID between pairs of (multi)point and * (multi)linestring * @@ -164,4 +167,8 @@ point_linestring_nearest_points_result pairwise_point_linestring_nearest_points( cudf::column_view linestring_points_xy, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); +/** + * @} // end of doxygen group + */ + } // namespace cuspatial diff --git a/cpp/include/cuspatial/pairwise_point_in_polygon.cuh b/cpp/include/cuspatial/pairwise_point_in_polygon.cuh deleted file mode 100644 index ac921556a..000000000 --- a/cpp/include/cuspatial/pairwise_point_in_polygon.cuh +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -namespace cuspatial { - -/** - * @ingroup spatial_relationship - * - * @brief Given (point, polygon) pairs, tests whether the point of each pair is inside the polygon - * of the pair. - * - * Tests whether each point is inside a corresponding polygon. Points on the edges of the - * polygon are not considered to be inside. - * Polygons are a collection of one or more rings. Rings are a collection of three or more vertices. - * - * Each input point will map to one `int32_t` element in the output. - * - * - * @tparam Cart2dItA iterator type for point array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam Cart2dItB iterator type for point array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OffsetIteratorA iterator type for offset array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OffsetIteratorB iterator type for offset array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OutputIt iterator type for output array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI], be device-accessible, mutable and - * iterate on `int32_t` type. - * - * @param test_points_first begin of range of test points - * @param test_points_last end of range of test points - * @param polygon_offsets_first begin of range of indices to the first ring in each polygon - * @param polygon_offsets_last end of range of indices to the first ring in each polygon - * @param ring_offsets_first begin of range of indices to the first point in each ring - * @param ring_offsets_last end of range of indices to the first point in each ring - * @param polygon_points_first begin of range of polygon points - * @param polygon_points_last end of range of polygon points - * @param output begin iterator to the output buffer - * @param stream The CUDA stream to use for kernel launches. - * @return iterator to one past the last element in the output buffer - * - * @note Direction of rings does not matter. - * @note This algorithm supports the ESRI shapefile format, but assumes all polygons are "clean" (as - * defined by the format), and does _not_ verify whether the input adheres to the shapefile format. - * @note The points of the rings must be explicitly closed. - * @note Overlapping rings negate each other. This behavior is not limited to a single negation, - * allowing for "islands" within the same polygon. - * @note `poly_ring_offsets` must contain only the rings that make up the polygons indexed by - * `poly_offsets`. If there are rings in `poly_ring_offsets` that are not part of the polygons in - * `poly_offsets`, results are likely to be incorrect and behavior is undefined. - * - * ``` - * poly w/two rings poly w/four rings - * +-----------+ +------------------------+ - * :███████████: :████████████████████████: - * :███████████: :██+------------------+██: - * :██████+----:------+ :██: +----+ +----+ :██: - * :██████: :██████: :██: :████: :████: :██: - * +------;----+██████: :██: :----: :----: :██: - * :███████████: :██+------------------+██: - * :███████████: :████████████████████████: - * +-----------+ +------------------------+ - * ``` - * - * @pre All point iterators must have the same `vec_2d` value type, with the same underlying - * floating-point coordinate type (e.g. `cuspatial::vec_2d`). - * @pre All offset iterators must have the same integral value type. - * @pre Output iterator must be mutable and iterate on int32_t type. - * - * @throw cuspatial::logic_error polygon has less than 1 ring. - * @throw cuspatial::logic_error polygon has less than 4 vertices. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template -OutputIt pairwise_point_in_polygon(Cart2dItA test_points_first, - Cart2dItA test_points_last, - OffsetIteratorA polygon_offsets_first, - OffsetIteratorA polygon_offsets_last, - OffsetIteratorB poly_ring_offsets_first, - OffsetIteratorB poly_ring_offsets_last, - Cart2dItB polygon_points_first, - Cart2dItB polygon_points_last, - OutputIt output, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/pairwise_point_in_polygon.hpp b/cpp/include/cuspatial/pairwise_point_in_polygon.hpp deleted file mode 100644 index 76563d2fc..000000000 --- a/cpp/include/cuspatial/pairwise_point_in_polygon.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include -#include - -#include - -#include - -namespace cuspatial { - -/** - * @addtogroup spatial_relationship - * @{ - */ - -/** - * @brief Given (point, polygon pairs), tests whether the point of each pair is inside the polygon - * of the pair. - * - * Tests that each point is or is not inside of the polygon in the corresponding index. - * Polygons are a collection of one or more * rings. Rings are a collection of three or more - * vertices. - * - * @param[in] test_points_x: x-coordinates of points to test - * @param[in] test_points_y: y-coordinates of points to test - * @param[in] poly_offsets: beginning index of the first ring in each polygon - * @param[in] poly_ring_offsets: beginning index of the first point in each ring - * @param[in] poly_points_x: x-coordinates of polygon points - * @param[in] poly_points_y: y-coordinates of polygon points - * - * @returns A column of booleans for each point/polygon pair. - * - * @note Direction of rings does not matter. - * @note Supports open or closed polygon formats. - * @note This algorithm supports the ESRI shapefile format, but assumes all polygons are "clean" (as - * defined by the format), and does _not_ verify whether the input adheres to the shapefile format. - * @note Overlapping rings negate each other. This behavior is not limited to a single negation, - * allowing for "islands" within the same polygon. - * @note `poly_ring_offsets` must contain only the rings that make up the polygons indexed by - * `poly_offsets`. If there are rings in `poly_ring_offsets` that are not part of the polygons in - * `poly_offsets`, results are likely to be incorrect and behavior is undefined. - * - * ``` - * poly w/two rings poly w/four rings - * +-----------+ +------------------------+ - * :███████████: :████████████████████████: - * :███████████: :██+------------------+██: - * :██████+----:------+ :██: +----+ +----+ :██: - * :██████: :██████: :██: :████: :████: :██: - * +------;----+██████: :██: :----: :----: :██: - * :███████████: :██+------------------+██: - * :███████████: :████████████████████████: - * +-----------+ +------------------------+ - * ``` - */ -std::unique_ptr pairwise_point_in_polygon( - cudf::column_view const& test_points_x, - cudf::column_view const& test_points_y, - cudf::column_view const& poly_offsets, - cudf::column_view const& poly_ring_offsets, - cudf::column_view const& poly_points_x, - cudf::column_view const& poly_points_y, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -/** - * @} // end of doxygen group - */ - -} // namespace cuspatial diff --git a/cpp/include/cuspatial/point_distance.cuh b/cpp/include/cuspatial/point_distance.cuh deleted file mode 100644 index 7d7321b53..000000000 --- a/cpp/include/cuspatial/point_distance.cuh +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @copybrief cuspatial::pairwise_point_distance - * - * @tparam MultiPointArrayViewA An instance of template type `array_view::multipoint_array` - * @tparam MultiPointArrayViewB An instance of template type `array_view::multipoint_array` - * - * @param multipoints1 Range of first multipoint in each distance pair. - * @param multipoints2 Range of second multipoint in each distance pair. - * @return Iterator past the last distance computed - */ -template -OutputIt pairwise_point_distance(MultiPointArrayViewA multipoints1, - MultiPointArrayViewB multipoints2, - OutputIt distances_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/point_in_polygon.cuh b/cpp/include/cuspatial/point_in_polygon.cuh index 8fcda7f80..6ae058acd 100644 --- a/cpp/include/cuspatial/point_in_polygon.cuh +++ b/cpp/include/cuspatial/point_in_polygon.cuh @@ -21,8 +21,11 @@ namespace cuspatial { /** - * @ingroup spatial_relationship - * + * @addtogroup spatial_relationship + * @{ + */ + +/** * @brief Tests whether the specified points are inside any of the specified polygons. * * Tests whether points are inside at most 31 polygons. Polygons are a collection of one or more @@ -110,6 +113,95 @@ OutputIt point_in_polygon(Cart2dItA test_points_first, OutputIt output, rmm::cuda_stream_view stream = rmm::cuda_stream_default); +/** + * @brief Given (point, polygon) pairs, tests whether the point of each pair is inside the polygon + * of the pair. + * + * Tests whether each point is inside a corresponding polygon. Points on the edges of the + * polygon are not considered to be inside. + * Polygons are a collection of one or more rings. Rings are a collection of three or more vertices. + * + * Each input point will map to one `int32_t` element in the output. + * + * + * @tparam Cart2dItA iterator type for point array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam Cart2dItB iterator type for point array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam OffsetIteratorA iterator type for offset array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam OffsetIteratorB iterator type for offset array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. + * @tparam OutputIt iterator type for output array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI], be device-accessible, mutable and + * iterate on `int32_t` type. + * + * @param test_points_first begin of range of test points + * @param test_points_last end of range of test points + * @param polygon_offsets_first begin of range of indices to the first ring in each polygon + * @param polygon_offsets_last end of range of indices to the first ring in each polygon + * @param ring_offsets_first begin of range of indices to the first point in each ring + * @param ring_offsets_last end of range of indices to the first point in each ring + * @param polygon_points_first begin of range of polygon points + * @param polygon_points_last end of range of polygon points + * @param output begin iterator to the output buffer + * @param stream The CUDA stream to use for kernel launches. + * @return iterator to one past the last element in the output buffer + * + * @note Direction of rings does not matter. + * @note This algorithm supports the ESRI shapefile format, but assumes all polygons are "clean" (as + * defined by the format), and does _not_ verify whether the input adheres to the shapefile format. + * @note The points of the rings must be explicitly closed. + * @note Overlapping rings negate each other. This behavior is not limited to a single negation, + * allowing for "islands" within the same polygon. + * @note `poly_ring_offsets` must contain only the rings that make up the polygons indexed by + * `poly_offsets`. If there are rings in `poly_ring_offsets` that are not part of the polygons in + * `poly_offsets`, results are likely to be incorrect and behavior is undefined. + * + * ``` + * poly w/two rings poly w/four rings + * +-----------+ +------------------------+ + * :███████████: :████████████████████████: + * :███████████: :██+------------------+██: + * :██████+----:------+ :██: +----+ +----+ :██: + * :██████: :██████: :██: :████: :████: :██: + * +------;----+██████: :██: :----: :----: :██: + * :███████████: :██+------------------+██: + * :███████████: :████████████████████████: + * +-----------+ +------------------------+ + * ``` + * + * @pre All point iterators must have the same `vec_2d` value type, with the same underlying + * floating-point coordinate type (e.g. `cuspatial::vec_2d`). + * @pre All offset iterators must have the same integral value type. + * @pre Output iterator must be mutable and iterate on int32_t type. + * + * @throw cuspatial::logic_error polygon has less than 1 ring. + * @throw cuspatial::logic_error polygon has less than 4 vertices. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +OutputIt pairwise_point_in_polygon(Cart2dItA test_points_first, + Cart2dItA test_points_last, + OffsetIteratorA polygon_offsets_first, + OffsetIteratorA polygon_offsets_last, + OffsetIteratorB poly_ring_offsets_first, + OffsetIteratorB poly_ring_offsets_last, + Cart2dItB polygon_points_first, + Cart2dItB polygon_points_last, + OutputIt output, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + +/** + * @} // end of doxygen group + */ + } // namespace cuspatial #include diff --git a/cpp/include/cuspatial/point_in_polygon.hpp b/cpp/include/cuspatial/point_in_polygon.hpp index 36703e450..11e7381c3 100644 --- a/cpp/include/cuspatial/point_in_polygon.hpp +++ b/cpp/include/cuspatial/point_in_polygon.hpp @@ -80,6 +80,55 @@ std::unique_ptr point_in_polygon( cudf::column_view const& poly_points_y, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); +/** + * @brief Given (point, polygon pairs), tests whether the point of each pair is inside the polygon + * of the pair. + * + * Tests that each point is or is not inside of the polygon in the corresponding index. + * Polygons are a collection of one or more * rings. Rings are a collection of three or more + * vertices. + * + * @param[in] test_points_x: x-coordinates of points to test + * @param[in] test_points_y: y-coordinates of points to test + * @param[in] poly_offsets: beginning index of the first ring in each polygon + * @param[in] poly_ring_offsets: beginning index of the first point in each ring + * @param[in] poly_points_x: x-coordinates of polygon points + * @param[in] poly_points_y: y-coordinates of polygon points + * + * @returns A column of booleans for each point/polygon pair. + * + * @note Direction of rings does not matter. + * @note Supports open or closed polygon formats. + * @note This algorithm supports the ESRI shapefile format, but assumes all polygons are "clean" (as + * defined by the format), and does _not_ verify whether the input adheres to the shapefile format. + * @note Overlapping rings negate each other. This behavior is not limited to a single negation, + * allowing for "islands" within the same polygon. + * @note `poly_ring_offsets` must contain only the rings that make up the polygons indexed by + * `poly_offsets`. If there are rings in `poly_ring_offsets` that are not part of the polygons in + * `poly_offsets`, results are likely to be incorrect and behavior is undefined. + * + * ``` + * poly w/two rings poly w/four rings + * +-----------+ +------------------------+ + * :███████████: :████████████████████████: + * :███████████: :██+------------------+██: + * :██████+----:------+ :██: +----+ +----+ :██: + * :██████: :██████: :██: :████: :████: :██: + * +------;----+██████: :██: :----: :----: :██: + * :███████████: :██+------------------+██: + * :███████████: :████████████████████████: + * +-----------+ +------------------------+ + * ``` + */ +std::unique_ptr pairwise_point_in_polygon( + cudf::column_view const& test_points_x, + cudf::column_view const& test_points_y, + cudf::column_view const& poly_offsets, + cudf::column_view const& poly_ring_offsets, + cudf::column_view const& poly_points_x, + cudf::column_view const& poly_points_y, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + /** * @} // end of doxygen group */ diff --git a/cpp/include/cuspatial/point_linestring_distance.cuh b/cpp/include/cuspatial/point_linestring_distance.cuh deleted file mode 100644 index e5d467265..000000000 --- a/cpp/include/cuspatial/point_linestring_distance.cuh +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -namespace cuspatial { - -/** - * @brief Compute pairwise multipoint to multilinestring distance - * - * @tparam MultiPointRange an instance of template type `multipoint_range` - * @tparam MultiLinestringRange an instance of template type `multilinestring_range` - * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). - * - * @param multipoints The range of multipoints, one per computed distance pair - * @param multilinestrings The range of multilinestrings, one per computed distance pair - * @param stream The CUDA stream to use for device memory operations and kernel launches. - * @return Output iterator to the element past the last distance computed. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template -OutputIt pairwise_point_linestring_distance( - MultiPointRange multipoints, - MultiLinestringRange multilinestrings, - OutputIt distances_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/point_polygon_distance.cuh b/cpp/include/cuspatial/point_polygon_distance.cuh deleted file mode 100644 index eb4674069..000000000 --- a/cpp/include/cuspatial/point_polygon_distance.cuh +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @brief Computes pairwise multipoint to multipolygon distance - * - * @tparam MultiPointRange An instance of template type `multipoint_range` - * @tparam MultiPolygonRange An instance of template type `multipolygon_range` - * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). - * Must be an iterator to type convertible from floating points. - * - * @param multipoints Range of multipoints, one per computed distance pair. - * @param multipolygons Range of multilinestrings, one per computed distance pair. - * @param stream The CUDA stream on which to perform computations - * @return Output Iterator past the last distance computed - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template -OutputIt pairwise_point_polygon_distance(MultiPointRange multipoints, - MultiPolygonRange multipoiygons, - OutputIt distances_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/points_in_range.cuh b/cpp/include/cuspatial/points_in_range.cuh index 79205e417..5b12ab690 100644 --- a/cpp/include/cuspatial/points_in_range.cuh +++ b/cpp/include/cuspatial/points_in_range.cuh @@ -24,11 +24,13 @@ namespace cuspatial { +/** + * @addtogroup nearest_points + */ + /** * @brief Count of points (x,y) that fall within a query range. * - * @ingroup spatial_relationship - * * The query range is defined by a pair of opposite vertices within the coordinate system of the * input points, `v1` and `v2`. A point (x, y) is in the range if `x` lies between `v1.x` and `v2.x` * and `y` lies between `v1.y` and `v2.y`. A point is only counted if it is strictly within the @@ -66,8 +68,6 @@ typename thrust::iterator_traits::difference_type count_points_in_range /** * @brief Copies points (x,y) that fall within a query range. * - * @ingroup spatial_relationship - * * The query range is defined by a pair of opposite vertices of a quadrilateral within the * coordinate system of the input points, `v1` and `v2`. A point (x, y) is in the range if `x` lies * between `v1.x` and `v2.x` and `y` lies between `v1.y` and `v2.y`. A point is only counted if it @@ -113,6 +113,10 @@ OutputIt copy_points_in_range(vec_2d vertex_1, OutputIt output_points_first, rmm::cuda_stream_view stream = rmm::cuda_stream_default); +/** + * @} // end of doxygen group + */ + } // namespace cuspatial #include diff --git a/cpp/include/cuspatial/spatial_window.hpp b/cpp/include/cuspatial/points_in_range.hpp similarity index 61% rename from cpp/include/cuspatial/spatial_window.hpp rename to cpp/include/cuspatial/points_in_range.hpp index fb13466c2..7bd23c2c0 100644 --- a/cpp/include/cuspatial/spatial_window.hpp +++ b/cpp/include/cuspatial/points_in_range.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,37 +27,43 @@ namespace cuspatial { /** - * @brief Find all points (x,y) that fall within a rectangular query window. - * - * @ingroup spatial_relationship + * @addtogroup spatial_relationship + */ + +/** + * @brief Find all points (x,y) that fall within a rectangular query range. * - * A point (x, y) is in the window if `x > window_min_x && x < window_min_y && y > window_min_y && y - * < window_max_y`. + * A point (x, y) is in the range if `x > range_min_x && x < range_min_y && y > range_min_y && y + * < range_max_y`. * - * Swaps `window_min_x` and `window_max_x` if `window_min_x > window_max_x`. - * Swaps `window_min_y` and `window_max_y` if `window_min_y > window_max_y`. + * Swaps `range_min_x` and `range_max_x` if `range_min_x > range_max_x`. + * Swaps `range_min_y` and `range_max_y` if `range_min_y > range_max_y`. * - * The window coordinates and the (x, y) points to be tested are assumed to be defined in the same + * The range coordinates and the (x, y) points to be tested are assumed to be defined in the same * coordinate system. * - * @param[in] window_min_x lower x-coordinate of the query window - * @param[in] window_max_x upper x-coordinate of the query window - * @param[in] window_min_y lower y-coordinate of the query window - * @param[in] window_max_y upper y-coordinate of the query window + * @param[in] range_min_x lower x-coordinate of the query range + * @param[in] range_max_x upper x-coordinate of the query range + * @param[in] range_min_y lower y-coordinate of the query range + * @param[in] range_max_y upper y-coordinate of the query range * @param[in] x x-coordinates of points to be queried * @param[in] y y-coordinates of points to be queried * @param[in] mr Optional `device_memory_resource` to use for allocating the output table * * @returns A table with two columns of the same type as the input columns. Columns 0, 1 are the - * (x, y) coordinates of the points in the input that fall within the query window. + * (x, y) coordinates of the points in the input that fall within the query range. */ -std::unique_ptr points_in_spatial_window( - double window_min_x, - double window_max_x, - double window_min_y, - double window_max_y, +std::unique_ptr points_in_range( + double range_min_x, + double range_max_x, + double range_min_y, + double range_max_y, cudf::column_view const& x, cudf::column_view const& y, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); +/** + * @} // end of doxygen group + */ + } // namespace cuspatial diff --git a/cpp/include/cuspatial/polygon_bounding_boxes.cuh b/cpp/include/cuspatial/polygon_bounding_boxes.cuh deleted file mode 100644 index 7cee2be26..000000000 --- a/cpp/include/cuspatial/polygon_bounding_boxes.cuh +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute minimum bounding box for each polygon. - * - * @ingroup spatial_relationship - * - * @tparam PolygonOffsetIterator Iterator type to polygon offsets. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam RingOffsetIterator Iterator type to polygon ring offsets. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam VertexIterator Iterator type to polygon vertices. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam BoundingBoxIterator Iterator type to bounding boxes. Must be writable using data of type - * `cuspatial::box`. Must meet the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be - * device-writeable. - * @tparam T The coordinate data value type. - * @tparam IndexT The offset data value type. - * @param polygon_offsets_first Iterator to beginning of the range of input polygon offsets. - * @param polygon_offsets_last Iterator to end of the range of input polygon offsets. - * @param polygon_ring_offsets_first Iterator to beginning of the range of input polygon ring - * offsets. - * @param polygon_ring_offsets_last Iterator to end of the range of input polygon ring offsets. - * @param polygon_vertices_first Iterator to beginning of the range of input polygon vertices. - * @param polygon_vertices_last Iterator to end of the range of input polygon vertices. - * @param bounding_boxes_first Iterator to beginning of the range of output bounding boxes. - * @param expansion_radius Optional radius to expand each vertex of the output bounding boxes. - * @param stream the CUDA stream on which to perform computations and allocate memory. - * - * @return An iterator to the end of the range of output bounding boxes. - * - * @pre For compatibility with GeoArrow, the number of polygon offsets - * `std::distance(polygon_offsets_first, polygon_offsets_last)` should be one more than the number - * of polygons. The number of ring offsets `std::distance(polygon_ring_offsets_first, - * polygon_ring_offsets_last)` should be one more than the number of total rings. The - * final offset in each range is not used by this function, but the number of polygon offsets - * determines the output size. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template , - class IndexT = iterator_value_type> -BoundingBoxIterator polygon_bounding_boxes(PolygonOffsetIterator polygon_offsets_first, - PolygonOffsetIterator polygon_offsets_last, - RingOffsetIterator polygon_ring_offsets_first, - RingOffsetIterator polygon_ring_offsets_last, - VertexIterator polygon_vertices_first, - VertexIterator polygon_vertices_last, - BoundingBoxIterator bounding_boxes_first, - T expansion_radius = T{0}, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/polygon_distance.cuh b/cpp/include/cuspatial/polygon_distance.cuh deleted file mode 100644 index 55f80857d..000000000 --- a/cpp/include/cuspatial/polygon_distance.cuh +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include - -namespace cuspatial { - -/** - * @ingroup distance - * @brief Computes pairwise multipolygon to multipolygon distance - * - * @tparam MultiPolygonRangeA An instance of template type `multipolygon_range` - * @tparam MultiPolygonRangeB An instance of template type `multipolygon_range` - * @tparam OutputIt iterator type for output array. Must meet the requirements of [LRAI](LinkLRAI). - * Must be an iterator to type convertible from floating points. - * - * @param lhs The first multipolygon range to compute distance from - * @param rhs The second multipolygon range to compute distance to - * @param stream The CUDA stream on which to perform computations - * @return Output Iterator past the last distance computed - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template -OutputIt pairwise_polygon_distance(MultipolygonRangeA lhs, - MultipolygonRangeB rhs, - OutputIt distances_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); -} // namespace cuspatial - -#include diff --git a/cpp/include/cuspatial/sinusoidal_projection.cuh b/cpp/include/cuspatial/projection.cuh similarity index 93% rename from cpp/include/cuspatial/sinusoidal_projection.cuh rename to cpp/include/cuspatial/projection.cuh index 885577287..ae6d4ea72 100644 --- a/cpp/include/cuspatial/sinusoidal_projection.cuh +++ b/cpp/include/cuspatial/projection.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,11 @@ namespace cuspatial { +/** + * @addtogroup spatial_join + * @{ + */ + /** * @brief Sinusoidal projection of longitude/latitude relative to origin to Cartesian (x/y) * coordinates in km. @@ -64,6 +69,11 @@ OutputIt sinusoidal_projection(InputIt lon_lat_first, vec_2d origin, rmm::cuda_stream_view stream = rmm::cuda_stream_default); +/** + * @addtogroup spatial_join + * @{ + */ + } // namespace cuspatial -#include +#include diff --git a/cpp/include/cuspatial/range/multilinestring_range.cuh b/cpp/include/cuspatial/range/multilinestring_range.cuh index 18a30a2bf..b79b2ae77 100644 --- a/cpp/include/cuspatial/range/multilinestring_range.cuh +++ b/cpp/include/cuspatial/range/multilinestring_range.cuh @@ -27,9 +27,12 @@ namespace cuspatial { +/** + * @addtogroup ranges + */ + /** * @brief Non-owning range-based interface to multilinestring data - * @ingroup ranges * * Provides a range-based interface to contiguous storage of multilinestring data, to make it easier * to access and iterate over multilinestrings, linestrings and points. @@ -211,7 +214,6 @@ class multilinestring_range { /** * @brief Create a multilinestring_range object from size and start iterators - * @ingroup ranges * * @tparam GeometryIteratorDiffType Index type of the size of the geometry array * @tparam PartIteratorDiffType Index type of the size of the part array @@ -260,7 +262,6 @@ auto make_multilinestring_range(GeometryIteratorDiffType num_multilinestrings, /** * @brief Create a range object of multilinestring data from offset and point ranges - * @ingroup ranges * * @tparam IntegerRange1 Range to integers * @tparam IntegerRange2 Range to integers @@ -285,7 +286,6 @@ auto make_multilinestring_range(IntegerRange1 geometry_offsets, } /** - * @ingroup ranges * @brief Create a range object of multilinestring from cuspatial::geometry_column_view. * Specialization for linestrings column. * @@ -315,7 +315,6 @@ auto make_multilinestring_range(GeometryColumnView const& linestrings_column) } /** - * @ingroup ranges * @brief Create a range object of multilinestring from cuspatial::geometry_column_view. * Specialization for multilinestrings column. * @@ -345,6 +344,10 @@ auto make_multilinestring_range(GeometryColumnView const& linestrings_column) points_it + points_xy.size() / 2); }; +/** + * @} // end of doxygen group + */ + } // namespace cuspatial #include diff --git a/cpp/include/cuspatial/range/multipoint_range.cuh b/cpp/include/cuspatial/range/multipoint_range.cuh index 1277d62b0..b41edbd7e 100644 --- a/cpp/include/cuspatial/range/multipoint_range.cuh +++ b/cpp/include/cuspatial/range/multipoint_range.cuh @@ -24,9 +24,13 @@ namespace cuspatial { +/** + * @addtogroup ranges + * @{ + */ + /** * @brief Non-owning range-based interface to multipoint data - * @ingroup ranges * * Provides a range-based interface to contiguous storage of multipoint data, to make it easier * to access and iterate over multipoints and points. @@ -160,7 +164,6 @@ class multipoint_range { /** * @brief Create a multipoint_range object of from size and start iterators - * @ingroup ranges * * @tparam GeometryIteratorDiffType Index type of the size of the geometry array * @tparam VecIteratorDiffType Index type of the size of the point array @@ -212,7 +215,6 @@ auto make_multipoint_range(IntegerRange geometry_offsets, PointRange points) } /** - * @ingroup ranges * @brief Create a range object of multipoints from cuspatial::geometry_column_view. * Specialization for points column. * @@ -239,7 +241,6 @@ auto make_multipoint_range(GeometryColumnView const& points_column) } /** - * @ingroup ranges * @brief Create a range object of multipoints from cuspatial::geometry_column_view. * Specialization for multipoints column. * @@ -265,6 +266,10 @@ auto make_multipoint_range(GeometryColumnView const& points_column) points_it + points_xy.size() / 2); }; +/** + * @} // end of doxygen group + */ + } // namespace cuspatial #include diff --git a/cpp/include/cuspatial/range/multipolygon_range.cuh b/cpp/include/cuspatial/range/multipolygon_range.cuh index 8a5e99841..1b8947345 100644 --- a/cpp/include/cuspatial/range/multipolygon_range.cuh +++ b/cpp/include/cuspatial/range/multipolygon_range.cuh @@ -26,9 +26,13 @@ namespace cuspatial { +/** + * @addtogroup ranges + * @{ + */ + /** * @brief Non-owning range-based interface to multipolygon data - * @ingroup ranges * * Provides a range-based interface to contiguous storage of multipolygon data, to make it easier * to access and iterate over multipolygons, polygons, rings and points. @@ -211,7 +215,6 @@ class multipolygon_range { }; /** - * @ingroup ranges * @brief Create a range object of multipolygon from cuspatial::geometry_column_view. * Specialization for polygons column. * @@ -245,7 +248,6 @@ auto make_multipolygon_range(GeometryColumnView const& polygons_column) } /** - * @ingroup ranges * @brief Create a range object of multipolygon from cuspatial::geometry_column_view. * Specialization for multipolygons column. * @@ -278,6 +280,10 @@ auto make_multipolygon_range(GeometryColumnView const& polygons_column) points_it + points_xy.size() / 2); }; +/** + * @} // end of doxygen group + */ + } // namespace cuspatial #include diff --git a/cpp/include/cuspatial/spatial_join.cuh b/cpp/include/cuspatial/spatial_join.cuh index 1b960e32c..9815d5f4f 100644 --- a/cpp/include/cuspatial/spatial_join.cuh +++ b/cpp/include/cuspatial/spatial_join.cuh @@ -16,9 +16,9 @@ #pragma once -#include #include #include +#include #include #include @@ -189,6 +189,6 @@ quadtree_point_to_nearest_linestring( } // namespace cuspatial -#include -#include -#include +#include +#include +#include diff --git a/cpp/include/cuspatial/derive_trajectories.cuh b/cpp/include/cuspatial/trajectory.cuh similarity index 61% rename from cpp/include/cuspatial/derive_trajectories.cuh rename to cpp/include/cuspatial/trajectory.cuh index e647f28bc..f6c5d76f4 100644 --- a/cpp/include/cuspatial/derive_trajectories.cuh +++ b/cpp/include/cuspatial/trajectory.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,10 +88,53 @@ std::unique_ptr> derive_trajectories( rmm::cuda_stream_view stream = rmm::cuda_stream_default, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); +/** + * @brief Compute the total distance (in meters) and average speed (in m/s) of objects in + * trajectories. + * + * @note Assumes object_id, timestamp, x, y presorted by (object_id, timestamp). + * + * @tparam IdInputIt Iterator over object IDs. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam PointInputIt Iterator over points. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam TimestampInputIt Iterator over timestamps. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. + * @tparam OutputIt Iterator over output (distance, speed) pairs. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI] and be device-writeable. + * @tparam IndexT The type of the object IDs. + * + * @param num_trajectories number of trajectories (unique object ids) + * @param ids_first beginning of the range of input object ids + * @param ids_last end of the range of input object ids + * @param points_first beginning of the range of input point (x,y) coordinates + * @param timestamps_first beginning of the range of input timestamps + * @param distances_and_speeds_first beginning of the range of output (distance, speed) pairs + * @param stream the CUDA stream on which to perform computations and allocate memory. + * + * @return An iterator to the end of the range of output (distance, speed) pairs. + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template > +OutputIt trajectory_distances_and_speeds(IndexT num_trajectories, + IdInputIt ids_first, + IdInputIt ids_last, + PointInputIt points_first, + TimestampInputIt timestamps_first, + OutputIt distances_and_speeds_first, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + /** * @} // end of doxygen group */ } // namespace cuspatial -#include +#include +#include diff --git a/cpp/include/cuspatial/trajectory_distances_and_speeds.cuh b/cpp/include/cuspatial/trajectory_distances_and_speeds.cuh deleted file mode 100644 index 81fc9c5a2..000000000 --- a/cpp/include/cuspatial/trajectory_distances_and_speeds.cuh +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * 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. - */ - -#include - -#include - -namespace cuspatial { - -/** - * @addtogroup trajectory_api - * @{ - */ - -/** - * @brief Compute the total distance (in meters) and average speed (in m/s) of objects in - * trajectories. - * - * @note Assumes object_id, timestamp, x, y presorted by (object_id, timestamp). - * - * @tparam IdInputIt Iterator over object IDs. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam PointInputIt Iterator over points. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam TimestampInputIt Iterator over timestamps. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-readable. - * @tparam OutputIt Iterator over output (distance, speed) pairs. Must meet the requirements of - * [LegacyRandomAccessIterator][LinkLRAI] and be device-writeable. - * @tparam IndexT The type of the object IDs. - * - * @param num_trajectories number of trajectories (unique object ids) - * @param ids_first beginning of the range of input object ids - * @param ids_last end of the range of input object ids - * @param points_first beginning of the range of input point (x,y) coordinates - * @param timestamps_first beginning of the range of input timestamps - * @param distances_and_speeds_first beginning of the range of output (distance, speed) pairs - * @param stream the CUDA stream on which to perform computations and allocate memory. - * - * @return An iterator to the end of the range of output (distance, speed) pairs. - * - * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator - * "LegacyRandomAccessIterator" - */ -template > -OutputIt trajectory_distances_and_speeds(IndexT num_trajectories, - IdInputIt ids_first, - IdInputIt ids_last, - PointInputIt points_first, - TimestampInputIt timestamps_first, - OutputIt distances_and_speeds_first, - rmm::cuda_stream_view stream = rmm::cuda_stream_default); - -/** - * @} // end of doxygen group - */ - -} // namespace cuspatial - -#include diff --git a/cpp/include/doxygen_groups.h b/cpp/include/doxygen_groups.h index 4e7ea055e..152e67bd8 100644 --- a/cpp/include/doxygen_groups.h +++ b/cpp/include/doxygen_groups.h @@ -24,8 +24,8 @@ // Below are the main groups that doxygen uses to build // the Modules page in the specified order. // -// To add a new API to an existing group, just use the -// @ingroup tag in the API's doxygen comment. +// To add a new API to an existing group, just use the @ingroup tag in the API's Doxygen +// comment or @addtogroup in the file, inside the namespace. // Add a new group by first specifying in the hierarchy below. /** @@ -42,46 +42,37 @@ * * This module contains APIs that transforms cartesian and geodesic coordinates. * @file projection.hpp - * @file coordinate_transform.hpp - * @file sinusoidal_projection.cuh + * @file projection.cuh * @} * @defgroup distance Distance * @{ * @brief Distance computation APIs * - * @file point_distance.hpp - * @file point_distance.cuh - * @file point_linestring_distance.hpp - * @file point_linestring_distance.cuh - * @file linestring_distance.hpp - * @file linestring_distance.cuh - * @file hausdorff.hpp - * @file hausdorff.cuh - * @file haversine.hpp - * @file haversine.cuh + * @file distance.hpp + * @file distance.cuh * @} * @defgroup spatial_relationship Spatial Relationship * @{ * @brief APIs related to spatial relationship * - @file bounding_box.hpp + @file bounding_boxes.hpp + @file bounding_boxes.cuh * @file point_in_polygon.hpp * @file point_in_polygon.cuh - * @file polygon_bounding_box.hpp - * @file linestring_bounding_box.hpp * @file spatial_window.hpp * @} * @defgroup nearest_points Nearest Points * @{ * @brief APIs to compute the nearest points between geometries - * @file point_linestring_nearest_points.hpp - * @file point_linestring_nearest_points.cuh + * @file nearest_points.hpp + * @file nearest_points.cuh * @} * @} * @defgroup trajectory_api Trajectory APIs * @{ * @brief APIs related to trajectories * @file trajectory.hpp + * @file trajectory.cuh * @} * @defgroup spatial_indexing Spatial Indexing * @{ @@ -97,7 +88,11 @@ * @{ * @brief Type declarations for cuspatial * @file types.hpp + * @file box.hpp * @file vec_2d.hpp + * @file linestring_ref.cuh + * @file polygon_ref.cuh + * @file segment.cuh * @file geometry_column_view.hpp * * @defgroup type_factories Factory Methods @@ -118,6 +113,7 @@ * @file range.cuh * @file multipoint_range.cuh * @file multilinestring_range.cuh + * @file multipolygon_range.cuh * @} * @defgroup exception Exception * @{ diff --git a/cpp/src/join/quadtree_bbox_filtering.cu b/cpp/src/join/quadtree_bbox_filtering.cu index d5e20c353..b90bad402 100644 --- a/cpp/src/join/quadtree_bbox_filtering.cu +++ b/cpp/src/join/quadtree_bbox_filtering.cu @@ -17,8 +17,8 @@ #include #include -#include #include +#include #include #include diff --git a/cpp/src/spatial/hausdorff.cu b/cpp/src/spatial/hausdorff.cu index 530e0ecad..9706b5bf6 100644 --- a/cpp/src/spatial/hausdorff.cu +++ b/cpp/src/spatial/hausdorff.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. + * Copyright (c) 2019-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ * limitations under the License. */ +#include #include -#include #include #include diff --git a/cpp/src/spatial/haversine.cu b/cpp/src/spatial/haversine.cu index c85ec9957..45c736c2f 100644 --- a/cpp/src/spatial/haversine.cu +++ b/cpp/src/spatial/haversine.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,8 @@ */ #include +#include #include -#include #include #include diff --git a/cpp/src/spatial/linestring_bounding_box.cu b/cpp/src/spatial/linestring_bounding_boxes.cu similarity index 98% rename from cpp/src/spatial/linestring_bounding_box.cu rename to cpp/src/spatial/linestring_bounding_boxes.cu index c47a6cf8d..86b6aeb75 100644 --- a/cpp/src/spatial/linestring_bounding_box.cu +++ b/cpp/src/spatial/linestring_bounding_boxes.cu @@ -14,10 +14,9 @@ * limitations under the License. */ -#include +#include #include #include -#include #include #include diff --git a/cpp/src/spatial/linestring_distance.cu b/cpp/src/spatial/linestring_distance.cu index 82cca68c2..8133d2a6f 100644 --- a/cpp/src/spatial/linestring_distance.cu +++ b/cpp/src/spatial/linestring_distance.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ #include "../utility/double_boolean_dispatch.hpp" #include "../utility/iterator.hpp" +#include #include #include #include -#include #include #include diff --git a/cpp/src/spatial/linestring_intersection.cu b/cpp/src/spatial/linestring_intersection.cu index e80adf442..760854692 100644 --- a/cpp/src/spatial/linestring_intersection.cu +++ b/cpp/src/spatial/linestring_intersection.cu @@ -18,12 +18,11 @@ #include "../utility/multi_geometry_dispatch.hpp" #include -#include #include #include +#include +#include #include -#include -#include #include #include diff --git a/cpp/src/spatial/linestring_polygon_distance.cu b/cpp/src/spatial/linestring_polygon_distance.cu index 7e99fabd5..d07a97baa 100644 --- a/cpp/src/spatial/linestring_polygon_distance.cu +++ b/cpp/src/spatial/linestring_polygon_distance.cu @@ -29,10 +29,9 @@ #include #include -#include +#include #include #include -#include #include #include #include diff --git a/cpp/src/spatial/pairwise_point_in_polygon.cu b/cpp/src/spatial/pairwise_point_in_polygon.cu deleted file mode 100644 index b263c223b..000000000 --- a/cpp/src/spatial/pairwise_point_in_polygon.cu +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2022-2023, NVIDIA CORPORATION. - * - * 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. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include - -namespace { - -struct pairwise_point_in_polygon_functor { - template - static constexpr bool is_supported() - { - return std::is_floating_point::value; - } - - template ()>* = nullptr, typename... Args> - std::unique_ptr operator()(Args&&...) - { - CUSPATIAL_FAIL("Non-floating point operation is not supported"); - } - - template ()>* = nullptr> - std::unique_ptr operator()(cudf::column_view const& test_points_x, - cudf::column_view const& test_points_y, - cudf::column_view const& poly_offsets, - cudf::column_view const& poly_ring_offsets, - cudf::column_view const& poly_points_x, - cudf::column_view const& poly_points_y, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) - { - auto size = test_points_x.size(); - auto tid = cudf::type_to_id(); - auto type = cudf::data_type{tid}; - auto results = - cudf::make_fixed_width_column(type, size, cudf::mask_state::UNALLOCATED, stream, mr); - - if (results->size() == 0) { return results; } - - auto points_begin = - cuspatial::make_vec_2d_iterator(test_points_x.begin(), test_points_y.begin()); - auto polygon_offsets_begin = poly_offsets.begin(); - auto ring_offsets_begin = poly_ring_offsets.begin(); - auto polygon_points_begin = - cuspatial::make_vec_2d_iterator(poly_points_x.begin(), poly_points_y.begin()); - auto results_begin = results->mutable_view().begin(); - - cuspatial::pairwise_point_in_polygon(points_begin, - points_begin + test_points_x.size(), - polygon_offsets_begin, - polygon_offsets_begin + poly_offsets.size(), - ring_offsets_begin, - ring_offsets_begin + poly_ring_offsets.size(), - polygon_points_begin, - polygon_points_begin + poly_points_x.size(), - results_begin, - stream); - - return results; - } -}; -} // anonymous namespace - -namespace cuspatial { - -namespace detail { - -std::unique_ptr pairwise_point_in_polygon(cudf::column_view const& test_points_x, - cudf::column_view const& test_points_y, - cudf::column_view const& poly_offsets, - cudf::column_view const& poly_ring_offsets, - cudf::column_view const& poly_points_x, - cudf::column_view const& poly_points_y, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) -{ - return cudf::type_dispatcher(test_points_x.type(), - pairwise_point_in_polygon_functor(), - test_points_x, - test_points_y, - poly_offsets, - poly_ring_offsets, - poly_points_x, - poly_points_y, - stream, - mr); -} - -} // namespace detail - -std::unique_ptr pairwise_point_in_polygon(cudf::column_view const& test_points_x, - cudf::column_view const& test_points_y, - cudf::column_view const& poly_offsets, - cudf::column_view const& poly_ring_offsets, - cudf::column_view const& poly_points_x, - cudf::column_view const& poly_points_y, - rmm::mr::device_memory_resource* mr) -{ - CUSPATIAL_EXPECTS( - test_points_x.size() == test_points_y.size() and poly_points_x.size() == poly_points_y.size(), - "All points must have both x and y values"); - - CUSPATIAL_EXPECTS(test_points_x.type() == test_points_y.type() and - test_points_x.type() == poly_points_x.type() and - test_points_x.type() == poly_points_y.type(), - "All points much have the same type for both x and y"); - - CUSPATIAL_EXPECTS(not test_points_x.has_nulls() && not test_points_y.has_nulls(), - "Test points must not contain nulls"); - - CUSPATIAL_EXPECTS(not poly_points_x.has_nulls() && not poly_points_y.has_nulls(), - "Polygon points must not contain nulls"); - - CUSPATIAL_EXPECTS(test_points_x.size() == std::max(poly_offsets.size() - 1, 0), - "Must pass in the same number of points as polygons."); - - return cuspatial::detail::pairwise_point_in_polygon(test_points_x, - test_points_y, - poly_offsets, - poly_ring_offsets, - poly_points_x, - poly_points_y, - rmm::cuda_stream_default, - mr); -} - -} // namespace cuspatial diff --git a/cpp/src/spatial/point_distance.cu b/cpp/src/spatial/point_distance.cu index 2b8776894..c0fe8d778 100644 --- a/cpp/src/spatial/point_distance.cu +++ b/cpp/src/spatial/point_distance.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ #include "../utility/double_boolean_dispatch.hpp" #include "../utility/iterator.hpp" +#include #include #include #include -#include #include #include diff --git a/cpp/src/spatial/point_in_polygon.cu b/cpp/src/spatial/point_in_polygon.cu index 22ff97609..255a507cf 100644 --- a/cpp/src/spatial/point_in_polygon.cu +++ b/cpp/src/spatial/point_in_polygon.cu @@ -52,6 +52,7 @@ struct point_in_polygon_functor { cudf::column_view const& poly_ring_offsets, cudf::column_view const& poly_points_x, cudf::column_view const& poly_points_y, + bool pairwise, rmm::cuda_stream_view stream, rmm::mr::device_memory_resource* mr) { @@ -71,16 +72,30 @@ struct point_in_polygon_functor { cuspatial::make_vec_2d_iterator(poly_points_x.begin(), poly_points_y.begin()); auto results_begin = results->mutable_view().begin(); - cuspatial::point_in_polygon(points_begin, - points_begin + test_points_x.size(), - polygon_offsets_begin, - polygon_offsets_begin + poly_offsets.size(), - ring_offsets_begin, - ring_offsets_begin + poly_ring_offsets.size(), - polygon_points_begin, - polygon_points_begin + poly_points_x.size(), - results_begin, - stream); + if (pairwise) { + cuspatial::pairwise_point_in_polygon(points_begin, + points_begin + test_points_x.size(), + polygon_offsets_begin, + polygon_offsets_begin + poly_offsets.size(), + ring_offsets_begin, + ring_offsets_begin + poly_ring_offsets.size(), + polygon_points_begin, + polygon_points_begin + poly_points_x.size(), + results_begin, + stream); + + } else { + cuspatial::point_in_polygon(points_begin, + points_begin + test_points_x.size(), + polygon_offsets_begin, + polygon_offsets_begin + poly_offsets.size(), + ring_offsets_begin, + ring_offsets_begin + poly_ring_offsets.size(), + polygon_points_begin, + polygon_points_begin + poly_points_x.size(), + results_begin, + stream); + } return results; } @@ -97,9 +112,30 @@ std::unique_ptr point_in_polygon(cudf::column_view const& test_poi cudf::column_view const& poly_ring_offsets, cudf::column_view const& poly_points_x, cudf::column_view const& poly_points_y, + bool pairwise, rmm::cuda_stream_view stream, rmm::mr::device_memory_resource* mr) { + CUSPATIAL_EXPECTS( + test_points_x.size() == test_points_y.size() and poly_points_x.size() == poly_points_y.size(), + "All points must have both x and y values"); + + CUSPATIAL_EXPECTS(test_points_x.type() == test_points_y.type() and + test_points_x.type() == poly_points_x.type() and + test_points_x.type() == poly_points_y.type(), + "All points much have the same type for both x and y"); + + CUSPATIAL_EXPECTS(not test_points_x.has_nulls() && not test_points_y.has_nulls(), + "Test points must not contain nulls"); + + CUSPATIAL_EXPECTS(not poly_points_x.has_nulls() && not poly_points_y.has_nulls(), + "Polygon points must not contain nulls"); + + if (pairwise) { + CUSPATIAL_EXPECTS(test_points_x.size() == std::max(poly_offsets.size() - 1, 0), + "Must pass in the same number of points as polygons."); + } + return cudf::type_dispatcher(test_points_x.type(), point_in_polygon_functor(), test_points_x, @@ -108,6 +144,7 @@ std::unique_ptr point_in_polygon(cudf::column_view const& test_poi poly_ring_offsets, poly_points_x, poly_points_y, + pairwise, stream, mr); } @@ -122,27 +159,32 @@ std::unique_ptr point_in_polygon(cudf::column_view const& test_poi cudf::column_view const& poly_points_y, rmm::mr::device_memory_resource* mr) { - CUSPATIAL_EXPECTS( - test_points_x.size() == test_points_y.size() and poly_points_x.size() == poly_points_y.size(), - "All points must have both x and y values"); - - CUSPATIAL_EXPECTS(test_points_x.type() == test_points_y.type() and - test_points_x.type() == poly_points_x.type() and - test_points_x.type() == poly_points_y.type(), - "All points much have the same type for both x and y"); - - CUSPATIAL_EXPECTS(not test_points_x.has_nulls() && not test_points_y.has_nulls(), - "Test points must not contain nulls"); - - CUSPATIAL_EXPECTS(not poly_points_x.has_nulls() && not poly_points_y.has_nulls(), - "Polygon points must not contain nulls"); + return cuspatial::detail::point_in_polygon(test_points_x, + test_points_y, + poly_offsets, + poly_ring_offsets, + poly_points_x, + poly_points_y, + false, + rmm::cuda_stream_default, + mr); +} +std::unique_ptr pairwise_point_in_polygon(cudf::column_view const& test_points_x, + cudf::column_view const& test_points_y, + cudf::column_view const& poly_offsets, + cudf::column_view const& poly_ring_offsets, + cudf::column_view const& poly_points_x, + cudf::column_view const& poly_points_y, + rmm::mr::device_memory_resource* mr) +{ return cuspatial::detail::point_in_polygon(test_points_x, test_points_y, poly_offsets, poly_ring_offsets, poly_points_x, poly_points_y, + true, rmm::cuda_stream_default, mr); } diff --git a/cpp/src/spatial/point_linestring_distance.cu b/cpp/src/spatial/point_linestring_distance.cu index 6f2786b51..ed0b0ab7d 100644 --- a/cpp/src/spatial/point_linestring_distance.cu +++ b/cpp/src/spatial/point_linestring_distance.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,10 +25,9 @@ #include -#include +#include #include #include -#include #include #include diff --git a/cpp/src/spatial/point_linestring_nearest_points.cu b/cpp/src/spatial/point_linestring_nearest_points.cu index 5843e9d5d..9e15cc225 100644 --- a/cpp/src/spatial/point_linestring_nearest_points.cu +++ b/cpp/src/spatial/point_linestring_nearest_points.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/cpp/src/spatial/point_polygon_distance.cu b/cpp/src/spatial/point_polygon_distance.cu index 52eea1309..e4053d972 100644 --- a/cpp/src/spatial/point_polygon_distance.cu +++ b/cpp/src/spatial/point_polygon_distance.cu @@ -29,10 +29,9 @@ #include #include -#include +#include #include #include -#include #include #include #include diff --git a/cpp/src/spatial_window/spatial_window.cu b/cpp/src/spatial/points_in_range.cu similarity index 55% rename from cpp/src/spatial_window/spatial_window.cu rename to cpp/src/spatial/points_in_range.cu index 8ed1358a3..df6f60c6a 100644 --- a/cpp/src/spatial_window/spatial_window.cu +++ b/cpp/src/spatial/points_in_range.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,14 +31,14 @@ namespace { -// Type-dispatch functor that creates the spatial window filter of the correct type. +// Type-dispatch functor that creates the spatial range filter of the correct type. // Only floating point types are supported. -struct spatial_window_dispatch { +struct points_in_range_dispatch { template ::value>* = nullptr> - std::unique_ptr operator()(double window_min_x, - double window_max_x, - double window_min_y, - double window_max_y, + std::unique_ptr operator()(double range_min_x, + double range_max_x, + double range_min_y, + double range_max_y, cudf::column_view const& x, cudf::column_view const& y, rmm::cuda_stream_view stream, @@ -46,13 +46,11 @@ struct spatial_window_dispatch { { auto points_begin = cuspatial::make_vec_2d_iterator(x.begin(), y.begin()); - auto window_min = - cuspatial::vec_2d{static_cast(window_min_x), static_cast(window_min_y)}; - auto window_max = - cuspatial::vec_2d{static_cast(window_max_x), static_cast(window_max_y)}; + auto range_min = cuspatial::vec_2d{static_cast(range_min_x), static_cast(range_min_y)}; + auto range_max = cuspatial::vec_2d{static_cast(range_max_x), static_cast(range_max_y)}; auto output_size = cuspatial::count_points_in_range( - window_min, window_max, points_begin, points_begin + x.size(), stream); + range_min, range_max, points_begin, points_begin + x.size(), stream); std::vector> cols{}; cols.reserve(2); @@ -67,7 +65,7 @@ struct spatial_window_dispatch { output_y->mutable_view().begin()); cuspatial::copy_points_in_range( - window_min, window_max, points_begin, points_begin + x.size(), output_zip, stream); + range_min, range_max, points_begin, points_begin + x.size(), output_zip, stream); return std::make_unique(std::move(cols)); } @@ -88,19 +86,19 @@ namespace cuspatial { namespace detail { /* - * Return all points (x,y) that fall within a query window (x1,y1,x2,y2) + * Return all points (x,y) that fall within a query range (x1,y1,x2,y2) * see query.hpp * * Detail version that takes a stream. */ -std::unique_ptr points_in_spatial_window(double window_min_x, - double window_max_x, - double window_min_y, - double window_max_y, - cudf::column_view const& x, - cudf::column_view const& y, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) +std::unique_ptr points_in_range(double range_min_x, + double range_max_x, + double range_min_y, + double range_max_y, + cudf::column_view const& x, + cudf::column_view const& y, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) { CUSPATIAL_EXPECTS(x.type() == y.type(), "Type mismatch between x and y arrays"); CUSPATIAL_EXPECTS(x.size() == y.size(), "Size mismatch between x and y arrays"); @@ -108,11 +106,11 @@ std::unique_ptr points_in_spatial_window(double window_min_x, CUSPATIAL_EXPECTS(not(x.has_nulls() || y.has_nulls()), "NULL point data not supported"); return cudf::type_dispatcher(x.type(), - spatial_window_dispatch(), - window_min_x, - window_max_x, - window_min_y, - window_max_y, + points_in_range_dispatch(), + range_min_x, + range_max_x, + range_min_y, + range_max_y, x, y, stream, @@ -122,19 +120,19 @@ std::unique_ptr points_in_spatial_window(double window_min_x, } // namespace detail /* - * Return all points (x,y) that fall within a query window (x1,y1,x2,y2) + * Return all points (x,y) that fall within a query range (x1,y1,x2,y2) * see query.hpp */ -std::unique_ptr points_in_spatial_window(double window_min_x, - double window_max_x, - double window_min_y, - double window_max_y, - cudf::column_view const& x, - cudf::column_view const& y, - rmm::mr::device_memory_resource* mr) +std::unique_ptr points_in_range(double range_min_x, + double range_max_x, + double range_min_y, + double range_max_y, + cudf::column_view const& x, + cudf::column_view const& y, + rmm::mr::device_memory_resource* mr) { - return detail::points_in_spatial_window( - window_min_x, window_max_x, window_min_y, window_max_y, x, y, rmm::cuda_stream_default, mr); + return detail::points_in_range( + range_min_x, range_max_x, range_min_y, range_max_y, x, y, rmm::cuda_stream_default, mr); } } // namespace cuspatial diff --git a/cpp/src/spatial/polygon_bounding_box.cu b/cpp/src/spatial/polygon_bounding_boxes.cu similarity index 99% rename from cpp/src/spatial/polygon_bounding_box.cu rename to cpp/src/spatial/polygon_bounding_boxes.cu index f8b0c5f17..9fdca1bd5 100644 --- a/cpp/src/spatial/polygon_bounding_box.cu +++ b/cpp/src/spatial/polygon_bounding_boxes.cu @@ -16,8 +16,8 @@ #include +#include #include -#include #include #include diff --git a/cpp/src/spatial/polygon_distance.cu b/cpp/src/spatial/polygon_distance.cu index 8d3192e13..3a24f04cf 100644 --- a/cpp/src/spatial/polygon_distance.cu +++ b/cpp/src/spatial/polygon_distance.cu @@ -28,9 +28,9 @@ #include #include +#include #include #include -#include #include #include diff --git a/cpp/src/spatial/sinusoidal_projection.cu b/cpp/src/spatial/sinusoidal_projection.cu index 522c8dea0..1be4ade40 100644 --- a/cpp/src/spatial/sinusoidal_projection.cu +++ b/cpp/src/spatial/sinusoidal_projection.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. + * Copyright (c) 2019-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/cpp/src/trajectory/derive_trajectories.cu b/cpp/src/trajectory/derive_trajectories.cu index cb760f1be..cfeeea77b 100644 --- a/cpp/src/trajectory/derive_trajectories.cu +++ b/cpp/src/trajectory/derive_trajectories.cu @@ -14,9 +14,9 @@ * limitations under the License. */ -#include #include #include +#include #include #include diff --git a/cpp/src/trajectory/trajectory_bounding_boxes.cu b/cpp/src/trajectory/trajectory_bounding_boxes.cu index f790f86e8..8d441b9c4 100644 --- a/cpp/src/trajectory/trajectory_bounding_boxes.cu +++ b/cpp/src/trajectory/trajectory_bounding_boxes.cu @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include diff --git a/cpp/src/trajectory/trajectory_distances_and_speeds.cu b/cpp/src/trajectory/trajectory_distances_and_speeds.cu index d239ec907..a27f8b7f8 100644 --- a/cpp/src/trajectory/trajectory_distances_and_speeds.cu +++ b/cpp/src/trajectory/trajectory_distances_and_speeds.cu @@ -16,8 +16,8 @@ #include #include +#include #include -#include #include #include diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 4f9533537..74cd736dd 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -118,8 +118,8 @@ ConfigureTest(PAIRWISE_POINT_IN_POLYGON_TEST spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp) # points in range -ConfigureTest(SPATIAL_WINDOW_POINT_TEST - spatial/points_in_range/spatial_window_test.cpp) +ConfigureTest(POINTS_IN_RANGE_TEST + spatial/points_in_range/points_in_range_test.cpp) # trajectory ConfigureTest(TRAJECTORY_DISTANCES_AND_SPEEDS_TEST diff --git a/cpp/tests/join/join_quadtree_and_bounding_boxes_test.cpp b/cpp/tests/join/join_quadtree_and_bounding_boxes_test.cpp index d0fe5586a..e7d6d5948 100644 --- a/cpp/tests/join/join_quadtree_and_bounding_boxes_test.cpp +++ b/cpp/tests/join/join_quadtree_and_bounding_boxes_test.cpp @@ -14,9 +14,9 @@ * limitations under the License. */ +#include #include #include -#include #include #include diff --git a/cpp/tests/join/quadtree_point_in_polygon_test.cpp b/cpp/tests/join/quadtree_point_in_polygon_test.cpp index 6206e8b45..c3d720c10 100644 --- a/cpp/tests/join/quadtree_point_in_polygon_test.cpp +++ b/cpp/tests/join/quadtree_point_in_polygon_test.cpp @@ -15,10 +15,10 @@ */ #include +#include #include #include #include -#include #include #include diff --git a/cpp/tests/join/quadtree_point_in_polygon_test_large.cu b/cpp/tests/join/quadtree_point_in_polygon_test_large.cu index c66879986..14a956016 100644 --- a/cpp/tests/join/quadtree_point_in_polygon_test_large.cu +++ b/cpp/tests/join/quadtree_point_in_polygon_test_large.cu @@ -20,10 +20,10 @@ #include #include +#include #include #include #include -#include #include #include diff --git a/cpp/tests/join/quadtree_point_in_polygon_test_small.cu b/cpp/tests/join/quadtree_point_in_polygon_test_small.cu index 500628bab..52792dd9b 100644 --- a/cpp/tests/join/quadtree_point_in_polygon_test_small.cu +++ b/cpp/tests/join/quadtree_point_in_polygon_test_small.cu @@ -18,9 +18,9 @@ #include #include +#include #include #include -#include #include #include diff --git a/cpp/tests/join/quadtree_point_to_nearest_linestring_test.cpp b/cpp/tests/join/quadtree_point_to_nearest_linestring_test.cpp index a04b590a3..d78cda350 100644 --- a/cpp/tests/join/quadtree_point_to_nearest_linestring_test.cpp +++ b/cpp/tests/join/quadtree_point_to_nearest_linestring_test.cpp @@ -15,9 +15,9 @@ */ #include +#include #include #include -#include #include #include diff --git a/cpp/tests/join/quadtree_point_to_nearest_linestring_test_small.cu b/cpp/tests/join/quadtree_point_to_nearest_linestring_test_small.cu index a27997a96..4f4f85837 100644 --- a/cpp/tests/join/quadtree_point_to_nearest_linestring_test_small.cu +++ b/cpp/tests/join/quadtree_point_to_nearest_linestring_test_small.cu @@ -18,8 +18,8 @@ #include #include +#include #include -#include #include #include #include diff --git a/cpp/tests/projection/sinusoidal_projection_test.cu b/cpp/tests/projection/sinusoidal_projection_test.cu index 1b0db23c7..41c2202e1 100644 --- a/cpp/tests/projection/sinusoidal_projection_test.cu +++ b/cpp/tests/projection/sinusoidal_projection_test.cu @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cpp b/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cpp index fb409a22b..d742b0cc7 100644 --- a/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cpp +++ b/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ +#include #include -#include #include #include diff --git a/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cu b/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cu index d18a32e73..53f3427b8 100644 --- a/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cu +++ b/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cu @@ -17,10 +17,10 @@ #include #include +#include #include #include #include -#include #include diff --git a/cpp/tests/spatial/bounding_boxes/point_bounding_boxes_test.cu b/cpp/tests/spatial/bounding_boxes/point_bounding_boxes_test.cu index 2d00a1a91..e96c2b783 100644 --- a/cpp/tests/spatial/bounding_boxes/point_bounding_boxes_test.cu +++ b/cpp/tests/spatial/bounding_boxes/point_bounding_boxes_test.cu @@ -18,10 +18,10 @@ #include -#include -#include +#include #include #include +#include #include #include diff --git a/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cpp b/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cpp index b161f9989..f933a2459 100644 --- a/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cpp +++ b/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ +#include #include -#include #include #include diff --git a/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cu b/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cu index 6ad497312..de81d06e2 100644 --- a/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cu +++ b/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cu @@ -17,10 +17,10 @@ #include #include +#include #include #include #include -#include #include diff --git a/cpp/tests/spatial/distance/hausdorff_test.cpp b/cpp/tests/spatial/distance/hausdorff_test.cpp index 6cf59c9a8..2111e3330 100644 --- a/cpp/tests/spatial/distance/hausdorff_test.cpp +++ b/cpp/tests/spatial/distance/hausdorff_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,11 @@ * limitations under the License. */ -#include -#include +#include #include +#include + #include #include #include diff --git a/cpp/tests/spatial/distance/hausdorff_test.cu b/cpp/tests/spatial/distance/hausdorff_test.cu index 5c9b0aecf..453ee02f3 100644 --- a/cpp/tests/spatial/distance/hausdorff_test.cu +++ b/cpp/tests/spatial/distance/hausdorff_test.cu @@ -16,9 +16,9 @@ #include +#include #include #include -#include #include diff --git a/cpp/tests/spatial/distance/haversine_test.cpp b/cpp/tests/spatial/distance/haversine_test.cpp index c91b899dd..351bfce93 100644 --- a/cpp/tests/spatial/distance/haversine_test.cpp +++ b/cpp/tests/spatial/distance/haversine_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include diff --git a/cpp/tests/spatial/distance/haversine_test.cu b/cpp/tests/spatial/distance/haversine_test.cu index 8428143c3..b0798a37d 100644 --- a/cpp/tests/spatial/distance/haversine_test.cu +++ b/cpp/tests/spatial/distance/haversine_test.cu @@ -16,8 +16,8 @@ #include +#include #include -#include #include diff --git a/cpp/tests/spatial/distance/linestring_distance_test.cpp b/cpp/tests/spatial/distance/linestring_distance_test.cpp index b4622980b..7fc25497e 100644 --- a/cpp/tests/spatial/distance/linestring_distance_test.cpp +++ b/cpp/tests/spatial/distance/linestring_distance_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ */ #include -#include +#include #include #include diff --git a/cpp/tests/spatial/distance/linestring_distance_test.cu b/cpp/tests/spatial/distance/linestring_distance_test.cu index 5cb285a5a..cb9836392 100644 --- a/cpp/tests/spatial/distance/linestring_distance_test.cu +++ b/cpp/tests/spatial/distance/linestring_distance_test.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ #include #include +#include #include #include #include -#include #include #include #include diff --git a/cpp/tests/spatial/distance/linestring_distance_test_medium.cu b/cpp/tests/spatial/distance/linestring_distance_test_medium.cu index efda52407..bdc991b06 100644 --- a/cpp/tests/spatial/distance/linestring_distance_test_medium.cu +++ b/cpp/tests/spatial/distance/linestring_distance_test_medium.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ #include #include +#include #include #include #include -#include #include #include diff --git a/cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp b/cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp index 8bffe1d94..7b5b73642 100644 --- a/cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp +++ b/cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/tests/spatial/distance/linestring_polygon_distance_test.cu b/cpp/tests/spatial/distance/linestring_polygon_distance_test.cu index 0d3ef91f0..bf74b731b 100644 --- a/cpp/tests/spatial/distance/linestring_polygon_distance_test.cu +++ b/cpp/tests/spatial/distance/linestring_polygon_distance_test.cu @@ -18,9 +18,9 @@ #include #include -#include +#include #include -#include +#include #include #include diff --git a/cpp/tests/spatial/distance/point_distance_test.cpp b/cpp/tests/spatial/distance/point_distance_test.cpp index d45e6459b..d16e2b5b1 100644 --- a/cpp/tests/spatial/distance/point_distance_test.cpp +++ b/cpp/tests/spatial/distance/point_distance_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include diff --git a/cpp/tests/spatial/distance/point_distance_test.cu b/cpp/tests/spatial/distance/point_distance_test.cu index 1b1f9ff90..573c5232a 100644 --- a/cpp/tests/spatial/distance/point_distance_test.cu +++ b/cpp/tests/spatial/distance/point_distance_test.cu @@ -18,11 +18,10 @@ #include -#include +#include #include #include #include -#include #include #include diff --git a/cpp/tests/spatial/distance/point_linestring_distance_test.cpp b/cpp/tests/spatial/distance/point_linestring_distance_test.cpp index 9f922cdcb..e35efa260 100644 --- a/cpp/tests/spatial/distance/point_linestring_distance_test.cpp +++ b/cpp/tests/spatial/distance/point_linestring_distance_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include diff --git a/cpp/tests/spatial/distance/point_linestring_distance_test.cu b/cpp/tests/spatial/distance/point_linestring_distance_test.cu index f16df5f10..e684f2a1b 100644 --- a/cpp/tests/spatial/distance/point_linestring_distance_test.cu +++ b/cpp/tests/spatial/distance/point_linestring_distance_test.cu @@ -16,11 +16,10 @@ #include -#include +#include #include #include #include -#include #include #include diff --git a/cpp/tests/spatial/distance/point_polygon_distance_test.cpp b/cpp/tests/spatial/distance/point_polygon_distance_test.cpp index 43d9b2c66..dfb486b69 100644 --- a/cpp/tests/spatial/distance/point_polygon_distance_test.cpp +++ b/cpp/tests/spatial/distance/point_polygon_distance_test.cpp @@ -15,7 +15,7 @@ */ #include -#include +#include #include #include #include diff --git a/cpp/tests/spatial/distance/point_polygon_distance_test.cu b/cpp/tests/spatial/distance/point_polygon_distance_test.cu index 01536a4af..2cee8da4b 100644 --- a/cpp/tests/spatial/distance/point_polygon_distance_test.cu +++ b/cpp/tests/spatial/distance/point_polygon_distance_test.cu @@ -17,9 +17,9 @@ #include #include -#include +#include #include -#include +#include #include #include diff --git a/cpp/tests/spatial/distance/polygon_distance_test.cu b/cpp/tests/spatial/distance/polygon_distance_test.cu index 6b0fc52c7..47a663824 100644 --- a/cpp/tests/spatial/distance/polygon_distance_test.cu +++ b/cpp/tests/spatial/distance/polygon_distance_test.cu @@ -18,9 +18,9 @@ #include #include -#include +#include #include -#include +#include #include #include diff --git a/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu b/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu index 5bf3407f6..a12420858 100644 --- a/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu +++ b/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu @@ -22,11 +22,6 @@ #include #include #include -#include - -#include - -#include using namespace cuspatial; using namespace cuspatial::test; diff --git a/cpp/tests/spatial/intersection/linestring_intersection_count_test.cu b/cpp/tests/spatial/intersection/linestring_intersection_count_test.cu index 549bdf468..24467462e 100644 --- a/cpp/tests/spatial/intersection/linestring_intersection_count_test.cu +++ b/cpp/tests/spatial/intersection/linestring_intersection_count_test.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/tests/spatial/intersection/linestring_intersection_intermediates_remove_if_test.cu b/cpp/tests/spatial/intersection/linestring_intersection_intermediates_remove_if_test.cu index f9f8504b1..eb36d5e35 100644 --- a/cpp/tests/spatial/intersection/linestring_intersection_intermediates_remove_if_test.cu +++ b/cpp/tests/spatial/intersection/linestring_intersection_intermediates_remove_if_test.cu @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/tests/spatial/intersection/linestring_intersection_test.cpp b/cpp/tests/spatial/intersection/linestring_intersection_test.cpp index 65a9b5d13..b48d1b057 100644 --- a/cpp/tests/spatial/intersection/linestring_intersection_test.cpp +++ b/cpp/tests/spatial/intersection/linestring_intersection_test.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/cpp/tests/spatial/intersection/linestring_intersection_test.cu b/cpp/tests/spatial/intersection/linestring_intersection_test.cu index c91d7de43..a63de917b 100644 --- a/cpp/tests/spatial/intersection/linestring_intersection_test.cu +++ b/cpp/tests/spatial/intersection/linestring_intersection_test.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,10 @@ #include #include -#include #include #include +#include #include -#include #include #include diff --git a/cpp/tests/spatial/intersection/linestring_intersection_with_duplicates_test.cu b/cpp/tests/spatial/intersection/linestring_intersection_with_duplicates_test.cu index f01f6b5e1..195968615 100644 --- a/cpp/tests/spatial/intersection/linestring_intersection_with_duplicates_test.cu +++ b/cpp/tests/spatial/intersection/linestring_intersection_with_duplicates_test.cu @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cpp b/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cpp index 6743db576..47f69853b 100644 --- a/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cpp +++ b/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cu b/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cu index 42b0a552a..dfeac5cb2 100644 --- a/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cu +++ b/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cu @@ -16,11 +16,10 @@ #include -#include #include #include #include -#include +#include #include diff --git a/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp b/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp index 97d9f7b7c..477d8ce90 100644 --- a/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp +++ b/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp @@ -15,7 +15,7 @@ */ #include -#include +#include #include #include diff --git a/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cu b/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cu index 13ae6a456..c05c24f63 100644 --- a/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cu +++ b/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cu @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/cpp/tests/spatial/points_in_range/spatial_window_test.cpp b/cpp/tests/spatial/points_in_range/points_in_range_test.cpp similarity index 80% rename from cpp/tests/spatial/points_in_range/spatial_window_test.cpp rename to cpp/tests/spatial/points_in_range/points_in_range_test.cpp index 3d56bce16..37f7b153d 100644 --- a/cpp/tests/spatial/points_in_range/spatial_window_test.cpp +++ b/cpp/tests/spatial/points_in_range/points_in_range_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ */ #include -#include +#include #include @@ -41,9 +41,8 @@ TEST_F(SpatialWindowErrorTest, TypeMismatch) auto points_x = cudf::test::fixed_width_column_wrapper({1.0, 2.0, 3.0}); auto points_y = cudf::test::fixed_width_column_wrapper({0.0, 1.0, 2.0}); - EXPECT_THROW( - auto result = cuspatial::points_in_spatial_window(1.5, 5.5, 1.5, 5.5, points_x, points_y), - cuspatial::logic_error); + EXPECT_THROW(auto result = cuspatial::points_in_range(1.5, 5.5, 1.5, 5.5, points_x, points_y), + cuspatial::logic_error); } TEST_F(SpatialWindowErrorTest, SizeMismatch) @@ -51,9 +50,8 @@ TEST_F(SpatialWindowErrorTest, SizeMismatch) auto points_x = cudf::test::fixed_width_column_wrapper({1.0, 2.0, 3.0}); auto points_y = cudf::test::fixed_width_column_wrapper({0.0}); - EXPECT_THROW( - auto result = cuspatial::points_in_spatial_window(1.5, 5.5, 1.5, 5.5, points_x, points_y), - cuspatial::logic_error); + EXPECT_THROW(auto result = cuspatial::points_in_range(1.5, 5.5, 1.5, 5.5, points_x, points_y), + cuspatial::logic_error); } struct IsFloat { @@ -73,9 +71,8 @@ TYPED_TEST(SpatialWindowUnsupportedTypesTest, ShouldThrow) auto points_x = cudf::test::fixed_width_column_wrapper({1.0, 2.0, 3.0}); auto points_y = cudf::test::fixed_width_column_wrapper({0.0, 1.0, 2.0}); - EXPECT_THROW( - auto result = cuspatial::points_in_spatial_window(1.5, 5.5, 1.5, 5.5, points_x, points_y), - cuspatial::logic_error); + EXPECT_THROW(auto result = cuspatial::points_in_range(1.5, 5.5, 1.5, 5.5, points_x, points_y), + cuspatial::logic_error); } template @@ -90,7 +87,6 @@ TYPED_TEST(SpatialWindowUnsupportedChronoTypesTest, ShouldThrow) auto points_x = cudf::test::fixed_width_column_wrapper({R{1}, R{2}, R{3}}); auto points_y = cudf::test::fixed_width_column_wrapper({R{0}, R{1}, R{2}}); - EXPECT_THROW( - auto result = cuspatial::points_in_spatial_window(1.5, 5.5, 1.5, 5.5, points_x, points_y), - cuspatial::logic_error); + EXPECT_THROW(auto result = cuspatial::points_in_range(1.5, 5.5, 1.5, 5.5, points_x, points_y), + cuspatial::logic_error); } diff --git a/cpp/tests/trajectory/derive_trajectories_test.cu b/cpp/tests/trajectory/derive_trajectories_test.cu index a52b8e6c7..cc47700c7 100644 --- a/cpp/tests/trajectory/derive_trajectories_test.cu +++ b/cpp/tests/trajectory/derive_trajectories_test.cu @@ -17,9 +17,9 @@ #include "cuspatial_test/vector_equality.hpp" #include "trajectory_test_utils.cuh" -#include -#include #include +#include +#include #include #include diff --git a/cpp/tests/trajectory/trajectory_distances_and_speeds_test.cu b/cpp/tests/trajectory/trajectory_distances_and_speeds_test.cu index f7fd2eddd..666b3c20b 100644 --- a/cpp/tests/trajectory/trajectory_distances_and_speeds_test.cu +++ b/cpp/tests/trajectory/trajectory_distances_and_speeds_test.cu @@ -19,10 +19,10 @@ #include -#include #include +#include +#include #include -#include #include diff --git a/python/cuspatial/cuspatial/_lib/CMakeLists.txt b/python/cuspatial/cuspatial/_lib/CMakeLists.txt index 6a0f0d012..4a1530d9b 100644 --- a/python/cuspatial/cuspatial/_lib/CMakeLists.txt +++ b/python/cuspatial/cuspatial/_lib/CMakeLists.txt @@ -19,13 +19,13 @@ set(cython_sources intersection.pyx nearest_points.pyx point_in_polygon.pyx + points_in_range.pyx pairwise_point_in_polygon.pyx polygon_bounding_boxes.pyx linestring_bounding_boxes.pyx quadtree.pyx spatial.pyx spatial_join.pyx - spatial_window.pyx trajectory.pyx types.pyx utils.pyx diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd index 6b6f81d5c..7fcebe35f 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2020, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr from libcpp.utility cimport pair @@ -8,7 +8,7 @@ from cudf._lib.cpp.column.column_view cimport column_view from cudf._lib.cpp.table.table_view cimport table_view -cdef extern from "cuspatial/distance/hausdorff.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef pair[unique_ptr[column], table_view] directed_hausdorff_distance( diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd index 4e39c6ad5..236c919fc 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd @@ -1,11 +1,11 @@ -# Copyright (c) 2019-2020, NVIDIA CORPORATION. +# Copyright (c) 2019-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr from cudf._lib.column cimport column, column_view -cdef extern from "cuspatial/distance/haversine.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] haversine_distance( const column_view& a_lon, diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd index a4d2a940b..3c14745c5 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2022, NVIDIA CORPORATION. +# Copyright (c) 2022-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr @@ -9,7 +9,7 @@ from cudf._lib.cpp.column.column_view cimport column_view from cuspatial._lib.cpp.optional cimport optional -cdef extern from "cuspatial/distance/linestring_distance.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] pairwise_linestring_distance( const optional[column_view] multilinestring1_geometry_offsets, diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd index 82a4f1834..8505a380f 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd @@ -9,7 +9,7 @@ from cuspatial._lib.cpp.column.geometry_column_view cimport ( ) -cdef extern from "cuspatial/distance/linestring_polygon_distance.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] pairwise_linestring_polygon_distance( const geometry_column_view & multilinestrings, diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd index 7ed67251b..7b6a921b6 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2022, NVIDIA CORPORATION. +# Copyright (c) 2022-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr @@ -10,7 +10,7 @@ from cudf._lib.cpp.types cimport size_type from cuspatial._lib.cpp.optional cimport optional -cdef extern from "cuspatial/distance/point_distance.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] pairwise_point_distance( const optional[column_view] multipoint1_offsets, diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd index 40c3d9bf3..56d431875 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2022, NVIDIA CORPORATION. +# Copyright (c) 2022-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr @@ -10,7 +10,7 @@ from cudf._lib.cpp.types cimport size_type from cuspatial._lib.cpp.optional cimport optional -cdef extern from "cuspatial/distance/point_linestring_distance.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] pairwise_point_linestring_distance( const optional[column_view] multipoint_geometry_offsets, diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd index 020bd4574..63f659184 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd @@ -9,7 +9,7 @@ from cuspatial._lib.cpp.column.geometry_column_view cimport ( ) -cdef extern from "cuspatial/distance/point_polygon_distance.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] pairwise_point_polygon_distance( const geometry_column_view & multipoints, diff --git a/python/cuspatial/cuspatial/_lib/cpp/linestring_bounding_box.pxd b/python/cuspatial/cuspatial/_lib/cpp/linestring_bounding_boxes.pxd similarity index 78% rename from python/cuspatial/cuspatial/_lib/cpp/linestring_bounding_box.pxd rename to python/cuspatial/cuspatial/_lib/cpp/linestring_bounding_boxes.pxd index b17f31ca8..fa458a6cf 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/linestring_bounding_box.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/linestring_bounding_boxes.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2022, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr @@ -6,7 +6,7 @@ from cudf._lib.cpp.column.column_view cimport column_view from cudf._lib.cpp.table.table cimport table -cdef extern from "cuspatial/linestring_bounding_box.hpp" \ +cdef extern from "cuspatial/bounding_boxes.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[table] linestring_bounding_boxes( const column_view & linestring_offsets, diff --git a/python/cuspatial/cuspatial/_lib/cpp/linestring_intersection.pxd b/python/cuspatial/cuspatial/_lib/cpp/linestring_intersection.pxd index 71424a23f..0478c87de 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/linestring_intersection.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/linestring_intersection.pxd @@ -9,7 +9,7 @@ from cuspatial._lib.cpp.column.geometry_column_view cimport ( ) -cdef extern from "cuspatial/linestring_intersection.hpp" \ +cdef extern from "cuspatial/intersection.hpp" \ namespace "cuspatial" nogil: struct linestring_intersection_column_result: diff --git a/python/cuspatial/cuspatial/_lib/cpp/point_linestring_nearest_points.pxd b/python/cuspatial/cuspatial/_lib/cpp/nearest_points.pxd similarity index 89% rename from python/cuspatial/cuspatial/_lib/cpp/point_linestring_nearest_points.pxd rename to python/cuspatial/cuspatial/_lib/cpp/nearest_points.pxd index 1f66dfe61..826505c30 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/point_linestring_nearest_points.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/nearest_points.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2022, NVIDIA CORPORATION. +# Copyright (c) 2022-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr @@ -7,7 +7,7 @@ from cudf._lib.column cimport column, column_view from cuspatial._lib.cpp.optional cimport optional -cdef extern from "cuspatial/point_linestring_nearest_points.hpp" \ +cdef extern from "cuspatial/nearest_points.hpp" \ namespace "cuspatial" nogil: cdef struct point_linestring_nearest_points_result: diff --git a/python/cuspatial/cuspatial/_lib/cpp/pairwise_point_in_polygon.pxd b/python/cuspatial/cuspatial/_lib/cpp/pairwise_point_in_polygon.pxd index 90149e590..a9f1f7622 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/pairwise_point_in_polygon.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/pairwise_point_in_polygon.pxd @@ -1,11 +1,11 @@ -# Copyright (c) 2022, NVIDIA CORPORATION. +# Copyright (c) 2022-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr from cudf._lib.column cimport column, column_view -cdef extern from "cuspatial/pairwise_point_in_polygon.hpp" \ +cdef extern from "cuspatial/point_in_polygon.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] pairwise_point_in_polygon( const column_view & test_points_x, diff --git a/python/cuspatial/cuspatial/_lib/cpp/points_in_range.pxd b/python/cuspatial/cuspatial/_lib/cpp/points_in_range.pxd new file mode 100644 index 000000000..e6534dc7b --- /dev/null +++ b/python/cuspatial/cuspatial/_lib/cpp/points_in_range.pxd @@ -0,0 +1,18 @@ +# Copyright (c) 2020-2023, NVIDIA CORPORATION. + +from libcpp.memory cimport unique_ptr + +from cudf._lib.column cimport column, column_view +from cudf._lib.cpp.table.table cimport table, table_view + + +cdef extern from "cuspatial/points_in_range.hpp" namespace "cuspatial" nogil: + cdef unique_ptr[table] points_in_range \ + "cuspatial::points_in_range" ( + double range_min_x, + double range_max_x, + double range_min_y, + double range_max_y, + const column_view & x, + const column_view & y + ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/polygon_bounding_box.pxd b/python/cuspatial/cuspatial/_lib/cpp/polygon_bounding_boxes.pxd similarity index 80% rename from python/cuspatial/cuspatial/_lib/cpp/polygon_bounding_box.pxd rename to python/cuspatial/cuspatial/_lib/cpp/polygon_bounding_boxes.pxd index 46fdbf2e1..a6d28f965 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/polygon_bounding_box.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/polygon_bounding_boxes.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2020, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr @@ -6,7 +6,7 @@ from cudf._lib.cpp.column.column_view cimport column_view from cudf._lib.cpp.table.table cimport table -cdef extern from "cuspatial/polygon_bounding_box.hpp" \ +cdef extern from "cuspatial/bounding_boxes.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[table] polygon_bounding_boxes( const column_view & poly_offsets, diff --git a/python/cuspatial/cuspatial/_lib/cpp/projection.pxd b/python/cuspatial/cuspatial/_lib/cpp/projection.pxd index e02aa8b47..3c85461e7 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/projection.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/projection.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2020, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr from libcpp.pair cimport pair diff --git a/python/cuspatial/cuspatial/_lib/cpp/spatial_window.pxd b/python/cuspatial/cuspatial/_lib/cpp/spatial_window.pxd deleted file mode 100644 index 1d69f2719..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/spatial_window.pxd +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2020, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr - -from cudf._lib.column cimport column, column_view -from cudf._lib.cpp.table.table cimport table, table_view - - -cdef extern from "cuspatial/spatial_window.hpp" namespace "cuspatial" nogil: - cdef unique_ptr[table] points_in_spatial_window \ - "cuspatial::points_in_spatial_window" ( - double window_min_x, - double window_max_x, - double window_min_y, - double window_max_y, - const column_view & x, - const column_view & y - ) except + diff --git a/python/cuspatial/cuspatial/_lib/linestring_bounding_boxes.pyx b/python/cuspatial/cuspatial/_lib/linestring_bounding_boxes.pyx index 823ad9960..28815cc57 100644 --- a/python/cuspatial/cuspatial/_lib/linestring_bounding_boxes.pyx +++ b/python/cuspatial/cuspatial/_lib/linestring_bounding_boxes.pyx @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2022, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr from libcpp.utility cimport move @@ -8,7 +8,7 @@ from cudf._lib.cpp.column.column_view cimport column_view from cudf._lib.cpp.table.table cimport table from cudf._lib.utils cimport columns_from_unique_ptr -from cuspatial._lib.cpp.linestring_bounding_box cimport ( +from cuspatial._lib.cpp.linestring_bounding_boxes cimport ( linestring_bounding_boxes as cpp_linestring_bounding_boxes, ) diff --git a/python/cuspatial/cuspatial/_lib/nearest_points.pyx b/python/cuspatial/cuspatial/_lib/nearest_points.pyx index fd8267419..d8ecebc58 100644 --- a/python/cuspatial/cuspatial/_lib/nearest_points.pyx +++ b/python/cuspatial/cuspatial/_lib/nearest_points.pyx @@ -1,13 +1,15 @@ +# Copyright (c) 2022-2023, NVIDIA CORPORATION. + from libcpp.utility cimport move from cudf._lib.column cimport Column from cudf._lib.cpp.column.column_view cimport column_view -from cuspatial._lib.cpp.optional cimport optional -from cuspatial._lib.cpp.point_linestring_nearest_points cimport ( +from cuspatial._lib.cpp.nearest_points cimport ( pairwise_point_linestring_nearest_points as c_func, point_linestring_nearest_points_result, ) +from cuspatial._lib.cpp.optional cimport optional from cuspatial._lib.utils cimport unwrap_pyoptcol diff --git a/python/cuspatial/cuspatial/_lib/spatial_window.pyx b/python/cuspatial/cuspatial/_lib/points_in_range.pyx similarity index 54% rename from python/cuspatial/cuspatial/_lib/spatial_window.pyx rename to python/cuspatial/cuspatial/_lib/points_in_range.pyx index 3e1ced019..e54b60a6b 100644 --- a/python/cuspatial/cuspatial/_lib/spatial_window.pyx +++ b/python/cuspatial/cuspatial/_lib/points_in_range.pyx @@ -1,4 +1,4 @@ -# Copyright (c) 2020, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr from libcpp.utility cimport move @@ -7,16 +7,16 @@ from cudf._lib.column cimport Column, column_view from cudf._lib.cpp.table.table cimport table from cudf._lib.utils cimport data_from_unique_ptr -from cuspatial._lib.cpp.spatial_window cimport ( - points_in_spatial_window as cpp_points_in_spatial_window, +from cuspatial._lib.cpp.points_in_range cimport ( + points_in_range as cpp_points_in_range, ) -cpdef points_in_spatial_window( - double window_min_x, - double window_max_x, - double window_min_y, - double window_max_y, +cpdef points_in_range( + double range_min_x, + double range_max_x, + double range_min_y, + double range_max_y, Column x, Column y ): @@ -27,11 +27,11 @@ cpdef points_in_spatial_window( with nogil: c_result = move( - cpp_points_in_spatial_window( - window_min_x, - window_max_x, - window_min_y, - window_max_y, + cpp_points_in_range( + range_min_x, + range_max_x, + range_min_y, + range_max_y, x_v, y_v ) diff --git a/python/cuspatial/cuspatial/_lib/polygon_bounding_boxes.pyx b/python/cuspatial/cuspatial/_lib/polygon_bounding_boxes.pyx index 8b68700c6..d9419fe7b 100644 --- a/python/cuspatial/cuspatial/_lib/polygon_bounding_boxes.pyx +++ b/python/cuspatial/cuspatial/_lib/polygon_bounding_boxes.pyx @@ -1,4 +1,4 @@ -# Copyright (c) 2020, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr from libcpp.utility cimport move @@ -8,7 +8,7 @@ from cudf._lib.cpp.column.column_view cimport column_view from cudf._lib.cpp.table.table cimport table from cudf._lib.utils cimport columns_from_unique_ptr -from cuspatial._lib.cpp.polygon_bounding_box cimport ( +from cuspatial._lib.cpp.polygon_bounding_boxes cimport ( polygon_bounding_boxes as cpp_polygon_bounding_boxes, ) diff --git a/python/cuspatial/cuspatial/core/spatial/filtering.py b/python/cuspatial/cuspatial/core/spatial/filtering.py index be7689e1d..615784fee 100644 --- a/python/cuspatial/cuspatial/core/spatial/filtering.py +++ b/python/cuspatial/cuspatial/core/spatial/filtering.py @@ -3,7 +3,7 @@ from cudf import DataFrame from cudf.core.column import as_column -from cuspatial._lib import spatial_window +from cuspatial._lib import points_in_range from cuspatial.core.geoseries import GeoSeries from cuspatial.utils.column_utils import contains_only_points @@ -52,8 +52,6 @@ def points_in_spatial_window(points: GeoSeries, min_x, max_x, min_y, max_y): ys = as_column(points.points.y) res_xy = DataFrame._from_data( - *spatial_window.points_in_spatial_window( - min_x, max_x, min_y, max_y, xs, ys - ) + *points_in_range.points_in_range(min_x, max_x, min_y, max_y, xs, ys) ).interleave_columns() return GeoSeries.from_points_xy(res_xy) From 3b6a59bc0721ceeaa55a22707c1fea9a814a6bdf Mon Sep 17 00:00:00 2001 From: Raymond Douglass Date: Wed, 3 May 2023 13:09:25 -0400 Subject: [PATCH 13/63] update changelog --- CHANGELOG.md | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6766231f4..c3d3524f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,85 @@ +# cuSpatial 23.04.00 (6 Apr 2023) + +## 🚨 Breaking Changes + +- Consistently validate polygon inputs for GeoArrow offset format ([#973](https://github.com/rapidsai/cuspatial/pull/973)) [@harrism](https://github.com/harrism) +- Remove cubic spline interpolation ([#959](https://github.com/rapidsai/cuspatial/pull/959)) [@harrism](https://github.com/harrism) +- Refactors API to accept GeoSeries input for projection and trajectory functions ([#955](https://github.com/rapidsai/cuspatial/pull/955)) [@isVoid](https://github.com/isVoid) +- Refactors `filtering.py`, `indexing.py` to Accept GeoSeries ([#938](https://github.com/rapidsai/cuspatial/pull/938)) [@isVoid](https://github.com/isVoid) +- Refactors `bounding.py` to accept GeoSeries Input ([#934](https://github.com/rapidsai/cuspatial/pull/934)) [@isVoid](https://github.com/isVoid) +- Remove shapefile reader, conda GDAL dependency, move cmake gdal dependency to cpp tests only ([#932](https://github.com/rapidsai/cuspatial/pull/932)) [@harrism](https://github.com/harrism) +- Refactor `directed_hausdorff_distance` and `haversine_distance` into `GeoSeries` Interface ([#924](https://github.com/rapidsai/cuspatial/pull/924)) [@isVoid](https://github.com/isVoid) + +## 🐛 Bug Fixes + +- Bug Fix: point-in-multipolygon reduction using the wrong key-compare functor ([#1043](https://github.com/rapidsai/cuspatial/pull/1043)) [@isVoid](https://github.com/isVoid) +- Fix quotes in backticks in Developer Guide ([#1034](https://github.com/rapidsai/cuspatial/pull/1034)) [@harrism](https://github.com/harrism) +- Attempt to Fix Broken C++ Build After `cudftestutil` is Made a Shared Lib ([#996](https://github.com/rapidsai/cuspatial/pull/996)) [@isVoid](https://github.com/isVoid) +- Consistently validate polygon inputs for GeoArrow offset format ([#973](https://github.com/rapidsai/cuspatial/pull/973)) [@harrism](https://github.com/harrism) +- Fix OB bug in `linestring_intersection_intermediates.remove_if` Function ([#945](https://github.com/rapidsai/cuspatial/pull/945)) [@isVoid](https://github.com/isVoid) +- Fix broken `point_indices` methods in `PolygonGeoColumnAccessor` ([#907](https://github.com/rapidsai/cuspatial/pull/907)) [@isVoid](https://github.com/isVoid) +- Fix multiple bugs in user guide ([#906](https://github.com/rapidsai/cuspatial/pull/906)) [@isVoid](https://github.com/isVoid) +- `_from_point_xy` improvements ([#905](https://github.com/rapidsai/cuspatial/pull/905)) [@isVoid](https://github.com/isVoid) +- Add `valid_count` and `has_nulls` to GeoColumn ([#894](https://github.com/rapidsai/cuspatial/pull/894)) [@thomcom](https://github.com/thomcom) + +## 📖 Documentation + +- : Fix linestring link in readme ([#1003](https://github.com/rapidsai/cuspatial/pull/1003)) [@jarmak-nv](https://github.com/jarmak-nv) +- : Move build instructions to dev guide ([#999](https://github.com/rapidsai/cuspatial/pull/999)) [@jarmak-nv](https://github.com/jarmak-nv) +- Add `pairwise_linestring_intersection` example in user guide ([#989](https://github.com/rapidsai/cuspatial/pull/989)) [@isVoid](https://github.com/isVoid) +- Update cuSpatial Readme ([#977](https://github.com/rapidsai/cuspatial/pull/977)) [@jarmak-nv](https://github.com/jarmak-nv) +- Add ZipCode Counting Notebook ([#919](https://github.com/rapidsai/cuspatial/pull/919)) [@isVoid](https://github.com/isVoid) + +## 🚀 New Features + +- Add segment Iterators, test multi*_range and miscellaneous lazy iterator additions ([#1026](https://github.com/rapidsai/cuspatial/pull/1026)) [@isVoid](https://github.com/isVoid) +- Add Header Only API for Linestring-Polygon Distance ([#1011](https://github.com/rapidsai/cuspatial/pull/1011)) [@isVoid](https://github.com/isVoid) +- Add `geometry_generator` factory for programmatic generation of geometry arrays ([#998](https://github.com/rapidsai/cuspatial/pull/998)) [@isVoid](https://github.com/isVoid) +- Add python API `pairwise_point_polygon_distance` ([#988](https://github.com/rapidsai/cuspatial/pull/988)) [@isVoid](https://github.com/isVoid) +- Add column API for `pairwise_point_polygon_distance` ([#984](https://github.com/rapidsai/cuspatial/pull/984)) [@isVoid](https://github.com/isVoid) +- Add Header-Only `point_polygon_distance`, add non-owning polygon objects ([#976](https://github.com/rapidsai/cuspatial/pull/976)) [@isVoid](https://github.com/isVoid) +- Remove cubic spline interpolation ([#959](https://github.com/rapidsai/cuspatial/pull/959)) [@harrism](https://github.com/harrism) +- Remove shapefile reader, conda GDAL dependency, move cmake gdal dependency to cpp tests only ([#932](https://github.com/rapidsai/cuspatial/pull/932)) [@harrism](https://github.com/harrism) +- Add `from_linestrings_xy` and `from_polygons_xy` ([#928](https://github.com/rapidsai/cuspatial/pull/928)) [@thomcom](https://github.com/thomcom) +- Implement `geom_equals` and binary predicates that depend only on it. ([#926](https://github.com/rapidsai/cuspatial/pull/926)) [@thomcom](https://github.com/thomcom) +- Add `apply_boolean_mask` Feature ([#918](https://github.com/rapidsai/cuspatial/pull/918)) [@isVoid](https://github.com/isVoid) +- Add C++ Column API and Python API for `pairwise_linestring_intersection` ([#862](https://github.com/rapidsai/cuspatial/pull/862)) [@isVoid](https://github.com/isVoid) + +## 🛠️ Improvements + +- Refactor spatial join tests ([#1019](https://github.com/rapidsai/cuspatial/pull/1019)) [@harrism](https://github.com/harrism) +- Reduce gtest times ([#1018](https://github.com/rapidsai/cuspatial/pull/1018)) [@harrism](https://github.com/harrism) +- Intersection only predicates ([#1016](https://github.com/rapidsai/cuspatial/pull/1016)) [@thomcom](https://github.com/thomcom) +- Updated binpred architecture ([#1009](https://github.com/rapidsai/cuspatial/pull/1009)) [@thomcom](https://github.com/thomcom) +- Add `dependency-file-generator` as `pre-commit` hook ([#1008](https://github.com/rapidsai/cuspatial/pull/1008)) [@ajschmidt8](https://github.com/ajschmidt8) +- Header-only quadtree_point_to_nearest_linestring ([#1005](https://github.com/rapidsai/cuspatial/pull/1005)) [@harrism](https://github.com/harrism) +- Add codespell as a linter ([#992](https://github.com/rapidsai/cuspatial/pull/992)) [@bdice](https://github.com/bdice) +- Pass `AWS_SESSION_TOKEN` and `SCCACHE_S3_USE_SSL` vars to conda build ([#982](https://github.com/rapidsai/cuspatial/pull/982)) [@ajschmidt8](https://github.com/ajschmidt8) +- Header-only `quadtree_point_in_polygon` ([#979](https://github.com/rapidsai/cuspatial/pull/979)) [@harrism](https://github.com/harrism) +- Update aarch64 to GCC 11 ([#978](https://github.com/rapidsai/cuspatial/pull/978)) [@bdice](https://github.com/bdice) +- Remove GDAL dependency in quadtree spatial join tests. ([#974](https://github.com/rapidsai/cuspatial/pull/974)) [@harrism](https://github.com/harrism) +- Enable discussions ([#966](https://github.com/rapidsai/cuspatial/pull/966)) [@jarmak-nv](https://github.com/jarmak-nv) +- Fix docs build to be `pydata-sphinx-theme=0.13.0` compatible ([#964](https://github.com/rapidsai/cuspatial/pull/964)) [@galipremsagar](https://github.com/galipremsagar) +- Update `.gitignore` for `ops-codeowners` ([#963](https://github.com/rapidsai/cuspatial/pull/963)) [@ajschmidt8](https://github.com/ajschmidt8) +- Update to GCC 11 ([#961](https://github.com/rapidsai/cuspatial/pull/961)) [@bdice](https://github.com/bdice) +- Add cuspatial devcontainers ([#960](https://github.com/rapidsai/cuspatial/pull/960)) [@trxcllnt](https://github.com/trxcllnt) +- Make docs builds less verbose ([#956](https://github.com/rapidsai/cuspatial/pull/956)) [@AyodeAwe](https://github.com/AyodeAwe) +- Refactors API to accept GeoSeries input for projection and trajectory functions ([#955](https://github.com/rapidsai/cuspatial/pull/955)) [@isVoid](https://github.com/isVoid) +- Update Notebook with GeoSeries Usage and Add Notebook Tests ([#953](https://github.com/rapidsai/cuspatial/pull/953)) [@isVoid](https://github.com/isVoid) +- Refactor functions in `join.py` to accept GeoSeries Input ([#948](https://github.com/rapidsai/cuspatial/pull/948)) [@isVoid](https://github.com/isVoid) +- Skip docs job in nightly runs ([#944](https://github.com/rapidsai/cuspatial/pull/944)) [@AyodeAwe](https://github.com/AyodeAwe) +- Refactors `filtering.py`, `indexing.py` to Accept GeoSeries ([#938](https://github.com/rapidsai/cuspatial/pull/938)) [@isVoid](https://github.com/isVoid) +- Refactors `bounding.py` to accept GeoSeries Input ([#934](https://github.com/rapidsai/cuspatial/pull/934)) [@isVoid](https://github.com/isVoid) +- Remove dead code from ContainsProperlyBinpred paths. ([#933](https://github.com/rapidsai/cuspatial/pull/933)) [@thomcom](https://github.com/thomcom) +- Refactor `directed_hausdorff_distance` and `haversine_distance` into `GeoSeries` Interface ([#924](https://github.com/rapidsai/cuspatial/pull/924)) [@isVoid](https://github.com/isVoid) +- Reduce error handling verbosity in CI tests scripts ([#912](https://github.com/rapidsai/cuspatial/pull/912)) [@AjayThorve](https://github.com/AjayThorve) +- Use quadtree for `.contains_properly` ([#910](https://github.com/rapidsai/cuspatial/pull/910)) [@thomcom](https://github.com/thomcom) +- Update shared workflow branches ([#909](https://github.com/rapidsai/cuspatial/pull/909)) [@ajschmidt8](https://github.com/ajschmidt8) +- Remove gpuCI scripts. ([#904](https://github.com/rapidsai/cuspatial/pull/904)) [@bdice](https://github.com/bdice) +- Allow initialization of a `GeoDataFrame` using a `cudf.DataFrame` ([#895](https://github.com/rapidsai/cuspatial/pull/895)) [@thomcom](https://github.com/thomcom) +- Move date to build string in `conda` recipe ([#882](https://github.com/rapidsai/cuspatial/pull/882)) [@ajschmidt8](https://github.com/ajschmidt8) +- Add docs build job ([#868](https://github.com/rapidsai/cuspatial/pull/868)) [@AyodeAwe](https://github.com/AyodeAwe) + # cuSpatial 23.02.00 (9 Feb 2023) ## 🚨 Breaking Changes From 986c1a66a993e733a2734439f1a55e3b9bf5e4ef Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 3 May 2023 16:11:24 -0700 Subject: [PATCH 14/63] Python API for `pairwise_polygon_distance` (#1074) This PR adds python API for `pairwise_polygon_distance` depends on #1073 closes #1054 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - H. Thomson Comer (https://github.com/thomcom) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1074 --- python/cuspatial/cuspatial/__init__.py | 1 + .../_lib/cpp/distance/polygon_distance.pxd | 17 ++ python/cuspatial/cuspatial/_lib/distance.pyx | 26 +++ .../cuspatial/core/spatial/__init__.py | 2 + .../cuspatial/core/spatial/distance.py | 84 +++++++- .../test_pairwise_linestring_distance.py | 2 + ...st_pairwise_linestring_polygon_distance.py | 2 + .../distance/test_pairwise_point_distance.py | 2 + .../test_pairwise_point_polygon_distance.py | 2 + .../test_pairwise_polygon_distance.py | 189 ++++++++++++++++++ 10 files changed, 322 insertions(+), 5 deletions(-) create mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd create mode 100644 python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_polygon_distance.py diff --git a/python/cuspatial/cuspatial/__init__.py b/python/cuspatial/cuspatial/__init__.py index b281c80c4..c72dc00bb 100644 --- a/python/cuspatial/cuspatial/__init__.py +++ b/python/cuspatial/cuspatial/__init__.py @@ -12,6 +12,7 @@ pairwise_point_linestring_distance, pairwise_point_linestring_nearest_points, pairwise_point_polygon_distance, + pairwise_polygon_distance, point_in_polygon, points_in_spatial_window, polygon_bounding_boxes, diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd new file mode 100644 index 000000000..9d2bfab39 --- /dev/null +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd @@ -0,0 +1,17 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +from libcpp.memory cimport unique_ptr + +from cudf._lib.cpp.column.column cimport column + +from cuspatial._lib.cpp.column.geometry_column_view cimport ( + geometry_column_view, +) + + +cdef extern from "cuspatial/distance/polygon_distance.hpp" \ + namespace "cuspatial" nogil: + cdef unique_ptr[column] pairwise_polygon_distance( + const geometry_column_view & lhs, + const geometry_column_view & rhs + ) except + diff --git a/python/cuspatial/cuspatial/_lib/distance.pyx b/python/cuspatial/cuspatial/_lib/distance.pyx index 972a112c8..7edf19754 100644 --- a/python/cuspatial/cuspatial/_lib/distance.pyx +++ b/python/cuspatial/cuspatial/_lib/distance.pyx @@ -25,6 +25,9 @@ from cuspatial._lib.cpp.distance.point_linestring_distance cimport ( from cuspatial._lib.cpp.distance.point_polygon_distance cimport ( pairwise_point_polygon_distance as c_pairwise_point_polygon_distance, ) +from cuspatial._lib.cpp.distance.polygon_distance cimport ( + pairwise_polygon_distance as c_pairwise_polygon_distance, +) from cuspatial._lib.cpp.optional cimport optional from cuspatial._lib.cpp.types cimport collection_type_id, geometry_type_id from cuspatial._lib.types cimport collection_type_py_to_c @@ -172,3 +175,26 @@ def pairwise_linestring_polygon_distance( )) return Column.from_unique_ptr(move(c_result)) + + +def pairwise_polygon_distance(Column lhs, Column rhs): + cdef shared_ptr[geometry_column_view] c_lhs = \ + make_shared[geometry_column_view]( + lhs.view(), + collection_type_id.MULTI, + geometry_type_id.POLYGON) + + cdef shared_ptr[geometry_column_view] c_rhs = \ + make_shared[geometry_column_view]( + rhs.view(), + collection_type_id.MULTI, + geometry_type_id.POLYGON) + + cdef unique_ptr[column] c_result + + with nogil: + c_result = move(c_pairwise_polygon_distance( + c_lhs.get()[0], c_rhs.get()[0] + )) + + return Column.from_unique_ptr(move(c_result)) diff --git a/python/cuspatial/cuspatial/core/spatial/__init__.py b/python/cuspatial/cuspatial/core/spatial/__init__.py index 756e5ec88..97486a877 100644 --- a/python/cuspatial/cuspatial/core/spatial/__init__.py +++ b/python/cuspatial/cuspatial/core/spatial/__init__.py @@ -9,6 +9,7 @@ pairwise_point_distance, pairwise_point_linestring_distance, pairwise_point_polygon_distance, + pairwise_polygon_distance, ) from .filtering import points_in_spatial_window from .indexing import quadtree_on_points @@ -32,6 +33,7 @@ "pairwise_point_polygon_distance", "pairwise_point_linestring_distance", "pairwise_point_linestring_nearest_points", + "pairwise_polygon_distance", "polygon_bounding_boxes", "linestring_bounding_boxes", "point_in_polygon", diff --git a/python/cuspatial/cuspatial/core/spatial/distance.py b/python/cuspatial/cuspatial/core/spatial/distance.py index da71fc157..d4188425e 100644 --- a/python/cuspatial/cuspatial/core/spatial/distance.py +++ b/python/cuspatial/cuspatial/core/spatial/distance.py @@ -12,6 +12,7 @@ pairwise_point_distance as cpp_pairwise_point_distance, pairwise_point_linestring_distance as c_pairwise_point_linestring_distance, pairwise_point_polygon_distance as c_pairwise_point_polygon_distance, + pairwise_polygon_distance as c_pairwise_polygon_distance, ) from cuspatial._lib.hausdorff import ( directed_hausdorff_distance as cpp_directed_hausdorff_distance, @@ -131,7 +132,7 @@ def haversine_distance(p1: GeoSeries, p2: GeoSeries): def pairwise_point_distance(points1: GeoSeries, points2: GeoSeries): - """Compute shortest distance between pairs of points and multipoints + """Compute distance between (multi)points-(multi)points pairs Currently `points1` and `points2` must contain either only points or multipoints. Mixing points and multipoints in the same series is @@ -199,7 +200,7 @@ def pairwise_point_distance(points1: GeoSeries, points2: GeoSeries): def pairwise_linestring_distance( multilinestrings1: GeoSeries, multilinestrings2: GeoSeries ): - """Compute shortest distance between pairs of linestrings + """Compute distance between (multi)linestring-(multi)linestring pairs The shortest distance between two linestrings is defined as the shortest distance between all pairs of segments of the two linestrings. If any of @@ -266,7 +267,7 @@ def pairwise_linestring_distance( def pairwise_point_linestring_distance( points: GeoSeries, linestrings: GeoSeries ): - """Compute distance between pairs of (multi)points and (multi)linestrings + """Compute distance between (multi)points-(multi)linestrings pairs The distance between a (multi)point and a (multi)linestring is defined as the shortest distance between every point in the @@ -384,7 +385,7 @@ def pairwise_point_linestring_distance( def pairwise_point_polygon_distance(points: GeoSeries, polygons: GeoSeries): - """Compute distance between pairs of (multi)points and (multi)polygons + """Compute distance between (multi)points-(multi)polygons pairs The distance between a (multi)point and a (multi)polygon is defined as the shortest distance between every point in the @@ -477,7 +478,7 @@ def pairwise_point_polygon_distance(points: GeoSeries, polygons: GeoSeries): def pairwise_linestring_polygon_distance( linestrings: GeoSeries, polygons: GeoSeries ): - """Compute distance between pairs of (multi)linestrings and (multi)polygons + """Compute distance between (multi)linestrings-(multi)polygons pairs. The distance between a (multi)linestrings and a (multi)polygon is defined as the shortest distance between every segment in the @@ -555,6 +556,79 @@ def pairwise_linestring_polygon_distance( ) +def pairwise_polygon_distance(polygons1: GeoSeries, polygons2: GeoSeries): + """Compute distance between (multi)polygon-(multi)polygon pairs. + + The distance between two (multi)polygons is defined as the shortest + distance between any edge of the first (multi)polygon and any edge + of the second (multi)polygon. If two (multi)polygons intersect, the + distance is 0. + + This algorithm computes distance pairwise. The ith row in the result is + the distance between the ith (multi)polygon in `polygons1` and the ith + (multi)polygon in `polygons2`. + + Parameters + ---------- + polygons1 : GeoSeries + The (multi)polygons to compute the distance from. + polygons2 : GeoSeries + The (multi)polygons to compute the distance from. + Returns + ------- + distance : cudf.Series + + Notes + ----- + `polygons1` and `polygons2` must contain only polygons. + + Examples + -------- + Compute distance between polygons: + + >>> from shapely.geometry import Polygon, MultiPolygon + >>> s0 = cuspatial.GeoSeries([ + ... Polygon([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)])]) + >>> s1 = cuspatial.GeoSeries([ + ... Polygon([(2, 2), (3, 2), (3, 3), (2, 2)])]) + >>> cuspatial.pairwise_polygon_distance(s0, s1) + 0 1.414214 + dtype: float64 + + Compute distance between multipolygons: + >>> s0 = cuspatial.GeoSeries([ + ... MultiPolygon([ + ... Polygon([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]), + ... Polygon([(2, 0), (3, 0), (3, 1), (2, 0)])])]) + >>> s1 = cuspatial.GeoSeries([ + ... MultiPolygon([ + ... Polygon([(-1, 0), (-2, 0), (-2, -1), (-1, -1), (-1, 0)]), + ... Polygon([(0, -1), (1, -1), (1, -2), (0, -2), (0, -1)])])]) + >>> cuspatial.pairwise_polygon_distance(s0, s1) + 0 1.0 + dtype: float64 + """ + + if len(polygons1) != len(polygons2): + raise ValueError("Unmatched input geoseries length.") + + if len(polygons1) == 0: + return cudf.Series(dtype=polygons1.lines.xy.dtype) + + if not contains_only_polygons(polygons1): + raise ValueError("`polygons1` array must contain only polygons") + + if not contains_only_polygons(polygons2): + raise ValueError("`polygons2` array must contain only polygons") + + polygon1_column = polygons1.polygons.column() + polygon2_column = polygons2.polygons.column() + + return Series._from_data( + {None: c_pairwise_polygon_distance(polygon1_column, polygon2_column)} + ) + + def _flatten_point_series( points: GeoSeries, ) -> Tuple[ diff --git a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_distance.py index 9f9b9b938..b36e328b1 100644 --- a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_distance.py +++ b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_distance.py @@ -1,3 +1,5 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + from shapely.geometry import LineString import cudf diff --git a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py index f092b6023..00b8a3dda 100644 --- a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py +++ b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_linestring_polygon_distance.py @@ -1,3 +1,5 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + import geopandas as gpd import pytest from shapely.geometry import LineString, MultiLineString, MultiPolygon, Polygon diff --git a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_distance.py index a53621d55..5a05aed45 100644 --- a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_distance.py +++ b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_distance.py @@ -1,3 +1,5 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + import geopandas as gpd import pytest from pandas.testing import assert_series_equal diff --git a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py index 49fabec39..dc7316e2e 100644 --- a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py +++ b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_point_polygon_distance.py @@ -1,3 +1,5 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + import geopandas as gpd import pytest from shapely.geometry import MultiPoint, MultiPolygon, Point, Polygon diff --git a/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_polygon_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_polygon_distance.py new file mode 100644 index 000000000..1ef57f7ee --- /dev/null +++ b/python/cuspatial/cuspatial/tests/spatial/distance/test_pairwise_polygon_distance.py @@ -0,0 +1,189 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +import cupy as cp +import geopandas as gpd +import pytest +from shapely.geometry import MultiPolygon, Polygon + +import cudf +from cudf.testing import assert_series_equal + +import cuspatial + + +def test_polygon_empty(): + lhs = cuspatial.GeoSeries.from_polygons_xy([], [0], [0], [0]) + rhs = cuspatial.GeoSeries.from_polygons_xy([], [0], [0], [0]) + + got = cuspatial.pairwise_polygon_distance(lhs, rhs) + + expect = cudf.Series([], dtype="f8") + + assert_series_equal(got, expect) + + +@pytest.mark.parametrize( + "polygons1", + [ + [Polygon([(10, 11), (11, 10), (11, 11), (10, 11)])], + [ + MultiPolygon( + [ + Polygon([(12, 10), (11, 10), (11, 11), (12, 10)]), + Polygon([(11, 10), (12, 10), (11, 11), (11, 10)]), + ] + ) + ], + ], +) +@pytest.mark.parametrize( + "polygons2", + [ + [Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)])], + [ + MultiPolygon( + [ + Polygon([(-2, 0), (-1, 0), (-1, -1), (-2, 0)]), + Polygon([(1, 0), (2, 0), (1, -1), (1, 0)]), + ] + ) + ], + ], +) +def test_one_pair(polygons1, polygons2): + lhs = gpd.GeoSeries(polygons1) + rhs = gpd.GeoSeries(polygons2) + + dlhs = cuspatial.GeoSeries(polygons1) + drhs = cuspatial.GeoSeries(polygons2) + + expect = lhs.distance(rhs) + got = cuspatial.pairwise_polygon_distance(dlhs, drhs) + + assert_series_equal(got, cudf.Series(expect)) + + +@pytest.mark.parametrize( + "polygons1", + [ + [ + Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)]), + Polygon([(-4, -4), (-4, -5), (-5, -5), (-5, -4), (-5, -5)]), + ], + [ + MultiPolygon( + [ + Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)]), + Polygon([(0, 1), (1, 0), (0, -1), (-1, 0), (0, 1)]), + ] + ), + MultiPolygon( + [ + Polygon( + [(-4, -4), (-4, -5), (-5, -5), (-5, -4), (-5, -5)] + ), + Polygon([(-2, 0), (-2, -2), (0, -2), (0, 0), (-2, 0)]), + ] + ), + ], + ], +) +@pytest.mark.parametrize( + "polygons2", + [ + [ + Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)]), + Polygon([(-4, -4), (-4, -5), (-5, -5), (-5, -4), (-5, -5)]), + ], + [ + MultiPolygon( + [ + Polygon([(0, 1), (1, 0), (-1, 0), (0, 1)]), + Polygon([(0, 1), (1, 0), (0, -1), (-1, 0), (0, 1)]), + ] + ), + MultiPolygon( + [ + Polygon( + [(-4, -4), (-4, -5), (-5, -5), (-5, -4), (-5, -5)] + ), + Polygon([(-2, 0), (-2, -2), (0, -2), (0, 0), (-2, 0)]), + ] + ), + ], + ], +) +def test_two_pair(polygons1, polygons2): + lhs = gpd.GeoSeries(polygons1) + rhs = gpd.GeoSeries(polygons2) + + dlhs = cuspatial.GeoSeries(polygons1) + drhs = cuspatial.GeoSeries(polygons2) + + expect = lhs.distance(rhs) + got = cuspatial.pairwise_polygon_distance(dlhs, drhs) + + assert_series_equal(got, cudf.Series(expect)) + + +def test_linestring_polygon_large(polygon_generator): + N = 100 + polygons1 = gpd.GeoSeries(polygon_generator(N, 20.0, 5.0)) + polygons2 = gpd.GeoSeries(polygon_generator(N, 10.0, 3.0)) + + dpolygons1 = cuspatial.from_geopandas(polygons1) + dpolygons2 = cuspatial.from_geopandas(polygons2) + + expect = polygons1.distance(polygons2) + got = cuspatial.pairwise_polygon_distance(dpolygons1, dpolygons2) + + assert_series_equal(got, cudf.Series(expect)) + + +def test_point_polygon_geoboundaries(naturalearth_lowres): + N = 50 + + lhs = naturalearth_lowres.geometry[:N].reset_index(drop=True) + rhs = naturalearth_lowres.geometry[N : 2 * N].reset_index(drop=True) + expect = lhs.distance(rhs) + got = cuspatial.pairwise_polygon_distance( + cuspatial.GeoSeries(lhs), cuspatial.GeoSeries(rhs) + ) + assert_series_equal(cudf.Series(expect), got) + + +def test_self_distance(polygon_generator): + N = 100 + polygons = gpd.GeoSeries(polygon_generator(N, 20.0, 5.0)) + polygons = cuspatial.from_geopandas(polygons) + got = cuspatial.pairwise_polygon_distance(polygons, polygons) + expect = cudf.Series(cp.zeros((N,))) + + assert_series_equal(got, expect) + + +def test_touching_distance(): + polygons1 = [Polygon([(0, 0), (1, 1), (1, 0), (0, 0)])] + polygons2 = [Polygon([(1, 0.5), (2, 0), (3, 0.5), (1, 0.5)])] + + got = cuspatial.pairwise_polygon_distance( + cuspatial.GeoSeries(polygons1), cuspatial.GeoSeries(polygons2) + ) + + expect = gpd.GeoSeries(polygons1).distance(gpd.GeoSeries(polygons2)) + + assert_series_equal(got, cudf.Series(expect)) + + +def test_distance_one(): + polygons1 = [Polygon([(1, 1), (2, 1), (2, 2), (1, 2), (1, 1)])] + + polygons2 = [Polygon([(0, 0), (0, 1), (-1, 1), (-1, 0), (0, 0)])] + + got = cuspatial.pairwise_polygon_distance( + cuspatial.GeoSeries(polygons1), cuspatial.GeoSeries(polygons2) + ) + + expect = gpd.GeoSeries(polygons1).distance(gpd.GeoSeries(polygons2)) + + assert_series_equal(got, cudf.Series(expect)) From e1de9f5d2b50de2d79ed16324e3a58d9fe5ec391 Mon Sep 17 00:00:00 2001 From: Mark Harris <783069+harrism@users.noreply.github.com> Date: Thu, 4 May 2023 12:57:24 +1000 Subject: [PATCH 15/63] Reorganize src, tests, and benchmarks (#1115) Fixes #663. Also fixes #1105 Organizes all source, test, and benchmark files into directories matching the names of the associated headers that define the APIs they implement/test/benchmark. Also fixes up documentation so it is consistent with this. Authors: - Mark Harris (https://github.com/harrism) Approvers: - Paul Taylor (https://github.com/trxcllnt) - H. Thomson Comer (https://github.com/thomcom) - Michael Wang (https://github.com/isVoid) URL: https://github.com/rapidsai/cuspatial/pull/1115 --- cpp/CMakeLists.txt | 34 ++++----- cpp/benchmarks/CMakeLists.txt | 19 ++--- .../{ => distance}/hausdorff_benchmark.cpp | 0 .../pairwise_linestring_distance.cu | 0 .../{ => indexing}/quadtree_on_points.cu | 0 .../point_in_polygon.cu | 0 .../{ => points_in_range}/points_in_range.cu | 0 .../{ => utility}/floating_point_equality.cu | 0 cpp/doxygen/developer_guide/BENCHMARKING.md | 7 +- .../developer_guide/DEVELOPER_GUIDE.md | 11 +-- cpp/doxygen/developer_guide/TESTING.md | 5 +- .../detail/algorithm/linestring_distance.cuh | 2 + .../geometry_collection/multipoint_ref.cuh | 4 +- .../geometry_collection/multipolygon_ref.cuh | 16 ++++ ...inestring_intersection_with_duplicates.cuh | 2 + .../detail/join/quadtree_point_in_polygon.cuh | 2 + .../quadtree_point_to_nearest_linestring.cuh | 2 + .../trajectory_distances_and_speeds.cuh | 4 +- cpp/include/cuspatial/distance.hpp | 17 +++++ .../cuspatial/distance/polygon_distance.hpp | 44 ----------- .../cuspatial_test/column_factories.hpp | 2 + .../cuspatial_test/geometry_generator.cuh | 2 + .../cuspatial_test/vector_factories.cuh | 2 + .../linestring_bounding_boxes.cu | 0 .../polygon_bounding_boxes.cu | 0 cpp/src/{spatial => distance}/hausdorff.cu | 0 cpp/src/{spatial => distance}/haversine.cu | 0 .../linestring_distance.cu | 0 .../linestring_polygon_distance.cu | 0 .../{spatial => distance}/point_distance.cu | 0 .../point_linestring_distance.cu | 0 .../point_polygon_distance.cu | 0 .../{spatial => distance}/polygon_distance.cu | 0 .../pairwise_multipoint_equals_count.cu | 0 .../construction/detail/utilities.cuh | 43 ----------- .../{construction => }/point_quadtree.cu | 0 .../linestring_intersection.cu | 0 .../point_linestring_nearest_points.cu | 0 .../point_in_polygon.cu | 0 .../points_in_range.cu | 0 .../sinusoidal_projection.cu | 0 cpp/tests/CMakeLists.txt | 74 +++++++++---------- .../linestring_bounding_boxes_test.cpp | 0 .../linestring_bounding_boxes_test.cu | 0 .../point_bounding_boxes_test.cu | 2 +- .../polygon_bounding_boxes_test.cpp | 0 .../polygon_bounding_boxes_test.cu | 0 .../{spatial => }/distance/hausdorff_test.cpp | 0 .../{spatial => }/distance/hausdorff_test.cu | 0 .../{spatial => }/distance/haversine_test.cpp | 0 .../{spatial => }/distance/haversine_test.cu | 0 .../distance/linestring_distance_test.cpp | 0 .../distance/linestring_distance_test.cu | 0 .../linestring_distance_test_medium.cu | 0 .../linestring_polygon_distance_test.cpp | 0 .../linestring_polygon_distance_test.cu | 0 .../distance/point_distance_test.cpp | 0 .../distance/point_distance_test.cu | 0 .../point_linestring_distance_test.cpp | 0 .../point_linestring_distance_test.cu | 0 .../distance/point_polygon_distance_test.cpp | 0 .../distance/point_polygon_distance_test.cu | 0 .../distance/polygon_distance_test.cpp | 2 +- .../distance/polygon_distance_test.cu | 0 .../pairwise_multipoint_equals_count_test.cpp | 0 .../pairwise_multipoint_equals_count_test.cu | 0 .../intersection/intersection_test_utils.cuh | 0 .../linestring_intersection_count_test.cu | 0 ...tersection_intermediates_remove_if_test.cu | 0 .../linestring_intersection_test.cpp | 0 .../linestring_intersection_test.cu | 0 ...tring_intersection_with_duplicates_test.cu | 0 .../point_linestring_nearest_points_test.cpp | 0 .../point_linestring_nearest_points_test.cu | 0 .../pairwise_point_in_polygon_test.cpp | 0 .../pairwise_point_in_polygon_test.cu | 0 .../point_in_polygon_test.cpp | 0 .../point_in_polygon/point_in_polygon_test.cu | 0 .../points_in_range/points_in_range_test.cpp | 0 .../points_in_range/points_in_range_test.cu | 0 .../trajectory/trajectory_test_utils.cuh | 1 - .../_lib/cpp/distance/polygon_distance.pxd | 2 +- 82 files changed, 129 insertions(+), 170 deletions(-) rename cpp/benchmarks/{ => distance}/hausdorff_benchmark.cpp (100%) rename cpp/benchmarks/{ => distance}/pairwise_linestring_distance.cu (100%) rename cpp/benchmarks/{ => indexing}/quadtree_on_points.cu (100%) rename cpp/benchmarks/{ => point_in_polygon}/point_in_polygon.cu (100%) rename cpp/benchmarks/{ => points_in_range}/points_in_range.cu (100%) rename cpp/benchmarks/{ => utility}/floating_point_equality.cu (100%) delete mode 100644 cpp/include/cuspatial/distance/polygon_distance.hpp rename cpp/src/{spatial => bounding_boxes}/linestring_bounding_boxes.cu (100%) rename cpp/src/{spatial => bounding_boxes}/polygon_bounding_boxes.cu (100%) rename cpp/src/{spatial => distance}/hausdorff.cu (100%) rename cpp/src/{spatial => distance}/haversine.cu (100%) rename cpp/src/{spatial => distance}/linestring_distance.cu (100%) rename cpp/src/{spatial => distance}/linestring_polygon_distance.cu (100%) rename cpp/src/{spatial => distance}/point_distance.cu (100%) rename cpp/src/{spatial => distance}/point_linestring_distance.cu (100%) rename cpp/src/{spatial => distance}/point_polygon_distance.cu (100%) rename cpp/src/{spatial => distance}/polygon_distance.cu (100%) rename cpp/src/{spatial => equality}/pairwise_multipoint_equals_count.cu (100%) delete mode 100644 cpp/src/indexing/construction/detail/utilities.cuh rename cpp/src/indexing/{construction => }/point_quadtree.cu (100%) rename cpp/src/{spatial => intersection}/linestring_intersection.cu (100%) rename cpp/src/{spatial => nearest_points}/point_linestring_nearest_points.cu (100%) rename cpp/src/{spatial => point_in_polygon}/point_in_polygon.cu (100%) rename cpp/src/{spatial => points_in_range}/points_in_range.cu (100%) rename cpp/src/{spatial => projection}/sinusoidal_projection.cu (100%) rename cpp/tests/{spatial => }/bounding_boxes/linestring_bounding_boxes_test.cpp (100%) rename cpp/tests/{spatial => }/bounding_boxes/linestring_bounding_boxes_test.cu (100%) rename cpp/tests/{spatial => }/bounding_boxes/point_bounding_boxes_test.cu (97%) rename cpp/tests/{spatial => }/bounding_boxes/polygon_bounding_boxes_test.cpp (100%) rename cpp/tests/{spatial => }/bounding_boxes/polygon_bounding_boxes_test.cu (100%) rename cpp/tests/{spatial => }/distance/hausdorff_test.cpp (100%) rename cpp/tests/{spatial => }/distance/hausdorff_test.cu (100%) rename cpp/tests/{spatial => }/distance/haversine_test.cpp (100%) rename cpp/tests/{spatial => }/distance/haversine_test.cu (100%) rename cpp/tests/{spatial => }/distance/linestring_distance_test.cpp (100%) rename cpp/tests/{spatial => }/distance/linestring_distance_test.cu (100%) rename cpp/tests/{spatial => }/distance/linestring_distance_test_medium.cu (100%) rename cpp/tests/{spatial => }/distance/linestring_polygon_distance_test.cpp (100%) rename cpp/tests/{spatial => }/distance/linestring_polygon_distance_test.cu (100%) rename cpp/tests/{spatial => }/distance/point_distance_test.cpp (100%) rename cpp/tests/{spatial => }/distance/point_distance_test.cu (100%) rename cpp/tests/{spatial => }/distance/point_linestring_distance_test.cpp (100%) rename cpp/tests/{spatial => }/distance/point_linestring_distance_test.cu (100%) rename cpp/tests/{spatial => }/distance/point_polygon_distance_test.cpp (100%) rename cpp/tests/{spatial => }/distance/point_polygon_distance_test.cu (100%) rename cpp/tests/{spatial => }/distance/polygon_distance_test.cpp (99%) rename cpp/tests/{spatial => }/distance/polygon_distance_test.cu (100%) rename cpp/tests/{spatial => }/equality/pairwise_multipoint_equals_count_test.cpp (100%) rename cpp/tests/{spatial => }/equality/pairwise_multipoint_equals_count_test.cu (100%) rename cpp/tests/{spatial => }/intersection/intersection_test_utils.cuh (100%) rename cpp/tests/{spatial => }/intersection/linestring_intersection_count_test.cu (100%) rename cpp/tests/{spatial => }/intersection/linestring_intersection_intermediates_remove_if_test.cu (100%) rename cpp/tests/{spatial => }/intersection/linestring_intersection_test.cpp (100%) rename cpp/tests/{spatial => }/intersection/linestring_intersection_test.cu (100%) rename cpp/tests/{spatial => }/intersection/linestring_intersection_with_duplicates_test.cu (100%) rename cpp/tests/{spatial => }/nearest_points/point_linestring_nearest_points_test.cpp (100%) rename cpp/tests/{spatial => }/nearest_points/point_linestring_nearest_points_test.cu (100%) rename cpp/tests/{spatial => }/point_in_polygon/pairwise_point_in_polygon_test.cpp (100%) rename cpp/tests/{spatial => }/point_in_polygon/pairwise_point_in_polygon_test.cu (100%) rename cpp/tests/{spatial => }/point_in_polygon/point_in_polygon_test.cpp (100%) rename cpp/tests/{spatial => }/point_in_polygon/point_in_polygon_test.cu (100%) rename cpp/tests/{spatial => }/points_in_range/points_in_range_test.cpp (100%) rename cpp/tests/{spatial => }/points_in_range/points_in_range_test.cu (100%) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 804bdaf95..983123252 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -117,27 +117,27 @@ endif() # - library targets ------------------------------------------------------------------------------- add_library(cuspatial + src/bounding_boxes/linestring_bounding_boxes.cu + src/bounding_boxes/polygon_bounding_boxes.cu src/column/geometry_column_view.cpp - src/indexing/construction/point_quadtree.cu + src/distance/hausdorff.cu + src/distance/haversine.cu + src/distance/linestring_distance.cu + src/distance/linestring_polygon_distance.cu + src/distance/point_distance.cu + src/distance/point_linestring_distance.cu + src/distance/point_polygon_distance.cu + src/distance/polygon_distance.cu + src/equality/pairwise_multipoint_equals_count.cu + src/indexing/point_quadtree.cu + src/intersection/linestring_intersection.cu src/join/quadtree_point_in_polygon.cu src/join/quadtree_point_to_nearest_linestring.cu src/join/quadtree_bbox_filtering.cu - src/spatial/linestring_bounding_boxes.cu - src/spatial/polygon_bounding_boxes.cu - src/spatial/pairwise_multipoint_equals_count.cu - src/spatial/point_in_polygon.cu - src/spatial/points_in_range.cu - src/spatial/haversine.cu - src/spatial/hausdorff.cu - src/spatial/linestring_distance.cu - src/spatial/linestring_intersection.cu - src/spatial/point_distance.cu - src/spatial/point_linestring_distance.cu - src/spatial/point_polygon_distance.cu - src/spatial/linestring_polygon_distance.cu - src/spatial/polygon_distance.cu - src/spatial/point_linestring_nearest_points.cu - src/spatial/sinusoidal_projection.cu + src/nearest_points/point_linestring_nearest_points.cu + src/point_in_polygon/point_in_polygon.cu + src/points_in_range/points_in_range.cu + src/projection/sinusoidal_projection.cu src/trajectory/derive_trajectories.cu src/trajectory/trajectory_bounding_boxes.cu src/trajectory/trajectory_distances_and_speeds.cu diff --git a/cpp/benchmarks/CMakeLists.txt b/cpp/benchmarks/CMakeLists.txt index 48e66a0a7..99f90eec0 100644 --- a/cpp/benchmarks/CMakeLists.txt +++ b/cpp/benchmarks/CMakeLists.txt @@ -76,23 +76,20 @@ endfunction() ### benchmark sources ############################################################################# ################################################################################################### -################################################################################################### -# - hausdorff benchmark --------------------------------------------------------------------------- - ConfigureBench(HAUSDORFF_BENCH - hausdorff_benchmark.cpp) + distance/hausdorff_benchmark.cpp) ConfigureNVBench(DISTANCES_BENCH - pairwise_linestring_distance.cu) + distance/pairwise_linestring_distance.cu) -ConfigureNVBench(POINTS_IN_RANGE_BENCH - points_in_range.cu) +ConfigureNVBench(QUADTREE_ON_POINTS_BENCH + indexing/quadtree_on_points.cu) ConfigureNVBench(POINT_IN_POLYGON_BENCH - point_in_polygon.cu) + point_in_polygon/point_in_polygon.cu) -ConfigureNVBench(QUADTREE_ON_POINTS_BENCH - quadtree_on_points.cu) +ConfigureNVBench(POINTS_IN_RANGE_BENCH + points_in_range/points_in_range.cu) ConfigureNVBench(FLOATING_POINT_EQUALITY_BENCH - floating_point_equality.cu) + utility/floating_point_equality.cu) diff --git a/cpp/benchmarks/hausdorff_benchmark.cpp b/cpp/benchmarks/distance/hausdorff_benchmark.cpp similarity index 100% rename from cpp/benchmarks/hausdorff_benchmark.cpp rename to cpp/benchmarks/distance/hausdorff_benchmark.cpp diff --git a/cpp/benchmarks/pairwise_linestring_distance.cu b/cpp/benchmarks/distance/pairwise_linestring_distance.cu similarity index 100% rename from cpp/benchmarks/pairwise_linestring_distance.cu rename to cpp/benchmarks/distance/pairwise_linestring_distance.cu diff --git a/cpp/benchmarks/quadtree_on_points.cu b/cpp/benchmarks/indexing/quadtree_on_points.cu similarity index 100% rename from cpp/benchmarks/quadtree_on_points.cu rename to cpp/benchmarks/indexing/quadtree_on_points.cu diff --git a/cpp/benchmarks/point_in_polygon.cu b/cpp/benchmarks/point_in_polygon/point_in_polygon.cu similarity index 100% rename from cpp/benchmarks/point_in_polygon.cu rename to cpp/benchmarks/point_in_polygon/point_in_polygon.cu diff --git a/cpp/benchmarks/points_in_range.cu b/cpp/benchmarks/points_in_range/points_in_range.cu similarity index 100% rename from cpp/benchmarks/points_in_range.cu rename to cpp/benchmarks/points_in_range/points_in_range.cu diff --git a/cpp/benchmarks/floating_point_equality.cu b/cpp/benchmarks/utility/floating_point_equality.cu similarity index 100% rename from cpp/benchmarks/floating_point_equality.cu rename to cpp/benchmarks/utility/floating_point_equality.cu diff --git a/cpp/doxygen/developer_guide/BENCHMARKING.md b/cpp/doxygen/developer_guide/BENCHMARKING.md index 7df628973..ebdd12526 100644 --- a/cpp/doxygen/developer_guide/BENCHMARKING.md +++ b/cpp/doxygen/developer_guide/BENCHMARKING.md @@ -15,9 +15,9 @@ benchmarks in `cpp/benchmarks` to understand the options. ## Directory and File Naming The naming of unit benchmark directories and source files should be consistent with the feature -being benchmarked. For example, the benchmarks for APIs in `point_in_polygon.hpp` should live in -`cpp/benchmarks/point_in_polygon.cu`. Each feature (or set of related features) should have its own -benchmark source file named `{.cu,cpp}`. +being benchmarked. For example, the benchmarks for APIs in `distance.hpp` should live in +`cpp/benchmarks/distance/`. Each feature (or set of related features) should have its own +benchmark source file named `{.cu,cpp}`. ## CUDA Asynchrony and benchmark accuracy @@ -46,7 +46,6 @@ sets larger than this point is generally not helpful, except in specific cases w exercises different code and can therefore uncover regressions that smaller benchmarks will not (this should be rare). - Generally we should benchmark public APIs. Benchmarking detail functions and/or internal utilities should only be done if detecting regressions in them would be sufficiently difficult to do from public API benchmarks. diff --git a/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md b/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md index 586310b19..4cbbd9bee 100644 --- a/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md +++ b/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md @@ -38,19 +38,20 @@ TODO: add terms External/public libcuspatial APIs are grouped based on functionality into an appropriately titled header file in `cuspatial/cpp/include/cuspatial/`. For example, -`cuspatial/cpp/include/cuspatial/projection.hpp` contains the declarations of public API -functions related to coordinate projection transforms. Note the `.hpp` file extension used to +`cuspatial/cpp/include/cuspatial/distance.hpp` contains the declarations of public API +functions related to distance computations. Note the `.hpp` file extension used to indicate a C++ header file that can be included from a `.cpp` source file. Header files should use the `#pragma once` include guard. The folder that contains the source files that implement an API should be named consistently with the name of the of the header for the API. For example, the implementation of the APIs found in -`cuspatial/cpp/include/cuspatial/trajectory.hpp` are located in `cuspatial/src/trajectory`. This +`cuspatial/cpp/include/cuspatial/trajectory.hpp` are located in `cuspatial/cpp/src/trajectory`. This rule obviously does not apply to the header-only API, since the headers are the source files. -Likewise, unit tests reside in folders corresponding to the names of the API headers, e.g. -trajectory.hpp tests are in `cuspatial/tests/trajectory/`. +Likewise, unit tests and benchmarks reside in folders corresponding to the names of the API headers, +e.g. distance.hpp tests are in `cuspatial/cpp/tests/distance/` and benchmarks are in +`cuspatial/cpp/benchmarks/distance/`. Internal API headers containing `detail` namespace definitions that are used across translation units inside libcuspatial should be placed in `include/cuspatial/detail`. diff --git a/cpp/doxygen/developer_guide/TESTING.md b/cpp/doxygen/developer_guide/TESTING.md index 8fcb58b25..fc71dd2b9 100644 --- a/cpp/doxygen/developer_guide/TESTING.md +++ b/cpp/doxygen/developer_guide/TESTING.md @@ -41,9 +41,8 @@ rather than throwing exceptions. ## Directory and File Naming The naming of unit test directories and source files should be consistent with the feature being -tested. For example, the tests for APIs in `point_in_polygon.hpp` should live in -`cuspatial/cpp/tests/point_in_polygon_test.cpp`. Each feature (or set of related features) should -have its own test source file named `_test.cu/cpp`. +tested. For example, the tests for APIs in `distance.hpp` should live in files in +`cuspatial/cpp/tests/distance/`. In the interest of improving compile time, whenever possible, test source files should be `.cpp` files because `nvcc` is slower than `gcc` in compiling host code. Note that `thrust::device_vector` diff --git a/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh b/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh index 31b984551..4c988612d 100644 --- a/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh +++ b/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include diff --git a/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh b/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh index 23346d9e0..9e935e7cc 100644 --- a/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry_collection/multipoint_ref.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #pragma once + #include #include diff --git a/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh b/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh index 78920afe5..a663a2dde 100644 --- a/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh +++ b/cpp/include/cuspatial/detail/geometry_collection/multipolygon_ref.cuh @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + #pragma once #include diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh index e240acb88..8e35dfdca 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include #include diff --git a/cpp/include/cuspatial/detail/join/quadtree_point_in_polygon.cuh b/cpp/include/cuspatial/detail/join/quadtree_point_in_polygon.cuh index 2a9594317..1ae0ff1bf 100644 --- a/cpp/include/cuspatial/detail/join/quadtree_point_in_polygon.cuh +++ b/cpp/include/cuspatial/detail/join/quadtree_point_in_polygon.cuh @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include #include diff --git a/cpp/include/cuspatial/detail/join/quadtree_point_to_nearest_linestring.cuh b/cpp/include/cuspatial/detail/join/quadtree_point_to_nearest_linestring.cuh index a317758d9..bdd0c611e 100644 --- a/cpp/include/cuspatial/detail/join/quadtree_point_to_nearest_linestring.cuh +++ b/cpp/include/cuspatial/detail/join/quadtree_point_to_nearest_linestring.cuh @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include #include diff --git a/cpp/include/cuspatial/detail/trajectory/trajectory_distances_and_speeds.cuh b/cpp/include/cuspatial/detail/trajectory/trajectory_distances_and_speeds.cuh index e5d7116af..baede9b92 100644 --- a/cpp/include/cuspatial/detail/trajectory/trajectory_distances_and_speeds.cuh +++ b/cpp/include/cuspatial/detail/trajectory/trajectory_distances_and_speeds.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include diff --git a/cpp/include/cuspatial/distance.hpp b/cpp/include/cuspatial/distance.hpp index 113707b72..d67c533df 100644 --- a/cpp/include/cuspatial/distance.hpp +++ b/cpp/include/cuspatial/distance.hpp @@ -362,6 +362,23 @@ std::unique_ptr pairwise_linestring_polygon_distance( geometry_column_view const& multipolygons, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); +/** + * @brief Compute pairwise (multi)polygon-to-(multi)polygon Cartesian distance + * + * Computes the cartesian distance between each pair of the multipolygons. + * + * @param lhs Geometry column of the multipolygons to compute distance from + * @param rhs Geometry column of the multipolygons to compute distance to + * @param mr Device memory resource used to allocate the returned column. + * + * @return Column of distances between each pair of input geometries, same type as input coordinate + * types. + */ +std::unique_ptr pairwise_polygon_distance( + geometry_column_view const& lhs, + geometry_column_view const& rhs, + rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); + /** * @} // end of doxygen group */ diff --git a/cpp/include/cuspatial/distance/polygon_distance.hpp b/cpp/include/cuspatial/distance/polygon_distance.hpp deleted file mode 100644 index 4b1a291c9..000000000 --- a/cpp/include/cuspatial/distance/polygon_distance.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. - * - * 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. - */ - -#include - -#include - -#include - -#include - -namespace cuspatial { - -/** - * @brief Compute pairwise (multi)polygon-to-(multi)polygon Cartesian distance - * - * Computes the cartesian distance between each pair of the multipolygons. - * - * @param lhs Geometry column of the multipolygons to compute distance from - * @param rhs Geometry column of the multipolygons to compute distance to - * @param mr Device memory resource used to allocate the returned column. - * - * @return Column of distances between each pair of input geometries, same type as input coordinate - * types. - */ -std::unique_ptr pairwise_polygon_distance( - geometry_column_view const& lhs, - geometry_column_view const& rhs, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); - -} // namespace cuspatial diff --git a/cpp/include/cuspatial_test/column_factories.hpp b/cpp/include/cuspatial_test/column_factories.hpp index 954f952ba..30f426cdc 100644 --- a/cpp/include/cuspatial_test/column_factories.hpp +++ b/cpp/include/cuspatial_test/column_factories.hpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include diff --git a/cpp/include/cuspatial_test/geometry_generator.cuh b/cpp/include/cuspatial_test/geometry_generator.cuh index d9214d447..4dd2dc73a 100644 --- a/cpp/include/cuspatial_test/geometry_generator.cuh +++ b/cpp/include/cuspatial_test/geometry_generator.cuh @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include diff --git a/cpp/include/cuspatial_test/vector_factories.cuh b/cpp/include/cuspatial_test/vector_factories.cuh index d8730e230..020645f94 100644 --- a/cpp/include/cuspatial_test/vector_factories.cuh +++ b/cpp/include/cuspatial_test/vector_factories.cuh @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include diff --git a/cpp/src/spatial/linestring_bounding_boxes.cu b/cpp/src/bounding_boxes/linestring_bounding_boxes.cu similarity index 100% rename from cpp/src/spatial/linestring_bounding_boxes.cu rename to cpp/src/bounding_boxes/linestring_bounding_boxes.cu diff --git a/cpp/src/spatial/polygon_bounding_boxes.cu b/cpp/src/bounding_boxes/polygon_bounding_boxes.cu similarity index 100% rename from cpp/src/spatial/polygon_bounding_boxes.cu rename to cpp/src/bounding_boxes/polygon_bounding_boxes.cu diff --git a/cpp/src/spatial/hausdorff.cu b/cpp/src/distance/hausdorff.cu similarity index 100% rename from cpp/src/spatial/hausdorff.cu rename to cpp/src/distance/hausdorff.cu diff --git a/cpp/src/spatial/haversine.cu b/cpp/src/distance/haversine.cu similarity index 100% rename from cpp/src/spatial/haversine.cu rename to cpp/src/distance/haversine.cu diff --git a/cpp/src/spatial/linestring_distance.cu b/cpp/src/distance/linestring_distance.cu similarity index 100% rename from cpp/src/spatial/linestring_distance.cu rename to cpp/src/distance/linestring_distance.cu diff --git a/cpp/src/spatial/linestring_polygon_distance.cu b/cpp/src/distance/linestring_polygon_distance.cu similarity index 100% rename from cpp/src/spatial/linestring_polygon_distance.cu rename to cpp/src/distance/linestring_polygon_distance.cu diff --git a/cpp/src/spatial/point_distance.cu b/cpp/src/distance/point_distance.cu similarity index 100% rename from cpp/src/spatial/point_distance.cu rename to cpp/src/distance/point_distance.cu diff --git a/cpp/src/spatial/point_linestring_distance.cu b/cpp/src/distance/point_linestring_distance.cu similarity index 100% rename from cpp/src/spatial/point_linestring_distance.cu rename to cpp/src/distance/point_linestring_distance.cu diff --git a/cpp/src/spatial/point_polygon_distance.cu b/cpp/src/distance/point_polygon_distance.cu similarity index 100% rename from cpp/src/spatial/point_polygon_distance.cu rename to cpp/src/distance/point_polygon_distance.cu diff --git a/cpp/src/spatial/polygon_distance.cu b/cpp/src/distance/polygon_distance.cu similarity index 100% rename from cpp/src/spatial/polygon_distance.cu rename to cpp/src/distance/polygon_distance.cu diff --git a/cpp/src/spatial/pairwise_multipoint_equals_count.cu b/cpp/src/equality/pairwise_multipoint_equals_count.cu similarity index 100% rename from cpp/src/spatial/pairwise_multipoint_equals_count.cu rename to cpp/src/equality/pairwise_multipoint_equals_count.cu diff --git a/cpp/src/indexing/construction/detail/utilities.cuh b/cpp/src/indexing/construction/detail/utilities.cuh deleted file mode 100644 index d89952e17..000000000 --- a/cpp/src/indexing/construction/detail/utilities.cuh +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. - * - * 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. - */ - -#pragma once - -#include -#include - -#include - -#include - -namespace cuspatial { -namespace detail { - -/** - * @brief Helper function to reduce verbosity creating cudf fixed-width columns - */ -template -inline std::unique_ptr make_fixed_width_column( - cudf::size_type size, - rmm::cuda_stream_view stream = rmm::cuda_stream_default, - rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()) -{ - return cudf::make_fixed_width_column( - cudf::data_type{cudf::type_to_id()}, size, cudf::mask_state::UNALLOCATED, stream, mr); -} - -} // namespace detail -} // namespace cuspatial diff --git a/cpp/src/indexing/construction/point_quadtree.cu b/cpp/src/indexing/point_quadtree.cu similarity index 100% rename from cpp/src/indexing/construction/point_quadtree.cu rename to cpp/src/indexing/point_quadtree.cu diff --git a/cpp/src/spatial/linestring_intersection.cu b/cpp/src/intersection/linestring_intersection.cu similarity index 100% rename from cpp/src/spatial/linestring_intersection.cu rename to cpp/src/intersection/linestring_intersection.cu diff --git a/cpp/src/spatial/point_linestring_nearest_points.cu b/cpp/src/nearest_points/point_linestring_nearest_points.cu similarity index 100% rename from cpp/src/spatial/point_linestring_nearest_points.cu rename to cpp/src/nearest_points/point_linestring_nearest_points.cu diff --git a/cpp/src/spatial/point_in_polygon.cu b/cpp/src/point_in_polygon/point_in_polygon.cu similarity index 100% rename from cpp/src/spatial/point_in_polygon.cu rename to cpp/src/point_in_polygon/point_in_polygon.cu diff --git a/cpp/src/spatial/points_in_range.cu b/cpp/src/points_in_range/points_in_range.cu similarity index 100% rename from cpp/src/spatial/points_in_range.cu rename to cpp/src/points_in_range/points_in_range.cu diff --git a/cpp/src/spatial/sinusoidal_projection.cu b/cpp/src/projection/sinusoidal_projection.cu similarity index 100% rename from cpp/src/spatial/sinusoidal_projection.cu rename to cpp/src/projection/sinusoidal_projection.cu diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 74cd736dd..68fa96dd5 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -68,58 +68,58 @@ ConfigureTest(SINUSOIDAL_PROJECTION_TEST # bounding boxes ConfigureTest(LINESTRING_BOUNDING_BOXES_TEST - spatial/bounding_boxes/linestring_bounding_boxes_test.cpp) + bounding_boxes/linestring_bounding_boxes_test.cpp) ConfigureTest(POLYGON_BOUNDING_BOXES_TEST - spatial/bounding_boxes/polygon_bounding_boxes_test.cpp) + bounding_boxes/polygon_bounding_boxes_test.cpp) # distance ConfigureTest(HAVERSINE_TEST - spatial/distance/haversine_test.cpp) + distance/haversine_test.cpp) ConfigureTest(HAUSDORFF_TEST - spatial/distance/hausdorff_test.cpp) + distance/hausdorff_test.cpp) ConfigureTest(POINT_DISTANCE_TEST - spatial/distance/point_distance_test.cpp) + distance/point_distance_test.cpp) ConfigureTest(POINT_LINESTRING_DISTANCE_TEST - spatial/distance/point_linestring_distance_test.cpp) + distance/point_linestring_distance_test.cpp) ConfigureTest(LINESTRING_DISTANCE_TEST - spatial/distance/linestring_distance_test.cpp) + distance/linestring_distance_test.cpp) ConfigureTest(POINT_POLYGON_DISTANCE_TEST - spatial/distance/point_polygon_distance_test.cpp) + distance/point_polygon_distance_test.cpp) ConfigureTest(LINESTRING_POLYGON_DISTANCE_TEST - spatial/distance/linestring_polygon_distance_test.cpp) + distance/linestring_polygon_distance_test.cpp) ConfigureTest(POLYGON_DISTANCE_TEST - spatial/distance/polygon_distance_test.cpp) + distance/polygon_distance_test.cpp) # equality ConfigureTest(PAIRWISE_MULTIPOINT_EQUALS_COUNT_TEST - spatial/equality/pairwise_multipoint_equals_count_test.cpp) + equality/pairwise_multipoint_equals_count_test.cpp) # intersection ConfigureTest(LINESTRING_INTERSECTION_TEST - spatial/intersection/linestring_intersection_test.cpp) + intersection/linestring_intersection_test.cpp) # nearest points ConfigureTest(POINT_LINESTRING_NEAREST_POINT_TEST - spatial/nearest_points/point_linestring_nearest_points_test.cpp) + nearest_points/point_linestring_nearest_points_test.cpp) # point in polygon ConfigureTest(POINT_IN_POLYGON_TEST - spatial/point_in_polygon/point_in_polygon_test.cpp) + point_in_polygon/point_in_polygon_test.cpp) ConfigureTest(PAIRWISE_POINT_IN_POLYGON_TEST - spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp) + point_in_polygon/pairwise_point_in_polygon_test.cpp) # points in range ConfigureTest(POINTS_IN_RANGE_TEST - spatial/points_in_range/points_in_range_test.cpp) + points_in_range/points_in_range_test.cpp) # trajectory ConfigureTest(TRAJECTORY_DISTANCES_AND_SPEEDS_TEST @@ -176,65 +176,65 @@ ConfigureTest(RANGE_TEST_EXP # bounding boxes ConfigureTest(POINT_BOUNDING_BOXES_TEST_EXP - spatial/bounding_boxes/point_bounding_boxes_test.cu) + bounding_boxes/point_bounding_boxes_test.cu) ConfigureTest(POLYGON_BOUNDING_BOXES_TEST_EXP - spatial/bounding_boxes/polygon_bounding_boxes_test.cu) + bounding_boxes/polygon_bounding_boxes_test.cu) ConfigureTest(LINESTRING_BOUNDING_BOXES_TEST_EXP - spatial/bounding_boxes/linestring_bounding_boxes_test.cu) + bounding_boxes/linestring_bounding_boxes_test.cu) # distance ConfigureTest(HAUSDORFF_TEST_EXP - spatial/distance/hausdorff_test.cu) + distance/hausdorff_test.cu) ConfigureTest(HAVERSINE_TEST_EXP - spatial/distance/haversine_test.cu) + distance/haversine_test.cu) ConfigureTest(POINT_DISTANCE_TEST_EXP - spatial/distance/point_distance_test.cu) + distance/point_distance_test.cu) ConfigureTest(POINT_LINESTRING_DISTANCE_TEST_EXP - spatial/distance/point_linestring_distance_test.cu) + distance/point_linestring_distance_test.cu) ConfigureTest(POINT_POLYGON_DISTANCE_TEST_EXP - spatial/distance/point_polygon_distance_test.cu) + distance/point_polygon_distance_test.cu) ConfigureTest(LINESTRING_POLYGON_DISTANCE_TEST_EXP - spatial/distance/linestring_polygon_distance_test.cu) + distance/linestring_polygon_distance_test.cu) ConfigureTest(LINESTRING_DISTANCE_TEST_EXP - spatial/distance/linestring_distance_test.cu - spatial/distance/linestring_distance_test_medium.cu) + distance/linestring_distance_test.cu + distance/linestring_distance_test_medium.cu) ConfigureTest(POLYGON_DISTANCE_TEST_EXP - spatial/distance/polygon_distance_test.cu) + distance/polygon_distance_test.cu) # equality ConfigureTest(PAIRWISE_MULTIPOINT_EQUALS_COUNT_TEST_EXP - spatial/equality/pairwise_multipoint_equals_count_test.cu) + equality/pairwise_multipoint_equals_count_test.cu) # intersection ConfigureTest(LINESTRING_INTERSECTION_TEST_EXP - spatial/intersection/linestring_intersection_count_test.cu - spatial/intersection/linestring_intersection_intermediates_remove_if_test.cu - spatial/intersection/linestring_intersection_with_duplicates_test.cu - spatial/intersection/linestring_intersection_test.cu) + intersection/linestring_intersection_count_test.cu + intersection/linestring_intersection_intermediates_remove_if_test.cu + intersection/linestring_intersection_with_duplicates_test.cu + intersection/linestring_intersection_test.cu) # nearest points ConfigureTest(POINT_LINESTRING_NEAREST_POINT_TEST_EXP - spatial/nearest_points/point_linestring_nearest_points_test.cu) + nearest_points/point_linestring_nearest_points_test.cu) # point in polygon ConfigureTest(POINT_IN_POLYGON_TEST_EXP - spatial/point_in_polygon/point_in_polygon_test.cu) + point_in_polygon/point_in_polygon_test.cu) ConfigureTest(PAIRWISE_POINT_IN_POLYGON_TEST_EXP - spatial/point_in_polygon/pairwise_point_in_polygon_test.cu) + point_in_polygon/pairwise_point_in_polygon_test.cu) # points in range ConfigureTest(POINTS_IN_RANGE_TEST_EXP - spatial/points_in_range/points_in_range_test.cu) + points_in_range/points_in_range_test.cu) # trajectory ConfigureTest(DERIVE_TRAJECTORIES_TEST_EXP diff --git a/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cpp b/cpp/tests/bounding_boxes/linestring_bounding_boxes_test.cpp similarity index 100% rename from cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cpp rename to cpp/tests/bounding_boxes/linestring_bounding_boxes_test.cpp diff --git a/cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cu b/cpp/tests/bounding_boxes/linestring_bounding_boxes_test.cu similarity index 100% rename from cpp/tests/spatial/bounding_boxes/linestring_bounding_boxes_test.cu rename to cpp/tests/bounding_boxes/linestring_bounding_boxes_test.cu diff --git a/cpp/tests/spatial/bounding_boxes/point_bounding_boxes_test.cu b/cpp/tests/bounding_boxes/point_bounding_boxes_test.cu similarity index 97% rename from cpp/tests/spatial/bounding_boxes/point_bounding_boxes_test.cu rename to cpp/tests/bounding_boxes/point_bounding_boxes_test.cu index e96c2b783..fcc85b965 100644 --- a/cpp/tests/spatial/bounding_boxes/point_bounding_boxes_test.cu +++ b/cpp/tests/bounding_boxes/point_bounding_boxes_test.cu @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "../../trajectory/trajectory_test_utils.cuh" +#include "../trajectory/trajectory_test_utils.cuh" #include diff --git a/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cpp b/cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cpp similarity index 100% rename from cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cpp rename to cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cpp diff --git a/cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cu b/cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cu similarity index 100% rename from cpp/tests/spatial/bounding_boxes/polygon_bounding_boxes_test.cu rename to cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cu diff --git a/cpp/tests/spatial/distance/hausdorff_test.cpp b/cpp/tests/distance/hausdorff_test.cpp similarity index 100% rename from cpp/tests/spatial/distance/hausdorff_test.cpp rename to cpp/tests/distance/hausdorff_test.cpp diff --git a/cpp/tests/spatial/distance/hausdorff_test.cu b/cpp/tests/distance/hausdorff_test.cu similarity index 100% rename from cpp/tests/spatial/distance/hausdorff_test.cu rename to cpp/tests/distance/hausdorff_test.cu diff --git a/cpp/tests/spatial/distance/haversine_test.cpp b/cpp/tests/distance/haversine_test.cpp similarity index 100% rename from cpp/tests/spatial/distance/haversine_test.cpp rename to cpp/tests/distance/haversine_test.cpp diff --git a/cpp/tests/spatial/distance/haversine_test.cu b/cpp/tests/distance/haversine_test.cu similarity index 100% rename from cpp/tests/spatial/distance/haversine_test.cu rename to cpp/tests/distance/haversine_test.cu diff --git a/cpp/tests/spatial/distance/linestring_distance_test.cpp b/cpp/tests/distance/linestring_distance_test.cpp similarity index 100% rename from cpp/tests/spatial/distance/linestring_distance_test.cpp rename to cpp/tests/distance/linestring_distance_test.cpp diff --git a/cpp/tests/spatial/distance/linestring_distance_test.cu b/cpp/tests/distance/linestring_distance_test.cu similarity index 100% rename from cpp/tests/spatial/distance/linestring_distance_test.cu rename to cpp/tests/distance/linestring_distance_test.cu diff --git a/cpp/tests/spatial/distance/linestring_distance_test_medium.cu b/cpp/tests/distance/linestring_distance_test_medium.cu similarity index 100% rename from cpp/tests/spatial/distance/linestring_distance_test_medium.cu rename to cpp/tests/distance/linestring_distance_test_medium.cu diff --git a/cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp b/cpp/tests/distance/linestring_polygon_distance_test.cpp similarity index 100% rename from cpp/tests/spatial/distance/linestring_polygon_distance_test.cpp rename to cpp/tests/distance/linestring_polygon_distance_test.cpp diff --git a/cpp/tests/spatial/distance/linestring_polygon_distance_test.cu b/cpp/tests/distance/linestring_polygon_distance_test.cu similarity index 100% rename from cpp/tests/spatial/distance/linestring_polygon_distance_test.cu rename to cpp/tests/distance/linestring_polygon_distance_test.cu diff --git a/cpp/tests/spatial/distance/point_distance_test.cpp b/cpp/tests/distance/point_distance_test.cpp similarity index 100% rename from cpp/tests/spatial/distance/point_distance_test.cpp rename to cpp/tests/distance/point_distance_test.cpp diff --git a/cpp/tests/spatial/distance/point_distance_test.cu b/cpp/tests/distance/point_distance_test.cu similarity index 100% rename from cpp/tests/spatial/distance/point_distance_test.cu rename to cpp/tests/distance/point_distance_test.cu diff --git a/cpp/tests/spatial/distance/point_linestring_distance_test.cpp b/cpp/tests/distance/point_linestring_distance_test.cpp similarity index 100% rename from cpp/tests/spatial/distance/point_linestring_distance_test.cpp rename to cpp/tests/distance/point_linestring_distance_test.cpp diff --git a/cpp/tests/spatial/distance/point_linestring_distance_test.cu b/cpp/tests/distance/point_linestring_distance_test.cu similarity index 100% rename from cpp/tests/spatial/distance/point_linestring_distance_test.cu rename to cpp/tests/distance/point_linestring_distance_test.cu diff --git a/cpp/tests/spatial/distance/point_polygon_distance_test.cpp b/cpp/tests/distance/point_polygon_distance_test.cpp similarity index 100% rename from cpp/tests/spatial/distance/point_polygon_distance_test.cpp rename to cpp/tests/distance/point_polygon_distance_test.cpp diff --git a/cpp/tests/spatial/distance/point_polygon_distance_test.cu b/cpp/tests/distance/point_polygon_distance_test.cu similarity index 100% rename from cpp/tests/spatial/distance/point_polygon_distance_test.cu rename to cpp/tests/distance/point_polygon_distance_test.cu diff --git a/cpp/tests/spatial/distance/polygon_distance_test.cpp b/cpp/tests/distance/polygon_distance_test.cpp similarity index 99% rename from cpp/tests/spatial/distance/polygon_distance_test.cpp rename to cpp/tests/distance/polygon_distance_test.cpp index 1bea37f43..c1a2e8b4f 100644 --- a/cpp/tests/spatial/distance/polygon_distance_test.cpp +++ b/cpp/tests/distance/polygon_distance_test.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/tests/spatial/distance/polygon_distance_test.cu b/cpp/tests/distance/polygon_distance_test.cu similarity index 100% rename from cpp/tests/spatial/distance/polygon_distance_test.cu rename to cpp/tests/distance/polygon_distance_test.cu diff --git a/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cpp b/cpp/tests/equality/pairwise_multipoint_equals_count_test.cpp similarity index 100% rename from cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cpp rename to cpp/tests/equality/pairwise_multipoint_equals_count_test.cpp diff --git a/cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu b/cpp/tests/equality/pairwise_multipoint_equals_count_test.cu similarity index 100% rename from cpp/tests/spatial/equality/pairwise_multipoint_equals_count_test.cu rename to cpp/tests/equality/pairwise_multipoint_equals_count_test.cu diff --git a/cpp/tests/spatial/intersection/intersection_test_utils.cuh b/cpp/tests/intersection/intersection_test_utils.cuh similarity index 100% rename from cpp/tests/spatial/intersection/intersection_test_utils.cuh rename to cpp/tests/intersection/intersection_test_utils.cuh diff --git a/cpp/tests/spatial/intersection/linestring_intersection_count_test.cu b/cpp/tests/intersection/linestring_intersection_count_test.cu similarity index 100% rename from cpp/tests/spatial/intersection/linestring_intersection_count_test.cu rename to cpp/tests/intersection/linestring_intersection_count_test.cu diff --git a/cpp/tests/spatial/intersection/linestring_intersection_intermediates_remove_if_test.cu b/cpp/tests/intersection/linestring_intersection_intermediates_remove_if_test.cu similarity index 100% rename from cpp/tests/spatial/intersection/linestring_intersection_intermediates_remove_if_test.cu rename to cpp/tests/intersection/linestring_intersection_intermediates_remove_if_test.cu diff --git a/cpp/tests/spatial/intersection/linestring_intersection_test.cpp b/cpp/tests/intersection/linestring_intersection_test.cpp similarity index 100% rename from cpp/tests/spatial/intersection/linestring_intersection_test.cpp rename to cpp/tests/intersection/linestring_intersection_test.cpp diff --git a/cpp/tests/spatial/intersection/linestring_intersection_test.cu b/cpp/tests/intersection/linestring_intersection_test.cu similarity index 100% rename from cpp/tests/spatial/intersection/linestring_intersection_test.cu rename to cpp/tests/intersection/linestring_intersection_test.cu diff --git a/cpp/tests/spatial/intersection/linestring_intersection_with_duplicates_test.cu b/cpp/tests/intersection/linestring_intersection_with_duplicates_test.cu similarity index 100% rename from cpp/tests/spatial/intersection/linestring_intersection_with_duplicates_test.cu rename to cpp/tests/intersection/linestring_intersection_with_duplicates_test.cu diff --git a/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cpp b/cpp/tests/nearest_points/point_linestring_nearest_points_test.cpp similarity index 100% rename from cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cpp rename to cpp/tests/nearest_points/point_linestring_nearest_points_test.cpp diff --git a/cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cu b/cpp/tests/nearest_points/point_linestring_nearest_points_test.cu similarity index 100% rename from cpp/tests/spatial/nearest_points/point_linestring_nearest_points_test.cu rename to cpp/tests/nearest_points/point_linestring_nearest_points_test.cu diff --git a/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp b/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cpp similarity index 100% rename from cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cpp rename to cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cpp diff --git a/cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cu b/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cu similarity index 100% rename from cpp/tests/spatial/point_in_polygon/pairwise_point_in_polygon_test.cu rename to cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cu diff --git a/cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cpp b/cpp/tests/point_in_polygon/point_in_polygon_test.cpp similarity index 100% rename from cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cpp rename to cpp/tests/point_in_polygon/point_in_polygon_test.cpp diff --git a/cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cu b/cpp/tests/point_in_polygon/point_in_polygon_test.cu similarity index 100% rename from cpp/tests/spatial/point_in_polygon/point_in_polygon_test.cu rename to cpp/tests/point_in_polygon/point_in_polygon_test.cu diff --git a/cpp/tests/spatial/points_in_range/points_in_range_test.cpp b/cpp/tests/points_in_range/points_in_range_test.cpp similarity index 100% rename from cpp/tests/spatial/points_in_range/points_in_range_test.cpp rename to cpp/tests/points_in_range/points_in_range_test.cpp diff --git a/cpp/tests/spatial/points_in_range/points_in_range_test.cu b/cpp/tests/points_in_range/points_in_range_test.cu similarity index 100% rename from cpp/tests/spatial/points_in_range/points_in_range_test.cu rename to cpp/tests/points_in_range/points_in_range_test.cu diff --git a/cpp/tests/trajectory/trajectory_test_utils.cuh b/cpp/tests/trajectory/trajectory_test_utils.cuh index 94112cdbe..679674674 100644 --- a/cpp/tests/trajectory/trajectory_test_utils.cuh +++ b/cpp/tests/trajectory/trajectory_test_utils.cuh @@ -1,4 +1,3 @@ - /* * Copyright (c) 2022, NVIDIA CORPORATION. * diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd index 9d2bfab39..62f3a318c 100644 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd +++ b/python/cuspatial/cuspatial/_lib/cpp/distance/polygon_distance.pxd @@ -9,7 +9,7 @@ from cuspatial._lib.cpp.column.geometry_column_view cimport ( ) -cdef extern from "cuspatial/distance/polygon_distance.hpp" \ +cdef extern from "cuspatial/distance.hpp" \ namespace "cuspatial" nogil: cdef unique_ptr[column] pairwise_polygon_distance( const geometry_column_view & lhs, From 8b97a72b4292b4d2c8341f0209c6f8a8a5212b06 Mon Sep 17 00:00:00 2001 From: "H. Thomson Comer" Date: Thu, 4 May 2023 18:13:50 -0500 Subject: [PATCH 16/63] Add `contains`predicate. (#1086) This PR creates a new `.contains` predicate that uses the sum of the result of the `.contains_properly` predicate and the `.intersects` predicate to compute the `.contains` relationship, boundary inclusive. Authors: - H. Thomson Comer (https://github.com/thomcom) Approvers: - Michael Wang (https://github.com/isVoid) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1086 --- .../cuspatial/core/binops/equals_count.py | 3 +- .../core/binpreds/basic_predicates.py | 107 +++++ .../core/binpreds/binpred_dispatch.py | 3 + .../core/binpreds/binpred_interface.py | 37 +- .../cuspatial/core/binpreds/contains.py | 14 +- .../binpreds/contains_geometry_processor.py | 274 +++++++++++ .../core/binpreds/feature_contains.py | 434 +++++------------- .../binpreds/feature_contains_properly.py | 186 ++++++++ .../core/binpreds/feature_intersects.py | 95 ++-- .../core/binpreds/feature_overlaps.py | 4 +- .../core/binpreds/feature_touches.py | 4 +- .../cuspatial/core/binpreds/feature_within.py | 112 ++--- python/cuspatial/cuspatial/core/geoseries.py | 153 +++++- .../cuspatial/tests/binpreds/test_contains.py | 93 ++++ .../tests/binpreds/test_contains_properly.py | 55 +-- .../tests/binpreds/test_pip_only_binpreds.py | 201 +++----- .../cuspatial/utils/binpred_utils.py | 326 +++++++++++++ 17 files changed, 1444 insertions(+), 657 deletions(-) create mode 100644 python/cuspatial/cuspatial/core/binpreds/basic_predicates.py create mode 100644 python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py create mode 100644 python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py create mode 100644 python/cuspatial/cuspatial/tests/binpreds/test_contains.py diff --git a/python/cuspatial/cuspatial/core/binops/equals_count.py b/python/cuspatial/cuspatial/core/binops/equals_count.py index 80f63027e..83cd97b9e 100644 --- a/python/cuspatial/cuspatial/core/binops/equals_count.py +++ b/python/cuspatial/cuspatial/core/binops/equals_count.py @@ -5,11 +5,10 @@ from cuspatial._lib.pairwise_multipoint_equals_count import ( pairwise_multipoint_equals_count as c_pairwise_multipoint_equals_count, ) -from cuspatial.core.geoseries import GeoSeries from cuspatial.utils.column_utils import contains_only_multipoints -def pairwise_multipoint_equals_count(lhs: GeoSeries, rhs: GeoSeries): +def pairwise_multipoint_equals_count(lhs, rhs): """Compute the number of points in each multipoint in the lhs that exist in the corresponding multipoint in the rhs. diff --git a/python/cuspatial/cuspatial/core/binpreds/basic_predicates.py b/python/cuspatial/cuspatial/core/binpreds/basic_predicates.py new file mode 100644 index 000000000..399eed58c --- /dev/null +++ b/python/cuspatial/cuspatial/core/binpreds/basic_predicates.py @@ -0,0 +1,107 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +import cudf + +from cuspatial.core.binops.equals_count import pairwise_multipoint_equals_count +from cuspatial.utils.binpred_utils import ( + _linestrings_from_geometry, + _multipoints_from_geometry, + _multipoints_is_degenerate, + _points_and_lines_to_multipoints, + _zero_series, +) + + +def _basic_equals(lhs, rhs): + """Utility method that returns True if any point in the lhs geometry + is equal to a point in the rhs geometry.""" + lhs = _multipoints_from_geometry(lhs) + rhs = _multipoints_from_geometry(rhs) + result = pairwise_multipoint_equals_count(lhs, rhs) + return result > 0 + + +def _basic_equals_all(lhs, rhs): + """Utility method that returns True if all points in the lhs geometry + are equal to points in the rhs geometry.""" + lhs = _multipoints_from_geometry(lhs) + rhs = _multipoints_from_geometry(rhs) + result = pairwise_multipoint_equals_count(lhs, rhs) + sizes = ( + lhs.multipoints.geometry_offset[1:] + - lhs.multipoints.geometry_offset[:-1] + ) + return result == sizes + + +def _basic_equals_count(lhs, rhs): + """Utility method that returns the number of points in the lhs geometry + that are equal to a point in the rhs geometry.""" + lhs = _multipoints_from_geometry(lhs) + rhs = _multipoints_from_geometry(rhs) + result = pairwise_multipoint_equals_count(lhs, rhs) + return result + + +def _basic_intersects_pli(lhs, rhs): + """Utility method that returns the original results of + `pairwise_linestring_intersection` (pli).""" + from cuspatial.core.binops.intersection import ( + pairwise_linestring_intersection, + ) + + lhs = _linestrings_from_geometry(lhs) + rhs = _linestrings_from_geometry(rhs) + return pairwise_linestring_intersection(lhs, rhs) + + +def _basic_intersects_count(lhs, rhs): + """Utility method that returns the number of points in the lhs geometry + that intersect with the rhs geometry.""" + pli = _basic_intersects_pli(lhs, rhs) + if len(pli[1]) == 0: + return _zero_series(len(rhs)) + intersections = _points_and_lines_to_multipoints(pli[1], pli[0]) + sizes = cudf.Series(intersections.sizes) + # If the result is degenerate + is_degenerate = _multipoints_is_degenerate(intersections) + # If all the points in the intersection are in the rhs + if len(is_degenerate) > 0: + sizes[is_degenerate] = 1 + return sizes + + +def _basic_intersects(lhs, rhs): + """Utility method that returns True if any point in the lhs geometry + intersects with the rhs geometry.""" + is_sizes = _basic_intersects_count(lhs, rhs) + return is_sizes > 0 + + +def _basic_contains_count(lhs, rhs): + """Utility method that returns the number of points in the lhs geometry + that are contained_properly in the rhs geometry. + """ + lhs = lhs + rhs = _multipoints_from_geometry(rhs) + contains = lhs.contains_properly(rhs, mode="basic_count") + return contains + + +def _basic_contains_any(lhs, rhs): + """Utility method that returns True if any point in the lhs geometry + is contained_properly in the rhs geometry.""" + lhs = lhs + rhs = _multipoints_from_geometry(rhs) + contains = lhs.contains_properly(rhs, mode="basic_any") + intersects = _basic_intersects(lhs, rhs) + return contains | intersects + + +def _basic_contains_properly_any(lhs, rhs): + """Utility method that returns True if any point in the lhs geometry + is contained_properly in the rhs geometry.""" + lhs = lhs + rhs = _multipoints_from_geometry(rhs) + contains = lhs.contains_properly(rhs, mode="basic_any") + return contains diff --git a/python/cuspatial/cuspatial/core/binpreds/binpred_dispatch.py b/python/cuspatial/cuspatial/core/binpreds/binpred_dispatch.py index f1cd0c51a..474841904 100644 --- a/python/cuspatial/cuspatial/core/binpreds/binpred_dispatch.py +++ b/python/cuspatial/cuspatial/core/binpreds/binpred_dispatch.py @@ -11,6 +11,9 @@ from cuspatial.core.binpreds.feature_contains import ( # NOQA F401 DispatchDict as CONTAINS_DISPATCH, ) +from cuspatial.core.binpreds.feature_contains_properly import ( # NOQA F401 + DispatchDict as CONTAINS_PROPERLY_DISPATCH, +) from cuspatial.core.binpreds.feature_covers import ( # NOQA F401 DispatchDict as COVERS_DISPATCH, ) diff --git a/python/cuspatial/cuspatial/core/binpreds/binpred_interface.py b/python/cuspatial/cuspatial/core/binpreds/binpred_interface.py index f380c425a..d9a7c3837 100644 --- a/python/cuspatial/cuspatial/core/binpreds/binpred_interface.py +++ b/python/cuspatial/cuspatial/core/binpreds/binpred_interface.py @@ -22,13 +22,18 @@ class BinPredConfig: Whether to compute the binary predicate between all pairs of features in the left-hand and right-hand GeoSeries. Defaults to False. Only available with the contains predicate. + mode: str + The mode to use when computing the binary predicate. Defaults to + "full". Only available with the contains predicate and used + for internal operations. """ def __init__(self, **kwargs): self.align = kwargs.get("align", True) + self.kwargs = kwargs def __repr__(self): - return f"BinpredConfig(align={self.align}, allpairs={self.allpairs})" + return f"BinPredConfig(align={self.align}, kwargs={self.kwargs})" def __str__(self): return self.__repr__() @@ -68,7 +73,7 @@ def __init__( def __repr__(self): return f"PreprocessorResult(lhs={self.lhs}, rhs={self.rhs}, \ - points={self.points}, point_indices={self.point_indices})" + points={self.final_rhs}, point_indices={self.point_indices})" def __str__(self): return self.__repr__() @@ -85,31 +90,31 @@ class ContainsOpResult(OpResult): Parameters ---------- - result : cudf.DataFrame + pip_result : cudf.DataFrame A cudf.DataFrame containing two columns: "polygon_index" and Point_index". The "polygon_index" column contains the index of the polygon that contains each point. The "point_index" column contains the index of each point that is contained by a polygon. - points : GeoSeries - A GeoSeries of points. - point_indices : cudf.Series - A cudf.Series of indices that map each point in `points` to its - corresponding feature in the right-hand GeoSeries. + intersection_result: Tuple (optional) + A tuple containing the result of the intersection operation + between the left-hand GeoSeries and the right-hand GeoSeries. + Used in .contains_properly. """ def __init__( self, - result: Series, - points: "GeoSeries" = None, - point_indices: Series = None, + pip_result: Series, + preprocessor_result: PreprocessorResult, + intersection_result: Tuple = None, ): - self.result = result - self.points = points - self.point_indices = point_indices + self.pip_result = pip_result + self.preprocessor_result = preprocessor_result + self.intersection_result = intersection_result def __repr__(self): - return f"OpResult(result={self.result}, points={self.points}, \ - point_indices={self.point_indices})" + return f"OpResult(pip_result={self.pip_result},\n \ + preprocessor_result={self.preprocessor_result},\n \ + intersection_result={self.intersection_result})\n" def __str__(self): return self.__repr__() diff --git a/python/cuspatial/cuspatial/core/binpreds/contains.py b/python/cuspatial/cuspatial/core/binpreds/contains.py index 51ced0031..398f134ff 100644 --- a/python/cuspatial/cuspatial/core/binpreds/contains.py +++ b/python/cuspatial/cuspatial/core/binpreds/contains.py @@ -69,7 +69,7 @@ def _quadtree_contains_properly(points, polygons): return polygons_and_points -def _byte_limited_contains_properly(points, polygons): +def _brute_force_contains_properly(points, polygons): """Compute from a series of points and a series of polygons which points are properly contained within the corresponding polygon. Polygon A contains Point B properly if B intersects the interior of A but not the boundary (or @@ -115,14 +115,14 @@ def _byte_limited_contains_properly(points, polygons): return final_result -def contains_properly(polygons, points, how="quadtree"): - if "quadtree" == how: +def contains_properly(polygons, points, quadtree=True): + if quadtree: return _quadtree_contains_properly(points, polygons) - elif "byte-limited" == how: + else: # Use stack to convert the result to the same shape as quadtree's # result, name the columns appropriately, and return the # two-column DataFrame. - bitmask_result = _byte_limited_contains_properly(points, polygons) + bitmask_result = _brute_force_contains_properly(points, polygons) quadtree_shaped_result = bitmask_result.stack().reset_index() quadtree_shaped_result.columns = [ "point_index", @@ -136,7 +136,3 @@ def contains_properly(polygons, points, how="quadtree"): drop=True ) return result - else: - raise NotImplementedError( - "contains_properly only supports 'quadtree' and 'byte_limited'" - ) diff --git a/python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py b/python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py new file mode 100644 index 000000000..12b2fc37d --- /dev/null +++ b/python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py @@ -0,0 +1,274 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +import cupy as cp + +import cudf +from cudf.core.dataframe import DataFrame +from cudf.core.series import Series + +from cuspatial.core._column.geocolumn import GeoColumn +from cuspatial.core.binpreds.binpred_interface import ( + BinPred, + PreprocessorResult, +) +from cuspatial.utils.binpred_utils import ( + _count_results_in_multipoint_geometries, + _false_series, + _true_series, +) +from cuspatial.utils.column_utils import ( + contains_only_linestrings, + contains_only_multipoints, + contains_only_polygons, +) + + +class ContainsGeometryProcessor(BinPred): + def _preprocess_multipoint_rhs(self, lhs, rhs): + """Flatten any rhs into only its points xy array. This is necessary + because the basic predicate for contains, point-in-polygon, + only accepts points. + + Parameters + ---------- + lhs : GeoSeries + The left-hand GeoSeries. + rhs : GeoSeries + The right-hand GeoSeries. + + Returns + ------- + result : PreprocessorResult + A PreprocessorResult object containing the original lhs and rhs, + the rhs with only its points, and the indices of the points in + the original rhs. + """ + # RHS conditioning: + point_indices = None + # point in polygon + if contains_only_linestrings(rhs): + # condition for linestrings + geom = rhs.lines + elif contains_only_polygons(rhs) is True: + # polygon in polygon + geom = rhs.polygons + elif contains_only_multipoints(rhs) is True: + # mpoint in polygon + geom = rhs.multipoints + else: + # no conditioning is required + geom = rhs.points + xy_points = geom.xy + + # Arrange into shape for calling point-in-polygon + point_indices = geom.point_indices() + from cuspatial.core.geoseries import GeoSeries + + final_rhs = GeoSeries(GeoColumn._from_points_xy(xy_points._column)) + preprocess_result = PreprocessorResult( + lhs, rhs, final_rhs, point_indices + ) + return preprocess_result + + def _convert_quadtree_result_from_part_to_polygon_indices( + self, lhs, point_result + ): + """Convert the result of a quadtree contains_properly call from + part indices to polygon indices. + + Parameters + ---------- + point_result : cudf.Series + The result of a quadtree contains_properly call. This result + contains the `part_index` of the polygon that contains the + point, not the polygon index. + + Returns + ------- + cudf.Series + The result of a quadtree contains_properly call. This result + contains the `polygon_index` of the polygon that contains the + point, not the part index. + """ + # Get the length of each part, map it to indices, and store + # the result in a dataframe. + rings_to_parts = cp.array(lhs.polygons.part_offset) + part_sizes = rings_to_parts[1:] - rings_to_parts[:-1] + parts_map = cudf.Series( + cp.arange(len(part_sizes)), name="part_index" + ).repeat(part_sizes) + parts_index_mapping_df = parts_map.reset_index(drop=True).reset_index() + # Map the length of each polygon in a similar fashion, then + # join them below. + parts_to_geoms = cp.array(lhs.polygons.geometry_offset) + geometry_sizes = parts_to_geoms[1:] - parts_to_geoms[:-1] + geometry_map = cudf.Series( + cp.arange(len(geometry_sizes)), name="polygon_index" + ).repeat(geometry_sizes) + geom_index_mapping_df = geometry_map.reset_index(drop=True) + geom_index_mapping_df.index.name = "part_index" + geom_index_mapping_df = geom_index_mapping_df.reset_index() + # Replace the part index with the polygon index by join + part_result = parts_index_mapping_df.merge( + point_result, on="part_index" + ) + # Replace the polygon index with the row index by join + return geom_index_mapping_df.merge(part_result, on="part_index")[ + ["polygon_index", "point_index"] + ] + + def _reindex_allpairs(self, lhs, op_result) -> DataFrame: + """Prepare the allpairs result of a contains_properly call as + the first step of postprocessing. An allpairs result is reindexed + by replacing the polygon index with the original index of the + polygon from the lhs. + + Parameters + ---------- + lhs : GeoSeries + The left-hand side of the binary predicate. + op_result : ContainsProperlyOpResult + The result of the contains_properly call. + + Returns + ------- + cudf.DataFrame + A cudf.DataFrame with two columns: `polygon_index` and + `point_index`. The `polygon_index` column contains the index + of the polygon from the original lhs that contains the point, + and the `point_index` column contains the index of the point + from the preprocessor final_rhs input to point-in-polygon. + """ + # Convert the quadtree part indices df into a polygon indices df + polygon_indices = ( + self._convert_quadtree_result_from_part_to_polygon_indices( + lhs, op_result.pip_result + ) + ) + # Because the quadtree contains_properly call returns a list of + # points that are contained in each part, parts can be duplicated + # once their index is converted to a polygon index. + allpairs_result = polygon_indices.drop_duplicates() + + # Replace the polygon index with the original index + allpairs_result["polygon_index"] = allpairs_result[ + "polygon_index" + ].replace(Series(lhs.index, index=cp.arange(len(lhs.index)))) + + return allpairs_result + + def _postprocess_multipoint_rhs( + self, lhs, rhs, preprocessor_result, op_result, mode + ): + """Reconstruct the original geometry from the result of the + contains_properly call. + + Parameters + ---------- + lhs : GeoSeries + The left-hand side of the binary predicate. + rhs : GeoSeries + The right-hand side of the binary predicate. + preprocessor_result : PreprocessorResult + The result of the preprocessor. + op_result : ContainsProperlyOpResult + The result of the contains_properly call. + mode : str + The mode of the predicate. Various mode options are available + to support binary predicates. The mode options are `full`, + `basic_none`, `basic_any`, and `basic_count`. If the default + option `full` is specified, `.contains` or .contains_properly` + will return a boolean series indicating whether each feature + in the right-hand GeoSeries is contained by the corresponding + feature in the left-hand GeoSeries. If `basic_none` is + specified, `.contains` or .contains_properly` returns the + negation of `basic_any`.`. If `basic_any` is specified, `.contains` + or `.contains_properly` returns a boolean series indicating + whether any point in the right-hand GeoSeries is contained by + the corresponding feature in the left-hand GeoSeries. If the + `basic_count` option is specified, `.contains` or + .contains_properly` returns a Series of integers indicating + the number of points in the right-hand GeoSeries that are + contained by the corresponding feature in the left-hand GeoSeries. + + Returns + ------- + cudf.Series + A boolean series indicating whether each feature in the + right-hand GeoSeries satisfies the requirements of the point- + in-polygon basic predicate with its corresponding feature in the + left-hand GeoSeries.""" + + point_indices = preprocessor_result.point_indices + allpairs_result = self._reindex_allpairs(lhs, op_result) + if isinstance(allpairs_result, Series): + return allpairs_result + # Hits is the number of calculated points in each polygon + # Expected count is the sizes of the features in the right-hand + # GeoSeries + (hits, expected_count,) = _count_results_in_multipoint_geometries( + point_indices, allpairs_result + ) + result_df = hits.reset_index().merge( + expected_count.reset_index(), on="rhs_index" + ) + + # Handling for the basic predicates + if mode == "basic_none": + none_result = _true_series(len(rhs)) + if len(result_df) == 0: + return none_result + none_result.loc[result_df["point_index_x"] > 0] = False + return none_result + elif mode == "basic_any": + any_result = _false_series(len(rhs)) + if len(result_df) == 0: + return any_result + indexes = result_df["rhs_index"][result_df["point_index_x"] > 0] + any_result.iloc[indexes] = True + return any_result + elif mode == "basic_count": + count_result = cudf.Series(cp.zeros(len(rhs)), dtype="int32") + if len(result_df) == 0: + return count_result + hits = result_df["point_index_x"] + hits.index = count_result.iloc[result_df["rhs_index"]].index + count_result.iloc[result_df["rhs_index"]] = hits + return count_result + + # Handling for full contains (equivalent to basic predicate all) + # for each input pair i: result[i] =  true iff point[i] is + # contained in at least one polygon of multipolygon[i]. + result_df["feature_in_polygon"] = ( + result_df["point_index_x"] >= result_df["point_index_y"] + ) + final_result = _false_series(len(rhs)) + final_result.loc[ + result_df["rhs_index"][result_df["feature_in_polygon"]] + ] = True + return final_result + + def _postprocess_points(self, lhs, rhs, preprocessor_result, op_result): + """Used when the rhs is naturally points. Instead of reconstructing + the original geometry, this method applies the `point_index` results + to the original rhs points and returns a boolean series reflecting + which `point_index`es were found. + """ + allpairs_result = self._reindex_allpairs(lhs, op_result) + if self.config.allpairs: + return allpairs_result + + final_result = _false_series(len(rhs)) + if len(lhs) == len(rhs): + matches = ( + allpairs_result["polygon_index"] + == allpairs_result["point_index"] + ) + polygon_indexes = allpairs_result["polygon_index"][matches] + final_result.loc[ + preprocessor_result.point_indices[polygon_indexes] + ] = True + return final_result + else: + final_result.loc[allpairs_result["polygon_index"]] = True + return final_result diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_contains.py b/python/cuspatial/cuspatial/core/binpreds/feature_contains.py index c5852698b..d576930bf 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_contains.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_contains.py @@ -1,376 +1,170 @@ # Copyright (c) 2023, NVIDIA CORPORATION. -from typing import Generic, TypeVar, Union - -import cupy as cp +from typing import TypeVar import cudf -from cudf.core.dataframe import DataFrame -from cudf.core.series import Series -from cuspatial.core._column.geocolumn import GeoColumn +from cuspatial.core.binpreds.basic_predicates import ( + _basic_contains_count, + _basic_equals, + _basic_equals_count, + _basic_intersects, + _basic_intersects_pli, +) from cuspatial.core.binpreds.binpred_interface import ( BinPred, - ContainsOpResult, + ImpossiblePredicate, NotImplementedPredicate, - PreprocessorResult, ) -from cuspatial.core.binpreds.contains import contains_properly +from cuspatial.core.binpreds.contains_geometry_processor import ( + ContainsGeometryProcessor, +) from cuspatial.utils.binpred_utils import ( LineString, MultiPoint, Point, Polygon, - _count_results_in_multipoint_geometries, _false_series, + _linestrings_to_center_point, + _open_polygon_rings, + _points_and_lines_to_multipoints, + _zero_series, ) from cuspatial.utils.column_utils import ( contains_only_linestrings, - contains_only_multipoints, + contains_only_points, contains_only_polygons, - has_multipolygons, ) GeoSeries = TypeVar("GeoSeries") -class ContainsPredicateBase(BinPred, Generic[GeoSeries]): - """Base class for binary predicates that are defined in terms of a - `contains` basic predicate. This class implements the logic that underlies - `polygon.contains` primarily, and is implemented for many cases. - - Subclasses are selected using the `DispatchDict` located at the end - of this file. - """ - +class ContainsPredicate(ContainsGeometryProcessor): def __init__(self, **kwargs): - """`ContainsPredicateBase` constructor. - - Parameters - ---------- - allpairs: bool - Whether to compute all pairs of features in the left-hand and - right-hand GeoSeries. If False, the feature will be compared in a - 1:1 fashion with the corresponding feature in the other GeoSeries. - """ super().__init__(**kwargs) self.config.allpairs = kwargs.get("allpairs", False) + self.config.mode = kwargs.get("mode", "full") def _preprocess(self, lhs, rhs): - """Flatten any rhs into only its points xy array. This is necessary - because the basic predicate for contains, point-in-polygon, - only accepts points. + preprocessor_result = super()._preprocess_multipoint_rhs(lhs, rhs) + return self._compute_predicate(lhs, rhs, preprocessor_result) - Parameters - ---------- - lhs : GeoSeries - The left-hand GeoSeries. - rhs : GeoSeries - The right-hand GeoSeries. + def _intersection_results_for_contains(self, lhs, rhs): + pli = _basic_intersects_pli(lhs, rhs) + pli_features = pli[1] + if len(pli_features) == 0: + return _zero_series(len(lhs)) - Returns - ------- - result : GeoSeries - A GeoSeries of boolean values indicating whether each feature in - the right-hand GeoSeries satisfies the requirements of the point- - in-polygon basic predicate with its corresponding feature in the - left-hand GeoSeries. - """ - # RHS conditioning: - point_indices = None - # point in polygon - if contains_only_linestrings(rhs): - # condition for linestrings - geom = rhs.lines - elif contains_only_polygons(rhs) is True: - # polygon in polygon - geom = rhs.polygons - elif contains_only_multipoints(rhs) is True: - # mpoint in polygon - geom = rhs.multipoints - else: - # no conditioning is required - geom = rhs.points - xy_points = geom.xy + pli_offsets = cudf.Series(pli[0]) - # Arrange into shape for calling point-in-polygon, intersection, or - # equals - point_indices = geom.point_indices() - from cuspatial.core.geoseries import GeoSeries - - final_rhs = GeoSeries(GeoColumn._from_points_xy(xy_points._column)) - preprocess_result = PreprocessorResult( - lhs, rhs, final_rhs, point_indices + # Convert the pli to multipoints for equality checking + multipoints = _points_and_lines_to_multipoints( + pli_features, pli_offsets ) - return self._compute_predicate(lhs, rhs, preprocess_result) - - def _should_use_quadtree(self, lhs): - """Determine if the quadtree should be used for the binary predicate. - - Returns - ------- - bool - True if the quadtree should be used, False otherwise. - Notes - ----- - 1. Quadtree is always used if user requests `allpairs=True`. - 2. If the number of polygons in the lhs is less than 32, we use the - byte-limited algorithm because it is faster and has less memory - overhead. - 3. If the lhs contains more than 32 polygons, we use the quadtree - because it does not have a polygon-count limit. - 4. If the lhs contains multipolygons, we use quadtree because the - performance between quadtree and byte-limited is similar, but - code complexity would be higher if we did multipolygon - reconstruction on both code paths. - """ - return len(lhs) >= 32 or has_multipolygons(lhs) or self.config.allpairs - - def _compute_predicate( - self, - lhs: "GeoSeries", - rhs: "GeoSeries", - preprocessor_result: PreprocessorResult, + # A point in the rhs can be one of three possible states: + # 1. It is in the interior of the lhs + # 2. It is in the exterior of the lhs + # 3. It is on the boundary of the lhs + # This function tests if the point in the rhs is in the boundary + # of the lhs + intersect_equals_count = _basic_equals_count(rhs, multipoints) + return intersect_equals_count + + def _compute_polygon_polygon_contains(self, lhs, rhs, preprocessor_result): + lines_rhs = _open_polygon_rings(rhs) + contains = _basic_contains_count(lhs, lines_rhs).reset_index(drop=True) + intersects = self._intersection_results_for_contains(lhs, lines_rhs) + # A closed polygon has an extra line segment that is not used in + # counting the number of points. We need to subtract this from the + # number of points in the polygon. + polygon_size_reduction = rhs.polygons.part_offset.take( + rhs.polygons.geometry_offset[1:] + ) - rhs.polygons.part_offset.take(rhs.polygons.geometry_offset[:-1]) + return contains + intersects >= rhs.sizes - polygon_size_reduction + + def _compute_polygon_linestring_contains( + self, lhs, rhs, preprocessor_result ): - """Compute the contains_properly relationship between two GeoSeries. - A feature A contains another feature B if no points of B lie in the - exterior of A, and at least one point of the interior of B lies in the - interior of A. This is the inverse of `within`.""" - if not contains_only_polygons(lhs): - raise TypeError( - "`.contains` can only be called with polygon series." + contains = _basic_contains_count(lhs, rhs).reset_index(drop=True) + intersects = self._intersection_results_for_contains(lhs, rhs) + if (contains == 0).all() and (intersects != 0).all(): + # The hardest case. We need to check if the linestring is + # contained in the boundary of the polygon, the interior, + # or the exterior. + # We only need to test linestrings that are length 2. + # Divide the linestring in half and test the point for containment + # in the polygon. + + if (rhs.sizes == 2).any(): + center_points = _linestrings_to_center_point( + rhs[rhs.sizes == 2] + ) + size_two_results = _false_series(len(lhs)) + size_two_results[rhs.sizes == 2] = ( + _basic_contains_count(lhs, center_points) > 0 + ) + return size_two_results + else: + line_intersections = _false_series(len(lhs)) + line_intersections[intersects == rhs.sizes] = True + return line_intersections + return contains + intersects >= rhs.sizes + + def _compute_predicate(self, lhs, rhs, preprocessor_result): + if contains_only_points(rhs): + # Special case in GeoPandas, points are not contained + # in the boundary of a polygon, so only return true if + # the points are contained_properly. + contains = _basic_contains_count(lhs, rhs).reset_index(drop=True) + return contains > 0 + elif contains_only_linestrings(rhs): + return self._compute_polygon_linestring_contains( + lhs, rhs, preprocessor_result ) - points = preprocessor_result.final_rhs - point_indices = preprocessor_result.point_indices - if self._should_use_quadtree(lhs): - result = contains_properly(lhs, points, how="quadtree") - else: - result = contains_properly(lhs, points, how="byte-limited") - op_result = ContainsOpResult(result, points, point_indices) - return self._postprocess(lhs, rhs, op_result) - - def _convert_quadtree_result_from_part_to_polygon_indices( - self, lhs, point_result - ): - """Convert the result of a quadtree contains_properly call from - part indices to polygon indices. - - Parameters - ---------- - point_result : cudf.Series - The result of a quadtree contains_properly call. This result - contains the `part_index` of the polygon that contains the - point, not the polygon index. - - Returns - ------- - cudf.Series - The result of a quadtree contains_properly call. This result - contains the `polygon_index` of the polygon that contains the - point, not the part index. - """ - # Get the length of each part, map it to indices, and store - # the result in a dataframe. - rings_to_parts = cp.array(lhs.polygons.part_offset) - part_sizes = rings_to_parts[1:] - rings_to_parts[:-1] - parts_map = cudf.Series( - cp.arange(len(part_sizes)), name="part_index" - ).repeat(part_sizes) - parts_index_mapping_df = parts_map.reset_index(drop=True).reset_index() - # Map the length of each polygon in a similar fashion, then - # join them below. - parts_to_geoms = cp.array(lhs.polygons.geometry_offset) - geometry_sizes = parts_to_geoms[1:] - parts_to_geoms[:-1] - geometry_map = cudf.Series( - cp.arange(len(geometry_sizes)), name="polygon_index" - ).repeat(geometry_sizes) - geom_index_mapping_df = geometry_map.reset_index(drop=True) - geom_index_mapping_df.index.name = "part_index" - geom_index_mapping_df = geom_index_mapping_df.reset_index() - # Replace the part index with the polygon index by join - part_result = parts_index_mapping_df.merge( - point_result, on="part_index" - ) - # Replace the polygon index with the row index by join - return geom_index_mapping_df.merge(part_result, on="part_index")[ - ["polygon_index", "point_index"] - ] - - def _reindex_allpairs(self, lhs, op_result) -> Union[Series, DataFrame]: - """Prepare the allpairs result of a contains_properly call as - the first step of postprocessing. - - Parameters - ---------- - lhs : GeoSeries - The left-hand side of the binary predicate. - op_result : ContainsOpResult - The result of the contains_properly call. - - Returns - ------- - cudf.DataFrame - - """ - # Convert the quadtree part indices df into a polygon indices df - polygon_indices = ( - self._convert_quadtree_result_from_part_to_polygon_indices( - lhs, op_result.result + elif contains_only_polygons(rhs): + return self._compute_polygon_polygon_contains( + lhs, rhs, preprocessor_result ) - ) - # Because the quadtree contains_properly call returns a list of - # points that are contained in each part, parts can be duplicated - # once their index is converted to a polygon index. - allpairs_result = polygon_indices.drop_duplicates() - - # Replace the polygon index with the original index - allpairs_result["polygon_index"] = allpairs_result[ - "polygon_index" - ].replace(Series(lhs.index, index=cp.arange(len(lhs.index)))) - - return allpairs_result - - def _postprocess(self, lhs, rhs, op_result): - """Postprocess the output GeoSeries to ensure that they are of the - correct type for the predicate. - - Postprocess for contains_properly has to handle multiple input and - output configurations. - - The input can be a single polygon, a single multipolygon, or a - GeoSeries containing a mix of polygons and multipolygons. - - The input to postprocess is `point_indices`, which can be either a - cudf.DataFrame with one row per point and one column per polygon or - a cudf.DataFrame containing the point index and the part index for - each point in the polygon. - - Parameters - ---------- - lhs : GeoSeries - The left-hand side of the binary predicate. - rhs : GeoSeries - The right-hand side of the binary predicate. - preprocessor_output : ContainsOpResult - The result of the contains_properly call. - - Returns - ------- - cudf.Series or cudf.DataFrame - A Series of boolean values indicating whether each feature in - the rhs GeoSeries is contained in the lhs GeoSeries in the - case of allpairs=False. Otherwise, a DataFrame containing the - point index and the polygon index for each point in the - polygon. - """ - if len(op_result.result) == 0: - return _false_series(len(lhs)) - - # Convert the quadtree part indices df into a polygon indices df. - # Helps with handling multipolygons. - allpairs_result = self._reindex_allpairs(lhs, op_result) - - # If the user wants all pairs, return the result. Otherwise, - # return a boolean series indicating whether each point is - # contained in the corresponding polygon. - if self.config.allpairs: - return allpairs_result else: - # for each input pair i: result[i] =  true iff point[i] is - # contained in at least one polygon of multipolygon[i]. - # pairwise - final_result = _false_series(len(rhs)) - if len(lhs) == len(rhs): - matches = ( - allpairs_result["polygon_index"] - == allpairs_result["point_index"] - ) - polygon_indexes = allpairs_result["polygon_index"][matches] - final_result.loc[ - op_result.point_indices[polygon_indexes] - ] = True - return final_result - else: - final_result.loc[allpairs_result["polygon_index"]] = True - return final_result + raise NotImplementedError("Invalid rhs for contains operation") -class PolygonComplexContains(ContainsPredicateBase): - """Base class for contains operations that use a complex object on - the right hand side. - - This class is shared by the Polygon*Contains classes that use - a non-points object on the right hand side: MultiPoint, LineString, - MultiLineString, Polygon, and MultiPolygon. - - Used by: - (Polygon, MultiPoint) - (Polygon, LineString) - (Polygon, Polygon) - """ - - def _postprocess(self, lhs, rhs, preprocessor_output): - # for each input pair i: result[i] =  true iff point[i] is - # contained in at least one polygon of multipolygon[i]. - # pairwise - point_indices = preprocessor_output.point_indices - allpairs_result = self._reindex_allpairs(lhs, preprocessor_output) - if isinstance(allpairs_result, Series): - return allpairs_result - - (hits, expected_count,) = _count_results_in_multipoint_geometries( - point_indices, allpairs_result - ) - result_df = hits.reset_index().merge( - expected_count.reset_index(), on="rhs_index" - ) - result_df["feature_in_polygon"] = ( - result_df["point_index_x"] >= result_df["point_index_y"] - ) - final_result = _false_series(len(rhs)) - final_result.loc[ - result_df["rhs_index"][result_df["feature_in_polygon"]] - ] = True - return final_result +class PointPointContains(BinPred): + def _preprocess(self, lhs, rhs): + return _basic_equals(lhs, rhs) -class ContainsByIntersection(BinPred): - """Point types are contained only by an intersection test. +class LineStringPointContains(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(lhs, rhs) + equals = _basic_equals(lhs, rhs) + return intersects & ~equals - Used by: - (Point, Point) - (LineString, Point) - """ +class LineStringLineStringContainsPredicate(BinPred): def _preprocess(self, lhs, rhs): - from cuspatial.core.binpreds.binpred_dispatch import ( - INTERSECTS_DISPATCH, - ) - - predicate = INTERSECTS_DISPATCH[(lhs.column_type, rhs.column_type)]( - align=self.config.align - ) - return predicate(lhs, rhs) + count = _basic_equals_count(lhs, rhs) + return count == rhs.sizes """DispatchDict listing the classes to use for each combination of left and right hand side types. """ DispatchDict = { - (Point, Point): ContainsByIntersection, - (Point, MultiPoint): NotImplementedPredicate, - (Point, LineString): NotImplementedPredicate, - (Point, Polygon): NotImplementedPredicate, + (Point, Point): PointPointContains, + (Point, MultiPoint): ImpossiblePredicate, + (Point, LineString): ImpossiblePredicate, + (Point, Polygon): ImpossiblePredicate, (MultiPoint, Point): NotImplementedPredicate, (MultiPoint, MultiPoint): NotImplementedPredicate, (MultiPoint, LineString): NotImplementedPredicate, (MultiPoint, Polygon): NotImplementedPredicate, - (LineString, Point): ContainsByIntersection, + (LineString, Point): LineStringPointContains, (LineString, MultiPoint): NotImplementedPredicate, - (LineString, LineString): NotImplementedPredicate, - (LineString, Polygon): NotImplementedPredicate, - (Polygon, Point): ContainsPredicateBase, - (Polygon, MultiPoint): PolygonComplexContains, - (Polygon, LineString): PolygonComplexContains, - (Polygon, Polygon): PolygonComplexContains, + (LineString, LineString): LineStringLineStringContainsPredicate, + (LineString, Polygon): ImpossiblePredicate, + (Polygon, Point): ContainsPredicate, + (Polygon, MultiPoint): ContainsPredicate, + (Polygon, LineString): ContainsPredicate, + (Polygon, Polygon): ContainsPredicate, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py b/python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py new file mode 100644 index 000000000..0c81ead59 --- /dev/null +++ b/python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py @@ -0,0 +1,186 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +from typing import TypeVar + +from cuspatial.core.binpreds.basic_predicates import ( + _basic_equals_all, + _basic_intersects, +) +from cuspatial.core.binpreds.binpred_interface import ( + BinPred, + ContainsOpResult, + ImpossiblePredicate, + NotImplementedPredicate, + PreprocessorResult, +) +from cuspatial.core.binpreds.contains import contains_properly +from cuspatial.core.binpreds.contains_geometry_processor import ( + ContainsGeometryProcessor, +) +from cuspatial.utils.binpred_utils import ( + LineString, + MultiPoint, + Point, + Polygon, + _is_complex, +) +from cuspatial.utils.column_utils import ( + contains_only_polygons, + has_multipolygons, +) + +GeoSeries = TypeVar("GeoSeries") + + +class ContainsProperlyPredicate(ContainsGeometryProcessor): + def __init__(self, **kwargs): + """Base class for binary predicates that are defined in terms of + `contains_properly`. + + Subclasses are selected using the `DispatchDict` located at the end + of this file. + + Parameters + ---------- + allpairs: bool + Whether to compute all pairs of features in the left-hand and + right-hand GeoSeries. If False, the feature will be compared in a + 1:1 fashion with the corresponding feature in the other GeoSeries. + mode: str + The mode to use for computing the predicate. The default is + "full", which computes true or false if the `.contains_properly` + predicate is satisfied. Other options include "basic_none", + "basic_any", "basic_all", and "basic_count". + """ + super().__init__(**kwargs) + self.config.allpairs = kwargs.get("allpairs", False) + self.config.mode = kwargs.get("mode", "full") + + def _preprocess(self, lhs, rhs): + preprocessor_result = super()._preprocess_multipoint_rhs(lhs, rhs) + return self._compute_predicate(lhs, rhs, preprocessor_result) + + def _should_use_quadtree(self, lhs): + """Determine if the quadtree should be used for the binary predicate. + + Returns + ------- + bool + True if the quadtree should be used, False otherwise. + + Notes + ----- + 1. Quadtree is always used if user requests `allpairs=True`. + 2. If the number of polygons in the lhs is less than 32, we use the + brute-force algorithm because it is faster and has less memory + overhead. + 3. If the lhs contains more than 32 polygons, we use the quadtree + because it does not have a polygon-count limit. + 4. If the lhs contains multipolygons, we use quadtree because the + performance between quadtree and brute-force is similar, but + code complexity would be higher if we did multipolygon + reconstruction on both code paths. + """ + return len(lhs) >= 32 or has_multipolygons(lhs) or self.config.allpairs + + def _compute_predicate( + self, + lhs: "GeoSeries", + rhs: "GeoSeries", + preprocessor_result: PreprocessorResult, + ): + """Compute the contains_properly relationship between two GeoSeries. + A feature A contains another feature B if no points of B lie in the + exterior of A, and at least one point of the interior of B lies in the + interior of A. This is the inverse of `within`.""" + if not contains_only_polygons(lhs): + raise TypeError( + "`.contains` can only be called with polygon series." + ) + use_quadtree = self._should_use_quadtree(lhs) + pip_result = contains_properly( + lhs, preprocessor_result.final_rhs, quadtree=use_quadtree + ) + op_result = ContainsOpResult(pip_result, preprocessor_result) + return self._postprocess(lhs, rhs, preprocessor_result, op_result) + + def _postprocess(self, lhs, rhs, preprocessor_result, op_result): + """Postprocess the output GeoSeries to ensure that they are of the + correct type for the predicate. + + Postprocess for contains_properly has to handle multiple input and + output configurations. + + + The input to postprocess is `point_indices`, which can be either a + cudf.DataFrame with one row per point and one column per polygon or + a cudf.DataFrame containing the point index and the part index for + each point in the polygon. + + Parameters + ---------- + lhs : GeoSeries + The left-hand side of the binary predicate. + rhs : GeoSeries + The right-hand side of the binary predicate. + preprocessor_output : ContainsOpResult + The result of the contains_properly call. + + Returns + ------- + cudf.Series or cudf.DataFrame + A Series of boolean values indicating whether each feature in + the rhs GeoSeries is contained in the lhs GeoSeries in the + case of allpairs=False. Otherwise, a DataFrame containing the + point index and the polygon index for each point in the + polygon. + """ + + if _is_complex(rhs): + return super()._postprocess_multipoint_rhs( + lhs, rhs, preprocessor_result, op_result, mode=self.config.mode + ) + else: + return super()._postprocess_points( + lhs, rhs, preprocessor_result, op_result + ) + + +class ContainsProperlyByIntersection(BinPred): + """Point types are contained only by an intersection test. + + Used by: + (Point, Point) + (LineString, Point) + """ + + def _preprocess(self, lhs, rhs): + return _basic_intersects(lhs, rhs) + + +class LineStringLineStringContainsProperly(BinPred): + def _preprocess(self, lhs, rhs): + count = _basic_equals_all(lhs, rhs) + return count + + +"""DispatchDict listing the classes to use for each combination of + left and right hand side types. """ +DispatchDict = { + (Point, Point): ContainsProperlyByIntersection, + (Point, MultiPoint): ImpossiblePredicate, + (Point, LineString): ImpossiblePredicate, + (Point, Polygon): ImpossiblePredicate, + (MultiPoint, Point): NotImplementedPredicate, + (MultiPoint, MultiPoint): NotImplementedPredicate, + (MultiPoint, LineString): NotImplementedPredicate, + (MultiPoint, Polygon): NotImplementedPredicate, + (LineString, Point): ContainsProperlyByIntersection, + (LineString, MultiPoint): ContainsProperlyPredicate, + (LineString, LineString): LineStringLineStringContainsProperly, + (LineString, Polygon): ImpossiblePredicate, + (Polygon, Point): ContainsProperlyPredicate, + (Polygon, MultiPoint): ContainsProperlyPredicate, + (Polygon, LineString): ContainsProperlyPredicate, + (Polygon, Polygon): ContainsProperlyPredicate, +} diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py b/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py index ecc3673f9..d8ecfdb38 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py @@ -5,15 +5,17 @@ import cudf -import cuspatial from cuspatial.core.binops.intersection import pairwise_linestring_intersection +from cuspatial.core.binpreds.basic_predicates import ( + _basic_contains_any, + _basic_intersects, +) from cuspatial.core.binpreds.binpred_interface import ( BinPred, IntersectsOpResult, NotImplementedPredicate, PreprocessorResult, ) -from cuspatial.core.binpreds.feature_contains import ContainsPredicateBase from cuspatial.core.binpreds.feature_equals import EqualsPredicateBase from cuspatial.utils.binpred_utils import ( LineString, @@ -21,6 +23,7 @@ Point, Polygon, _false_series, + _linestrings_from_geometry, ) @@ -74,18 +77,6 @@ def _get_intersecting_geometry_indices(self, lhs, op_result): ].reset_index(drop=True) return cp.arange(len(lhs))[is_sizes > 0] - def _linestrings_from_polygons(self, geoseries): - xy = geoseries.polygons.xy - parts = geoseries.polygons.part_offset.take( - geoseries.polygons.geometry_offset - ) - rings = geoseries.polygons.ring_offset - return cuspatial.GeoSeries.from_linestrings_xy( - xy, - rings, - parts, - ) - def _postprocess(self, lhs, rhs, op_result): """Postprocess the output GeoSeries to ensure that they are of the correct type for the predicate.""" @@ -100,36 +91,25 @@ class IntersectsByEquals(EqualsPredicateBase): pass -class PointPolygonIntersects(ContainsPredicateBase): +class PolygonPointIntersects(BinPred): def _preprocess(self, lhs, rhs): - """Swap LHS and RHS and call the normal contains processing.""" - self.lhs = rhs - self.rhs = lhs - return super()._preprocess(rhs, lhs) + contains = _basic_contains_any(lhs, rhs) + intersects = _basic_intersects(lhs, rhs) + return contains | intersects -class LineStringPointIntersects(IntersectsPredicateBase): +class PointPolygonIntersects(BinPred): def _preprocess(self, lhs, rhs): - """Convert rhs to linestrings by making a linestring that has - the same start and end point.""" - x = cp.repeat(rhs.points.x, 2) - y = cp.repeat(rhs.points.y, 2) - xy = cudf.DataFrame({"x": x, "y": y}).interleave_columns() - parts = cp.arange((len(lhs) + 1)) * 2 - geometries = cp.arange(len(lhs) + 1) - ls_rhs = cuspatial.GeoSeries.from_linestrings_xy(xy, parts, geometries) - return self._compute_predicate( - lhs, ls_rhs, PreprocessorResult(lhs, ls_rhs) - ) + contains = _basic_contains_any(rhs, lhs) + intersects = _basic_intersects(rhs, lhs) + return contains | intersects -class LineStringMultiPointIntersects(IntersectsPredicateBase): +class LineStringPointIntersects(IntersectsPredicateBase): def _preprocess(self, lhs, rhs): - """Convert rhs to linestrings.""" - xy = rhs.multipoints.xy - parts = rhs.multipoints.geometry_offset - geometries = cp.arange(len(lhs) + 1) - ls_rhs = cuspatial.GeoSeries.from_linestrings_xy(xy, parts, geometries) + """Convert rhs to linestrings by making a linestring that has + the same start and end point.""" + ls_rhs = _linestrings_from_geometry(rhs) return self._compute_predicate( lhs, ls_rhs, PreprocessorResult(lhs, ls_rhs) ) @@ -141,18 +121,27 @@ def _preprocess(self, lhs, rhs): return super()._preprocess(rhs, lhs) -class LineStringPointIntersects(IntersectsPredicateBase): +class LineStringPolygonIntersects(BinPred): def _preprocess(self, lhs, rhs): - """Convert rhs to linestrings.""" - x = cp.repeat(rhs.points.x, 2) - y = cp.repeat(rhs.points.y, 2) - xy = cudf.DataFrame({"x": x, "y": y}).interleave_columns() - parts = cp.arange((len(lhs) + 1)) * 2 - geometries = cp.arange(len(lhs) + 1) - ls_rhs = cuspatial.GeoSeries.from_linestrings_xy(xy, parts, geometries) - return self._compute_predicate( - lhs, ls_rhs, PreprocessorResult(lhs, ls_rhs) - ) + intersects = _basic_intersects(lhs, rhs) + contains = _basic_contains_any(rhs, lhs) + return intersects | contains + + +class PolygonLineStringIntersects(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(lhs, rhs) + contains = _basic_contains_any(lhs, rhs) + return intersects | contains + + +class PolygonPolygonIntersects(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(lhs, rhs) + contains_rhs = _basic_contains_any(rhs, lhs) + contains_lhs = _basic_contains_any(lhs, rhs) + + return intersects | contains_rhs | contains_lhs """ Type dispatch dictionary for intersects binary predicates. """ @@ -166,11 +155,11 @@ def _preprocess(self, lhs, rhs): (MultiPoint, LineString): NotImplementedPredicate, (MultiPoint, Polygon): NotImplementedPredicate, (LineString, Point): LineStringPointIntersects, - (LineString, MultiPoint): LineStringMultiPointIntersects, + (LineString, MultiPoint): LineStringPointIntersects, (LineString, LineString): IntersectsPredicateBase, - (LineString, Polygon): NotImplementedPredicate, - (Polygon, Point): NotImplementedPredicate, + (LineString, Polygon): LineStringPolygonIntersects, + (Polygon, Point): PolygonPointIntersects, (Polygon, MultiPoint): NotImplementedPredicate, - (Polygon, LineString): NotImplementedPredicate, - (Polygon, Polygon): NotImplementedPredicate, + (Polygon, LineString): PolygonLineStringIntersects, + (Polygon, Polygon): PolygonPolygonIntersects, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py b/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py index 20bad01a3..b0eab48a9 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py @@ -6,7 +6,7 @@ ImpossiblePredicate, NotImplementedPredicate, ) -from cuspatial.core.binpreds.feature_contains import ContainsPredicateBase +from cuspatial.core.binpreds.feature_contains import ContainsPredicate from cuspatial.core.binpreds.feature_equals import EqualsPredicateBase from cuspatial.utils.binpred_utils import ( LineString, @@ -36,7 +36,7 @@ class OverlapsPredicateBase(EqualsPredicateBase): pass -class PolygonPointOverlaps(ContainsPredicateBase): +class PolygonPointOverlaps(ContainsPredicate): def _postprocess(self, lhs, rhs, op_result): if not has_same_geometry(lhs, rhs) or len(op_result.point_result) == 0: return _false_series(len(lhs)) diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_touches.py b/python/cuspatial/cuspatial/core/binpreds/feature_touches.py index 8b4844577..c6935b782 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_touches.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_touches.py @@ -4,7 +4,7 @@ ImpossiblePredicate, NotImplementedPredicate, ) -from cuspatial.core.binpreds.feature_contains import ContainsPredicateBase +from cuspatial.core.binpreds.feature_contains import ContainsPredicate from cuspatial.utils.binpred_utils import ( LineString, MultiPoint, @@ -13,7 +13,7 @@ ) -class TouchesPredicateBase(ContainsPredicateBase): +class TouchesPredicateBase(ContainsPredicate): """Base class for binary predicates that use the contains predicate to implement the touches predicate. For example, a Point-Polygon Touches predicate is defined in terms of a Point-Polygon Contains diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_within.py b/python/cuspatial/cuspatial/core/binpreds/feature_within.py index 66bc21943..043f4629e 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_within.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_within.py @@ -1,95 +1,79 @@ # Copyright (c) 2023, NVIDIA CORPORATION. -import cudf - -from cuspatial.core.binpreds.binpred_interface import NotImplementedPredicate -from cuspatial.core.binpreds.feature_contains import ContainsPredicateBase -from cuspatial.core.binpreds.feature_equals import EqualsPredicateBase -from cuspatial.utils import binpred_utils +from cuspatial.core.binpreds.basic_predicates import ( + _basic_equals, + _basic_equals_all, + _basic_intersects, +) +from cuspatial.core.binpreds.binpred_interface import ( + BinPred, + ImpossiblePredicate, + NotImplementedPredicate, +) from cuspatial.utils.binpred_utils import ( LineString, MultiPoint, Point, Polygon, - _false_series, ) -class WithinPredicateBase(EqualsPredicateBase): - """Base class for binary predicates that are defined in terms of a - root-level binary predicate. For example, a Point-Point Within - predicate is defined in terms of a Point-Point Contains predicate. - Used by: - (Polygon, Point) - (Polygon, MultiPoint) - (Polygon, LineString) - """ +class WithinPredicateBase(BinPred): + def _preprocess(self, lhs, rhs): + return _basic_equals_all(lhs, rhs) - pass +class WithinIntersectsPredicate(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(rhs, lhs) + equals = _basic_equals(rhs, lhs) + return intersects & ~equals -class PointPointWithin(WithinPredicateBase): - def _postprocess(self, lhs, rhs, op_result): - return cudf.Series(op_result.result) +class PointLineStringWithin(BinPred): + def _preprocess(self, lhs, rhs): + intersects = lhs.intersects(rhs) + equals = _basic_equals(lhs, rhs) + return intersects & ~equals -class PointPolygonWithin(ContainsPredicateBase): + +class PointPolygonWithin(BinPred): def _preprocess(self, lhs, rhs): - # Note the order of arguments is reversed. - return super()._preprocess(rhs, lhs) + return rhs.contains_properly(lhs) + +class LineStringLineStringWithin(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(rhs, lhs) + equals = _basic_equals_all(rhs, lhs) + return intersects & equals -class ComplexPolygonWithin(ContainsPredicateBase): - """Implements within for complex polygons. Depends on contains result - for the types. - Used by: - (MultiPoint, Polygon) - (LineString, Polygon) - (Polygon, Polygon) - """ +class LineStringPolygonWithin(BinPred): + def _preprocess(self, lhs, rhs): + return rhs.contains(lhs) + +class PolygonPolygonWithin(BinPred): def _preprocess(self, lhs, rhs): - # Note the order of arguments is reversed. - return super()._preprocess(rhs, lhs) - - def _postprocess(self, lhs, rhs, op_result): - """Postprocess the output GeoSeries to ensure that they are of the - correct type for the predicate.""" - ( - hits, - expected_count, - ) = binpred_utils._count_results_in_multipoint_geometries( - op_result.point_indices, op_result.result - ) - result_df = hits.reset_index().merge( - expected_count.reset_index(), on="rhs_index" - ) - result_df["feature_in_polygon"] = ( - result_df["point_index_x"] >= result_df["point_index_y"] - ) - final_result = _false_series(len(lhs)) - final_result.loc[ - result_df["rhs_index"][result_df["feature_in_polygon"]] - ] = True - return final_result + return rhs.contains(lhs) DispatchDict = { - (Point, Point): PointPointWithin, - (Point, MultiPoint): NotImplementedPredicate, - (Point, LineString): NotImplementedPredicate, + (Point, Point): WithinPredicateBase, + (Point, MultiPoint): WithinIntersectsPredicate, + (Point, LineString): PointLineStringWithin, (Point, Polygon): PointPolygonWithin, (MultiPoint, Point): NotImplementedPredicate, (MultiPoint, MultiPoint): NotImplementedPredicate, - (MultiPoint, LineString): NotImplementedPredicate, - (MultiPoint, Polygon): ComplexPolygonWithin, - (LineString, Point): NotImplementedPredicate, - (LineString, MultiPoint): NotImplementedPredicate, - (LineString, LineString): NotImplementedPredicate, - (LineString, Polygon): ComplexPolygonWithin, + (MultiPoint, LineString): WithinIntersectsPredicate, + (MultiPoint, Polygon): PolygonPolygonWithin, + (LineString, Point): ImpossiblePredicate, + (LineString, MultiPoint): WithinIntersectsPredicate, + (LineString, LineString): LineStringLineStringWithin, + (LineString, Polygon): LineStringPolygonWithin, (Polygon, Point): WithinPredicateBase, (Polygon, MultiPoint): WithinPredicateBase, (Polygon, LineString): WithinPredicateBase, - (Polygon, Polygon): ComplexPolygonWithin, + (Polygon, Polygon): PolygonPolygonWithin, } diff --git a/python/cuspatial/cuspatial/core/geoseries.py b/python/cuspatial/cuspatial/core/geoseries.py index cfcd9051d..c13b673ed 100644 --- a/python/cuspatial/cuspatial/core/geoseries.py +++ b/python/cuspatial/cuspatial/core/geoseries.py @@ -28,12 +28,14 @@ from cuspatial.core._column.geometa import Feature_Enum, GeoMeta from cuspatial.core.binpreds.binpred_dispatch import ( CONTAINS_DISPATCH, + CONTAINS_PROPERLY_DISPATCH, COVERS_DISPATCH, CROSSES_DISPATCH, DISJOINT_DISPATCH, EQUALS_DISPATCH, INTERSECTS_DISPATCH, OVERLAPS_DISPATCH, + TOUCHES_DISPATCH, WITHIN_DISPATCH, ) from cuspatial.utils.column_utils import ( @@ -157,6 +159,57 @@ def point_indices(self): "Polygons to return point indices." ) + @property + def sizes(self): + """Returns the number of points of each geometry in the GeoSeries." + + Returns + ------- + sizes : cudf.Series + The size of each geometry in the GeoSeries. + + Notes + ----- + The size of a geometry is the number of points it contains. + The size of a polygon is the total number of points in all of its + rings. + The size of a multipolygon is the sum of the sizes of all of its + polygons. + The size of a linestring is the number of points in its single line. + The size of a multilinestring is the sum of the sizes of all of its + linestrings. + The size of a multipoint is the number of points in its single point. + The size of a point is 1. + """ + if contains_only_polygons(self): + # The size of a polygon is the length of its exterior ring + # plus the lengths of its interior rings. + # The size of a multipolygon is the sum of all its polygons. + full_sizes = self.polygons.ring_offset.take( + self.polygons.part_offset.take(self.polygons.geometry_offset) + ) + return cudf.Series(full_sizes[1:] - full_sizes[:-1]) + elif contains_only_linestrings(self): + # Not supporting multilinestring yet + full_sizes = self.lines.part_offset.take( + self.lines.geometry_offset + ) + return cudf.Series(full_sizes[1:] - full_sizes[:-1]) + elif contains_only_multipoints(self): + return ( + self.multipoints.geometry_offset[1:] + - self.multipoints.geometry_offset[:-1] + ) + elif contains_only_points(self): + return cudf.Series(cp.repeat(cp.array(1), len(self))) + else: + if len(self) == 0: + return cudf.Series([0], dtype="int32") + raise NotImplementedError( + "GeoSeries must contain only Points, MultiPoints, Lines, or " + "Polygons to return sizes." + ) + class GeoColumnAccessor: def __init__(self, list_series, meta): self._series = list_series @@ -315,12 +368,7 @@ def __getitem__(self, item): return self._sr.iloc[item] map_df = cudf.DataFrame( - { - "map": self._sr.index, - "idx": cp.arange(len(self._sr.index)) - if not isinstance(item, Integral) - else 0, - } + {"map": self._sr.index, "idx": cp.arange(len(self._sr.index))} ) index_df = cudf.DataFrame({"map": item}).reset_index() new_index = index_df.merge( @@ -665,7 +713,8 @@ def from_multipoints_xy(cls, multipoints_xy, geometry_offset): """ return cls( GeoColumn._from_multipoints_xy( - as_column(multipoints_xy), as_column(geometry_offset) + as_column(multipoints_xy), + as_column(geometry_offset, dtype="int32"), ) ) @@ -948,7 +997,65 @@ def reset_index( self.index = cudf_series.index return None - def contains_properly(self, other, align=False, allpairs=False): + def contains(self, other, align=False, allpairs=False, mode="full"): + """Returns a `Series` of `dtype('bool')` with value `True` for each + aligned geometry that contains _other_. + + An object a is said to contain b if b's boundary and + interiors are within those of a and no point of b lies in the + exterior of a. + + If `allpairs=False`, the result will be a `Series` of `dtype('bool')`. + If `allpairs=True`, the result will be a `DataFrame` containing two + columns, `point_indices` a`nd `polygon_indices`, each of which is a + `Series` of `dtype('int32')`. The `point_indices` `Series` contains + the indices of the points in the right GeoSeries, and the + `polygon_indices` `Series` contains the indices of the polygons in the + left GeoSeries. + + Notes + ----- + `allpairs=True` excludes geometries that contain points in the + boundary of A. + + Parameters + ---------- + other : GeoSeries + align : bool, default False + If True, the two GeoSeries are aligned before performing the + operation. If False, the operation is performed on the + unaligned GeoSeries. + allpairs : bool, default False + If True, the result will be a `DataFrame` containing two + columns, `point_indices` and `polygon_indices`, each of which is a + `Series` of `dtype('int32')`. The `point_indices` `Series` contains + the indices of the points in the right GeoSeries, and the + `polygon_indices` `Series` contains the indices of the polygons in + the left GeoSeries. Excludes boundary points. + mode : str, default "full" or "basic_none", "basic_any", + "basic_all", or "basic_count". + If "full", the result will be a `Series` of `dtype('bool')` with + value `True` for each aligned geometry that contains _other_. + If "intersects", the result will be a `Series` of `dtype('bool')` + with value `True` for each aligned geometry that contains _other_ + or intersects _other_. + + Returns + ------- + Series or DataFrame + A `Series` of `dtype('bool')` with value `True` for each aligned + geometry that contains _other_. If `allpairs=True`, the result + will be a `DataFrame` containing two columns, `point_indices` and + `polygon_indices`, each of which is a `Series` of `dtype('int32')`. + """ + predicate = CONTAINS_DISPATCH[(self.column_type, other.column_type)]( + align=align, allpairs=allpairs, mode=mode + ) + return predicate(self, other) + + def contains_properly( + self, other, align=False, allpairs=False, mode="full" + ): """Returns a `Series` of `dtype('bool')` with value `True` for each aligned geometry that contains _other_. @@ -1041,9 +1148,9 @@ def contains_properly(self, other, align=False, allpairs=False): `point_indices` and `polygon_indices`, each of which is a `Series` of `dtype('int32')` in the case of `allpairs=True`. """ - predicate = CONTAINS_DISPATCH[(self.column_type, other.column_type)]( - align=align, allpairs=allpairs - ) + predicate = CONTAINS_PROPERLY_DISPATCH[ + (self.column_type, other.column_type) + ](align=align, allpairs=allpairs, mode=mode) return predicate(self, other) def geom_equals(self, other, align=True): @@ -1244,3 +1351,27 @@ def disjoint(self, other, align=True): align=align ) return predicate(self, other) + + def touches(self, other, align=True): + """Returns True for all aligned geometries that touch other, else + False. + + Geometries touch if they have any coincident edges or share any + vertices, and their interiors do not intersect. + + Parameters + ---------- + other + a cuspatial.GeoSeries + align=True + align the GeoSeries indexes before calling the binpred + + Returns + ------- + result : cudf.Series + A Series of boolean values indicating whether each geometry + touches the corresponding geometry in the input.""" + predicate = TOUCHES_DISPATCH[(self.column_type, other.column_type)]( + align=align + ) + return predicate(self, other) diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_contains.py b/python/cuspatial/cuspatial/tests/binpreds/test_contains.py new file mode 100644 index 000000000..274c96165 --- /dev/null +++ b/python/cuspatial/cuspatial/tests/binpreds/test_contains.py @@ -0,0 +1,93 @@ +# Copyright (c) 2023, NVIDIA CORPORATION + +import geopandas as gpd +import pandas as pd +import pytest +from shapely.geometry import MultiPolygon, Polygon + +import cuspatial + + +def test_same(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + gpdlhs = lhs.to_geopandas() + gpdrhs = rhs.to_geopandas() + got = lhs.contains(rhs) + expected = gpdlhs.contains(gpdrhs) + pd.testing.assert_series_equal(expected, got.to_pandas()) + + +def test_adjacent(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Polygon([(1, 0), (1, 1), (2, 1), (2, 0)])]) + gpdlhs = lhs.to_geopandas() + gpdrhs = rhs.to_geopandas() + got = lhs.contains(rhs) + expected = gpdlhs.contains(gpdrhs) + pd.testing.assert_series_equal(expected, got.to_pandas()) + + +def test_interior(): + lhs = cuspatial.GeoSeries( + [Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])] + ) + rhs = cuspatial.GeoSeries( + [Polygon([(0, 0), (0, 0.5), (0.5, 0.5), (0.5, 0)])] + ) + gpdlhs = lhs.to_geopandas() + gpdrhs = rhs.to_geopandas() + got = lhs.contains(rhs) + expected = gpdlhs.contains(gpdrhs) + pd.testing.assert_series_equal(expected, got.to_pandas()) + + +@pytest.mark.parametrize( + "object", + [ + Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), + MultiPolygon( + [ + Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), + Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), + ] + ), + ], +) +def test_self_contains(object): + gpdobject = gpd.GeoSeries(object) + object = cuspatial.from_geopandas(gpdobject) + got = object.contains(object).values_host + expected = gpdobject.contains(gpdobject).values + assert (got == expected).all() + + +def test_complex_input(): + gpdobject = gpd.GeoSeries( + [ + Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), + Polygon( + ([0, 0], [1, 1], [1, 0], [0, 0]), + [([0, 0], [1, 1], [1, 0], [0, 0])], + ), + MultiPolygon( + [ + Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), + Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), + ] + ), + MultiPolygon( + [ + Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), + Polygon( + ([0, 0], [1, 1], [1, 0], [0, 0]), + [([0, 0], [1, 1], [1, 0], [0, 0])], + ), + ] + ), + ] + ) + object = cuspatial.from_geopandas(gpdobject) + got = object.contains(object).values_host + expected = gpdobject.contains(gpdobject).values + assert (got == expected).all() diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py b/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py index a93b429c9..e3a67df6c 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py @@ -1,3 +1,5 @@ +# Copyright (c) 2023, NVIDIA CORPORATION + import cupy as cp import geopandas as gpd import numpy as np @@ -387,59 +389,6 @@ def test_max_polygons_max_multipoints(multipoint_generator, polygon_generator): assert (got == expected).all() -@pytest.mark.parametrize( - "object", - [ - Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), - MultiPolygon( - [ - Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), - Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), - ] - ), - ], -) -def test_self_contains(object): - gpdobject = gpd.GeoSeries(object) - object = cuspatial.from_geopandas(gpdobject) - got = object.contains_properly(object).values_host - expected = gpdobject.contains(gpdobject).values - np.testing.assert_array_equal(got, np.array([False])) - np.testing.assert_array_equal(expected, np.array([True])) - - -def test_complex_input(): - gpdobject = gpd.GeoSeries( - [ - Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), - Polygon( - ([0, 0], [1, 1], [1, 0], [0, 0]), - [([0, 0], [1, 1], [1, 0], [0, 0])], - ), - MultiPolygon( - [ - Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), - Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), - ] - ), - MultiPolygon( - [ - Polygon([[0, 0], [1, 1], [1, 0], [0, 0]]), - Polygon( - ([0, 0], [1, 1], [1, 0], [0, 0]), - [([0, 0], [1, 1], [1, 0], [0, 0])], - ), - ] - ), - ] - ) - object = cuspatial.from_geopandas(gpdobject) - got = object.contains_properly(object).values_host - expected = gpdobject.contains(gpdobject).values - assert (got == [False, False, False, False]).all() - assert (expected == [True, True, True, True]).all() - - def test_multi_contains(): lhs = cuspatial.GeoSeries( [ diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_pip_only_binpreds.py b/python/cuspatial/cuspatial/tests/binpreds/test_pip_only_binpreds.py index 545629402..f3d1c10c8 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_pip_only_binpreds.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_pip_only_binpreds.py @@ -1,4 +1,3 @@ -import geopandas as gpd from shapely.geometry import LineString, Point, Polygon import cuspatial @@ -6,189 +5,141 @@ """Overlaps, Within, and Intersects""" +def _test(lhs, rhs, predicate): + gpdlhs = lhs.to_geopandas() + gpdrhs = rhs.to_geopandas() + got = getattr(lhs, predicate)(rhs).values_host + expected = getattr(gpdlhs, predicate)(gpdrhs).values + assert (got == expected).all() + + def test_polygon_overlaps_point(): - gpdpolygon = gpd.GeoSeries( - Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]) + lhs = cuspatial.GeoSeries( + [Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]])] ) - gpdpoint = gpd.GeoSeries([Point(0.5, 0.5)]) - polygon = cuspatial.from_geopandas(gpdpolygon) - point = cuspatial.from_geopandas(gpdpoint) - got = polygon.overlaps(point).values_host - expected = gpdpolygon.overlaps(gpdpoint).values - assert (got == expected).all() + rhs = cuspatial.GeoSeries([Point(0.5, 0.5)]) + _test(lhs, rhs, "overlaps") def test_max_polygons_overlaps_max_points(polygon_generator, point_generator): - gpdpolygon = gpd.GeoSeries([*polygon_generator(31, 0)]) - gpdpoint = gpd.GeoSeries([*point_generator(31)]) - polygon = cuspatial.from_geopandas(gpdpolygon) - point = cuspatial.from_geopandas(gpdpoint) - got = polygon.overlaps(point).values_host - expected = gpdpolygon.overlaps(gpdpoint).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([*polygon_generator(31, 0)]) + rhs = cuspatial.GeoSeries([*point_generator(31)]) + _test(lhs, rhs, "overlaps") def test_polygon_overlaps_polygon_partially(): - gpdpolygon1 = gpd.GeoSeries( - Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]) + lhs = cuspatial.GeoSeries( + [Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]])] ) - gpdpolygon2 = gpd.GeoSeries( - Polygon([[0.5, 0.5], [0.5, 1.5], [1.5, 1.5], [1.5, 0.5], [0.5, 0.5]]) + rhs = cuspatial.GeoSeries( + [Polygon([[0.5, 0.5], [0.5, 1.5], [1.5, 1.5], [1.5, 0.5], [0.5, 0.5]])] ) - polygon1 = cuspatial.from_geopandas(gpdpolygon1) - polygon2 = cuspatial.from_geopandas(gpdpolygon2) - got = polygon1.overlaps(polygon2).values_host - expected = gpdpolygon1.overlaps(gpdpolygon2).values - assert (got == expected).all() + _test(lhs, rhs, "overlaps") def test_polygon_overlaps_polygon_completely(): - gpdpolygon1 = gpd.GeoSeries( - Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]) + lhs = cuspatial.GeoSeries( + [Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]])] ) - gpdpolygon2 = gpd.GeoSeries( - Polygon( - [[0.25, 0.25], [0.25, 0.5], [0.5, 0.5], [0.5, 0.25], [0.25, 0.25]] - ) + rhs = cuspatial.GeoSeries( + [ + Polygon( + [ + [0.25, 0.25], + [0.25, 0.5], + [0.5, 0.5], + [0.5, 0.25], + [0.25, 0.25], + ] + ) + ] ) - polygon1 = cuspatial.from_geopandas(gpdpolygon1) - polygon2 = cuspatial.from_geopandas(gpdpolygon2) - got = polygon1.overlaps(polygon2).values_host - expected = gpdpolygon1.overlaps(gpdpolygon2).values - assert (got == expected).all() + _test(lhs, rhs, "overlaps") def test_polygon_overlaps_polygon_no_overlap(): - gpdpolygon1 = gpd.GeoSeries( - Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]) + lhs = cuspatial.GeoSeries( + [Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]])] ) - gpdpolygon2 = gpd.GeoSeries( - Polygon([[2, 2], [2, 3], [3, 3], [3, 2], [2, 2]]) + rhs = cuspatial.GeoSeries( + [Polygon([[2, 2], [2, 3], [3, 3], [3, 2], [2, 2]])] ) - polygon1 = cuspatial.from_geopandas(gpdpolygon1) - polygon2 = cuspatial.from_geopandas(gpdpolygon2) - got = polygon1.overlaps(polygon2).values_host - expected = gpdpolygon1.overlaps(gpdpolygon2).values - assert (got == expected).all() + _test(lhs, rhs, "overlaps") def test_max_polygon_overlaps_max_points(polygon_generator, point_generator): - gpdpolygon = gpd.GeoSeries([*polygon_generator(31, 0)]) - gpdpoint = gpd.GeoSeries([*point_generator(31)]) - polygon = cuspatial.from_geopandas(gpdpolygon) - point = cuspatial.from_geopandas(gpdpoint) - got = polygon.overlaps(point).values_host - expected = gpdpolygon.overlaps(gpdpoint).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([*polygon_generator(31, 0)]) + rhs = cuspatial.GeoSeries([*point_generator(31)]) + _test(lhs, rhs, "overlaps") def test_point_intersects_polygon_interior(): - gpdpoint = gpd.GeoSeries([Point(0.5, 0.5)]) - gpdpolygon = gpd.GeoSeries( - Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]) + lhs = cuspatial.GeoSeries([Point(0.5, 0.5)]) + rhs = cuspatial.GeoSeries( + [Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]])] ) - point = cuspatial.from_geopandas(gpdpoint) - polygon = cuspatial.from_geopandas(gpdpolygon) - got = point.intersects(polygon).values_host - expected = gpdpoint.intersects(gpdpolygon).values - assert (got == expected).all() + _test(lhs, rhs, "intersects") def test_max_points_intersects_max_polygons_interior( polygon_generator, point_generator ): - gpdpolygon = gpd.GeoSeries([*polygon_generator(31, 0)]) - gpdpoint = gpd.GeoSeries([*point_generator(31)]) - polygon = cuspatial.from_geopandas(gpdpolygon) - point = cuspatial.from_geopandas(gpdpoint) - got = point.intersects(polygon).values_host - expected = gpdpoint.intersects(gpdpolygon).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([*polygon_generator(31, 0)]) + rhs = cuspatial.GeoSeries([*point_generator(31)]) + _test(lhs, rhs, "intersects") def test_point_within_polygon(): - gpdpoint = gpd.GeoSeries([Point(0, 0)]) - gpdpolygon = gpd.GeoSeries(Polygon([[0, 0], [1, 0], [1, 1], [0, 0]])) - point = cuspatial.from_geopandas(gpdpoint) - polygon = cuspatial.from_geopandas(gpdpolygon) - got = point.within(polygon).values_host - expected = gpdpoint.within(gpdpolygon).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([Point(0, 0)]) + rhs = cuspatial.GeoSeries([Polygon([[0, 0], [1, 0], [1, 1], [0, 0]])]) + _test(lhs, rhs, "within") def test_max_points_within_max_polygons(polygon_generator, point_generator): - gpdpolygon = gpd.GeoSeries([*polygon_generator(31, 0)]) - gpdpoint = gpd.GeoSeries([*point_generator(31)]) - polygon = cuspatial.from_geopandas(gpdpolygon) - point = cuspatial.from_geopandas(gpdpoint) - got = point.within(polygon).values_host - expected = gpdpoint.within(gpdpolygon).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([*polygon_generator(31, 0)]) + rhs = cuspatial.GeoSeries([*point_generator(31)]) + _test(lhs, rhs, "within") def test_linestring_within_polygon(): - gpdline = gpd.GeoSeries([LineString([(0, 0), (1, 1)])]) - gpdpolygon = gpd.GeoSeries(Polygon([[0, 0], [1, 0], [1, 1], [0, 0]])) - line = cuspatial.from_geopandas(gpdline) - polygon = cuspatial.from_geopandas(gpdpolygon) - got = line.within(polygon).values_host - expected = gpdline.within(gpdpolygon).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([LineString([(0, 0), (1, 1)])]) + rhs = cuspatial.GeoSeries([Polygon([[0, 0], [1, 0], [1, 1], [0, 0]])]) + _test(lhs, rhs, "within") def test_max_linestring_within_max_polygon( polygon_generator, linestring_generator ): - gpdpolygon = gpd.GeoSeries([*polygon_generator(31, 0)]) - gpdline = gpd.GeoSeries([*linestring_generator(31, 5)]) - polygon = cuspatial.from_geopandas(gpdpolygon) - line = cuspatial.from_geopandas(gpdline) - got = line.within(polygon).values_host - expected = gpdline.within(gpdpolygon).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([*polygon_generator(31, 0)]) + rhs = cuspatial.GeoSeries([*linestring_generator(31, 5)]) + _test(lhs, rhs, "within") def test_polygon_within_polygon(): - gpdpolygon1 = gpd.GeoSeries( - Polygon([[0, 0], [-1, 1], [1, 1], [1, -2], [0, 0]]) + lhs = cuspatial.GeoSeries( + [Polygon([[0, 0], [-1, 1], [1, 1], [1, -2], [0, 0]])] ) - gpdpolygon2 = gpd.GeoSeries(Polygon([[-1, -1], [-2, 2], [2, 2], [2, -2]])) - polygon1 = cuspatial.from_geopandas(gpdpolygon1) - polygon2 = cuspatial.from_geopandas(gpdpolygon2) - got = polygon1.within(polygon2).values_host - expected = gpdpolygon1.within(gpdpolygon2).values - assert (got == expected).all() + rhs = cuspatial.GeoSeries([Polygon([[-1, -1], [-2, 2], [2, 2], [2, -2]])]) + _test(lhs, rhs, "within") def test_max_polygons_within_max_polygons(polygon_generator): - gpdpolygon1 = gpd.GeoSeries([*polygon_generator(31, 0)]) - gpdpolygon2 = gpd.GeoSeries([*polygon_generator(31, 1)]) - polygon1 = cuspatial.from_geopandas(gpdpolygon1) - polygon2 = cuspatial.from_geopandas(gpdpolygon2) - got = polygon1.within(polygon2).values_host - expected = gpdpolygon1.within(gpdpolygon2).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([*polygon_generator(31, 0)]) + rhs = cuspatial.GeoSeries([*polygon_generator(31, 1)]) + _test(lhs, rhs, "within") def test_polygon_overlaps_linestring(): - gpdpolygon = gpd.GeoSeries( - Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]) + lhs = cuspatial.GeoSeries( + [Polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]])] ) - gpdline = gpd.GeoSeries([LineString([(0.5, 0.5), (1.5, 1.5)])]) - polygon = cuspatial.from_geopandas(gpdpolygon) - line = cuspatial.from_geopandas(gpdline) - got = polygon.overlaps(line).values_host - expected = gpdpolygon.overlaps(gpdline).values - assert (got == expected).all() + rhs = cuspatial.GeoSeries([LineString([(0.5, 0.5), (1.5, 1.5)])]) + _test(lhs, rhs, "overlaps") def test_max_polygons_overlaps_max_linestrings( polygon_generator, linestring_generator ): - gpdpolygon = gpd.GeoSeries([*polygon_generator(31, 0)]) - gpdline = gpd.GeoSeries([*linestring_generator(31, 5)]) - polygon = cuspatial.from_geopandas(gpdpolygon) - line = cuspatial.from_geopandas(gpdline) - got = polygon.overlaps(line).values_host - expected = gpdpolygon.overlaps(gpdline).values - assert (got == expected).all() + lhs = cuspatial.GeoSeries([*polygon_generator(31, 0)]) + rhs = cuspatial.GeoSeries([*linestring_generator(31, 5)]) + _test(lhs, rhs, "overlaps") diff --git a/python/cuspatial/cuspatial/utils/binpred_utils.py b/python/cuspatial/cuspatial/utils/binpred_utils.py index 8cbddbda2..7229df632 100644 --- a/python/cuspatial/cuspatial/utils/binpred_utils.py +++ b/python/cuspatial/cuspatial/utils/binpred_utils.py @@ -1,9 +1,11 @@ # Copyright (c) 2023, NVIDIA CORPORATION. import cupy as cp +import numpy as np import cudf +import cuspatial from cuspatial.core._column.geocolumn import ColumnType """Column-Type objects to use for simple syntax in the `DispatchDict` contained @@ -21,6 +23,21 @@ def _false_series(size): return cudf.Series(cp.zeros(size, dtype=cp.bool_)) +def _true_series(size): + """Return a Series of True values""" + return cudf.Series(cp.ones(size, dtype=cp.bool_)) + + +def _zero_series(size): + """Return a Series of zeros""" + return cudf.Series(cp.zeros(size, dtype=cp.int32)) + + +def _one_series(size): + """Return a Series of ones""" + return cudf.Series(cp.ones(size, dtype=cp.int32)) + + def _count_results_in_multipoint_geometries(point_indices, point_result): """Count the number of points in each multipoint geometry. @@ -54,3 +71,312 @@ def _count_results_in_multipoint_geometries(point_indices, point_result): ) expected_count = point_indices_df.groupby("rhs_index").count().sort_index() return hits, expected_count + + +def _linestrings_from_polygons(geoseries): + """Converts the exterior and interior rings of a geoseries of polygons + into a geoseries of linestrings.""" + xy = geoseries.polygons.xy + parts = geoseries.polygons.part_offset.take( + geoseries.polygons.geometry_offset + ) + rings = geoseries.polygons.ring_offset + return cuspatial.GeoSeries.from_linestrings_xy( + xy, + rings, + parts, + ) + + +def _linestrings_from_multipoints(geoseries): + """Converts a geoseries of multipoints into a geoseries of + linestrings.""" + points = cudf.DataFrame( + { + "x": geoseries.multipoints.x.repeat(2).reset_index(drop=True), + "y": geoseries.multipoints.y.repeat(2).reset_index(drop=True), + } + ).interleave_columns() + result = cuspatial.GeoSeries.from_linestrings_xy( + points, + geoseries.multipoints.geometry_offset * 2, + cp.arange(len(geoseries) + 1), + ) + return result + + +def _linestrings_from_points(geoseries): + """Converts a geoseries of points into a geoseries of linestrings. + + Linestrings converted to points are represented as a segment of + length two, with the beginning and ending of the segment being the + same point. + + Example + ------- + >>> import cuspatial + >>> from cuspatial.utils.binpred_utils import ( + ... _linestrings_from_points + ... ) + >>> from shapely.geometry import Point + >>> points = cuspatial.GeoSeries([Point(0, 0), Point(1, 1)]) + >>> linestrings = _linestrings_from_points(points) + >>> linestrings + Out[1]: + 0 LINESTRING (0.00000 0.00000, 0.00000 0.00000) + 1 LINESTRING (1.00000 1.00000, 1.00000 1.00000) + dtype: geometry + """ + x = cp.repeat(geoseries.points.x, 2) + y = cp.repeat(geoseries.points.y, 2) + xy = cudf.DataFrame({"x": x, "y": y}).interleave_columns() + parts = cp.arange((len(geoseries) + 1)) * 2 + geometries = cp.arange(len(geoseries) + 1) + return cuspatial.GeoSeries.from_linestrings_xy(xy, parts, geometries) + + +def _linestrings_from_geometry(geoseries): + """Wrapper function that converts any homogeneous geoseries into + a geoseries of linestrings.""" + if geoseries.column_type == ColumnType.POINT: + return _linestrings_from_points(geoseries) + if geoseries.column_type == ColumnType.MULTIPOINT: + return _linestrings_from_multipoints(geoseries) + elif geoseries.column_type == ColumnType.LINESTRING: + return geoseries + elif geoseries.column_type == ColumnType.POLYGON: + return _linestrings_from_polygons(geoseries) + else: + raise NotImplementedError( + "Cannot convert type {} to linestrings".format(geoseries.type) + ) + + +def _multipoints_from_points(geoseries): + """Converts a geoseries of points into a geoseries of length 1 + multipoints.""" + result = cuspatial.GeoSeries.from_multipoints_xy( + geoseries.points.xy, cp.arange((len(geoseries) + 1)) + ) + return result + + +def _multipoints_from_linestrings(geoseries): + """Converts a geoseries of linestrings into a geoseries of + multipoints. MultiLineStrings are converted into a single multipoint.""" + xy = geoseries.lines.xy + mpoints = geoseries.lines.part_offset.take(geoseries.lines.geometry_offset) + return cuspatial.GeoSeries.from_multipoints_xy(xy, mpoints) + + +def _multipoints_from_polygons(geoseries): + """Converts a geoseries of polygons into a geoseries of multipoints. + All exterior and interior points become points in each multipoint object. + """ + xy = geoseries.polygons.xy + polygon_offsets = geoseries.polygons.ring_offset.take( + geoseries.polygons.part_offset.take(geoseries.polygons.geometry_offset) + ) + # Drop the endpoint from all polygons + return cuspatial.GeoSeries.from_multipoints_xy(xy, polygon_offsets) + + +def _multipoints_from_geometry(geoseries): + """Wrapper function that converts any homogeneous geoseries into + a geoseries of multipoints.""" + if geoseries.column_type == ColumnType.POINT: + return _multipoints_from_points(geoseries) + elif geoseries.column_type == ColumnType.MULTIPOINT: + return geoseries + elif geoseries.column_type == ColumnType.LINESTRING: + return _multipoints_from_linestrings(geoseries) + elif geoseries.column_type == ColumnType.POLYGON: + return _multipoints_from_polygons(geoseries) + else: + raise NotImplementedError( + "Cannot convert type {} to multipoints".format(geoseries.type) + ) + + +def _points_from_linestrings(geoseries): + """Convert a geoseries of linestrings into a geoseries of points. + The length of the result is equal to the sum of the lengths of the + linestrings in the original geoseries.""" + return cuspatial.GeoSeries.from_points_xy(geoseries.lines.xy) + + +def _points_from_polygons(geoseries): + """Convert a geoseries of linestrings into a geoseries of points. + The length of the result is equal to the sum of the lengths of the + polygons in the original geoseries.""" + return cuspatial.GeoSeries.from_points_xy(geoseries.polygons.xy) + + +def _points_from_geometry(geoseries): + """Wrapper function that converts any homogeneous geoseries into + a geoseries of points.""" + if geoseries.column_type == ColumnType.POINT: + return geoseries + elif geoseries.column_type == ColumnType.LINESTRING: + return _points_from_linestrings(geoseries) + elif geoseries.column_type == ColumnType.POLYGON: + return _points_from_polygons(geoseries) + else: + raise NotImplementedError( + "Cannot convert type {} to points".format(geoseries.type) + ) + + +def _linestring_to_boundary(geoseries): + """Convert a geoseries of linestrings to a geoseries of multipoints + containing only the start and end of the linestrings.""" + x = geoseries.lines.x + y = geoseries.lines.y + starts = geoseries.lines.part_offset.take(geoseries.lines.geometry_offset) + ends = (starts - 1)[1:] + starts = starts[:-1] + points_x = cudf.DataFrame( + { + "starts": x[starts].reset_index(drop=True), + "ends": x[ends].reset_index(drop=True), + } + ).interleave_columns() + points_y = cudf.DataFrame( + { + "starts": y[starts].reset_index(drop=True), + "ends": y[ends].reset_index(drop=True), + } + ).interleave_columns() + xy = cudf.DataFrame({"x": points_x, "y": points_y}).interleave_columns() + mpoints = cp.arange(len(starts) + 1) * 2 + return cuspatial.GeoSeries.from_multipoints_xy(xy, mpoints) + + +def _polygon_to_boundary(geoseries): + """Convert a geoseries of polygons to a geoseries of linestrings or + multilinestrings containing only the exterior and interior boundaries + of the polygons.""" + xy = geoseries.polygons.xy + parts = geoseries.polygons.part_offset.take( + geoseries.polygons.geometry_offset + ) + rings = geoseries.polygons.ring_offset + return cuspatial.GeoSeries.from_linestrings_xy( + xy, + rings, + parts, + ) + + +def _is_complex(geoseries): + """Returns True if the GeoSeries contains non-point features that + need to be reconstructed after basic predicates have computed.""" + if len(geoseries.polygons.xy) > 0: + return True + if len(geoseries.lines.xy) > 0: + return True + if len(geoseries.multipoints.xy) > 0: + return True + return False + + +def _open_polygon_rings(geoseries): + """Converts a geoseries of polygons into a geoseries of linestrings + by opening the rings of each polygon.""" + x = geoseries.polygons.x + y = geoseries.polygons.y + parts = geoseries.polygons.part_offset.take( + geoseries.polygons.geometry_offset + ) + rings_mask = geoseries.polygons.ring_offset - 1 + rings_mask[0] = 0 + mask = _true_series(len(x)) + mask[rings_mask[1:]] = False + x = x[mask] + y = y[mask] + xy = cudf.DataFrame({"x": x, "y": y}).interleave_columns() + rings = geoseries.polygons.ring_offset - cp.arange(len(rings_mask)) + return cuspatial.GeoSeries.from_linestrings_xy( + xy, + rings, + parts, + ) + + +def _points_and_lines_to_multipoints(geoseries, offsets): + """Converts a geoseries of points and lines into a geoseries of + multipoints.""" + points_mask = geoseries.type == "Point" + lines_mask = geoseries.type == "Linestring" + if (points_mask + lines_mask).sum() != len(geoseries): + raise ValueError("Geoseries must contain only points and lines") + points = geoseries[points_mask] + lines = geoseries[lines_mask] + points_offsets = _zero_series(len(geoseries)) + points_offsets[points_mask] = 1 + lines_series = geoseries[lines_mask] + lines_sizes = lines_series.sizes + xy = _zero_series(len(points.points.xy) + len(lines.lines.xy)) + sizes = _zero_series(len(geoseries)) + if (lines_sizes != 0).all(): + lines_sizes.index = points_offsets[lines_mask].index + points_offsets[lines_mask] = lines_series.sizes.values + sizes[lines_mask] = lines.sizes.values * 2 + sizes[points_mask] = 2 + # TODO Inevitable host device copy + points_xy_mask = cp.array(np.repeat(points_mask, sizes.values_host)) + xy.iloc[points_xy_mask] = points.points.xy.reset_index(drop=True) + xy.iloc[~points_xy_mask] = lines.lines.xy.reset_index(drop=True) + collected_offsets = cudf.concat( + [cudf.Series([0]), sizes.cumsum()] + ).reset_index(drop=True)[offsets] + result = cuspatial.GeoSeries.from_multipoints_xy( + xy, collected_offsets // 2 + ) + return result + + +def _linestrings_to_center_point(geoseries): + if (geoseries.sizes != 2).any(): + raise ValueError( + "Geoseries must contain only linestrings with two points" + ) + x = geoseries.lines.x + y = geoseries.lines.y + return cuspatial.GeoSeries.from_points_xy( + cudf.DataFrame( + { + "x": ( + x[::2].reset_index(drop=True) + + x[1::2].reset_index(drop=True) + ) + / 2, + "y": ( + y[::2].reset_index(drop=True) + + y[1::2].reset_index(drop=True) + ) + / 2, + } + ).interleave_columns() + ) + + +def _multipoints_is_degenerate(geoseries): + """Only tests if the first two points are degenerate.""" + offsets = geoseries.multipoints.geometry_offset[:-1] + sizes_mask = geoseries.sizes > 1 + x1 = geoseries.multipoints.x[offsets[sizes_mask]] + x2 = geoseries.multipoints.x[offsets[sizes_mask] + 1] + y1 = geoseries.multipoints.y[offsets[sizes_mask]] + y2 = geoseries.multipoints.y[offsets[sizes_mask] + 1] + result = _false_series(len(geoseries)) + is_degenerate = ( + x1.reset_index(drop=True) == x2.reset_index(drop=True) + ) & (y1.reset_index(drop=True) == y2.reset_index(drop=True)) + result[sizes_mask] = is_degenerate.reset_index(drop=True) + return result + + +def _linestrings_is_degenerate(geoseries): + multipoints = _multipoints_from_geometry(geoseries) + return _multipoints_is_degenerate(multipoints) From 6e56d138655db91e0ccda8cc888451ff587a3c68 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 9 May 2023 11:18:47 -0700 Subject: [PATCH 17/63] Bump Gtest version following Rapids-cmake change (#1126) Following Rapids-cmake bump to gtest 1.13.0 https://github.com/rapidsai/rapids-cmake/issues/400, this PR implements some custom out stream operator for more constrained ADL rules that 1.11+ uses. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - AJ Schmidt (https://github.com/ajschmidt8) - Bradley Dice (https://github.com/bdice) URL: https://github.com/rapidsai/cuspatial/pull/1126 --- .../all_cuda-118_arch-x86_64.yaml | 4 ++-- .../libcuspatial/conda_build_config.yaml | 2 +- cpp/include/cuspatial_test/test_util.cuh | 5 +++-- cpp/tests/operators/linestrings_test.cu | 16 +++++++++++++++ .../trajectory/derive_trajectories_test.cu | 20 +++++++++++++++++++ dependencies.yaml | 4 ++-- 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index a428c0b6d..5fda0d096 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -16,8 +16,8 @@ dependencies: - doxygen - gcc_linux-64=11.* - geopandas>=0.11.0 -- gmock=1.10.0 -- gtest=1.10.0 +- gmock>=1.13.0 +- gtest>=1.13.0 - ipython - ipywidgets - libcudf==23.6.* diff --git a/conda/recipes/libcuspatial/conda_build_config.yaml b/conda/recipes/libcuspatial/conda_build_config.yaml index a50e5c3ff..6056ed6b2 100644 --- a/conda/recipes/libcuspatial/conda_build_config.yaml +++ b/conda/recipes/libcuspatial/conda_build_config.yaml @@ -11,7 +11,7 @@ cmake_version: - ">=3.23.1,!=3.25.0" gtest_version: - - "1.10.0" + - ">=1.13.0" sysroot_version: - "2.17" diff --git a/cpp/include/cuspatial_test/test_util.cuh b/cpp/include/cuspatial_test/test_util.cuh index 2cc10bae9..bf9e1fb01 100644 --- a/cpp/include/cuspatial_test/test_util.cuh +++ b/cpp/include/cuspatial_test/test_util.cuh @@ -19,14 +19,15 @@ #include #include -#include #include -#include #include #include +#include #include +#include +#include namespace cuspatial { diff --git a/cpp/tests/operators/linestrings_test.cu b/cpp/tests/operators/linestrings_test.cu index 86c8133c4..e67810f33 100644 --- a/cpp/tests/operators/linestrings_test.cu +++ b/cpp/tests/operators/linestrings_test.cu @@ -30,6 +30,7 @@ #include +#include #include using namespace cuspatial; @@ -39,6 +40,21 @@ using namespace cuspatial::test; template using optional_vec2d = thrust::optional>; +namespace cuspatial { + +// Required by gtest test suite to compile +// Need to be defined within cuspatial namespace for ADL. +template +std::ostream& operator<<(std::ostream& os, thrust::optional> const& opt) +{ + if (opt.has_value()) + return os << opt.value(); + else + return os << "null"; +} + +} // namespace cuspatial + template struct SegmentIntersectionTest : public BaseFixture {}; diff --git a/cpp/tests/trajectory/derive_trajectories_test.cu b/cpp/tests/trajectory/derive_trajectories_test.cu index cc47700c7..d6b78b6ec 100644 --- a/cpp/tests/trajectory/derive_trajectories_test.cu +++ b/cpp/tests/trajectory/derive_trajectories_test.cu @@ -35,6 +35,26 @@ #include #include +#include + +namespace std { + +// Required by gtest EXPECT_EQ test suite to compile. +// Since `time_point` is an alias on +// std::chrono::time_point, +// according to ADL rules for templates, only the inner most enclosing namespaces, +// and associated namespaces of the template arguments are added to search. In this +// case, only `std` namespace is searched. +// +// [1]: https://en.cppreference.com/w/cpp/language/adl +std::ostream& operator<<(std::ostream& os, cuspatial::test::time_point const& tp) +{ + // Output the time point in the desired format + os << tp.time_since_epoch().count() << "ms"; + return os; +} + +} // namespace std template struct DeriveTrajectoriesTest : public ::testing::Test {}; diff --git a/dependencies.yaml b/dependencies.yaml index f078c3716..86694ef13 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -54,8 +54,8 @@ dependencies: - &cmake_ver cmake>=3.23.1,!=3.25.0 - c-compiler - cxx-compiler - - gmock=1.10.0 - - gtest=1.10.0 + - gmock>=1.13.0 + - gtest>=1.13.0 - libcudf==23.6.* - librmm==23.6.* - ninja From 916b8ba0e700bf395b1bd2c8ec70c9259a19d2e0 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 9 May 2023 15:25:35 -0700 Subject: [PATCH 18/63] Add Legal Terms to Trajectory Clustering Notebook (#1111) This PR adds license terms to trajectory clustering notebook. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) - Mark Harris (https://github.com/harrism) - Ben Jarmak (https://github.com/jarmak-nv) URL: https://github.com/rapidsai/cuspatial/pull/1111 --- notebooks/trajectory_clustering.ipynb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/notebooks/trajectory_clustering.ipynb b/notebooks/trajectory_clustering.ipynb index 0e9e2f56f..654c5d1ef 100644 --- a/notebooks/trajectory_clustering.ipynb +++ b/notebooks/trajectory_clustering.ipynb @@ -45,12 +45,29 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Load preprocessed trajectories" ] }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The real-world trajectory dataset we used here for this example is collected from a traffic intersection located in Dubuque, Iowa.\n", + "We applied the following steps to extract vehicle trajectories from multiple cameras implemented at this intersection:\n", + "\n", + "- Detect vehicle locations in camera domain using AI based detectors\n", + "- Apply tracking algorithm to assign the same id to the same vehicle\n", + "- Project the vehicle location from camera domain to latitudes and longitudes\n", + "- Create trajectories based on vehicle id\n", + "\n", + "This dataset provided by NVIDIA is under the [Creative Commons 4.0 Attribution-ShareAlike 4.0 International license](https://creativecommons.org/licenses/by-sa/4.0/)." + ] + }, { "cell_type": "code", "execution_count": 2, @@ -81,6 +98,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -152,6 +170,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -187,6 +206,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -232,6 +252,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -280,6 +301,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -385,6 +407,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -457,6 +480,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -527,6 +551,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -598,6 +623,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ From 9a8540900b00b87cb2ce46da0c362948561c34f9 Mon Sep 17 00:00:00 2001 From: Ben Jarmak <104460670+jarmak-nv@users.noreply.github.com> Date: Tue, 9 May 2023 23:23:10 -0500 Subject: [PATCH 19/63] Delete add_issue_to_project.yml (#1129) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #1000 The built-in workflow has been working for over a month now. We can delete this action since it's no longer needed 🎉 Authors: - Ben Jarmak (https://github.com/jarmak-nv) - Mark Harris (https://github.com/harrism) Approvers: - Mark Harris (https://github.com/harrism) - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1129 --- .github/workflows/add_issue_to_project.yml | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 .github/workflows/add_issue_to_project.yml diff --git a/.github/workflows/add_issue_to_project.yml b/.github/workflows/add_issue_to_project.yml deleted file mode 100644 index c2962d78c..000000000 --- a/.github/workflows/add_issue_to_project.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Add new issue/PR to project - -on: - issues: - types: - - opened - - pull_request_target: - types: - - opened - -jobs: - add-to-project: - name: Add issue or PR to project - runs-on: ubuntu-latest - steps: - - uses: actions/add-to-project@v0.3.0 - with: - project-url: https://github.com/orgs/rapidsai/projects/41 - github-token: ${{ secrets.ADD_TO_PROJECT_GITHUB_TOKEN }} From 036c89786de1d5b3c85e86a8ca1a932119fd0f32 Mon Sep 17 00:00:00 2001 From: Ben Jarmak <104460670+jarmak-nv@users.noreply.github.com> Date: Thu, 11 May 2023 11:35:45 -0500 Subject: [PATCH 20/63] Make User Guide appear in Docs page header (#1133) closes #737 user_guide/index.md did not have a title, causing it to not show up as a link in the header of our docs. This PR adds the title, resolving the issue. Authors: - Ben Jarmak (https://github.com/jarmak-nv) Approvers: - Michael Wang (https://github.com/isVoid) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1133 --- docs/source/user_guide/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/user_guide/index.md b/docs/source/user_guide/index.md index 9473fd6ed..d9db7e6b7 100644 --- a/docs/source/user_guide/index.md +++ b/docs/source/user_guide/index.md @@ -1,3 +1,4 @@ +# User Guide ```{toctree} :maxdepth: 2 From 5829c497a91a24621fbae4979af9233654db55be Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 15 May 2023 13:19:02 -0700 Subject: [PATCH 21/63] Improve zipcode counting notebook by adding GPU backed WKT parser (#1130) This PR improves the zipcode counting notebook by utilizing cudf string and list column methods to parse WKT as geometry column. This achieves 40X speed up comparing to parsing on host. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - Ben Jarmak (https://github.com/jarmak-nv) URL: https://github.com/rapidsai/cuspatial/pull/1130 --- notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb | 208 +++++++++++++------ 1 file changed, 145 insertions(+), 63 deletions(-) diff --git a/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb b/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb index c47f47753..bd74e59a4 100644 --- a/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb +++ b/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb @@ -135,7 +135,7 @@ "metadata": {}, "outputs": [], "source": [ - "#Import CSV of Zipcodes\n", + "# Import CSV of ZipCodes\n", "d_zip = cudf.read_csv(\n", " path_of(\"USA_Zipcodes_2019_Tiger.csv\"),\n", " usecols=[\"WKT\", \"ZCTA5CE10\", \"INTPTLAT10\", \"INTPTLON10\"])\n", @@ -143,6 +143,15 @@ "d_zip.INTPTLON10 = d_zip.INTPTLON10.astype(\"float\")" ] }, + { + "cell_type": "markdown", + "id": "50b8d8bc-378f-4faa-b60c-e8f0ff507b2a", + "metadata": {}, + "source": [ + "The geometries are stored in [Well Known Text (WKT)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) format.\n", + "Parsing the geoseries to geometry objects on host is possible, but can be very slow (uncomment to run):" + ] + }, { "cell_type": "code", "execution_count": 6, @@ -150,18 +159,90 @@ "metadata": {}, "outputs": [], "source": [ - "# Load WKT as shapely objects\n", - "h_zip = d_zip.to_pandas()\n", - "h_zip[\"WKT\"] = h_zip[\"WKT\"].apply(wkt.loads)\n", - "h_zip = gpd.GeoDataFrame(h_zip, geometry=\"WKT\", crs='epsg:4326')\n", + "# %%time\n", + "# # Load WKT as shapely objects\n", + "# h_zip = d_zip.to_pandas()\n", + "# h_zip[\"WKT\"] = h_zip[\"WKT\"].apply(wkt.loads)\n", + "# h_zip = gpd.GeoDataFrame(h_zip, geometry=\"WKT\", crs='epsg:4326')\n", + "\n", + "# # Transfer back to GPU with cuSpatial\n", + "# d_zip = cuspatial.from_geopandas(h_zip)" + ] + }, + { + "cell_type": "markdown", + "id": "6fdaedfc-2d7f-4d73-a9b8-e3a8131bea2f", + "metadata": {}, + "source": [ + "Instead, we can use cudf list and string method to parse the wkt into coordinates and build a geoseries.\n", + "Without roundtripping to host, cudf provides ~40x speed up by computing on GPU. \n", "\n", - "# Transfer back to GPU with cuSpatial\n", - "d_zip = cuspatial.from_geopandas(h_zip)" + "Reference machine: Intel(R) Xeon(R) CPU E5-2698 v4 @ 2.20GHz v.s. NVIDIA Tesla V100 SXM2 32GB\n", + "\n", + "Caveats: geopandas also perform coordinate transform when loading WKT, since the dataset CRS is natively epsg:4326, loading on device can skip this step." ] }, { "cell_type": "code", "execution_count": 7, + "id": "fd3a5139-3b8b-4311-b966-7d2f08bff21f", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.5 s, sys: 890 ms, total: 2.39 s\n", + "Wall time: 2.37 s\n" + ] + } + ], + "source": [ + "%%time\n", + "def parse_multipolygon_WKT_cudf(wkts, dtype=\"f8\"):\n", + " def offsets_from_listlen(list_len):\n", + " return cudf.concat([cudf.Series([0]), list_len.cumsum()])\n", + " \n", + " def traverse(s, split_pat, regex=False):\n", + " \"\"\"Traverse one level lower into the geometry hierarchy,\n", + " using `split_pat` as the child delimiter.\n", + " \"\"\"\n", + " s = s.str.split(split_pat, regex=regex)\n", + " list_len = s.list.len()\n", + " return s.explode(), list_len\n", + " \n", + " wkts = (wkts.str.lstrip(\"MULTIPOLYGON \") \n", + " .str.strip(\"(\") \n", + " .str.strip(\")\"))\n", + " # split into list of polygons\n", + " wkts, num_polygons = traverse(wkts, \"\\)\\),\\s?\\(\\(\", regex=True)\n", + " # split polygons into rings\n", + " wkts, num_rings = traverse(wkts, \"\\),\\s?\\(\", regex=True)\n", + " # split coordinates into lists\n", + " wkts, num_coords = traverse(wkts, \",\", regex=True)\n", + " # split into x-y coordinates\n", + " wkts = wkts.str.split(\" \")\n", + " wkts = wkts.explode().astype(cp.dtype(dtype))\n", + " \n", + " # compute ring_offsets\n", + " ring_offsets = offsets_from_listlen(num_coords)\n", + " # compute part_offsets\n", + " part_offsets = offsets_from_listlen(num_rings)\n", + " # compute geometry_offsets\n", + " geometry_offsets = offsets_from_listlen(num_polygons)\n", + " \n", + " return cuspatial.GeoSeries.from_polygons_xy(\n", + " wkts, ring_offsets, part_offsets, geometry_offsets)\n", + "\n", + "d_wkt = parse_multipolygon_WKT_cudf(d_zip.WKT)\n", + "d_zip.WKT = d_wkt" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "id": "a13b228d-9a60-4f32-b548-fa6f4240e75e", "metadata": { "tags": [] @@ -175,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "33da801e-01a3-4c9f-bbba-0c61dc7677d9", "metadata": { "tags": [] @@ -330,7 +411,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "c0cadafb-acae-41d6-bbca-c10a8201699c", "metadata": { "tags": [] @@ -342,7 +423,7 @@ "text": [ "/raid/wangm/dev/rapids/cuspatial/python/cuspatial/cuspatial/core/spatial/indexing.py:174: UserWarning: scale -1 is less than required minimum scale 0.009837776664632286. Clamping to minimum scale\n", " warnings.warn(\n", - "/raid/wangm/dev/rapids/cuspatial/python/cuspatial/cuspatial/core/spatial/join.py:150: UserWarning: scale -1 is less than required minimum scale 0.009837776664632286. Clamping to minimum scale\n", + "/raid/wangm/dev/rapids/cuspatial/python/cuspatial/cuspatial/core/spatial/join.py:146: UserWarning: scale -1 is less than required minimum scale 0.009837776664632286. Clamping to minimum scale\n", " warnings.warn(\n" ] } @@ -365,7 +446,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "d2571a4a-a898-4e04-9fd2-21eb6b7a7f3e", "metadata": { "tags": [] @@ -377,7 +458,7 @@ "(1762, 33144)" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -406,7 +487,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "370ee37c-1311-4f54-9b0c-afd862c489aa", "metadata": { "tags": [] @@ -418,7 +499,7 @@ "text": [ "/raid/wangm/dev/rapids/cuspatial/python/cuspatial/cuspatial/core/spatial/indexing.py:174: UserWarning: scale -1 is less than required minimum scale 0.0029100948550503493. Clamping to minimum scale\n", " warnings.warn(\n", - "/raid/wangm/dev/rapids/cuspatial/python/cuspatial/cuspatial/core/spatial/join.py:150: UserWarning: scale -1 is less than required minimum scale 0.0029100948550503493. Clamping to minimum scale\n", + "/raid/wangm/dev/rapids/cuspatial/python/cuspatial/cuspatial/core/spatial/join.py:146: UserWarning: scale -1 is less than required minimum scale 0.0029100948550503493. Clamping to minimum scale\n", " warnings.warn(\n" ] } @@ -436,7 +517,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "5674f74a-9315-4e1f-ac0d-c45a1b97ae3e", "metadata": { "tags": [] @@ -471,33 +552,33 @@ " \n", " \n", " 0\n", - " -121.858094\n", - " 37.280787\n", - " 95136\n", + " -117.649068\n", + " 33.494571\n", + " 92675\n", " \n", " \n", " 1\n", - " -121.856648\n", - " 37.278295\n", - " 95136\n", + " -117.649226\n", + " 33.494498\n", + " 92675\n", " \n", " \n", " 2\n", - " -121.855441\n", - " 37.280375\n", - " 95136\n", + " -117.649102\n", + " 33.494483\n", + " 92675\n", " \n", " \n", " 3\n", - " -121.856343\n", - " 37.283195\n", - " 95136\n", + " -117.646427\n", + " 33.494877\n", + " 92675\n", " \n", " \n", " 4\n", - " -121.856604\n", - " 37.281005\n", - " 95136\n", + " -117.647351\n", + " 33.499920\n", + " 92675\n", " \n", " \n", "\n", @@ -505,15 +586,15 @@ ], "text/plain": [ " x y ZCTA5CE10\n", - "0 -121.858094 37.280787 95136\n", - "1 -121.856648 37.278295 95136\n", - "2 -121.855441 37.280375 95136\n", - "3 -121.856343 37.283195 95136\n", - "4 -121.856604 37.281005 95136\n", + "0 -117.649068 33.494571 92675\n", + "1 -117.649226 33.494498 92675\n", + "2 -117.649102 33.494483 92675\n", + "3 -117.646427 33.494877 92675\n", + "4 -117.647351 33.499920 92675\n", "(GPU)" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -534,7 +615,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "247d716c-4718-4aba-8d4f-5f816852194d", "metadata": { "tags": [] @@ -544,15 +625,15 @@ "data": { "text/plain": [ "ZCTA5CE10\n", - "94901 131\n", - "94535 205\n", - "95112 103\n", - "95407 126\n", - "93933 205\n", + "91107 13\n", + "91941 29\n", + "93730 17\n", + "94512 3\n", + "92553 43\n", "Name: stop_count, dtype: int32" ] }, - "execution_count": 13, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -565,7 +646,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "ccf31694-275d-4987-a318-79bc1ea79e73", "metadata": { "tags": [] @@ -599,18 +680,27 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, + "id": "2d3d09b1-d42c-471d-b197-d3d705b2b109", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# host_df = stop_counts_and_bounds.to_geopandas()\n", + "# host_df = host_df.rename({\"WKT\": \"geometry\"}, axis=1).set_geometry(\"geometry\")\n", + "# host_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "id": "6a9cb2d6-c7d3-4063-9b24-47101dba0044", "metadata": {}, "outputs": [], "source": [ "# # Visualize the Dataset\n", "\n", - "# # Move dataframe to host for visualization\n", - "# host_df = stop_counts_and_bounds.to_geopandas()\n", - "# host_df = host_df.rename({\"WKT\": \"geometry\"}, axis=1)\n", - "# host_df.head()\n", - "\n", "# # Geo Center of CA: 120°4.9'W 36°57.9'N\n", "# view_state = pdk.ViewState(\n", "# **{\"latitude\": 33.96500, \"longitude\": -118.08167, \"zoom\": 6, \"maxZoom\": 16, \"pitch\": 95, \"bearing\": 0}\n", @@ -618,20 +708,20 @@ "\n", "# gpd_layer = pdk.Layer(\n", "# \"GeoJsonLayer\",\n", - "# data=host_df[[\"geometry\", \"stop_count\", \"ZCTA5CE10\"]],\n", + "# data=host_df,\n", "# get_polygon=\"geometry\",\n", "# get_elevation=\"stop_count\",\n", "# extruded=True,\n", "# elevation_scale=50,\n", "# get_fill_color=[227,74,51],\n", "# get_line_color=[255, 255, 255],\n", - "# auto_highlight=True,\n", + "# auto_highlight=False,\n", "# filled=True,\n", "# wireframe=True,\n", "# pickable=True\n", "# )\n", "\n", - "# tooltip = {\"html\": \"Stop Sign Count: {stop_count}
    ZipCode: {ZCTA5CE10}\"}\n", + "# tooltip = {\"html\": \"Stop Sign Count: {stop_count}
    ZipCode: {ZCTA5CE10}\"}\n", "\n", "# r = pdk.Deck(\n", "# gpd_layer,\n", @@ -640,7 +730,7 @@ "# tooltip=tooltip,\n", "# )\n", "\n", - "# r.to_html(\"geopandas_layer.html\", notebook_display=False)" + "# r.to_html(\"geopandas_layer.html\", notebook_display=True)" ] }, { @@ -652,14 +742,6 @@ "\n", "![stop_per_state_map](https://github.com/isVoid/cuspatial/raw/notebook/zipcode_counting/notebooks/stop_states.png)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b7611be2-6dbe-40a5-ae9e-51283737d3f2", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -678,7 +760,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.10.10" } }, "nbformat": 4, From d7bb3fbe731d36111cfcaeaee55dd908df9eec18 Mon Sep 17 00:00:00 2001 From: "H. Thomson Comer" Date: Mon, 15 May 2023 16:19:14 -0500 Subject: [PATCH 22/63] Add GTC 2023 Reverse GeoCoding Demo Notebook (#1001) Closes #883 This PR includes the notebook demoed at GTC 2023 and updates `notebooks/README.md` Authors: - H. Thomson Comer (https://github.com/thomcom) - Ben Jarmak (https://github.com/jarmak-nv) - Mark Harris (https://github.com/harrism) Approvers: - Mark Harris (https://github.com/harrism) - Michael Wang (https://github.com/isVoid) - Ben Jarmak (https://github.com/jarmak-nv) URL: https://github.com/rapidsai/cuspatial/pull/1001 --- notebooks/README.md | 3 + .../Taxi_Dropoff_Reverse_Geocoding.ipynb | 544 ++++++++++++++++++ 2 files changed, 547 insertions(+) create mode 100644 notebooks/Taxi_Dropoff_Reverse_Geocoding.ipynb diff --git a/notebooks/README.md b/notebooks/README.md index d0c2f430c..daf20b44a 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -15,6 +15,9 @@ Notebook Title | Data set(s) | Notebook Description | External Download (Size) --- | --- | --- | --- [NYC Taxi Years Correlation](nyc_taxi_years_correlation.ipynb) | [NYC Taxi Yellow 01/2016, 01/2017, taxi zone data](https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page) | Demonstrates using Point in Polygon to correlate the NYC Taxi datasets pre-2017 `lat/lon` locations with the post-2017 `LocationID` for cross format comparisons. | Yes (~3GB) [Stop Sign Counting By Zipcode Boundary](ZipCodes_Stops_PiP_cuSpatial.ipynb) | [Stop Sign Locations](https://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop) [Zipcode Boundaries](https://catalog.data.gov/dataset/tiger-line-shapefile-2019-2010-nation-u-s-2010-census-5-digit-zip-code-tabulation-area-zcta5-na) [USA States Boundaries](https://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative) | Demonstrates Quadtree Point-in-Polygon to categorize stop signs by zipcode boundaries. | Yes (~1GB) +[Taxi Dropoff Reverse Geocoding (GTC 2023)](Taxi_Dropoff_Reverse_Geocoding.ipynb) | [National Address Database](https://nationaladdressdata.s3.amazonaws.com/NAD_r12_TXT.zip) [NYC Taxi Zones](https://d37ci6vzurychx.cloudfront.net/misc/taxi_zones.zip) [taxi2015.csv](https://rapidsai-data.s3.us-east-2.amazonaws.com/viz-data/nyc_taxi.tar.gz) | Reverse Geocoding of 22GB of datasets in NYC delivered for GTC 2023 | Yes (~22GB) + +*Each user is responsible for checking the content of datasets and the applicable licenses and determining if suitable for the intended use.* ## For more details Many more examples can be found in the [RAPIDS Notebooks diff --git a/notebooks/Taxi_Dropoff_Reverse_Geocoding.ipynb b/notebooks/Taxi_Dropoff_Reverse_Geocoding.ipynb new file mode 100644 index 000000000..451928a63 --- /dev/null +++ b/notebooks/Taxi_Dropoff_Reverse_Geocoding.ipynb @@ -0,0 +1,544 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "6e155f6c-ada2-4a48-a967-84aa1f0ef011", + "metadata": { + "tags": [] + }, + "source": [ + "# cuSpatial API Demo - Reverse Geocoding\n", + "GTC April 2023 Michael Wang and Thomson Comer\n", + "\n", + "Demo System: Intel Xeon Gold 3.4Ghz, 48GB RAM, 32GB GV100 GPU\n", + "\n", + "The following notebook demonstrates the use of cuSpatial to perform analytics using large datasets.\n", + "\n", + "The structure of the notebook is as follows:\n", + "1. Imports\n", + "1. Read datasets: National Address Database (NAD), NYC Taxi Zones Polygons, 2015 NYC Taxi pickup/dropoff information with lon/lat. Also convert epsg:2263 (NYC Long Island) to WGS.\n", + "1. Convert separate lon/lat columns in DataFrames into cuspatial.GeoSeries\n", + "1. Compute number of addresses and pickups in each zone\n", + "1. Compute addresses for each pickup in one zone\n", + "\n", + "## Data\n", + "\n", + "- [National Address Database Usage Disclaimer](https://www.transportation.gov/mission/open/gis/national-address-database/national-address-database-nad-disclaimer)\n", + " - [National Address Database](https://nationaladdressdata.s3.amazonaws.com/NAD_r12_TXT.zip)\n", + "- [NYC Data Usage Policy](https://www.nyc.gov/home/terms-of-use.page)\n", + " - [NYC Taxi Zones](https://d37ci6vzurychx.cloudfront.net/misc/taxi_zones.zip)\n", + " - [taxi2015.csv](https://rapidsai-data.s3.us-east-2.amazonaws.com/viz-data/nyc_taxi.tar.gz)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "dc3c05f8-ba7a-44de-9f94-c6bc1b3cf17c", + "metadata": { + "slideshow": { + "slide_type": "skip" + }, + "source_hidden": true, + "tags": [] + }, + "source": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + "
    \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    \n", + "\n", + "I/O\n", + " \n", + "- National Address Database (NAD): \n", + "- NYC Taxi Zones Shapefile (zones)\n", + "- NYC 2015 Taxi Pickups and Dropoffs with Lon/Lat Coords (taxi2015)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77a16fd2-9ae1-4725-bf0a-97b9ecd9dc18", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%time\n", + "import cudf\n", + "import cuspatial\n", + "import geopandas\n", + "import numpy as np\n", + "\n", + "from shapely.geometry import Polygon\n", + "\n", + "cudf.set_option(\"spill\", True) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "393edadb-fc55-4bb6-a16c-b8ba40817324", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# I/O (18GB NAD, 265 borough polygons, 13m taxi pickups and dropoffs.\n", + "try:\n", + " NAD = cudf.read_csv('NAD_r11.txt', usecols=[\n", + " 'State',\n", + " 'Longitude',\n", + " 'Latitude',\n", + " ])\n", + " NAD = NAD[NAD['State'] == 'NY']\n", + " NAD_Street = cudf.read_csv('NAD_r11.txt', usecols=[\n", + " 'State',\n", + " 'StN_PreDir',\n", + " 'StreetName',\n", + " 'StN_PosTyp',\n", + " 'Add_Number',\n", + " ])\n", + " NAD_Street = NAD_Street[NAD_Street['State'] == 'NY']\n", + "\n", + " # Read taxi_zones.zip shapefile with GeoPandas, then convert to epsg:4326 for lon/lat\n", + " host_zones = geopandas.read_file('taxi_zones.zip')\n", + " host_lonlat = host_zones.to_crs(epsg=4326)\n", + " zones = cuspatial.from_geopandas(host_lonlat)\n", + "\n", + " zones.set_index(zones['OBJECTID'], inplace=True)\n", + " taxi2015 = cudf.read_csv('taxi2015.csv')\n", + "\n", + "except FileNotFoundError:\n", + " # If you don't want to download 22GB of data but want to get a handle on cuSpatial\n", + " # This section generates synthetic data in the NYC area, only the coordinates are randomized\n", + " # All other values are 'a'\n", + " print(\"DATA NOT FOUND - generating synthetic data\")\n", + "\n", + " xmin, ymin, xmax, ymax = -74.15, 40.5774, -73.7004, 40.9176\n", + "\n", + " NAD_Street = cudf.DataFrame([['a', 'a', 'a', 'a', 'a']for i in range(1000)],\n", + " columns=['State', 'StN_PreDir', 'StreetName', 'StN_PosTyp', 'Add_Number'])\n", + " NAD = cudf.DataFrame({'Longitude': np.random.uniform(xmin, xmax, size=10000), \n", + " 'Latitude': np.random.uniform(ymin, ymax, size=10000)})\n", + "\n", + " zones = [Polygon(np.column_stack((np.random.uniform(xmin, xmax, size=10),\n", + " np.random.uniform(ymin, ymax, size=10)))) for i in range(31)]\n", + " zones = cuspatial.from_geopandas(geopandas.GeoDataFrame({'geometry': zones, 'label': 'a'}))\n", + " \n", + " \n", + " taxi2015 = cudf.DataFrame({'pickup_longitude': np.random.uniform(xmin, xmax, size=100000), \n", + " 'pickup_latitude': np.random.uniform(ymin, ymax, size=100000),\n", + " 'tpep_pickup_datetime': 'a',\n", + " 'passenger_count': 'a',\n", + " 'trip_distance': 'a',\n", + " 'distance': 'a',\n", + " 'fare_amount': 'a',\n", + " 'tip_amount': 'a',\n", + " 'pickup_address': 'a'})\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "d889dfd1-a7a6-4fb0-8e26-a2e0eafc474f", + "metadata": {}, + "source": [ + "
    \n", + "
    \n", + "
    Input coordinates are stored as separate columns named \"Lon\" and \"Lat\"
    \n", + "
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da697bb0-d405-4c0e-8030-4b2b099ab863", + "metadata": {}, + "outputs": [], + "source": [ + "# Convert DataFrames to GeoSeries\n", + "\n", + "pickups = cuspatial.GeoSeries.from_points_xy(\n", + " cudf.DataFrame({\n", + " 'x': taxi2015['pickup_longitude'],\n", + " 'y': taxi2015['pickup_latitude'],\n", + " }).interleave_columns()\n", + ")\n", + "addresses = cuspatial.GeoSeries.from_points_xy(\n", + " cudf.DataFrame({\n", + " 'x': NAD['Longitude'],\n", + " 'y': NAD['Latitude'],\n", + " }).interleave_columns()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "97a423bb-7058-42bc-b8d9-d6af1cd16edd", + "metadata": {}, + "outputs": [], + "source": [ + "zone_addresses = zones['geometry'].contains_properly(addresses, allpairs=True)\n", + "display(zone_addresses)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eb654b04-86d8-4a5f-9b61-78894457d00b", + "metadata": {}, + "outputs": [], + "source": [ + "zone_pickups = zones['geometry'].iloc[0:120].contains_properly(pickups, allpairs=True)\n", + "display(zone_pickups)\n", + "\n", + "# You can do it one of two ways: .contains_properly, or write the pip yourself." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "896a796f-a80c-42a4-a6d4-c106b17e613f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Add pickup and address counts to zones dataframe\n", + "\n", + "zones[\"pickup_count\"] = zone_pickups.groupby('polygon_index').count()\n", + "zones[\"address_count\"] = zone_addresses.groupby('polygon_index').count()\n", + "zones.head(12)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "290d231a-2648-4ab1-9d33-97deecca689b", + "metadata": {}, + "source": [ + "# Computing distances\n", + "## Cartesian product via tiling\n", + "\n", + "
    \n", + "
    \n", + "
    Visualizing the cartesian product tiling process
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "559fc631-35d1-456c-af31-c8e89bc23789", + "metadata": {}, + "outputs": [], + "source": [ + "NEIGHBORHOOD_ID = 12\n", + "\n", + "# Let's make two GeoSeries: For each zone, create a GeoSeries with all address Points\n", + "# repeated the number of times there are pickups in that zone, and another GeoSeries with\n", + "# the opposite: all pickups Points repeated the number of times there are addresses in that\n", + "# zone.\n", + "\n", + "# addresses tiled\n", + "zone_address_point_ids = zone_addresses['point_index'][zone_addresses['polygon_index'] == NEIGHBORHOOD_ID]\n", + "pickups_count = len(zone_pickups[zone_pickups['polygon_index'] == NEIGHBORHOOD_ID])\n", + "addresses_tiled = NAD.iloc[\n", + " zone_address_point_ids\n", + "].tile(pickups_count)\n", + "\n", + "# pickups tiled\n", + "zone_pickup_point_ids = zone_pickups['point_index'][zone_pickups['polygon_index'] == NEIGHBORHOOD_ID]\n", + "addresses_count = len(zone_addresses[zone_addresses['polygon_index'] == NEIGHBORHOOD_ID])\n", + "pickups_tiled = taxi2015[[\n", + " 'pickup_longitude',\n", + " 'pickup_latitude'\n", + "]].iloc[\n", + " zone_pickup_point_ids\n", + "].tile(addresses_count)\n", + "\n", + "pickup_points = cuspatial.GeoSeries.from_points_xy(\n", + " cudf.DataFrame({\n", + " 'x': pickups_tiled['pickup_longitude'],\n", + " 'y': pickups_tiled['pickup_latitude'] \n", + " }).interleave_columns()\n", + ")\n", + "address_points = cuspatial.GeoSeries.from_points_xy(\n", + " cudf.DataFrame({\n", + " 'x': addresses_tiled['Longitude'],\n", + " 'y': addresses_tiled['Latitude']\n", + " }).interleave_columns()\n", + ")\n", + "len(address_points)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "dcba649c-4adf-42ab-bc0a-2c2ebe8fa7d5", + "metadata": {}, + "source": [ + "
    \n", + "
    \n", + "
    Visualizing the combinations of distance calculations created by the cartesian product tiling.
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27e5f68c-ad66-428d-8cd6-6e1268d5e884", + "metadata": {}, + "outputs": [], + "source": [ + "# get the list of addresses and their indices that are closest to a pickup point\n", + "\n", + "haversines = cuspatial.haversine_distance(pickup_points, address_points)\n", + "\n", + "gb_df = cudf.DataFrame({\n", + " 'address': addresses_tiled.index,\n", + " 'pickup': pickups_tiled.index,\n", + " 'distance': haversines\n", + "})\n", + "\n", + "address_indices_of_nearest = gb_df[['address', 'distance']].groupby('address').idxmin()\n", + "pickup_indices_of_nearest = gb_df[['pickup', 'distance']].groupby('pickup').idxmin()\n", + "address_nearest_pickups = gb_df.loc[address_indices_of_nearest['distance']]\n", + "pickups_nearest_address = gb_df.loc[pickup_indices_of_nearest['distance']]" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "4b70ac6f-98ef-4df7-8f15-c0bb98934758", + "metadata": {}, + "source": [ + "# We have almost everything we need to perform reverse geocoding\n", + "\n", + "#### With the index of the addresses and their pickups, we now need to make the addresses readable by a human" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7abd09dd-8207-4550-88bb-0ccbd32c4055", + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [], + "source": [ + "# Original data nearest pickups and addresses\n", + "\n", + "nearest_pickups = taxi2015.iloc[pickups_nearest_address['pickup']]\n", + "nearest_addresses_lonlat = NAD.loc[pickups_nearest_address['address']]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94d52460-d36a-4cbc-bf5a-f1be82b89eea", + "metadata": {}, + "outputs": [], + "source": [ + "# Concatenate address fields\n", + "\n", + "def build_address_string(NAD_Street):\n", + " blanks = cudf.Series([' '] * len(NAD_Street))\n", + " blanks.index = NAD_Street.index\n", + " NAD_Street['StN_PreDir'] = NAD_Street['StN_PreDir'].fillna('')\n", + " NAD_Street['StN_PosTyp'] = NAD_Street['StN_PosTyp'].fillna('')\n", + " street_names = NAD_Street['Add_Number'].astype('str').str.cat(\n", + " blanks\n", + " ).str.cat(\n", + " NAD_Street['StN_PreDir']\n", + " ).str.cat(\n", + " blanks\n", + " ).str.cat(\n", + " NAD_Street['StreetName']\n", + " ).str.cat(\n", + " blanks\n", + " ).str.cat(\n", + " NAD_Street['StN_PosTyp']\n", + " )\n", + " return street_names.str.replace(' ', ' ')\n", + "\n", + "nearest_addresses_street_name = NAD_Street.loc[pickups_nearest_address['address']]\n", + "street_names = build_address_string(nearest_addresses_street_name)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "434321bd-78f4-4547-acb2-8977e271beb0", + "metadata": { + "tags": [] + }, + "source": [ + "# Last Step: attaching the street names to the original pickups dataframe\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "070bc274-1642-49d5-903b-ee4baabe8a22", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# save the taxi2015 index\n", + "no_index = nearest_pickups.reset_index()\n", + "# set taxi2015 street names and distances based on their iloc positions\n", + "no_index['pickup_address'] = street_names.reset_index(drop=True)\n", + "no_index['distance'] = pickups_nearest_address['distance'].reset_index(drop=True)\n", + "# return the index\n", + "taxi_pickups_with_address = no_index.set_index(no_index['index'])\n", + "taxi_pickups_with_address.drop('index', inplace=True, axis=1)\n", + "\n", + "display(taxi_pickups_with_address[[\n", + " 'tpep_pickup_datetime',\n", + " 'passenger_count',\n", + " 'trip_distance',\n", + " 'distance',\n", + " 'pickup_longitude',\n", + " 'pickup_latitude',\n", + " 'fare_amount',\n", + " 'tip_amount',\n", + " 'pickup_address'\n", + "]])\n", + "display(taxi_pickups_with_address[[\n", + " 'pickup_latitude',\n", + " 'pickup_longitude',\n", + " 'pickup_address',\n", + " 'distance'\n", + "]].sort_values('distance'))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "88b7dead-84e6-49c3-b33d-5ee1076d6d60", + "metadata": {}, + "source": [ + "# Use cuXfilter to display these coordinates\n", + "#### Uncomment the cells below to run visualization" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18d67ad6-861e-42f8-a2b1-3277cb6cf0f2", + "metadata": {}, + "outputs": [], + "source": [ + "# import cuxfilter\n", + "# from bokeh import palettes\n", + "# from cuxfilter.layouts import feature_and_double_base\n", + "# import cupy as cp\n", + "\n", + "# from pyproj import Proj, Transformer\n", + "\n", + "# display_pickups = taxi2015.iloc[address_nearest_pickups['pickup']]\n", + "# display_addresses = NAD.loc[address_nearest_pickups['address']]\n", + "\n", + "# combined_pickups_and_addresses = cudf.concat([\n", + "# display_pickups[['pickup_longitude', 'pickup_latitude']].rename(\n", + "# columns={\n", + "# 'pickup_longitude': 'Longitude',\n", + "# 'pickup_latitude': 'Latitude'\n", + "# }\n", + "# ),\n", + "# display_addresses[['Longitude', 'Latitude']]], axis=0\n", + "# )\n", + "# combined_pickups_and_addresses['color'] = cp.repeat(cp.array([1, 2]), len(\n", + "# combined_pickups_and_addresses\n", + "# )//2)\n", + "# # Back to NYC CRS for display\n", + "# transform_4326_to_3857 = Transformer.from_crs('epsg:4326', 'epsg:3857')\n", + "# combined_pickups_and_addresses['location_x'], combined_pickups_and_addresses['location_y'] = transform_4326_to_3857.transform(\n", + "# combined_pickups_and_addresses['Latitude'].values_host, combined_pickups_and_addresses['Longitude'].values_host\n", + "# )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a7242e4-973d-412f-aa58-cf295c07bbbf", + "metadata": {}, + "outputs": [], + "source": [ + "# cux_df = cuxfilter.DataFrame.from_dataframe(combined_pickups_and_addresses)\n", + "# chart1 = cuxfilter.charts.scatter(\n", + "# title=\"Matched address pickup pairs\",\n", + "# x='location_x',\n", + "# y='location_y',\n", + "# color_palette=[\"Green\", \"Red\"],\n", + "# aggregate_col=\"color\", aggregate_fn=\"mean\",\n", + "# unselected_alpha=0.0,\n", + "# tile_provider=\"CartoLight\", x_range=(-8239910.23,-8229529.24), y_range=(4968481.34,4983152.92),\n", + "# )\n", + "# d = cux_df.dashboard([chart1], theme=cuxfilter.themes.dark, title= 'NYC TAXI DATASSET')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2623c6ee-ce00-4e51-862a-afc72c31a50c", + "metadata": {}, + "outputs": [], + "source": [ + "# chart1.view()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "daa2558d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.8.16" + }, + "trusted": true + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c6ecbc028918f8d14af1c479ea888924379378ee Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 16 May 2023 08:59:06 -0700 Subject: [PATCH 23/63] Refactor ST_Distance Column API and Cython (#1124) This PR makes all ST_Distance API conforms to a homogenous API format and documentation. This also greatly simplifies the implementation of each of the column APIs. Closes #1123 This PR also introduces several `GeometryColumnFixtures` that manages the life time of a few commonly used geometry columns and use them across the tests of these APIs. Supersedes #1104 This PR also fixes several bugs in the computation kernels when the input is empty. Authors: - Michael Wang (https://github.com/isVoid) - Mark Harris (https://github.com/harrism) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1124 --- .../detail/distance/linestring_distance.cuh | 2 + .../detail/distance/point_distance.cuh | 2 + cpp/include/cuspatial/distance.hpp | 243 +++++------------- cpp/include/cuspatial_test/base_fixture.hpp | 2 +- .../cuspatial_test/geometry_fixtures.hpp | 199 ++++++++++++++ cpp/src/distance/linestring_distance.cu | 147 ++++------- .../distance/linestring_polygon_distance.cu | 18 +- cpp/src/distance/point_distance.cu | 113 +++----- cpp/src/distance/point_linestring_distance.cu | 145 ++++------- cpp/src/distance/point_polygon_distance.cu | 1 - cpp/src/distance/polygon_distance.cu | 18 +- .../intersection/linestring_intersection.cu | 1 - .../distance/linestring_distance_test.cpp | 243 +++--------------- .../linestring_polygon_distance_test.cpp | 97 ++----- cpp/tests/distance/point_distance_test.cpp | 111 +++----- .../point_linestring_distance_test.cpp | 110 ++++---- .../cuspatial/cuspatial/_lib/CMakeLists.txt | 3 +- .../cuspatial/cuspatial/_lib/cpp/distance.pxd | 59 +++++ .../cuspatial/_lib/cpp/distance/__init__.pxd | 0 .../cuspatial/_lib/cpp/distance/__init__.pyx | 0 .../cuspatial/_lib/cpp/distance/hausdorff.pxd | 18 -- .../cuspatial/_lib/cpp/distance/haversine.pxd | 15 -- .../_lib/cpp/distance/linestring_distance.pxd | 21 -- .../distance/linestring_polygon_distance.pxd | 17 -- .../_lib/cpp/distance/point_distance.pxd | 20 -- .../distance/point_linestring_distance.pxd | 21 -- .../cpp/distance/point_polygon_distance.pxd | 17 -- python/cuspatial/cuspatial/_lib/distance.pyx | 177 ++++++++----- python/cuspatial/cuspatial/_lib/hausdorff.pyx | 40 --- python/cuspatial/cuspatial/_lib/spatial.pyx | 17 -- .../cuspatial/core/spatial/distance.py | 98 +++---- 31 files changed, 763 insertions(+), 1212 deletions(-) create mode 100644 cpp/include/cuspatial_test/geometry_fixtures.hpp create mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/__init__.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/__init__.pyx delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd delete mode 100644 python/cuspatial/cuspatial/_lib/hausdorff.pyx diff --git a/cpp/include/cuspatial/detail/distance/linestring_distance.cuh b/cpp/include/cuspatial/detail/distance/linestring_distance.cuh index 09bb66cb3..19e70b51b 100644 --- a/cpp/include/cuspatial/detail/distance/linestring_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/linestring_distance.cuh @@ -51,6 +51,8 @@ OutputIt pairwise_linestring_distance(MultiLinestringRange1 multilinestrings1, CUSPATIAL_EXPECTS(multilinestrings1.size() == multilinestrings2.size(), "Inputs must have the same number of rows."); + if (multilinestrings1.size() == 0) return distances_first; + thrust::fill(rmm::exec_policy(stream), distances_first, distances_first + multilinestrings1.size(), diff --git a/cpp/include/cuspatial/detail/distance/point_distance.cuh b/cpp/include/cuspatial/detail/distance/point_distance.cuh index 72cd4634b..64c269b9c 100644 --- a/cpp/include/cuspatial/detail/distance/point_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/point_distance.cuh @@ -49,6 +49,8 @@ OutputIt pairwise_point_distance(MultiPointArrayViewA multipoints1, CUSPATIAL_EXPECTS(multipoints1.size() == multipoints2.size(), "Inputs should have the same number of multipoints."); + if (multipoints1.size() == 0) return distances_first; + return thrust::transform(rmm::exec_policy(stream), multipoints1.multipoint_begin(), multipoints1.multipoint_end(), diff --git a/cpp/include/cuspatial/distance.hpp b/cpp/include/cuspatial/distance.hpp index d67c533df..11cec4fae 100644 --- a/cpp/include/cuspatial/distance.hpp +++ b/cpp/include/cuspatial/distance.hpp @@ -129,116 +129,62 @@ std::pair, cudf::table_view> directed_hausdorff_di /** * @brief Compute pairwise (multi)point-to-(multi)point Cartesian distance * - * Computes the cartesian distance between each pair of the multipoints. If input is - * a single point column, the offset of the column should be std::nullopt. + * The distance between a pair of multipoints is the shortest Cartesian distance + * between any pair of points in the two multipoints. * - * @param points1_xy Column of xy-coordinates of the first point in each pair - * @param multipoints1_offset Index to the first point of each multipoint in points1_xy - * @param points2_xy Column of xy-coordinates of the second point in each pair - * @param multipoints2_offset Index to the second point of each multipoint in points2_xy + * @param points1 First column of (multi)points to compute distances + * @param points2 Second column of (multi)points to compute distances * @return Column of distances between each pair of input points + * + * @throw cuspatial::logic_error if `multipoints1` and `multipoints2` sizes differ + * @throw cuspatial::logic_error if either `multipoints1` or `multipoints2` is not a multipoint + * column + * @throw cuspatial::logic_error if `multipoints1` and `multipoints2` coordinate types differ */ - std::unique_ptr pairwise_point_distance( - std::optional> multipoints1_offset, - cudf::column_view const& points1_xy, - std::optional> multipoints2_offset, - cudf::column_view const& points2_xy, + geometry_column_view const& multipoints1, + geometry_column_view const& multipoints2, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); /** - * @brief Compute distance between pairs of points and linestrings - * - * The distance between a point and a linestring is defined as the minimum distance - * between the point and any segment of the linestring. For each input point, this - * function returns the distance between the point and the corresponding linestring. - * - * The following example contains 2 pairs of points and linestrings. - * ``` - * First pair: - * Point: (0, 0) - * Linestring: (0, 1) -> (1, 0) -> (2, 0) - * - * Second pair: - * Point: (1, 1) - * Linestring: (0, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> (3, 1) - * - * The input of the above example is: - * multipoint_geometry_offsets: nullopt - * points_xy: {0, 1, 0, 1} - * multilinestring_geometry_offsets: nullopt - * linestring_part_offsets: {0, 3, 8} - * linestring_xy: {0, 1, 1, 0, 2, 0, 0, 0, 1, 1, 2, 0, 3, 0, 3, 1} - * - * Result: {sqrt(2)/2, 0} - * ``` + * @brief Compute pairwise (multi)points-to-(multi)linestrings Cartesian distance * - * The following example contains 3 pairs of MultiPoint and MultiLinestring. - * ``` - * First pair: - * MultiPoint: (0, 1) - * MultiLinestring: (0, -1) -> (-2, -3), (-4, -5) -> (-5, -6) - * - * Second pair: - * MultiPoint: (2, 3), (4, 5) - * MultiLinestring: (7, 8) -> (8, 9) - * - * Third pair: - * MultiPoint: (6, 7), (8, 9) - * MultiLinestring: (9, 10) -> (10, 11) - - * The input of the above example is: - * multipoint_geometry_offsets: {0, 1, 3, 5} - * points_xy: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - * multilinestring_geometry_offsets: {0, 2, 3, 5} - * linestring_part_offsets: {0, 2, 4, 6, 8} - * linestring_points_xy: {0, -1, -2, -3, -4, -5, -5, -6, 7, 8, 8, 9, 9, 10, 10 ,11} - * - * Result: {2.0, 4.24264, 1.41421} - * ``` + * The distance between a point and a linestring is defined as the minimum Cartesian distance + * between the point and any segment of the linestring. * - * @param multipoint_geometry_offsets Beginning and ending indices to each geometry in the - * multi-point - * @param points_xy Interleaved x, y-coordinates of points - * @param multilinestring_geometry_offsets Beginning and ending indices to each geometry in the - * multi-linestring - * @param linestring_part_offsets Beginning and ending indices for each linestring in the point - * array. Because the coordinates are interleaved, the actual starting position for the coordinate - * of linestring `i` is `2*linestring_part_offsets[i]`. - * @param linestring_points_xy Interleaved x, y-coordinates of linestring points. + * @param multipoints Column of multipoints to compute distances + * @param multilinestrings Column of multilinestrings to compute distances * @param mr Device memory resource used to allocate the returned column. - * @return A column containing the distance between each pair of corresponding points and - * linestrings. + * @return A column containing the distance between each pair of input (multi)points and + * (multi)linestrings * - * @note Any optional geometry indices, if is `nullopt`, implies the underlying geometry contains - * only one component. Otherwise, it contains multiple components. - * - * @throws cuspatial::logic_error if the number of (multi)points and (multi)linestrings do not - * match. - * @throws cuspatial::logic_error if the any of the point arrays have mismatched types. + * @throw cuspatial::logic_error if `multipoints` and `multilinestrings` sizes differ + * @throw cuspatial::logic_error if `multipoints` is not a multipoints column or `multilinestrings` + * is not a multilinestrings column + * @throw cuspatial::logic_error if `multipoints` and `multilinestrings` coordinate types differ */ std::unique_ptr pairwise_point_linestring_distance( - std::optional> multipoint_geometry_offsets, - cudf::column_view const& points_xy, - std::optional> multilinestring_geometry_offsets, - cudf::device_span linestring_part_offsets, - cudf::column_view const& linestring_points_xy, + geometry_column_view const& multipoints, + geometry_column_view const& multilinestrings, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); /** * @brief Compute pairwise (multi)point-to-(multi)polygon Cartesian distance * + * The distance between a point and a polygon is defined as the minimum Cartesian distance between + * the point and any segment of the polygon. If the any point of the multipoint is contained in the + * polygon, the distance is 0. + * * @param multipoints Geometry column of multipoints * @param multipolygons Geometry column of multipolygons * @param mr Device memory resource used to allocate the returned column. - * @return Column of distances between each pair of input geometries, same type as input coordinate - * types. + * @return A column containing the distance between each pair of input (multi)points and + * (multi)polygons * - * @throw cuspatial::logic_error if `multipoints` and `multipolygons` has different coordinate - * types. + * @throw cuspatial::logic_error if `multipoints` and `multipolygons` sizes differ * @throw cuspatial::logic_error if `multipoints` is not a point column and `multipolygons` is not a * polygon column. - * @throw cuspatial::logic_error if input column sizes mismatch. + * @throw cuspatial::logic_error if `multipoints` and `multipolygons` coordinate types differ */ std::unique_ptr pairwise_point_polygon_distance( @@ -247,116 +193,47 @@ std::unique_ptr pairwise_point_polygon_distance( rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); /** - * @brief Compute shortest distance between pairs of linestrings - * - * The shortest distance between two linestrings is defined as the shortest distance - * between all pairs of segments of the two linestrings. If any of the segments intersect, - * the distance is 0. The shortest distance between two multilinestrings is defined as the - * the shortest distance between all pairs of linestrings of the two multilinestrings. - * - * The following example contains 4 pairs of linestrings. The first array is a single linestring - * array and the second array is a multilinestring array. - * ``` - * First pair: - * (0, 1) -> (1, 0) -> (-1, 0) - * {(1, 1) -> (2, 1) -> (2, 0) -> (3, 0)} + * @brief Compute pairwise (multi)linestring-to-(multi)linestring Cartesian distance * - * | - * * #---# - * | \ | - * ----O---*---#---# - * | / - * * - * | + * The distance between a pair of multilinestrings is the shortest Cartesian distance + * between any pair of segments in the two multilinestrings. If any of the segments intersects, + * the distance is 0. * - * The shortest distance between the two linestrings is the distance - * from point (1, 1) to segment (0, 1) -> (1, 0), which is sqrt(2)/2. - * - * Second pair: - * - * (0, 0) -> (0, 1) - * {(1, 0) -> (1, 1) -> (1, 2), (1, -1) -> (1, -2) -> (1, -3)} - * - * The linestrings in the pairs are parallel. Their distance is 1 (point (0, 0) to point (1, 0)). - * - * Third pair: - * - * (0, 0) -> (2, 2) -> (-2, 0) - * {(2, 0) -> (0, 2), (0, 2) -> (-2, 0)} - * - * The linestrings in the pairs intersect, so their distance is 0. - * - * Forth pair: - * - * (2, 2) -> (-2, -2) - * {(1, 1) -> (5, 5) -> (10, 0), (-1, -1) -> (-5, -5) -> (-10, 0)} - * - * These linestrings contain colinear and overlapping sections, so - * their distance is 0. - * - * The input of above example is: - * multilinestring1_geometry_offsets: nullopt - * linestring1_part_offsets: {0, 3, 5, 8, 10} - * linestring1_points_xy: - * {0, 1, 1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 2, 2, -2, 0, 2, 2, -2, -2} - * - * multilinestring2_geometry_offsets: {0, 1, 3, 5, 7} - * linestring2_offsets: {0, 4, 7, 10, 12, 14, 17, 20} - * linestring2_points_xy: {1, 1, 2, 1, 2, 0, 3, 0, 1, 0, 1, 1, 1, 2, 1, -1, 1, -2, 1, -3, 2, 0, 0, - * 2, 0, 2, -2, 0, 1, 1, 5, 5, 10, 0, -1, -1, -5, -5, -10, 0} - * - * Result: {sqrt(2.0)/2, 1, 0, 0} - * ``` - * - * @param multilinestring1_geometry_offsets Beginning and ending indices to each multilinestring in - * the first multilinestring array. - * @param linestring1_part_offsets Beginning and ending indices for each linestring in the point - * array. Because the coordinates are interleaved, the actual starting position for the coordinate - * of linestring `i` is `2*linestring_part_offsets[i]`. - * @param linestring1_points_xy Interleaved x, y-coordinates of linestring points. - * @param multilinestring2_geometry_offsets Beginning and ending indices to each multilinestring in - * the second multilinestring array. - * @param linestring2_part_offsets Beginning and ending indices for each linestring in the point - * array. Because the coordinates are interleaved, the actual starting position for the coordinate - * of linestring `i` is `2*linestring_part_offsets[i]`. - * @param linestring2_points_xy Interleaved x, y-coordinates of linestring points. + * @param multilinestrings1 First column of multilinestrings to compute distances + * @param multilinestrings2 Second column of multilinestrings to compute distances * @param mr Device memory resource used to allocate the returned column's device memory - * @return A column of shortest distances between each pair of (multi)linestrings - * - * @note If `multilinestring_geometry_offset` is std::nullopt, the input is a single linestring - * array. - * @note If any of the linestring contains less than 2 points, the behavior is undefined. - * - * @throw cuspatial::logic_error if `linestring1_offsets.size() != linestring2_offsets.size()` - * @throw cuspatial::logic_error if any of the point arrays have mismatched types. - * @throw cuspatial::logic_error if any linestring has fewer than 2 points. + * @return A column containing the distance between each pair of input (multi)linestrings * + * @throw cuspatial::logic_error if `multilinestrings1` and `multilinestrings2` sizes differ + * @throw cuspatial::logic_error if either `multilinestrings1` or `multilinestrings2` is not a + * linestring column. + * @throw cuspatial::logic_error if `multilinestrings1` and `multilinestrings2` coordinate types */ std::unique_ptr pairwise_linestring_distance( - std::optional> multilinestring1_geometry_offsets, - cudf::device_span linestring1_part_offsets, - cudf::column_view const& linestring1_points_xy, - std::optional> multilinestring2_geometry_offsets, - cudf::device_span linestring2_part_offsets, - cudf::column_view const& linestring2_points_xy, + geometry_column_view const& multilinestrings1, + geometry_column_view const& multilinestrings2, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); /** * @brief Compute pairwise (multi)linestring-to-(multi)polygon Cartesian distance * + * The distance between a pair of (multi)linestring and (multipolygon) is the shortest Cartesian + * distance between any pair of segments in the multilinestring and edges in the multipolygon. If + * any of the segments intersects, or if any linestring is contained in any polygon, the distance is + * 0. + * * @param multilinestrings Geometry column of multilinestrings * @param multipolygons Geometry column of multipolygons * @param mr Device memory resource used to allocate the returned column. * @return Column of distances between each pair of input geometries, same type as input coordinate * types. * - * @throw cuspatial::logic_error if `multilinestrings` and `multipolygons` have different coordinate - * types. - * @throw cuspatial::logic_error if `multilinestrings` is not a linestring column and + * @throw cuspatial::logic_error if `multilinestrings` and `multipolygons` sizes differ + * @throw cuspatial::logic_error if either `multilinestrings` is not a linestrings column or * `multipolygons` is not a polygon column. - * @throw cuspatial::logic_error if input column sizes mismatch. + * @throw cuspatial::logic_error if `multilinestrings` and `multipolygons` has different coordinate + * types. */ - std::unique_ptr pairwise_linestring_polygon_distance( geometry_column_view const& multilinestrings, geometry_column_view const& multipolygons, @@ -365,18 +242,20 @@ std::unique_ptr pairwise_linestring_polygon_distance( /** * @brief Compute pairwise (multi)polygon-to-(multi)polygon Cartesian distance * - * Computes the cartesian distance between each pair of the multipolygons. + * The distance between a pair of (multi)polygon and (multi)polygon is the shortest Cartesian + * distance between any pair of edges in the multipolygons. If any edges intersects, or if any + * polygon is contained in any other polygon, the distance is 0. * - * @param lhs Geometry column of the multipolygons to compute distance from - * @param rhs Geometry column of the multipolygons to compute distance to + * @param multipolygons1 Geometry column of the multipolygons to compute distance from + * @param multipolygons2 Geometry column of the multipolygons to compute distance to * @param mr Device memory resource used to allocate the returned column. * * @return Column of distances between each pair of input geometries, same type as input coordinate * types. */ std::unique_ptr pairwise_polygon_distance( - geometry_column_view const& lhs, - geometry_column_view const& rhs, + geometry_column_view const& multipolygons1, + geometry_column_view const& multipolygons2, rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()); /** diff --git a/cpp/include/cuspatial_test/base_fixture.hpp b/cpp/include/cuspatial_test/base_fixture.hpp index a2beffd2b..44a22d2bb 100644 --- a/cpp/include/cuspatial_test/base_fixture.hpp +++ b/cpp/include/cuspatial_test/base_fixture.hpp @@ -19,7 +19,7 @@ #include #include -#include +#include namespace cuspatial { namespace test { diff --git a/cpp/include/cuspatial_test/geometry_fixtures.hpp b/cpp/include/cuspatial_test/geometry_fixtures.hpp new file mode 100644 index 000000000..d52775785 --- /dev/null +++ b/cpp/include/cuspatial_test/geometry_fixtures.hpp @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include + +#include +#include + +#include +#include + +#include + +namespace cuspatial { +namespace test { + +/** + * @brief Test Fixture that initializes empty geometry columns. + * + * @tparam T Type of the coordinates + */ +template +class EmptyGeometryColumnBase { + protected: + // TODO: explore SetUpTestSuite to perform per-test-suite initialization, saving expenses. + // However, this requires making `stream` method a static member. + EmptyGeometryColumnBase(rmm::cuda_stream_view stream) + { + collection_type_id _; + + std::tie(_, empty_point_column) = make_point_column({}, stream); + std::tie(_, empty_linestring_column) = make_linestring_column({0}, {}, stream); + std::tie(_, empty_polygon_column) = make_polygon_column({0}, {0}, {}, stream); + std::tie(_, empty_multipoint_column) = make_point_column({0}, {}, stream); + std::tie(_, empty_multilinestring_column) = make_linestring_column({0}, {0}, {}, stream); + std::tie(_, empty_multipolygon_column) = make_polygon_column({0}, {0}, {0}, {}, stream); + } + + geometry_column_view empty_point() + { + return geometry_column_view( + empty_point_column->view(), collection_type_id::SINGLE, geometry_type_id::POINT); + } + + geometry_column_view empty_multipoint() + { + return geometry_column_view( + empty_multipoint_column->view(), collection_type_id::MULTI, geometry_type_id::POINT); + } + + geometry_column_view empty_linestring() + { + return geometry_column_view( + empty_linestring_column->view(), collection_type_id::SINGLE, geometry_type_id::LINESTRING); + } + + geometry_column_view empty_multilinestring() + { + return geometry_column_view(empty_multilinestring_column->view(), + collection_type_id::MULTI, + geometry_type_id::LINESTRING); + } + + geometry_column_view empty_polygon() + { + return geometry_column_view( + empty_polygon_column->view(), collection_type_id::SINGLE, geometry_type_id::POLYGON); + } + + geometry_column_view empty_multipolygon() + { + return geometry_column_view( + empty_multipolygon_column->view(), collection_type_id::MULTI, geometry_type_id::POLYGON); + } + + std::unique_ptr empty_point_column; + std::unique_ptr empty_linestring_column; + std::unique_ptr empty_polygon_column; + std::unique_ptr empty_multipoint_column; + std::unique_ptr empty_multilinestring_column; + std::unique_ptr empty_multipolygon_column; +}; + +/** + * @brief Test Fixture that initializes one geometry column. + * + * @tparam T Type of the coordinates + */ +template +class OneGeometryColumnBase { + protected: + // TODO: explore SetUpTestSuite to perform per-test-suite initialization, saving expenses. + // However, this requires making `stream` method a static member. + OneGeometryColumnBase(rmm::cuda_stream_view stream) + { + collection_type_id _; + + std::tie(_, one_point_column) = make_point_column({0, 0}, stream); + std::tie(_, one_linestring_column) = make_linestring_column({0, 2}, {0, 0, 1, 1}, stream); + std::tie(_, one_polygon_column) = + make_polygon_column({0, 1}, {0, 4}, {0, 0, 1, 0, 1, 1, 0, 0}, stream); + std::tie(_, one_multipoint_column) = make_point_column({0, 1}, {0, 0}, stream); + std::tie(_, one_multilinestring_column) = + make_linestring_column({0, 1}, {0, 2}, {0, 0, 1, 1}, stream); + std::tie(_, one_multipolygon_column) = + make_polygon_column({0, 1}, {0, 1}, {0, 4}, {0, 0, 1, 0, 1, 1, 0, 0}, stream); + } + + geometry_column_view one_point() + { + return geometry_column_view( + one_point_column->view(), collection_type_id::SINGLE, geometry_type_id::POINT); + } + + geometry_column_view one_multipoint() + { + return geometry_column_view( + one_multipoint_column->view(), collection_type_id::MULTI, geometry_type_id::POINT); + } + + geometry_column_view one_linestring() + { + return geometry_column_view( + one_linestring_column->view(), collection_type_id::SINGLE, geometry_type_id::LINESTRING); + } + + geometry_column_view one_multilinestring() + { + return geometry_column_view( + one_multilinestring_column->view(), collection_type_id::MULTI, geometry_type_id::LINESTRING); + } + + geometry_column_view one_polygon() + { + return geometry_column_view( + one_polygon_column->view(), collection_type_id::SINGLE, geometry_type_id::POLYGON); + } + + geometry_column_view one_multipolygon() + { + return geometry_column_view( + one_multipolygon_column->view(), collection_type_id::MULTI, geometry_type_id::POLYGON); + } + + std::unique_ptr one_point_column; + std::unique_ptr one_linestring_column; + std::unique_ptr one_polygon_column; + std::unique_ptr one_multipoint_column; + std::unique_ptr one_multilinestring_column; + std::unique_ptr one_multipolygon_column; +}; + +template +struct EmptyGeometryColumnFixture : public BaseFixture, public EmptyGeometryColumnBase { + EmptyGeometryColumnFixture() : EmptyGeometryColumnBase(this->stream()) {} +}; + +template +struct OneGeometryColumnFixture : public BaseFixture, public OneGeometryColumnBase { + OneGeometryColumnFixture() : EmptyGeometryColumnBase(this->stream()) {} +}; + +struct EmptyAndOneGeometryColumnFixture : public BaseFixture, + public EmptyGeometryColumnBase, + public OneGeometryColumnBase { + EmptyAndOneGeometryColumnFixture() + : EmptyGeometryColumnBase(this->stream()), OneGeometryColumnBase(this->stream()) + { + } +}; + +struct EmptyGeometryColumnFixtureMultipleTypes : public BaseFixture, + public EmptyGeometryColumnBase, + public EmptyGeometryColumnBase { + EmptyGeometryColumnFixtureMultipleTypes() + : EmptyGeometryColumnBase(this->stream()), + EmptyGeometryColumnBase(this->stream()) + { + } +}; + +} // namespace test +} // namespace cuspatial diff --git a/cpp/src/distance/linestring_distance.cu b/cpp/src/distance/linestring_distance.cu index 8133d2a6f..fe7b99fda 100644 --- a/cpp/src/distance/linestring_distance.cu +++ b/cpp/src/distance/linestring_distance.cu @@ -14,154 +14,95 @@ * limitations under the License. */ -#include "../utility/double_boolean_dispatch.hpp" -#include "../utility/iterator.hpp" +#include "../utility/multi_geometry_dispatch.hpp" +#include #include #include -#include -#include #include +#include +#include #include #include -#include -#include #include #include -#include #include #include namespace cuspatial { namespace detail { -template +template struct pairwise_linestring_distance_launch { using SizeType = cudf::device_span::size_type; - template - std::enable_if_t::value, std::unique_ptr> operator()( - SizeType num_pairs, - std::optional> multilinestring1_geometry_offsets, - cudf::device_span linestring1_part_offsets, - cudf::column_view const& linestring1_points_xy, - std::optional> multilinestring2_geometry_offsets, - cudf::device_span linestring2_part_offsets, - cudf::column_view const& linestring2_points_xy, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) + template )> + std::unique_ptr operator()(geometry_column_view const& multilinestrings1, + geometry_column_view const& multilinestrings2, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) { - auto const num_multilinestring1_parts = - static_cast(linestring1_part_offsets.size() - 1); - auto const num_multilinestring2_parts = - static_cast(linestring2_part_offsets.size() - 1); - auto const num_multilinestring1_points = - static_cast(linestring1_points_xy.size() / 2); - auto const num_multilinestring2_points = - static_cast(linestring2_points_xy.size() / 2); + auto size = multilinestrings1.size(); auto distances = cudf::make_numeric_column( - cudf::data_type{cudf::type_to_id()}, num_pairs, cudf::mask_state::UNALLOCATED, stream, mr); - - auto linestring1_coords_it = make_vec_2d_iterator(linestring1_points_xy.begin()); - auto linestring2_coords_it = make_vec_2d_iterator(linestring2_points_xy.begin()); - - auto multilinestrings1 = make_multilinestring_range( - num_pairs, - get_geometry_iterator_functor{}(multilinestring1_geometry_offsets), - num_multilinestring1_parts, - linestring1_part_offsets.begin(), - num_multilinestring1_points, - linestring1_coords_it); - - auto multilinestrings2 = make_multilinestring_range( - num_pairs, - get_geometry_iterator_functor{}(multilinestring2_geometry_offsets), - num_multilinestring2_parts, - linestring2_part_offsets.begin(), - num_multilinestring2_points, - linestring2_coords_it); - - pairwise_linestring_distance( - multilinestrings1, multilinestrings2, distances->mutable_view().begin(), stream); + cudf::data_type{cudf::type_to_id()}, size, cudf::mask_state::UNALLOCATED, stream, mr); + + auto lhs = + make_multilinestring_range(multilinestrings1); + auto rhs = + make_multilinestring_range(multilinestrings2); + + pairwise_linestring_distance(lhs, rhs, distances->mutable_view().begin(), stream); return distances; } - template - std::enable_if_t::value, std::unique_ptr> operator()( - Args&&...) + template ), typename... Args> + std::unique_ptr operator()(Args&&...) { CUSPATIAL_FAIL("Linestring distance API only supports floating point coordinates."); } }; -template +template struct pairwise_linestring_distance_functor { - std::unique_ptr operator()( - std::optional> multilinestring1_geometry_offsets, - cudf::device_span linestring1_part_offsets, - cudf::column_view const& linestring1_points_xy, - std::optional> multilinestring2_geometry_offsets, - cudf::device_span linestring2_part_offsets, - cudf::column_view const& linestring2_points_xy, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) + std::unique_ptr operator()(geometry_column_view const& multilinestrings1, + geometry_column_view const& multilinestrings2, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) { - CUSPATIAL_EXPECTS( - linestring1_points_xy.size() % 2 == 0 && linestring2_points_xy.size() % 2 == 0, - "Points array must contain even number of coordinates."); - - auto num_lhs = first_is_multilinestring ? multilinestring1_geometry_offsets.value().size() - 1 - : linestring1_part_offsets.size() - 1; - auto num_rhs = second_is_multilinestring ? multilinestring2_geometry_offsets.value().size() - 1 - : linestring2_part_offsets.size() - 1; - - CUSPATIAL_EXPECTS(num_lhs == num_rhs, "Mismatch number of points and linestrings."); - - CUSPATIAL_EXPECTS(linestring1_points_xy.type() == linestring2_points_xy.type(), - "The types of linestring coordinates arrays mismatch."); + CUSPATIAL_EXPECTS(multilinestrings1.geometry_type() == geometry_type_id::LINESTRING && + multilinestrings2.geometry_type() == geometry_type_id::LINESTRING, + "Unexpected input geometry types."); - CUSPATIAL_EXPECTS(!(linestring1_points_xy.has_nulls() || linestring2_points_xy.has_nulls()), - "All inputs must not have nulls."); + CUSPATIAL_EXPECTS(multilinestrings1.coordinate_type() == multilinestrings2.coordinate_type(), + "Inputs must have the same coordinate type."); - if (num_lhs == 0) { return cudf::empty_like(linestring1_points_xy); } + CUSPATIAL_EXPECTS(multilinestrings1.size() == multilinestrings2.size(), + "Inputs should have the same number of geometries."); return cudf::type_dispatcher( - linestring1_points_xy.type(), - pairwise_linestring_distance_launch{}, - num_lhs, - multilinestring1_geometry_offsets, - linestring1_part_offsets, - linestring1_points_xy, - multilinestring2_geometry_offsets, - linestring2_part_offsets, - linestring2_points_xy, + multilinestrings1.coordinate_type(), + pairwise_linestring_distance_launch{}, + multilinestrings1, + multilinestrings2, stream, mr); } }; } // namespace detail std::unique_ptr pairwise_linestring_distance( - std::optional> multilinestring1_geometry_offsets, - cudf::device_span linestring1_part_offsets, - cudf::column_view const& linestring1_points_xy, - std::optional> multilinestring2_geometry_offsets, - cudf::device_span linestring2_part_offsets, - cudf::column_view const& linestring2_points_xy, + geometry_column_view const& multilinestrings1, + geometry_column_view const& multilinestrings2, rmm::mr::device_memory_resource* mr) { - return double_boolean_dispatch( - multilinestring1_geometry_offsets.has_value(), - multilinestring2_geometry_offsets.has_value(), - multilinestring1_geometry_offsets, - linestring1_part_offsets, - linestring1_points_xy, - multilinestring2_geometry_offsets, - linestring2_part_offsets, - linestring2_points_xy, + return multi_geometry_double_dispatch( + multilinestrings1.collection_type(), + multilinestrings2.collection_type(), + multilinestrings1, + multilinestrings2, rmm::cuda_stream_default, mr); } diff --git a/cpp/src/distance/linestring_polygon_distance.cu b/cpp/src/distance/linestring_polygon_distance.cu index d07a97baa..347f998fa 100644 --- a/cpp/src/distance/linestring_polygon_distance.cu +++ b/cpp/src/distance/linestring_polygon_distance.cu @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "../utility/iterator.hpp" #include "../utility/multi_geometry_dispatch.hpp" #include @@ -90,6 +89,16 @@ struct pairwise_linestring_polygon_distance { rmm::cuda_stream_view stream, rmm::mr::device_memory_resource* mr) { + CUSPATIAL_EXPECTS(multilinestrings.geometry_type() == geometry_type_id::LINESTRING && + multipolygons.geometry_type() == geometry_type_id::POLYGON, + "Unexpected input geometry types."); + + CUSPATIAL_EXPECTS(multilinestrings.coordinate_type() == multipolygons.coordinate_type(), + "Inputs must have the same coordinate type."); + + CUSPATIAL_EXPECTS(multilinestrings.size() == multipolygons.size(), + "Inputs must have the same number of rows."); + return cudf::type_dispatcher( multilinestrings.coordinate_type(), pairwise_linestring_polygon_distance_impl{}, @@ -107,13 +116,6 @@ std::unique_ptr pairwise_linestring_polygon_distance( geometry_column_view const& multipolygons, rmm::mr::device_memory_resource* mr) { - CUSPATIAL_EXPECTS(multilinestrings.geometry_type() == geometry_type_id::LINESTRING && - multipolygons.geometry_type() == geometry_type_id::POLYGON, - "Unexpected input geometry types."); - - CUSPATIAL_EXPECTS(multilinestrings.coordinate_type() == multipolygons.coordinate_type(), - "Input geometries must have the same coordinate data types."); - return multi_geometry_double_dispatch( multilinestrings.collection_type(), multipolygons.collection_type(), diff --git a/cpp/src/distance/point_distance.cu b/cpp/src/distance/point_distance.cu index c0fe8d778..d2349b7a2 100644 --- a/cpp/src/distance/point_distance.cu +++ b/cpp/src/distance/point_distance.cu @@ -14,58 +14,43 @@ * limitations under the License. */ -#include "../utility/double_boolean_dispatch.hpp" -#include "../utility/iterator.hpp" +#include "../utility/multi_geometry_dispatch.hpp" +#include #include #include -#include -#include #include +#include #include #include -#include #include #include -#include #include #include namespace cuspatial { namespace detail { -template +template struct pairwise_point_distance_impl { template std::enable_if_t::value, std::unique_ptr> operator()( - cudf::size_type num_pairs, - std::optional> multipoints1_offset, - cudf::column_view const& points1_xy, - std::optional> multipoints2_offset, - cudf::column_view const& points2_xy, + geometry_column_view const& multipoints1, + geometry_column_view const& multipoints2, rmm::cuda_stream_view stream, rmm::mr::device_memory_resource* mr) { - auto distances = cudf::make_numeric_column( - cudf::data_type{cudf::type_to_id()}, num_pairs, cudf::mask_state::UNALLOCATED, stream, mr); - - auto multipoint1_offset_it = - get_geometry_iterator_functor{}(multipoints1_offset); - auto multipoint2_offset_it = - get_geometry_iterator_functor{}(multipoints2_offset); + auto size = multipoints1.size(); - auto points1_it = make_vec_2d_iterator(points1_xy.begin()); - auto points2_it = make_vec_2d_iterator(points2_xy.begin()); + auto distances = cudf::make_numeric_column( + cudf::data_type{cudf::type_to_id()}, size, cudf::mask_state::UNALLOCATED, stream, mr); - auto multipoint1_its = - make_multipoint_range(num_pairs, multipoint1_offset_it, points1_xy.size() / 2, points1_it); - auto multipoint2_its = - make_multipoint_range(num_pairs, multipoint2_offset_it, points2_xy.size() / 2, points2_it); + auto lhs = make_multipoint_range(multipoints1); + auto rhs = make_multipoint_range(multipoints2); - pairwise_point_distance( - multipoint1_its, multipoint2_its, distances->mutable_view().begin(), stream); + pairwise_point_distance(lhs, rhs, distances->mutable_view().begin(), stream); return distances; } @@ -78,58 +63,44 @@ struct pairwise_point_distance_impl { } }; -template +template struct pairwise_point_distance_functor { - std::unique_ptr operator()( - std::optional> multipoints1_offset, - cudf::column_view const& points1_xy, - std::optional> multipoints2_offset, - cudf::column_view const& points2_xy, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) + std::unique_ptr operator()(geometry_column_view const& multipoints1, + geometry_column_view const& multipoints2, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) { - CUSPATIAL_EXPECTS(points1_xy.size() % 2 == 0 and points2_xy.size() % 2 == 0, - "Coordinate array should contain even number of points."); - CUSPATIAL_EXPECTS(points1_xy.type() == points2_xy.type(), - "The types of point coordinates arrays mismatch."); - CUSPATIAL_EXPECTS(not points1_xy.has_nulls() and not points2_xy.has_nulls(), - "The coordinate columns cannot have nulls."); - - auto num_lhs = is_multipoint1 ? multipoints1_offset.value().size() - 1 : points1_xy.size() / 2; - auto num_rhs = is_multipoint2 ? multipoints2_offset.value().size() - 1 : points2_xy.size() / 2; - - CUSPATIAL_EXPECTS(num_lhs == num_rhs, "Mismatch number of (multi)point(s) in input."); - - if (num_lhs == 0) { return cudf::empty_like(points1_xy); } - - return cudf::type_dispatcher(points1_xy.type(), - pairwise_point_distance_impl{}, - num_lhs, - multipoints1_offset, - points1_xy, - multipoints2_offset, - points2_xy, - stream, - mr); + CUSPATIAL_EXPECTS(multipoints1.geometry_type() == geometry_type_id::POINT && + multipoints2.geometry_type() == geometry_type_id::POINT, + "Unexpected input geometry types."); + + CUSPATIAL_EXPECTS(multipoints1.coordinate_type() == multipoints2.coordinate_type(), + "Input coordinates must have the same floating point type."); + + CUSPATIAL_EXPECTS(multipoints1.size() == multipoints2.size(), + "Inputs should have the same number of geometries."); + + return cudf::type_dispatcher( + multipoints1.coordinate_type(), + pairwise_point_distance_impl{}, + multipoints1, + multipoints2, + stream, + mr); } }; } // namespace detail -std::unique_ptr pairwise_point_distance( - std::optional> multipoints1_offset, - cudf::column_view const& points1_xy, - std::optional> multipoints2_offset, - cudf::column_view const& points2_xy, - rmm::mr::device_memory_resource* mr) +std::unique_ptr pairwise_point_distance(geometry_column_view const& multipoints1, + geometry_column_view const& multipoints2, + rmm::mr::device_memory_resource* mr) { - return double_boolean_dispatch( - multipoints1_offset.has_value(), - multipoints2_offset.has_value(), - multipoints1_offset, - points1_xy, - multipoints2_offset, - points2_xy, + return multi_geometry_double_dispatch( + multipoints1.collection_type(), + multipoints2.collection_type(), + multipoints1, + multipoints2, rmm::cuda_stream_default, mr); } diff --git a/cpp/src/distance/point_linestring_distance.cu b/cpp/src/distance/point_linestring_distance.cu index ed0b0ab7d..59cb1b460 100644 --- a/cpp/src/distance/point_linestring_distance.cu +++ b/cpp/src/distance/point_linestring_distance.cu @@ -14,88 +14,59 @@ * limitations under the License. */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include "utility/multi_geometry_dispatch.hpp" +#include #include #include -#include #include #include +#include +#include -#include +#include +#include +#include +#include + +#include #include #include -#include "../utility/double_boolean_dispatch.hpp" -#include "../utility/iterator.hpp" - namespace cuspatial { namespace detail { namespace { -template +template struct pairwise_point_linestring_distance_impl { using SizeType = cudf::device_span::size_type; - template )> - std::unique_ptr operator()( - SizeType num_pairs, - std::optional> multipoint_geometry_offsets, - cudf::column_view const& points_xy, - std::optional> multilinestring_geometry_offsets, - cudf::device_span linestring_part_offsets, - cudf::column_view const& linestring_points_xy, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) + template )> + std::unique_ptr operator()(geometry_column_view const& multipoints, + geometry_column_view const& multilinestrings, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) { - auto const num_points = static_cast(points_xy.size() / 2); - auto const num_linestring_points = static_cast(linestring_points_xy.size() / 2); - auto const num_linestring_parts = static_cast(linestring_part_offsets.size() - 1); - - auto output = cudf::make_numeric_column( - points_xy.type(), num_pairs, cudf::mask_state::UNALLOCATED, stream, mr); - - auto point_geometry_it_first = - get_geometry_iterator_functor{}(multipoint_geometry_offsets); - auto points_it = make_vec_2d_iterator(points_xy.begin()); - - auto linestring_geometry_it_first = - get_geometry_iterator_functor{}(multilinestring_geometry_offsets); - auto linestring_points_it = make_vec_2d_iterator(linestring_points_xy.begin()); + auto size = multipoints.size(); - auto output_begin = output->mutable_view().begin(); + auto distances = cudf::make_numeric_column( + cudf::data_type{cudf::type_to_id()}, size, cudf::mask_state::UNALLOCATED, stream, mr); - auto multipoints = - make_multipoint_range(num_pairs, point_geometry_it_first, num_points, points_it); - - auto multilinestrings = make_multilinestring_range(num_pairs, - linestring_geometry_it_first, - num_linestring_parts, - linestring_part_offsets.begin(), - num_linestring_points, - linestring_points_it); + auto lhs = make_multipoint_range(multipoints); + auto rhs = + make_multilinestring_range(multilinestrings); cuspatial::pairwise_point_linestring_distance( - multipoints, multilinestrings, output_begin, stream); + lhs, rhs, distances->mutable_view().begin(), stream); - return output; + return distances; } - template ), typename... Args> + template ), typename... Args> std::unique_ptr operator()(Args&&...) - { CUSPATIAL_FAIL("Point-linestring distance API only supports floating point coordinates."); } @@ -103,44 +74,28 @@ struct pairwise_point_linestring_distance_impl { } // namespace -template +template struct pairwise_point_linestring_distance_functor { - std::unique_ptr operator()( - std::optional> multipoint_geometry_offsets, - cudf::column_view const& points_xy, - std::optional> multilinestring_geometry_offsets, - cudf::device_span linestring_part_offsets, - cudf::column_view const& linestring_points_xy, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) + std::unique_ptr operator()(geometry_column_view const& multipoints, + geometry_column_view const& multilinestrings, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) { - CUSPATIAL_EXPECTS(points_xy.size() % 2 == 0 && linestring_points_xy.size() % 2 == 0, - "Points array must contain even number of coordinates."); - - auto num_lhs = - is_multi_point ? multipoint_geometry_offsets.value().size() : (points_xy.size() / 2 + 1); - auto num_rhs = is_multi_linestring ? multilinestring_geometry_offsets.value().size() - : linestring_part_offsets.size(); - - CUSPATIAL_EXPECTS(num_lhs == num_rhs, "Mismatch number of points and linestrings."); - - CUSPATIAL_EXPECTS(points_xy.type() == linestring_points_xy.type(), - "Points and linestring coordinates must have the same type."); + CUSPATIAL_EXPECTS(multipoints.geometry_type() == geometry_type_id::POINT && + multilinestrings.geometry_type() == geometry_type_id::LINESTRING, + "Unexpected input geometry types."); - CUSPATIAL_EXPECTS(!(points_xy.has_nulls() || linestring_points_xy.has_nulls()), - "All inputs must not have nulls."); + CUSPATIAL_EXPECTS(multipoints.coordinate_type() == multilinestrings.coordinate_type(), + "Inputs must have the same coordinate type."); - if (num_rhs - 1 == 0) return cudf::make_empty_column(points_xy.type()); + CUSPATIAL_EXPECTS(multipoints.size() == multilinestrings.size(), + "Inputs should have the same number of geometries."); return cudf::type_dispatcher( - points_xy.type(), + multipoints.coordinate_type(), pairwise_point_linestring_distance_impl{}, - num_lhs - 1, - multipoint_geometry_offsets, - points_xy, - multilinestring_geometry_offsets, - linestring_part_offsets, - linestring_points_xy, + multipoints, + multilinestrings, stream, mr); } @@ -149,21 +104,15 @@ struct pairwise_point_linestring_distance_functor { } // namespace detail std::unique_ptr pairwise_point_linestring_distance( - std::optional> multipoint_geometry_offsets, - cudf::column_view const& points_xy, - std::optional> multilinestring_geometry_offsets, - cudf::device_span linestring_part_offsets, - cudf::column_view const& linestring_points_xy, + geometry_column_view const& multipoints, + geometry_column_view const& multilinestrings, rmm::mr::device_memory_resource* mr) { - return double_boolean_dispatch( - multipoint_geometry_offsets.has_value(), - multilinestring_geometry_offsets.has_value(), - multipoint_geometry_offsets, - points_xy, - multilinestring_geometry_offsets, - linestring_part_offsets, - linestring_points_xy, + return multi_geometry_double_dispatch( + multipoints.collection_type(), + multilinestrings.collection_type(), + multipoints, + multilinestrings, rmm::cuda_stream_default, mr); } diff --git a/cpp/src/distance/point_polygon_distance.cu b/cpp/src/distance/point_polygon_distance.cu index e4053d972..ecd5e06aa 100644 --- a/cpp/src/distance/point_polygon_distance.cu +++ b/cpp/src/distance/point_polygon_distance.cu @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "../utility/iterator.hpp" #include "../utility/multi_geometry_dispatch.hpp" #include diff --git a/cpp/src/distance/polygon_distance.cu b/cpp/src/distance/polygon_distance.cu index 3a24f04cf..d31db9bb9 100644 --- a/cpp/src/distance/polygon_distance.cu +++ b/cpp/src/distance/polygon_distance.cu @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "../utility/iterator.hpp" #include "../utility/multi_geometry_dispatch.hpp" #include @@ -83,6 +82,16 @@ struct pairwise_polygon_distance { rmm::cuda_stream_view stream, rmm::mr::device_memory_resource* mr) { + CUSPATIAL_EXPECTS(lhs.geometry_type() == geometry_type_id::POLYGON && + rhs.geometry_type() == geometry_type_id::POLYGON, + "Unexpected input geometry types."); + + CUSPATIAL_EXPECTS(lhs.coordinate_type() == rhs.coordinate_type(), + "Input geometries must have the same coordinate data types."); + + CUSPATIAL_EXPECTS(lhs.size() == rhs.size(), + "Input geometries must have the same number of polygons."); + return cudf::type_dispatcher( lhs.coordinate_type(), pairwise_polygon_distance_impl{}, @@ -99,13 +108,6 @@ std::unique_ptr pairwise_polygon_distance(geometry_column_view con geometry_column_view const& rhs, rmm::mr::device_memory_resource* mr) { - CUSPATIAL_EXPECTS(lhs.geometry_type() == geometry_type_id::POLYGON && - rhs.geometry_type() == geometry_type_id::POLYGON, - "Unexpected input geometry types."); - - CUSPATIAL_EXPECTS(lhs.coordinate_type() == rhs.coordinate_type(), - "Input geometries must have the same coordinate data types."); - return multi_geometry_double_dispatch( lhs.collection_type(), rhs.collection_type(), lhs, rhs, rmm::cuda_stream_default, mr); } diff --git a/cpp/src/intersection/linestring_intersection.cu b/cpp/src/intersection/linestring_intersection.cu index 760854692..e92e2a366 100644 --- a/cpp/src/intersection/linestring_intersection.cu +++ b/cpp/src/intersection/linestring_intersection.cu @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "../utility/iterator.hpp" #include "../utility/multi_geometry_dispatch.hpp" #include diff --git a/cpp/tests/distance/linestring_distance_test.cpp b/cpp/tests/distance/linestring_distance_test.cpp index 7fc25497e..68558f104 100644 --- a/cpp/tests/distance/linestring_distance_test.cpp +++ b/cpp/tests/distance/linestring_distance_test.cpp @@ -14,252 +14,81 @@ * limitations under the License. */ -#include +#include + #include #include -#include -#include -#include -#include - -#include #include using namespace cuspatial; +using namespace cuspatial::test; + using namespace cudf; using namespace cudf::test; template -using wrapper = fixed_width_column_wrapper; - -template -struct PairwiseLinestringDistanceTest : public BaseFixture {}; - -struct PairwiseLinestringDistanceTestUntyped : public BaseFixture {}; - -// float and double are logically the same but would require separate tests due to precision. -using TestTypes = FloatingPointTypes; -TYPED_TEST_CASE(PairwiseLinestringDistanceTest, TestTypes); - -constexpr cudf::test::debug_output_level verbosity{cudf::test::debug_output_level::ALL_ERRORS}; - -TYPED_TEST(PairwiseLinestringDistanceTest, EmptyInput) -{ - using T = TypeParam; - wrapper l1offsets{0}; - wrapper xy1{}; - wrapper l2offsets{0}; - wrapper xy2{}; - - wrapper expected{}; +struct PairwiseLineStringDistanceTest : public EmptyGeometryColumnFixture {}; - auto result = cuspatial::pairwise_linestring_distance( - std::nullopt, column_view(l1offsets), xy1, std::nullopt, column_view(l2offsets), xy2); - CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expected, result->view(), verbosity); -} - -TYPED_TEST(PairwiseLinestringDistanceTest, FourPairSingleToMultiLineString) -{ - using T = TypeParam; +using TestTypes = ::testing::Types; - wrapper l1part_offset{0, 3, 5, 8, 10}; - wrapper l1_xy{0, 1, 1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 2, 2, -2, 0, 2, 2, -2, -2}; - wrapper l2geom_offset{0, 1, 3, 5, 7}; - wrapper l2part_offset{0, 4, 7, 10, 12, 14, 17, 20}; - wrapper l2_xy{1, 1, 2, 1, 2, 0, 3, 0, 1, 0, 1, 1, 1, 2, 1, -1, 1, -2, 1, -3, - 2, 0, 0, 2, 0, 2, -2, 0, 1, 1, 5, 5, 10, 0, -1, -1, -5, -5, -10, 0}; +TYPED_TEST_CASE(PairwiseLineStringDistanceTest, TestTypes); - wrapper expected{std::sqrt(2.0) / 2, 1.0, 0.0, 0.0}; - - auto result = cuspatial::pairwise_linestring_distance(std::nullopt, - column_view(l1part_offset), - l1_xy, - column_view(l2geom_offset), - column_view(l2part_offset), - l2_xy); - - CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expected, result->view(), verbosity); -} - -TYPED_TEST(PairwiseLinestringDistanceTest, FourPairSingleToSingleLineString) +TYPED_TEST(PairwiseLineStringDistanceTest, SingleToSingleEmpty) { - using T = TypeParam; - - wrapper l1part_offset{0, 3, 5, 8, 10}; - wrapper l1_xy{0, 1, 1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 2, 2, -2, 0, 2, 2, -2, -2}; - wrapper l2part_offset{0, 4, 7, 9, 11}; - wrapper l2_xy{1, 1, 2, 1, 2, 0, 3, 0, 1, 0, 1, 1, 1, 2, 2, 0, 0, 2, 1, 1, 5, 5, 10, 0}; - - wrapper expected{std::sqrt(2.0) / 2, 1.0, 0.0, 0.0}; - - auto result = cuspatial::pairwise_linestring_distance(std::nullopt, - column_view(l1part_offset), - l1_xy, - std::nullopt, - column_view(l2part_offset), - l2_xy); - - CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expected, result->view(), verbosity); + auto got = pairwise_linestring_distance(this->empty_linestring(), this->empty_linestring()); + auto expect = fixed_width_column_wrapper{}; + CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -TYPED_TEST(PairwiseLinestringDistanceTest, TwoPairMultiToSingleLineString) +TYPED_TEST(PairwiseLineStringDistanceTest, SingleToMultiEmpty) { - using T = TypeParam; - - wrapper l1geom_offset{0, 1, 3}; - wrapper l1part_offset{0, 3, 6, 8}; - wrapper l1_xy{0, 0, 0, 1, 0, 2, 0, 1, 1, 1, 2, 1, 2, 1, 2, 0}; - wrapper l2part_offset{0, 2, 4}; - wrapper l2_xy{1, 0, 1, 1, 0, 0, 1, 0}; - - wrapper expected{1.0, 1.0}; - - auto result = cuspatial::pairwise_linestring_distance(column_view(l1geom_offset), - column_view(l1part_offset), - l1_xy, - std::nullopt, - column_view(l2part_offset), - l2_xy); - - CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expected, result->view(), verbosity); + auto got = pairwise_linestring_distance(this->empty_linestring(), this->empty_multilinestring()); + auto expect = fixed_width_column_wrapper{}; + CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -TYPED_TEST(PairwiseLinestringDistanceTest, OnePairMultiToMultiLineString) +TYPED_TEST(PairwiseLineStringDistanceTest, MultiToSingleEmpty) { - using T = TypeParam; - - wrapper l1geom_offset{0, 3}; - wrapper l1part_offset{0, 3, 6, 8}; - wrapper l1_xy{0, 0, 0, 1, 0, 2, 0, 1, 1, 1, 2, 1, 2, 1, 2, 0}; - wrapper l2geom_offset{0, 3}; - wrapper l2part_offset{0, 2, 4, 6}; - wrapper l2_xy{0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3}; - - wrapper expected{0.0}; - - auto result = cuspatial::pairwise_linestring_distance(column_view(l1geom_offset), - column_view(l1part_offset), - l1_xy, - column_view(l2geom_offset), - column_view(l2part_offset), - l2_xy); - - CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expected, result->view(), verbosity); + auto got = pairwise_linestring_distance(this->empty_multilinestring(), this->empty_linestring()); + auto expect = fixed_width_column_wrapper{}; + CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -TEST_F(PairwiseLinestringDistanceTestUntyped, InputSizeMismatchSingletoSingle) +TYPED_TEST(PairwiseLineStringDistanceTest, MultiToMultiEmpty) { - wrapper l1part_offset{0, 2}; - wrapper l1_xy{0, 0, 1, 1}; - wrapper l2part_offset{0, 2, 4}; - wrapper l2_xy{0, 0, 1, 1, 2, 2, 3, 3}; - - EXPECT_THROW(cuspatial::pairwise_linestring_distance(std::nullopt, - column_view(l1part_offset), - l1_xy, - std::nullopt, - column_view(l2part_offset), - l2_xy), - cuspatial::logic_error); + auto got = + pairwise_linestring_distance(this->empty_multilinestring(), this->empty_multilinestring()); + auto expect = fixed_width_column_wrapper{}; + CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -TEST_F(PairwiseLinestringDistanceTestUntyped, InputSizeMismatchSingletoMulti) -{ - wrapper l1part_offset{0, 2}; - wrapper l1_xy{0, 0, 1, 1}; - wrapper l2geom_offset{0, 1, 3}; - wrapper l2part_offset{0, 2, 4, 6}; - wrapper l2_xy{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5}; - - EXPECT_THROW(cuspatial::pairwise_linestring_distance(std::nullopt, - column_view(l1part_offset), - l1_xy, - column_view(l2geom_offset), - column_view(l2part_offset), - l2_xy), - cuspatial::logic_error); -} +struct PairwiseLineStringDistanceFailOnSizeTest : public EmptyAndOneGeometryColumnFixture {}; -TEST_F(PairwiseLinestringDistanceTestUntyped, InputSizeMismatchMultitoSingle) +TEST_F(PairwiseLineStringDistanceFailOnSizeTest, SizeMismatch) { - wrapper l1geom_offset{0, 1, 3}; - wrapper l1part_offset{0, 2, 4, 6}; - wrapper l1_xy{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5}; - wrapper l2part_offset{0, 2}; - wrapper l2_xy{0, 0, 1, 1}; - - EXPECT_THROW(cuspatial::pairwise_linestring_distance(column_view(l1geom_offset), - column_view(l1part_offset), - l1_xy, - std::nullopt, - column_view(l2part_offset), - l2_xy), + EXPECT_THROW(pairwise_linestring_distance(this->empty_linestring(), this->one_linestring()), cuspatial::logic_error); } -TEST_F(PairwiseLinestringDistanceTestUntyped, InputSizeMismatchMultitoMulti) +TEST_F(PairwiseLineStringDistanceFailOnSizeTest, SizeMismatch2) { - wrapper l1geom_offset{0, 1, 3}; - wrapper l1part_offset{0, 2, 4, 6}; - wrapper l1_xy{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5}; - wrapper l2geom_offset{0, 2}; - wrapper l2part_offset{0, 2, 4}; - wrapper l2_xy{0, 0, 1, 1, 2, 2, 3, 3}; - - EXPECT_THROW(cuspatial::pairwise_linestring_distance(column_view(l1geom_offset), - column_view(l1part_offset), - l1_xy, - column_view(l2geom_offset), - column_view(l2part_offset), - l2_xy), + EXPECT_THROW(pairwise_linestring_distance(this->one_linestring(), this->empty_multilinestring()), cuspatial::logic_error); } -TEST_F(PairwiseLinestringDistanceTestUntyped, CoordinatesNotEven) -{ - wrapper l1_part_offset{0, 2}; - wrapper l1_xy{0, 0, 1, 1, 2, 2, 3}; - wrapper l2_part_offset{0, 2}; - wrapper l2_xy{0, 0, 1, 1, 2, 2, 3, 3}; +struct PairwiseLineStringDistanceFailOnTypeTest : public EmptyGeometryColumnFixtureMultipleTypes {}; - EXPECT_THROW(cuspatial::pairwise_linestring_distance(std::nullopt, - column_view(l1_part_offset), - l1_xy, - std::nullopt, - column_view(l2_part_offset), - l2_xy), - cuspatial::logic_error); -} - -TEST_F(PairwiseLinestringDistanceTestUntyped, TypeMismatch) +TEST_F(PairwiseLineStringDistanceFailOnTypeTest, CoordinateTypeMismatch) { - wrapper l1_part_offset{0, 2}; - wrapper l1_xy{0, 0, 1, 1}; - wrapper l2_part_offset{0, 2}; - wrapper l2_xy{0, 0, 1, 1}; - - EXPECT_THROW(cuspatial::pairwise_linestring_distance(std::nullopt, - column_view(l1_part_offset), - l1_xy, - std::nullopt, - column_view(l2_part_offset), - l2_xy), + EXPECT_THROW(pairwise_linestring_distance(EmptyGeometryColumnBase::empty_linestring(), + EmptyGeometryColumnBase::empty_linestring()), cuspatial::logic_error); } -TEST_F(PairwiseLinestringDistanceTestUntyped, ContainsNull) +TEST_F(PairwiseLineStringDistanceFailOnTypeTest, GeometryTypeMismatch) { - wrapper l1_part_offset{0, 2}; - wrapper l1_xy{{0, 0, 1, 1}, {1, 0, 1, 1}}; - wrapper l2_part_offset{0, 2}; - wrapper l2_xy{0, 0, 1, 1}; - - EXPECT_THROW(cuspatial::pairwise_linestring_distance(std::nullopt, - column_view(l1_part_offset), - l1_xy, - std::nullopt, - column_view(l2_part_offset), - l2_xy), + EXPECT_THROW(pairwise_linestring_distance(EmptyGeometryColumnBase::empty_linestring(), + EmptyGeometryColumnBase::empty_polygon()), cuspatial::logic_error); } diff --git a/cpp/tests/distance/linestring_polygon_distance_test.cpp b/cpp/tests/distance/linestring_polygon_distance_test.cpp index 7b5b73642..95beec0bd 100644 --- a/cpp/tests/distance/linestring_polygon_distance_test.cpp +++ b/cpp/tests/distance/linestring_polygon_distance_test.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include @@ -40,42 +41,7 @@ using namespace cudf; using namespace cudf::test; template -struct PairwiseLinestringPolygonDistanceTest : ::testing::Test { - rmm::cuda_stream_view stream() { return cudf::get_default_stream(); } - void SetUp() - { - collection_type_id _; - std::tie(_, empty_linestring_column) = make_linestring_column({0}, {}, stream()); - std::tie(_, empty_multilinestring_column) = make_linestring_column({0}, {0}, {}, stream()); - std::tie(_, empty_polygon_column) = make_polygon_column({0}, {0}, {}, stream()); - std::tie(_, empty_multipolygon_column) = make_polygon_column({0}, {0}, {0}, {}, stream()); - } - - geometry_column_view empty_linestring() - { - return geometry_column_view( - empty_linestring_column->view(), collection_type_id::SINGLE, geometry_type_id::LINESTRING); - } - - geometry_column_view empty_multilinestring() - { - return geometry_column_view(empty_multilinestring_column->view(), - collection_type_id::MULTI, - geometry_type_id::LINESTRING); - } - - geometry_column_view empty_polygon() - { - return geometry_column_view( - empty_polygon_column->view(), collection_type_id::SINGLE, geometry_type_id::POLYGON); - } - - geometry_column_view empty_multipolygon() - { - return geometry_column_view( - empty_multipolygon_column->view(), collection_type_id::MULTI, geometry_type_id::POLYGON); - } - +struct PairwiseLinestringPolygonDistanceTest : EmptyGeometryColumnFixture { void run_single(geometry_column_view linestrings, geometry_column_view polygons, std::initializer_list expected) @@ -83,16 +49,11 @@ struct PairwiseLinestringPolygonDistanceTest : ::testing::Test { auto got = pairwise_linestring_polygon_distance(linestrings, polygons); CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(*got, fixed_width_column_wrapper(expected)); } - - std::unique_ptr empty_linestring_column; - std::unique_ptr empty_multilinestring_column; - std::unique_ptr empty_polygon_column; - std::unique_ptr empty_multipolygon_column; }; -struct PairwiseLinestringPolygonDistanceTestUntyped : testing::Test { - rmm::cuda_stream_view stream() { return cudf::get_default_stream(); } -}; +struct PairwiseLinestringPolygonDistanceFailOnSizeTest : EmptyAndOneGeometryColumnFixture {}; + +struct PairwiseLinestringPolygonDistanceFailOnTypeTest : EmptyGeometryColumnFixtureMultipleTypes {}; using TestTypes = ::testing::Types; @@ -119,48 +80,24 @@ TYPED_TEST(PairwiseLinestringPolygonDistanceTest, MultiToMultiEmpty) this->run_single, this->empty_multilinestring(), this->empty_multipolygon(), {}); }; -TEST_F(PairwiseLinestringPolygonDistanceTestUntyped, SizeMismatch) +TEST_F(PairwiseLinestringPolygonDistanceFailOnSizeTest, SizeMismatch) { - auto [ptype, linestrings] = - make_linestring_column({0, 1, 2}, {0, 1, 2}, {0.0, 0.0, 1.0, 1.0}, this->stream()); - - auto [polytype, polygons] = - make_polygon_column({0, 1}, {0, 1}, {0, 4}, {1, 1, 1, 2, 2, 2, 1, 1}, this->stream()); - - auto linestrings_view = - geometry_column_view(linestrings->view(), ptype, geometry_type_id::LINESTRING); - auto polygons_view = geometry_column_view(polygons->view(), polytype, geometry_type_id::POLYGON); - - EXPECT_THROW(pairwise_linestring_polygon_distance(linestrings_view, polygons_view), + EXPECT_THROW(pairwise_linestring_polygon_distance(this->empty_linestring(), this->one_polygon()), cuspatial::logic_error); }; -TEST_F(PairwiseLinestringPolygonDistanceTestUntyped, TypeMismatch) +TEST_F(PairwiseLinestringPolygonDistanceFailOnTypeTest, CoordinateTypeMismatch) { - auto [ptype, linestrings] = - make_linestring_column({0, 1}, {0, 1}, {0.0, 0.0}, this->stream()); - - auto [polytype, polygons] = - make_polygon_column({0, 1}, {0, 1}, {0, 4}, {1, 1, 1, 2, 2, 2, 1, 1}, this->stream()); - - auto linestrings_view = - geometry_column_view(linestrings->view(), ptype, geometry_type_id::LINESTRING); - auto polygons_view = geometry_column_view(polygons->view(), polytype, geometry_type_id::POLYGON); - - EXPECT_THROW(pairwise_linestring_polygon_distance(linestrings_view, polygons_view), - cuspatial::logic_error); + EXPECT_THROW( + pairwise_linestring_polygon_distance(EmptyGeometryColumnBase::empty_linestring(), + EmptyGeometryColumnBase::empty_polygon()), + cuspatial::logic_error); }; -TEST_F(PairwiseLinestringPolygonDistanceTestUntyped, WrongGeometryType) +TEST_F(PairwiseLinestringPolygonDistanceFailOnTypeTest, WrongGeometryType) { - auto [ptype, points] = make_point_column({0, 1}, {0.0, 0.0}, this->stream()); - - auto [polytype, polygons] = - make_polygon_column({0, 1}, {0, 1}, {0, 4}, {1, 1, 1, 2, 2, 2, 1, 1}, this->stream()); - - auto points_view = geometry_column_view(points->view(), ptype, geometry_type_id::POINT); - auto polygons_view = geometry_column_view(polygons->view(), polytype, geometry_type_id::POLYGON); - - EXPECT_THROW(pairwise_linestring_polygon_distance(points_view, polygons_view), - cuspatial::logic_error); + EXPECT_THROW( + pairwise_linestring_polygon_distance(EmptyGeometryColumnBase::empty_point(), + EmptyGeometryColumnBase::empty_polygon()), + cuspatial::logic_error); }; diff --git a/cpp/tests/distance/point_distance_test.cpp b/cpp/tests/distance/point_distance_test.cpp index d16e2b5b1..c7d2b6400 100644 --- a/cpp/tests/distance/point_distance_test.cpp +++ b/cpp/tests/distance/point_distance_test.cpp @@ -14,25 +14,21 @@ * limitations under the License. */ +#include + #include #include -#include - -#include -#include - -#include -#include #include -namespace cuspatial { +using namespace cuspatial; +using namespace cuspatial::test; using namespace cudf; using namespace cudf::test; template -struct PairwisePointDistanceTest : public ::testing::Test {}; +struct PairwisePointDistanceTest : public EmptyGeometryColumnFixture {}; using TestTypes = ::testing::Types; @@ -40,103 +36,58 @@ TYPED_TEST_CASE(PairwisePointDistanceTest, TestTypes); TYPED_TEST(PairwisePointDistanceTest, SingleToSingleEmpty) { - using T = TypeParam; - - auto offset1 = std::nullopt; - auto offset2 = std::nullopt; - - auto xy1 = fixed_width_column_wrapper{}; - auto xy2 = fixed_width_column_wrapper{}; - - auto expect = fixed_width_column_wrapper{}; - - auto got = pairwise_point_distance(offset1, xy1, offset2, xy2); - + auto got = pairwise_point_distance(this->empty_point(), this->empty_point()); + auto expect = fixed_width_column_wrapper{}; CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } TYPED_TEST(PairwisePointDistanceTest, SingleToMultiEmpty) { - using T = TypeParam; - - auto offset1 = std::nullopt; - column_view offset2 = fixed_width_column_wrapper{0}; - - auto xy1 = fixed_width_column_wrapper{}; - auto xy2 = fixed_width_column_wrapper{}; - - auto expect = fixed_width_column_wrapper{}; - - auto got = pairwise_point_distance(offset1, xy1, offset2, xy2); - + auto got = pairwise_point_distance(this->empty_point(), this->empty_multipoint()); + auto expect = fixed_width_column_wrapper{}; CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } TYPED_TEST(PairwisePointDistanceTest, MultiToSingleEmpty) { - using T = TypeParam; - - column_view offset1 = fixed_width_column_wrapper{0}; - auto offset2 = std::nullopt; - - auto xy1 = fixed_width_column_wrapper{}; - auto xy2 = fixed_width_column_wrapper{}; - - auto expect = fixed_width_column_wrapper{}; - - auto got = pairwise_point_distance(offset1, xy1, offset2, xy2); - + auto got = pairwise_point_distance(this->empty_point(), this->empty_multipoint()); + auto expect = fixed_width_column_wrapper{}; CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } TYPED_TEST(PairwisePointDistanceTest, MultiToMultiEmpty) { - using T = TypeParam; - - column_view offset1 = fixed_width_column_wrapper{0}; - column_view offset2 = fixed_width_column_wrapper{0}; - - auto xy1 = fixed_width_column_wrapper{}; - auto xy2 = fixed_width_column_wrapper{}; - - auto expect = fixed_width_column_wrapper{}; - - auto got = pairwise_point_distance(offset1, xy1, offset2, xy2); - + auto got = pairwise_point_distance(this->empty_multipoint(), this->empty_multipoint()); + auto expect = fixed_width_column_wrapper{}; CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -struct PairwisePointDistanceTestThrow : public ::testing::Test {}; +struct PairwisePointDistanceFailOnSizeTest : public EmptyAndOneGeometryColumnFixture {}; -TEST_F(PairwisePointDistanceTestThrow, SizeMismatch) +TEST_F(PairwisePointDistanceFailOnSizeTest, SizeMismatch) { - column_view offset1 = fixed_width_column_wrapper{0, 3}; - column_view offset2 = fixed_width_column_wrapper{0}; - - auto xy1 = fixed_width_column_wrapper{1, 1, 2, 2, 3, 3}; - auto xy2 = fixed_width_column_wrapper{}; - - EXPECT_THROW(pairwise_point_distance(offset1, xy1, offset2, xy2), cuspatial::logic_error); + EXPECT_THROW(pairwise_point_distance(this->empty_point(), this->one_point()), + cuspatial::logic_error); } -TEST_F(PairwisePointDistanceTestThrow, SizeMismatch2) +TEST_F(PairwisePointDistanceFailOnSizeTest, SizeMismatch2) { - column_view offset1 = fixed_width_column_wrapper{0, 3}; - auto offset2 = std::nullopt; + EXPECT_THROW(pairwise_point_distance(this->one_point(), this->empty_multipoint()), + cuspatial::logic_error); +} - auto xy1 = fixed_width_column_wrapper{1, 1, 2, 2, 3, 3}; - auto xy2 = fixed_width_column_wrapper{}; +struct PairwisePointDistanceFailOnTypeTest : public EmptyGeometryColumnFixtureMultipleTypes {}; - EXPECT_THROW(pairwise_point_distance(offset1, xy1, offset2, xy2), cuspatial::logic_error); +TEST_F(PairwisePointDistanceFailOnTypeTest, CoordinateTypeMismatch) +{ + EXPECT_THROW(pairwise_point_distance(EmptyGeometryColumnBase::empty_point(), + EmptyGeometryColumnBase::empty_point()), + cuspatial::logic_error); } -TEST_F(PairwisePointDistanceTestThrow, TypeMismatch) +TEST_F(PairwisePointDistanceFailOnTypeTest, GeometryTypeMismatch) { - auto offset1 = std::nullopt; - auto offset2 = std::nullopt; - auto xy1 = fixed_width_column_wrapper{1, 1, 2, 2, 3, 3}; - auto xy2 = fixed_width_column_wrapper{1, 1, 2, 2, 3, 3}; - - EXPECT_THROW(pairwise_point_distance(offset1, xy1, offset2, xy2), cuspatial::logic_error); + EXPECT_THROW(pairwise_point_distance(EmptyGeometryColumnBase::empty_point(), + EmptyGeometryColumnBase::empty_polygon()), + cuspatial::logic_error); } -} // namespace cuspatial diff --git a/cpp/tests/distance/point_linestring_distance_test.cpp b/cpp/tests/distance/point_linestring_distance_test.cpp index e35efa260..bcbca0bd6 100644 --- a/cpp/tests/distance/point_linestring_distance_test.cpp +++ b/cpp/tests/distance/point_linestring_distance_test.cpp @@ -14,107 +14,83 @@ * limitations under the License. */ +#include + #include #include -#include - -#include -#include - -#include -#include #include -namespace cuspatial { +using namespace cuspatial; +using namespace cuspatial::test; using namespace cudf; using namespace cudf::test; template -struct PairwisePointLinestringDistanceTest : public ::testing::Test {}; +struct PairwisePointLineStringDistanceTest : public EmptyGeometryColumnFixture {}; using TestTypes = ::testing::Types; -TYPED_TEST_CASE(PairwisePointLinestringDistanceTest, TestTypes); +TYPED_TEST_CASE(PairwisePointLineStringDistanceTest, TestTypes); -TYPED_TEST(PairwisePointLinestringDistanceTest, EmptySingleComponent) +TYPED_TEST(PairwisePointLineStringDistanceTest, SingleToSingleEmpty) { - using T = TypeParam; - - auto xy = fixed_width_column_wrapper{}; - auto offset = fixed_width_column_wrapper{0}; - auto line_xy = fixed_width_column_wrapper{}; - - auto expect = fixed_width_column_wrapper{}; - auto got = pairwise_point_linestring_distance( - std::nullopt, xy, std::nullopt, column_view(offset), line_xy); - + auto got = pairwise_point_linestring_distance(this->empty_point(), this->empty_linestring()); + auto expect = fixed_width_column_wrapper{}; CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -TYPED_TEST(PairwisePointLinestringDistanceTest, EmptyMultiComponent) +TYPED_TEST(PairwisePointLineStringDistanceTest, SingleToMultiEmpty) { - using T = TypeParam; - - auto multipoint_offset = fixed_width_column_wrapper{0}; - auto xy = fixed_width_column_wrapper{}; - auto multilinestring_offset = fixed_width_column_wrapper{0}; - auto offset = fixed_width_column_wrapper{0}; - auto line_xy = fixed_width_column_wrapper{}; - - auto expect = fixed_width_column_wrapper{}; - auto got = pairwise_point_linestring_distance(column_view(multipoint_offset), - xy, - column_view(multilinestring_offset), - column_view(offset), - line_xy); - + auto got = pairwise_point_linestring_distance(this->empty_point(), this->empty_multilinestring()); + auto expect = fixed_width_column_wrapper{}; CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -TYPED_TEST(PairwisePointLinestringDistanceTest, OnePairMultiPointMultiLinestring) +TYPED_TEST(PairwisePointLineStringDistanceTest, MultiToSingleEmpty) { - using T = TypeParam; - - auto multipoint_offset = fixed_width_column_wrapper{0, 2}; - auto xy = fixed_width_column_wrapper{0.0, 0.0, 0.5, 0.5}; - auto multilinestring_offset = fixed_width_column_wrapper{0, 1}; - auto offset = fixed_width_column_wrapper{0, 2}; - auto line_xy = fixed_width_column_wrapper{1.0, 0.0, 0.0, 1.0}; - - auto expect = fixed_width_column_wrapper{0.0}; - auto got = pairwise_point_linestring_distance(column_view(multipoint_offset), - xy, - column_view(multilinestring_offset), - column_view(offset), - line_xy); + auto got = pairwise_point_linestring_distance(this->empty_multipoint(), this->empty_linestring()); + auto expect = fixed_width_column_wrapper{}; + CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); +} +TYPED_TEST(PairwisePointLineStringDistanceTest, MultiToMultiEmpty) +{ + auto got = + pairwise_point_linestring_distance(this->empty_multipoint(), this->empty_multilinestring()); + auto expect = fixed_width_column_wrapper{}; CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got); } -struct PairwisePointLinestringDistanceTestThrow : public ::testing::Test {}; +struct PairwisePointLineStringDistanceFailOnSizeTest : public EmptyAndOneGeometryColumnFixture {}; -TEST_F(PairwisePointLinestringDistanceTestThrow, PointTypeMismatch) +TEST_F(PairwisePointLineStringDistanceFailOnSizeTest, SizeMismatch) { - auto xy = fixed_width_column_wrapper{1, 1, 2, 2, 3, 3}; - auto offset = fixed_width_column_wrapper{0, 6}; - auto line_xy = fixed_width_column_wrapper{1, 1, 2, 2, 3, 3}; + EXPECT_THROW(pairwise_point_linestring_distance(this->empty_point(), this->one_linestring()), + cuspatial::logic_error); +} - EXPECT_THROW(pairwise_point_linestring_distance( - std::nullopt, xy, std::nullopt, column_view(offset), line_xy), +TEST_F(PairwisePointLineStringDistanceFailOnSizeTest, SizeMismatch2) +{ + EXPECT_THROW(pairwise_point_linestring_distance(this->one_point(), this->empty_multilinestring()), cuspatial::logic_error); } -TEST_F(PairwisePointLinestringDistanceTestThrow, ContainsNull) +struct PairwisePointLineStringDistanceFailOnTypeTest + : public EmptyGeometryColumnFixtureMultipleTypes {}; + +TEST_F(PairwisePointLineStringDistanceFailOnTypeTest, CoordinateTypeMismatch) { - auto xy = fixed_width_column_wrapper{{1, 1, 2, 2, 3, 3}, {1, 0, 1, 1, 1, 1}}; - auto offset = fixed_width_column_wrapper{0, 6}; - auto line_xy = fixed_width_column_wrapper{1, 2, 3, 1, 2, 3}; + EXPECT_THROW( + pairwise_point_linestring_distance(EmptyGeometryColumnBase::empty_point(), + EmptyGeometryColumnBase::empty_linestring()), + cuspatial::logic_error); +} - EXPECT_THROW(pairwise_point_linestring_distance( - std::nullopt, xy, std::nullopt, column_view(offset), line_xy), +TEST_F(PairwisePointLineStringDistanceFailOnTypeTest, GeometryTypeMismatch) +{ + EXPECT_THROW(pairwise_point_linestring_distance(EmptyGeometryColumnBase::empty_point(), + EmptyGeometryColumnBase::empty_polygon()), cuspatial::logic_error); } - -} // namespace cuspatial diff --git a/python/cuspatial/cuspatial/_lib/CMakeLists.txt b/python/cuspatial/cuspatial/_lib/CMakeLists.txt index 4a1530d9b..e124dfb86 100644 --- a/python/cuspatial/cuspatial/_lib/CMakeLists.txt +++ b/python/cuspatial/cuspatial/_lib/CMakeLists.txt @@ -13,13 +13,12 @@ # ============================================================================= set(cython_sources - pairwise_multipoint_equals_count.pyx distance.pyx - hausdorff.pyx intersection.pyx nearest_points.pyx point_in_polygon.pyx points_in_range.pyx + pairwise_multipoint_equals_count.pyx pairwise_point_in_polygon.pyx polygon_bounding_boxes.pyx linestring_bounding_boxes.pyx diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance.pxd new file mode 100644 index 000000000..1af0f97e0 --- /dev/null +++ b/python/cuspatial/cuspatial/_lib/cpp/distance.pxd @@ -0,0 +1,59 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +from libcpp.memory cimport unique_ptr +from libcpp.utility cimport pair + +from cudf._lib.cpp.column.column cimport column +from cudf._lib.cpp.column.column_view cimport column_view +from cudf._lib.cpp.table.table_view cimport table_view + +from cuspatial._lib.cpp.column.geometry_column_view cimport ( + geometry_column_view, +) + + +cdef extern from "cuspatial/distance.hpp" \ + namespace "cuspatial" nogil: + + cdef pair[unique_ptr[column], table_view] directed_hausdorff_distance( + const column_view& xs, + const column_view& ys, + const column_view& space_offsets + ) except + + + cdef unique_ptr[column] haversine_distance( + const column_view& a_lon, + const column_view& a_lat, + const column_view& b_lon, + const column_view& b_lat + ) except + + + cdef unique_ptr[column] pairwise_point_distance( + const geometry_column_view & multipoints1, + const geometry_column_view & multipoints2 + ) except + + + cdef unique_ptr[column] pairwise_point_linestring_distance( + const geometry_column_view & multipoints, + const geometry_column_view & multilinestrings + ) except + + + cdef unique_ptr[column] pairwise_point_polygon_distance( + const geometry_column_view & multipoints, + const geometry_column_view & multipolygons + ) except + + + cdef unique_ptr[column] pairwise_linestring_distance( + const geometry_column_view & multilinestrings1, + const geometry_column_view & multilinestrings2 + ) except + + + cdef unique_ptr[column] pairwise_linestring_polygon_distance( + const geometry_column_view & multilinestrings, + const geometry_column_view & multipolygons + ) except + + + cdef unique_ptr[column] pairwise_polygon_distance( + const geometry_column_view & multipolygons1, + const geometry_column_view & multipolygons2 + ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/__init__.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/__init__.pxd deleted file mode 100644 index e69de29bb..000000000 diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/__init__.pyx b/python/cuspatial/cuspatial/_lib/cpp/distance/__init__.pyx deleted file mode 100644 index e69de29bb..000000000 diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd deleted file mode 100644 index 7fcebe35f..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/hausdorff.pxd +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2020-2023, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr -from libcpp.utility cimport pair - -from cudf._lib.cpp.column.column cimport column -from cudf._lib.cpp.column.column_view cimport column_view -from cudf._lib.cpp.table.table_view cimport table_view - - -cdef extern from "cuspatial/distance.hpp" \ - namespace "cuspatial" nogil: - - cdef pair[unique_ptr[column], table_view] directed_hausdorff_distance( - const column_view& xs, - const column_view& ys, - const column_view& space_offsets - ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd deleted file mode 100644 index 236c919fc..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/haversine.pxd +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2019-2023, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr - -from cudf._lib.column cimport column, column_view - - -cdef extern from "cuspatial/distance.hpp" \ - namespace "cuspatial" nogil: - cdef unique_ptr[column] haversine_distance( - const column_view& a_lon, - const column_view& a_lat, - const column_view& b_lon, - const column_view& b_lat - ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd deleted file mode 100644 index 3c14745c5..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_distance.pxd +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2022-2023, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr - -from cudf._lib.column cimport Column -from cudf._lib.cpp.column.column cimport column -from cudf._lib.cpp.column.column_view cimport column_view - -from cuspatial._lib.cpp.optional cimport optional - - -cdef extern from "cuspatial/distance.hpp" \ - namespace "cuspatial" nogil: - cdef unique_ptr[column] pairwise_linestring_distance( - const optional[column_view] multilinestring1_geometry_offsets, - const column_view linestring1_part_offsets, - const column_view linestring1_points_xy, - const optional[column_view] multilinestring2_geometry_offsets, - const column_view linestring2_part_offsets, - const column_view linestring2_points_xy - ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd deleted file mode 100644 index 8505a380f..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/linestring_polygon_distance.pxd +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2023, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr - -from cudf._lib.cpp.column.column cimport column - -from cuspatial._lib.cpp.column.geometry_column_view cimport ( - geometry_column_view, -) - - -cdef extern from "cuspatial/distance.hpp" \ - namespace "cuspatial" nogil: - cdef unique_ptr[column] pairwise_linestring_polygon_distance( - const geometry_column_view & multilinestrings, - const geometry_column_view & multipolygons - ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd deleted file mode 100644 index 7b6a921b6..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2022-2023, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr - -from cudf._lib.column cimport Column -from cudf._lib.cpp.column.column cimport column -from cudf._lib.cpp.column.column_view cimport column_view -from cudf._lib.cpp.types cimport size_type - -from cuspatial._lib.cpp.optional cimport optional - - -cdef extern from "cuspatial/distance.hpp" \ - namespace "cuspatial" nogil: - cdef unique_ptr[column] pairwise_point_distance( - const optional[column_view] multipoint1_offsets, - const column_view point1_xy, - const optional[column_view] multipoint2_offsets, - const column_view point2_xy - ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd deleted file mode 100644 index 56d431875..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/point_linestring_distance.pxd +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2022-2023, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr - -from cudf._lib.column cimport Column -from cudf._lib.cpp.column.column cimport column -from cudf._lib.cpp.column.column_view cimport column_view -from cudf._lib.cpp.types cimport size_type - -from cuspatial._lib.cpp.optional cimport optional - - -cdef extern from "cuspatial/distance.hpp" \ - namespace "cuspatial" nogil: - cdef unique_ptr[column] pairwise_point_linestring_distance( - const optional[column_view] multipoint_geometry_offsets, - const column_view points_xy, - const optional[column_view] multilinestring_geometry_offsets, - const column_view linestring_part_offsets, - const column_view linestring_points_xy, - ) except + diff --git a/python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd b/python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd deleted file mode 100644 index 63f659184..000000000 --- a/python/cuspatial/cuspatial/_lib/cpp/distance/point_polygon_distance.pxd +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2023, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr - -from cudf._lib.cpp.column.column cimport column - -from cuspatial._lib.cpp.column.geometry_column_view cimport ( - geometry_column_view, -) - - -cdef extern from "cuspatial/distance.hpp" \ - namespace "cuspatial" nogil: - cdef unique_ptr[column] pairwise_point_polygon_distance( - const geometry_column_view & multipoints, - const geometry_column_view & multipolygons - ) except + diff --git a/python/cuspatial/cuspatial/_lib/distance.pyx b/python/cuspatial/cuspatial/_lib/distance.pyx index 7edf19754..cf61773e0 100644 --- a/python/cuspatial/cuspatial/_lib/distance.pyx +++ b/python/cuspatial/cuspatial/_lib/distance.pyx @@ -1,120 +1,159 @@ # Copyright (c) 2022-2023, NVIDIA CORPORATION. from libcpp.memory cimport make_shared, shared_ptr, unique_ptr -from libcpp.utility cimport move +from libcpp.utility cimport move, pair from cudf._lib.column cimport Column from cudf._lib.cpp.column.column cimport column from cudf._lib.cpp.column.column_view cimport column_view +from cudf._lib.cpp.table.table_view cimport table_view +from cudf._lib.utils cimport columns_from_table_view from cuspatial._lib.cpp.column.geometry_column_view cimport ( geometry_column_view, ) -from cuspatial._lib.cpp.distance.linestring_distance cimport ( +from cuspatial._lib.cpp.distance cimport ( + directed_hausdorff_distance as directed_cpp_hausdorff_distance, + haversine_distance as cpp_haversine_distance, pairwise_linestring_distance as c_pairwise_linestring_distance, -) -from cuspatial._lib.cpp.distance.linestring_polygon_distance cimport ( pairwise_linestring_polygon_distance as c_pairwise_line_poly_dist, -) -from cuspatial._lib.cpp.distance.point_distance cimport ( pairwise_point_distance as c_pairwise_point_distance, -) -from cuspatial._lib.cpp.distance.point_linestring_distance cimport ( pairwise_point_linestring_distance as c_pairwise_point_linestring_distance, -) -from cuspatial._lib.cpp.distance.point_polygon_distance cimport ( pairwise_point_polygon_distance as c_pairwise_point_polygon_distance, -) -from cuspatial._lib.cpp.distance.polygon_distance cimport ( pairwise_polygon_distance as c_pairwise_polygon_distance, ) -from cuspatial._lib.cpp.optional cimport optional from cuspatial._lib.cpp.types cimport collection_type_id, geometry_type_id from cuspatial._lib.types cimport collection_type_py_to_c -from cuspatial._lib.utils cimport unwrap_pyoptcol + + +cpdef haversine_distance(Column x1, Column y1, Column x2, Column y2): + cdef column_view c_x1 = x1.view() + cdef column_view c_y1 = y1.view() + cdef column_view c_x2 = x2.view() + cdef column_view c_y2 = y2.view() + + cdef unique_ptr[column] c_result + + with nogil: + c_result = move(cpp_haversine_distance(c_x1, c_y1, c_x2, c_y2)) + + return Column.from_unique_ptr(move(c_result)) + + +def directed_hausdorff_distance( + Column xs, + Column ys, + Column space_offsets, +): + cdef column_view c_xs = xs.view() + cdef column_view c_ys = ys.view() + cdef column_view c_shape_offsets = space_offsets.view() + + cdef pair[unique_ptr[column], table_view] result + + with nogil: + result = move( + directed_cpp_hausdorff_distance( + c_xs, + c_ys, + c_shape_offsets, + ) + ) + + owner = Column.from_unique_ptr(move(result.first), data_ptr_exposed=True) + + return columns_from_table_view( + result.second, + owners=[owner] * result.second.num_columns() + ) def pairwise_point_distance( - Column points1_xy, - Column points2_xy, - multipoint1_offsets=None, - multipoint2_offsets=None, + lhs_point_collection_type, + rhs_point_collection_type, + Column points1, + Column points2, ): - cdef optional[column_view] c_multipoints1_offset = unwrap_pyoptcol( - multipoint1_offsets) - cdef optional[column_view] c_multipoints2_offset = unwrap_pyoptcol( - multipoint2_offsets) + cdef collection_type_id lhs_point_multi_type = collection_type_py_to_c( + lhs_point_collection_type + ) + cdef collection_type_id rhs_point_multi_type = collection_type_py_to_c( + rhs_point_collection_type + ) + cdef shared_ptr[geometry_column_view] c_multipoints_lhs = \ + make_shared[geometry_column_view]( + points1.view(), + lhs_point_multi_type, + geometry_type_id.POINT) + cdef shared_ptr[geometry_column_view] c_multipoints_rhs = \ + make_shared[geometry_column_view]( + points2.view(), + rhs_point_multi_type, + geometry_type_id.POINT) - cdef column_view c_points1_xy = points1_xy.view() - cdef column_view c_points2_xy = points2_xy.view() cdef unique_ptr[column] c_result with nogil: c_result = move(c_pairwise_point_distance( - c_multipoints1_offset, - c_points1_xy, - c_multipoints2_offset, - c_points2_xy, + c_multipoints_lhs.get()[0], + c_multipoints_rhs.get()[0], )) return Column.from_unique_ptr(move(c_result)) def pairwise_linestring_distance( - Column linestring1_part_offsets, - Column linestring1_points_xy, - Column linestring2_part_offsets, - Column linestring2_points_xy, - multilinestring1_geometry_offsets=None, - multilinestring2_geometry_offsets=None + Column multilinestrings1, + Column multilinestrings2 ): - cdef optional[column_view] c_mls1_geometry_offsets = unwrap_pyoptcol( - multilinestring1_geometry_offsets) - cdef optional[column_view] c_mls2_geometry_offsets = unwrap_pyoptcol( - multilinestring2_geometry_offsets) - cdef column_view linestring1_offsets_view = linestring1_part_offsets.view() - cdef column_view linestring1_points_xy_view = linestring1_points_xy.view() - cdef column_view linestring2_offsets_view = linestring2_part_offsets.view() - cdef column_view linestring2_points_xy_view = linestring2_points_xy.view() + cdef shared_ptr[geometry_column_view] c_multilinestring_lhs = \ + make_shared[geometry_column_view]( + multilinestrings1.view(), + collection_type_id.MULTI, + geometry_type_id.LINESTRING) + cdef shared_ptr[geometry_column_view] c_multilinestring_rhs = \ + make_shared[geometry_column_view]( + multilinestrings2.view(), + collection_type_id.MULTI, + geometry_type_id.LINESTRING) cdef unique_ptr[column] c_result + with nogil: c_result = move(c_pairwise_linestring_distance( - c_mls1_geometry_offsets, - linestring1_offsets_view, - linestring1_points_xy_view, - c_mls2_geometry_offsets, - linestring2_offsets_view, - linestring2_points_xy_view, + c_multilinestring_lhs.get()[0], + c_multilinestring_rhs.get()[0], )) return Column.from_unique_ptr(move(c_result)) def pairwise_point_linestring_distance( - Column points_xy, - Column linestring_part_offsets, - Column linestring_points_xy, - multipoint_geometry_offset=None, - multilinestring_geometry_offset=None, + point_collection_type, + Column points, + Column linestrings, ): - cdef optional[column_view] c_multipoint_parts_offset = unwrap_pyoptcol( - multipoint_geometry_offset) - cdef optional[column_view] c_multilinestring_parts_offset = ( - unwrap_pyoptcol(multilinestring_geometry_offset)) - - cdef column_view c_points_xy = points_xy.view() - cdef column_view c_linestring_offsets = linestring_part_offsets.view() - cdef column_view c_linestring_points_xy = linestring_points_xy.view() + cdef collection_type_id points_multi_type = collection_type_py_to_c( + point_collection_type + ) + cdef shared_ptr[geometry_column_view] c_points = \ + make_shared[geometry_column_view]( + points.view(), + points_multi_type, + geometry_type_id.POINT) + cdef shared_ptr[geometry_column_view] c_multilinestrings = \ + make_shared[geometry_column_view]( + linestrings.view(), + collection_type_id.MULTI, + geometry_type_id.LINESTRING) + cdef unique_ptr[column] c_result with nogil: c_result = move(c_pairwise_point_linestring_distance( - c_multipoint_parts_offset, - c_points_xy, - c_multilinestring_parts_offset, - c_linestring_offsets, - c_linestring_points_xy, + c_points.get()[0], + c_multilinestrings.get()[0], )) + return Column.from_unique_ptr(move(c_result)) @@ -123,15 +162,14 @@ def pairwise_point_polygon_distance( Column multipoints, Column multipolygons ): - - cdef collection_type_id point_multi_type = collection_type_py_to_c( + cdef collection_type_id points_multi_type = collection_type_py_to_c( point_collection_type ) cdef shared_ptr[geometry_column_view] c_multipoints = \ make_shared[geometry_column_view]( multipoints.view(), - point_multi_type, + points_multi_type, geometry_type_id.POINT) cdef shared_ptr[geometry_column_view] c_multipolygons = \ @@ -154,7 +192,6 @@ def pairwise_linestring_polygon_distance( Column multilinestrings, Column multipolygons ): - cdef shared_ptr[geometry_column_view] c_multilinestrings = \ make_shared[geometry_column_view]( multilinestrings.view(), diff --git a/python/cuspatial/cuspatial/_lib/hausdorff.pyx b/python/cuspatial/cuspatial/_lib/hausdorff.pyx deleted file mode 100644 index caa5121d0..000000000 --- a/python/cuspatial/cuspatial/_lib/hausdorff.pyx +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2019, NVIDIA CORPORATION. - -from libcpp.memory cimport unique_ptr -from libcpp.utility cimport move, pair - -from cudf._lib.column cimport Column, column, column_view -from cudf._lib.cpp.table.table_view cimport table_view -from cudf._lib.utils cimport columns_from_table_view - -from cuspatial._lib.cpp.distance.hausdorff cimport ( - directed_hausdorff_distance as directed_cpp_hausdorff_distance, -) - - -def directed_hausdorff_distance( - Column xs, - Column ys, - Column space_offsets, -): - cdef column_view c_xs = xs.view() - cdef column_view c_ys = ys.view() - cdef column_view c_shape_offsets = space_offsets.view() - - cdef pair[unique_ptr[column], table_view] result - - with nogil: - result = move( - directed_cpp_hausdorff_distance( - c_xs, - c_ys, - c_shape_offsets, - ) - ) - - owner = Column.from_unique_ptr(move(result.first), data_ptr_exposed=True) - - return columns_from_table_view( - result.second, - owners=[owner] * result.second.num_columns() - ) diff --git a/python/cuspatial/cuspatial/_lib/spatial.pyx b/python/cuspatial/cuspatial/_lib/spatial.pyx index d2922dd4a..916d66cec 100644 --- a/python/cuspatial/cuspatial/_lib/spatial.pyx +++ b/python/cuspatial/cuspatial/_lib/spatial.pyx @@ -8,28 +8,11 @@ from cudf._lib.column cimport Column from cudf._lib.cpp.column.column cimport column from cudf._lib.cpp.column.column_view cimport column_view -from cuspatial._lib.cpp.distance.haversine cimport ( - haversine_distance as cpp_haversine_distance, -) from cuspatial._lib.cpp.projection cimport ( sinusoidal_projection as cpp_sinusoidal_projection, ) -cpdef haversine_distance(Column x1, Column y1, Column x2, Column y2): - cdef column_view c_x1 = x1.view() - cdef column_view c_y1 = y1.view() - cdef column_view c_x2 = x2.view() - cdef column_view c_y2 = y2.view() - - cdef unique_ptr[column] c_result - - with nogil: - c_result = move(cpp_haversine_distance(c_x1, c_y1, c_x2, c_y2)) - - return Column.from_unique_ptr(move(c_result)) - - def sinusoidal_projection( double origin_lon, double origin_lat, diff --git a/python/cuspatial/cuspatial/core/spatial/distance.py b/python/cuspatial/cuspatial/core/spatial/distance.py index d4188425e..5ab1d1c7b 100644 --- a/python/cuspatial/cuspatial/core/spatial/distance.py +++ b/python/cuspatial/cuspatial/core/spatial/distance.py @@ -1,12 +1,12 @@ # Copyright (c) 2022-2023, NVIDIA CORPORATION. -from typing import Tuple - import cudf from cudf import DataFrame, Series from cudf.core.column import as_column from cuspatial._lib.distance import ( + directed_hausdorff_distance as cpp_directed_hausdorff_distance, + haversine_distance as cpp_haversine_distance, pairwise_linestring_distance as cpp_pairwise_linestring_distance, pairwise_linestring_polygon_distance as c_pairwise_line_poly_dist, pairwise_point_distance as cpp_pairwise_point_distance, @@ -14,10 +14,6 @@ pairwise_point_polygon_distance as c_pairwise_point_polygon_distance, pairwise_polygon_distance as c_pairwise_polygon_distance, ) -from cuspatial._lib.hausdorff import ( - directed_hausdorff_distance as cpp_directed_hausdorff_distance, -) -from cuspatial._lib.spatial import haversine_distance as cpp_haversine_distance from cuspatial._lib.types import CollectionType from cuspatial.core.geoseries import GeoSeries from cuspatial.utils.column_utils import ( @@ -176,6 +172,7 @@ def pairwise_point_distance(points1: GeoSeries, points2: GeoSeries): raise ValueError("`points1` array must contain only points") if not contains_only_points(points2): raise ValueError("`points2` array must contain only points") + if (len(points1.points.xy) > 0 and len(points1.multipoints.xy) > 0) or ( len(points2.points.xy) > 0 and len(points2.multipoints.xy) > 0 ): @@ -183,15 +180,22 @@ def pairwise_point_distance(points1: GeoSeries, points2: GeoSeries): "Mixing point and multipoint geometries is not supported" ) - points1_xy, points1_geometry_offsets = _flatten_point_series(points1) - points2_xy, points2_geometry_offsets = _flatten_point_series(points2) + ( + lhs_column, + lhs_point_collection_type, + ) = _extract_point_column_and_collection_type(points1) + ( + rhs_column, + rhs_point_collection_type, + ) = _extract_point_column_and_collection_type(points2) + return Series._from_data( { None: cpp_pairwise_point_distance( - points1_xy, - points2_xy, - points1_geometry_offsets, - points2_geometry_offsets, + lhs_point_collection_type, + rhs_point_collection_type, + lhs_column, + rhs_column, ) } ) @@ -250,15 +254,22 @@ def pairwise_linestring_distance( if len(multilinestrings1) == 0: return cudf.Series(dtype="float64") + if not contains_only_linestrings( + multilinestrings1 + ) or not contains_only_linestrings(multilinestrings2): + raise ValueError( + "`multilinestrings1` and `multilinestrings2` must contain only " + "linestrings" + ) + + if len(multilinestrings1) == 0: + return cudf.Series(dtype="float64") + return Series._from_data( { None: cpp_pairwise_linestring_distance( - as_column(multilinestrings1.lines.part_offset), - as_column(multilinestrings1.lines.xy), - as_column(multilinestrings2.lines.part_offset), - as_column(multilinestrings2.lines.xy), - as_column(multilinestrings1.lines.geometry_offset), - as_column(multilinestrings2.lines.geometry_offset), + multilinestrings1.lines.column(), + multilinestrings2.lines.column(), ) } ) @@ -369,16 +380,17 @@ def pairwise_point_linestring_distance( "Mixing point and multipoint geometries is not supported" ) - point_xy_col, points_geometry_offset = _flatten_point_series(points) + ( + point_column, + point_collection_type, + ) = _extract_point_column_and_collection_type(points) return Series._from_data( { None: c_pairwise_point_linestring_distance( - point_xy_col, - as_column(linestrings.lines.part_offset), - linestrings.lines.xy._column, - points_geometry_offset, - as_column(linestrings.lines.geometry_offset), + point_collection_type, + point_column, + linestrings.lines.column(), ) } ) @@ -452,18 +464,10 @@ def pairwise_point_polygon_distance(points: GeoSeries, polygons: GeoSeries): "Mixing point and multipoint geometries is not supported" ) - point_collection_type = ( - CollectionType.SINGLE - if len(points.points.xy > 0) - else CollectionType.MULTI - ) - - # Handle slicing in geoseries - if point_collection_type == CollectionType.SINGLE: - points_column = points.points.column() - else: - points_column = points.multipoints.column() - + ( + points_column, + point_collection_type, + ) = _extract_point_column_and_collection_type(points) polygon_column = polygons.polygons.column() return Series._from_data( @@ -629,15 +633,15 @@ def pairwise_polygon_distance(polygons1: GeoSeries, polygons2: GeoSeries): ) -def _flatten_point_series( - points: GeoSeries, -) -> Tuple[ - cudf.core.column.column.ColumnBase, cudf.core.column.column.ColumnBase -]: - """Given a geoseries of (multi)points, extract the offset and x/y column""" - if len(points.points.xy) > 0: - return points.points.xy._column, None - return ( - points.multipoints.xy._column, - as_column(points.multipoints.geometry_offset), +def _extract_point_column_and_collection_type(s: GeoSeries): + """Given a GeoSeries that contains only points or multipoints, return + the point or multipoint column and the collection type of the GeoSeries. + """ + point_collection_type = ( + CollectionType.SINGLE if len(s.points.xy > 0) else CollectionType.MULTI ) + + if point_collection_type == CollectionType.SINGLE: + return s.points.column(), point_collection_type + else: + return s.multipoints.column(), point_collection_type From 49734176fa732e6bce9aa49713bcbf31261951a1 Mon Sep 17 00:00:00 2001 From: Ray Douglass Date: Fri, 19 May 2023 09:50:46 -0400 Subject: [PATCH 24/63] DOC --- .github/workflows/build.yaml | 8 +++--- .github/workflows/pr.yaml | 16 ++++++------ .github/workflows/test.yaml | 4 +-- ci/build_docs.sh | 2 +- .../all_cuda-118_arch-x86_64.yaml | 10 +++---- cpp/CMakeLists.txt | 2 +- cpp/doxygen/Doxyfile | 4 +-- dependencies.yaml | 26 +++++++++---------- docs/source/conf.py | 4 +-- fetch_rapids.cmake | 2 +- python/cuspatial/CMakeLists.txt | 2 +- 11 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 25a77b783..14cf2fbca 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ concurrency: jobs: cpp-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -37,7 +37,7 @@ jobs: python-build: needs: [cpp-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -46,7 +46,7 @@ jobs: upload-conda: needs: [cpp-build, python-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -56,7 +56,7 @@ jobs: if: github.ref_type == 'branch' && github.event_name == 'push' needs: python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 with: build_type: branch node_type: "gpu-v100-latest-1" diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 7e14bc978..d35ae5d99 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -20,40 +20,40 @@ jobs: - conda-notebook-tests - docs-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.08 checks: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@branch-23.08 with: enable_check_generated_files: false conda-cpp-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 with: build_type: pull-request conda-cpp-tests: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 with: build_type: pull-request conda-python-build: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 with: build_type: pull-request conda-python-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 with: build_type: pull-request conda-notebook-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -63,7 +63,7 @@ jobs: docs-build: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 with: build_type: pull-request node_type: "gpu-v100-latest-1" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index eb3cb4d94..a3db4e124 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,7 +16,7 @@ on: jobs: conda-cpp-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 with: build_type: nightly branch: ${{ inputs.branch }} @@ -24,7 +24,7 @@ jobs: sha: ${{ inputs.sha }} conda-python-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 with: build_type: nightly branch: ${{ inputs.branch }} diff --git a/ci/build_docs.sh b/ci/build_docs.sh index 1972c931a..6b97527a1 100755 --- a/ci/build_docs.sh +++ b/ci/build_docs.sh @@ -19,7 +19,7 @@ rapids-print-env rapids-logger "Downloading artifacts from previous jobs" CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp) PYTHON_CHANNEL=$(rapids-download-conda-from-s3 python) -VERSION_NUMBER="23.06" +VERSION_NUMBER="23.08" rapids-mamba-retry install \ --channel "${CPP_CHANNEL}" \ diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 5fda0d096..0fbe91c42 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -9,8 +9,8 @@ dependencies: - c-compiler - cmake>=3.23.1,!=3.25.0 - cudatoolkit=11.8 -- cudf==23.6.* -- cuml==23.6.* +- cudf==23.8.* +- cuml==23.8.* - cxx-compiler - cython>=0.29,<0.30 - doxygen @@ -20,8 +20,8 @@ dependencies: - gtest>=1.13.0 - ipython - ipywidgets -- libcudf==23.6.* -- librmm==23.6.* +- libcudf==23.8.* +- librmm==23.8.* - myst-parser - nbsphinx - ninja @@ -35,7 +35,7 @@ dependencies: - pytest-cov - pytest-xdist - python>=3.9,<3.11 -- rmm==23.6.* +- rmm==23.8.* - scikit-build>=0.13.1 - scikit-image - setuptools diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 983123252..ba017f245 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -25,7 +25,7 @@ include(rapids-find) rapids_cuda_init_architectures(CUSPATIAL) -project(CUSPATIAL VERSION 23.06.00 LANGUAGES C CXX CUDA) +project(CUSPATIAL VERSION 23.08.00 LANGUAGES C CXX CUDA) # Needed because GoogleBenchmark changes the state of FindThreads.cmake, # causing subsequent runs to have different values for the `Threads::Threads` target. diff --git a/cpp/doxygen/Doxyfile b/cpp/doxygen/Doxyfile index 1c66cb038..2c3b7bb66 100644 --- a/cpp/doxygen/Doxyfile +++ b/cpp/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "libcuspatial" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 23.06.00 +PROJECT_NUMBER = 23.08.00 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -2171,7 +2171,7 @@ SKIP_FUNCTION_MACROS = YES # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = rmm.tag=https://docs.rapids.ai/api/librmm/22.10 "libcudf.tag=https://docs.rapids.ai/api/libcudf/22.10" +TAGFILES = rmm.tag=https://docs.rapids.ai/api/librmm/23.08 "libcudf.tag=https://docs.rapids.ai/api/libcudf/23.08" # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to diff --git a/dependencies.yaml b/dependencies.yaml index 86694ef13..933fc1460 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -56,8 +56,8 @@ dependencies: - cxx-compiler - gmock>=1.13.0 - gtest>=1.13.0 - - libcudf==23.6.* - - librmm==23.6.* + - libcudf==23.8.* + - librmm==23.8.* - ninja specific: - output_types: conda @@ -94,7 +94,7 @@ dependencies: - setuptools - output_types: conda packages: - - &cudf_conda cudf==23.6.* + - &cudf_conda cudf==23.8.* specific: - output_types: conda matrices: @@ -114,22 +114,22 @@ dependencies: cuda: "11.8" packages: - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* + - cudf-cu11==23.8.* - matrix: cuda: "11.5" packages: - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* + - cudf-cu11==23.8.* - matrix: cuda: "11.4" packages: - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* + - cudf-cu11==23.8.* - matrix: cuda: "11.2" packages: - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* + - cudf-cu11==23.8.* cudatoolkit: specific: - output_types: conda @@ -170,7 +170,7 @@ dependencies: common: - output_types: [conda, requirements] packages: - - cuml==23.6.* + - cuml==23.8.* - ipython - ipywidgets - notebook @@ -200,7 +200,7 @@ dependencies: - output_types: conda packages: - *cudf_conda - - rmm==23.6.* + - rmm==23.8.* specific: - output_types: requirements matrices: @@ -208,22 +208,22 @@ dependencies: cuda: "11.8" packages: - "--extra-index-url=https://pypi.nvidia.com" - - rmm-cu11==23.6.* + - rmm-cu11==23.8.* - matrix: cuda: "11.5" packages: - "--extra-index-url=https://pypi.nvidia.com" - - rmm-cu11==23.6.* + - rmm-cu11==23.8.* - matrix: cuda: "11.4" packages: - "--extra-index-url=https://pypi.nvidia.com" - - rmm-cu11==23.6.* + - rmm-cu11==23.8.* - matrix: cuda: "11.2" packages: - "--extra-index-url=https://pypi.nvidia.com" - - rmm-cu11==23.6.* + - rmm-cu11==23.8.* test_python: common: - output_types: [conda, requirements] diff --git a/docs/source/conf.py b/docs/source/conf.py index 0084abee3..6851fe052 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -50,9 +50,9 @@ # built documents. # # The short X.Y version. -version = '23.06' +version = '23.08' # The full version, including alpha/beta/rc tags. -release = '23.06.00' +release = '23.08.00' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/fetch_rapids.cmake b/fetch_rapids.cmake index 927acfd7b..99da99888 100644 --- a/fetch_rapids.cmake +++ b/fetch_rapids.cmake @@ -11,7 +11,7 @@ # or implied. See the License for the specific language governing permissions and limitations under # the License. # ============================================================================= -file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-23.06/RAPIDS.cmake +file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-23.08/RAPIDS.cmake ${CMAKE_BINARY_DIR}/RAPIDS.cmake ) include(${CMAKE_BINARY_DIR}/RAPIDS.cmake) diff --git a/python/cuspatial/CMakeLists.txt b/python/cuspatial/CMakeLists.txt index 9f06c3ad9..2c985b47f 100644 --- a/python/cuspatial/CMakeLists.txt +++ b/python/cuspatial/CMakeLists.txt @@ -14,7 +14,7 @@ cmake_minimum_required(VERSION 3.23.1 FATAL_ERROR) -set(cuspatial_version 23.06.00) +set(cuspatial_version 23.08.00) include(../../fetch_rapids.cmake) include(rapids-cuda) From 7f42eebb8a9cecff4d730cc024876a87406b2569 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 23 May 2023 11:52:17 -0400 Subject: [PATCH 25/63] Adds `pairwise_point_polygon_distance` benchmark (#1131) This PR separates the `pairwise_point_polygon_distance` benchmark portion of PR #1002. While that PR is only left for nvtx3 experiments. # Original PR description: This PR adds pairwise point polygon distance benchmark. Depends on #998 Point-polygon distance performance can be affected by many factors, because the geometry is complex in nature. I benchmarked these questions: 1. How does the algorithm scales with simple multipolygons? 2. How does it scales with complex multipolygons? ## How does the algorithm scales with simple multipolygons? The benchmark uses the most simple multipolygon, 3 sides per polygon, 0 hole and 1 polygon per multipolygon. Float32 | Num multipolygon | Throughput (#multipolygons / s) | | --- | --- | | 1 | 28060.32971 | | 100 | 2552687.469 | | 10000 | 186044781 | | 1000000 | 1047783101 | | 100000000 | 929537385.2 | Float64 | Num multipolygon | Throughput (#multipolygons / s) | | --- | --- | | 1 | 28296.94817 | | 100 | 2491541.218 | | 10000 | 179379919.5 | | 1000000 | 854678939.9 | | 100000000 | 783364410.7 | ![image](https://user-images.githubusercontent.com/13521008/226502300-c3273d80-5f9f-4d53-b961-a24e64216e9b.png) The chart shows that with simple polygons and simple multipoint (1 point per multipoint), the algorithm scales pretty nicely. Throughput is maxed out at near 1M pairs. ## How does the algorithm scales with complex multipolygons? The benchmark uses a complex multipolygon, 100 edges per ring, 10 holes per polygon and 3 polygons per multipolygon. float32 Num multipolygon | Throughput (#multipolygons / s) -- | -- 1000 | 158713.2377 10000 | 345694.2642 100000 | 382849.058 float64 Num multipolygon | Throughput (#multipolygons / s) -- | -- 1000 | 148727.1246 10000 | 353141.9758 100000 | 386007.3016 ![image](https://user-images.githubusercontent.com/13521008/226502732-0d116db7-6257-4dec-b170-c42b30df9cea.png) The algorithm reaches max throughput at near 10K pairs. About 100X lower than the simple multipolygon example. Authors: - Michael Wang (https://github.com/isVoid) - Mark Harris (https://github.com/harrism) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1131 --- cpp/benchmarks/CMakeLists.txt | 1 + .../pairwise_point_polygon_distance.cu | 134 ++++++++++++++++++ cpp/include/cuspatial/detail/nvtx/ranges.hpp | 11 +- .../cuspatial_test/geometry_generator.cuh | 56 ++++++++ cpp/include/cuspatial_test/random.cuh | 17 ++- .../cuspatial_test/vector_factories.cuh | 45 ++++-- cpp/tests/distance/point_distance_test.cu | 6 +- .../distance/point_polygon_distance_test.cu | 2 +- .../pairwise_multipoint_equals_count_test.cu | 4 +- cpp/tests/find/find_duplicate_points_test.cu | 6 +- .../find/find_points_on_segments_test.cu | 2 +- .../quadtree_point_in_polygon_test_large.cu | 7 +- .../point_in_polygon/point_in_polygon_test.cu | 2 +- cpp/tests/range/multilinestring_range_test.cu | 2 +- cpp/tests/range/multipolygon_range_test.cu | 6 +- .../utility_test/test_multipoint_factory.cu | 10 +- 16 files changed, 269 insertions(+), 42 deletions(-) create mode 100644 cpp/benchmarks/distance/pairwise_point_polygon_distance.cu diff --git a/cpp/benchmarks/CMakeLists.txt b/cpp/benchmarks/CMakeLists.txt index 99f90eec0..d153b63ab 100644 --- a/cpp/benchmarks/CMakeLists.txt +++ b/cpp/benchmarks/CMakeLists.txt @@ -80,6 +80,7 @@ ConfigureBench(HAUSDORFF_BENCH distance/hausdorff_benchmark.cpp) ConfigureNVBench(DISTANCES_BENCH + distance/pairwise_point_polygon_distance.cu distance/pairwise_linestring_distance.cu) ConfigureNVBench(QUADTREE_ON_POINTS_BENCH diff --git a/cpp/benchmarks/distance/pairwise_point_polygon_distance.cu b/cpp/benchmarks/distance/pairwise_point_polygon_distance.cu new file mode 100644 index 000000000..c3f84da70 --- /dev/null +++ b/cpp/benchmarks/distance/pairwise_point_polygon_distance.cu @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include + +#include + +#include +#include + +#include +#include + +using namespace cuspatial; +using namespace cuspatial::test; + +template +void pairwise_point_polygon_distance_benchmark(nvbench::state& state, nvbench::type_list) +{ + // TODO: to be replaced by nvbench fixture once it's ready + cuspatial::rmm_pool_raii rmm_pool; + rmm::cuda_stream_view stream{rmm::cuda_stream_default}; + + auto const num_pairs{static_cast(state.get_int64("num_pairs"))}; + + auto const num_polygons_per_multipolygon{ + static_cast(state.get_int64("num_polygons_per_multipolygon"))}; + auto const num_holes_per_polygon{ + static_cast(state.get_int64("num_holes_per_polygon"))}; + auto const num_edges_per_ring{static_cast(state.get_int64("num_edges_per_ring"))}; + + auto const num_points_per_multipoint{ + static_cast(state.get_int64("num_points_per_multipoint"))}; + + auto mpoly_generator_param = multipolygon_generator_parameter{ + num_pairs, num_polygons_per_multipolygon, num_holes_per_polygon, num_edges_per_ring}; + + auto mpoint_generator_param = multipoint_generator_parameter{ + num_pairs, num_points_per_multipoint, vec_2d{-1, -1}, vec_2d{0, 0}}; + + auto multipolygons = generate_multipolygon_array(mpoly_generator_param, stream); + auto multipoints = generate_multipoint_array(mpoint_generator_param, stream); + + auto distances = rmm::device_vector(num_pairs); + auto out_it = distances.begin(); + + auto mpoly_view = multipolygons.range(); + auto mpoint_view = multipoints.range(); + + state.add_element_count(num_pairs, "NumPairs"); + state.add_element_count(mpoly_generator_param.num_polygons(), "NumPolygons"); + state.add_element_count(mpoly_generator_param.num_rings(), "NumRings"); + state.add_element_count(mpoly_generator_param.num_coords(), "NumPoints (in mpoly)"); + state.add_element_count(static_cast(mpoly_generator_param.num_coords() * + mpoly_generator_param.num_rings() * + mpoly_generator_param.num_polygons()), + "Multipolygon Complexity"); + state.add_element_count(mpoint_generator_param.num_points(), "NumPoints (in multipoints)"); + + state.add_global_memory_reads( + mpoly_generator_param.num_coords() + mpoint_generator_param.num_points(), + "CoordinatesReadSize"); + state.add_global_memory_reads( + (mpoly_generator_param.num_rings() + 1) + (mpoly_generator_param.num_polygons() + 1) + + (mpoly_generator_param.num_multipolygons + 1) + (mpoint_generator_param.num_multipoints + 1), + "OffsetsDataSize"); + + state.add_global_memory_writes(num_pairs); + + state.exec(nvbench::exec_tag::sync, + [&mpoly_view, &mpoint_view, &out_it, &stream](nvbench::launch& launch) { + pairwise_point_polygon_distance(mpoint_view, mpoly_view, out_it, stream); + }); +} + +using floating_point_types = nvbench::type_list; + +// Benchmark scalability with simple multipolygon (3 sides, 0 hole, 1 poly) +NVBENCH_BENCH_TYPES(pairwise_point_polygon_distance_benchmark, + NVBENCH_TYPE_AXES(floating_point_types)) + .set_type_axes_names({"CoordsType"}) + .add_int64_axis("num_pairs", {1, 1'00, 10'000, 1'000'000, 100'000'000}) + .add_int64_axis("num_polygons_per_multipolygon", {1}) + .add_int64_axis("num_holes_per_polygon", {0}) + .add_int64_axis("num_edges_per_ring", {3}) + .add_int64_axis("num_points_per_multipoint", {1}) + .set_name("point_polygon_distance_benchmark_simple_polygon"); + +// Benchmark scalability with complex multipolygon (100 sides, 10 holes, 3 polys) +NVBENCH_BENCH_TYPES(pairwise_point_polygon_distance_benchmark, + NVBENCH_TYPE_AXES(floating_point_types)) + .set_type_axes_names({"CoordsType"}) + .add_int64_axis("num_pairs", {1'000, 10'000, 100'000, 1'000'000}) + .add_int64_axis("num_polygons_per_multipolygon", {2}) + .add_int64_axis("num_holes_per_polygon", {3}) + .add_int64_axis("num_edges_per_ring", {50}) + .add_int64_axis("num_points_per_multipoint", {1}) + .set_name("point_polygon_distance_benchmark_complex_polygon"); + +// // Benchmark impact of rings (100K pairs, 1 polygon, 3 sides) +NVBENCH_BENCH_TYPES(pairwise_point_polygon_distance_benchmark, + NVBENCH_TYPE_AXES(floating_point_types)) + .set_type_axes_names({"CoordsType"}) + .add_int64_axis("num_pairs", {10'000}) + .add_int64_axis("num_polygons_per_multipolygon", {1}) + .add_int64_axis("num_holes_per_polygon", {0, 10, 100, 1000}) + .add_int64_axis("num_edges_per_ring", {3}) + .add_int64_axis("num_points_per_multipoint", {1}) + .set_name("point_polygon_distance_benchmark_ring_numbers"); + +// Benchmark impact of rings (1M pairs, 1 polygon, 0 holes, 3 sides) +NVBENCH_BENCH_TYPES(pairwise_point_polygon_distance_benchmark, + NVBENCH_TYPE_AXES(floating_point_types)) + .set_type_axes_names({"CoordsType"}) + .add_int64_axis("num_pairs", {100}) + .add_int64_axis("num_polygons_per_multipolygon", {1}) + .add_int64_axis("num_holes_per_polygon", {0}) + .add_int64_axis("num_edges_per_ring", {3}) + .add_int64_axis("num_points_per_multipoint", {50, 5'00, 5'000, 50'000, 500'000}) + .set_name("point_polygon_distance_benchmark_points_in_multipoint"); diff --git a/cpp/include/cuspatial/detail/nvtx/ranges.hpp b/cpp/include/cuspatial/detail/nvtx/ranges.hpp index 1757ae1e5..855221aa0 100644 --- a/cpp/include/cuspatial/detail/nvtx/ranges.hpp +++ b/cpp/include/cuspatial/detail/nvtx/ranges.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,17 +20,12 @@ namespace cuspatial { /** - * @brief Tag type for libcudf's NVTX domain. + * @brief Tag type for libcuspatial's NVTX domain. */ struct libcuspatial_domain { - static constexpr char const* name{"libcuspatial"}; ///< Name of the libcudf domain + static constexpr char const* name{"libcuspatial"}; ///< Name of the libcuspatial domain }; -/** - * @brief Alias for an NVTX range in the libcudf domain. - */ -using thread_range = ::nvtx3::domain_thread_range; - } // namespace cuspatial /** diff --git a/cpp/include/cuspatial_test/geometry_generator.cuh b/cpp/include/cuspatial_test/geometry_generator.cuh index 4dd2dc73a..2e3ab27c4 100644 --- a/cpp/include/cuspatial_test/geometry_generator.cuh +++ b/cpp/include/cuspatial_test/geometry_generator.cuh @@ -16,6 +16,7 @@ #pragma once +#include #include #include @@ -251,5 +252,60 @@ auto generate_multipolygon_array(multipolygon_generator_parameter params, std::move(coordinates)); } +/** + * @brief Struct to store the parameters of the multipoint aray + * + * @tparam T Type of the coordinates + */ +template +struct multipoint_generator_parameter { + using element_t = T; + + std::size_t num_multipoints; + std::size_t num_points_per_multipoints; + vec_2d lower_left; + vec_2d upper_right; + + CUSPATIAL_HOST_DEVICE std::size_t num_points() + { + return num_multipoints * num_points_per_multipoints; + } +}; + +/** + * @brief Helper to generate random multipoints within a range + * + * @tparam T The floating point type for the coordinates + * @param params Parameters to specify for the multipoints + * @param stream The CUDA stream to use for device memory operations and kernel launches + * @return a cuspatial::test::multipoint_array object + */ +template +auto generate_multipoint_array(multipoint_generator_parameter params, + rmm::cuda_stream_view stream) +{ + rmm::device_uvector> coordinates(params.num_points(), stream); + rmm::device_uvector offsets(params.num_multipoints + 1, stream); + + thrust::sequence(rmm::exec_policy(stream), + offsets.begin(), + offsets.end(), + std::size_t{0}, + params.num_points_per_multipoints); + + auto engine_x = deterministic_engine(params.num_points()); + auto engine_y = deterministic_engine(2 * params.num_points()); + + auto x_dist = make_uniform_dist(params.lower_left.x, params.upper_right.x); + auto y_dist = make_uniform_dist(params.lower_left.y, params.upper_right.y); + + auto point_gen = + point_generator(params.lower_left, params.upper_right, engine_x, engine_y, x_dist, y_dist); + + thrust::tabulate(rmm::exec_policy(stream), coordinates.begin(), coordinates.end(), point_gen); + + return make_multipoint_array(std::move(offsets), std::move(coordinates)); +} + } // namespace test } // namespace cuspatial diff --git a/cpp/include/cuspatial_test/random.cuh b/cpp/include/cuspatial_test/random.cuh index 8cd6b71e2..d2a65af3b 100644 --- a/cpp/include/cuspatial_test/random.cuh +++ b/cpp/include/cuspatial_test/random.cuh @@ -154,14 +154,21 @@ struct value_generator { template struct point_generator { using Cart2D = cuspatial::vec_2d; - value_generator vgen; - - point_generator(T lower_bound, T upper_bound, thrust::minstd_rand& engine, Generator gen) - : vgen(lower_bound, upper_bound, engine, gen) + value_generator vgenx; + value_generator vgeny; + + point_generator(vec_2d lower_left, + vec_2d upper_right, + thrust::minstd_rand& engine_x, + thrust::minstd_rand& engine_y, + Generator gen_x, + Generator gen_y) + : vgenx(lower_left.x, upper_right.x, engine_x, gen_x), + vgeny(lower_left.y, upper_right.y, engine_y, gen_y) { } - __device__ Cart2D operator()(size_t n) { return {vgen(n), vgen(n)}; } + __device__ Cart2D operator()(size_t n) { return {vgenx(n), vgeny(n)}; } }; /** diff --git a/cpp/include/cuspatial_test/vector_factories.cuh b/cpp/include/cuspatial_test/vector_factories.cuh index 020645f94..14c363b30 100644 --- a/cpp/include/cuspatial_test/vector_factories.cuh +++ b/cpp/include/cuspatial_test/vector_factories.cuh @@ -309,11 +309,22 @@ auto make_multilinestring_array(std::initializer_list geometry_inl, template class multipoint_array { public: - multipoint_array(GeometryArray geometry_offsets_array, CoordinateArray coordinate_array) + using geometry_t = typename GeometryArray::value_type; + using coord_t = typename CoordinateArray::value_type; + + multipoint_array(thrust::device_vector geometry_offsets_array, + thrust::device_vector coordinate_array) : _geometry_offsets(geometry_offsets_array), _coordinates(coordinate_array) { } + multipoint_array(rmm::device_uvector&& geometry_offsets_array, + rmm::device_uvector&& coordinate_array) + : _geometry_offsets(std::move(geometry_offsets_array)), + _coordinates(std::move(coordinate_array)) + { + } + /// Return the number of multipoints auto size() { return _geometry_offsets.size() - 1; } @@ -337,9 +348,15 @@ class multipoint_array { * coordinates */ template -auto make_multipoints_array(GeometryRange geometry_inl, CoordRange coordinates_inl) +auto make_multipoint_array(GeometryRange geometry_inl, CoordRange coordinates_inl) { - return multipoint_array{make_device_vector(geometry_inl), make_device_vector(coordinates_inl)}; + using IndexType = typename GeometryRange::value_type; + using CoordType = typename CoordRange::value_type; + using DeviceIndexVector = thrust::device_vector; + using DeviceCoordVector = thrust::device_vector; + + return multipoint_array{ + make_device_vector(geometry_inl), make_device_vector(coordinates_inl)}; } /** @@ -347,17 +364,17 @@ auto make_multipoints_array(GeometryRange geometry_inl, CoordRange coordinates_i * * Example: Construct an array of 2 multipoints, each with 2, 0, 1 points: * using P = vec_2d; - * make_multipoints_array({{P{0.0, 1.0}, P{2.0, 0.0}}, {}, {P{3.0, 4.0}}}); + * make_multipoint_array({{P{0.0, 1.0}, P{2.0, 0.0}}, {}, {P{3.0, 4.0}}}); * * Example: Construct an empty multilinestring array: - * make_multipoints_array({}); // Explicit parameter required to deduce type. + * make_multipoint_array({}); // Explicit parameter required to deduce type. * * @tparam T Type of coordinate * @param inl List of multipoints * @return multipoints_array object */ template -auto make_multipoints_array(std::initializer_list>> inl) +auto make_multipoint_array(std::initializer_list>> inl) { std::vector offsets{0}; std::transform(inl.begin(), inl.end(), std::back_inserter(offsets), [](auto multipoint) { @@ -371,8 +388,20 @@ auto make_multipoints_array(std::initializer_list(offsets), - rmm::device_vector>(coordinates)}; + return multipoint_array, rmm::device_vector>>{ + rmm::device_vector(offsets), rmm::device_vector>(coordinates)}; +} + +/** + * @brief Factory method to construct multipoint array by moving the offsets and coordinates from + * `rmm::device_uvector`. + */ +template +auto make_multipoint_array(rmm::device_uvector geometry_offsets, + rmm::device_uvector> coords) +{ + return multipoint_array, rmm::device_uvector>>{ + std::move(geometry_offsets), std::move(coords)}; } } // namespace test diff --git a/cpp/tests/distance/point_distance_test.cu b/cpp/tests/distance/point_distance_test.cu index 573c5232a..72476ee19 100644 --- a/cpp/tests/distance/point_distance_test.cu +++ b/cpp/tests/distance/point_distance_test.cu @@ -14,9 +14,8 @@ * limitations under the License. */ -#include - #include +#include #include #include @@ -59,7 +58,8 @@ struct PairwisePointDistanceTest : public ::testing::Test { { auto engine = cuspatial::test::deterministic_engine(0); auto uniform = cuspatial::test::make_normal_dist(0.0, 1.0); - auto pgen = cuspatial::test::point_generator(T{0.0}, T{1.0}, engine, uniform); + auto pgen = cuspatial::test::point_generator( + vec_2d{0.0, 0.0}, vec_2d{1.0, 1.0}, engine, engine, uniform, uniform); rmm::device_vector> points(num_points); auto counting_iter = thrust::make_counting_iterator(seed); thrust::transform( diff --git a/cpp/tests/distance/point_polygon_distance_test.cu b/cpp/tests/distance/point_polygon_distance_test.cu index 2cee8da4b..c16d324e0 100644 --- a/cpp/tests/distance/point_polygon_distance_test.cu +++ b/cpp/tests/distance/point_polygon_distance_test.cu @@ -61,7 +61,7 @@ struct PairwisePointPolygonDistanceTest : public ::testing::Test { std::vector> const& multipolygon_coordinates, std::initializer_list expected) { - auto d_multipoints = make_multipoints_array(multipoints); + auto d_multipoints = make_multipoint_array(multipoints); auto d_multipolygons = make_multipolygon_array( range{multipolygon_geometry_offsets.begin(), multipolygon_geometry_offsets.end()}, range{multipolygon_part_offsets.begin(), multipolygon_part_offsets.end()}, diff --git a/cpp/tests/equality/pairwise_multipoint_equals_count_test.cu b/cpp/tests/equality/pairwise_multipoint_equals_count_test.cu index a12420858..a7d5f57de 100644 --- a/cpp/tests/equality/pairwise_multipoint_equals_count_test.cu +++ b/cpp/tests/equality/pairwise_multipoint_equals_count_test.cu @@ -32,8 +32,8 @@ struct PairwiseMultipointEqualsCountTest : public BaseFixture { std::initializer_list>> rhs_coordinates, std::initializer_list expected) { - auto larray = make_multipoints_array(lhs_coordinates); - auto rarray = make_multipoints_array(rhs_coordinates); + auto larray = make_multipoint_array(lhs_coordinates); + auto rarray = make_multipoint_array(rhs_coordinates); auto lhs = larray.range(); auto rhs = rarray.range(); diff --git a/cpp/tests/find/find_duplicate_points_test.cu b/cpp/tests/find/find_duplicate_points_test.cu index f4185227c..49bc86bb9 100644 --- a/cpp/tests/find/find_duplicate_points_test.cu +++ b/cpp/tests/find/find_duplicate_points_test.cu @@ -41,7 +41,7 @@ TYPED_TEST(FindDuplicatePointsTest, simple) using T = TypeParam; using P = vec_2d; - auto multipoints = make_multipoints_array({{P{0.0, 0.0}, P{1.0, 0.0}, P{0.0, 0.0}}}); + auto multipoints = make_multipoint_array({{P{0.0, 0.0}, P{1.0, 0.0}, P{0.0, 0.0}}}); rmm::device_vector flags(multipoints.range().num_points()); std::vector expected_flags{0, 0, 1}; @@ -56,7 +56,7 @@ TYPED_TEST(FindDuplicatePointsTest, empty) using T = TypeParam; using P = vec_2d; - auto multipoints = make_multipoints_array({}); + auto multipoints = make_multipoint_array({}); rmm::device_vector flags(multipoints.range().num_points()); std::vector expected_flags{}; @@ -71,7 +71,7 @@ TYPED_TEST(FindDuplicatePointsTest, multi) using T = TypeParam; using P = vec_2d; - auto multipoints = make_multipoints_array( + auto multipoints = make_multipoint_array( {{P{0.0, 0.0}, P{1.0, 0.0}, P{0.0, 0.0}, P{0.0, 0.0}, P{1.0, 0.0}, P{2.0, 0.0}}, {P{5.0, 5.0}, P{5.0, 5.0}}, {P{0.0, 0.0}}}); diff --git a/cpp/tests/find/find_points_on_segments_test.cu b/cpp/tests/find/find_points_on_segments_test.cu index 8981986bc..4296f6479 100644 --- a/cpp/tests/find/find_points_on_segments_test.cu +++ b/cpp/tests/find/find_points_on_segments_test.cu @@ -41,7 +41,7 @@ struct FindPointOnSegmentTest : public BaseFixture { std::initializer_list> segments, std::initializer_list expected_flags) { - auto d_multipoints = make_multipoints_array(multipoints); + auto d_multipoints = make_multipoint_array(multipoints); auto d_segment_offsets = make_device_vector(segment_offsets); auto d_segments = make_device_vector>(segments); diff --git a/cpp/tests/join/quadtree_point_in_polygon_test_large.cu b/cpp/tests/join/quadtree_point_in_polygon_test_large.cu index 14a956016..8da2a2aed 100644 --- a/cpp/tests/join/quadtree_point_in_polygon_test_large.cu +++ b/cpp/tests/join/quadtree_point_in_polygon_test_large.cu @@ -58,7 +58,12 @@ inline auto generate_points( { auto engine = cuspatial::test::deterministic_engine(0); auto uniform = cuspatial::test::make_normal_dist(0.0, 1.0); - auto pgen = cuspatial::test::point_generator(T{0.0}, T{1.0}, engine, uniform); + auto pgen = cuspatial::test::point_generator(cuspatial::vec_2d{0.0, 0.0}, + cuspatial::vec_2d{1.0, 1.0}, + engine, + engine, + uniform, + uniform); auto num_points = quads.size() * points_per_quad; rmm::device_uvector> points(num_points, stream, mr); diff --git a/cpp/tests/point_in_polygon/point_in_polygon_test.cu b/cpp/tests/point_in_polygon/point_in_polygon_test.cu index d958a9a97..00e4229ed 100644 --- a/cpp/tests/point_in_polygon/point_in_polygon_test.cu +++ b/cpp/tests/point_in_polygon/point_in_polygon_test.cu @@ -383,7 +383,7 @@ TYPED_TEST(PointInPolygonTest, ContainsButCollinearWithBoundary) { using T = TypeParam; - auto point = cuspatial::test::make_multipoints_array({{{0.5, 0.5}}}); + auto point = cuspatial::test::make_multipoint_array({{{0.5, 0.5}}}); auto polygon = cuspatial::test::make_multipolygon_array( {0, 1}, {0, 1}, diff --git a/cpp/tests/range/multilinestring_range_test.cu b/cpp/tests/range/multilinestring_range_test.cu index 0d00d5c5f..ec374ef8f 100644 --- a/cpp/tests/range/multilinestring_range_test.cu +++ b/cpp/tests/range/multilinestring_range_test.cu @@ -128,7 +128,7 @@ struct MultilinestringRangeTest : public BaseFixture { thrust::device_vector> got_coordinates(multipoint_range.point_begin(), multipoint_range.point_end()); - auto expected_multipoint = make_multipoints_array(expected); + auto expected_multipoint = make_multipoint_array(expected); auto expected_range = expected_multipoint.range(); thrust::device_vector expected_geometry_offset(expected_range.offsets_begin(), diff --git a/cpp/tests/range/multipolygon_range_test.cu b/cpp/tests/range/multipolygon_range_test.cu index 0f1b08809..90ffa7e18 100644 --- a/cpp/tests/range/multipolygon_range_test.cu +++ b/cpp/tests/range/multipolygon_range_test.cu @@ -140,10 +140,10 @@ struct MultipolygonRangeTest : public BaseFixture { multipolygon_coordinates); auto rng = multipolygon_array.range().as_multipoint_range(); - auto got = make_multipoints_array(range(rng.offsets_begin(), rng.offsets_end()), - range(rng.point_begin(), rng.point_end())); + auto got = make_multipoint_array(range(rng.offsets_begin(), rng.offsets_end()), + range(rng.point_begin(), rng.point_end())); - auto expected = make_multipoints_array( + auto expected = make_multipoint_array( range(multipoint_geometry_offset.begin(), multipoint_geometry_offset.end()), range(multipoint_coordinates.begin(), multipoint_coordinates.end())); diff --git a/cpp/tests/utility_test/test_multipoint_factory.cu b/cpp/tests/utility_test/test_multipoint_factory.cu index f7b1ba0a4..ad800cf98 100644 --- a/cpp/tests/utility_test/test_multipoint_factory.cu +++ b/cpp/tests/utility_test/test_multipoint_factory.cu @@ -34,7 +34,7 @@ TYPED_TEST(MultiPointFactoryTest, simple) using P = vec_2d; auto multipoints = - make_multipoints_array({{P{0.0, 0.0}, P{1.0, 0.0}}, {P{2.0, 0.0}, P{2.0, 2.0}}}); + make_multipoint_array({{P{0.0, 0.0}, P{1.0, 0.0}}, {P{2.0, 0.0}, P{2.0, 2.0}}}); auto [offsets, coords] = multipoints.release(); @@ -51,7 +51,7 @@ TYPED_TEST(MultiPointFactoryTest, empty) using T = TypeParam; using P = vec_2d; - auto multipoints = make_multipoints_array({}); + auto multipoints = make_multipoint_array({}); auto [offsets, coords] = multipoints.release(); @@ -67,7 +67,7 @@ TYPED_TEST(MultiPointFactoryTest, mixed_empty_multipoint) using T = TypeParam; using P = vec_2d; - auto multipoints = make_multipoints_array({{P{1.0, 0.0}}, {}, {P{2.0, 3.0}, P{4.0, 5.0}}}); + auto multipoints = make_multipoint_array({{P{1.0, 0.0}}, {}, {P{2.0, 3.0}, P{4.0, 5.0}}}); auto [offsets, coords] = multipoints.release(); @@ -83,7 +83,7 @@ TYPED_TEST(MultiPointFactoryTest, mixed_empty_multipoint2) using T = TypeParam; using P = vec_2d; - auto multipoints = make_multipoints_array({{}, {P{1.0, 0.0}}, {P{2.0, 3.0}, P{4.0, 5.0}}}); + auto multipoints = make_multipoint_array({{}, {P{1.0, 0.0}}, {P{2.0, 3.0}, P{4.0, 5.0}}}); auto [offsets, coords] = multipoints.release(); @@ -99,7 +99,7 @@ TYPED_TEST(MultiPointFactoryTest, mixed_empty_multipoint3) using T = TypeParam; using P = vec_2d; - auto multipoints = make_multipoints_array({{P{1.0, 0.0}}, {P{2.0, 3.0}, P{4.0, 5.0}}, {}}); + auto multipoints = make_multipoint_array({{P{1.0, 0.0}}, {P{2.0, 3.0}, P{4.0, 5.0}}, {}}); auto [offsets, coords] = multipoints.release(); From 5162e39d04f2d9a0ed1c1f15940bfab32ecf736e Mon Sep 17 00:00:00 2001 From: Paul Taylor <178183+trxcllnt@users.noreply.github.com> Date: Fri, 26 May 2023 09:20:31 -0700 Subject: [PATCH 26/63] Fix `cudf::column` constructor args (#1151) Update `cudf::column` constructor args to match the changes in https://github.com/rapidsai/cudf/pull/13341. Also corrects a minor issue in the docs, closes #1154. Authors: - Paul Taylor (https://github.com/trxcllnt) - Taurean Dyer (https://github.com/taureandyernv) - Bradley Dice (https://github.com/bdice) Approvers: - Michael Wang (https://github.com/isVoid) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1151 --- cpp/src/indexing/point_quadtree.cu | 37 ++++--- .../intersection/linestring_intersection.cu | 31 ++++-- cpp/src/join/quadtree_bbox_filtering.cu | 4 +- cpp/src/join/quadtree_point_in_polygon.cu | 15 ++- .../quadtree_point_to_nearest_linestring.cu | 18 ++-- cpp/src/trajectory/derive_trajectories.cu | 7 +- .../trajectory/test_derive_trajectories.cpp | 97 ++++++++++++------ .../test_trajectory_bounding_boxes.cu | 52 ++++++---- .../test_trajectory_distances_and_speeds.cu | 99 +++++++++++++------ .../user_guide/cuspatial_api_examples.ipynb | 2 +- 10 files changed, 246 insertions(+), 116 deletions(-) diff --git a/cpp/src/indexing/point_quadtree.cu b/cpp/src/indexing/point_quadtree.cu index ce9623522..4e2f5987f 100644 --- a/cpp/src/indexing/point_quadtree.cu +++ b/cpp/src/indexing/point_quadtree.cu @@ -90,20 +90,31 @@ struct dispatch_construct_quadtree { std::vector> cols{}; cols.push_back(std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, size, tree.key.release())); + cudf::data_type{cudf::type_id::UINT32}, size, tree.key.release(), rmm::device_buffer{}, 0)); cols.push_back(std::make_unique( - cudf::data_type{cudf::type_id::UINT8}, size, tree.level.release())); - cols.push_back(std::make_unique( - cudf::data_type{cudf::type_id::BOOL8}, size, tree.internal_node_flag.release())); - cols.push_back(std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, size, tree.length.release())); - cols.push_back(std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, size, tree.offset.release())); - - return std::make_pair( - std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, x.size(), point_indices.release()), - std::make_unique(std::move(cols))); + cudf::data_type{cudf::type_id::UINT8}, size, tree.level.release(), rmm::device_buffer{}, 0)); + cols.push_back(std::make_unique(cudf::data_type{cudf::type_id::BOOL8}, + size, + tree.internal_node_flag.release(), + rmm::device_buffer{}, + 0)); + cols.push_back(std::make_unique(cudf::data_type{cudf::type_id::UINT32}, + size, + tree.length.release(), + rmm::device_buffer{}, + 0)); + cols.push_back(std::make_unique(cudf::data_type{cudf::type_id::UINT32}, + size, + tree.offset.release(), + rmm::device_buffer{}, + 0)); + + return std::make_pair(std::make_unique(cudf::data_type{cudf::type_id::UINT32}, + x.size(), + point_indices.release(), + rmm::device_buffer{}, + 0), + std::make_unique(std::move(cols))); } }; diff --git a/cpp/src/intersection/linestring_intersection.cu b/cpp/src/intersection/linestring_intersection.cu index e92e2a366..30e60e798 100644 --- a/cpp/src/intersection/linestring_intersection.cu +++ b/cpp/src/intersection/linestring_intersection.cu @@ -85,7 +85,9 @@ struct pairwise_linestring_intersection_launch { auto points_xy = std::make_unique(cudf::data_type(cudf::type_to_id()), 2 * num_points, - intersection_results.points_coords->release()); + intersection_results.points_coords->release(), + rmm::device_buffer{}, + 0); auto points = cudf::make_lists_column(num_points, std::move(points_offsets), std::move(points_xy), 0, {}); @@ -100,7 +102,9 @@ struct pairwise_linestring_intersection_launch { auto segments_xy = std::make_unique(cudf::data_type(cudf::type_to_id()), num_segment_coords, - intersection_results.segments_coords->release()); + intersection_results.segments_coords->release(), + rmm::device_buffer{}, + 0); auto segments = cudf::make_lists_column(num_segments, @@ -118,15 +122,24 @@ struct pairwise_linestring_intersection_launch { mr); return linestring_intersection_column_result{ - std::make_unique(std::move(*intersection_results.geometry_collection_offset)), - std::make_unique(std::move(*intersection_results.types_buffer)), - std::make_unique(std::move(*intersection_results.offset_buffer)), + std::make_unique( + std::move(*intersection_results.geometry_collection_offset.release()), + rmm::device_buffer{}, + 0), + std::make_unique( + std::move(*intersection_results.types_buffer.release()), rmm::device_buffer{}, 0), + std::make_unique( + std::move(*intersection_results.offset_buffer.release()), rmm::device_buffer{}, 0), std::move(points), std::move(segments), - std::make_unique(std::move(*intersection_results.lhs_linestring_id)), - std::make_unique(std::move(*intersection_results.lhs_segment_id)), - std::make_unique(std::move(*intersection_results.rhs_linestring_id)), - std::make_unique(std::move(*intersection_results.rhs_segment_id))}; + std::make_unique( + std::move(*intersection_results.lhs_linestring_id.release()), rmm::device_buffer{}, 0), + std::make_unique( + std::move(*intersection_results.lhs_segment_id.release()), rmm::device_buffer{}, 0), + std::make_unique( + std::move(*intersection_results.rhs_linestring_id.release()), rmm::device_buffer{}, 0), + std::make_unique( + std::move(*intersection_results.rhs_segment_id.release()), rmm::device_buffer{}, 0)}; } template diff --git a/cpp/src/join/quadtree_bbox_filtering.cu b/cpp/src/join/quadtree_bbox_filtering.cu index b90bad402..42b07c015 100644 --- a/cpp/src/join/quadtree_bbox_filtering.cu +++ b/cpp/src/join/quadtree_bbox_filtering.cu @@ -72,8 +72,8 @@ struct dispatch_quadtree_bounding_box_join { mr); std::vector> cols{}; - cols.push_back(std::make_unique(std::move(bbox_offset))); - cols.push_back(std::make_unique(std::move(quad_offset))); + cols.push_back(std::make_unique(std::move(bbox_offset), rmm::device_buffer{}, 0)); + cols.push_back(std::make_unique(std::move(quad_offset), rmm::device_buffer{}, 0)); return std::make_unique(std::move(cols)); } diff --git a/cpp/src/join/quadtree_point_in_polygon.cu b/cpp/src/join/quadtree_point_in_polygon.cu index 3a9be80bb..452b4fe21 100644 --- a/cpp/src/join/quadtree_point_in_polygon.cu +++ b/cpp/src/join/quadtree_point_in_polygon.cu @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "rmm/device_buffer.hpp" #include #include #include @@ -89,10 +90,16 @@ struct compute_quadtree_point_in_polygon { // Allocate output columns for the number of pairs that intersected auto num_intersections = poly_idx.size(); - auto poly_idx_col = std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, num_intersections, poly_idx.release()); - auto point_idx_col = std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, num_intersections, point_idx.release()); + auto poly_idx_col = std::make_unique(cudf::data_type{cudf::type_id::UINT32}, + num_intersections, + poly_idx.release(), + rmm::device_buffer{}, + 0); + auto point_idx_col = std::make_unique(cudf::data_type{cudf::type_id::UINT32}, + num_intersections, + point_idx.release(), + rmm::device_buffer{}, + 0); std::vector> cols{}; cols.reserve(2); diff --git a/cpp/src/join/quadtree_point_to_nearest_linestring.cu b/cpp/src/join/quadtree_point_to_nearest_linestring.cu index 1a8f93293..c423c1cb4 100644 --- a/cpp/src/join/quadtree_point_to_nearest_linestring.cu +++ b/cpp/src/join/quadtree_point_to_nearest_linestring.cu @@ -88,12 +88,18 @@ struct compute_quadtree_point_to_nearest_linestring { auto num_distances = distances.size(); - auto point_idx_col = std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, num_distances, point_idxs.release()); - auto linestring_idx_col = std::make_unique( - cudf::data_type{cudf::type_id::UINT32}, num_distances, linestring_idxs.release()); - auto distance_col = - std::make_unique(point_x.type(), num_distances, distances.release()); + auto point_idx_col = std::make_unique(cudf::data_type{cudf::type_id::UINT32}, + num_distances, + point_idxs.release(), + rmm::device_buffer{}, + 0); + auto linestring_idx_col = std::make_unique(cudf::data_type{cudf::type_id::UINT32}, + num_distances, + linestring_idxs.release(), + rmm::device_buffer{}, + 0); + auto distance_col = std::make_unique( + point_x.type(), num_distances, distances.release(), rmm::device_buffer{}, 0); std::vector> cols{}; cols.reserve(3); diff --git a/cpp/src/trajectory/derive_trajectories.cu b/cpp/src/trajectory/derive_trajectories.cu index cfeeea77b..0a5db39ed 100644 --- a/cpp/src/trajectory/derive_trajectories.cu +++ b/cpp/src/trajectory/derive_trajectories.cu @@ -70,8 +70,11 @@ struct derive_trajectories_dispatch { auto num_trajectories = offsets->size(); - auto offsets_column = std::make_unique( - cudf::data_type{cudf::type_id::INT32}, num_trajectories, offsets->release()); + auto offsets_column = std::make_unique(cudf::data_type{cudf::type_id::INT32}, + num_trajectories, + offsets->release(), + rmm::device_buffer{}, + 0); return {std::move(result_table), std::move(offsets_column)}; } diff --git a/cpp/tests/trajectory/test_derive_trajectories.cpp b/cpp/tests/trajectory/test_derive_trajectories.cpp index 90b10dc22..86269620b 100644 --- a/cpp/tests/trajectory/test_derive_trajectories.cpp +++ b/cpp/tests/trajectory/test_derive_trajectories.cpp @@ -35,28 +35,43 @@ TEST_F(DeriveTrajectoriesErrorTest, SizeMismatch) auto const size = 1000; { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size / 2, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::derive_trajectories(id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { - auto id = cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column( + rmm::device_uvector(size / 2, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::derive_trajectories(id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); auto ts = - cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); + cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::derive_trajectories(id, xs, ys, ts, this->mr()), cuspatial::logic_error); } @@ -67,29 +82,44 @@ TEST_F(DeriveTrajectoriesErrorTest, TypeError) auto const size = 1000; { - auto id = - cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); // not integer - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); // not integer + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::derive_trajectories(id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = - cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); // not timestamp + auto id = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); // not timestamp EXPECT_THROW(cuspatial::derive_trajectories(id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { // x-y type mismatch - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::derive_trajectories(id, xs, ys, ts, this->mr()), cuspatial::logic_error); } @@ -100,15 +130,20 @@ TEST_F(DeriveTrajectoriesErrorTest, Nulls) auto const size = 1000; { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); auto nulls = rmm::device_uvector(1000, rmm::cuda_stream_default); cudaMemsetAsync(nulls.data(), 0xcccc, nulls.size(), rmm::cuda_stream_default.value()); auto nulls_buffer = nulls.release(); - id.set_null_mask(nulls_buffer); + id.set_null_mask(nulls_buffer, 4000); EXPECT_THROW(cuspatial::derive_trajectories(id, xs, ys, ts, this->mr()), cuspatial::logic_error); } diff --git a/cpp/tests/trajectory/test_trajectory_bounding_boxes.cu b/cpp/tests/trajectory/test_trajectory_bounding_boxes.cu index fc7dc0432..684d7fa3b 100644 --- a/cpp/tests/trajectory/test_trajectory_bounding_boxes.cu +++ b/cpp/tests/trajectory/test_trajectory_bounding_boxes.cu @@ -26,17 +26,24 @@ TEST_F(TrajectoryBoundingBoxesErrorTest, SizeMismatch) auto const size = 1000; { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size / 2, rmm::cuda_stream_default), rmm::device_buffer{}, 0); EXPECT_THROW(cuspatial::trajectory_bounding_boxes(1, id, xs, ys, this->mr()), cuspatial::logic_error); } { - auto id = cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column( + rmm::device_uvector(size / 2, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); EXPECT_THROW(cuspatial::trajectory_bounding_boxes(1, id, xs, ys, this->mr()), cuspatial::logic_error); } @@ -47,19 +54,26 @@ TEST_F(TrajectoryBoundingBoxesErrorTest, TypeError) auto const size = 1000; { - auto id = - cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); // not integer - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); // not integer + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); EXPECT_THROW(cuspatial::trajectory_bounding_boxes(1, id, xs, ys, this->mr()), cuspatial::logic_error); } { // x-y type mismatch - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); EXPECT_THROW(cuspatial::trajectory_bounding_boxes(1, id, xs, ys, this->mr()), cuspatial::logic_error); } @@ -70,14 +84,18 @@ TEST_F(TrajectoryBoundingBoxesErrorTest, Nulls) auto const size = 1000; { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); auto nulls = rmm::device_uvector(1000, rmm::cuda_stream_default); cudaMemsetAsync(nulls.data(), 0xcccc, nulls.size(), rmm::cuda_stream_default.value()); auto nulls_buffer = nulls.release(); - id.set_null_mask(nulls_buffer); + id.set_null_mask(nulls_buffer, 4000); EXPECT_THROW(cuspatial::trajectory_bounding_boxes(1, id, xs, ys, this->mr()), cuspatial::logic_error); } diff --git a/cpp/tests/trajectory/test_trajectory_distances_and_speeds.cu b/cpp/tests/trajectory/test_trajectory_distances_and_speeds.cu index b23a73e2e..128251b01 100644 --- a/cpp/tests/trajectory/test_trajectory_distances_and_speeds.cu +++ b/cpp/tests/trajectory/test_trajectory_distances_and_speeds.cu @@ -30,27 +30,43 @@ TEST_F(TrajectoryDistanceSpeedErrorTest, SizeMismatch) auto const size = 1000; { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size / 2, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::trajectory_distances_and_speeds(1, id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { - auto id = cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column( + rmm::device_uvector(size / 2, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::trajectory_distances_and_speeds(1, id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { - auto id = cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column( + rmm::device_uvector(size / 2, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); auto ts = - cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default)); + cudf::column(rmm::device_uvector(size / 2, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::trajectory_distances_and_speeds(1, id, xs, ys, ts, this->mr()), cuspatial::logic_error); } @@ -61,29 +77,44 @@ TEST_F(TrajectoryDistanceSpeedErrorTest, TypeError) auto const size = 1000; { - auto id = - cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); // not integer - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); // not integer + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::trajectory_distances_and_speeds(1, id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = - cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); // not timestamp + auto id = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); // not timestamp EXPECT_THROW(cuspatial::trajectory_distances_and_speeds(1, id, xs, ys, ts, this->mr()), cuspatial::logic_error); } { // x-y type mismatch - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); EXPECT_THROW(cuspatial::trajectory_distances_and_speeds(1, id, xs, ys, ts, this->mr()), cuspatial::logic_error); } @@ -94,15 +125,21 @@ TEST_F(TrajectoryDistanceSpeedErrorTest, Nulls) auto const size = 1000; { - auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto xs = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ys = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); - auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default)); + auto id = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); + auto xs = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ys = cudf::column( + rmm::device_uvector(size, rmm::cuda_stream_default), rmm::device_buffer{}, 0); + auto ts = cudf::column(rmm::device_uvector(size, rmm::cuda_stream_default), + rmm::device_buffer{}, + 0); auto nulls = rmm::device_uvector(1000, rmm::cuda_stream_default); cudaMemsetAsync(nulls.data(), 0xcccc, nulls.size(), rmm::cuda_stream_default.value()); auto nulls_buffer = nulls.release(); - id.set_null_mask(nulls_buffer); + id.set_null_mask(nulls_buffer, 4000); EXPECT_THROW(cuspatial::trajectory_distances_and_speeds(1, id, xs, ys, ts, this->mr()), cuspatial::logic_error); } diff --git a/docs/source/user_guide/cuspatial_api_examples.ipynb b/docs/source/user_guide/cuspatial_api_examples.ipynb index bd78b237f..396f566c6 100644 --- a/docs/source/user_guide/cuspatial_api_examples.ipynb +++ b/docs/source/user_guide/cuspatial_api_examples.ipynb @@ -77,7 +77,7 @@ "## GPU accelerated memory layout\n", "\n", "cuSpatial uses `GeoArrow` buffers, a GPU-friendly data format for geometric data that is well \n", - "suited for massively parallel programming. See [I/O](#io) on the fastest methods to get your \n", + "suited for massively parallel programming. See [I/O]((#Input-/-Output) on the fastest methods to get your \n", "data into cuSpatial. GeoArrow extends [PyArrow](\n", "https://arrow.apache.org/docs/python/index.html ) bindings and introduces several new types suited \n", "for geometry applications. GeoArrow supports [ListArrays](\n", From 3bb733a43cc65cfc2b5d221ba2d1157f2cc8b2f9 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Fri, 26 May 2023 17:11:01 -0400 Subject: [PATCH 27/63] Fix scatter bug due to overlapping range in `pairwise_linestring_intersection` (#1152) This PR closes #1149 `thrust::scatter` does not perform in place scatter. As the document says: ``` The iterator result + i shall not refer to any element referenced by any iterator j in the range [first,last) for all iterators i in the range [map,map + (last - first)). ``` The input and output range must not overlap. However, currently in intersection there is overlap. This may cause a bad scatter that only happens when input is large (device dependent). This PR also fixes a bug in `find_duplicate_point` kernel where the `duplicate_flag` was incorrectly referenced. Additionally, this PR includes a fix to the python API to handle sparse geoseries. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1152 --- .../detail/find/find_duplicate_points.cuh | 5 +- .../intersection/linestring_intersection.cuh | 42 +- cpp/tests/CMakeLists.txt | 3 +- .../intersection/intersection_test_utils.cuh | 158 ++ .../linestring_intersection_large_test.cu | 2027 +++++++++++++++++ .../linestring_intersection_test.cu | 151 -- .../cuspatial/core/binops/intersection.py | 2 +- 7 files changed, 2215 insertions(+), 173 deletions(-) create mode 100644 cpp/tests/intersection/linestring_intersection_large_test.cu diff --git a/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh b/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh index baf7651c1..f391e97ea 100644 --- a/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh +++ b/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh @@ -45,10 +45,13 @@ void __global__ find_duplicate_points_kernel_simple(MultiPointRange multipoints, duplicate_flags[i + global_offset] = 0; } - for (auto i = 0; i < multipoint.size() && duplicate_flags[i] != 1; ++i) + // Loop over the point range to find duplicates, skipping if the point is already marked as + // duplicate. + for (auto i = 0; i < multipoint.size() && duplicate_flags[i + global_offset] != 1; ++i) { for (auto j = i + 1; j < multipoint.size(); ++j) { if (multipoint[i] == multipoint[j]) duplicate_flags[j + global_offset] = 1; } + } } } diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh index db9b28075..796365bde 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -159,30 +160,33 @@ std::unique_ptr> compute_types_buffer( * This is performing a group-by cumulative sum (pandas semantic) operation * to an "all 1s vector", using `types_buffer` as the key column. */ -template +template std::unique_ptr> compute_offset_buffer( - rmm::device_uvector const& types_buffer, + rmm::device_uvector const& types_buffer, rmm::mr::device_memory_resource* mr, rmm::cuda_stream_view stream) { - auto N = types_buffer.size(); - auto keys_copy = rmm::device_uvector(types_buffer, stream); - auto indices_temp = rmm::device_uvector(N, stream); - thrust::sequence(rmm::exec_policy(stream), indices_temp.begin(), indices_temp.end()); - thrust::stable_sort_by_key( - rmm::exec_policy(stream), keys_copy.begin(), keys_copy.end(), indices_temp.begin()); + auto N = types_buffer.size(); + auto [offset_buffer_grouped, indices] = [&]() { + auto indices = rmm::device_uvector(N, stream); + auto keys = rmm::device_uvector(types_buffer, stream); + thrust::sequence(rmm::exec_policy(stream), indices.begin(), indices.end()); + thrust::stable_sort_by_key(rmm::exec_policy(stream), keys.begin(), keys.end(), indices.begin()); + + auto offset_buffer_grouped = std::make_unique>(N, stream); + + auto one_it = thrust::make_constant_iterator(1); + thrust::exclusive_scan_by_key( + rmm::exec_policy(stream), keys.begin(), keys.end(), one_it, offset_buffer_grouped->begin()); + + return std::pair{std::move(offset_buffer_grouped), std::move(indices)}; + }(); auto offset_buffer = std::make_unique>(N, stream, mr); - thrust::uninitialized_fill_n(rmm::exec_policy(stream), offset_buffer->begin(), N, 1); - thrust::exclusive_scan_by_key(rmm::exec_policy(stream), - keys_copy.begin(), - keys_copy.end(), - offset_buffer->begin(), - offset_buffer->begin()); thrust::scatter(rmm::exec_policy(stream), - offset_buffer->begin(), - offset_buffer->end(), - indices_temp.begin(), + offset_buffer_grouped->begin(), + offset_buffer_grouped->end(), + indices.begin(), offset_buffer->begin()); return offset_buffer; } @@ -226,7 +230,7 @@ linestring_intersection_result pairwise_linestring_intersection( // Phase 3: Remove duplicate points from intermediates // TODO: improve memory usage by using IIFE to // Remove the duplicate points - rmm::device_uvector point_flags(num_points, stream); + rmm::device_uvector point_flags(num_points, stream); detail::find_duplicate_points( make_multipoint_range(points.offset_range(), points.geom_range()), point_flags.begin(), stream); @@ -275,7 +279,7 @@ linestring_intersection_result pairwise_linestring_intersection( stream, mr); - auto offsets_buffer = detail::compute_offset_buffer(*types_buffer, mr, stream); + auto offsets_buffer = detail::compute_offset_buffer(*types_buffer, mr, stream); // Assemble the look-back ids. auto lhs_linestring_id = diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 68fa96dd5..8f344e534 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -219,7 +219,8 @@ ConfigureTest(LINESTRING_INTERSECTION_TEST_EXP intersection/linestring_intersection_count_test.cu intersection/linestring_intersection_intermediates_remove_if_test.cu intersection/linestring_intersection_with_duplicates_test.cu - intersection/linestring_intersection_test.cu) + intersection/linestring_intersection_test.cu + intersection/linestring_intersection_large_test.cu) # nearest points ConfigureTest(POINT_LINESTRING_NEAREST_POINT_TEST_EXP diff --git a/cpp/tests/intersection/intersection_test_utils.cuh b/cpp/tests/intersection/intersection_test_utils.cuh index 34a93de64..ab0971648 100644 --- a/cpp/tests/intersection/intersection_test_utils.cuh +++ b/cpp/tests/intersection/intersection_test_utils.cuh @@ -16,9 +16,16 @@ #pragma once +#include + #include #include +#include +#include +#include +#include +#include #include namespace cuspatial { @@ -56,5 +63,156 @@ struct order_key_value_pairs { } }; +/** + * @brief Perform sorting to the intersection result + * + * The result of intersection result is non-determinisitc. This algorithm sorts + * the geometries of the same types and the same list and makes the result deterministic. + * + * The example below contains 2 rows and 4 geometries. The order of the first + * and second point is non-deterministic. + * [ + * [Point(1.0, 1.5), Point(0.0, -0.3), Segment((0.0, 0.0), (1.0, 1.0))] + * ^ ^ + * [Point(-3, -5)] + * ] + * + * After sorting, the result is deterministic: + * [ + * [Point(0.0, -0.3), Point(1.0, 1.5), Segment((0.0, 0.0), (1.0, 1.0))] + * ^ ^ + * [Point(-3, -5)] + * ] + * + * This function invalidates the input @p result and return a copy of sorted results. + */ +template +linestring_intersection_result segment_sort_intersection_result( + linestring_intersection_result& result, + rmm::mr::device_memory_resource* mr, + rmm::cuda_stream_view stream) +{ + auto const num_points = result.points_coords->size(); + auto const num_segments = result.segments_coords->size(); + auto const num_geoms = num_points + num_segments; + + rmm::device_uvector scatter_map(num_geoms, stream); + thrust::sequence(rmm::exec_policy(stream), scatter_map.begin(), scatter_map.end()); + + // Compute keys for each row in the union column. Rows of the same list + // are assigned the same label. + rmm::device_uvector geometry_collection_keys(num_geoms, stream); + auto geometry_collection_keys_begin = make_geometry_id_iterator( + result.geometry_collection_offset->begin(), result.geometry_collection_offset->end()); + + thrust::copy(rmm::exec_policy(stream), + geometry_collection_keys_begin, + geometry_collection_keys_begin + num_geoms, + geometry_collection_keys.begin()); + + // Perform "group-by" based on the list label and type of the row - + // This makes the geometry of the same type and of the same list neighbor. + + // Make a copy of types buffer so that the sorting does not affect the original. + auto types_buffer = rmm::device_uvector(*result.types_buffer, stream); + auto keys_begin = + thrust::make_zip_iterator(types_buffer.begin(), geometry_collection_keys.begin()); + auto value_begin = thrust::make_zip_iterator(scatter_map.begin(), + result.lhs_linestring_id->begin(), + result.lhs_segment_id->begin(), + result.rhs_linestring_id->begin(), + result.rhs_segment_id->begin()); + + thrust::sort_by_key(rmm::exec_policy(stream), keys_begin, keys_begin + num_geoms, value_begin); + + // Segment-sort the point array + auto keys_points_begin = thrust::make_zip_iterator(keys_begin, result.points_coords->begin()); + thrust::sort_by_key(rmm::exec_policy(stream), + keys_points_begin, + keys_points_begin + num_points, + scatter_map.begin(), + order_key_value_pairs, vec_2d>{}); + + // Segment-sort the segment array + auto keys_segment_begin = + thrust::make_zip_iterator(keys_begin + num_points, result.segments_coords->begin()); + + thrust::sort_by_key(rmm::exec_policy(stream), + keys_segment_begin, + keys_segment_begin + num_segments, + scatter_map.begin() + num_points, + order_key_value_pairs, segment>{}); + + // Restore the order of indices + auto lhs_linestring_id = std::make_unique>(num_geoms, stream, mr); + auto lhs_segment_id = std::make_unique>(num_geoms, stream, mr); + auto rhs_linestring_id = std::make_unique>(num_geoms, stream, mr); + auto rhs_segment_id = std::make_unique>(num_geoms, stream, mr); + + auto input_it = thrust::make_zip_iterator(result.lhs_linestring_id->begin(), + result.lhs_segment_id->begin(), + result.rhs_linestring_id->begin(), + result.rhs_segment_id->begin()); + + auto output_it = thrust::make_zip_iterator(lhs_linestring_id->begin(), + lhs_segment_id->begin(), + rhs_linestring_id->begin(), + rhs_segment_id->begin()); + + thrust::scatter( + rmm::exec_policy(stream), input_it, input_it + num_geoms, scatter_map.begin(), output_it); + + return {std::move(result.geometry_collection_offset), + std::move(result.types_buffer), + std::move(result.offset_buffer), + std::move(result.points_coords), + std::move(result.segments_coords), + std::move(lhs_linestring_id), + std::move(lhs_segment_id), + std::move(rhs_linestring_id), + std::move(rhs_segment_id)}; +} + +template , + typename segment_t = segment> +auto make_linestring_intersection_result( + std::initializer_list geometry_collection_offset, + std::initializer_list types_buffer, + std::initializer_list offset_buffer, + std::initializer_list points_coords, + std::initializer_list segments_coords, + std::initializer_list lhs_linestring_ids, + std::initializer_list lhs_segment_ids, + std::initializer_list rhs_linestring_ids, + std::initializer_list rhs_segment_ids, + rmm::cuda_stream_view stream, + rmm::mr::device_memory_resource* mr) +{ + auto d_geometry_collection_offset = + make_device_uvector(geometry_collection_offset, stream, mr); + auto d_types_buffer = make_device_uvector(types_buffer, stream, mr); + auto d_offset_buffer = make_device_uvector(offset_buffer, stream, mr); + auto d_points_coords = make_device_uvector(points_coords, stream, mr); + auto d_segments_coords = make_device_uvector(segments_coords, stream, mr); + auto d_lhs_linestring_ids = make_device_uvector(lhs_linestring_ids, stream, mr); + auto d_lhs_segment_ids = make_device_uvector(lhs_segment_ids, stream, mr); + auto d_rhs_linestring_ids = make_device_uvector(rhs_linestring_ids, stream, mr); + auto d_rhs_segment_ids = make_device_uvector(rhs_segment_ids, stream, mr); + + return linestring_intersection_result{ + std::make_unique>(d_geometry_collection_offset, stream), + std::make_unique>(d_types_buffer, stream), + std::make_unique>(d_offset_buffer, stream), + std::make_unique>(d_points_coords, stream), + std::make_unique>(d_segments_coords, stream), + std::make_unique>(d_lhs_linestring_ids, stream), + std::make_unique>(d_lhs_segment_ids, stream), + std::make_unique>(d_rhs_linestring_ids, stream), + std::make_unique>(d_rhs_segment_ids, stream)}; +} + } // namespace test } // namespace cuspatial diff --git a/cpp/tests/intersection/linestring_intersection_large_test.cu b/cpp/tests/intersection/linestring_intersection_large_test.cu new file mode 100644 index 000000000..aed4c00f3 --- /dev/null +++ b/cpp/tests/intersection/linestring_intersection_large_test.cu @@ -0,0 +1,2027 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +/// Regression case found on V100-32GB machine. + +#include "intersection_test_utils.cuh" + +#include +#include +#include +#include + +#include +#include +#include + +#include + +template +struct LinestringIntersectionLargeTest : public cuspatial::test::BaseFixture { + using I = typename cuspatial::linestring_intersection_result; + using index_t = typename I::index_t; + using types_t = typename I::types_t; + + template + void verify_legal_result(MultiLinestringRange lhs, MultiLinestringRange rhs) + { + auto unsorted = + cuspatial::pairwise_linestring_intersection(lhs, rhs, this->mr(), this->stream()); + // auto got = cuspatial::test::segment_sort_intersection_result( + // unsorted, this->mr(), this->stream()); + + // auto [points, segments] = cuspatial::pairwise_linestring_intersection_with_duplicates(lhs, + // rhs, this->mr(), this->stream); + + auto num_points = unsorted.points_coords->size(); + auto num_segments = unsorted.segments_coords->size(); + + auto h_types_buffer = cuspatial::test::to_host(std::move(*unsorted.types_buffer)); + auto h_offset_buffer = cuspatial::test::to_host(std::move(*unsorted.offset_buffer)); + + for (std::size_t i = 0; i < h_types_buffer.size(); ++i) { + switch (h_types_buffer[i]) { + case static_cast(cuspatial::IntersectionTypeCode::POINT): + // EXPECT_LT(h_offset_buffer[i], num_points); + if (h_offset_buffer[i] >= num_points) { + std::cout << "offset: " << h_offset_buffer[i] << " numpoints: " << num_points + << " idx: " << i << std::endl; + FAIL(); + } + break; + case static_cast(cuspatial::IntersectionTypeCode::LINESTRING): + if (h_offset_buffer[i] >= num_segments) { + std::cout << "offset: " << h_offset_buffer[i] << " numsegments: " << num_segments + << " idx: " << i << std::endl; + FAIL(); + } + // EXPECT_LT(h_offset_buffer[i], num_segments); + break; + default: + FAIL() << "Unknown intersection type. idx: " << i + << " type: " << static_cast(h_types_buffer[i]); + } + } + } +}; + +// float and double are logically the same but would require separate tests due to precision. +using TestTypes = ::testing::Types; +TYPED_TEST_CASE(LinestringIntersectionLargeTest, TestTypes); + +TYPED_TEST(LinestringIntersectionLargeTest, LongInput) +{ + using T = TypeParam; + using P = cuspatial::vec_2d; + + auto multilinestrings1 = cuspatial::test::make_multilinestring_array( + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, + 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, + 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, + 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, + 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, + 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, + 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, + 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, + 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, + 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, + 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, + 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, + 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, + 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, + 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, + 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, + 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, + 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, + 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, + 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, + 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, + 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, + 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, + 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, + 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, + 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, + 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, + 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, + 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, + 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, + 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, + 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, + 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, + 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, + 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, + 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, + 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, + 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, + 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, + 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, + 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, + 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, + 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, + 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, + 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, + 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, + 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, + 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, + 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, + 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, + 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, + 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, + 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, + 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, + 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, + 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, + 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, + 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, + 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, + 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, + 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, + 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, + 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, + 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, + 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, + 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, + 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, + 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, + 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, + 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, + 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, + 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, + 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, + 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, + 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, + 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, + 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, + 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, + 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, + 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, + 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, + 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, + 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, + 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, + 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, + 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, + 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, + 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, + 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, + 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, + 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, + 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, + 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, + 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, + 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, + 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, + 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, + 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, + 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, + 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, + 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, + 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, + 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, + 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, + 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, + 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, + 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, + 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, + 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, + 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, + 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, + 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, + 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, + 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, + 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, + 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, + 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, + 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, + 2385, 2386, 2387, 2388, 2389, 2390, + }, + { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, + 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, + 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, + 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, + 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, + 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, + 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, + 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, + 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, + 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 358, + 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, + 390, 392, 394, 396, 398, 400, 402, 404, 406, 408, 410, 412, 414, 416, 418, + 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, + 450, 452, 454, 456, 458, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, + 480, 482, 484, 486, 488, 490, 492, 494, 496, 498, 500, 502, 504, 506, 508, + 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, 532, 534, 536, 538, + 540, 542, 544, 546, 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, + 570, 572, 574, 576, 578, 580, 582, 584, 586, 588, 590, 592, 594, 596, 598, + 600, 602, 604, 606, 608, 610, 612, 614, 616, 618, 620, 622, 624, 626, 628, + 630, 632, 634, 636, 638, 640, 642, 644, 646, 648, 650, 652, 654, 656, 658, + 660, 662, 664, 666, 668, 670, 672, 674, 676, 678, 680, 682, 684, 686, 688, + 690, 692, 694, 696, 698, 700, 702, 704, 706, 708, 710, 712, 714, 716, 718, + 720, 722, 724, 726, 728, 730, 732, 734, 736, 738, 740, 742, 744, 746, 748, + 750, 752, 754, 756, 758, 760, 762, 764, 766, 768, 770, 772, 774, 776, 778, + 780, 782, 784, 786, 788, 790, 792, 794, 796, 798, 800, 802, 804, 806, 808, + 810, 812, 814, 816, 818, 820, 822, 824, 826, 828, 830, 832, 834, 836, 838, + 840, 842, 844, 846, 848, 850, 852, 854, 856, 858, 860, 862, 864, 866, 868, + 870, 872, 874, 876, 878, 880, 882, 884, 886, 888, 890, 892, 894, 896, 898, + 900, 902, 904, 906, 908, 910, 912, 914, 916, 918, 920, 922, 924, 926, 928, + 930, 932, 934, 936, 938, 940, 942, 944, 946, 948, 950, 952, 954, 956, 958, + 960, 962, 964, 966, 968, 970, 972, 974, 976, 978, 980, 982, 984, 986, 988, + 990, 992, 994, 996, 998, 1000, 1002, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1018, + 1020, 1022, 1024, 1026, 1028, 1030, 1032, 1034, 1036, 1038, 1040, 1042, 1044, 1046, 1048, + 1050, 1052, 1054, 1056, 1058, 1060, 1062, 1064, 1066, 1068, 1070, 1072, 1074, 1076, 1078, + 1080, 1082, 1084, 1086, 1088, 1090, 1092, 1094, 1096, 1098, 1100, 1102, 1104, 1106, 1108, + 1110, 1112, 1114, 1116, 1118, 1120, 1122, 1124, 1126, 1128, 1130, 1132, 1134, 1136, 1138, + 1140, 1142, 1144, 1146, 1148, 1150, 1152, 1154, 1156, 1158, 1160, 1162, 1164, 1166, 1168, + 1170, 1172, 1174, 1176, 1178, 1180, 1182, 1184, 1186, 1188, 1190, 1192, 1194, 1196, 1198, + 1200, 1202, 1204, 1206, 1208, 1210, 1212, 1214, 1216, 1218, 1220, 1222, 1224, 1226, 1228, + 1230, 1232, 1234, 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, + 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, 1284, 1286, 1288, + 1290, 1292, 1294, 1296, 1298, 1300, 1302, 1304, 1306, 1308, 1310, 1312, 1314, 1316, 1318, + 1320, 1322, 1324, 1326, 1328, 1330, 1332, 1334, 1336, 1338, 1340, 1342, 1344, 1346, 1348, + 1350, 1352, 1354, 1356, 1358, 1360, 1362, 1364, 1366, 1368, 1370, 1372, 1374, 1376, 1378, + 1380, 1382, 1384, 1386, 1388, 1390, 1392, 1394, 1396, 1398, 1400, 1402, 1404, 1406, 1408, + 1410, 1412, 1414, 1416, 1418, 1420, 1422, 1424, 1426, 1428, 1430, 1432, 1434, 1436, 1438, + 1440, 1442, 1444, 1446, 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, + 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, 1494, 1496, 1498, + 1500, 1502, 1504, 1506, 1508, 1510, 1512, 1514, 1516, 1518, 1520, 1522, 1524, 1526, 1528, + 1530, 1532, 1534, 1536, 1538, 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, + 1560, 1562, 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, 1588, + 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, 1612, 1614, 1616, 1618, + 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, 1636, 1638, 1640, 1642, 1644, 1646, 1648, + 1650, 1652, 1654, 1656, 1658, 1660, 1662, 1664, 1666, 1668, 1670, 1672, 1674, 1676, 1678, + 1680, 1682, 1684, 1686, 1688, 1690, 1692, 1694, 1696, 1698, 1700, 1702, 1704, 1706, 1708, + 1710, 1712, 1714, 1716, 1718, 1720, 1722, 1724, 1726, 1728, 1730, 1732, 1734, 1736, 1738, + 1740, 1742, 1744, 1746, 1748, 1750, 1752, 1754, 1756, 1758, 1760, 1762, 1764, 1766, 1768, + 1770, 1772, 1774, 1776, 1778, 1780, 1782, 1784, 1786, 1788, 1790, 1792, 1794, 1796, 1798, + 1800, 1802, 1804, 1806, 1808, 1810, 1812, 1814, 1816, 1818, 1820, 1822, 1824, 1826, 1828, + 1830, 1832, 1834, 1836, 1838, 1840, 1842, 1844, 1846, 1848, 1850, 1852, 1854, 1856, 1858, + 1860, 1862, 1864, 1866, 1868, 1870, 1872, 1874, 1876, 1878, 1880, 1882, 1884, 1886, 1888, + 1890, 1892, 1894, 1896, 1898, 1900, 1902, 1904, 1906, 1908, 1910, 1912, 1914, 1916, 1918, + 1920, 1922, 1924, 1926, 1928, 1930, 1932, 1934, 1936, 1938, 1940, 1942, 1944, 1946, 1948, + 1950, 1952, 1954, 1956, 1958, 1960, 1962, 1964, 1966, 1968, 1970, 1972, 1974, 1976, 1978, + 1980, 1982, 1984, 1986, 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2004, 2006, 2008, + 2010, 2012, 2014, 2016, 2018, 2020, 2022, 2024, 2026, 2028, 2030, 2032, 2034, 2036, 2038, + 2040, 2042, 2044, 2046, 2048, 2050, 2052, 2054, 2056, 2058, 2060, 2062, 2064, 2066, 2068, + 2070, 2072, 2074, 2076, 2078, 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, 2096, 2098, + 2100, 2102, 2104, 2106, 2108, 2110, 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, 2128, + 2130, 2132, 2134, 2136, 2138, 2140, 2142, 2144, 2146, 2148, 2150, 2152, 2154, 2156, 2158, + 2160, 2162, 2164, 2166, 2168, 2170, 2172, 2174, 2176, 2178, 2180, 2182, 2184, 2186, 2188, + 2190, 2192, 2194, 2196, 2198, 2200, 2202, 2204, 2206, 2208, 2210, 2212, 2214, 2216, 2218, + 2220, 2222, 2224, 2226, 2228, 2230, 2232, 2234, 2236, 2238, 2240, 2242, 2244, 2246, 2248, + 2250, 2252, 2254, 2256, 2258, 2260, 2262, 2264, 2266, 2268, 2270, 2272, 2274, 2276, 2278, + 2280, 2282, 2284, 2286, 2288, 2290, 2292, 2294, 2296, 2298, 2300, 2302, 2304, 2306, 2308, + 2310, 2312, 2314, 2316, 2318, 2320, 2322, 2324, 2326, 2328, 2330, 2332, 2334, 2336, 2338, + 2340, 2342, 2344, 2346, 2348, 2350, 2352, 2354, 2356, 2358, 2360, 2362, 2364, 2366, 2368, + 2370, 2372, 2374, 2376, 2378, 2380, 2382, 2384, 2386, 2388, 2390, 2392, 2394, 2396, 2398, + 2400, 2402, 2404, 2406, 2408, 2410, 2412, 2414, 2416, 2418, 2420, 2422, 2424, 2426, 2428, + 2430, 2432, 2434, 2436, 2438, 2440, 2442, 2444, 2446, 2448, 2450, 2452, 2454, 2456, 2458, + 2460, 2462, 2464, 2466, 2468, 2470, 2472, 2474, 2476, 2478, 2480, 2482, 2484, 2486, 2488, + 2490, 2492, 2494, 2496, 2498, 2500, 2502, 2504, 2506, 2508, 2510, 2512, 2514, 2516, 2518, + 2520, 2522, 2524, 2526, 2528, 2530, 2532, 2534, 2536, 2538, 2540, 2542, 2544, 2546, 2548, + 2550, 2552, 2554, 2556, 2558, 2560, 2562, 2564, 2566, 2568, 2570, 2572, 2574, 2576, 2578, + 2580, 2582, 2584, 2586, 2588, 2590, 2592, 2594, 2596, 2598, 2600, 2602, 2604, 2606, 2608, + 2610, 2612, 2614, 2616, 2618, 2620, 2622, 2624, 2626, 2628, 2630, 2632, 2634, 2636, 2638, + 2640, 2642, 2644, 2646, 2648, 2650, 2652, 2654, 2656, 2658, 2660, 2662, 2664, 2666, 2668, + 2670, 2672, 2674, 2676, 2678, 2680, 2682, 2684, 2686, 2688, 2690, 2692, 2694, 2696, 2698, + 2700, 2702, 2704, 2706, 2708, 2710, 2712, 2714, 2716, 2718, 2720, 2722, 2724, 2726, 2728, + 2730, 2732, 2734, 2736, 2738, 2740, 2742, 2744, 2746, 2748, 2750, 2752, 2754, 2756, 2758, + 2760, 2762, 2764, 2766, 2768, 2770, 2772, 2774, 2776, 2778, 2780, 2782, 2784, 2786, 2788, + 2790, 2792, 2794, 2796, 2798, 2800, 2802, 2804, 2806, 2808, 2810, 2812, 2814, 2816, 2818, + 2820, 2822, 2824, 2826, 2828, 2830, 2832, 2834, 2836, 2838, 2840, 2842, 2844, 2846, 2848, + 2850, 2852, 2854, 2856, 2858, 2860, 2862, 2864, 2866, 2868, 2870, 2872, 2874, 2876, 2878, + 2880, 2882, 2884, 2886, 2888, 2890, 2892, 2894, 2896, 2898, 2900, 2902, 2904, 2906, 2908, + 2910, 2912, 2914, 2916, 2918, 2920, 2922, 2924, 2926, 2928, 2930, 2932, 2934, 2936, 2938, + 2940, 2942, 2944, 2946, 2948, 2950, 2952, 2954, 2956, 2958, 2960, 2962, 2964, 2966, 2968, + 2970, 2972, 2974, 2976, 2978, 2980, 2982, 2984, 2986, 2988, 2990, 2992, 2994, 2996, 2998, + 3000, 3002, 3004, 3006, 3008, 3010, 3012, 3014, 3016, 3018, 3020, 3022, 3024, 3026, 3028, + 3030, 3032, 3034, 3036, 3038, 3040, 3042, 3044, 3046, 3048, 3050, 3052, 3054, 3056, 3058, + 3060, 3062, 3064, 3066, 3068, 3070, 3072, 3074, 3076, 3078, 3080, 3082, 3084, 3086, 3088, + 3090, 3092, 3094, 3096, 3098, 3100, 3102, 3104, 3106, 3108, 3110, 3112, 3114, 3116, 3118, + 3120, 3122, 3124, 3126, 3128, 3130, 3132, 3134, 3136, 3138, 3140, 3142, 3144, 3146, 3148, + 3150, 3152, 3154, 3156, 3158, 3160, 3162, 3164, 3166, 3168, 3170, 3172, 3174, 3176, 3178, + 3180, 3182, 3184, 3186, 3188, 3190, 3192, 3194, 3196, 3198, 3200, 3202, 3204, 3206, 3208, + 3210, 3212, 3214, 3216, 3218, 3220, 3222, 3224, 3226, 3228, 3230, 3232, 3234, 3236, 3238, + 3240, 3242, 3244, 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 3262, 3264, 3266, 3268, + 3270, 3272, 3274, 3276, 3278, 3280, 3282, 3284, 3286, 3288, 3290, 3292, 3294, 3296, 3298, + 3300, 3302, 3304, 3306, 3308, 3310, 3312, 3314, 3316, 3318, 3320, 3322, 3324, 3326, 3328, + 3330, 3332, 3334, 3336, 3338, 3340, 3342, 3344, 3346, 3348, 3350, 3352, 3354, 3356, 3358, + 3360, 3362, 3364, 3366, 3368, 3370, 3372, 3374, 3376, 3378, 3380, 3382, 3384, 3386, 3388, + 3390, 3392, 3394, 3396, 3398, 3400, 3402, 3404, 3406, 3408, 3410, 3412, 3414, 3416, 3418, + 3420, 3422, 3424, 3426, 3428, 3430, 3432, 3434, 3436, 3438, 3440, 3442, 3444, 3446, 3448, + 3450, 3452, 3454, 3456, 3458, 3460, 3462, 3464, 3466, 3468, 3470, 3472, 3474, 3476, 3478, + 3480, 3482, 3484, 3486, 3488, 3490, 3492, 3494, 3496, 3498, 3500, 3502, 3504, 3506, 3508, + 3510, 3512, 3514, 3516, 3518, 3520, 3522, 3524, 3526, 3528, 3530, 3532, 3534, 3536, 3538, + 3540, 3542, 3544, 3546, 3548, 3550, 3552, 3554, 3556, 3558, 3560, 3562, 3564, 3566, 3568, + 3570, 3572, 3574, 3576, 3578, 3580, 3582, 3584, 3586, 3588, 3590, 3592, 3594, 3596, 3598, + 3600, 3602, 3604, 3606, 3608, 3610, 3612, 3614, 3616, 3618, 3620, 3622, 3624, 3626, 3628, + 3630, 3632, 3634, 3636, 3638, 3640, 3642, 3644, 3646, 3648, 3650, 3652, 3654, 3656, 3658, + 3660, 3662, 3664, 3666, 3668, 3670, 3672, 3674, 3676, 3678, 3680, 3682, 3684, 3686, 3688, + 3690, 3692, 3694, 3696, 3698, 3700, 3702, 3704, 3706, 3708, 3710, 3712, 3714, 3716, 3718, + 3720, 3722, 3724, 3726, 3728, 3730, 3732, 3734, 3736, 3738, 3740, 3742, 3744, 3746, 3748, + 3750, 3752, 3754, 3756, 3758, 3760, 3762, 3764, 3766, 3768, 3770, 3772, 3774, 3776, 3778, + 3780, 3782, 3784, 3786, 3788, 3790, 3792, 3794, 3796, 3798, 3800, 3802, 3804, 3806, 3808, + 3810, 3812, 3814, 3816, 3818, 3820, 3822, 3824, 3826, 3828, 3830, 3832, 3834, 3836, 3838, + 3840, 3842, 3844, 3846, 3848, 3850, 3852, 3854, 3856, 3858, 3860, 3862, 3864, 3866, 3868, + 3870, 3872, 3874, 3876, 3878, 3880, 3882, 3884, 3886, 3888, 3890, 3892, 3894, 3896, 3898, + 3900, 3902, 3904, 3906, 3908, 3910, 3912, 3914, 3916, 3918, 3920, 3922, 3924, 3926, 3928, + 3930, 3932, 3934, 3936, 3938, 3940, 3942, 3944, 3946, 3948, 3950, 3952, 3954, 3956, 3958, + 3960, 3962, 3964, 3966, 3968, 3970, 3972, 3974, 3976, 3978, 3980, 3982, 3984, 3986, 3988, + 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4014, 4016, 4018, + 4020, 4022, 4024, 4026, 4028, 4030, 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, + 4050, 4052, 4054, 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 4078, + 4080, 4082, 4084, 4086, 4088, 4090, 4092, 4094, 4096, 4098, 4100, 4102, 4104, 4106, 4108, + 4110, 4112, 4114, 4116, 4118, 4120, 4122, 4124, 4126, 4128, 4130, 4132, 4134, 4136, 4138, + 4140, 4142, 4144, 4146, 4148, 4150, 4152, 4154, 4156, 4158, 4160, 4162, 4164, 4166, 4168, + 4170, 4172, 4174, 4176, 4178, 4180, 4182, 4184, 4186, 4188, 4190, 4192, 4194, 4196, 4198, + 4200, 4202, 4204, 4206, 4208, 4210, 4212, 4214, 4216, 4218, 4220, 4222, 4224, 4226, 4228, + 4230, 4232, 4234, 4236, 4238, 4240, 4242, 4244, 4246, 4248, 4250, 4252, 4254, 4256, 4258, + 4260, 4262, 4264, 4266, 4268, 4270, 4272, 4274, 4276, 4278, 4280, 4282, 4284, 4286, 4288, + 4290, 4292, 4294, 4296, 4298, 4300, 4302, 4304, 4306, 4308, 4310, 4312, 4314, 4316, 4318, + 4320, 4322, 4324, 4326, 4328, 4330, 4332, 4334, 4336, 4338, 4340, 4342, 4344, 4346, 4348, + 4350, 4352, 4354, 4356, 4358, 4360, 4362, 4364, 4366, 4368, 4370, 4372, 4374, 4376, 4378, + 4380, 4382, 4384, 4386, 4388, 4390, 4392, 4394, 4396, 4398, 4400, 4402, 4404, 4406, 4408, + 4410, 4412, 4414, 4416, 4418, 4420, 4422, 4424, 4426, 4428, 4430, 4432, 4434, 4436, 4438, + 4440, 4442, 4444, 4446, 4448, 4450, 4452, 4454, 4456, 4458, 4460, 4462, 4464, 4466, 4468, + 4470, 4472, 4474, 4476, 4478, 4480, 4482, 4484, 4486, 4488, 4490, 4492, 4494, 4496, 4498, + 4500, 4502, 4504, 4506, 4508, 4510, 4512, 4514, 4516, 4518, 4520, 4522, 4524, 4526, 4528, + 4530, 4532, 4534, 4536, 4538, 4540, 4542, 4544, 4546, 4548, 4550, 4552, 4554, 4556, 4558, + 4560, 4562, 4564, 4566, 4568, 4570, 4572, 4574, 4576, 4578, 4580, 4582, 4584, 4586, 4588, + 4590, 4592, 4594, 4596, 4598, 4600, 4602, 4604, 4606, 4608, 4610, 4612, 4614, 4616, 4618, + 4620, 4622, 4624, 4626, 4628, 4630, 4632, 4634, 4636, 4638, 4640, 4642, 4644, 4646, 4648, + 4650, 4652, 4654, 4656, 4658, 4660, 4662, 4664, 4666, 4668, 4670, 4672, 4674, 4676, 4678, + 4680, 4682, 4684, 4686, 4688, 4690, 4692, 4694, 4696, 4698, 4700, 4702, 4704, 4706, 4708, + 4710, 4712, 4714, 4716, 4718, 4720, 4722, 4724, 4726, 4728, 4730, 4732, 4734, 4736, 4738, + 4740, 4742, 4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4764, 4766, 4768, + 4770, 4772, 4774, 4776, 4778, 4780, + }, + { + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, + {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {0.0, 1.0}, + {0.5, 0.0}, {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, + {0.5, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + }); + + auto multilinestrings2 = cuspatial::test::make_multilinestring_array( + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, + 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, + 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, + 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, + 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, + 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, + 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, + 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, + 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, + 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, + 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, + 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, + 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, + 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, + 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, + 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, + 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, + 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, + 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, + 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, + 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, + 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, + 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, + 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, + 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, + 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, + 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, + 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, + 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, + 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, + 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, + 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, + 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, + 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, + 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, + 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, + 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, + 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, + 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, + 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, + 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, + 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, + 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, + 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, + 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, + 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, + 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, + 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, + 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, + 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, + 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, + 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, + 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, + 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, + 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, + 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, + 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, + 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, + 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, + 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, + 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, + 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, + 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, + 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, + 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, + 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, + 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, + 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, + 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, + 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, + 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, + 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, + 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, + 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, + 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, + 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, + 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, + 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, + 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, + 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, + 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, + 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, + 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, + 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, + 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, + 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, + 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, + 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, + 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, + 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, + 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, + 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, + 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, + 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, + 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, + 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, + 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, + 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, + 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, + 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, + 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, + 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, + 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, + 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, + 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, + 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, + 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, + 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, + 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, + 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, + 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, + 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, + 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, + 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, + 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, + 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, + 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, + 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, + 2385, 2386, 2387, 2388, 2389, 2390, + }, + { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, + 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, + 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, + 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, + 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, + 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, + 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, + 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, + 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, + 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 358, + 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, + 390, 392, 394, 396, 398, 400, 402, 404, 406, 408, 410, 412, 414, 416, 418, + 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, + 450, 452, 454, 456, 458, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, + 480, 482, 484, 486, 488, 490, 492, 494, 496, 498, 500, 502, 504, 506, 508, + 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, 532, 534, 536, 538, + 540, 542, 544, 546, 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, + 570, 572, 574, 576, 578, 580, 582, 584, 586, 588, 590, 592, 594, 596, 598, + 600, 602, 604, 606, 608, 610, 612, 614, 616, 618, 620, 622, 624, 626, 628, + 630, 632, 634, 636, 638, 640, 642, 644, 646, 648, 650, 652, 654, 656, 658, + 660, 662, 664, 666, 668, 670, 672, 674, 676, 678, 680, 682, 684, 686, 688, + 690, 692, 694, 696, 698, 700, 702, 704, 706, 708, 710, 712, 714, 716, 718, + 720, 722, 724, 726, 728, 730, 732, 734, 736, 738, 740, 742, 744, 746, 748, + 750, 752, 754, 756, 758, 760, 762, 764, 766, 768, 770, 772, 774, 776, 778, + 780, 782, 784, 786, 788, 790, 792, 794, 796, 798, 800, 802, 804, 806, 808, + 810, 812, 814, 816, 818, 820, 822, 824, 826, 828, 830, 832, 834, 836, 838, + 840, 842, 844, 846, 848, 850, 852, 854, 856, 858, 860, 862, 864, 866, 868, + 870, 872, 874, 876, 878, 880, 882, 884, 886, 888, 890, 892, 894, 896, 898, + 900, 902, 904, 906, 908, 910, 912, 914, 916, 918, 920, 922, 924, 926, 928, + 930, 932, 934, 936, 938, 940, 942, 944, 946, 948, 950, 952, 954, 956, 958, + 960, 962, 964, 966, 968, 970, 972, 974, 976, 978, 980, 982, 984, 986, 988, + 990, 992, 994, 996, 998, 1000, 1002, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1018, + 1020, 1022, 1024, 1026, 1028, 1030, 1032, 1034, 1036, 1038, 1040, 1042, 1044, 1046, 1048, + 1050, 1052, 1054, 1056, 1058, 1060, 1062, 1064, 1066, 1068, 1070, 1072, 1074, 1076, 1078, + 1080, 1082, 1084, 1086, 1088, 1090, 1092, 1094, 1096, 1098, 1100, 1102, 1104, 1106, 1108, + 1110, 1112, 1114, 1116, 1118, 1120, 1122, 1124, 1126, 1128, 1130, 1132, 1134, 1136, 1138, + 1140, 1142, 1144, 1146, 1148, 1150, 1152, 1154, 1156, 1158, 1160, 1162, 1164, 1166, 1168, + 1170, 1172, 1174, 1176, 1178, 1180, 1182, 1184, 1186, 1188, 1190, 1192, 1194, 1196, 1198, + 1200, 1202, 1204, 1206, 1208, 1210, 1212, 1214, 1216, 1218, 1220, 1222, 1224, 1226, 1228, + 1230, 1232, 1234, 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, + 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, 1284, 1286, 1288, + 1290, 1292, 1294, 1296, 1298, 1300, 1302, 1304, 1306, 1308, 1310, 1312, 1314, 1316, 1318, + 1320, 1322, 1324, 1326, 1328, 1330, 1332, 1334, 1336, 1338, 1340, 1342, 1344, 1346, 1348, + 1350, 1352, 1354, 1356, 1358, 1360, 1362, 1364, 1366, 1368, 1370, 1372, 1374, 1376, 1378, + 1380, 1382, 1384, 1386, 1388, 1390, 1392, 1394, 1396, 1398, 1400, 1402, 1404, 1406, 1408, + 1410, 1412, 1414, 1416, 1418, 1420, 1422, 1424, 1426, 1428, 1430, 1432, 1434, 1436, 1438, + 1440, 1442, 1444, 1446, 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, + 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, 1494, 1496, 1498, + 1500, 1502, 1504, 1506, 1508, 1510, 1512, 1514, 1516, 1518, 1520, 1522, 1524, 1526, 1528, + 1530, 1532, 1534, 1536, 1538, 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, + 1560, 1562, 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, 1588, + 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, 1612, 1614, 1616, 1618, + 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, 1636, 1638, 1640, 1642, 1644, 1646, 1648, + 1650, 1652, 1654, 1656, 1658, 1660, 1662, 1664, 1666, 1668, 1670, 1672, 1674, 1676, 1678, + 1680, 1682, 1684, 1686, 1688, 1690, 1692, 1694, 1696, 1698, 1700, 1702, 1704, 1706, 1708, + 1710, 1712, 1714, 1716, 1718, 1720, 1722, 1724, 1726, 1728, 1730, 1732, 1734, 1736, 1738, + 1740, 1742, 1744, 1746, 1748, 1750, 1752, 1754, 1756, 1758, 1760, 1762, 1764, 1766, 1768, + 1770, 1772, 1774, 1776, 1778, 1780, 1782, 1784, 1786, 1788, 1790, 1792, 1794, 1796, 1798, + 1800, 1802, 1804, 1806, 1808, 1810, 1812, 1814, 1816, 1818, 1820, 1822, 1824, 1826, 1828, + 1830, 1832, 1834, 1836, 1838, 1840, 1842, 1844, 1846, 1848, 1850, 1852, 1854, 1856, 1858, + 1860, 1862, 1864, 1866, 1868, 1870, 1872, 1874, 1876, 1878, 1880, 1882, 1884, 1886, 1888, + 1890, 1892, 1894, 1896, 1898, 1900, 1902, 1904, 1906, 1908, 1910, 1912, 1914, 1916, 1918, + 1920, 1922, 1924, 1926, 1928, 1930, 1932, 1934, 1936, 1938, 1940, 1942, 1944, 1946, 1948, + 1950, 1952, 1954, 1956, 1958, 1960, 1962, 1964, 1966, 1968, 1970, 1972, 1974, 1976, 1978, + 1980, 1982, 1984, 1986, 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2004, 2006, 2008, + 2010, 2012, 2014, 2016, 2018, 2020, 2022, 2024, 2026, 2028, 2030, 2032, 2034, 2036, 2038, + 2040, 2042, 2044, 2046, 2048, 2050, 2052, 2054, 2056, 2058, 2060, 2062, 2064, 2066, 2068, + 2070, 2072, 2074, 2076, 2078, 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, 2096, 2098, + 2100, 2102, 2104, 2106, 2108, 2110, 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, 2128, + 2130, 2132, 2134, 2136, 2138, 2140, 2142, 2144, 2146, 2148, 2150, 2152, 2154, 2156, 2158, + 2160, 2162, 2164, 2166, 2168, 2170, 2172, 2174, 2176, 2178, 2180, 2182, 2184, 2186, 2188, + 2190, 2192, 2194, 2196, 2198, 2200, 2202, 2204, 2206, 2208, 2210, 2212, 2214, 2216, 2218, + 2220, 2222, 2224, 2226, 2228, 2230, 2232, 2234, 2236, 2238, 2240, 2242, 2244, 2246, 2248, + 2250, 2252, 2254, 2256, 2258, 2260, 2262, 2264, 2266, 2268, 2270, 2272, 2274, 2276, 2278, + 2280, 2282, 2284, 2286, 2288, 2290, 2292, 2294, 2296, 2298, 2300, 2302, 2304, 2306, 2308, + 2310, 2312, 2314, 2316, 2318, 2320, 2322, 2324, 2326, 2328, 2330, 2332, 2334, 2336, 2338, + 2340, 2342, 2344, 2346, 2348, 2350, 2352, 2354, 2356, 2358, 2360, 2362, 2364, 2366, 2368, + 2370, 2372, 2374, 2376, 2378, 2380, 2382, 2384, 2386, 2388, 2390, 2392, 2394, 2396, 2398, + 2400, 2402, 2404, 2406, 2408, 2410, 2412, 2414, 2416, 2418, 2420, 2422, 2424, 2426, 2428, + 2430, 2432, 2434, 2436, 2438, 2440, 2442, 2444, 2446, 2448, 2450, 2452, 2454, 2456, 2458, + 2460, 2462, 2464, 2466, 2468, 2470, 2472, 2474, 2476, 2478, 2480, 2482, 2484, 2486, 2488, + 2490, 2492, 2494, 2496, 2498, 2500, 2502, 2504, 2506, 2508, 2510, 2512, 2514, 2516, 2518, + 2520, 2522, 2524, 2526, 2528, 2530, 2532, 2534, 2536, 2538, 2540, 2542, 2544, 2546, 2548, + 2550, 2552, 2554, 2556, 2558, 2560, 2562, 2564, 2566, 2568, 2570, 2572, 2574, 2576, 2578, + 2580, 2582, 2584, 2586, 2588, 2590, 2592, 2594, 2596, 2598, 2600, 2602, 2604, 2606, 2608, + 2610, 2612, 2614, 2616, 2618, 2620, 2622, 2624, 2626, 2628, 2630, 2632, 2634, 2636, 2638, + 2640, 2642, 2644, 2646, 2648, 2650, 2652, 2654, 2656, 2658, 2660, 2662, 2664, 2666, 2668, + 2670, 2672, 2674, 2676, 2678, 2680, 2682, 2684, 2686, 2688, 2690, 2692, 2694, 2696, 2698, + 2700, 2702, 2704, 2706, 2708, 2710, 2712, 2714, 2716, 2718, 2720, 2722, 2724, 2726, 2728, + 2730, 2732, 2734, 2736, 2738, 2740, 2742, 2744, 2746, 2748, 2750, 2752, 2754, 2756, 2758, + 2760, 2762, 2764, 2766, 2768, 2770, 2772, 2774, 2776, 2778, 2780, 2782, 2784, 2786, 2788, + 2790, 2792, 2794, 2796, 2798, 2800, 2802, 2804, 2806, 2808, 2810, 2812, 2814, 2816, 2818, + 2820, 2822, 2824, 2826, 2828, 2830, 2832, 2834, 2836, 2838, 2840, 2842, 2844, 2846, 2848, + 2850, 2852, 2854, 2856, 2858, 2860, 2862, 2864, 2866, 2868, 2870, 2872, 2874, 2876, 2878, + 2880, 2882, 2884, 2886, 2888, 2890, 2892, 2894, 2896, 2898, 2900, 2902, 2904, 2906, 2908, + 2910, 2912, 2914, 2916, 2918, 2920, 2922, 2924, 2926, 2928, 2930, 2932, 2934, 2936, 2938, + 2940, 2942, 2944, 2946, 2948, 2950, 2952, 2954, 2956, 2958, 2960, 2962, 2964, 2966, 2968, + 2970, 2972, 2974, 2976, 2978, 2980, 2982, 2984, 2986, 2988, 2990, 2992, 2994, 2996, 2998, + 3000, 3002, 3004, 3006, 3008, 3010, 3012, 3014, 3016, 3018, 3020, 3022, 3024, 3026, 3028, + 3030, 3032, 3034, 3036, 3038, 3040, 3042, 3044, 3046, 3048, 3050, 3052, 3054, 3056, 3058, + 3060, 3062, 3064, 3066, 3068, 3070, 3072, 3074, 3076, 3078, 3080, 3082, 3084, 3086, 3088, + 3090, 3092, 3094, 3096, 3098, 3100, 3102, 3104, 3106, 3108, 3110, 3112, 3114, 3116, 3118, + 3120, 3122, 3124, 3126, 3128, 3130, 3132, 3134, 3136, 3138, 3140, 3142, 3144, 3146, 3148, + 3150, 3152, 3154, 3156, 3158, 3160, 3162, 3164, 3166, 3168, 3170, 3172, 3174, 3176, 3178, + 3180, 3182, 3184, 3186, 3188, 3190, 3192, 3194, 3196, 3198, 3200, 3202, 3204, 3206, 3208, + 3210, 3212, 3214, 3216, 3218, 3220, 3222, 3224, 3226, 3228, 3230, 3232, 3234, 3236, 3238, + 3240, 3242, 3244, 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 3262, 3264, 3266, 3268, + 3270, 3272, 3274, 3276, 3278, 3280, 3282, 3284, 3286, 3288, 3290, 3292, 3294, 3296, 3298, + 3300, 3302, 3304, 3306, 3308, 3310, 3312, 3314, 3316, 3318, 3320, 3322, 3324, 3326, 3328, + 3330, 3332, 3334, 3336, 3338, 3340, 3342, 3344, 3346, 3348, 3350, 3352, 3354, 3356, 3358, + 3360, 3362, 3364, 3366, 3368, 3370, 3372, 3374, 3376, 3378, 3380, 3382, 3384, 3386, 3388, + 3390, 3392, 3394, 3396, 3398, 3400, 3402, 3404, 3406, 3408, 3410, 3412, 3414, 3416, 3418, + 3420, 3422, 3424, 3426, 3428, 3430, 3432, 3434, 3436, 3438, 3440, 3442, 3444, 3446, 3448, + 3450, 3452, 3454, 3456, 3458, 3460, 3462, 3464, 3466, 3468, 3470, 3472, 3474, 3476, 3478, + 3480, 3482, 3484, 3486, 3488, 3490, 3492, 3494, 3496, 3498, 3500, 3502, 3504, 3506, 3508, + 3510, 3512, 3514, 3516, 3518, 3520, 3522, 3524, 3526, 3528, 3530, 3532, 3534, 3536, 3538, + 3540, 3542, 3544, 3546, 3548, 3550, 3552, 3554, 3556, 3558, 3560, 3562, 3564, 3566, 3568, + 3570, 3572, 3574, 3576, 3578, 3580, 3582, 3584, 3586, 3588, 3590, 3592, 3594, 3596, 3598, + 3600, 3602, 3604, 3606, 3608, 3610, 3612, 3614, 3616, 3618, 3620, 3622, 3624, 3626, 3628, + 3630, 3632, 3634, 3636, 3638, 3640, 3642, 3644, 3646, 3648, 3650, 3652, 3654, 3656, 3658, + 3660, 3662, 3664, 3666, 3668, 3670, 3672, 3674, 3676, 3678, 3680, 3682, 3684, 3686, 3688, + 3690, 3692, 3694, 3696, 3698, 3700, 3702, 3704, 3706, 3708, 3710, 3712, 3714, 3716, 3718, + 3720, 3722, 3724, 3726, 3728, 3730, 3732, 3734, 3736, 3738, 3740, 3742, 3744, 3746, 3748, + 3750, 3752, 3754, 3756, 3758, 3760, 3762, 3764, 3766, 3768, 3770, 3772, 3774, 3776, 3778, + 3780, 3782, 3784, 3786, 3788, 3790, 3792, 3794, 3796, 3798, 3800, 3802, 3804, 3806, 3808, + 3810, 3812, 3814, 3816, 3818, 3820, 3822, 3824, 3826, 3828, 3830, 3832, 3834, 3836, 3838, + 3840, 3842, 3844, 3846, 3848, 3850, 3852, 3854, 3856, 3858, 3860, 3862, 3864, 3866, 3868, + 3870, 3872, 3874, 3876, 3878, 3880, 3882, 3884, 3886, 3888, 3890, 3892, 3894, 3896, 3898, + 3900, 3902, 3904, 3906, 3908, 3910, 3912, 3914, 3916, 3918, 3920, 3922, 3924, 3926, 3928, + 3930, 3932, 3934, 3936, 3938, 3940, 3942, 3944, 3946, 3948, 3950, 3952, 3954, 3956, 3958, + 3960, 3962, 3964, 3966, 3968, 3970, 3972, 3974, 3976, 3978, 3980, 3982, 3984, 3986, 3988, + 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4014, 4016, 4018, + 4020, 4022, 4024, 4026, 4028, 4030, 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, + 4050, 4052, 4054, 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 4078, + 4080, 4082, 4084, 4086, 4088, 4090, 4092, 4094, 4096, 4098, 4100, 4102, 4104, 4106, 4108, + 4110, 4112, 4114, 4116, 4118, 4120, 4122, 4124, 4126, 4128, 4130, 4132, 4134, 4136, 4138, + 4140, 4142, 4144, 4146, 4148, 4150, 4152, 4154, 4156, 4158, 4160, 4162, 4164, 4166, 4168, + 4170, 4172, 4174, 4176, 4178, 4180, 4182, 4184, 4186, 4188, 4190, 4192, 4194, 4196, 4198, + 4200, 4202, 4204, 4206, 4208, 4210, 4212, 4214, 4216, 4218, 4220, 4222, 4224, 4226, 4228, + 4230, 4232, 4234, 4236, 4238, 4240, 4242, 4244, 4246, 4248, 4250, 4252, 4254, 4256, 4258, + 4260, 4262, 4264, 4266, 4268, 4270, 4272, 4274, 4276, 4278, 4280, 4282, 4284, 4286, 4288, + 4290, 4292, 4294, 4296, 4298, 4300, 4302, 4304, 4306, 4308, 4310, 4312, 4314, 4316, 4318, + 4320, 4322, 4324, 4326, 4328, 4330, 4332, 4334, 4336, 4338, 4340, 4342, 4344, 4346, 4348, + 4350, 4352, 4354, 4356, 4358, 4360, 4362, 4364, 4366, 4368, 4370, 4372, 4374, 4376, 4378, + 4380, 4382, 4384, 4386, 4388, 4390, 4392, 4394, 4396, 4398, 4400, 4402, 4404, 4406, 4408, + 4410, 4412, 4414, 4416, 4418, 4420, 4422, 4424, 4426, 4428, 4430, 4432, 4434, 4436, 4438, + 4440, 4442, 4444, 4446, 4448, 4450, 4452, 4454, 4456, 4458, 4460, 4462, 4464, 4466, 4468, + 4470, 4472, 4474, 4476, 4478, 4480, 4482, 4484, 4486, 4488, 4490, 4492, 4494, 4496, 4498, + 4500, 4502, 4504, 4506, 4508, 4510, 4512, 4514, 4516, 4518, 4520, 4522, 4524, 4526, 4528, + 4530, 4532, 4534, 4536, 4538, 4540, 4542, 4544, 4546, 4548, 4550, 4552, 4554, 4556, 4558, + 4560, 4562, 4564, 4566, 4568, 4570, 4572, 4574, 4576, 4578, 4580, 4582, 4584, 4586, 4588, + 4590, 4592, 4594, 4596, 4598, 4600, 4602, 4604, 4606, 4608, 4610, 4612, 4614, 4616, 4618, + 4620, 4622, 4624, 4626, 4628, 4630, 4632, 4634, 4636, 4638, 4640, 4642, 4644, 4646, 4648, + 4650, 4652, 4654, 4656, 4658, 4660, 4662, 4664, 4666, 4668, 4670, 4672, 4674, 4676, 4678, + 4680, 4682, 4684, 4686, 4688, 4690, 4692, 4694, 4696, 4698, 4700, 4702, 4704, 4706, 4708, + 4710, 4712, 4714, 4716, 4718, 4720, 4722, 4724, 4726, 4728, 4730, 4732, 4734, 4736, 4738, + 4740, 4742, 4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4764, 4766, 4768, + 4770, 4772, 4774, 4776, 4778, 4780, + }, + {{0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 1.0}, {1.0, 1.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.0}, {1.0, 0.0}, + {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}, {0.0, 0.5}, {1.0, 0.5}, + {0.0, 0.5}, {1.0, 0.5}, {0.0, 0.0}, {1.0, 0.0}}); + + CUSPATIAL_RUN_TEST( + this->template verify_legal_result, multilinestrings1.range(), multilinestrings2.range()); +} diff --git a/cpp/tests/intersection/linestring_intersection_test.cu b/cpp/tests/intersection/linestring_intersection_test.cu index a63de917b..a2e5b3693 100644 --- a/cpp/tests/intersection/linestring_intersection_test.cu +++ b/cpp/tests/intersection/linestring_intersection_test.cu @@ -41,157 +41,6 @@ using namespace cuspatial; using namespace cuspatial::test; -/** - * @brief Perform sorting to the intersection result - * - * The result of intersection result is non-determinisitc. This algorithm sorts - * the geometries of the same types and the same list and makes the result deterministic. - * - * The example below contains 2 rows and 4 geometries. The order of the first - * and second point is non-deterministic. - * [ - * [Point(1.0, 1.5), Point(0.0, -0.3), Segment((0.0, 0.0), (1.0, 1.0))] - * ^ ^ - * [Point(-3, -5)] - * ] - * - * After sorting, the result is deterministic: - * [ - * [Point(0.0, -0.3), Point(1.0, 1.5), Segment((0.0, 0.0), (1.0, 1.0))] - * ^ ^ - * [Point(-3, -5)] - * ] - * - * This function invalidates the input @p result and return a copy of sorted results. - */ -template -linestring_intersection_result segment_sort_intersection_result( - linestring_intersection_result& result, - rmm::mr::device_memory_resource* mr, - rmm::cuda_stream_view stream) -{ - auto const num_points = result.points_coords->size(); - auto const num_segments = result.segments_coords->size(); - auto const num_geoms = num_points + num_segments; - - rmm::device_uvector scatter_map(num_geoms, stream); - thrust::sequence(rmm::exec_policy(stream), scatter_map.begin(), scatter_map.end()); - - // Compute keys for each row in the union column. Rows of the same list - // are assigned the same label. - rmm::device_uvector geometry_collection_keys(num_geoms, stream); - auto geometry_collection_keys_begin = make_geometry_id_iterator( - result.geometry_collection_offset->begin(), result.geometry_collection_offset->end()); - - thrust::copy(rmm::exec_policy(stream), - geometry_collection_keys_begin, - geometry_collection_keys_begin + num_geoms, - geometry_collection_keys.begin()); - - // Perform "group-by" based on the list label and type of the row - - // This makes the geometry of the same type and of the same list neighbor. - - // Make a copy of types buffer so that the sorting does not affect the original. - auto types_buffer = rmm::device_uvector(*result.types_buffer, stream); - auto keys_begin = - thrust::make_zip_iterator(types_buffer.begin(), geometry_collection_keys.begin()); - auto value_begin = thrust::make_zip_iterator(scatter_map.begin(), - result.lhs_linestring_id->begin(), - result.lhs_segment_id->begin(), - result.rhs_linestring_id->begin(), - result.rhs_segment_id->begin()); - - thrust::sort_by_key(rmm::exec_policy(stream), keys_begin, keys_begin + num_geoms, value_begin); - - // Segment-sort the point array - auto keys_points_begin = thrust::make_zip_iterator(keys_begin, result.points_coords->begin()); - thrust::sort_by_key(rmm::exec_policy(stream), - keys_points_begin, - keys_points_begin + num_points, - scatter_map.begin(), - order_key_value_pairs, vec_2d>{}); - - // Segment-sort the segment array - auto keys_segment_begin = - thrust::make_zip_iterator(keys_begin + num_points, result.segments_coords->begin()); - - thrust::sort_by_key(rmm::exec_policy(stream), - keys_segment_begin, - keys_segment_begin + num_segments, - scatter_map.begin() + num_points, - order_key_value_pairs, segment>{}); - - // Restore the order of indices - auto lhs_linestring_id = std::make_unique>(num_geoms, stream, mr); - auto lhs_segment_id = std::make_unique>(num_geoms, stream, mr); - auto rhs_linestring_id = std::make_unique>(num_geoms, stream, mr); - auto rhs_segment_id = std::make_unique>(num_geoms, stream, mr); - - auto input_it = thrust::make_zip_iterator(result.lhs_linestring_id->begin(), - result.lhs_segment_id->begin(), - result.rhs_linestring_id->begin(), - result.rhs_segment_id->begin()); - - auto output_it = thrust::make_zip_iterator(lhs_linestring_id->begin(), - lhs_segment_id->begin(), - rhs_linestring_id->begin(), - rhs_segment_id->begin()); - - thrust::scatter( - rmm::exec_policy(stream), input_it, input_it + num_geoms, scatter_map.begin(), output_it); - - return {std::move(result.geometry_collection_offset), - std::move(result.types_buffer), - std::move(result.offset_buffer), - std::move(result.points_coords), - std::move(result.segments_coords), - std::move(lhs_linestring_id), - std::move(lhs_segment_id), - std::move(rhs_linestring_id), - std::move(rhs_segment_id)}; -} - -template , - typename segment_t = segment> -auto make_linestring_intersection_result( - std::initializer_list geometry_collection_offset, - std::initializer_list types_buffer, - std::initializer_list offset_buffer, - std::initializer_list points_coords, - std::initializer_list segments_coords, - std::initializer_list lhs_linestring_ids, - std::initializer_list lhs_segment_ids, - std::initializer_list rhs_linestring_ids, - std::initializer_list rhs_segment_ids, - rmm::cuda_stream_view stream, - rmm::mr::device_memory_resource* mr) -{ - auto d_geometry_collection_offset = - make_device_uvector(geometry_collection_offset, stream, mr); - auto d_types_buffer = make_device_uvector(types_buffer, stream, mr); - auto d_offset_buffer = make_device_uvector(offset_buffer, stream, mr); - auto d_points_coords = make_device_uvector(points_coords, stream, mr); - auto d_segments_coords = make_device_uvector(segments_coords, stream, mr); - auto d_lhs_linestring_ids = make_device_uvector(lhs_linestring_ids, stream, mr); - auto d_lhs_segment_ids = make_device_uvector(lhs_segment_ids, stream, mr); - auto d_rhs_linestring_ids = make_device_uvector(rhs_linestring_ids, stream, mr); - auto d_rhs_segment_ids = make_device_uvector(rhs_segment_ids, stream, mr); - - return linestring_intersection_result{ - std::make_unique>(d_geometry_collection_offset, stream), - std::make_unique>(d_types_buffer, stream), - std::make_unique>(d_offset_buffer, stream), - std::make_unique>(d_points_coords, stream), - std::make_unique>(d_segments_coords, stream), - std::make_unique>(d_lhs_linestring_ids, stream), - std::make_unique>(d_lhs_segment_ids, stream), - std::make_unique>(d_rhs_linestring_ids, stream), - std::make_unique>(d_rhs_segment_ids, stream)}; -} - template struct LinestringIntersectionTest : public ::testing::Test { rmm::cuda_stream_view stream() { return rmm::cuda_stream_default; } diff --git a/python/cuspatial/cuspatial/core/binops/intersection.py b/python/cuspatial/cuspatial/core/binops/intersection.py index 978921532..731e03f09 100644 --- a/python/cuspatial/cuspatial/core/binops/intersection.py +++ b/python/cuspatial/cuspatial/core/binops/intersection.py @@ -71,7 +71,7 @@ def pairwise_linestring_intersection( raise ValueError("Input GeoSeries must contain only linestrings.") geoms, look_back_ids = c_pairwise_linestring_intersection( - linestrings1._column.lines._column, linestrings2._column.lines._column + linestrings1.lines.column(), linestrings2.lines.column() ) ( From 3300768510e31dd93db58635122785408e6013d5 Mon Sep 17 00:00:00 2001 From: "H. Thomson Comer" Date: Fri, 26 May 2023 17:00:30 -0500 Subject: [PATCH 28/63] Implement and Test All Simple Feature Combinations (#1064) Tests and passes all simple feature combinations across nine binary predicates. Authors: - H. Thomson Comer (https://github.com/thomcom) - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - Michael Wang (https://github.com/isVoid) URL: https://github.com/rapidsai/cuspatial/pull/1064 --- .../core/binpreds/basic_predicates.py | 2 +- .../core/binpreds/feature_contains.py | 13 +- .../cuspatial/core/binpreds/feature_covers.py | 83 ++++-- .../core/binpreds/feature_crosses.py | 58 +++- .../core/binpreds/feature_disjoint.py | 59 ++-- .../cuspatial/core/binpreds/feature_equals.py | 13 +- .../core/binpreds/feature_intersects.py | 8 +- .../core/binpreds/feature_overlaps.py | 32 ++- .../core/binpreds/feature_touches.py | 150 ++++++++-- .../cuspatial/core/binpreds/feature_within.py | 11 +- .../test_contains_basic_predicate.py | 73 +++++ .../basicpreds/test_equals_basic_predicate.py | 48 ++++ .../test_equals_count.py | 0 .../test_intersections.py | 0 .../test_intersects_basic_predicate.py | 67 +++++ .../tests/binpreds/binpred_test_dispatch.py | 45 ++- .../tests/binpreds/test_binpred_internals.py | 265 +++++++++++++++++- .../binpreds/test_binpred_test_dispatch.py | 160 ++++++----- .../cuspatial/tests/binpreds/test_contains.py | 22 ++ .../binpreds/test_equals_only_binpreds.py | 13 +- .../binpreds/test_intersects_only_binpreds.py | 36 +-- .../cuspatial/utils/binpred_utils.py | 49 +++- 22 files changed, 970 insertions(+), 237 deletions(-) create mode 100644 python/cuspatial/cuspatial/tests/basicpreds/test_contains_basic_predicate.py create mode 100644 python/cuspatial/cuspatial/tests/basicpreds/test_equals_basic_predicate.py rename python/cuspatial/cuspatial/tests/{binops => basicpreds}/test_equals_count.py (100%) rename python/cuspatial/cuspatial/tests/{binops => basicpreds}/test_intersections.py (100%) create mode 100644 python/cuspatial/cuspatial/tests/basicpreds/test_intersects_basic_predicate.py diff --git a/python/cuspatial/cuspatial/core/binpreds/basic_predicates.py b/python/cuspatial/cuspatial/core/binpreds/basic_predicates.py index 399eed58c..85438fefa 100644 --- a/python/cuspatial/cuspatial/core/binpreds/basic_predicates.py +++ b/python/cuspatial/cuspatial/core/binpreds/basic_predicates.py @@ -12,7 +12,7 @@ ) -def _basic_equals(lhs, rhs): +def _basic_equals_any(lhs, rhs): """Utility method that returns True if any point in the lhs geometry is equal to a point in the rhs geometry.""" lhs = _multipoints_from_geometry(lhs) diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_contains.py b/python/cuspatial/cuspatial/core/binpreds/feature_contains.py index d576930bf..562ce03b7 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_contains.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_contains.py @@ -6,7 +6,7 @@ from cuspatial.core.binpreds.basic_predicates import ( _basic_contains_count, - _basic_equals, + _basic_equals_any, _basic_equals_count, _basic_intersects, _basic_intersects_pli, @@ -132,20 +132,23 @@ def _compute_predicate(self, lhs, rhs, preprocessor_result): class PointPointContains(BinPred): def _preprocess(self, lhs, rhs): - return _basic_equals(lhs, rhs) + return _basic_equals_any(lhs, rhs) class LineStringPointContains(BinPred): def _preprocess(self, lhs, rhs): intersects = _basic_intersects(lhs, rhs) - equals = _basic_equals(lhs, rhs) + equals = _basic_equals_any(lhs, rhs) return intersects & ~equals class LineStringLineStringContainsPredicate(BinPred): def _preprocess(self, lhs, rhs): - count = _basic_equals_count(lhs, rhs) - return count == rhs.sizes + pli = _basic_intersects_pli(lhs, rhs) + points = _points_and_lines_to_multipoints(pli[1], pli[0]) + # Every point in B must be in the intersection + equals = _basic_equals_count(rhs, points) == rhs.sizes + return equals """DispatchDict listing the classes to use for each combination of diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_covers.py b/python/cuspatial/cuspatial/core/binpreds/feature_covers.py index 8c32ce9e4..94e25c254 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_covers.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_covers.py @@ -1,56 +1,101 @@ # Copyright (c) 2023, NVIDIA CORPORATION. -from cuspatial.core.binpreds.binpred_interface import NotImplementedPredicate +from cuspatial.core.binpreds.basic_predicates import ( + _basic_contains_any, + _basic_contains_count, + _basic_equals_count, + _basic_intersects_pli, +) +from cuspatial.core.binpreds.binpred_interface import ( + BinPred, + ImpossiblePredicate, + NotImplementedPredicate, +) from cuspatial.core.binpreds.feature_equals import EqualsPredicateBase from cuspatial.core.binpreds.feature_intersects import ( LineStringPointIntersects, - PointLineStringIntersects, ) from cuspatial.utils.binpred_utils import ( LineString, MultiPoint, Point, Polygon, + _points_and_lines_to_multipoints, + _zero_series, ) class CoversPredicateBase(EqualsPredicateBase): """Implements the covers predicate across different combinations of geometry types. For example, a Point-Polygon covers predicate is - defined in terms of a Point-Point equals predicate. The initial release - implements covers predicates that depend only on the equals predicate, or - depend on no predicate, such as impossible cases like - `LineString.covers(Polygon)`. - - For this initial release, cover is supported for the following types: + defined in terms of a Point-Polygon equals predicate. Point.covers(Point) - Point.covers(Polygon) LineString.covers(Polygon) - Polygon.covers(Point) - Polygon.covers(MultiPoint) - Polygon.covers(LineString) - Polygon.covers(Polygon) """ pass +class LineStringLineStringCovers(BinPred): + def _preprocess(self, lhs, rhs): + # A linestring A covers another linestring B iff + # no point in B is outside of A. + pli = _basic_intersects_pli(lhs, rhs) + points = _points_and_lines_to_multipoints(pli[1], pli[0]) + # Every point in B must be in the intersection + equals = _basic_equals_count(rhs, points) == rhs.sizes + return equals + + +class PolygonPointCovers(BinPred): + def _preprocess(self, lhs, rhs): + return _basic_contains_any(lhs, rhs) + + +class PolygonLineStringCovers(BinPred): + def _preprocess(self, lhs, rhs): + # A polygon covers a linestring if all of the points in the linestring + # are in the interior or exterior of the polygon. This differs from + # a polygon that contains a linestring in that some point of the + # linestring must be in the interior of the polygon. + # Count the number of points from rhs in the interior of lhs + contains_count = _basic_contains_count(lhs, rhs) + # Now count the number of points from rhs in the boundary of lhs + pli = _basic_intersects_pli(lhs, rhs) + intersections = pli[1] + # There may be no intersection, so start with _zero_series + equality = _zero_series(len(rhs)) + if len(intersections) > 0: + matching_length_multipoints = _points_and_lines_to_multipoints( + intersections, pli[0] + ) + equality = _basic_equals_count(matching_length_multipoints, rhs) + covers = contains_count + equality >= rhs.sizes + return covers + + +class PolygonPolygonCovers(BinPred): + def _preprocess(self, lhs, rhs): + contains = lhs.contains(rhs) + return contains + + DispatchDict = { (Point, Point): CoversPredicateBase, (Point, MultiPoint): NotImplementedPredicate, - (Point, LineString): PointLineStringIntersects, - (Point, Polygon): CoversPredicateBase, + (Point, LineString): ImpossiblePredicate, + (Point, Polygon): ImpossiblePredicate, (MultiPoint, Point): NotImplementedPredicate, (MultiPoint, MultiPoint): NotImplementedPredicate, (MultiPoint, LineString): NotImplementedPredicate, (MultiPoint, Polygon): NotImplementedPredicate, (LineString, Point): LineStringPointIntersects, (LineString, MultiPoint): NotImplementedPredicate, - (LineString, LineString): NotImplementedPredicate, + (LineString, LineString): LineStringLineStringCovers, (LineString, Polygon): CoversPredicateBase, - (Polygon, Point): CoversPredicateBase, + (Polygon, Point): PolygonPointCovers, (Polygon, MultiPoint): CoversPredicateBase, - (Polygon, LineString): CoversPredicateBase, - (Polygon, Polygon): CoversPredicateBase, + (Polygon, LineString): PolygonLineStringCovers, + (Polygon, Polygon): PolygonPolygonCovers, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py b/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py index e1ea40a92..0316f3cbd 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py @@ -1,16 +1,23 @@ # Copyright (c) 2023, NVIDIA CORPORATION. +from cuspatial.core.binpreds.basic_predicates import ( + _basic_equals_count, + _basic_intersects_count, + _basic_intersects_pli, +) from cuspatial.core.binpreds.binpred_interface import ( + BinPred, ImpossiblePredicate, - NotImplementedPredicate, ) from cuspatial.core.binpreds.feature_equals import EqualsPredicateBase +from cuspatial.core.binpreds.feature_intersects import IntersectsPredicateBase from cuspatial.utils.binpred_utils import ( LineString, MultiPoint, Point, Polygon, _false_series, + _points_and_lines_to_multipoints, ) @@ -30,6 +37,33 @@ class CrossesPredicateBase(EqualsPredicateBase): pass +class LineStringLineStringCrosses(IntersectsPredicateBase): + def _compute_predicate(self, lhs, rhs, preprocessor_result): + # A linestring crosses another linestring iff + # they intersect, and none of the points of the + # intersection are in the boundary of the other + pli = _basic_intersects_pli(rhs, lhs) + intersections = _points_and_lines_to_multipoints(pli[1], pli[0]) + equals = (_basic_equals_count(intersections, lhs) > 0) | ( + _basic_equals_count(intersections, rhs) > 0 + ) + intersects = _basic_intersects_count(rhs, lhs) > 0 + return intersects & ~equals + + +class LineStringPolygonCrosses(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects_count(rhs, lhs) > 1 + touches = rhs.touches(lhs) + contains = rhs.contains(lhs) + return ~touches & intersects & ~contains + + +class PolygonLineStringCrosses(LineStringPolygonCrosses): + def _preprocess(self, lhs, rhs): + return super()._preprocess(rhs, lhs) + + class PointPointCrosses(CrossesPredicateBase): def _preprocess(self, lhs, rhs): """Points can't cross other points, so we return False.""" @@ -38,19 +72,19 @@ def _preprocess(self, lhs, rhs): DispatchDict = { (Point, Point): PointPointCrosses, - (Point, MultiPoint): NotImplementedPredicate, - (Point, LineString): NotImplementedPredicate, + (Point, MultiPoint): ImpossiblePredicate, + (Point, LineString): ImpossiblePredicate, (Point, Polygon): CrossesPredicateBase, - (MultiPoint, Point): NotImplementedPredicate, - (MultiPoint, MultiPoint): NotImplementedPredicate, - (MultiPoint, LineString): NotImplementedPredicate, - (MultiPoint, Polygon): NotImplementedPredicate, + (MultiPoint, Point): ImpossiblePredicate, + (MultiPoint, MultiPoint): ImpossiblePredicate, + (MultiPoint, LineString): ImpossiblePredicate, + (MultiPoint, Polygon): ImpossiblePredicate, (LineString, Point): ImpossiblePredicate, - (LineString, MultiPoint): NotImplementedPredicate, - (LineString, LineString): NotImplementedPredicate, - (LineString, Polygon): NotImplementedPredicate, + (LineString, MultiPoint): ImpossiblePredicate, + (LineString, LineString): LineStringLineStringCrosses, + (LineString, Polygon): LineStringPolygonCrosses, (Polygon, Point): CrossesPredicateBase, (Polygon, MultiPoint): CrossesPredicateBase, - (Polygon, LineString): CrossesPredicateBase, - (Polygon, Polygon): CrossesPredicateBase, + (Polygon, LineString): PolygonLineStringCrosses, + (Polygon, Polygon): ImpossiblePredicate, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py b/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py index 92541b95f..a0347b76a 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py @@ -1,13 +1,14 @@ # Copyright (c) 2023, NVIDIA CORPORATION. +from cuspatial.core.binpreds.basic_predicates import ( + _basic_contains_any, + _basic_intersects, +) from cuspatial.core.binpreds.binpred_interface import ( BinPred, NotImplementedPredicate, ) -from cuspatial.core.binpreds.feature_intersects import ( - IntersectsPredicateBase, - PointLineStringIntersects, -) +from cuspatial.core.binpreds.feature_intersects import IntersectsPredicateBase from cuspatial.utils.binpred_utils import ( LineString, MultiPoint, @@ -16,7 +17,7 @@ ) -class ContainsDisjoint(BinPred): +class DisjointByWayOfContains(BinPred): def _preprocess(self, lhs, rhs): """Disjoint is the opposite of contains, so just implement contains and then negate the result. @@ -26,20 +27,22 @@ def _preprocess(self, lhs, rhs): (Point, Polygon) (Polygon, Point) """ - from cuspatial.core.binpreds.binpred_dispatch import CONTAINS_DISPATCH + return ~_basic_contains_any(lhs, rhs) - predicate = CONTAINS_DISPATCH[(lhs.column_type, rhs.column_type)]( - align=self.config.align - ) - return ~predicate(lhs, rhs) - -class PointLineStringDisjoint(PointLineStringIntersects): - def _postprocess(self, lhs, rhs, op_result): +class PointLineStringDisjoint(BinPred): + def _preprocess(self, lhs, rhs): """Disjoint is the opposite of intersects, so just implement intersects and then negate the result.""" - result = super()._postprocess(lhs, rhs, op_result) - return ~result + intersects = _basic_intersects(lhs, rhs) + return ~intersects + + +class PointPolygonDisjoint(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(lhs, rhs) + contains = _basic_contains_any(lhs, rhs) + return ~intersects & ~contains class LineStringPointDisjoint(PointLineStringDisjoint): @@ -56,21 +59,33 @@ def _postprocess(self, lhs, rhs, op_result): return ~result +class LineStringPolygonDisjoint(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(lhs, rhs) + contains = _basic_contains_any(rhs, lhs) + return ~intersects & ~contains + + +class PolygonPolygonDisjoint(BinPred): + def _preprocess(self, lhs, rhs): + return ~_basic_contains_any(lhs, rhs) & ~_basic_contains_any(rhs, lhs) + + DispatchDict = { - (Point, Point): ContainsDisjoint, + (Point, Point): DisjointByWayOfContains, (Point, MultiPoint): NotImplementedPredicate, (Point, LineString): PointLineStringDisjoint, - (Point, Polygon): ContainsDisjoint, + (Point, Polygon): PointPolygonDisjoint, (MultiPoint, Point): NotImplementedPredicate, (MultiPoint, MultiPoint): NotImplementedPredicate, (MultiPoint, LineString): NotImplementedPredicate, - (MultiPoint, Polygon): NotImplementedPredicate, + (MultiPoint, Polygon): LineStringPolygonDisjoint, (LineString, Point): LineStringPointDisjoint, (LineString, MultiPoint): NotImplementedPredicate, (LineString, LineString): LineStringLineStringDisjoint, - (LineString, Polygon): NotImplementedPredicate, - (Polygon, Point): ContainsDisjoint, + (LineString, Polygon): LineStringPolygonDisjoint, + (Polygon, Point): DisjointByWayOfContains, (Polygon, MultiPoint): NotImplementedPredicate, - (Polygon, LineString): NotImplementedPredicate, - (Polygon, Polygon): NotImplementedPredicate, + (Polygon, LineString): DisjointByWayOfContains, + (Polygon, Polygon): PolygonPolygonDisjoint, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_equals.py b/python/cuspatial/cuspatial/core/binpreds/feature_equals.py index dc52423d7..bf6997e0a 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_equals.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_equals.py @@ -13,6 +13,7 @@ from cuspatial.core.binpreds.binpred_interface import ( BinPred, EqualsOpResult, + ImpossiblePredicate, NotImplementedPredicate, PreprocessorResult, ) @@ -334,11 +335,19 @@ def _preprocess(self, lhs, rhs): return _false_series(len(lhs)) +class PolygonPolygonEquals(BinPred): + def _preprocess(self, lhs, rhs): + """Two polygons are equal if they contain each other.""" + lhs_contains_rhs = lhs.contains(rhs) + rhs_contains_lhs = rhs.contains(lhs) + return lhs_contains_rhs & rhs_contains_lhs + + """DispatchDict for Equals operations.""" DispatchDict = { (Point, Point): EqualsPredicateBase, (Point, MultiPoint): NotImplementedPredicate, - (Point, LineString): NotImplementedPredicate, + (Point, LineString): ImpossiblePredicate, (Point, Polygon): EqualsPredicateBase, (MultiPoint, Point): NotImplementedPredicate, (MultiPoint, MultiPoint): MultiPointMultiPointEquals, @@ -351,5 +360,5 @@ def _preprocess(self, lhs, rhs): (Polygon, Point): EqualsPredicateBase, (Polygon, MultiPoint): EqualsPredicateBase, (Polygon, LineString): EqualsPredicateBase, - (Polygon, Polygon): EqualsPredicateBase, + (Polygon, Polygon): PolygonPolygonEquals, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py b/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py index d8ecfdb38..c35947826 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py @@ -23,7 +23,6 @@ Point, Polygon, _false_series, - _linestrings_from_geometry, ) @@ -107,12 +106,7 @@ def _preprocess(self, lhs, rhs): class LineStringPointIntersects(IntersectsPredicateBase): def _preprocess(self, lhs, rhs): - """Convert rhs to linestrings by making a linestring that has - the same start and end point.""" - ls_rhs = _linestrings_from_geometry(rhs) - return self._compute_predicate( - lhs, ls_rhs, PreprocessorResult(lhs, ls_rhs) - ) + return _basic_intersects(lhs, rhs) class PointLineStringIntersects(LineStringPointIntersects): diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py b/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py index b0eab48a9..d515d92fe 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_overlaps.py @@ -2,9 +2,12 @@ import cudf +from cuspatial.core.binpreds.basic_predicates import ( + _basic_contains_properly_any, +) from cuspatial.core.binpreds.binpred_interface import ( + BinPred, ImpossiblePredicate, - NotImplementedPredicate, ) from cuspatial.core.binpreds.feature_contains import ContainsPredicate from cuspatial.core.binpreds.feature_equals import EqualsPredicateBase @@ -36,6 +39,17 @@ class OverlapsPredicateBase(EqualsPredicateBase): pass +class PolygonPolygonOverlaps(BinPred): + def _preprocess(self, lhs, rhs): + contains_lhs = lhs.contains(rhs) + contains_rhs = rhs.contains(lhs) + contains_properly_lhs = _basic_contains_properly_any(lhs, rhs) + contains_properly_rhs = _basic_contains_properly_any(rhs, lhs) + return ~(contains_lhs | contains_rhs) & ( + contains_properly_lhs | contains_properly_rhs + ) + + class PolygonPointOverlaps(ContainsPredicate): def _postprocess(self, lhs, rhs, op_result): if not has_same_geometry(lhs, rhs) or len(op_result.point_result) == 0: @@ -62,19 +76,19 @@ def _postprocess(self, lhs, rhs, op_result): """Dispatch table for overlaps binary predicate.""" DispatchDict = { (Point, Point): ImpossiblePredicate, - (Point, MultiPoint): NotImplementedPredicate, - (Point, LineString): NotImplementedPredicate, + (Point, MultiPoint): ImpossiblePredicate, + (Point, LineString): ImpossiblePredicate, (Point, Polygon): OverlapsPredicateBase, - (MultiPoint, Point): NotImplementedPredicate, - (MultiPoint, MultiPoint): NotImplementedPredicate, - (MultiPoint, LineString): NotImplementedPredicate, - (MultiPoint, Polygon): NotImplementedPredicate, + (MultiPoint, Point): ImpossiblePredicate, + (MultiPoint, MultiPoint): ImpossiblePredicate, + (MultiPoint, LineString): ImpossiblePredicate, + (MultiPoint, Polygon): ImpossiblePredicate, (LineString, Point): ImpossiblePredicate, - (LineString, MultiPoint): NotImplementedPredicate, + (LineString, MultiPoint): ImpossiblePredicate, (LineString, LineString): ImpossiblePredicate, (LineString, Polygon): ImpossiblePredicate, (Polygon, Point): OverlapsPredicateBase, (Polygon, MultiPoint): OverlapsPredicateBase, (Polygon, LineString): OverlapsPredicateBase, - (Polygon, Polygon): OverlapsPredicateBase, + (Polygon, Polygon): PolygonPolygonOverlaps, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_touches.py b/python/cuspatial/cuspatial/core/binpreds/feature_touches.py index c6935b782..c1ddc1312 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_touches.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_touches.py @@ -1,8 +1,22 @@ # Copyright (c) 2023, NVIDIA CORPORATION. +import cupy as cp + +import cudf + +from cuspatial.core.binpreds.basic_predicates import ( + _basic_contains_count, + _basic_contains_properly_any, + _basic_equals_all, + _basic_equals_any, + _basic_equals_count, + _basic_intersects, + _basic_intersects_count, + _basic_intersects_pli, +) from cuspatial.core.binpreds.binpred_interface import ( + BinPred, ImpossiblePredicate, - NotImplementedPredicate, ) from cuspatial.core.binpreds.feature_contains import ContainsPredicate from cuspatial.utils.binpred_utils import ( @@ -10,41 +24,129 @@ MultiPoint, Point, Polygon, + _false_series, + _points_and_lines_to_multipoints, ) class TouchesPredicateBase(ContainsPredicate): - """Base class for binary predicates that use the contains predicate - to implement the touches predicate. For example, a Point-Polygon - Touches predicate is defined in terms of a Point-Polygon Contains - predicate. + """ + If any point is shared between the following geometry types, they touch: Used by: - (Point, Polygon) - (Polygon, Point) + (Point, MultiPoint) + (Point, LineString) + (MultiPoint, Point) + (MultiPoint, MultiPoint) + (MultiPoint, LineString) + (MultiPoint, Polygon) + (LineString, Point) + (LineString, MultiPoint) (Polygon, MultiPoint) - (Polygon, LineString) - (Polygon, Polygon) """ - pass + def _preprocess(self, lhs, rhs): + return _basic_equals_any(lhs, rhs) + + +class PointPolygonTouches(ContainsPredicate): + def _preprocess(self, lhs, rhs): + # Reverse argument order. + equals_all = _basic_equals_all(rhs, lhs) + touches = _basic_intersects(rhs, lhs) + return ~equals_all & touches + + +class LineStringLineStringTouches(BinPred): + def _preprocess(self, lhs, rhs): + """A and B have at least one point in common, and the common points + lie in at least one boundary""" + + # First compute pli which will contain points for line crossings and + # linestrings for overlapping segments. + pli = _basic_intersects_pli(lhs, rhs) + offsets = cudf.Series(pli[0]) + pli_geometry_count = offsets[1:].reset_index(drop=True) - offsets[ + :-1 + ].reset_index(drop=True) + indices = ( + cudf.Series(cp.arange(len(pli_geometry_count))) + .repeat(pli_geometry_count) + .reset_index(drop=True) + ) + + # In order to be a touch, all of the intersecting geometries + # for a particular row must be points. + pli_types = pli[1]._column._meta.input_types + point_intersection = _false_series(len(lhs)) + only_points_in_intersection = ( + pli_types.groupby(indices).sum().sort_index() == 0 + ) + point_intersection.iloc[ + only_points_in_intersection.index + ] = only_points_in_intersection + + # Finally, we need to check if the points in the intersection + # are equal to endpoints of either linestring. + points = _points_and_lines_to_multipoints(pli[1], pli[0]) + equals_lhs = _basic_equals_count(points, lhs) > 0 + equals_rhs = _basic_equals_count(points, rhs) > 0 + touches = point_intersection & (equals_lhs | equals_rhs) + return touches + + +class LineStringPolygonTouches(BinPred): + def _preprocess(self, lhs, rhs): + pli = _basic_intersects_pli(lhs, rhs) + if len(pli[1]) == 0: + return _false_series(len(lhs)) + intersections = _points_and_lines_to_multipoints(pli[1], pli[0]) + # A touch can only occur if the point in the intersection + # is equal to a point in the linestring: it must + # terminate in the boundary of the polygon. + equals = _basic_equals_count(intersections, lhs) > 0 + intersects = _basic_intersects_count(lhs, rhs) + intersects = (intersects == 1) | (intersects == 2) + contains = rhs.contains(lhs) + contains_any = _basic_contains_properly_any(rhs, lhs) + return equals & intersects & ~contains & ~contains_any + + +class PolygonPointTouches(BinPred): + def _preprocess(self, lhs, rhs): + intersects = _basic_intersects(lhs, rhs) + return intersects + + +class PolygonLineStringTouches(LineStringPolygonTouches): + def _preprocess(self, lhs, rhs): + return super()._preprocess(rhs, lhs) + + +class PolygonPolygonTouches(BinPred): + def _preprocess(self, lhs, rhs): + contains_lhs_none = _basic_contains_count(lhs, rhs) == 0 + contains_rhs_none = _basic_contains_count(rhs, lhs) == 0 + equals = lhs.geom_equals(rhs) + intersects = _basic_intersects_count(lhs, rhs) > 0 + return ~equals & contains_lhs_none & contains_rhs_none & intersects DispatchDict = { (Point, Point): ImpossiblePredicate, - (Point, MultiPoint): NotImplementedPredicate, - (Point, LineString): NotImplementedPredicate, - (Point, Polygon): TouchesPredicateBase, - (MultiPoint, Point): NotImplementedPredicate, - (MultiPoint, MultiPoint): NotImplementedPredicate, - (MultiPoint, LineString): NotImplementedPredicate, - (MultiPoint, Polygon): NotImplementedPredicate, - (LineString, Point): NotImplementedPredicate, - (LineString, MultiPoint): NotImplementedPredicate, - (LineString, LineString): NotImplementedPredicate, - (LineString, Polygon): NotImplementedPredicate, - (Polygon, Point): TouchesPredicateBase, + (Point, MultiPoint): TouchesPredicateBase, + (Point, LineString): TouchesPredicateBase, + (Point, Polygon): PointPolygonTouches, + (MultiPoint, Point): TouchesPredicateBase, + (MultiPoint, MultiPoint): TouchesPredicateBase, + (MultiPoint, LineString): TouchesPredicateBase, + (MultiPoint, Polygon): TouchesPredicateBase, + (LineString, Point): TouchesPredicateBase, + (LineString, MultiPoint): TouchesPredicateBase, + (LineString, LineString): LineStringLineStringTouches, + (LineString, Polygon): LineStringPolygonTouches, + (Polygon, Point): PolygonPointTouches, (Polygon, MultiPoint): TouchesPredicateBase, - (Polygon, LineString): TouchesPredicateBase, - (Polygon, Polygon): TouchesPredicateBase, + (Polygon, LineString): PolygonLineStringTouches, + (Polygon, Polygon): PolygonPolygonTouches, } diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_within.py b/python/cuspatial/cuspatial/core/binpreds/feature_within.py index 043f4629e..3b6ea133d 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_within.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_within.py @@ -1,8 +1,8 @@ # Copyright (c) 2023, NVIDIA CORPORATION. from cuspatial.core.binpreds.basic_predicates import ( - _basic_equals, _basic_equals_all, + _basic_equals_any, _basic_intersects, ) from cuspatial.core.binpreds.binpred_interface import ( @@ -26,14 +26,14 @@ def _preprocess(self, lhs, rhs): class WithinIntersectsPredicate(BinPred): def _preprocess(self, lhs, rhs): intersects = _basic_intersects(rhs, lhs) - equals = _basic_equals(rhs, lhs) + equals = _basic_equals_any(rhs, lhs) return intersects & ~equals class PointLineStringWithin(BinPred): def _preprocess(self, lhs, rhs): intersects = lhs.intersects(rhs) - equals = _basic_equals(lhs, rhs) + equals = _basic_equals_any(lhs, rhs) return intersects & ~equals @@ -44,9 +44,8 @@ def _preprocess(self, lhs, rhs): class LineStringLineStringWithin(BinPred): def _preprocess(self, lhs, rhs): - intersects = _basic_intersects(rhs, lhs) - equals = _basic_equals_all(rhs, lhs) - return intersects & equals + contains = rhs.contains(lhs) + return contains class LineStringPolygonWithin(BinPred): diff --git a/python/cuspatial/cuspatial/tests/basicpreds/test_contains_basic_predicate.py b/python/cuspatial/cuspatial/tests/basicpreds/test_contains_basic_predicate.py new file mode 100644 index 000000000..c299770cc --- /dev/null +++ b/python/cuspatial/cuspatial/tests/basicpreds/test_contains_basic_predicate.py @@ -0,0 +1,73 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +from shapely.geometry import LineString, Point, Polygon + +import cuspatial +from cuspatial.core.binpreds.basic_predicates import ( + _basic_contains_any, + _basic_contains_count, +) + + +def test_basic_contains_any_outside(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Point(2, 2)]) + got = _basic_contains_any(lhs, rhs).to_pandas() + expected = [False] + assert (got == expected).all() + + +def test_basic_contains_any_inside(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([LineString([(0.5, 0.5), (1.5, 1.5)])]) + got = _basic_contains_any(lhs, rhs).to_pandas() + expected = [True] + assert (got == expected).all() + + +def test_basic_contains_any_point(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Point(0, 0)]) + got = _basic_contains_any(lhs, rhs).to_pandas() + expected = [True] + assert (got == expected).all() + + +def test_basic_contains_any_edge(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Point(0, 0.5)]) + got = _basic_contains_any(lhs, rhs).to_pandas() + expected = [True] + assert (got == expected).all() + + +def test_basic_contains_count_outside(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Point(2, 2)]) + got = _basic_contains_count(lhs, rhs).to_pandas() + expected = [0] + assert (got == expected).all() + + +def test_basic_contains_count_inside(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([LineString([(0.5, 0.5), (1.5, 1.5)])]) + got = _basic_contains_count(lhs, rhs).to_pandas() + expected = [1] + assert (got == expected).all() + + +def test_basic_contains_count_point(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Point(0, 0)]) + got = _basic_contains_count(lhs, rhs).to_pandas() + expected = [0] + assert (got == expected).all() + + +def test_basic_contains_count_edge(): + lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) + rhs = cuspatial.GeoSeries([Point(0, 0.5)]) + got = _basic_contains_count(lhs, rhs).to_pandas() + expected = [0] + assert (got == expected).all() diff --git a/python/cuspatial/cuspatial/tests/basicpreds/test_equals_basic_predicate.py b/python/cuspatial/cuspatial/tests/basicpreds/test_equals_basic_predicate.py new file mode 100644 index 000000000..a164c5d0f --- /dev/null +++ b/python/cuspatial/cuspatial/tests/basicpreds/test_equals_basic_predicate.py @@ -0,0 +1,48 @@ +import pandas as pd +from pandas.testing import assert_series_equal +from shapely.geometry import Point + +import cuspatial +from cuspatial.core.binpreds.basic_predicates import _basic_equals_any + + +def test_single_true(): + p1 = cuspatial.GeoSeries([Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(0, 0)]) + result = _basic_equals_any(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([True])) + + +def test_single_false(): + p1 = cuspatial.GeoSeries([Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(1, 1)]) + result = _basic_equals_any(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([False])) + + +def test_true_false(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(1, 1)]) + p2 = cuspatial.GeoSeries([Point(0, 0), Point(2, 2)]) + result = _basic_equals_any(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([True, False])) + + +def test_false_true(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(1, 1), Point(0, 0)]) + result = _basic_equals_any(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([False, True])) + + +def test_true_false_true(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(1, 1), Point(2, 2)]) + p2 = cuspatial.GeoSeries([Point(0, 0), Point(2, 2), Point(2, 2)]) + result = _basic_equals_any(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([True, False, True])) + + +def test_false_true_false(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(0, 0), Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(1, 1), Point(0, 0), Point(2, 2)]) + result = _basic_equals_any(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([False, True, False])) diff --git a/python/cuspatial/cuspatial/tests/binops/test_equals_count.py b/python/cuspatial/cuspatial/tests/basicpreds/test_equals_count.py similarity index 100% rename from python/cuspatial/cuspatial/tests/binops/test_equals_count.py rename to python/cuspatial/cuspatial/tests/basicpreds/test_equals_count.py diff --git a/python/cuspatial/cuspatial/tests/binops/test_intersections.py b/python/cuspatial/cuspatial/tests/basicpreds/test_intersections.py similarity index 100% rename from python/cuspatial/cuspatial/tests/binops/test_intersections.py rename to python/cuspatial/cuspatial/tests/basicpreds/test_intersections.py diff --git a/python/cuspatial/cuspatial/tests/basicpreds/test_intersects_basic_predicate.py b/python/cuspatial/cuspatial/tests/basicpreds/test_intersects_basic_predicate.py new file mode 100644 index 000000000..00193c5d1 --- /dev/null +++ b/python/cuspatial/cuspatial/tests/basicpreds/test_intersects_basic_predicate.py @@ -0,0 +1,67 @@ +import pandas as pd +from pandas.testing import assert_series_equal +from shapely.geometry import LineString, Point, Polygon + +import cuspatial +from cuspatial.core.binpreds.basic_predicates import _basic_intersects + + +def test_single_true(): + p1 = cuspatial.GeoSeries([Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(0, 0)]) + result = _basic_intersects(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([True])) + + +def test_single_false(): + p1 = cuspatial.GeoSeries([Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(1, 1)]) + result = _basic_intersects(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([False])) + + +def test_true_false(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(1, 1)]) + p2 = cuspatial.GeoSeries([Point(0, 0), Point(2, 2)]) + result = _basic_intersects(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([True, False])) + + +def test_false_true(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(1, 1), Point(0, 0)]) + result = _basic_intersects(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([False, True])) + + +def test_true_false_true(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(1, 1), Point(2, 2)]) + p2 = cuspatial.GeoSeries([Point(0, 0), Point(2, 2), Point(2, 2)]) + result = _basic_intersects(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([True, False, True])) + + +def test_false_true_false(): + p1 = cuspatial.GeoSeries([Point(0, 0), Point(0, 0), Point(0, 0)]) + p2 = cuspatial.GeoSeries([Point(1, 1), Point(0, 0), Point(2, 2)]) + result = _basic_intersects(p1, p2) + assert_series_equal(result.to_pandas(), pd.Series([False, True, False])) + + +def test_linestring_polygon_within(): + lhs = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 1)]), + LineString([(0, 0), (1, 1)]), + LineString([(0, 0), (1, 1)]), + ] + ) + rhs = cuspatial.GeoSeries( + [ + Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]), + Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]), + Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]), + ] + ) + result = _basic_intersects(lhs, rhs) + assert_series_equal(result.to_pandas(), pd.Series([True, True, True])) diff --git a/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py b/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py index 03f6e3ab0..55ceeaea3 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py +++ b/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py @@ -105,6 +105,17 @@ def predicate(request): LineString([(0.0, 0.0), (1.0, 0.0)]), LineString([(0.0, 0.0), (1.0, 0.0)]), ), + "linestring-linestring-covers": ( + """ + x + x + / + x + x + """, + LineString([(0.0, 0.0), (1.0, 1.0)]), + LineString([(0.25, 0.25), (0.5, 0.5)]), + ), "linestring-linestring-touches": ( """ x @@ -138,6 +149,17 @@ def predicate(request): LineString([(0.0, 0.0), (1.0, 0.0)]), LineString([(0.5, 0.0), (0.5, 1.0)]), ), + "linestring-linestring-touch-edge-twice": ( + """ + x + x + / \\ + x---x + x + """, + LineString([(0.0, 0.0), (1.0, 1.0), (2.0, 2.0)]), + LineString([(0.25, 0.25), (1.0, 0.0), (0.5, 0.5)]), + ), "linestring-linestring-crosses": ( """ x @@ -358,15 +380,27 @@ def predicate(request): Polygon([(0.0, 1.0), (0.0, 2.0), (1.0, 2.0)]), point_polygon, ), + "polygon-polygon-overlap-inside-edge": ( + """ + x + /| + x---x | + \\ / | + x | + / | + x-----x + """, + Polygon([(0, 0), (1, 0), (1, 1), (0, 0)]), + Polygon([(0.25, 0.25), (0.5, 0.5), (0, 0.5), (0.25, 0.25)]), + ), "polygon-polygon-point-inside": ( """ x---x | / - | / - --|/- + --|-/ + | |/| | x | | | - | | ----- """, Polygon([(0.5, 0.5), (0.5, 1.5), (1.5, 1.5)]), @@ -453,7 +487,11 @@ def predicate(request): linestring_linestring_dispatch_list = [ "linestring-linestring-disjoint", "linestring-linestring-same", + "linestring-linestring-covers", "linestring-linestring-touches", + "linestring-linestring-touch-interior", + "linestring-linestring-touch-edge", + "linestring-linestring-touch-edge-twice", "linestring-linestring-crosses", ] @@ -475,6 +513,7 @@ def predicate(request): "polygon-polygon-touch-point", "polygon-polygon-touch-edge", "polygon-polygon-overlap-edge", + "polygon-polygon-overlap-inside-edge", "polygon-polygon-point-inside", "polygon-polygon-point-outside", "polygon-polygon-in-out-point", diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_binpred_internals.py b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_internals.py index 7d18530ac..9b87f821f 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_binpred_internals.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_internals.py @@ -1,10 +1,15 @@ # Copyright (c) 2020-2023, NVIDIA CORPORATION import pandas as pd -from shapely.geometry import LineString +from shapely.geometry import LineString, MultiPoint, Point, Polygon import cuspatial from cuspatial.core.binpreds.binpred_dispatch import EQUALS_DISPATCH +from cuspatial.utils.binpred_utils import ( + _linestrings_to_center_point, + _open_polygon_rings, + _points_and_lines_to_multipoints, +) def test_internal_reversed_linestrings(): @@ -74,3 +79,261 @@ def test_internal_reversed_linestrings_triple(): ).to_pandas() expected = linestring2.lines.xy.to_pandas() pd.testing.assert_series_equal(got, expected) + + +def test_open_polygon_rings(): + polygon = cuspatial.GeoSeries( + [ + Polygon([(0, 0), (1, 1), (1, 0), (0, 0)]), + ] + ) + linestring = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 1), (1, 0)]), + ] + ) + got = _open_polygon_rings(polygon) + assert (got.lines.xy == linestring.lines.xy).all() + + +def test_open_polygon_rings_two(): + polygon = cuspatial.GeoSeries( + [ + Polygon([(0, 0), (1, 1), (1, 0), (0, 0)]), + Polygon([(0, 0), (1, 1), (1, 0), (0, 0)]), + ] + ) + linestring = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 1), (1, 0)]), + LineString([(0, 0), (1, 1), (1, 0)]), + ] + ) + got = _open_polygon_rings(polygon) + assert (got.lines.xy == linestring.lines.xy).all() + + +def test_open_polygon_rings_three_varying_length(): + polygon = cuspatial.GeoSeries( + [ + Polygon([(0, 0), (1, 1), (0, 1), (0, 0)]), + Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]), + Polygon([(0, 0), (1, 1), (1, 0), (0, 0)]), + ] + ) + linestring = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 1), (0, 1)]), + LineString([(0, 0), (0, 1), (1, 1), (1, 0)]), + LineString([(0, 0), (1, 1), (1, 0)]), + ] + ) + got = _open_polygon_rings(polygon) + assert (got.lines.xy == linestring.lines.xy).all() + + +def test_points_and_lines_to_multipoints(): + mixed = cuspatial.GeoSeries( + [ + Point(0, 0), + LineString([(1, 1), (2, 2)]), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(0, 0)]), + MultiPoint([(1, 1), (2, 2)]), + ] + ) + offsets = [0, 1, 2] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_points_and_lines_to_multipoints_reverse(): + mixed = cuspatial.GeoSeries( + [ + LineString([(1, 1), (2, 2)]), + Point(0, 0), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(1, 1), (2, 2)]), + MultiPoint([(0, 0)]), + ] + ) + offsets = [0, 1, 2] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_points_and_lines_to_multipoints_two_points_one_linestring(): + mixed = cuspatial.GeoSeries( + [ + Point(0, 0), + LineString([(1, 1), (2, 2)]), + Point(3, 3), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(0, 0)]), + MultiPoint([(1, 1), (2, 2)]), + MultiPoint([(3, 3)]), + ] + ) + offsets = [0, 1, 2, 3] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_points_and_lines_to_multipoints_two_linestrings_one_point(): + mixed = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 1)]), + Point(2, 2), + LineString([(3, 3), (4, 4)]), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(0, 0), (1, 1)]), + MultiPoint([(2, 2)]), + MultiPoint([(3, 3), (4, 4)]), + ] + ) + offsets = [0, 1, 2, 3] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_points_and_lines_to_multipoints_complex(): + mixed = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 1), (2, 2), (3, 3)]), + Point(4, 4), + LineString([(5, 5), (6, 6)]), + Point(7, 7), + Point(8, 8), + LineString([(9, 9), (10, 10), (11, 11)]), + LineString([(12, 12), (13, 13)]), + Point(14, 14), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(0, 0), (1, 1), (2, 2), (3, 3)]), + MultiPoint([(4, 4)]), + MultiPoint([(5, 5), (6, 6)]), + MultiPoint([(7, 7)]), + MultiPoint([(8, 8)]), + MultiPoint([(9, 9), (10, 10), (11, 11)]), + MultiPoint([(12, 12), (13, 13)]), + MultiPoint([(14, 14)]), + ] + ) + offsets = [0, 1, 2, 3, 4, 5, 6, 7, 8] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_points_and_lines_to_multipoints_no_points(): + mixed = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 1), (2, 2), (3, 3)]), + LineString([(5, 5), (6, 6)]), + LineString([(9, 9), (10, 10), (11, 11)]), + LineString([(12, 12), (13, 13)]), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(0, 0), (1, 1), (2, 2), (3, 3)]), + MultiPoint([(5, 5), (6, 6)]), + MultiPoint([(9, 9), (10, 10), (11, 11)]), + MultiPoint([(12, 12), (13, 13)]), + ] + ) + offsets = [0, 1, 2, 3, 4] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_points_and_lines_to_multipoints_no_linestrings(): + mixed = cuspatial.GeoSeries( + [ + Point(0, 0), + Point(4, 4), + Point(7, 7), + Point(8, 8), + Point(14, 14), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(0, 0)]), + MultiPoint([(4, 4)]), + MultiPoint([(7, 7)]), + MultiPoint([(8, 8)]), + MultiPoint([(14, 14)]), + ] + ) + offsets = [0, 1, 2, 3, 4, 5] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_points_and_lines_to_multipoints_real_example(): + mixed = cuspatial.GeoSeries( + [ + Point(7, 7), + Point(4, 4), + LineString([(5, 5), (6, 6)]), + LineString([(9, 9), (10, 10), (11, 11)]), + LineString([(12, 12), (13, 13)]), + Point(8, 8), + Point(14, 14), + ] + ) + expected = cuspatial.GeoSeries( + [ + MultiPoint([(7, 7), (4, 4)]), + MultiPoint( + [ + (5, 5), + (6, 6), + (9, 9), + (10, 10), + (11, 11), + (12, 12), + (13, 13), + ] + ), + MultiPoint([(8, 8), (14, 14)]), + ] + ) + offsets = [0, 2, 5, 7] + got = _points_and_lines_to_multipoints(mixed, offsets) + assert (got.multipoints.xy == expected.multipoints.xy).all() + + +def test_linestrings_to_center_point(): + linestrings = cuspatial.GeoSeries( + [ + LineString([(0, 0), (10, 10)]), + LineString([(5, 5), (6, 6)]), + LineString([(10, 10), (9, 9)]), + LineString([(11, 11), (1, 1)]), + ] + ) + expected = cuspatial.GeoSeries( + [ + Point(5, 5), + Point(5.5, 5.5), + Point(9.5, 9.5), + Point(6, 6), + ] + ) + got = _linestrings_to_center_point(linestrings) + assert (got.points.xy == expected.points.xy).all() diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_binpred_test_dispatch.py b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_test_dispatch.py index 914e2e88e..11e5ad8f1 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_binpred_test_dispatch.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_test_dispatch.py @@ -1,31 +1,35 @@ # Copyright (c) 2023, NVIDIA CORPORATION. -from functools import wraps +import os import pandas as pd -import pytest from binpred_test_dispatch import predicate, simple_test # noqa: F401 -"""Decorator function that xfails a test if an exception is throw -by the test function. Will be removed when all tests are passing.""" - +# In the below file, all failing tests are recorded with visualizations. +LOG_DISPATCHED_PREDICATES = os.environ.get("LOG_DISPATCHED_PREDICATES", False) +if LOG_DISPATCHED_PREDICATES: + out_file = open("test_binpred_test_dispatch.log", "w") -def xfail_on_exception(func): - @wraps(func) - def wrapper(*args, **kwargs): - try: - return func(*args, **kwargs) - except Exception as e: - pytest.xfail(f"Xfailing due to an exception: {e}") - return wrapper +def execute_test(pred, lhs, rhs): + gpdlhs = lhs.to_geopandas() + gpdrhs = rhs.to_geopandas() + # Reverse + pred_fn = getattr(rhs, pred) + got = pred_fn(lhs) + gpd_pred_fn = getattr(gpdrhs, pred) + expected = gpd_pred_fn(gpdlhs) + assert (got.values_host == expected.values).all() -# In the below file, all failing tests are recorded with visualizations. -out_file = open("test_binpred_test_dispatch.log", "w") + # Forward + pred_fn = getattr(lhs, pred) + got = pred_fn(rhs) + gpd_pred_fn = getattr(gpdlhs, pred) + expected = gpd_pred_fn(gpdrhs) + assert (got.values_host == expected.values).all() -@xfail_on_exception # TODO: Remove when all tests are passing def test_simple_features( predicate, # noqa: F811 simple_test, # noqa: F811 @@ -38,10 +42,15 @@ def test_simple_features( """Parameterized test fixture that runs a binary predicate test for each combination of geometry types and binary predicates. + Enable the `LOG_DISPATCHED_PREDICATES` environment variable to + log the dispatched predicate results. + Uses four fixtures from `conftest.py` to store the number of times each binary predicate has passed and failed, and the number of times each combination of geometry types has passed and failed. These - results are saved to CSV files after each test. + results are saved to CSV files after each test. The result of the + tests can be summarized with + `tests/binpreds/summarize_binpred_test_dispatch_results.py`. Uses the @xfail_on_exception decorator to mark a test as xfailed if an exception is thrown. This is a temporary measure to allow @@ -71,75 +80,72 @@ def test_simple_features( The pytest request object. Used to print the test name in diagnostic output. """ - try: + if not LOG_DISPATCHED_PREDICATES: (lhs, rhs) = simple_test[2], simple_test[3] - gpdlhs = lhs.to_geopandas() - gpdrhs = rhs.to_geopandas() - pred_fn = getattr(lhs, predicate) - got = pred_fn(rhs) - gpd_pred_fn = getattr(gpdlhs, predicate) - expected = gpd_pred_fn(gpdrhs) - assert (got.values_host == expected.values).all() - - # The test is complete, the rest is just logging. + execute_test(predicate, lhs, rhs) + else: try: - # The test passed, store the results. - predicate_passes[predicate] = ( + execute_test(predicate, lhs, rhs) + + # The test is complete, the rest is just logging. + try: + # The test passed, store the results. + predicate_passes[predicate] = ( + 1 + if predicate not in predicate_passes + else predicate_passes[predicate] + 1 + ) + feature_passes[(lhs.column_type, rhs.column_type)] = ( + 1 + if (lhs.column_type, rhs.column_type) not in feature_passes + else feature_passes[(lhs.column_type, rhs.column_type)] + 1 + ) + passes_df = pd.DataFrame( + { + "predicate": list(predicate_passes.keys()), + "predicate_passes": list(predicate_passes.values()), + } + ) + passes_df.to_csv("predicate_passes.csv", index=False) + passes_df = pd.DataFrame( + { + "feature": list(feature_passes.keys()), + "feature_passes": list(feature_passes.values()), + } + ) + passes_df.to_csv("feature_passes.csv", index=False) + except Exception as e: + raise e + except Exception as e: + # The test failed, store the results. + out_file.write( + f"""{predicate}, + ------------ + {simple_test[0]}\n{simple_test[1]}\nfailed + test: {request.node.name}\n\n""" + ) + predicate_fails[predicate] = ( 1 - if predicate not in predicate_passes - else predicate_passes[predicate] + 1 + if predicate not in predicate_fails + else predicate_fails[predicate] + 1 ) - feature_passes[(lhs.column_type, rhs.column_type)] = ( + feature_fails[(lhs.column_type, rhs.column_type)] = ( 1 - if (lhs.column_type, rhs.column_type) not in feature_passes - else feature_passes[(lhs.column_type, rhs.column_type)] + 1 + if (lhs.column_type, rhs.column_type) not in feature_fails + else feature_fails[(lhs.column_type, rhs.column_type)] + 1 ) - passes_df = pd.DataFrame( + predicate_fails_df = pd.DataFrame( { - "predicate": list(predicate_passes.keys()), - "predicate_passes": list(predicate_passes.values()), + "predicate": list(predicate_fails.keys()), + "predicate_fails": list(predicate_fails.values()), } ) - passes_df.to_csv("predicate_passes.csv", index=False) - passes_df = pd.DataFrame( + predicate_fails_df.to_csv("predicate_fails.csv", index=False) + feature_fails_df = pd.DataFrame( { - "feature": list(feature_passes.keys()), - "feature_passes": list(feature_passes.values()), + "feature": list(feature_fails.keys()), + "feature_fails": list(feature_fails.values()), } ) - passes_df.to_csv("feature_passes.csv", index=False) - except Exception as e: - raise ValueError(e) - except Exception as e: - # The test failed, store the results. - out_file.write( - f"""{predicate}, ------------- -{simple_test[0]}\n{simple_test[1]}\nfailed -test: {request.node.name}\n\n""" - ) - predicate_fails[predicate] = ( - 1 - if predicate not in predicate_fails - else predicate_fails[predicate] + 1 - ) - feature_fails[(lhs.column_type, rhs.column_type)] = ( - 1 - if (lhs.column_type, rhs.column_type) not in feature_fails - else feature_fails[(lhs.column_type, rhs.column_type)] + 1 - ) - predicate_fails_df = pd.DataFrame( - { - "predicate": list(predicate_fails.keys()), - "predicate_fails": list(predicate_fails.values()), - } - ) - predicate_fails_df.to_csv("predicate_fails.csv", index=False) - feature_fails_df = pd.DataFrame( - { - "feature": list(feature_fails.keys()), - "feature_fails": list(feature_fails.values()), - } - ) - feature_fails_df.to_csv("feature_fails.csv", index=False) - raise e + feature_fails_df.to_csv("feature_fails.csv", index=False) + raise e diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_contains.py b/python/cuspatial/cuspatial/tests/binpreds/test_contains.py index 274c96165..fe8197b37 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_contains.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_contains.py @@ -8,6 +8,28 @@ import cuspatial +def test_manual_polygons(): + gpdlhs = gpd.GeoSeries([Polygon(((-8, -8), (-8, 8), (8, 8), (8, -8)))] * 6) + gpdrhs = gpd.GeoSeries( + [ + Polygon(((-8, -8), (-8, 8), (8, 8), (8, -8))), + Polygon(((-2, -2), (-2, 2), (2, 2), (2, -2))), + Polygon(((-10, -2), (-10, 2), (-6, 2), (-6, -2))), + Polygon(((-2, 8), (-2, 12), (2, 12), (2, 8))), + Polygon(((6, 0), (8, 2), (10, 0), (8, -2))), + Polygon(((-2, -8), (-2, -4), (2, -4), (2, -8))), + ] + ) + rhs = cuspatial.from_geopandas(gpdrhs) + lhs = cuspatial.from_geopandas(gpdlhs) + got = lhs.contains(rhs).values_host + expected = gpdlhs.contains(gpdrhs).values + assert (got == expected).all() + got = rhs.contains(lhs).values_host + expected = gpdrhs.contains(gpdlhs).values + assert (got == expected).all() + + def test_same(): lhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) rhs = cuspatial.GeoSeries([Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])]) diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py b/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py index 331f3002d..47a07bee9 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py @@ -532,7 +532,10 @@ def test_pair_linestrings_different_last_two(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") +@pytest.mark.xfail( + reason="""The current implementation of .contains +conceals this special case. Unsure of the solution.""" +) def test_pair_polygons_different_ordering(): gpdpoly1 = gpd.GeoSeries( [ @@ -551,7 +554,6 @@ def test_pair_polygons_different_ordering(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") def test_pair_polygons_different_winding(): gpdpoly1 = gpd.GeoSeries( [ @@ -570,7 +572,6 @@ def test_pair_polygons_different_winding(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") def test_3_polygons_geom_equals_3_polygons_misordered_corrected_vertex(): gpdpoly1 = gpd.GeoSeries( [ @@ -593,7 +594,6 @@ def test_3_polygons_geom_equals_3_polygons_misordered_corrected_vertex(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") def test_polygon_geom_equals_polygon(): gpdpolygon1 = gpd.GeoSeries(Polygon([[0, 0], [1, 0], [1, 1], [0, 0]])) gpdpolygon2 = gpd.GeoSeries(Polygon([[0, 0], [1, 0], [1, 1], [0, 0]])) @@ -604,7 +604,6 @@ def test_polygon_geom_equals_polygon(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") def test_polygon_geom_equals_polygon_swap_inner(): gpdpolygon1 = gpd.GeoSeries(Polygon([[0, 0], [1, 0], [1, 1], [0, 0]])) gpdpolygon2 = gpd.GeoSeries(Polygon([[0, 0], [1, 1], [1, 0], [0, 0]])) @@ -615,7 +614,6 @@ def test_polygon_geom_equals_polygon_swap_inner(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") @pytest.mark.parametrize( "lhs", [ @@ -652,7 +650,6 @@ def test_3_polygons_geom_equals_3_polygons_one_equal(lhs): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") def test_100_polygons_geom_equals_100_polygons(polygon_generator): gpdpolygons1 = gpd.GeoSeries([*polygon_generator(100, 0)]) gpdpolygons2 = gpd.GeoSeries([*polygon_generator(100, 0)]) @@ -663,7 +660,6 @@ def test_100_polygons_geom_equals_100_polygons(polygon_generator): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") def test_3_polygons_geom_equals_3_polygons_different_sizes(): gpdpoly1 = gpd.GeoSeries( [ @@ -688,7 +684,6 @@ def test_3_polygons_geom_equals_3_polygons_different_sizes(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip(reason="NotImplemented: Depends on .contains") def test_3_polygons_geom_equals_3_polygons_misordered(): gpdpoly1 = gpd.GeoSeries( [ diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_intersects_only_binpreds.py b/python/cuspatial/cuspatial/tests/binpreds/test_intersects_only_binpreds.py index 69a99b6c6..46e11f8a4 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_intersects_only_binpreds.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_intersects_only_binpreds.py @@ -261,9 +261,7 @@ def test_linestring_intersects_multipoint_cross_intersection(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="NotImplemented. Depends on allpairs_multipoint_equals_count" -) +@pytest.mark.xfail(reason="Multipoints not supported yet.") def test_linestring_intersects_multipoint_implicit_cross_intersection(): g1 = cuspatial.GeoSeries([LineString([(0.0, 0.0), (1.0, 1.0)])]) g2 = cuspatial.GeoSeries([MultiPoint([(0.0, 1.0), (1.0, 0.0)])]) @@ -274,9 +272,7 @@ def test_linestring_intersects_multipoint_implicit_cross_intersection(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="NotImplemented. Depends on allpairs_multipoint_equals_count" -) +@pytest.mark.xfail(reason="Multipoints not supported yet.") def test_100_linestrings_intersects_100_multipoints( linestring_generator, multipoint_generator ): @@ -569,10 +565,6 @@ def test_multilinestring_intersects_linestring(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="""NotImplemented. Depends on a a combination -of intersects and contains.""" -) def test_linestring_intersects_polygon(): g1 = cuspatial.GeoSeries( [ @@ -593,10 +585,6 @@ def test_linestring_intersects_polygon(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="""NotImplemented. Depends on a a combination -of intersects and contains.""" -) def test_polygon_intersects_linestring(): g1 = cuspatial.GeoSeries( [ @@ -617,10 +605,6 @@ def test_polygon_intersects_linestring(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="""NotImplemented. Depends on a a combination -of intersects and contains.""" -) def test_multipolygon_intersects_linestring(): g1 = cuspatial.GeoSeries( [ @@ -651,10 +635,6 @@ def test_multipolygon_intersects_linestring(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="""NotImplemented. Depends on a a combination -of intersects and contains.""" -) def test_linestring_intersects_multipolygon(): g1 = cuspatial.GeoSeries( [ @@ -685,10 +665,6 @@ def test_linestring_intersects_multipolygon(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="""NotImplemented. Depends on a a combination -of intersects and contains.""" -) def test_polygon_intersects_multipolygon(): g1 = cuspatial.GeoSeries( [ @@ -719,10 +695,6 @@ def test_polygon_intersects_multipolygon(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="""NotImplemented. Depends on a a combination -of intersects and contains.""" -) def test_multipolygon_intersects_polygon(): g1 = cuspatial.GeoSeries( [ @@ -753,10 +725,6 @@ def test_multipolygon_intersects_polygon(): pd.testing.assert_series_equal(expected, got.to_pandas()) -@pytest.mark.skip( - reason="""NotImplemented. Depends on a a combination -of intersects and contains.""" -) def test_multipolygon_intersects_multipolygon(): g1 = cuspatial.GeoSeries( [ diff --git a/python/cuspatial/cuspatial/utils/binpred_utils.py b/python/cuspatial/cuspatial/utils/binpred_utils.py index 7229df632..22b495513 100644 --- a/python/cuspatial/cuspatial/utils/binpred_utils.py +++ b/python/cuspatial/cuspatial/utils/binpred_utils.py @@ -305,7 +305,49 @@ def _open_polygon_rings(geoseries): def _points_and_lines_to_multipoints(geoseries, offsets): """Converts a geoseries of points and lines into a geoseries of - multipoints.""" + multipoints. + + Given a geoseries of points and lines, this function will return a + geoseries of multipoints. The multipoints will contain the points + and lines in the same order as the original geoseries. The offsets + parameter groups the points and lines into multipoints. The offsets + parameter must be a list of integers that contains the offsets of + the multipoints in the original geoseries. A group of four points + and lines can be arranged into four sets of multipoints depending + on the offset used: + + >>> import cuspatial + >>> from cuspatial.utils.binpred_utils import ( + ... _points_and_lines_to_multipoints + ... ) + >>> from shapely.geometry import Point, LineString + >>> mixed = cuspatial.GeoSeries([ + ... Point(0, 0), + ... LineString([(1, 1), (2, 2)]), + ... Point(3, 3), + ... LineString([(4, 4), (5, 5)]), + ... ]) + >>> offsets = [0, 4] + >>> # Place all of the points and linestrings into a single + >>> # multipoint + >>> _points_and_lines_to_multipoints(mixed, offsets) + 0 MULTIPOINT (0.00000 0.00000, 1.00000, 1.0000, ... + dtype: geometry + >>> offsets = [0, 1, 2, 3, 4] + >>> # Place each point and linestring into its own multipoint + >>> _points_and_lines_to_multipoints(mixed, offsets) + 0 MULTIPOINT (0.00000 0.00000) + 1 MULTIPOINT (1.00000, 1.00000, 2.00000, 2.00000) + 2 MULTIPOINT (3.00000 3.00000) + 3 MULTIPOINT (4.00000, 4.00000, 5.00000, 5.00000) + dtype: geometry + >>> offsets = [0, 2, 4] + >>> # Split the points and linestrings into two multipoints + >>> _points_and_lines_to_multipoints(mixed, offsets) + 0 MULTIPOINT (0.00000 0.00000, 1.00000, 1.0000, ... + 1 MULTIPOINT (3.00000 3.00000, 4.00000, 4.0000, ... + dtype: geometry + """ points_mask = geoseries.type == "Point" lines_mask = geoseries.type == "Linestring" if (points_mask + lines_mask).sum() != len(geoseries): @@ -375,8 +417,3 @@ def _multipoints_is_degenerate(geoseries): ) & (y1.reset_index(drop=True) == y2.reset_index(drop=True)) result[sizes_mask] = is_degenerate.reset_index(drop=True) return result - - -def _linestrings_is_degenerate(geoseries): - multipoints = _multipoints_from_geometry(geoseries) - return _multipoints_is_degenerate(multipoints) From 88b86da5587dc3c1cd72402e4315a78906f76c88 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 31 May 2023 09:02:03 -0400 Subject: [PATCH 29/63] Refactor `ST_Distance` header only API (#1143) This PR refactors `ST_Distance` API to reduce the number of kernels to maintain. Currently, each st_distance API maintains its own distance kernel. This refactor let linestring_polygon distance and polygon_polygon distance share the underlying linestring-linestring distance. Also, point-polygon distance now share the same kernel with point-linestring distance kernel. As we are moving to optimization, reducing the total number of kernel to maintain can help scaling the optimization benefit across multiple APIs. Authors: - Michael Wang (https://github.com/isVoid) - Paul Taylor (https://github.com/trxcllnt) - Mark Harris (https://github.com/harrism) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1143 --- .../detail/distance/linestring_distance.cuh | 2 +- .../distance/linestring_polygon_distance.cuh | 149 ++---------------- .../distance/point_linestring_distance.cuh | 59 +------ .../distance/point_polygon_distance.cuh | 77 ++------- .../detail/distance/polygon_distance.cuh | 2 +- .../pairwise_distance.cuh} | 48 ++++++ 6 files changed, 83 insertions(+), 254 deletions(-) rename cpp/include/cuspatial/detail/{algorithm/linestring_distance.cuh => kernel/pairwise_distance.cuh} (56%) diff --git a/cpp/include/cuspatial/detail/distance/linestring_distance.cuh b/cpp/include/cuspatial/detail/distance/linestring_distance.cuh index 19e70b51b..95e0a1872 100644 --- a/cpp/include/cuspatial/detail/distance/linestring_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/linestring_distance.cuh @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include #include diff --git a/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh b/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh index aa0c7cc11..afc569edd 100644 --- a/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh @@ -20,92 +20,16 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include #include #include namespace cuspatial { -namespace detail { - -/** - * @brief Computes distances between the multilinestring and multipolygons - * - * @param multilinestrings Range to the multilinestring - * @param multipolygons Range to the multipolygon - * @param thread_bounds Range to the boundary of thread partitions - * @param multilinestrings_segment_offsets Range to the indices where the first segment of each - * multilinestring begins - * @param multipolygons_segment_offsets Range to the indices where the first segment of each - * multipolygon begins - * @param intersects A uint8_t array that indicates if the corresponding pair of multipoint and - * multipolygon intersects - * @param distances Output range of distances, pre-filled with std::numerical_limits::max() - */ -template -void __global__ -pairwise_linestring_polygon_distance_kernel(MultiLinestringRange multilinestrings, - MultiPolygonRange multipolygons, - IndexRange thread_bounds, - IndexRange multilinestrings_segment_offsets, - IndexRange multipolygons_segment_offsets, - uint8_t* intersects, - OutputIt* distances) -{ - using T = typename MultiLinestringRange::element_t; - using index_t = iterator_value_type; - - auto num_threads = thread_bounds[thread_bounds.size() - 1]; - for (auto idx = blockDim.x * blockIdx.x + threadIdx.x; idx < num_threads; - idx += blockDim.x * gridDim.x) { - auto it = thrust::prev( - thrust::upper_bound(thrust::seq, thread_bounds.begin(), thread_bounds.end(), idx)); - auto geometry_id = thrust::distance(thread_bounds.begin(), it); - auto local_idx = idx - *it; - - if (intersects[geometry_id]) { - distances[geometry_id] = 0.0f; - continue; - } - - // Retrieve the number of segments in multilinestrings[geometry_id] - auto num_segment_this_multilinestring = - multilinestrings.multilinestring_segment_count_begin()[geometry_id]; - // The segment id from the multilinestring this thread is computing (local_id + global_offset) - auto multilinestring_segment_id = - local_idx % num_segment_this_multilinestring + multilinestrings_segment_offsets[geometry_id]; - // The segment id from the multipolygon this thread is computing (local_id + global_offset) - auto multipolygon_segment_id = - local_idx / num_segment_this_multilinestring + multipolygons_segment_offsets[geometry_id]; - - auto [a, b] = multilinestrings.segment_begin()[multilinestring_segment_id]; - auto [c, d] = multipolygons.segment_begin()[multipolygon_segment_id]; - - atomicMin(&distances[geometry_id], sqrt(squared_segment_distance(a, b, c, d))); - } -}; - -} // namespace detail template OutputIt pairwise_linestring_polygon_distance(MultiLinestringRange multilinestrings, @@ -119,70 +43,25 @@ OutputIt pairwise_linestring_polygon_distance(MultiLinestringRange multilinestri CUSPATIAL_EXPECTS(multilinestrings.size() == multipolygons.size(), "Must have the same number of input rows."); - if (multilinestrings.size() == 0) return distances_first; + auto size = multilinestrings.size(); + + if (size == 0) return distances_first; // Create a multipoint range from multilinestrings, computes intersection - auto multipoints = multilinestrings.as_multipoint_range(); - auto multipoint_intersects = point_polygon_intersects(multipoints, multipolygons, stream); - - // Compute the "boundary" of threads. Threads are partitioned based on the number of linestrings - // times the number of polygons in a multipoint-multipolygon pair. - auto segment_count_product_it = thrust::make_transform_iterator( - thrust::make_zip_iterator(multilinestrings.multilinestring_segment_count_begin(), - multipolygons.multipolygon_segment_count_begin()), - thrust::make_zip_function(thrust::multiplies{})); - - // Computes the "thread boundary" of each pair. This array partitions the thread range by - // geometries. E.g. threadIdx within [thread_bounds[i], thread_bounds[i+1]) computes distances of - // the ith pair. - auto thread_bounds = rmm::device_uvector(multilinestrings.size() + 1, stream); - detail::zero_data_async(thread_bounds.begin(), thread_bounds.end(), stream); - - thrust::inclusive_scan(rmm::exec_policy(stream), - segment_count_product_it, - segment_count_product_it + thread_bounds.size() - 1, - thrust::next(thread_bounds.begin())); - - // Compute offsets to the first segment of each multilinestring and multipolygon - auto multilinestring_segment_offsets = - rmm::device_uvector(multilinestrings.num_multilinestrings() + 1, stream); - detail::zero_data_async( - multilinestring_segment_offsets.begin(), multilinestring_segment_offsets.end(), stream); - - auto multipolygon_segment_offsets = - rmm::device_uvector(multipolygons.num_multipolygons() + 1, stream); - detail::zero_data_async( - multipolygon_segment_offsets.begin(), multipolygon_segment_offsets.end(), stream); - - thrust::inclusive_scan(rmm::exec_policy(stream), - multilinestrings.multilinestring_segment_count_begin(), - multilinestrings.multilinestring_segment_count_begin() + - multilinestrings.num_multilinestrings(), - thrust::next(multilinestring_segment_offsets.begin())); - - thrust::inclusive_scan( - rmm::exec_policy(stream), - multipolygons.multipolygon_segment_count_begin(), - multipolygons.multipolygon_segment_count_begin() + multipolygons.num_multipolygons(), - thrust::next(multipolygon_segment_offsets.begin())); - - // Initialize output range + auto multipoints = multilinestrings.as_multipoint_range(); + auto intersects = point_polygon_intersects(multipoints, multipolygons, stream); + + auto polygons_as_linestrings = multipolygons.as_multilinestring_range(); + thrust::fill(rmm::exec_policy(stream), distances_first, - distances_first + multilinestrings.num_multilinestrings(), + distances_first + size, std::numeric_limits::max()); - auto num_threads = thread_bounds.back_element(stream); - auto [tpb, num_blocks] = grid_1d(num_threads); - - detail::pairwise_linestring_polygon_distance_kernel<<>>( - multilinestrings, - multipolygons, - range{thread_bounds.begin(), thread_bounds.end()}, - range{multilinestring_segment_offsets.begin(), multilinestring_segment_offsets.end()}, - range{multipolygon_segment_offsets.begin(), multipolygon_segment_offsets.end()}, - multipoint_intersects.begin(), - distances_first); + auto [threads_per_block, num_blocks] = grid_1d(multilinestrings.num_points()); + + detail::linestring_distance<<>>( + multilinestrings, polygons_as_linestrings, intersects.begin(), distances_first); return distances_first + multilinestrings.num_multilinestrings(); } diff --git a/cpp/include/cuspatial/detail/distance/point_linestring_distance.cuh b/cpp/include/cuspatial/detail/distance/point_linestring_distance.cuh index c245cd83c..8adcbb440 100644 --- a/cpp/include/cuspatial/detail/distance/point_linestring_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/point_linestring_distance.cuh @@ -16,8 +16,8 @@ #pragma once -#include -#include +#include +#include #include #include #include @@ -25,59 +25,14 @@ #include #include -#include -#include -#include -#include #include -#include -#include #include -#include #include namespace cuspatial { namespace detail { -/** - * @brief Kernel to compute the distance between pairs of point and linestring. - * - * The kernel is launched on one linestring point per thread. Each thread iterates on all points in - * the multipoint operand and use atomics to aggregate the shortest distance. - */ -template -void __global__ pairwise_point_linestring_distance_kernel(MultiPointRange multipoints, - MultiLinestringRange multilinestrings, - OutputIterator distances) -{ - using T = typename MultiPointRange::element_t; - - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings.num_points(); - idx += gridDim.x * blockDim.x) { - // Search from the part offsets array to determine the part idx of current linestring point - auto part_idx = multilinestrings.part_idx_from_point_idx(idx); - // Pointer to the last point in the linestring, skip iteration. - // Note that the last point for the last linestring is guarded by the grid-stride loop. - if (!multilinestrings.is_valid_segment_id(idx, part_idx)) continue; - - // Search from the linestring geometry offsets array to determine the geometry idx of - // current linestring point - auto geometry_idx = multilinestrings.geometry_idx_from_part_idx(part_idx); - - // Reduce the minimum distance between different parts of the multi-point. - auto [a, b] = multilinestrings.segment(idx); - T min_distance_squared = std::numeric_limits::max(); - - for (vec_2d const& c : multipoints[geometry_idx]) { - // TODO: reduce redundant computation only related to `a`, `b` in this helper. - auto const distance_squared = point_to_segment_distance_squared(c, a, b); - min_distance_squared = min(distance_squared, min_distance_squared); - } - atomicMin(&distances[geometry_idx], static_cast(sqrt(min_distance_squared))); - } -} - } // namespace detail template OutputIt pairwise_point_linestring_distance(MultiPointRange multipoints, @@ -96,6 +51,7 @@ OutputIt pairwise_point_linestring_distance(MultiPointRange multipoints, CUSPATIAL_EXPECTS(multilinestrings.size() == multipoints.size(), "Input must have the same number of rows."); + if (multilinestrings.size() == 0) { return distances_first; } thrust::fill_n(rmm::exec_policy(stream), @@ -103,13 +59,10 @@ OutputIt pairwise_point_linestring_distance(MultiPointRange multipoints, multilinestrings.size(), std::numeric_limits::max()); - std::size_t constexpr threads_per_block = 256; - std::size_t const num_blocks = - (multilinestrings.size() + threads_per_block - 1) / threads_per_block; + auto [threads_per_block, num_blocks] = grid_1d(multilinestrings.num_points()); - detail:: - pairwise_point_linestring_distance_kernel<<>>( - multipoints, multilinestrings, distances_first); + detail::point_linestring_distance<<>>( + multipoints, multilinestrings, thrust::nullopt, distances_first); CUSPATIAL_CUDA_TRY(cudaGetLastError()); diff --git a/cpp/include/cuspatial/detail/distance/point_polygon_distance.cuh b/cpp/include/cuspatial/detail/distance/point_polygon_distance.cuh index 1729b6775..67feb7699 100644 --- a/cpp/include/cuspatial/detail/distance/point_polygon_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/point_polygon_distance.cuh @@ -19,74 +19,21 @@ #include "distance_utils.cuh" #include -#include -#include -#include -#include +#include #include -#include -#include -#include #include -#include #include -#include -#include -#include -#include -#include -#include - -#include #include #include namespace cuspatial { -namespace detail { - -/** - * @brief Kernel to compute the distance between pairs of point and polygon. - */ -template -void __global__ pairwise_point_polygon_distance_kernel(MultiPointRange multipoints, - MultiPolygonRange multipolygons, - IntersectionRange intersects, - OutputIterator distances) -{ - using T = typename MultiPointRange::element_t; - - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multipolygons.num_points(); - idx += gridDim.x * blockDim.x) { - auto geometry_idx = multipolygons.geometry_idx_from_segment_idx(idx); - if (geometry_idx == MultiPolygonRange::INVALID_INDEX) continue; - - if (intersects[geometry_idx]) { - distances[geometry_idx] = T{0.0}; - continue; - } - - auto [a, b] = multipolygons.get_segment(idx); - - T dist_squared = std::numeric_limits::max(); - for (vec_2d point : multipoints[geometry_idx]) { - dist_squared = min(dist_squared, point_to_segment_distance_squared(point, a, b)); - } - - atomicMin(&distances[geometry_idx], sqrt(dist_squared)); - } -} - -} // namespace detail template OutputIt pairwise_point_polygon_distance(MultiPointRange multipoints, MultiPolygonRange multipolygons, - OutputIt distances_first, + OutputIt distances, rmm::cuda_stream_view stream) { using T = typename MultiPointRange::element_t; @@ -95,23 +42,25 @@ OutputIt pairwise_point_polygon_distance(MultiPointRange multipoints, CUSPATIAL_EXPECTS(multipoints.size() == multipolygons.size(), "Must have the same number of input rows."); - if (multipoints.size() == 0) return distances_first; + if (multipoints.size() == 0) return distances; + + auto intersects = point_polygon_intersects(multipoints, multipolygons, stream); - auto multipoint_intersects = point_polygon_intersects(multipoints, multipolygons, stream); + auto polygons_as_linestrings = multipolygons.as_multilinestring_range(); thrust::fill(rmm::exec_policy(stream), - distances_first, - distances_first + multipoints.size(), + distances, + distances + multipoints.size(), std::numeric_limits::max()); - auto [threads_per_block, n_blocks] = grid_1d(multipolygons.num_points()); - detail:: - pairwise_point_polygon_distance_kernel<<>>( - multipoints, multipolygons, multipoint_intersects.begin(), distances_first); + auto [threads_per_block, n_blocks] = grid_1d(polygons_as_linestrings.num_points()); + + detail::point_linestring_distance<<>>( + multipoints, polygons_as_linestrings, intersects.begin(), distances); CUSPATIAL_CHECK_CUDA(stream.value()); - return distances_first + multipoints.size(); + return distances + multipoints.size(); } } // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/distance/polygon_distance.cuh b/cpp/include/cuspatial/detail/distance/polygon_distance.cuh index 2da92a4a4..e787d8f30 100644 --- a/cpp/include/cuspatial/detail/distance/polygon_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/polygon_distance.cuh @@ -17,9 +17,9 @@ #pragma once #include "distance_utils.cuh" -#include "linestring_distance.cuh" #include +#include #include #include diff --git a/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh b/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh similarity index 56% rename from cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh rename to cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh index 4c988612d..e064092a9 100644 --- a/cpp/include/cuspatial/detail/algorithm/linestring_distance.cuh +++ b/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh @@ -72,5 +72,53 @@ __global__ void linestring_distance(MultiLinestringRange1 multilinestrings1, } } +/** + * @brief Kernel to compute the distance between pairs of point and linestring. + * + * The kernel is launched on one linestring point per thread. Each thread iterates on all points in + * the multipoint operand and use atomics to aggregate the shortest distance. + * + * `intersects` is an optional pointer to a boolean range where the `i`th element indicates the + * `i`th output should be set to 0 and bypass distance computation. This argument is optional, if + * set to nullopt, no distance computation will be bypassed. + */ +template +void __global__ point_linestring_distance(MultiPointRange multipoints, + MultiLinestringRange multilinestrings, + thrust::optional intersects, + OutputIterator distances) +{ + using T = typename MultiPointRange::element_t; + + for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings.num_points(); + idx += gridDim.x * blockDim.x) { + // Search from the part offsets array to determine the part idx of current linestring point + auto part_idx = multilinestrings.part_idx_from_point_idx(idx); + // Pointer to the last point in the linestring, skip iteration. + // Note that the last point for the last linestring is guarded by the grid-stride loop. + if (!multilinestrings.is_valid_segment_id(idx, part_idx)) continue; + + // Search from the linestring geometry offsets array to determine the geometry idx of + // current linestring point + auto geometry_idx = multilinestrings.geometry_idx_from_part_idx(part_idx); + + if (intersects.has_value() && intersects.value()[geometry_idx]) { + distances[geometry_idx] = 0; + continue; + } + + // Reduce the minimum distance between different parts of the multi-point. + auto [a, b] = multilinestrings.segment(idx); + T min_distance_squared = std::numeric_limits::max(); + + for (vec_2d const& c : multipoints[geometry_idx]) { + // TODO: reduce redundant computation only related to `a`, `b` in this helper. + auto const distance_squared = point_to_segment_distance_squared(c, a, b); + min_distance_squared = min(distance_squared, min_distance_squared); + } + atomicMin(&distances[geometry_idx], static_cast(sqrt(min_distance_squared))); + } +} + } // namespace detail } // namespace cuspatial From f571e9d8ac62b968e0e908bee3d4d388df444dbf Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 31 May 2023 17:41:49 -0400 Subject: [PATCH 30/63] Add Benchmark to `pairwise_linestring_polygon_distance` (#1153) This PR adds nvbenchmark suite benchmarks to pariwise_linestring_polygon distance. This PR also adds `multilinestring_array_generator` and reuses in both linestring distance and linestring-polygon distance. The addition of `multilinestring_array_generator` completes the `geometry_generator.cuh`, which now has generators for `multipolygons`, `multilinestrings` and `multipoints`. I have an additional driver python suite that helps parameterizing this nvbench test suite. Not sure where to put them for now. https://gist.github.com/isVoid/99ce3f6425528217da78118ab2653959 Contributes to #259 Closes #1160 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1153 --- cpp/benchmarks/CMakeLists.txt | 9 +- .../distance/pairwise_linestring_distance.cu | 140 +++++------------- .../pairwise_linestring_polygon_distance.cu | 90 +++++++++++ .../cuspatial_test/geometry_generator.cuh | 105 +++++++++++++ .../cuspatial_test/vector_factories.cuh | 4 +- 5 files changed, 245 insertions(+), 103 deletions(-) create mode 100644 cpp/benchmarks/distance/pairwise_linestring_polygon_distance.cu diff --git a/cpp/benchmarks/CMakeLists.txt b/cpp/benchmarks/CMakeLists.txt index d153b63ab..e2587c710 100644 --- a/cpp/benchmarks/CMakeLists.txt +++ b/cpp/benchmarks/CMakeLists.txt @@ -79,10 +79,15 @@ endfunction() ConfigureBench(HAUSDORFF_BENCH distance/hausdorff_benchmark.cpp) -ConfigureNVBench(DISTANCES_BENCH - distance/pairwise_point_polygon_distance.cu +ConfigureNVBench(POINT_POLYGON_DISTANCES_BENCH + distance/pairwise_point_polygon_distance.cu) + +ConfigureNVBench(LINESTRING_DISTANCES_BENCH distance/pairwise_linestring_distance.cu) +ConfigureNVBench(LINESTRING_POLYGON_DISTANCES_BENCH + distance/pairwise_linestring_polygon_distance.cu) + ConfigureNVBench(QUADTREE_ON_POINTS_BENCH indexing/quadtree_on_points.cu) diff --git a/cpp/benchmarks/distance/pairwise_linestring_distance.cu b/cpp/benchmarks/distance/pairwise_linestring_distance.cu index e8f7258d5..c17c59b0d 100644 --- a/cpp/benchmarks/distance/pairwise_linestring_distance.cu +++ b/cpp/benchmarks/distance/pairwise_linestring_distance.cu @@ -17,124 +17,64 @@ #include #include -#include -#include -#include -#include - -#include -#include +#include -#include -#include -#include +#include -#include +#include using namespace cuspatial; -/** - * @brief Helper to generate linestrings used for benchmarks. - * - * The generator adopts a walking algorithm. The ith point is computed by - * walking (cos(i) * segment_length, sin(i) * segment_length) from the `i-1` - * point. The initial point of the linestring is at `(init_xy, init_xy)`. - * Since equidistance sampling on a sinusoid will result in random values, - * the shape of the linestring is random. - * - * The number of line segments per linestring is constrolled by - * `num_segment_per_string`. - * - * Since the outreach upper bound of the linestring group is - * `(init_xy + num_strings * num_segments_per_string * segment_length)`, - * user may control the locality of the linestring group via these four - * arguments. It's important to control the locality between pairs of - * the linestrings. Linestrings pair that do not intersect will take - * the longest compute path in the kernel and will benchmark the worst - * case performance of the API. - * - * @tparam T The floating point type for the coordinates - * @param num_strings Total number of linestrings - * @param num_segments_per_string Number of line segments per linestring - * @param segment_length Length of each segment, or stride of walk - * @param init_xy The initial coordinate to start the walk - * @param stream The CUDA stream to use for device memory operations and kernel launches - * @return A tuple of x and y coordinates of points and offsets to which the first point - * of each linestring starts. - * - */ template -std::tuple>, rmm::device_vector> generate_linestring( - int32_t num_strings, int32_t num_segments_per_string, T segment_length, vec_2d init_xy) +void pairwise_linestring_distance_benchmark(nvbench::state& state, nvbench::type_list) { - int32_t num_points = num_strings * (num_segments_per_string + 1); + // TODO: to be replaced by nvbench fixture once it's ready + cuspatial::rmm_pool_raii rmm_pool; + rmm::cuda_stream_view stream = rmm::cuda_stream_default; - auto offset_iter = detail::make_counting_transform_iterator( - 0, [num_segments_per_string](auto i) { return i * num_segments_per_string; }); - auto rads_iter = detail::make_counting_transform_iterator(0, [](auto i) { - return vec_2d{cos(static_cast(i)), sin(static_cast(i))}; - }); + auto const num_pairs{static_cast(state.get_int64("NumPairs"))}; + auto const num_linestrings_per_multilinestring{ + static_cast(state.get_int64("NumLineStringsPerMultiLineString"))}; + auto const num_segments_per_linestring{ + static_cast(state.get_int64("NumSegmentsPerLineString"))}; - std::vector offsets(offset_iter, offset_iter + num_strings); - std::vector> rads(rads_iter, rads_iter + num_points); - std::vector> points(num_points); + auto params1 = test::multilinestring_generator_parameter{ + num_pairs, num_linestrings_per_multilinestring, num_segments_per_linestring, 1.0, {0., 0.}}; + auto params2 = test::multilinestring_generator_parameter{num_pairs, + num_linestrings_per_multilinestring, + num_segments_per_linestring, + 1.0, + {100000., 100000.}}; - auto random_walk_func = [segment_length](vec_2d const& prev, vec_2d const& rad) { - return prev + segment_length * rad; - }; + auto ls1 = generate_multilinestring_array(params1, stream); + auto ls2 = generate_multilinestring_array(params2, stream); - thrust::exclusive_scan( - thrust::host, points.begin(), points.end(), points.begin(), init_xy, random_walk_func); + auto ls1range = ls1.range(); + auto ls2range = ls2.range(); - // Implicitly constructing a device vector from host vector. - return std::tuple(std::move(points), std::move(offsets)); -} + auto output = rmm::device_uvector(num_pairs, stream); + auto out_it = output.begin(); -template -void pairwise_linestring_distance_benchmark(nvbench::state& state, nvbench::type_list) -{ - // TODO: to be replaced by nvbench fixture once it's ready - cuspatial::rmm_pool_raii rmm_pool; + auto const total_points = params1.num_points() + params2.num_points(); - auto const num_string_pairs{state.get_int64("NumStrings")}; - auto const num_segments_per_string{state.get_int64("NumSegmentsPerString")}; - - auto [ls1, ls1_offset] = - generate_linestring(num_string_pairs, num_segments_per_string, 1, {0, 0}); - auto [ls2, ls2_offset] = - generate_linestring(num_string_pairs, num_segments_per_string, 1, {100, 100}); - - auto distances = rmm::device_vector(ls1.size()); - auto out_it = distances.begin(); - - auto multilinestrings1 = make_multilinestring_range(1, - thrust::make_counting_iterator(0), - num_string_pairs, - ls1_offset.begin(), - ls1.size(), - ls1.begin()); - auto multilinestrings2 = make_multilinestring_range(1, - thrust::make_counting_iterator(0), - num_string_pairs, - ls2_offset.begin(), - ls2.size(), - ls2.begin()); - auto const total_points = ls1.size() + ls2.size(); - - state.add_element_count(num_string_pairs, "LineStringPairs"); + state.add_element_count(num_pairs, "NumPairs"); state.add_element_count(total_points, "NumPoints"); - state.add_global_memory_reads(total_points * 2, "CoordinatesDataSize"); - state.add_global_memory_reads(num_string_pairs * 2, "OffsetsDataSize"); - state.add_global_memory_writes(num_string_pairs); - state.exec(nvbench::exec_tag::sync, - [&multilinestrings1, &multilinestrings2, &out_it](nvbench::launch& launch) { - pairwise_linestring_distance(multilinestrings1, multilinestrings2, out_it); - }); + state.add_global_memory_reads(total_points * 2, "CoordinatesDataSize"); + state.add_global_memory_reads(params1.num_multilinestrings + + params2.num_multilinestrings + + params1.num_linestrings() + params2.num_linestrings(), + "OffsetsDataSize"); + state.add_global_memory_writes(num_pairs); + + state.exec(nvbench::exec_tag::sync, [&ls1range, &ls2range, &out_it](nvbench::launch& launch) { + pairwise_linestring_distance(ls1range, ls2range, out_it); + }); } using floating_point_types = nvbench::type_list; NVBENCH_BENCH_TYPES(pairwise_linestring_distance_benchmark, NVBENCH_TYPE_AXES(floating_point_types)) .set_type_axes_names({"CoordsType"}) - .add_int64_axis("NumStrings", {1'000, 10'000, 100'000}) - .add_int64_axis("NumSegmentsPerString", {10, 100, 1'000}); + .add_int64_axis("NumPairs", {1'000, 10'000, 100'000}) + .add_int64_axis("NumLineStringsPerMultiLineString", {1'000, 10'000, 100'000}) + .add_int64_axis("NumSegmentsPerLineString", {10, 100, 1'000}); diff --git a/cpp/benchmarks/distance/pairwise_linestring_polygon_distance.cu b/cpp/benchmarks/distance/pairwise_linestring_polygon_distance.cu new file mode 100644 index 000000000..0d4fdf574 --- /dev/null +++ b/cpp/benchmarks/distance/pairwise_linestring_polygon_distance.cu @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include +#include + +#include + +#include + +#include + +using namespace cuspatial; + +template +void pairwise_linestring_polygon_distance_benchmark(nvbench::state& state, nvbench::type_list) +{ + // TODO: to be replaced by nvbench fixture once it's ready + cuspatial::rmm_pool_raii rmm_pool; + rmm::cuda_stream_view stream = rmm::cuda_stream_default; + + auto const num_pairs{static_cast(state.get_int64("NumPairs"))}; + auto const num_linestrings_per_multilinestring{ + static_cast(state.get_int64("NumLineStringPerMultiLineString"))}; + auto const num_segments_per_linestring{ + static_cast(state.get_int64("NumSegmentsPerLineString"))}; + + auto const num_polygon_per_multipolygon{ + static_cast(state.get_int64("NumPolygonPerMultiPolygon"))}; + auto const num_ring_per_polygon{static_cast(state.get_int64("NumRingsPerPolygon"))}; + auto const num_points_per_ring{static_cast(state.get_int64("NumPointsPerRing"))}; + + auto params1 = test::multilinestring_generator_parameter{ + num_pairs, num_linestrings_per_multilinestring, num_segments_per_linestring, 1.0, {0., 0.}}; + auto params2 = test::multipolygon_generator_parameter{num_pairs, + num_polygon_per_multipolygon, + num_ring_per_polygon - 1, + num_points_per_ring - 1, + {10000, 10000}, + 1}; + + auto lines = generate_multilinestring_array(params1, stream); + auto polys = generate_multipolygon_array(params2, stream); + + auto lines_range = lines.range(); + auto poly_range = polys.range(); + + auto output = rmm::device_uvector(num_pairs, stream); + auto out_it = output.begin(); + + auto const total_points = lines_range.num_points() + poly_range.num_points(); + + state.add_element_count(num_pairs, "NumPairs"); + state.add_element_count(total_points, "NumPoints"); + state.add_global_memory_reads(total_points * 2, "CoordinatesDataSize"); + state.add_global_memory_reads(params1.num_multilinestrings + params1.num_linestrings() + + params2.num_multipolygons + params2.num_polygons() + + params2.num_rings() + 5, + "OffsetsDataSize"); + state.add_global_memory_writes(num_pairs); + + state.exec(nvbench::exec_tag::sync, + [&lines_range, &poly_range, &out_it](nvbench::launch& launch) { + pairwise_linestring_polygon_distance(lines_range, poly_range, out_it); + }); +} + +using floating_point_types = nvbench::type_list; +NVBENCH_BENCH_TYPES(pairwise_linestring_polygon_distance_benchmark, + NVBENCH_TYPE_AXES(floating_point_types)) + .set_type_axes_names({"CoordsType"}) + .add_int64_axis("NumPairs", {100'00}) + .add_int64_axis("NumLineStringPerMultiLineString", {10, 100, 1'000}) + .add_int64_axis("NumSegmentsPerLineString", {100}) + .add_int64_axis("NumPolygonPerMultiPolygon", {100}) + .add_int64_axis("NumRingsPerPolygon", {10}) + .add_int64_axis("NumPointsPerRing", {100}); diff --git a/cpp/include/cuspatial_test/geometry_generator.cuh b/cpp/include/cuspatial_test/geometry_generator.cuh index 2e3ab27c4..73b1d270e 100644 --- a/cpp/include/cuspatial_test/geometry_generator.cuh +++ b/cpp/include/cuspatial_test/geometry_generator.cuh @@ -34,6 +34,28 @@ namespace cuspatial { namespace test { +namespace detail { + +template +struct tabulate_direction_functor { + vec_2d __device__ operator()(index_t i) + { + return vec_2d{cos(static_cast(i)), sin(static_cast(i))}; + } +}; + +template +struct random_walk_functor { + T segment_length; + + vec_2d __device__ operator()(vec_2d prev, vec_2d rad) + { + return prev + segment_length * rad; + } +}; + +} // namespace detail + /** * @brief Struct to store the parameters of the multipolygon array generator * @@ -252,6 +274,89 @@ auto generate_multipolygon_array(multipolygon_generator_parameter params, std::move(coordinates)); } +/** + * @brief Struct to store the parameters of the multilinestring generator + * + * @tparam T Underlying type of the coordinates + */ +template +struct multilinestring_generator_parameter { + std::size_t num_multilinestrings; + std::size_t num_linestrings_per_multilinestring; + std::size_t num_segments_per_linestring; + T segment_length; + vec_2d origin; + + std::size_t num_linestrings() + { + return num_multilinestrings * num_linestrings_per_multilinestring; + } + + std::size_t num_points_per_linestring() { return num_segments_per_linestring + 1; } + + std::size_t num_segments() { return num_linestrings() * num_segments_per_linestring; } + std::size_t num_points() { return num_linestrings() * num_points_per_linestring(); } +}; + +/** + * @brief Helper to generate linestrings used for benchmarks. + * + * The generator adopts a walking algorithm. The ith point is computed by + * walking (cos(i) * segment_length, sin(i) * segment_length) from the `i-1` + * point. The initial point of the linestring is at `(init_xy, init_xy)`. + * + * The number of line segments per linestring is constrolled by + * `num_segment_per_string`. + * + * Since the outreach upper bound of the linestring group is + * `(init_xy + total_num_segments * segment_length)`, user may control the + * locality of the linestring group via these five arguments. + * + * The locality of the multilinestrings is important to the computation and + * and carefully designing the parameters can make the multilinestrings intersect/disjoint. + * which could affect whether the benchmark is testing against best or worst case. + * + * @tparam T The floating point type for the coordinates + * @param params The parameters used to specify the generator + * @param stream The CUDA stream to use for device memory operations and kernel launches + * @return The generated multilinestring array + */ +template +auto generate_multilinestring_array(multilinestring_generator_parameter params, + rmm::cuda_stream_view stream) +{ + rmm::device_uvector geometry_offset(params.num_multilinestrings + 1, stream); + rmm::device_uvector part_offset(params.num_linestrings() + 1, stream); + rmm::device_uvector> points(params.num_points(), stream); + + thrust::sequence(rmm::exec_policy(stream), + geometry_offset.begin(), + geometry_offset.end(), + static_cast(0), + params.num_linestrings_per_multilinestring); + + thrust::sequence(rmm::exec_policy(stream), + part_offset.begin(), + part_offset.end(), + static_cast(0), + params.num_segments_per_linestring + 1); + + thrust::tabulate(rmm::exec_policy(stream), + points.begin(), + points.end(), + detail::tabulate_direction_functor{}); + + thrust::exclusive_scan(rmm::exec_policy(stream), + points.begin(), + points.end(), + points.begin(), + params.origin, + detail::random_walk_functor{params.segment_length}); + + return make_multilinestring_array( + std::move(geometry_offset), std::move(part_offset), std::move(points)); +} + /** * @brief Struct to store the parameters of the multipoint aray * diff --git a/cpp/include/cuspatial_test/vector_factories.cuh b/cpp/include/cuspatial_test/vector_factories.cuh index 14c363b30..f2572c17e 100644 --- a/cpp/include/cuspatial_test/vector_factories.cuh +++ b/cpp/include/cuspatial_test/vector_factories.cuh @@ -276,7 +276,9 @@ auto make_multilinestring_array(IndexRangeA geometry_inl, using DeviceCoordVector = thrust::device_vector; return multilinestring_array( - make_device_vector(geometry_inl), make_device_vector(part_inl), make_device_vector(coord_inl)); + make_device_vector(std::move(geometry_inl)), + make_device_vector(std::move(part_inl)), + make_device_vector(std::move(coord_inl))); } /** From 50e3b6a2251b798ff32068a0ef6d8b11a52ecdfd Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 31 May 2023 21:47:37 -0400 Subject: [PATCH 31/63] Add `multilinestring_segment_manager` for segment related methods in multilinestring ranges (#1134) closes #1055 This PR adds `multilinestring_segment_manager` owning class to track the lifetime of intermediate allocations that has to do with segment iterators. In addition `multilinestring_segment_range` is added as the non-owning class to the previous class to provide iterators to the segments. The syntax to use this object is like: ```c++ auto segment_manager = multilinestrings._segments(stream); auto segment_range = segment_manager.range(); ``` Then a user can easily access the segments in the multilinestrings with: ```c++ for (auto seg : segment_range) { auto length = sqrt(dot(seg.a, seg.b)); } ``` Secondly, this PR includes tests that has empty geometry collections in the input, linestring_polygon_distance now correctly computes nans for these input pairs. In addition, `CUSPATIAL_EXPECTS_VALID_MULTI*_SIZES` is relaxed. Valid polygon and ring sizes are only implicitly required but not checked via the size of the arrays since they are insufficient checks. Accordingly, some tests are also relaxed. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1134 --- .../distance/linestring_polygon_distance.cuh | 18 +- cpp/include/cuspatial/detail/functors.cuh | 92 ------ .../detail/kernel/pairwise_distance.cuh | 8 +- .../detail/multilinestring_segment.cuh | 128 ++++++++ .../detail/range/multilinestring_range.cuh | 67 +---- .../range/multilinestring_segment_range.cuh | 273 ++++++++++++++++++ .../detail/range/multipolygon_range.cuh | 81 +----- .../cuspatial/detail/utility/validation.hpp | 44 ++- .../multilinestring_ref.cuh | 3 + .../geometry_collection/multipolygon_ref.cuh | 3 + .../cuspatial/range/multilinestring_range.cuh | 23 +- .../cuspatial/range/multipolygon_range.cuh | 33 +-- .../cuspatial_test/vector_equality.hpp | 12 +- .../polygon_bounding_boxes_test.cpp | 26 -- .../linestring_polygon_distance_test.cu | 105 +++++++ .../point_in_polygon_test.cpp | 17 -- cpp/tests/range/multilinestring_range_test.cu | 163 +++++++++-- cpp/tests/range/multipolygon_range_test.cu | 153 ++++++++-- 18 files changed, 851 insertions(+), 398 deletions(-) create mode 100644 cpp/include/cuspatial/detail/multilinestring_segment.cuh create mode 100644 cpp/include/cuspatial/detail/range/multilinestring_segment_range.cuh diff --git a/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh b/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh index afc569edd..abb54e227 100644 --- a/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh +++ b/cpp/include/cuspatial/detail/distance/linestring_polygon_distance.cuh @@ -22,8 +22,6 @@ #include #include -#include - #include #include @@ -53,17 +51,23 @@ OutputIt pairwise_linestring_polygon_distance(MultiLinestringRange multilinestri auto polygons_as_linestrings = multipolygons.as_multilinestring_range(); - thrust::fill(rmm::exec_policy(stream), - distances_first, - distances_first + size, - std::numeric_limits::max()); + thrust::transform(rmm::exec_policy(stream), + multilinestrings.begin(), + multilinestrings.end(), + multipolygons.begin(), + distances_first, + [] __device__(auto multilinestring, auto multipolygon) { + return (multilinestring.is_empty() || multipolygon.is_empty()) + ? std::numeric_limits::quiet_NaN() + : std::numeric_limits::max(); + }); auto [threads_per_block, num_blocks] = grid_1d(multilinestrings.num_points()); detail::linestring_distance<<>>( multilinestrings, polygons_as_linestrings, intersects.begin(), distances_first); - return distances_first + multilinestrings.num_multilinestrings(); + return distances_first + size; } } // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/functors.cuh b/cpp/include/cuspatial/detail/functors.cuh index 1f390753d..25c79885d 100644 --- a/cpp/include/cuspatial/detail/functors.cuh +++ b/cpp/include/cuspatial/detail/functors.cuh @@ -46,97 +46,5 @@ struct offset_pair_to_count_functor { } }; -/** - * @brief Convert counts of points to counts of segments in a linestring. - * - * A Multilinestring is composed of a series of Linestrings. Each Linestring is composed of a - * segments. The number of segments in a multilinestring is the number of points in the - * multilinestring minus the number of linestrings. - * - * Caveats: This has a strong assumption that the Multilinestring does not contain empty - * linestrings. While each non-empty linestring in the multilinestring represents 1 extra segment, - * an empty multilinestring does not introduce any extra segments since it does not contain any - * points. - * - * Used to create segment count iterators, such as `multi*_segment_count_begin`. - * - * @tparam IndexPair Must be iterator to a pair of counts - * @param n_point_linestring_pair A pair of counts, the first is the number of points, the second is - * the number of linestrings. - */ -struct point_count_to_segment_count_functor { - template - CUSPATIAL_HOST_DEVICE auto operator()(IndexPair n_point_linestring_pair) - { - auto nPoints = thrust::get<0>(n_point_linestring_pair); - auto nLinestrings = thrust::get<1>(n_point_linestring_pair); - return nPoints - nLinestrings; - } -}; - -/** - * @brief Given an offset iterator it, returns an iterator of the distance between it and an input - * index i - * - * @tparam OffsetIterator Iterator type to the offset - * - * Caveats: This has a strong assumption that the Multilinestring does not contain empty - * linestrings. While each non-empty linestring in the multilinestring represents 1 extra segment, - * an empty multilinestring does not introduce any extra segments since it does not contain any - * points. - * - * Used to create iterator to segment offsets, such as `segment_offset_begin`. - */ -template -struct to_distance_iterator { - OffsetIterator begin; - - template - CUSPATIAL_HOST_DEVICE auto operator()(IndexType i) - { - return begin[i] - i; - } -}; - -/// Deduction guide for to_distance_iterator -template -to_distance_iterator(OffsetIterator) -> to_distance_iterator; - -/** - * @brief Return a segment from the a partitioned range of points - * - * Used in a counting transform iterator. Given an index of the segment, offset it by the number of - * skipped segments preceding i in the partitioned range of points. Dereference the corresponding - * point and the point following to make a segment. - * - * Used to create iterator to segments, such as `segment_begin`. - * - * @tparam OffsetIterator the iterator type indicating partitions of the point range. - * @tparam CoordinateIterator the iterator type to the point range. - */ -template -struct to_valid_segment_functor { - using element_t = iterator_vec_base_type; - - OffsetIterator begin; - OffsetIterator end; - CoordinateIterator point_begin; - - template - CUSPATIAL_HOST_DEVICE segment operator()(IndexType i) - { - auto kit = thrust::upper_bound(thrust::seq, begin, end, i); - auto k = thrust::distance(begin, kit); - auto pid = i + k - 1; - - return segment{point_begin[pid], point_begin[pid + 1]}; - } -}; - -/// Deduction guide for to_valid_segment_functor -template -to_valid_segment_functor(OffsetIterator, OffsetIterator, CoordinateIterator) - -> to_valid_segment_functor; - } // namespace detail } // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh b/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh index e064092a9..cc791c9ce 100644 --- a/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh +++ b/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -40,6 +41,8 @@ namespace detail { * `intersects` is an optional pointer to a boolean range where the `i`th element indicates the * `i`th output should be set to 0 and bypass distance computation. This argument is optional, if * set to nullopt, no distance computation will be bypassed. + * + * @note This kernel does not compute pairs that contains empty geometry. */ template __global__ void linestring_distance(MultiLinestringRange1 multilinestrings1, @@ -55,11 +58,14 @@ __global__ void linestring_distance(MultiLinestringRange1 multilinestrings1, if (!multilinestrings1.is_valid_segment_id(idx, part_idx)) continue; auto const geometry_idx = multilinestrings1.geometry_idx_from_part_idx(part_idx); + if (multilinestrings1[geometry_idx].is_empty() || multilinestrings2[geometry_idx].is_empty()) { + continue; + } + if (intersects.has_value() && intersects.value()[geometry_idx]) { distances_first[geometry_idx] = 0; continue; } - auto [a, b] = multilinestrings1.segment(idx); T min_distance_squared = std::numeric_limits::max(); diff --git a/cpp/include/cuspatial/detail/multilinestring_segment.cuh b/cpp/include/cuspatial/detail/multilinestring_segment.cuh new file mode 100644 index 000000000..ddcce9d4b --- /dev/null +++ b/cpp/include/cuspatial/detail/multilinestring_segment.cuh @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace cuspatial { +namespace detail { + +/** + * @internal + * @brief Functor that returns true if current value is greater than 0. + */ +template +struct greater_than_zero_functor { + __device__ IndexType operator()(IndexType x) const { return x > 0; } +}; + +/** + * @internal + * @brief Owning class to provide iterators to segments in a multilinestring range + * + * The owned memory in this struct is the vector `_non_empty_linestring_prefix_sum` of size equal to + * the number of linestrings in the multilinestring range plus 1. This vector holds the number + * of non empty linestrings that precedes the current linestring. + * + * This class is only meant for tracking the life time of the owned memory. To access the + * segment iterators, call `segment_range()` function to create a non-owning object of this class. + * + * For detailed explanation on the implementation of the segment iterators, see documentation + * of `multilinestring_segment_range`. + * + * @note To use this class with a multipolygon range, cast the multipolygon range as a + * multilinestring range. + * + * TODO: Optimization: for ranges that do not contain any empty linestrings, + * `_non_empty_linestring_prefix_sum` can replaced by a `counting_iterator`. + * + * @tparam MultilinestringRange The multilinestring range to initialize this class with. + */ +template +class multilinestring_segment_manager { + using index_t = iterator_value_type; + + public: + /** + * @brief Construct a new multilinestring segment object + * + * @note multilinestring_segment is always internal use, thus memory consumed is always + * temporary, therefore always use default device memory resource. + * + * @param parent The parent multilinestring object to construct from + * @param stream The stream to perform computation on + */ + multilinestring_segment_manager(MultilinestringRange parent, rmm::cuda_stream_view stream) + : _parent(parent), _non_empty_linestring_prefix_sum(parent.num_linestrings() + 1, stream) + { + auto offset_range = ::cuspatial::range{_parent.part_offset_begin(), _parent.part_offset_end()}; + auto count_begin = thrust::make_transform_iterator( + thrust::make_zip_iterator(offset_range.begin(), thrust::next(offset_range.begin())), + offset_pair_to_count_functor{}); + + auto count_greater_than_zero = + thrust::make_transform_iterator(count_begin, greater_than_zero_functor{}); + + zero_data_async( + _non_empty_linestring_prefix_sum.begin(), _non_empty_linestring_prefix_sum.end(), stream); + + thrust::inclusive_scan(rmm::exec_policy(stream), + count_greater_than_zero, + count_greater_than_zero + _parent.num_linestrings(), + thrust::next(_non_empty_linestring_prefix_sum.begin())); + + _num_segments = _parent.num_points() - _non_empty_linestring_prefix_sum.element( + _non_empty_linestring_prefix_sum.size() - 1, stream); + } + + /** + * @brief Return a non-owning `multilinestring_segment_range` object from this class + * + * @return multilinestring_segment_range + */ + auto segment_range() + { + auto index_range = ::cuspatial::range{_non_empty_linestring_prefix_sum.begin(), + _non_empty_linestring_prefix_sum.end()}; + return multilinestring_segment_range{ + _parent, index_range, _num_segments}; + } + + private: + MultilinestringRange _parent; + index_t _num_segments; + rmm::device_uvector _non_empty_linestring_prefix_sum; +}; + +} // namespace detail + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/range/multilinestring_range.cuh b/cpp/include/cuspatial/detail/range/multilinestring_range.cuh index 5983efc00..a73d423ac 100644 --- a/cpp/include/cuspatial/detail/range/multilinestring_range.cuh +++ b/cpp/include/cuspatial/detail/range/multilinestring_range.cuh @@ -16,14 +16,9 @@ #pragma once -#include -#include -#include -#include -#include - #include #include +#include #include #include #include @@ -31,7 +26,13 @@ #include #include +#include +#include +#include #include +#include +#include +#include #include #include @@ -115,13 +116,6 @@ multilinestring_range::num_points() return thrust::distance(_point_begin, _point_end); } -template -CUSPATIAL_HOST_DEVICE auto -multilinestring_range::num_segments() -{ - return num_points() - num_linestrings(); -} - template CUSPATIAL_HOST_DEVICE auto multilinestring_range::multilinestring_begin() @@ -231,23 +225,6 @@ CUSPATIAL_HOST_DEVICE auto multilinestring_range -CUSPATIAL_HOST_DEVICE auto multilinestring_range:: - multilinestring_segment_count_begin() -{ - auto n_point_linestring_pair_it = thrust::make_zip_iterator( - multilinestring_point_count_begin(), multilinestring_linestring_count_begin()); - return thrust::make_transform_iterator(n_point_linestring_pair_it, - detail::point_count_to_segment_count_functor{}); -} - -template -CUSPATIAL_HOST_DEVICE auto multilinestring_range:: - multilinestring_segment_count_end() -{ - return multilinestring_segment_count_begin() + num_multilinestrings(); -} - template CUSPATIAL_HOST_DEVICE auto multilinestring_range:: multilinestring_linestring_count_begin() @@ -264,34 +241,10 @@ CUSPATIAL_HOST_DEVICE auto multilinestring_range -CUSPATIAL_HOST_DEVICE auto -multilinestring_range::segment_begin() -{ - return detail::make_counting_transform_iterator( - 0, - detail::to_valid_segment_functor{ - this->segment_offset_begin(), this->segment_offset_end(), _point_begin}); -} - -template -CUSPATIAL_HOST_DEVICE auto -multilinestring_range::segment_end() -{ - return segment_begin() + num_segments(); -} - -template -CUSPATIAL_HOST_DEVICE auto -multilinestring_range::segment_offset_begin() -{ - return detail::make_counting_transform_iterator(0, detail::to_distance_iterator{_part_begin}); -} - -template -CUSPATIAL_HOST_DEVICE auto -multilinestring_range::segment_offset_end() +auto multilinestring_range::_segments( + rmm::cuda_stream_view stream) { - return segment_offset_begin() + thrust::distance(_part_begin, _part_end); + return multilinestring_segment_manager{*this, stream}; } template diff --git a/cpp/include/cuspatial/detail/range/multilinestring_segment_range.cuh b/cpp/include/cuspatial/detail/range/multilinestring_segment_range.cuh new file mode 100644 index 000000000..028756347 --- /dev/null +++ b/cpp/include/cuspatial/detail/range/multilinestring_segment_range.cuh @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace cuspatial { +namespace detail { + +/** + * @internal + * @brief Computes the offsets to the starting segment per linestring + * + * The point indices and segment indices are correlated, but in a different index space. + * For example: + * ``` + * {0, 3} + * {0, 3, 3, 6} + * {A, B, C, X, Y, Z} + * ``` + * + * ``` + * segments: AB BC XY YZ + * sid: 0 1 2 3 + * points: A B C X Y Z + * pid: 0 1 2 3 4 5 + * ``` + * + * The original {0, 3, 3, 6} offsets are in the point index space. For example: + * The first and past the last point of the first linestring is at point index 0 and 3 (A, X). + * The first and past the last point of the second linestring is at point index 3 and 3 (empty), + * and so on. + * + * The transformed segment offsets {0, 2, 2, 4} are in the segment index space. For example: + * The first and past the last segment of the first linestring is at segment index 0 and 2 ((AB), + * (XY)). + * The first and past the last segment of the second linestring is at segment index 2 and 2 + * (empty), and so on. + * + * @tparam OffsetIterator Iterator type to the offset + */ +template +struct point_offset_to_segment_offset { + OffsetIterator part_offset_begin; + CountIterator non_empty_linestrings_count_begin; + + template + CUSPATIAL_HOST_DEVICE auto operator()(IndexType i) + { + return part_offset_begin[i] - non_empty_linestrings_count_begin[i]; + } +}; + +/// Deduction guide +template +point_offset_to_segment_offset(OffsetIterator, CountIterator) + -> point_offset_to_segment_offset; + +/** + * @internal + * @brief Given a segment index, return the corresponding segment + * + * Given a segment index, first find its corresponding part index by performing a binary search in + * the segment offsets range. Then, skip the segment index by the number of non empty linestrings + * that precedes the current linestring to find point index to the first point of the segment. + * Dereference this point and the following point to construct the segment. + * + * @tparam OffsetIterator Iterator to the segment offsets + * @tparam CountIterator Iterator the the range of the prefix sum of non empty linestrings + * @tparam CoordinateIterator Iterator to the point range + */ +template +struct to_valid_segment_functor { + using element_t = iterator_vec_base_type; + + OffsetIterator segment_offset_begin; + OffsetIterator segment_offset_end; + CountIterator non_empty_partitions_begin; + CoordinateIterator point_begin; + + template + CUSPATIAL_HOST_DEVICE segment operator()(IndexType sid) + { + auto kit = + thrust::prev(thrust::upper_bound(thrust::seq, segment_offset_begin, segment_offset_end, sid)); + auto part_id = thrust::distance(segment_offset_begin, kit); + auto preceding_non_empty_linestrings = non_empty_partitions_begin[part_id]; + auto pid = sid + preceding_non_empty_linestrings; + + return segment{point_begin[pid], point_begin[pid + 1]}; + } +}; + +/// Deduction guide +template +to_valid_segment_functor(OffsetIterator, OffsetIterator, CountIterator, CoordinateIterator) + -> to_valid_segment_functor; + +/** + * @internal + * @brief A non-owning range of segments in a multilinestring + * + * A `multilinestring_segment_range` provide views into the segments of a multilinestring. + * The segments of a multilinestring have a near 1:1 mapping to the points of the multilinestring, + * except that the last point of a linestring and the first point of the next linestring do not + * form a valid segment. For example, the below multilinestring (points are denoted a letters): + * + * ``` + * {0, 2} + * {0, 3, 6} + * {A, B, C, X, Y, Z} + * ``` + * + * contains 6 points, but only 4 segments. AB, BC, XY and YZ. + * If we assign an index to all four segments, and an index to all points: + * + * ``` + * segments: AB BC XY YZ + * sid: 0 1 2 3 + * points: A B C X Y Z + * pid: 0 1 2 3 4 5 + * ``` + * + * Notice that if we "skip" the segment index by a few steps, it can correctly find the + * corresponding point index of the starting point of the segment. For example: skipping sid==0 (AB) + * by 0 steps, finds the starting point of A (pid==0) skipping sid==2 (XY) by 1 step, finds the + * starting point of X (pid==3) + * + * Intuitively, the *steps to skip* equals the number of linestrings that precedes the linestring + * that the current segment is in. This is because every linestring adds an "invalid" segment to the + * preceding linestring. However, consider the following edge case that contains empty linestrings: + * + * ``` + * {0, 3} + * {0, 3, 3, 6} + * {A, B, C, X, Y, Z} + * ``` + * + * For segment XY, there are 2 linestrings that precedes its linestring ((0, 3) and (3, 3)). + * However, we cannot skip the sid of XY by 2 to get its starting point index. This is because the + * empty linestring in between does not introduce the "invalid" segment. Therefore, the correct + * steps to skip equals the number of *non-empty* linestrings that precedes the current linestring + * that the segment is in. + * + * Concretely, with the above example: + * ``` + * segments: AB BC XY YZ + * sid: 0 1 2 3 + * num_preceding_non_empty_linestrings: 0 0 1 1 + * skipped sid (pid): 0 0 3 4 + * starting point: A B X Y + * ``` + * + * @tparam ParentRange The multilinestring range to construct from + * @tparam IndexRange The range to the prefix sum of the non empty linestring counts + */ +template +class multilinestring_segment_range { + using index_t = typename IndexRange::value_type; + + public: + multilinestring_segment_range(ParentRange parent, + IndexRange non_empty_geometry_prefix_sum, + index_t num_segments) + : _parent(parent), + _non_empty_geometry_prefix_sum(non_empty_geometry_prefix_sum), + _num_segments(num_segments) + { + } + + /// Returns the number of segments in the multilinestring + CUSPATIAL_HOST_DEVICE index_t num_segments() { return _num_segments; } + + /// Returns starting iterator to the range of the starting segment index per + /// multilinestring or multipolygon + CUSPATIAL_HOST_DEVICE auto multigeometry_offset_begin() + { + return thrust::make_permutation_iterator(_per_linestring_offset_begin(), + _parent.geometry_offsets_begin()); + } + + /// Returns end iterator to the range of the starting segment index per multilinestring + /// or multipolygon + CUSPATIAL_HOST_DEVICE auto multigeometry_offset_end() + { + return multigeometry_offset_begin() + _parent.num_multilinestrings() + 1; + } + + /// Returns starting iterator to the range of the number of segments per multilinestring of + /// multipolygon + CUSPATIAL_HOST_DEVICE auto multigeometry_count_begin() + { + auto zipped_offset_it = thrust::make_zip_iterator(multigeometry_offset_begin(), + thrust::next(multigeometry_offset_begin())); + + return thrust::make_transform_iterator(zipped_offset_it, offset_pair_to_count_functor{}); + } + + /// Returns end iterator to the range of the number of segments per multilinestring of + /// multipolygon + CUSPATIAL_HOST_DEVICE auto multigeometry_count_end() + { + return multigeometry_count_begin() + _parent.num_multilinestrings(); + } + + /// Returns the iterator to the first segment of the geometry range + /// See `to_valid_segment_functor` for implementation detail + CUSPATIAL_HOST_DEVICE auto begin() + { + return make_counting_transform_iterator( + 0, + to_valid_segment_functor{_per_linestring_offset_begin(), + _per_linestring_offset_end(), + _non_empty_geometry_prefix_sum.begin(), + _parent.point_begin()}); + } + + /// Returns the iterator to the past the last segment of the geometry range + CUSPATIAL_HOST_DEVICE auto end() { return begin() + _num_segments; } + + private: + ParentRange _parent; + IndexRange _non_empty_geometry_prefix_sum; + index_t _num_segments; + + /// Returns begin iterator to the index that points to the starting index for each linestring + /// See documentation of `to_segment_offset_iterator` for detail. + CUSPATIAL_HOST_DEVICE auto _per_linestring_offset_begin() + { + return make_counting_transform_iterator( + 0, + point_offset_to_segment_offset{_parent.part_offset_begin(), + _non_empty_geometry_prefix_sum.begin()}); + } + + /// Returns end iterator to the index that points to the starting index for each linestring + CUSPATIAL_HOST_DEVICE auto _per_linestring_offset_end() + { + return _per_linestring_offset_begin() + _non_empty_geometry_prefix_sum.size(); + } +}; + +template +multilinestring_segment_range(ParentRange, IndexRange, typename IndexRange::value_type, bool) + -> multilinestring_segment_range; + +} // namespace detail + +} // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/range/multipolygon_range.cuh b/cpp/include/cuspatial/detail/range/multipolygon_range.cuh index 85781e55b..a76803229 100644 --- a/cpp/include/cuspatial/detail/range/multipolygon_range.cuh +++ b/cpp/include/cuspatial/detail/range/multipolygon_range.cuh @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -27,8 +28,11 @@ #include #include +#include + #include #include +#include #include #include #include @@ -154,16 +158,6 @@ multipolygon_range::n return thrust::distance(_point_begin, _point_end); } -template -CUSPATIAL_HOST_DEVICE auto -multipolygon_range::num_segments() -{ - return num_points() - num_rings(); -} - template :: return multipolygon_ring_count_begin() + num_multipolygons(); } -template -CUSPATIAL_HOST_DEVICE auto -multipolygon_range:: - multipolygon_segment_count_begin() -{ - auto multipolygon_point_ring_count_it = - thrust::make_zip_iterator(multipolygon_point_count_begin(), multipolygon_ring_count_begin()); - - return thrust::make_transform_iterator(multipolygon_point_ring_count_it, - detail::point_count_to_segment_count_functor{}); -} - -template -CUSPATIAL_HOST_DEVICE auto -multipolygon_range:: - multipolygon_segment_count_end() -{ - return multipolygon_segment_count_begin() + num_multipolygons(); -} - template -CUSPATIAL_HOST_DEVICE auto -multipolygon_range::segment_begin() -{ - return detail::make_counting_transform_iterator( - 0, - detail::to_valid_segment_functor{ - this->subtracted_ring_begin(), this->subtracted_ring_end(), _point_begin}); -} - -template -CUSPATIAL_HOST_DEVICE auto -multipolygon_range::segment_end() -{ - return segment_begin() + num_segments(); -} - -template -CUSPATIAL_HOST_DEVICE auto -multipolygon_range:: - subtracted_ring_begin() -{ - return detail::make_counting_transform_iterator(0, detail::to_distance_iterator{_ring_begin}); -} - -template -CUSPATIAL_HOST_DEVICE auto -multipolygon_range::subtracted_ring_end() +auto multipolygon_range::_segments( + rmm::cuda_stream_view stream) { - return subtracted_ring_begin() + thrust::distance(_ring_begin, _ring_end); + auto multilinestring_range = this->as_multilinestring_range(); + return multilinestring_segment_manager{multilinestring_range, stream}; } template 0, \ - "Polygon offsets must contain at least one (1) value"); \ - CUSPATIAL_HOST_DEVICE_EXPECTS(num_linestring_points >= 2 * (num_linestring_offsets - 1), \ - "Each linestring must have at least two vertices"); + "Polygon offsets must contain at least one (1) value"); /** * @brief Macro for validating the data array sizes for multilinestrings. @@ -46,7 +46,6 @@ * Raises an exception if any of the following are false: * - The number of multilinestring offsets is greater than zero. * - The number of linestring offsets is greater than zero. - * - There are at least two vertices per linestring offset. * * Multilinestrings follow [GeoArrow data layout][1]. Offsets arrays have one more element than the * number of items in the array. The last offset is always the sum of the previous offset and the @@ -69,8 +68,6 @@ * Raises an exception if any of the following are false: * - The number of polygon offsets is greater than zero. * - The number of ring offsets is greater than zero. - * - There is at least one ring offset per polygon offset. - * - There are at least four vertices per ring offset. * * Polygons follow [GeoArrow data layout][1]. Offsets arrays (polygons and rings) have one more * element than the number of items in the array. The last offset is always the sum of the previous @@ -78,22 +75,21 @@ * last ring offset plus the number of rings in the last polygon. See * [Arrow Variable-Size Binary layout](2). Note that an empty list still has one offset: {0}. * - * Rings are assumed to be closed (closed means the first and last vertices of - * each ring are equal). Therefore rings must have at least 4 vertices. + * The following are not explicitly checked in this macro, but is always assumed in cuspatial: + * + * 1. Polygon can contain zero or more rings. A polygon with zero rings is an empty polygon. + * 2. Rings are assumed to be closed (closed means the first and last vertices of each ring are + * equal). Rings can also be empty. Therefore each ring must contain zero or four or more vertices. * * [1]: https://github.com/geoarrow/geoarrow/blob/main/format.md * [2]: https://arrow.apache.org/docs/format/Columnar.html#variable-size-binary-layout */ -#define CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( \ - num_poly_points, num_poly_offsets, num_poly_ring_offsets) \ - CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_offsets > 0, \ - "Polygon offsets must contain at least one (1) value"); \ - CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_ring_offsets > 0, \ - "Polygon ring offsets must contain at least one (1) value"); \ - CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_ring_offsets >= num_poly_offsets, \ - "Each polygon must have at least one (1) ring"); \ - CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_points >= 4 * (num_poly_ring_offsets - 1), \ - "Each ring must have at least four (4) vertices"); +#define CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( \ + num_poly_points, num_poly_offsets, num_poly_ring_offsets) \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_offsets > 0, \ + "Polygon offsets must contain at least one (1) value"); \ + CUSPATIAL_HOST_DEVICE_EXPECTS(num_poly_ring_offsets > 0, \ + "Polygon ring offsets must contain at least one (1) value"); /** * @brief Macro for validating the data array sizes for a multipolygon. @@ -102,8 +98,6 @@ * - The number of multipolygon offsets is greater than zero. * - The number of polygon offsets is greater than zero. * - The number of ring offsets is greater than zero. - * - There is at least one ring offset per polygon offset. - * - There are at least four vertices per ring offset. * * MultiPolygons follow [GeoArrow data layout][1]. Offsets arrays (polygons and rings) have one more * element than the number of items in the array. The last offset is always the sum of the previous @@ -111,8 +105,12 @@ * last ring offset plus the number of rings in the last polygon. See * [Arrow Variable-Size Binary layout](2). Note that an empty list still has one offset: {0}. * - * Rings are assumed to be closed (closed means the first and last vertices of - * each ring are equal). Therefore rings must have at least 4 vertices. + * The following are not explicitly checked in this macro, but is always assumed in cuspatial: + * + * 1. Polygon can contain zero or more rings. A polygon with zero rings is an empty polygon. + * 2. Rings are assumed to be closed (closed means the first and last vertices of each ring are + * equal). Rings can also be empty. Therefore each ring must contain zero or four or more + * coordinates. * * [1]: https://github.com/geoarrow/geoarrow/blob/main/format.md * [2]: https://arrow.apache.org/docs/format/Columnar.html#variable-size-binary-layout diff --git a/cpp/include/cuspatial/geometry_collection/multilinestring_ref.cuh b/cpp/include/cuspatial/geometry_collection/multilinestring_ref.cuh index 872135f72..36304a7bc 100644 --- a/cpp/include/cuspatial/geometry_collection/multilinestring_ref.cuh +++ b/cpp/include/cuspatial/geometry_collection/multilinestring_ref.cuh @@ -38,6 +38,9 @@ class multilinestring_ref { /// Return the number of linestrings in the multilinestring. CUSPATIAL_HOST_DEVICE auto size() const { return num_linestrings(); } + /// Return true if this multilinestring contains 0 linestrings. + CUSPATIAL_HOST_DEVICE bool is_empty() const { return num_linestrings() == 0; } + /// Return iterator to the first linestring. CUSPATIAL_HOST_DEVICE auto part_begin() const; /// Return iterator to one past the last linestring. diff --git a/cpp/include/cuspatial/geometry_collection/multipolygon_ref.cuh b/cpp/include/cuspatial/geometry_collection/multipolygon_ref.cuh index e4ff5010f..d9972d9b1 100644 --- a/cpp/include/cuspatial/geometry_collection/multipolygon_ref.cuh +++ b/cpp/include/cuspatial/geometry_collection/multipolygon_ref.cuh @@ -41,6 +41,9 @@ class multipolygon_ref { /// Return the number of polygons in the multipolygon. CUSPATIAL_HOST_DEVICE auto size() const { return num_polygons(); } + /// Returns true if the multipolygon contains 0 geometries. + CUSPATIAL_HOST_DEVICE bool is_empty() const { return num_polygons() == 0; } + /// Return iterator to the first polygon. CUSPATIAL_HOST_DEVICE auto part_begin() const; /// Return iterator to one past the last polygon. diff --git a/cpp/include/cuspatial/range/multilinestring_range.cuh b/cpp/include/cuspatial/range/multilinestring_range.cuh index b79b2ae77..b4bb6eaf5 100644 --- a/cpp/include/cuspatial/range/multilinestring_range.cuh +++ b/cpp/include/cuspatial/range/multilinestring_range.cuh @@ -23,6 +23,8 @@ #include #include +#include + #include namespace cuspatial { @@ -81,9 +83,6 @@ class multilinestring_range { /// Return the total number of points in the array. CUSPATIAL_HOST_DEVICE auto num_points(); - /// Return the total number of segments in the array. - CUSPATIAL_HOST_DEVICE auto num_segments(); - /// Return the iterator to the first multilinestring in the range. CUSPATIAL_HOST_DEVICE auto multilinestring_begin(); @@ -154,23 +153,16 @@ class multilinestring_range { /// Returns an iterator to the counts of segments per multilinestring CUSPATIAL_HOST_DEVICE auto multilinestring_point_count_end(); - /// Returns an iterator to the counts of segments per multilinestring - CUSPATIAL_HOST_DEVICE auto multilinestring_segment_count_begin(); - - /// Returns an iterator to the counts of points per multilinestring - CUSPATIAL_HOST_DEVICE auto multilinestring_segment_count_end(); - /// Returns an iterator to the counts of points per multilinestring CUSPATIAL_HOST_DEVICE auto multilinestring_linestring_count_begin(); /// Returns an iterator to the counts of points per multilinestring CUSPATIAL_HOST_DEVICE auto multilinestring_linestring_count_end(); - /// Returns an iterator to the start of the segment - CUSPATIAL_HOST_DEVICE auto segment_begin(); - - /// Returns an iterator to the end of the segment - CUSPATIAL_HOST_DEVICE auto segment_end(); + /// @internal + /// Returns the owning class that provides views into the segments of the multilinestring range + /// Can only be constructed on host + auto _segments(rmm::cuda_stream_view); /// Returns the `multilinestring_idx`th multilinestring in the range. template @@ -198,9 +190,6 @@ class multilinestring_range { VecIterator _point_begin; VecIterator _point_end; - CUSPATIAL_HOST_DEVICE auto segment_offset_begin(); - CUSPATIAL_HOST_DEVICE auto segment_offset_end(); - private: /// @internal /// Return the iterator to the part index where the point locates. diff --git a/cpp/include/cuspatial/range/multipolygon_range.cuh b/cpp/include/cuspatial/range/multipolygon_range.cuh index 1b8947345..99b2843b2 100644 --- a/cpp/include/cuspatial/range/multipolygon_range.cuh +++ b/cpp/include/cuspatial/range/multipolygon_range.cuh @@ -16,14 +16,16 @@ #pragma once -#include - #include #include #include #include #include +#include + +#include + namespace cuspatial { /** @@ -96,9 +98,6 @@ class multipolygon_range { /// Return the total number of points in the array. CUSPATIAL_HOST_DEVICE auto num_points(); - /// Return the total number of segments in the array. - CUSPATIAL_HOST_DEVICE auto num_segments(); - /// Return the iterator to the first multipolygon in the range. CUSPATIAL_HOST_DEVICE auto multipolygon_begin(); @@ -117,6 +116,12 @@ class multipolygon_range { /// Return the iterator to the one past the last point in the range. CUSPATIAL_HOST_DEVICE auto point_end(); + /// Return the iterator to the first geometry offset in the range. + CUSPATIAL_HOST_DEVICE auto geometry_offsets_begin() { return _part_begin; } + + /// Return the iterator to the one past the last geometry offset in the range. + CUSPATIAL_HOST_DEVICE auto geometry_offsets_end() { return _part_end; } + /// Return the iterator to the first part offset in the range. CUSPATIAL_HOST_DEVICE auto part_offset_begin() { return _part_begin; } @@ -175,16 +180,10 @@ class multipolygon_range { /// Returns the one past the iterator to the number of rings of the last multipolygon CUSPATIAL_HOST_DEVICE auto multipolygon_ring_count_end(); - /// Returns an iterator to the number of segments of the first multipolygon - CUSPATIAL_HOST_DEVICE auto multipolygon_segment_count_begin(); - /// Returns the one past the iterator to the number of segments of the last multipolygon - CUSPATIAL_HOST_DEVICE auto multipolygon_segment_count_end(); - - /// Returns an iterator to the start of the segment - CUSPATIAL_HOST_DEVICE auto segment_begin(); - - /// Returns an iterator to the end of the segment - CUSPATIAL_HOST_DEVICE auto segment_end(); + /// @internal + /// Returns the owning class that provides views into the segments of the multipolygon range + /// Can only be constructed on host. + auto _segments(rmm::cuda_stream_view); /// Range Casting @@ -205,10 +204,6 @@ class multipolygon_range { VecIterator _point_begin; VecIterator _point_end; - // TODO: find a better name - CUSPATIAL_HOST_DEVICE auto subtracted_ring_begin(); - CUSPATIAL_HOST_DEVICE auto subtracted_ring_end(); - private: template CUSPATIAL_HOST_DEVICE bool is_valid_segment_id(IndexType1 segment_idx, IndexType2 ring_idx); diff --git a/cpp/include/cuspatial_test/vector_equality.hpp b/cpp/include/cuspatial_test/vector_equality.hpp index 5d72f6228..4abde035d 100644 --- a/cpp/include/cuspatial_test/vector_equality.hpp +++ b/cpp/include/cuspatial_test/vector_equality.hpp @@ -37,7 +37,7 @@ namespace cuspatial { namespace test { /** - * @brief Compare two floats are close within N ULPs + * @brief Compare two floats are close within N ULPs, nans are treated equal * * N is predefined by GoogleTest * https://google.github.io/googletest/reference/assertions.html#EXPECT_FLOAT_EQ @@ -46,22 +46,22 @@ template auto floating_eq_by_ulp(T val) { if constexpr (std::is_same_v) { - return ::testing::FloatEq(val); + return ::testing::NanSensitiveFloatEq(val); } else { - return ::testing::DoubleEq(val); + return ::testing::NanSensitiveDoubleEq(val); } } /** - * @brief Compare two floats are close within `abs_error` + * @brief Compare two floats are close within `abs_error`, nans are treated equal */ template auto floating_eq_by_abs_error(T val, T abs_error) { if constexpr (std::is_same_v) { - return ::testing::FloatNear(val, abs_error); + return ::testing::NanSensitiveFloatNear(val, abs_error); } else { - return ::testing::DoubleNear(val, abs_error); + return ::testing::NanSensitiveDoubleNear(val, abs_error); } } diff --git a/cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cpp b/cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cpp index f933a2459..07f6ac2f0 100644 --- a/cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cpp +++ b/cpp/tests/bounding_boxes/polygon_bounding_boxes_test.cpp @@ -55,19 +55,6 @@ TEST_F(PolygonBoundingBoxErrorTest, test_empty) } } -TEST_F(PolygonBoundingBoxErrorTest, test_more_polys_than_rings) -{ - using namespace cudf::test; - - fixed_width_column_wrapper poly_offsets({0, 1, 2}); - fixed_width_column_wrapper ring_offsets({0, 4}); - fixed_width_column_wrapper x({2.488450, 1.333584, 3.460720, 2.488450}); - fixed_width_column_wrapper y({5.856625, 5.008840, 4.586599, 5.856625}); - - EXPECT_THROW(cuspatial::polygon_bounding_boxes(poly_offsets, ring_offsets, x, y, 0.0), - cuspatial::logic_error); -} - TEST_F(PolygonBoundingBoxErrorTest, type_mismatch) { using namespace cudf::test; @@ -130,16 +117,3 @@ TEST_F(PolygonBoundingBoxErrorTest, vertex_size_mismatch) EXPECT_THROW(cuspatial::polygon_bounding_boxes(poly_offsets, ring_offsets, x, y, 0.0), cuspatial::logic_error); } - -TEST_F(PolygonBoundingBoxErrorTest, ring_too_small) -{ - using namespace cudf::test; - - fixed_width_column_wrapper poly_offsets({0, 1}); - fixed_width_column_wrapper ring_offsets({0, 2}); - fixed_width_column_wrapper x({2.488450, 1.333584}); - fixed_width_column_wrapper y({5.856625, 5.008840}); - - EXPECT_THROW(cuspatial::polygon_bounding_boxes(poly_offsets, ring_offsets, x, y, 0.0), - cuspatial::logic_error); -} diff --git a/cpp/tests/distance/linestring_polygon_distance_test.cu b/cpp/tests/distance/linestring_polygon_distance_test.cu index bf74b731b..7cc3b6b55 100644 --- a/cpp/tests/distance/linestring_polygon_distance_test.cu +++ b/cpp/tests/distance/linestring_polygon_distance_test.cu @@ -413,3 +413,108 @@ TYPED_TEST(PairwiseLinestringPolygonDistanceTest, TwoPairsCrosses) P{5, 5}}, {std::sqrt(T{2}), 0.0}); } + +// Empty Geometries Tests + +/// Empty MultiLinestring vs Non-empty multipolygons +TYPED_TEST(PairwiseLinestringPolygonDistanceTest, ThreePairEmptyMultiLinestring) +{ + using T = TypeParam; + using P = vec_2d; + + CUSPATIAL_RUN_TEST(this->run_single, + + {0, 1, 1, 2}, + {0, 4, 7}, + {P{0, 0}, P{1, 1}, P{2, 2}, P{3, 3}, P{10, 10}, P{11, 11}, P{12, 12}}, + + {0, 1, 2, 3}, + {0, 1, 2, 3}, + {0, 4, 9, 14}, + {P{-1, -1}, + P{-2, -2}, + P{-2, -1}, + P{-1, -1}, + + P{-20, -20}, + P{-20, -21}, + P{-21, -21}, + P{-21, -20}, + P{-20, -20}, + + P{-10, -10}, + P{-10, -11}, + P{-11, -11}, + P{-11, -10}, + P{-10, -10}}, + + {std::sqrt(T{2}), std::numeric_limits::quiet_NaN(), 20 * std::sqrt(T{2})}); +} + +/// Non-empty MultiLinestring vs Empty multipolygons +TYPED_TEST(PairwiseLinestringPolygonDistanceTest, ThreePairEmptyMultiPolygon) +{ + using T = TypeParam; + using P = vec_2d; + + CUSPATIAL_RUN_TEST(this->run_single, + + {0, 1, 2, 3}, + {0, 4, 7, 10}, + {P{0, 0}, + P{1, 1}, + P{2, 2}, + P{3, 3}, + P{20, 20}, + P{21, 21}, + P{22, 22}, + P{10, 10}, + P{11, 11}, + P{12, 12}}, + + {0, 1, 1, 2}, + {0, 1, 2}, + {0, 4, 9}, + {P{-1, -1}, + P{-2, -2}, + P{-2, -1}, + P{-1, -1}, + + P{-10, -10}, + P{-10, -11}, + P{-11, -11}, + P{-11, -10}, + P{-10, -10}}, + {std::sqrt(T{2}), std::numeric_limits::quiet_NaN(), 20 * std::sqrt(T{2})}); +} + +/// FIXME: Empty MultiLinestring vs Empty multipolygons +/// This example fails at distance util, where point-polyogn intersection kernel doesn't handle +/// empty multipoint/multipolygons. +TYPED_TEST(PairwiseLinestringPolygonDistanceTest, + DISABLED_ThreePairEmptyMultiLineStringEmptyMultiPolygon) +{ + using T = TypeParam; + using P = vec_2d; + + CUSPATIAL_RUN_TEST(this->run_single, + + {0, 1, 1, 3}, + {0, 4, 7}, + {P{0, 0}, P{1, 1}, P{2, 2}, P{3, 3}, P{10, 10}, P{11, 11}, P{12, 12}}, + + {0, 1, 1, 2}, + {0, 1, 2, 3}, + {0, 4, 9, 14}, + {P{-1, -1}, + P{-2, -2}, + P{-2, -1}, + P{-1, -1}, + + P{-10, -10}, + P{-10, -11}, + P{-11, -11}, + P{-11, -10}, + P{-10, -10}}, + {std::sqrt(T{2}), std::numeric_limits::quiet_NaN(), 20 * std::sqrt(T{2})}); +} diff --git a/cpp/tests/point_in_polygon/point_in_polygon_test.cpp b/cpp/tests/point_in_polygon/point_in_polygon_test.cpp index 42b15fc0e..640de0f30 100644 --- a/cpp/tests/point_in_polygon/point_in_polygon_test.cpp +++ b/cpp/tests/point_in_polygon/point_in_polygon_test.cpp @@ -123,23 +123,6 @@ TEST_F(PointInPolygonErrorTest, EmptyPolygonOffsets) cuspatial::logic_error); } -TEST_F(PointInPolygonErrorTest, TriangleUnclosedNotEnoughPoints) -{ - using T = double; - - auto test_point_xs = wrapper({0.0, 1.0}); - auto test_point_ys = wrapper({0.0, 1.0}); - auto poly_offsets = wrapper({0, 1}); - auto poly_ring_offsets = wrapper({0, 3}); - auto poly_point_xs = wrapper({0.0, 1.0, 0.0}); - auto poly_point_ys = wrapper({1.0, 0.0, -1.0}); - - EXPECT_THROW( - cuspatial::point_in_polygon( - test_point_xs, test_point_ys, poly_offsets, poly_ring_offsets, poly_point_xs, poly_point_ys), - cuspatial::logic_error); -} - TEST_F(PointInPolygonErrorTest, EmptyTestPointsReturnsEmpty) { using T = double; diff --git a/cpp/tests/range/multilinestring_range_test.cu b/cpp/tests/range/multilinestring_range_test.cu index ec374ef8f..250e88355 100644 --- a/cpp/tests/range/multilinestring_range_test.cu +++ b/cpp/tests/range/multilinestring_range_test.cu @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include #include @@ -38,11 +39,13 @@ struct MultilinestringRangeTest : public BaseFixture { { auto multilinestring_array = make_multilinestring_array(geometry_offset, part_offset, coordinates); + auto rng = multilinestring_array.range(); + auto segments = rng._segments(stream()); + auto segments_range = segments.segment_range(); - auto rng = multilinestring_array.range(); - - rmm::device_uvector> got(rng.num_segments(), stream()); - thrust::copy(rmm::exec_policy(stream()), rng.segment_begin(), rng.segment_end(), got.begin()); + rmm::device_uvector> got(segments_range.num_segments(), stream()); + thrust::copy( + rmm::exec_policy(stream()), segments_range.begin(), segments_range.end(), got.begin()); auto d_expected = thrust::device_vector>(expected.begin(), expected.end()); CUSPATIAL_EXPECT_VEC2D_PAIRS_EQUIVALENT(d_expected, got); @@ -76,15 +79,39 @@ struct MultilinestringRangeTest : public BaseFixture { { auto multilinestring_array = make_multilinestring_array(geometry_offset, part_offset, coordinates); + auto rng = multilinestring_array.range(); + auto segments = rng._segments(stream()); + auto segments_range = segments.segment_range(); auto d_expected = thrust::device_vector(expected.begin(), expected.end()); - auto rng = multilinestring_array.range(); - rmm::device_uvector got(rng.num_multilinestrings(), stream()); thrust::copy(rmm::exec_policy(stream()), - rng.multilinestring_segment_count_begin(), - rng.multilinestring_segment_count_end(), + segments_range.multigeometry_count_begin(), + segments_range.multigeometry_count_end(), + got.begin()); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(d_expected, got); + } + + void run_multilinestring_segment_offset_test(std::initializer_list geometry_offset, + std::initializer_list part_offset, + std::initializer_list> coordinates, + std::initializer_list expected) + { + auto multilinestring_array = + make_multilinestring_array(geometry_offset, part_offset, coordinates); + auto rng = multilinestring_array.range(); + auto segments = rng._segments(stream()); + auto segments_range = segments.segment_range(); + + auto d_expected = thrust::device_vector(expected.begin(), expected.end()); + + rmm::device_uvector got(rng.num_multilinestrings() + 1, stream()); + + thrust::copy(rmm::exec_policy(stream()), + segments_range.multigeometry_offset_begin(), + segments_range.multigeometry_offset_end(), got.begin()); CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(d_expected, got); @@ -190,22 +217,26 @@ TYPED_TEST(MultilinestringRangeTest, SegmentIteratorManyPairTest) CUSPATIAL_RUN_TEST(this->run_segment_test_single, {0, 1, 2, 3}, {0, 6, 11, 14}, - {P{0, 0}, - P{1, 1}, - P{2, 2}, - P{3, 3}, - P{4, 4}, - P{5, 5}, - - P{10, 10}, - P{11, 11}, - P{12, 12}, - P{13, 13}, - P{14, 14}, - - P{20, 20}, - P{21, 21}, - P{22, 22}}, + { + + P{0, 0}, + P{1, 1}, + P{2, 2}, + P{3, 3}, + P{4, 4}, + P{5, 5}, + + P{10, 10}, + P{11, 11}, + P{12, 12}, + P{13, 13}, + P{14, 14}, + + P{20, 20}, + P{21, 21}, + P{22, 22} + + }, {S{P{0, 0}, P{1, 1}}, S{P{1, 1}, P{2, 2}}, @@ -220,8 +251,7 @@ TYPED_TEST(MultilinestringRangeTest, SegmentIteratorManyPairTest) S{P{21, 21}, P{22, 22}}}); } -/// FIXME: Currently, segment iterator doesn't handle empty linestrings. -TYPED_TEST(MultilinestringRangeTest, DISABLED_SegmentIteratorWithEmptyLineTest) +TYPED_TEST(MultilinestringRangeTest, SegmentIteratorWithEmptyLineTest) { using T = TypeParam; using P = vec_2d; @@ -235,6 +265,38 @@ TYPED_TEST(MultilinestringRangeTest, DISABLED_SegmentIteratorWithEmptyLineTest) {S{P{0, 0}, P{1, 1}}, S{P{1, 1}, P{2, 2}}, S{P{10, 10}, P{11, 11}}, S{P{11, 11}, P{12, 12}}}); } +TYPED_TEST(MultilinestringRangeTest, SegmentIteratorWithEmptyMultiLineStringTest) +{ + using T = TypeParam; + using P = vec_2d; + using S = segment; + + CUSPATIAL_RUN_TEST( + this->run_segment_test_single, + {0, 1, 1, 2}, + {0, 3, 6}, + {P{0, 0}, P{1, 1}, P{2, 2}, P{10, 10}, P{11, 11}, P{12, 12}}, + {S{P{0, 0}, P{1, 1}}, S{P{1, 1}, P{2, 2}}, S{P{10, 10}, P{11, 11}}, S{P{11, 11}, P{12, 12}}}); +} + +TYPED_TEST(MultilinestringRangeTest, SegmentIteratorWithEmptyMultiLineStringTest2) +{ + using T = TypeParam; + using P = vec_2d; + using S = segment; + + CUSPATIAL_RUN_TEST(this->run_segment_test_single, + + {0, 1, 1, 2}, + {0, 4, 7}, + {P{0, 0}, P{1, 1}, P{2, 2}, P{3, 3}, P{10, 10}, P{11, 11}, P{12, 12}}, + {S{P{0, 0}, P{1, 1}}, + S{P{1, 1}, P{2, 2}}, + S{P{2, 2}, P{3, 3}}, + S{P{10, 10}, P{11, 11}}, + S{P{11, 11}, P{12, 12}}}); +} + TYPED_TEST(MultilinestringRangeTest, PerMultilinestringCountTest) { using T = TypeParam; @@ -271,8 +333,7 @@ TYPED_TEST(MultilinestringRangeTest, MultilinestringSegmentCountTest) this->run_multilinestring_segment_count_test, {0, 1}, {0, 3}, {P{0, 0}, P{1, 1}, P{2, 2}}, {2}); } -// FIXME: contains empty linestring -TYPED_TEST(MultilinestringRangeTest, DISABLED_MultilinestringSegmentCountTest2) +TYPED_TEST(MultilinestringRangeTest, MultilinestringSegmentCountTest2) { using T = TypeParam; using P = vec_2d; @@ -311,8 +372,8 @@ TYPED_TEST(MultilinestringRangeTest, MultilinestringSegmentCountTest4) {2, 2}); } -// FIXME: contains empty linestring -TYPED_TEST(MultilinestringRangeTest, DISABLED_MultilinestringSegmentCountTest5) +// contains empty linestring +TYPED_TEST(MultilinestringRangeTest, MultilinestringSegmentCountTest5) { using T = TypeParam; using P = vec_2d; @@ -325,6 +386,48 @@ TYPED_TEST(MultilinestringRangeTest, DISABLED_MultilinestringSegmentCountTest5) {2, 0, 2}); } +// contains empty multilinestring +TYPED_TEST(MultilinestringRangeTest, MultilinestringSegmentCountTest6) +{ + using T = TypeParam; + using P = vec_2d; + using S = segment; + + CUSPATIAL_RUN_TEST(this->run_multilinestring_segment_count_test, + {0, 1, 1, 2}, + {0, 3, 6}, + {P{0, 0}, P{1, 1}, P{2, 2}, P{10, 10}, P{11, 11}, P{12, 12}}, + {2, 0, 2}); +} + +// contains empty multilinestring +TYPED_TEST(MultilinestringRangeTest, MultilinestringSegmentCountTest7) +{ + using T = TypeParam; + using P = vec_2d; + using S = segment; + + CUSPATIAL_RUN_TEST(this->run_multilinestring_segment_count_test, + {0, 1, 1, 2}, + {0, 4, 7}, + {P{0, 0}, P{1, 1}, P{2, 2}, P{3, 3}, P{10, 10}, P{11, 11}, P{12, 12}}, + {3, 0, 2}); +} + +// contains empty multilinestring +TYPED_TEST(MultilinestringRangeTest, MultilinestringSegmentOffsetTest) +{ + using T = TypeParam; + using P = vec_2d; + using S = segment; + + CUSPATIAL_RUN_TEST(this->run_multilinestring_segment_offset_test, + {0, 1, 1, 2}, + {0, 4, 7}, + {P{0, 0}, P{1, 1}, P{2, 2}, P{3, 3}, P{10, 10}, P{11, 11}, P{12, 12}}, + {0, 3, 3, 5}); +} + TYPED_TEST(MultilinestringRangeTest, MultilinestringLinestringCountTest) { using T = TypeParam; diff --git a/cpp/tests/range/multipolygon_range_test.cu b/cpp/tests/range/multipolygon_range_test.cu index 90ffa7e18..2fe133945 100644 --- a/cpp/tests/range/multipolygon_range_test.cu +++ b/cpp/tests/range/multipolygon_range_test.cu @@ -33,19 +33,23 @@ using namespace cuspatial::test; template struct MultipolygonRangeTest : public BaseFixture { - void run_multipolygon_segment_iterator_single(std::initializer_list geometry_offset, - std::initializer_list part_offset, - std::initializer_list ring_offset, - std::initializer_list> coordinates, - std::initializer_list> expected) + void run_multipolygon_segment_method_iterator_single( + std::initializer_list geometry_offset, + std::initializer_list part_offset, + std::initializer_list ring_offset, + std::initializer_list> coordinates, + std::initializer_list> expected) { auto multipolygon_array = make_multipolygon_array(geometry_offset, part_offset, ring_offset, coordinates); - auto rng = multipolygon_array.range(); + auto rng = multipolygon_array.range(); + auto segments = rng._segments(stream()); + auto segment_range = segments.segment_range(); - auto got = rmm::device_uvector>(rng.num_segments(), stream()); + auto got = rmm::device_uvector>(segment_range.num_segments(), stream()); - thrust::copy(rmm::exec_policy(stream()), rng.segment_begin(), rng.segment_end(), got.begin()); + thrust::copy( + rmm::exec_policy(stream()), segment_range.begin(), segment_range.end(), got.begin()); auto d_expected = thrust::device_vector>(expected.begin(), expected.end()); @@ -76,7 +80,7 @@ struct MultipolygonRangeTest : public BaseFixture { CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(got, d_expected); } - void run_multipolygon_segment_count_single( + void run_multipolygon_segment_method_count_single( std::initializer_list geometry_offset, std::initializer_list part_offset, std::initializer_list ring_offset, @@ -85,13 +89,15 @@ struct MultipolygonRangeTest : public BaseFixture { { auto multipolygon_array = make_multipolygon_array(geometry_offset, part_offset, ring_offset, coordinates); - auto rng = multipolygon_array.range(); + auto rng = multipolygon_array.range(); + auto segments = rng._segments(stream()); + auto segment_range = segments.segment_range(); auto got = rmm::device_uvector(rng.num_multipolygons(), stream()); thrust::copy(rmm::exec_policy(stream()), - rng.multipolygon_segment_count_begin(), - rng.multipolygon_segment_count_end(), + segment_range.multigeometry_count_begin(), + segment_range.multigeometry_count_end(), got.begin()); auto d_expected = thrust::device_vector(expected_segment_counts.begin(), @@ -158,17 +164,17 @@ TYPED_TEST(MultipolygonRangeTest, SegmentIterators) using T = TypeParam; using P = vec_2d; using S = segment; - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_iterator_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, {0, 1}, {0, 1}, {0, 4}, {{0, 0}, {1, 0}, {1, 1}, {0, 0}}, - {S{P{0, 0}, P{1, 0}}, S{P{1, 0}, P{1, 1}}, S{P{1, 1}, P{0, 0}}}); + {S{{0, 0}, P{1, 0}}, S{P{1, 0}, P{1, 1}}, S{P{1, 1}, P{0, 0}}}); } TYPED_TEST(MultipolygonRangeTest, SegmentIterators2) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_iterator_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, {0, 1}, {0, 2}, {0, 4, 8}, @@ -183,7 +189,7 @@ TYPED_TEST(MultipolygonRangeTest, SegmentIterators2) TYPED_TEST(MultipolygonRangeTest, SegmentIterators3) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_iterator_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, {0, 2}, {0, 1, 2}, {0, 4, 8}, @@ -198,7 +204,7 @@ TYPED_TEST(MultipolygonRangeTest, SegmentIterators3) TYPED_TEST(MultipolygonRangeTest, SegmentIterators4) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_iterator_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, {0, 1, 2}, {0, 1, 2}, {0, 4, 8}, @@ -211,6 +217,87 @@ TYPED_TEST(MultipolygonRangeTest, SegmentIterators4) {{11, 11}, {10, 10}}}); } +TYPED_TEST(MultipolygonRangeTest, SegmentIterators5) +{ + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, + {0, 1, 2, 3}, + {0, 1, 2, 3}, + {0, 4, 9, 14}, + {{-1, -1}, + {-2, -2}, + {-2, -1}, + {-1, -1}, + + {-20, -20}, + {-20, -21}, + {-21, -21}, + {-21, -20}, + {-20, -20}, + + {-10, -10}, + {-10, -11}, + {-11, -11}, + {-11, -10}, + {-10, -10}}, + + {{{-1, -1}, {-2, -2}}, + {{-2, -2}, {-2, -1}}, + {{-2, -1}, {-1, -1}}, + {{-20, -20}, {-20, -21}}, + {{-20, -21}, {-21, -21}}, + {{-21, -21}, {-21, -20}}, + {{-21, -20}, {-20, -20}}, + {{-10, -10}, {-10, -11}}, + {{-10, -11}, {-11, -11}}, + {{-11, -11}, {-11, -10}}, + {{-11, -10}, {-10, -10}}}); +} + +TYPED_TEST(MultipolygonRangeTest, SegmentIterators5EmptyRing) +{ + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, + {0, 1, 2}, + {0, 1, 3}, + {0, 4, 4, 8}, + {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {10, 10}, {11, 10}, {11, 11}, {10, 10}}, + {{{0, 0}, {1, 0}}, + {{1, 0}, {1, 1}}, + {{1, 1}, {0, 0}}, + {{10, 10}, {11, 10}}, + {{11, 10}, {11, 11}}, + {{11, 11}, {10, 10}}}); +} + +TYPED_TEST(MultipolygonRangeTest, SegmentIterators6EmptyPolygon) +{ + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, + {0, 1, 3}, + {0, 1, 1, 2}, + {0, 4, 8}, + {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {10, 10}, {11, 10}, {11, 11}, {10, 10}}, + {{{0, 0}, {1, 0}}, + {{1, 0}, {1, 1}}, + {{1, 1}, {0, 0}}, + {{10, 10}, {11, 10}}, + {{11, 10}, {11, 11}}, + {{11, 11}, {10, 10}}}); +} + +TYPED_TEST(MultipolygonRangeTest, SegmentIterators7EmptyMultiPolygon) +{ + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_iterator_single, + {0, 1, 1, 2}, + {0, 1, 2}, + {0, 4, 8}, + {{0, 0}, {1, 0}, {1, 1}, {0, 0}, {10, 10}, {11, 10}, {11, 11}, {10, 10}}, + {{{0, 0}, {1, 0}}, + {{1, 0}, {1, 1}}, + {{1, 1}, {0, 0}}, + {{10, 10}, {11, 10}}, + {{11, 10}, {11, 11}}, + {{11, 11}, {10, 10}}}); +} + TYPED_TEST(MultipolygonRangeTest, MultipolygonCountIterator) { CUSPATIAL_RUN_TEST(this->run_multipolygon_point_count_iterator_single, @@ -280,7 +367,7 @@ TYPED_TEST(MultipolygonRangeTest, MultipolygonCountIterator4) TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_count_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_count_single, {0, 1}, {0, 1}, {0, 4}, @@ -291,7 +378,7 @@ TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount) TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount2) { CUSPATIAL_RUN_TEST( - this->run_multipolygon_segment_count_single, + this->run_multipolygon_segment_method_count_single, {0, 1}, {0, 2}, {0, 4, 8}, @@ -301,7 +388,7 @@ TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount2) TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount3) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_count_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_count_single, {0, 2}, {0, 2, 3}, {0, 4, 8, 12}, @@ -322,7 +409,7 @@ TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount3) TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount4) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_count_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_count_single, {0, 2, 3}, {0, 2, 3, 4}, {0, 4, 8, 12, 16}, @@ -345,16 +432,19 @@ TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount4) {9, 3}); } -// FIXME: multipolygon doesn't constructor doesn't allow empty rings, should it? -TYPED_TEST(MultipolygonRangeTest, DISABLED_MultipolygonSegmentCount_ConatainsEmptyRing) +// FIXME: multipolygon constructor doesn't allow empty rings, should it? +TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount_ContainsEmptyRing) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_count_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_count_single, {0, 2, 3}, {0, 2, 3, 4}, - {0, 4, 4, 8, 12}, + {0, 7, 7, 11, 18}, {{0, 0}, {1, 0}, {1, 1}, + {0.5, 1.5}, + {0, 1.0}, + {0.5, 0.5}, {0, 0}, {0.2, 0.2}, {0.2, 0.3}, @@ -363,16 +453,19 @@ TYPED_TEST(MultipolygonRangeTest, DISABLED_MultipolygonSegmentCount_ConatainsEmp {0, 0}, {1, 0}, {1, 1}, + {0.5, 1.5}, + {0, 1.0}, + {0.5, 0.5}, {0, 0}}, - {6, 3}); + {9, 6}); } -// FIXME: multipolygon doesn't constructor doesn't allow empty rings, should it? -TYPED_TEST(MultipolygonRangeTest, DISABLED_MultipolygonSegmentCount_ConatainsEmptyPart) +// FIXME: multipolygon constructor doesn't allow empty rings, should it? +TYPED_TEST(MultipolygonRangeTest, MultipolygonSegmentCount_ContainsEmptyPart) { - CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_count_single, + CUSPATIAL_RUN_TEST(this->run_multipolygon_segment_method_count_single, {0, 3, 4}, - {0, 2, 2, 3, 4}, + {0, 1, 1, 2, 3}, {0, 4, 8, 12}, {{0, 0}, {1, 0}, From 400cc15a64c46b367e56c6851c930e01800eab8e Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 1 Jun 2023 14:01:58 -0400 Subject: [PATCH 32/63] Add documentation for `pairwise_linestring_polygon_distance`, `pairwise_polygon_distance` (#1145) closes #1146 Add missing API examples for 23.06 release. - Added example for `pairwise_linestring_polygon_distance`, `pairwise_polygon_distance` Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - Ben Jarmak (https://github.com/jarmak-nv) - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1145 --- .../all_cuda-118_arch-x86_64.yaml | 1 + dependencies.yaml | 1 + docs/source/_static/bounding.png | Bin 0 -> 29019 bytes docs/source/_static/hausdorff.png | Bin 0 -> 44003 bytes docs/source/_static/haversine.png | Bin 0 -> 37234 bytes docs/source/_static/spatial_window.png | Bin 0 -> 14151 bytes docs/source/_static/trajectory.png | Bin 0 -> 34732 bytes .../user_guide/cuspatial_api_examples.ipynb | 1034 ++++++++++++++++- 8 files changed, 981 insertions(+), 55 deletions(-) create mode 100644 docs/source/_static/bounding.png create mode 100644 docs/source/_static/hausdorff.png create mode 100644 docs/source/_static/haversine.png create mode 100644 docs/source/_static/spatial_window.png create mode 100644 docs/source/_static/trajectory.png diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 5fda0d096..d5d126a73 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -28,6 +28,7 @@ dependencies: - notebook - numpydoc - nvcc_linux-64=11.8 +- osmnx - pre-commit - pydata-sphinx-theme - pydeck diff --git a/dependencies.yaml b/dependencies.yaml index 86694ef13..ce7ed798a 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -174,6 +174,7 @@ dependencies: - ipython - ipywidgets - notebook + - osmnx - pydeck - shapely - scikit-image diff --git a/docs/source/_static/bounding.png b/docs/source/_static/bounding.png new file mode 100644 index 0000000000000000000000000000000000000000..258fb6a151762fc4f64060e357c2ffa2f6b4b8d1 GIT binary patch literal 29019 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 w# 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 literal 0 HcmV?d00001 diff --git a/docs/source/_static/haversine.png b/docs/source/_static/haversine.png new file mode 100644 index 0000000000000000000000000000000000000000..4ac97fe85ee776475380e56643df85a251d5a4dc GIT binary patch literal 37234 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 P00000NkvXXu0mjf8=}|) literal 0 HcmV?d00001 diff --git a/docs/source/_static/spatial_window.png b/docs/source/_static/spatial_window.png new file mode 100644 index 0000000000000000000000000000000000000000..6387bcaf1bf1ff34ca60f0961951073fe833f6ed GIT binary patch literal 14151 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 literal 0 HcmV?d00001 diff --git a/docs/source/_static/trajectory.png b/docs/source/_static/trajectory.png new file mode 100644 index 0000000000000000000000000000000000000000..e29e796e136e9474a11da6ab808251c895782cba GIT binary patch literal 34732 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 literal 0 HcmV?d00001 diff --git a/docs/source/user_guide/cuspatial_api_examples.ipynb b/docs/source/user_guide/cuspatial_api_examples.ipynb index 396f566c6..bc40c82b0 100644 --- a/docs/source/user_guide/cuspatial_api_examples.ipynb +++ b/docs/source/user_guide/cuspatial_api_examples.ipynb @@ -1,6 +1,7 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", "id": "c5fdf490-fa77-4e56-92d1-53101fff75ba", "metadata": {}, @@ -14,6 +15,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "caadf3ca-be3c-4523-877c-4c35dd25093a", "metadata": {}, @@ -36,6 +38,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "115c8382-f83f-476f-9a26-a64a45b3a8da", "metadata": {}, @@ -59,6 +62,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "051b6e68-9ffd-473a-89e2-313fe1c59d18", "metadata": {}, @@ -70,6 +74,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "7b770cb4-793e-467a-a306-2d3409545748", "metadata": {}, @@ -103,6 +108,8 @@ "import cudf\n", "import cupy\n", "import geopandas\n", + "import pandas as pd\n", + "import osmnx as ox\n", "import numpy as np\n", "from shapely.geometry import *" ] @@ -122,6 +129,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "4b1251d1-558a-4899-8e7a-8066db0ad091", "metadata": {}, @@ -136,6 +144,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "11b973bd-87e1-4b67-ab8c-23c3b8291335", "metadata": {}, @@ -153,6 +162,14 @@ "tags": [] }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/3038749724.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\n" + ] + }, { "name": "stdout", "output_type": "stream", @@ -184,6 +201,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "da5c775b-7458-4e3c-a573-e1bd060e3365", "metadata": {}, @@ -247,6 +265,14 @@ "(GPU)\n", "\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/567044009.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] } ], "source": [ @@ -257,6 +283,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "5453f308-317f-4775-ba3c-ff0633755bc4", "metadata": {}, @@ -277,6 +304,14 @@ "tags": [] }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/1940355512.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] + }, { "data": { "image/svg+xml": [ @@ -300,11 +335,7 @@ ] }, { - "attachments": { - "046b885c-ab14-4c44-bd23-daebad76ebae.png": { - "image/png": "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CICA6wlQfpYkSeHh4W+88cb7779fVVV1//33f/bZZ6IoqqqKSUquhz4tJUKApwUzKgEBEACBOyDA87xWq1Xsx/Lly0tLS2fPnv3www+//fbbgiDQQtN3UDwedQ8BCLB7uKNWEAABELhdAjQqLMtybGzsO++88+KLLz7//PMvvPCCLMu0yvTtFoj73UtA497qUTsIgAAIgMDECVCONCnus88+m52dvXnz5ra2trfffpuWrhRFceKl4U73EkAE7F7+qB0EQAAEbpsAqawkSatWrfr444//+Mc/bt682Wq18jyP8eDbpum+ByDA7mOPmkEABEBgsgRof0OLxTJv3rxDhw5VVFQ89dRTqqpCgydL1A3PQYDdAB1VggAIgMCdE+B5XqfTWa3W2bNnHz58+MiRI9u3bycBxqrRd453GkqAAE8DZFQBAiAAAlNCwFGD//Vf//XnP//5vn37aIelKakPhbqUAATYpThRGAiAAAhMOwGtVitJ0je/+c2nn376hz/8YVNTE22vNO2GoMLbIwABvj1euBsEQAAEPI0ApUYrivLjH/84Ojp6165diqLwPI+OaE/zlJM9EGAnIPgIAiAAAt5HQBAERVGMRuO2bds++uijixcv0q5K3tcSf7IYAuxP3kZbQQAEfJcALYm1YsWKzMzMTz75hOM4nud9t7m+0DIIsC94EW0AARAAAcp/njFjRk5OTlVV1cjICK0UDTIeSwAC7LGugWEgAAIgcBsESIB5nk9KSurt7bVYLLfxMG51BwEIsDuoo04QAAEQmAIClHUVExNz69at4eFhjuOQhzUFmF1WJATYZShREAiAAAi4lwAN+g4MDAQGBur1egwDu9cdf7N2CPDfRIQbQAAEQMALCKiqSrnQjY2NcXFxwcHBCH893G0QYA93EMwDARAAgQkRUBRFEIT29vYTJ04UFhbqdDpszDAhcO67CQLsPvaoGQRAAARcR8Bms/E8/9577ymKsnHjRioYM5FcB9j1JWE/YNczRYkgAAIgMM0ELBZLQEDAyZMnd+7cuWvXruzsbEmSNBp8w0+zH26vOkTAt8cLd4MACICARxFQVXVkZCQgIKCuru673/3uhg0bNm3apCiKRqNB+OtRnhptDAR4NBNcAQEQAAHvICDLsiRJer3+1KlTGzZsmDdv3s9+9jNafwPq6/kuhAB7vo9gIQiAAAg4E1BV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" - } - }, + "attachments": {}, "cell_type": "markdown", "id": "56b80722-38b6-457c-a7f0-591af6efd3ff", "metadata": {}, @@ -314,7 +345,7 @@ "A trajectory is a `LineString` coupled with a time sample for each point in the `LineString`. \n", "Use `cuspatial.trajectory.derive_trajectories` to group trajectory datasets and sort by time.\n", "\n", - "\n", + "\n", "\n", "### [cuspatial.derive_trajectories](https://docs.rapids.ai/api/cuspatial/stable/api_docs/trajectory.html#cuspatial.derive_trajectories)" ] @@ -369,6 +400,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "3c4a90f9-8661-4fda-9026-473e6ce87bd2", "metadata": {}, @@ -419,6 +451,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "eeb0da7c-0bdf-49ec-8244-4165acc96074", "metadata": {}, @@ -428,11 +461,7 @@ ] }, { - "attachments": { - "8c5d8b90-2241-45c2-b98c-20d48d1ee6b7.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAHCCAYAAAAzc7dkAAAgAElEQVR4AeydB3xUxfbHf7PpIZSEANJ7EQFRVEwBNoAoKrYnVuw+u2IF6wN774oNsVf8+95TnwUFFkjAhh1FlCJdkN4CSXb+n3M3d/duDJCyd/fu3t98Pjr3zs6dOfOdS/bszJlzACYSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAES2AsBtZfP+XFsCTQEcASAvgCSYisKeycBEiABEnAJgfkAPgaw2iXjtWWYVLBswRqRRkW5+gzAIRFpjY2QAAmQAAmQQM0JrAAwEMCimj/CmlYCHusNrx1F4DgqVzGYj/QMYN9eQEpKDDpnlyRAAiTgGAKtAVzsGGniUBAqWM6dtF7OFS1BJVMK6NoDyMkF9u8HNMhK0IFyWCRAAiRQIwK9a1SLlaolQAWrWiyOKOT2bbSnoXVboFHjQK9p6UCfA4Dc5tGWgv2RAAmQgFMIUEeox0wk1+NZPhp9An4Am6LfrQt6zGqYhHYdGoWN1JMEdO8JZGWVYsniHYAO+5g3JEACJJBABGTJnrYREZxQKlgRhBmFpv4E0CoK/biri+HD07Blx1fQMJbD+/TcF5u3bMGSZcsDHFq3S0frtlOA8lEoKdniLjgcLQmQgEsIfAhguEvGGpVhcvkvKpjZiaMJbNpxr6lcNWrYEI/ceRvenvQshgwcYBFbHQOkfIMBQ3paCnlJAiRAAiRAAtUSoIJVLRYWuoZAofcIKFxhjveGKy9D82a5yMzIwCN33oqrLr4AHk/QHK4L/BWfI7/oWLM+cxIgARIgARKojgAVrOqosMwdBAoLs6ExEYChQR0+2IsRhw8Ljl0phfNOPxUP3DoOGenpZnlDKP1vFHrHm8+ZHzAnARIgARIgAZMAFSyTBHP3EdDJjwEQXy/IzcnBzddcWS2DYUWD8NozT6J1y5bm5woa41DgfQP9RmSahcxJgARIgARIwCRABcskwdxdBAqKTgIwSgYtK1V33nQ9shtXumiohkS3zp3w1sSn0b/fAdZPT0b6lhLkD25vLeQ1CZAACZAACVDB4jvgPgIDBrQE9ARz4P8YcRQK+h9s3u42b9K4EZ596H5j29BSqS+U/2sMKBpkKeMlCZAACZCAywlQ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552jJgESIAESIAESsJEAFSwb4bJpEiABEiABEiABdxKgguXOeeeoSYAESIAESIAEbCRABctGuGyaBEiABEiABEjAnQSoYLlz3jlqEiABEiABEiABGwlQwbIRLpsmARIgARIgARJwJwEqWO6cd46aBEiABEiABEjARgJUsGyEy6ZJgARIgARIgATcSYAKljvnnaMmARIgARIgARKwkQAVLBvhsmkSIAESIAESIAF3EqCC5c5556hJgARIgARIgARsJEAFy0a4bJoESIAESIAESMCdBKhguXPeOWoSIAESIAESIAEbCVDBshEumyYBEiABEiABEnAnASpY7px3jpoESIAESIAESMBGAlSwbITLpkmABEiABEiABNxJgAqWO+edoyYBEiABEiABErCRABUsG+GyaRIgARIgARIgAXcSoILlznnnqEmABEiABEiABGwkQAXLRrhsmgRIgARIgARIwJ0EqGC5c945ahIgARIgARIgARsJUMGyES6bJgESIAESIAEScCcBKljunHeOmgRIgARIgARIwEYCVLBshMumSYAESIAESIAE3EmACpY7552jJgESIAESIAESsJEAFSwb4bJpEiABEiABEiABdxKgguXOeeeoSYAESIAESIAEbCRABctGuGyaBEiABEiABEjAnQSoYLlz3jlqEiABEiABEiABGwlQwbIRLpsmARIgARIgARJwJwEqWO6cd46aBEiABEiABEjARgJUsGyEy6ZJgARIgARIgATcSYAKljvnnaMmARIgARIgARKwkQAVLBvhsmkSIAESIAESIAF3EqCC5c5556hJgARIgARIgARsJEAFy0a4bJoESIAESIAESMCdBKhguXPeOWoSIAESIAESIAEbCVDBshEumyYBEiABEiABEnAnASpY7px3jpoESIAESIAESMBGAlSwbITLpkmABEiABEiABNxJgAqWO+edoyYBEiABEiABErCRABUsG+GyaRIgARIgARIgAXcSoILlznnnqEmABEiABEiABGwkQAXLRrhsmgRIgARIgARIwJ0Ekt05bI46igQUCgubQKc3hEdnoaK8ATwePzS2wq+2YpdnK+Z+timK8rArEiABEiABErCdABUs2xG7pIOCoe3gr9gXHt0bwH4AegHYF0ADaGFQDvgBKAVoowDwaCDdDxR4pcIGAD8BmAdl5hXzMGvWWpcQ5DBJ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" - } - }, + "attachments": {}, "cell_type": "markdown", "id": "12a3ce7e-82b7-4b51-8227-5e157a48701c", "metadata": { @@ -443,7 +472,7 @@ "\n", "Compute the bounding boxes of `n` polygons or linestrings:\n", "\n", - "\n", + "\n", "\n", "### [cuspatial.trajectory_bounding_boxes](https://docs.rapids.ai/api/cuspatial/stable/api_docs/trajectory.html#cuspatial.trajectory_bounding_boxes)\n", "\n", @@ -482,6 +511,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "a56dfe17-1739-4b20-85c9-fcb5902c1585", "metadata": {}, @@ -512,6 +542,14 @@ "3 55.928917 37.144994 73.055417 45.586804\n", "4 12.182337 -13.257227 31.174149 5.256088\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/1016569337.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] } ], "source": [ @@ -526,6 +564,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "85197478-801c-4d2d-8b10-c1136d7bb15c", "metadata": {}, @@ -568,6 +607,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "81c4d3ca-5d3f-4ae1-ae8e-ac1e252f3e17", "metadata": {}, @@ -602,6 +642,14 @@ "4 POINT (-98.002 -279.540)\n", "dtype: geometry\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/2658722012.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] } ], "source": [ @@ -618,11 +666,7 @@ ] }, { - "attachments": { - "image.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAF3CAYAAABewAv+AAAgAElEQVR4AexdB5gcxdF9vXeSQAKEBIicMyIaAQKETicRBYhgEDkbbJONCSZJIxFtEQwYk4PBZGPzm5x0dxI55yQwGQQiCxTvtv7v9Xbv9czt3m2avd29ru+TZnpmOsybvZqe6qpXgBePgEfAI+AR8Ah4BDwCHgGPgEfAI+AR8Ah4BDwCHgGPgEfAI+AR8Ah4BDwCHgGPgEfAI+AR8Ah4BDwCHgGPgEfAI+AR8Ah4BHoIAiKytYjcKiJ7Vuoti8hKInKtiFwtIotW6jj9uDwCHgGPQBoBEVlZRA4QkT+KyB9EZI30ySJ2RGQzETlcRE4Rkb1FpLfbnIjUi8jfRCQp7TLavaZS9kXkX+1DlA9FZK1KGZsfh0fAI1ClCIhIL6N8jxaRDUt1GyKiROQcEZnvKC67e6eI9CmkLxHZWEResg052+dFZEG2KSJ1InIbz7333ntyyy232MsmFNJn3HVE5LlffvlFzjvvPGltbeVYp3sFHzfqvn2PQA0jYBTwfVbzmVnuxaW4ZRE5je22tbXJ7bffLn/605/k7LPPlk8++cR2d2K+/YhIXxGZkUwm5bnnnpN77rlH/v73v8sjjzxi29yBbYrIBTxAxT506FD58ccfWZwhIsvm22c5rheRiznAf/zjH3LggQcK709E3hWR/uXo3/fhEfAI1BgCZsYu33zzjYwbN05eeOEFKhXKwcXcqogsLyJzf/75Zxk2bJjstttu8u2338qyyy4rm266qelC7s+3DxFZgu+LTz/9VPbbbz9Zeumlhbr8b3+j9UXLjiIyjNew73XXXVeeffZZe26nfPsr1/V86YjIDxzonnvuqWfwZtA3lGsMvh+PgEeghhAQkRuoRI477jitJDfccEOrCB8o5jZF5Fw2dPLJJ0t9fb3MmDFDZs6cKYMGDZKGhgbbx2WF9CEil9oGDj/8cD3uV1991R5Km2yOP/54+f3vf2+P31tIX+WsIyKHcbBffPGFDBw4UF5//XUWOYXfopzj8H15BDwCNYCAiGxHDTJ16lRtvrjuuuusMrylmNsTkTfZ0ODBg3W7ttFZs2bJ/PnaBE87yWqF9GHs6d+zzU022UQGDBigTT8iMktExvA4TT8LL7ywfP755yxSQa5bSF/lriMi93PAJ554ouy8887cpTxc7nH4/jwCHoEiETAeHYsV2UxR1UXk/4wSsRtqxNULbVREFqFZhI0tv/zy2sxgGzbb/9F0UkT7y4jIj1yA7NWrl+y00062+YdE5B4WOGOnecPIo4X2Ve56IsJ7m/XGG2+IUkrefFO/I3kbIe+Z+nIPzPfnEejpCHCBEsBIAHsB2AjAQABJAF8D+B7AdwBmA+B1XNzbAADtyFcCOBfAsQD2BbAwgA8APA2gBcB00+76ANYB0BfAfAA/RzD/AsB9AP6hlJobOdehKCL7AYj6VT/EvkWEi5NHAKBZYAaAdwG0AVjI1KHrIft/BsClSin2TTkIQII7v/zyCxZZZJHUUYAmlDcAbK2UIh45iXnR7AaAs++1AQwGsOAzzzyD+fPnY6uttrLt0JR0/rx583D77bfjiiuusMevtjt2KyK8h98DGA6AXju8v2/Ms+Ez2wYAFzPfAjBOKTXZ1s1ly5c2gOPNs2Q7nxiM/mPr8yUIYHfT/21KqZ+IoYjcPnjw4EM22mgjXH/99bjgggtYZW8Aga3rtx4Bj0AZEaBng4g8bqeL3bzl7HjTzm6fE9wsY6QZY2aWc9kOc7bPWSd92dPSr18/oV08Iv/tbFzuORHZRkR+idTXxTPOOEPb25966imW54rIgdx54IEH9KyXC7jmOBV5WkRkkIi8phvJ7T/akfjCzknojikikzM0TVzHshER+ZWIfOxc87SI6BeiiBzL4yeccIKstdZa9hK+5L14BDwC3YGAiNzBv8S33npLu7Odcsop2nZK17YjjjgiZHvmHy5NFn379pUll1zS/gHr7dZbb629ShZccEHZfffdQ+e4GMlFSdqZr7nmGnnsscdku+2206aJLbbYQrbddlt55plnbB3aoDnTzygichkvpJJcYYUV9FjYhiunn366HgsXRffZZx+ZPXu2XiQ96KCDZOzYsbLyyivLRRddZKvQx1Eb1A8++GDhfSQSCV2f+3vssYfce++9vJYmm+jXQocxigj97rV5h/W22WYbOfroo2XXXXeVxx9/XLbccks95rlzqde1aWkcd2iSWWONNeyYmtyGRWQBEdEuQe+8847Gly8f2u6vuuoqXWfSpEnyu9/9Tt8f79n4nb/sttPZvohczobo0cN73mWXXbSJyKw1cOV3gIh8xmvOPPNMvd5hBqtfxnyRsEz3Ub4HvvrqKxbnWR/+zvr25zwCHoESI2Bd9L777jtZccUVraeD+ZsVuf/++7Wio883hduWlhY9w4wqd7rwXXrppfoPO6rcf/rpJzn11FP1OSok+o4bpaHbvf7667V3Cn2/jTDYhyagDsKAJc5s6VP9yiuvCF8mUeXOth988EHdH18ihx12mKuMtN86FdC///1v219ols1FzR122EGIi71381XQr8OAnAMi0mgV+x//+EdZZZVV5KOPPtJ9cExU9LS3NzbyMi2HiAgDo/QxKlUjFzrNcsZ8HI9zwXX77beX6dMZKyRCbxvauPfff3+55JJL9DG+JHhv5suAs+7QF4Dbrt0XkaX5gpszZ47svffe8v3338trr72m2+GL2Czuav//zz77TPdpXyo2ctco/+S7777r1mPdkgWY2fH6rUfAI9AFAiIyin99//d//yfrrLOOVg7R/zjTNMEpP4nIdzy/2GKLuTN3mkK0jYGzSioWR7lTM2iTz6OPPqrPDRkyxHbxs4jcyEVGHmCduro6dwavA3sy3QK9FW0jHLej3Dm71TNhnl9ooYW0Mr3pppvs5Xr2+/LLL+ux8CvFCF0gr7cFKnfOXI3wnmmuoD07q5iI2Wmsc/HFF+uXFV8+RvQ09pxzztH9cuZrhH71U7i/9tprC18IRn7jdiQiNH/IAQccIB9/3G4Vofsh8V5kkUXEfAnoa+iTTxdOg23Gl2Sk/d/w4iuuuEL/FrhPzJyXBA/dxf/omcTjJraAvwltlmF7DLhiv9x1PJh+bftKX2gP+K1HwCMQGwL672327Nl466238Pe//71DR0cccQSU0vrhPQCP8IIFF9TR8vbaVwDo4KF+/TpMbD8FcCD/2AcO5HofsMoqq9h6f1FKsR4X53DkkUeira0N48aNs+d3sTsZtlyte5HHe/Xq5Z5+Tyk1EcCrPNi/f3+9eDl6tKZm4cKjJuHicQoXTo2wkcPNArA9Zrd/VkqNVEp15b3CYKPVpk+fjjPOOANjxozBBhtw3RlcMNVBPd98wyEAW2yhXcC5sPwZAO11xEXWQYMG2T6/sjtmu9oPP/yA5ZZbDiussAIPfcn/3n//fX16u+22Q+/eXCcGbrrpJjz77LNYaCE9YT+DM3t9ovP/dKOvvfYadtopFTN177336kXlTTbZhDXnANAP96GHHsLCCy9s7+1VpRQX3q3MYL99+/aFvVcAA+xJr9wtEn7rEYgfgTepeHfYYQcsu+yyOOqoo7DiiitqRfvII4+AHhwHHkjdrIWeLx9xb4EFFjCH9OYXpRQV/0cZlPtXSqnP6dFh6zjKuJm1lVKPA/jf0KFDUV9fjylTpti217M70a1RKFqzsY4j1vPlWR7r06eP/rfYYlp/8mUQ8naZM4c6S8vPSil61OgXhj1otrzvXETPUM855xz90hg7Vq9Bsh69ibSWf+WVV5BIJMB7Je4AqJHrWKBytxgBmBnp8DN670ycyPcWqPhv5s7TT6fWK3feeWd7OTGlrz89bXZXSuUacMWXMC699FI9vrlz54JKfMSIEfqZGM+iDfnyfeyxx/T4De5Rm/5PbIfK38GWHlJavHK3SPitRyBmBIwb4LNUHI8++qj+o/3kk0+0Ox5ng0sttRRuvfVWOwouJi7DAmfuIukJod3hLFSLc46KnaKsErbbiDvkx3wx8B+VQmtrK+ukpvqp+pn+p2umVj58CRmhayBFzyY5m3VeJnyRcKqe1uj8YjHyrd3h1hk/iz+65zrZH0Xld8stt6Curg477rgjL/1CKfUkgA05Rs6o11lnHSy6qF6XpWI/HUDa9TOZTE+Co6aU4xOJxEv19fXU5mx4eTb+5JNP6q8qvpzNVxW9Y54wrpH6K6uT8bqnbuML1j4bKvCZM2di6623ttewzaWff/55fP/999hyyy3t8ejLUJOq8eVgvvZ4XfrheOVuYfNbj0DMCIgIFegGVCprr722ngl+9NFHuOGGG7DnnntqRXvwwQfj5Zf1BI1/0QdwSBHlbqfxvYxS1uYVM3QafqnEBloly5mrEZcMSytyKgSep3I0Cspem2mr7RAcu6Ok7YtmOVaIKOklTCN6dsl9Z3ZpZ8paaXIW7ShabbLINAB7jNGnAAZ9+umnWvmtttpq1ixCxkdGtC713HPPYdasWdYkY6ueafzg9Uvqp5/SQwsRbymlGDNA/KnY+QLbhFi3tLRgjTXWwOKLL872XjI+5XSUP44TcdtJV1ulFP3+NzaxCbjnnnt0lW220csM+k3LA01NKScex0f/hUjb2hZE5W5NXwDSN5V+8pFKvugR8AiUHgFG0izI2SbtrRSaZajQ77zzTlAh0YbKoBRXqNwd5Uc3PSq3NTnbo3AGa4QKlYbkhJ0V2hMAdDSpiFARD/7ss89Au/KSSy5pZ3009XQm+oVAJecod/1lAUBHRnIcjoInMyNfCP3t2J0ZP6NTeU5TC1C5O/cwprNBmHOciifs/a+/ftqTk2YvbdeiIqYYezumTp1qMdQ6jy+/zz+3HzpY0vZp/Ns5++dXB4PJPuY4+RXw448/YrPNNrOX8t5P4zHzMj5IRPqJyOYioglfRORLEQncRVBbWSn1gzET4c0338Tyyy+PtdbSMDKAa1deR+VO05G5B74Q3rH1zW9gBWLAlyafoxFt8uG+V+4WEr/1CMSPgP7r5Yzy6qvTAZGMOuX3+Pvrrrsudt11V6103aHwD9xRqJyt/ZHRn5z1UxzFyMVSbXN1Zuy2KTrDUwOw4/r770+RLR5wgP444DWP2QujWxMlqakAqKCdGfivRYTRm2klbRW5GQddDPvYY5xhGqF3CiM/+/JlwfPOPdCjKG2HsBUiW77VkrQ1U8xMmrt8eZ7IF8y///1vfc4qd0aiuphQmb7zTlpXMprVCleYt/j6668TjG61wgVPyqabpmO+9iGOF110kX2h8YXLl86d/DrgQu/8+fOXAjAeAL8YMgkXeTFjxgzw2RtZifWJFc1AHL9ZG3jZrFPY61bky+G9997T/fN+jHT1krbX+a1HwCNQKgREZALd2+hfzqhM182Oxyn0zXbc2rQr5L777kvzh9B/3ZVDDz00U1DRVF5DH23WWXXVVdN+2rbul19+KUsttZR2xyT3ioiQYCsd/+/er+FyTzOFsR6DozIJg6369OnT4ZR12SRBWFRI2sVxbrYZEyal5eWugnFEhNfoACn6nbty/vnnazdPuizSrXTatGku86O+lG6QTuxA2jNHRDSL2Oqrr67dOhmcNG/ePFlppZX0OB1OeM3pQkphI28xGIz7zc3N2jed2Dv4Ru36VMq383q6qzI+wJUbb7xR90dueyN6ddc+G1JC8PjNN9+sx2n6Sc/a7XV+6xHwCJQBARH5Hf8gr776aq10qdCmTNFu1zqqc/z48TqYxwQcUeHuw+vJNc6XAf/Q+UfMkHlGhTIoiEqH/upUVkxMYYXBPFSajFZlIA4jUqnonn76aR2uPnz4cFfpH53t9m2YO33z99prL6202C73//Of/+ju7rjjDs3FzuOMNmXkqQ1YIof6mDFj9Fh4nsrQcqdfdtllMmrUKH2ud+/e2mf88ssvt37+6U+bTGMjKSI7Z1TqcsstJx9++KGO9mTAFpX7tddeq19CjJalvzoVvImM3Zc7Ng7g66+/ZjE92+U+D6y55ppy1FFHCQON2CbvnwyMjCQmrz0TgIwcOVJMfUadkZ5xXdadPHlyGqcnnniChyjWhJW+Hbq38wQzQDE4jLjYZ0s8iNeLL76Yqi2ifSRtZROzoGkbGKhm5B/2PLcd3ibuSb/vEfAIlA4Bw9r31muvvabowUH7+m233Yaff6Y5FVh99dW1WSaRSNDjYaxSikyM9Nve4cMPP8Qdd9yhTTa0p//6178GSaNOO+00vXBI98ORI0emPSt4PX3caXa5/PLLtRcOj9FTh9cZ90B2ezmAY7L5Z5PuF8BDX3zxBb78Urt7pwGhdw9dOrmw+fXXIa9HcDwrrbQS3n77bT2+dCVA+4/TRky/cdqsXaEJYvBgbSX5UinVQSHaa83M/jmaMF566SW9KMm6dInkAivlrrvuwosvvqh9yYcN01YlLmb8jl41ra2tiy+99NKacOugg8hhhg2UUuSSOQ3AObynK6+8UpuM9t13X6y33nqgqeTmm2/W41555ZW126qJQThVKXW+sa2TyG0lmnzeffdd/YxHjRrF9gcrpUgwpsWsOdAutDIP0DOGC6t8tttvvz1OPvlkcF3kf//7H9dEpnGNxT4jc+9cMBjAcTBm4aSTTmIzeyql/pXqwf/vEfAIlBUBBibaaVaWLadqaZsz/5BNjlHNcJWljntYTxU5U+XMj7wnWYRx+vvncvMiMjELSRijXWk6ypT/NEu36cNz0nvhHbb1hrln8vEyY1LGPKoisriIuOn/2BLT5JGtkjwrrjzKkH3er4icxxPky+GXgxHm4GM+VybMZqIPnaTUnhSRpgzkZOR+STu9m7a3NAupOurU0BKwGe2PafHmS5sH+bX1/vvvO92IvP322/oLiOMzcoqtZ/rQdqiXXnpJR+YaPno+B+tJ5V7u9z0CHoFyIMDZHWlyRYQE4+uJCEPRGZf/WxHRwTeZxmHyglLRMRPPEc4/mhls2jgyYR1PhcA/fOoxhz+FypR9HWySR+f11U52ARFZxfxbLJMHSHTcVGiGA4VMkKx7jNVWGbanm2tXFxG6NLrClwgjWjMK+VaMDXp7y5FjyL/IcKZfEG5Fk95vPsm2SH1AXhcj6T7MNeSiIc+MdpExjJb2eZGJUvuQRtpmKrxP2R5NUGadhDPvtIiI5p4geRzNWFEqCpq8mGWJ5h/zskpHnZoXkE78zbWG3/6WPxstf0134Hc8Ah6B2kJARJibTs9YSUBF5U57tyOc5XZQSKVGwSggrrry38KmTJKbz8mFQrZG2rzJl0IyLsOo+DbHYVkzuTZA2zVnsbSbG0mTshc7Zmvv/utf/yo77sh3oxa+RLTPfqHti8gktsTxM1OSkUlue5bRkXZ80vX+97//tdfpxXQuTHNR1shvI3X34nEm9SbnkCE1I0BZTVhufb/vEfAIVCEC1oOEVLuk56Wu7N+/v4wePdpVFppbJo7bM94iV1qPE6ud3C3ZLLnYSpIxju+CCy7QrIgiomkHRERzEU+cOFEWWGABnZCbtLhmNpx25i52/HS0EZHZfLFwYZQLpEbuKqZtEdGa+sgjj7SzdlIquwFkfIGRv3k+Z/Vc7KYHDrMpHXvssTrl4PPPpz9c6E2T/sIyL8tPyJy51VZbyb/+9S875pAnTTHj93U9Ah6BCkSAnnH8a6dHDelz3X8Ola5m9Srl8I0JhEo9baemHfiDDz7Q5iGaiIyrnlVG2ruHyp0zZyP0UtE0jaTAJdOiY6+me6Lri16S4dv+6KEyYsQIOwsmbS99zQsSm/TbfI3w1hi92kEsmyb7pjsjefc5W3ee05NRd1ARuY0NXnjhhfqfwe3D6HUdOvMHPAIegepGwOQlvcX80WfanM07NDNH2qMZhPSHbNmYRIQ8vPQn5yInlYjmCmfgklkQ1Iu/dlGTNmJyudM9c9iwYdpnnzlKmYSEtL9GNNUvlT994jfYYAN7nC+GNrqBko7YcSHk4mrByrazJ2rWP27lAH744QfNp28Gs31n9To7Z2bXXCzluI/s4lquB2gfTQuCiNDQfgHNWdG6fAY0UVk3U2OCK/nLOtqvL3sEPAIVgIBRWDoQx1EYdvftLCYTzlYZMZoWN73ejz/+aH3PyQkfdu0wWZAYGLXhhhsKg2+cWavt124fpgugTZhBpc93jVXk9MM/7rjj0r7/IkJ++pCXSXqAJdox3jF/dr46mLKJ0Z9lE/LhiMjWJq2e5vDJ1LnleDdgMkVip2n90vacTI35Yx4Bj0DlIEDuEjIekjHQxKjQufxFQ0SlB8ok2m1tbb8l0yCJscg9whB/Mgsa/3Htpz15ciqX8xJLLKF93pdeemlynSxGel96ipAOgYqY/tYMpWcb9Mm3stdee2G//fbTPOo8Rrra448/Xvvpm2u4QMqISTqyk3fgGqWU5hdmjBCTSr/55psJht3vtttumi6AfW2++ea6DID0mAcrpXSIvu03rq2xi5Mu4DOlVJTfPa5u82rXJNTe3JC8vRThds+rLX+xR8AjUAEIUBmKCM0HofR0ZgZHk8k1TNjEoTLRE2fAtHfb6E/OkE2mIF2FNm1GvHKhlbNmY+elp4gmaxeRP/FC0iQwgpZZgpZYYgnTnei2aFKhJwuFkZU77UTPzk7lB+Y7tXDajEi0ddMdkGNkRiUjzBjlea8sWAVuQ8z7Bbbhq3kEPAJFIkBbrWniR3dGZhbk6ErXi+RhjMZktKiVlVdeuX7IkCEk4uJM+SIAB5GydpVVVln/uuuu0xS106ZNs5S4uhqzL/3hD3/AWWedZZshm+IpSilLN6vdAZmJiHSz11xzjZ5R24v5VcDITNLfUpjEgpmfSIZGMi9GWTISllTCdrvaaqv179+/PxOP/tMwIk4l0dchhxyC5uZmzUzJmT+Ap5ilycXA9uu3+SHglXt+ePmrPQJFIyAiewD4M6CpZml2cO3KtGv/x3CEHwZgElkYTz/9dE0BS8oBmlJIXUDaWibIGDJkCMekub2pOEVkWwBTVlxxxTVIJ0yl++qrr+pUbRdffLGmBTjhhBNYh0r990opKlpXnmeBGYfIsMgsUePHk9wwJQ8++KDu07Is8hqabZhYgv8yCVPB9e/fn9zE1syik0rYF9WJJ57IarTBH1kuU0ymcfpjHgGPgEegIAREJJ2tmeRehtBKWyPo68wkzEaY7XkevUe23XZbmTRpkjWf2PPulqH17guCSpkUjPPJyEizB2kI6EJ3ySWcPGuhN0coSYW9IbMoq0mtSFzF+s64NBOjk3RaGDBFkq0uhLZ8TYBiFlV1lCXNOeuuq/m2WD36krFD8luPgEfAI1C5CBielCQpZE899VQhAyJdB8eOHStHH320dnEjwyGVvBUyHDoh5jzMmTm5U0gxS2IxatWMnCJkIWAFRmBSQU+YoBmHbdM6V1w2tMhEywvvuusuHXBkK1HZc4Y9dapmFubhefSOWX/99UMvKuMK+ILhpCH1os4ETYoFUqqwIhkXScvLoCsjvKd01upsY/PHPQIeAY9ARSFgXQCp2LngSSFxFJXlDTfcIHQnXGaZZeSNNzipTgk5wbkA2oV8HOVjN4uwegH25JNP1hS0hx9+uNsMPW+yiojsyosZHUr+FY6TVAEMl2fUq6El5mIueXHkySeflLXXXjtN5+t2ZPZJRk//bR1+ya+W0047Td87lbvhUeGlzHPqpQQIeJt7CUD0TXgEckRAm0522mknTcfLOqR6pe18991314uPTuo3naGHmY/OP//8dPOktWVia+bM5OIlM/AMGzaMeUdpn7+YFxqekYeZ6Yj5WXkNaWRvuukmBEGAZZbRNCRcwGUquWyifai5qEraXC6i0rY+aNAg7VLJRVPmjDZ9jt5iiy2G33jjjZp+lpmRmPqOC6qkNh4wYABGjx698HLLLccMUrod0v02Njbqf1w/cDJNWZt8tnH54zki4JV7jkD5yzwCJUDgZgDb2NRvbI+eJszLSa+SqPTp00crx403Zi7lzEJlb2RBbsm+COC/TM96991345tvvtFc31yI5ULohRdeqP8BOARA2l3GNuJsR9NP/rDDDgMXYX//+9/jgw8+0F42jz/+uL3sUqUUicpIe/vvTTfddBRfVswp+sknnzDNnL3OTcJ9lVJq8KhRo5ieL0rly4zQnSbpSDfodzwCHgGPQKUgYLlBrMmCpo3FF19cTjrpJHsoZG/nwY033liHxqcv6LhD5Xo1F0cN3a+24ZCr5Jhjwgy7Q4cO1WRcJr0fKYCZiKODGBoD7QNPMwyZB0kXwAhUZosy8qBb0TA/kjyexF9cPHWFZaacSmcTMhTGpEAghTFpDnq57fn94hHwEarFY+hbiBWBR/sDvVcBZClADQKSjM5cFEj0B3TeT3Jw6FmrGQbTGnHKyH+pFEc6SlKSgPoFkGlA4hOg7iNgy+mASsY6fNO4CMePLzmTZraga6+9VmfZ2WabbXSGJR5jViJm1DHJs2mPVtdffz2YqNkcY2s/AWBm7G8BMEKV+0y8zXQ/2h2SphcmV+ZMvb6+/jsA9E9c9dZbb9VRpXSPpLnGYHSSUuoSFwMTzMTkDwtPmjRJR6h+9913OPTQQzF8OCfcYAahrZRS37j17L6JcF2PSZfMGF9XSjFDkZcyIuCVexnB9l11hcDD/YAFNmPqTwCc5ZEJkPbkuISKnanPnk79U88Aw98BFBVrScV4gUz/4IMPFE0kt9xyiw4Ooq84bdT77LMPaLM+55xzsMIK+pbJ9XIWsw1RGdNEc9FFF4WCkdwBtrW1aXoAvjRaWlpw7rnn4tRTT+UlzzKkfv78+b/+y1/+gjPOOEObSLi///7704bOe11WKRXKoSciYwHwDdDX7QfAYwAOUEppit7IOV+sIAS8cq+gh9EzhzJ1FaBtbwC7APgVgO5eByIXyuOAPArUPwJs9b9SPRdmuwewF3NrcuF0k0020YujnGVzRt/Q0KAjPQFcppyz6wIAACAASURBVJQ6VkSIyz+ZYOPSSy8F/6255ppawXMRkouVG2ywAUwOUHz00Uc65yfHy0VX5illPlATJHUUF2dnzJihc4HyBM/369fvE87qnejU9O2KCN8y5H9fG8AcAP8HoNlHj6Yhqugdr9wr+vHU6uCeWAaYvy+g9gSwaYXf5fsAHgXwILDQ48CQWYWO17grXsNExob4i18OfJlY6gESVo1XSl1l+yAtL0m3eA0TNH/88ceaDMyet0mqbdnZ0mRzI4AzAGxk7sFdteWMnexhRyulaGbxUmMIeOVeYw+0cm+naQEgsQsgTDXP8Phc0r19BiiGyL8NJKn4PkvZyxPTgdZ5QP2PQOt8oNHa1p3bnzoAaK0D6hcBkn2Atr5AXX8guQKQWBHQs1LahZm3NCvNqtMgd+cAqgWQ+4G6+wud1TsMhMxgPwPAugCo6N9TSpFBMSQmkvR3ABgINNT5umEd4kMlTUXOfRsE9GV0hm1S7JGrgLb5NyqV/TB0875QMAJeuRcMna+YGwLNmwPqQECbGEIh8pH6bYB6ARASR00Fej0JbMnZZ8zyZm/g2w2BJJXelgC2dhRkV32/k1L0iQeAflOBIe2+f9lrUrGSwZHsX7lc36El8wVQp5TKTOTSoYY/0BMR8Mq9Jz712O+5aTlAHUCGQgDk7s4mNA2QT+QOIHEXMJyz2G4W5qycQs70bQFNwMWZcnRRMdMYfwIUzTcPAMkHgMbogiNNIyQLY3AQv1pmAqAN/k8A6NHixSNQUgS8ci8pnD25sacWBObvZswunP12xsdN972bgLabgFEV7iLHmf2MBkCNAXSwTi5ZevjSejGl6BP3A9v1AmYzYjRTyD9NKcMAMFmGF49AyRDwyr1kUPbUhiZvBtQdnIPZ5WdA7k7ZhkdMKZd/eYmfSh/g5OHActsD/UcCvdYPv8RouueapWvCp54/MAl82tnLjn7mmsw883ifGgjMWRpILAMo+vkvnfL3V3SHWRRQAwDNB8+IT9LqWpkNqPcB+V/K5JV4AdjqPXvSb2sbAa/ca/v5xnR3TQzI2R9QDGFfp5NOqNlaAHUjkLw788JnJ7XLe4qKkSYk/mNQEDNRDASwOIAlzLZD0uLMQ2RTvJT/aIGhw01n0m8OcP9N5gra5AcAaiCgGRKpzNMcA521kuO5DwC5Eejzd2ALbw7KEbRqvMwr92p8at0yZm2e2NFwkpAutjN/dM4UbwKS/wAaaYKpNKENnS6YDLfczChzmls68+ChImREJv9lcIdUClhoSaB+aaCtPzC7Pr/10nsiOTtih+wXQF0DJCcAjd4kFDvc5e/AK/fyY15lPU5ZH5BDANnPzGCzjZ8Kj2aXG4CG5jiiPLN1nMNx2roZnk/bNv/RMybKZfKZCat/16Ss45YeLQzzp0J3zR05dDl1BeDL7YGpY4HL2HcXQqsNY4boncn3DsnCclnH1eMiJQH/RcfIL46uvja4iH060HBdlZrKusC15572yr3nPvtO7pw23rn7Agna0rNTEuoW1JNA8kZgwTuBoVQwlSI0p5CtcFcyMUb4Z+hiScoBul3y36vGeyWOsVNrTwNAtsYsQgoW/iny/UJLFoUfRmvPBTb8Gth8GrDOm4B8AajPAfkUkC+BRT7tOqiqie6n6wKJjQEdELVFli+UyUDbgcAo+t57qQEEvHKvgYdYmlugC2DTSCBxhFGI7qpgtAsqGXq73AiM5Ay3UoT+4/ub8W/lKDG+dB5IRZlqpU5lW06h+yNZFDNgmvgY2GVb4IQZwKWLAY83AN+RW4eMjTYgiWMlRwwpg+k+ya+JAqVpJUCdZvjfo4u83wLJw4CRpBnwUuUIeOVe5Q+w+OHrxdGDAfUbcox00h4jJ/+bWhz96mFgbNQE0EnVWE/xN0zbOV9K5EGxi4/0MyevOZNNkye8Q+RnrKPq2DjHSK5y6/fPKToV/uHG/BOtQcXLr6btDV0B7TUUJpZmPS7A8oVFzpcCpGUjQC41Ziq3PtkzTwAaQkyR7gV+vzoQ8Mq9Op5TiUcpCaBpGzNLp+kian92+3sp5b7Y+5YK866gVwkVOv9ZhcmITc5ubwPwnAnpd++lu/dpmlnZ+LTz5ZOPCYQ0CQcC2BcAvZUonMFfCeBvAKJBU+aSzjb8WmvhS52K3KVNZqVzgRE+5V1n8FX4Oa/cK/wBlXZ4L/QFfjkAkD84CjFTFz8A6p9A27XASNqjK0lIsnUMgGNNGD/HxihXkmvdVfhMtiy3+A+joMmtw2jWQoQePaxPN1R+qbDMr5J/ArjIUBjn2W7LeoDcabyGnLrqbKDhTOeA360iBLxyr6KHVfhQH18RqDsKAGdploEwQ3NcHKWS7HdX1wt1GarHe4izVb6UyHNODxCaJ6jQLjDeLfH2XprWqShJbcx/+czas/XOrwAGPx1qyMBo6rkXwCnG8ydbvQzHSbTWRjMWvYkcUWcADaQN9lJlCHjlXmUPLL/hTm4A6o4BhB4j2Xy4vwPkZkCuAUYyFL7ShOYX0tYeZ+zpdLm81ij1TyttsN00Hr6wyRrJLxoGPbUCuA7ABGZ/yn1MpJCYd5/hv7HVJLUe03C9PeC31YGAV+7V8ZzyGGVTPZDYF5ATjdN0trrPmwW1fwGNBS7KZWu6JMe5oEjysfOMwqLHC23LtA+XgS2yJPdQ7kbojUNzTWDs8r8AuBDAJCflYBdjaloIUI8A2Ny5sBVI7gqMvN855ncrHAGv3Cv8AeU+PB1BShZGsgxm86kmxezdgFwCND6Te9tlv5KKhUqcqfbIWU5bNd33Clg0LPvYK6FDfu38EQBf8NxnoBJ/F0ybZx3pOxkn89b2ajFc9/a6WYCMqvDfjR2r35rICQ9EVSOgP6VpSz8JwPJZbmUGIFcDySsqPEiFft1/BcD0cpx4cA2ANuUXstxXNR0eY7jimVSDHkjlEBKLcRZPjyJ+CTH/Kfc/7LpzZstqJf4rOdd+AyRGAcNfc475XY+AR6C0CNCNrfkAoPkzoFmy/HsRaDkUYBakihemk6O5hTPLjx0FX/EDz3GA9HHnvTGbUrmFSUi4nsL+mbWK6xfRAKYMY5q8JtA8I/LbmgE0ke/ei0fAI1B6BKb8Cmh5JvJH5yr4p4HJOwJ8AVS8MKr0VqN4aIK5LAvvecXfSBcD5FfVboZdsotLYzlNe/x44ypKJU/6BbJfdiFNQ4HmnyO/tW+BZkYAe6lgBKrhj7+C4Sv30O6sAwaNA3Bq5sAj5vdMng008vO7suUsrIwmHIsncQTmoi/6YRa2wxSsDyZr5uLph0hgGpL4AIG3tZfwYa5tYgI4m+csnl42t3TefsvwVDpBbb+3l84F1BFAg6Uqtsf9tkIQ8Mq9Qh5E18No4cyPLovkHYnKq4AcDzQ2R09UVPlcLIF5ILvkoZiK9TQpAOeQvzJhOaRBzyykpGUw1StQeB2CJxHol0Dmq/3RrhAgKxln8VykpnmGAWA01czOXnHylkDiIbNA6142EWgIKowF1B1fj933yr0qHn0zP+fp283kEa58BahTgOE3VzRd69lYEa16wfdQzMWCIHX524ZGi8uM67q3lPM+PUBoWrgfvXAvTs/HnzvnPkp1Ibl7qVAriTWT90YqYtI10Deei6RjAXRCBNc0BFAkFVsmAswNwEK/zTFBeKSqL8aFgFfucSFbknZ1XtKLAOGnc0TU3UDyd0AjucYrU87CqmjDWQD20GYkquM7DDs6Le17RXgPC78L2urpgXIH6nEbzihJ9Gfho+lYk+RgXFClOyKTZFeS0EOJphWyUJKbh5QGnXwB6uTnjIKNLKqqh4FeuwFbdDL7r6Tbrv2xeOVesc9Y832QAGtwZIizATkBaCRhVGXKuVgM83RU6ZFpmtv/GbJakgaQ5mtXPI++uBsKk1GHT5DAPMzFACTQH6KpbleAgNmRVjeKZLXcPDx0wopHoXApBA8j0H7y3Y3Tb43P+cmGpbK7xxPtn3pgookE5hM6zFA7RK8zZR3oRB4fMla68gCwxG7AYLbhpZsR8Mq9mx9Ax+7p4TLlSEDImRJ1YXwDSO5doTQB9KheAIJjofSCL5NEpIROeCTeJUnwr/AiRuMgnKVd8+wVXW8DvZhH6zypc5lwgoFO7X1kboHJS6/SJq0APpVcZozco+So4aTB2uT51ZVFXugF/ExsGRHrCM02yT2ARlIgeOlGBLxy70bwO3b92GJAr+sAIbGUK1x2vALofWLFfvYGoPWc/OCcbbfL84Z1XKENA3AMvuV9lEACvRDIfHTEir7j2S33gh+hcBl64684rZhEFyUYd+U3waxV/wKwiIloJVFbJ1z4TRcAitGwrlwKjOACrZduRMAr924EP9x1c6NZ3Fo2fJzKqIKz46QWS6nUqdzD0gxBMxQUZkO0j/fD4QtKWJqIwUhqLpp9TDLSTI3PNDPTi7x7ZSZ40seYGIQ8MvTQYmIQLuh3ouBbLk55a6XrM8D4t0AD1xm8dBMCXrl3E/Dt3T7QB+j7F8PoF3ke6n5AHQIM51JkZclV6IXpOAFJnAkFJqAOy734DC+CyUGZUGJHkyYufE0cpTtRh7exEwRHm3D/TL2QKI0sh5MQ4KNMF5TwGNcKmGSDZFxPlLDduJuiRww559cxNMJcFM9iS9dJP+grzxerlTYguYsnG7NwlH8bUSblH0DP7vHxVYE6RmfSvOBKK6ACYPh5FeniGGi7998zLPbyHt7FjXgZH2l+GL6URhSWQMKFo8D9idgSSb2wG134sw2SSI34n4sA79mDJd6SzI18MvSSobdMNQm5aZiikIFPXDWhfxMxyyB6kZUvL2aMsvItIEOBRq59eCkzAl65lxnw9u5aDgSEFLZMPOEKSZ32A0bQh7uyZBL64RcwcQOzIEV/O7OhcB7OQgKtmqyKLpo0Nb3R7TcRYIiJ6iWvfSZOFS713gbB6ZiAT0o8XjJ0MnMSg7Aq75l2fbOLA3gcwPoAGMREDLOYaHRSGCby5kvByltA/VBgGE1iXsqIQPQPtIxd99SuuGhaz4Ak/pFE5VKg958qctF0AkYhiWugdA7Q6LgfRB2OwZlaiV0OgDziXJirLFrhQJsYOHum+YAeIVGhj/b5WAfnYKz27Yme76llZsHiDJ5cNLebPK5c5M8g5D1KMu0hA7esPAJ8PbqCkqrbcdX01iv3sj7eZrrv0TbJ9GiuzATU0RXJ03E++mOOTmVH3+fo74Wp4o5HoL0rmLiZ0Y6c1Y3uPBDGvfVu2CevTZuOmKUbX9TdlAN6GAtgL/wJP3bD6Cq1S0axUmmvCuBsAJ3kVm3ZCxDGaDi/F5kANJJ+2EuZEHDAL1OPPbIbTfhFHg+SfkVnjM8BbfsCoz6oOGgmYGeIdl2MevBw1savjxMR6JD6oWZmR5MHXRP5+V75Eugweia0oLtfVMm3YCC2w7HZTBCVf3sxjJAzd5qW+ptFYuawzSLN5xpTmD3PdH17AA3/tgf8Nl4EvHKPF18ALasDwtk6swq5Mh9QJwHDL6u4RdMAtLMyExJn41FhrOnhCDDZnOBMjnZWEgrQK4Sz9+qSQCekoDvnzpGB34ggGqQTuaLzIqOLqQz5/PkCqQVhAm2yjvJFvoOxx2e4L+1BQ7KJPZ2T84HkzsDI+Fxinc56+m6mxaWejkkJ7795T0Co+KKK/bMUl0fDJRWo2JkF6a0Mip38LZegH9Z3FDvtqncaxc7F4epT7HzadIccj10gOrLWff4HYyKK4S0nbwvdB7O4ELpdVc0+PWK4oN5LL0IDdPXMIEoAYdYnl4isF5C4A5jsetRkqOsPlQIBP3MvBYod2ni4H9Cbipt26qj8B2g9HNia/t+VIykTBd0bo9GxzN/zNupwGMaFvD3426Fip/8zZ/Eknqr+kPNAJwuhj7yV5xBgM1socMtEGbWk4AkDE2+fYLyh6MqbhTBs6hpA25SIB833gIz2+VgL/DXlWM0r9xyByv0y7S1A32nSY7kyC1AnAA3k46gcEShM0KYH/rFGuVro0zwJAzExg+35DwAuAkAzDf+4K+tlVSjCKXdP+ry7tLYbIcArhTZZo/XqjHmGcQyMRCU5WhbhTD1Bb5sBzgU/A7JbVSSWcQZdTbveLFOyp6VtjH8EkrSxRhX7q4AaUnGKPcAqmKAjJ6/LoNhf1ko7wOkZFDvD07lgxkhPhqbXhmLnb+Ek/AKlvYPcXwaDd7yEEWBsABOvMFCN5hdywWeRkfz9k/+HmZ+sLAQwArvpxCpJB2nHXTVbr9xL8qjou97yX8PkyE9wK/QQ+CswazOggekpKkMC1CMAvURezxCiP1cH83A2nnm2Sjs7F8roXcI2mOShtkT0/XGNwQo5zvMV/m0dA2BkvhWr6PovjFKnoiedQyc5WRueMli4VBq9ATUJaHkIaKIvvZcSIuDNMkWD2TQMUDTDkGTJla9SdKgjSLxUOTIRGyOpP6NJnxuVp1CH3+BMnScpes6Wra2VvCO0s2cJZrGXV+k2AJUR4xIoggXRH6cgnyhLehEx7J725kypEU3TNbGZZF705AAlHXMnay+T1zTp+laK3DmV/ulAw3UV52QQGWi1FP3MveAnJQmg+VRA0ZYYVeyTgcRGQAUp9nOwJAJciySeM1lL3Tv/CUoTbW3VhWJnWrbjjRmGAUC1qdhTyLg2doW5nc1KXSjT+7NSykrPaNMHa3SHMRz8XdErrAuq35HvAr03NmRkLhxLpGz3Lc8DmiHVPef3C0DAz9wLAA14chDQehMgnLm60gowEm/EuRUz+yB745c4BoJxUDr4xB0v95ky7UgEoHtmZ7Kg8YwgVwp9l8n5XbsSaE8QfqWkRGFXjAfzh3rJjAD59JnqkF5B9O//OPNl9qhOSnMCIOcZt0p7wm6bATUeaOCXj5cCEPAz97xBaxkJzH85g2L/FJBGoPHsilDsKS+Y3fAluDB6YQbFTrPRXmCSja4VO1FidC0VO7lFaluxp34T4WTW0oHgLe9fTo1XIEEcF9lJ/5wDjzv94BsuBBRfBKRDjsoIQFqA5seB5mJiDaLt9piyV+45P2rtDXM6IPwhum5ypND4P6D3hkBjZfB1B9gaE/AMBAz1juZg5eLX39EbgxFoP/VcECDlK32aybVCF8jaF6XJz9rvMxNnfftZv5dCgLNwOg6QBdPldu8En4ZpwIjtAOHXYKavRy5ITwFaHgO4vuUlVwS8cs8JqakDgCn3AkLCJPr3WiFJ1nHAcGZ9/84e7LZtgC0Q6Mz1XOyMcsRzWC3a3h7gqDzTzV1sEl1zZja92+6vvB27Xk9cXcjCY551UIzy7Wk8Kvx7sC9/LrIyVV+O0vgvoPcagOKaDr1wIiKjADU1peQnbxk56YsZEPDKPQMo4UMMSmp7ERBmE3LlQ0BtDoy4FOAnZjdKgEEI9MIdvxwyeWa8DKXNLyMQ5O26yAhUri1QWVHJ9wyRSHap6Ey+cxTIZ86w/OhCe+e1auMseWPICEmyuZPyu6UtZgOk5JBVUyyp+LRjfSr5xBMp98mWjTqe90csAl65WyQybltOAZLkholS9N4J1G8ANNCe3X3ClHITcBSAd0wW+ugCOXk99sJ4bIzxeuE037GSP+R8U4kh+fnOXvPtr5Kud/nIOS56v+QqXM9gfRJr9UQhZz4D3DgLdxN35IhF4xyg4XKgge6SDI5y+WlMG3RmkBeB5ptSDg45Nt2DLvPKPePDZl7T5hsAoWJzKXrbAHUG0LB3t2eWOQur4i08BQEJu9ywbt7RN1D4DYB1tV1dFeyySG4c+ms/YCh9M6JVkwejNnaJ2OC7vmn6ejMbVU8UZrMiy+ZCmpatYARUEhhxF7DQeoCQVTM6k+dk5gBg/utAM11zvTgIeOXugJHafWxJoC+JsA6OnJoBJLcDGs6pADPM/mjTbmdRuzoVymXogzUwHtch6CyYJHJ3HYt9ANB/mSanThIzdKxYE0cklEmIt5TPzL0mICjyJri4ynUoThCyMEfm2sOQ+UDjlcAs0mcz6jdqkyf75vVA820Ac7l6IQJeuYd+ByQ4qmcwBqPsXHkakF8BI5lLsvvkz1gYAW4y1LrRxSq+kEhwdSxOxfclGOThxmbMxMj0X+5pElUSLi9KV1gMB7BhZPG9qzq1dv4HwxxJ097E0tzc6LlA49+AuWsAwoTjUabNvQH1HDBlndL0V92tRG201X03RY2+mQRYVJyRP2q5BBh0MjA4+kMqqre8K6coeUllwETFrsyCwvEYj2vcg0Xuc9Y+DcByJprVjdYssukqqR5of36XMGxZBB1mjNluhh5FZNjkb6mTUPxs1WvmOJO/k4KByV9Ipsf9EkrTWkDiRkCilMw/ALJzxbgml/CO82nKz9xB//Vmmh8YmOMq9rmAOghoPL7bFftZ+g/jyQyK/VXUYUiJFTt/PzRJ0dODmPQ8xZ76C6JCapeBOTNf0lX2RvOvJyt2YkcuHmb0op6hOaXE0vgO0G8rQBhJ7HqsLQqohwB6uvVc6eEz9yYull6bUuKhH8FXgNod0Ex2oRNlLwTaX/1+M/ux3fOHfBkG4uQMdLz2mmK2ZItkODk5QHqiSYbZmfhSsxmDZiLIx2e7GOi7sW6gmT75tbYMlPFyEbQhoV9s3yGJb8GXXH55ZfmS5AIrX3RsOxz5W7LbbdoJUExn6JorPwNkE6Cxp8RmhNB0PUFCJ2q/0LQAkLgdkGjmoVeBujHAVvxBdq8E2FZHmYY9N1qh8Du9YBrP6EgORsVOn/meqdhTuLbP3KVGvV4CDITCjhAdG0GfcT73VPCWOw92yY+5RBpoXnZy+DMalabC2xHg6yw/R3oM/QPA7wzv+wVZrivycON9QNN2qRl7mkNpOUBdn4pR6eZYlCLvrpDqPXTm/mZvYMZ9ALaJgPYfQA4EGvNZPIs0UaIiqXnb0IKwYmcqs70R4L8l6iVTM4yq5PoDEzGQyrhnSqDTxpGznvICgg55cM2pKtyQniIVYMTQ/uIneHQTVbgSwAUIMkYwr2FeBHRlpOdMjOaqyQxyouuuE2FMDxsuxPYs6aHKvYmmmEh+U3UlMPyoiiD9Go8VoPAMgKWdn+N3SGAMxoG297iEUYUfGg4Z2twZiNLzhF5Js0Pmg4cQ5ByQ9FfDPcQk0pVlDgh0QNCpxpMnjuc6WydtFExCAHe+z74eA8CvQn4pxzk5AdDMyNi/ODc4G5D1gcYSL+g6PVTgbvFv7Qq8qc6H1DIWkIhip1vVCEbVdb+kbLv8qnAVOz9tGzBOUwDEOUamS6PrGrPq9EzFTnTnd8glm08awTEAVgBwYJwPKq+2mU6RZHEpGolsVRl9/KahdeYMm77k86DQB4LFgA7/GLU9MNLYghAd0bwdAhwYYRvlzJnKnYv1MSt3sk228DlYorEFgQTNQbtGxlvTxR42c2+iDY5p4dyIzuuBERFl303PPEXTSw8VN63bHAi2wQRtA49zYPwtfACAId/8dGbi654pAegnTUVn5QoEONIWutjypbwioL+8uri0DKcnYD8InQb0Ymm0Q9Ik3AHBXVgMz+e1UMrf6lkYgqROjM0XGScFrnyFBLbDOLxqDtJM8qWhBCZGpYjFcPuL7DetBijSENOt14gaBTQwHqRHSA9yhaTLo+LCjqvY3wZ6kzOlMmSiptV1FTv/hA4tg2Ln/dNXmLMxJvjuuYqdSCQ6cLfnk16PCowmte6XABMg+GcGxU4uosMxECsiwHH695WfBwxASotxeB6BprmgTf2hyA0viSSaMRGWwZFxIsy9S2XbSTLtSCsFF7UJhhQIjtBlknqgZ0gPUu4tZDd0kxXPA9R+AJnoKkDGYxgEDNl25WyM1wx77rG49smnTbnTbHvuJlmUcq8M3AKQcpcJVtoltfDJpObr6ZSL+Sr09pbCewE+wniMNnS/pP21siiSeAxB+u+ObJEULtaXQRYgRbfrxbMh0MRx9gjpIcqdRGBpdkPzYIUpvLqX1dH+xJjfVOlZjftpOxnrYIK9JOYtZzOcTXERzCt3FVHuKufE2JVB8xvgHJOw2v3ZvIReGIzxuLBIziG3zfZ9zuQD/BUKO0B0Uhd7bgHtzhvoyGq6135kbOHRBNn2+hJuh/4EyFnhBuu4oNwjpIco9770XOCikpVpwKCLbKFbtzS8zNcLmG52py/RC/tiLJg1qRxCAjIGmNCcQLNCz5ZoSj3JWbmTRZTxEVFuovLhGYAzc0Zcu/Io+mE4zugqr6lbpcD98WhCnfabb/cUSuXufQDnYCkAdzN1mXG3LbCTfKr1uQ4A1xaMyJZAC7l/al56gHJ/gbzap4SfZPKkbqcUsAOaoBek3E9FKvR9cbr7g7QXx7b1JhkX2sJn7lyEZUJnJjYpv6Ts364LIMdAn+8xOClvyuLCx89F1AS2j0SjLov5uAML6PGw7Why+cL767Qmza5C91RHhDkQal56gHKfyZV8unJZmQKMrIws9mdhdQiiEXtnm1R5drzl2DKohRKzi5rppfI3hSbqGG8yYZERsbwSgGtKDCRyFwybsQj2QNANbq1U8Ep7fbmEe1vhRNBFkRQEnD3bILGYsWq9wvDc2H52BUjtXdtS48pdEoBiYmdHJLpo6Zwr426AerTh5kgEKumGuQhUTuGPnEyTDF7iPy/JkIIkJZUbjF95+JCmAiCvipvf9wUdMHSCjrTtnjGPBymyw7PkehyLAfrLZsEsKSFjGOs2TOxOryErvYFeTGZT01Ljyr2Zs4PVnSf4HjDiEafcfbsKpxv3w9QY6MlQh/1jWezq/C6JEWd7TZ1f5s9WJAJ0NRSdiLs93F4058sOCEJRtt0z/ED72NPubUVhcww2hSj9h70mhq0wMM8ROcgp1ORujSt3tW/4qcllFUEvMBGbQHBGaGwJ/BFnag710OEyFBpNH165W7ATBc3UDwBwVQZaZttq6bcBNkQS90W+/j6GwrYIKorsjLEk7esQa6S9kfjFUSZp5JeM6x23eq1TvzYDwwAAIABJREFUAtewcn+Kn31usoW5QD0/XbtXAvRFEjdHCJvuw3itGLpjbA2m05bu6Lwi+xS4vtocYtQGn2nYXEAkfYO7vpPputIcS3H8P2ySgtg2v0IdtomE/dtz3bdN2fw5U04RhjGNCf+lWCj7l29g0dl7W2TyV76RlKOnGlbu87hI6HA7k7x/q5hDnnN6ZAwuYVYaKwyy6C76Ay5orWUy5ESTD9vx9cRtdEE0pYo6R4Luh1zUjJ8m+WysiDY8CoC5Q638oMP9u+frz44h+zbAC1DOelKKOUlhQDqCNXvdkp3pRcZTh9BM/bqWI1ZrWLkr172QP4+7SvYbKbShQLuHMYt7uyj8phMu7Pbr4tkjORjdRMNjiqevamo1rNxTftpdjf9j48PNxbv4JMBSaNWKnaydVmZBsLPD42KPV9ZWdHAVE8G00+Ktgj+Wb5DDvgDUVKe/lYCpmzjlmtqtYeUuOzhPqg1I8hO2++Rc/bnORR3XVe1qjMe93Tco3TNdMUnH6sUikIiQWgmWsKe6dZvKo9sccRKYD4U9ysQ/VNztB9osQ/u7wIbszUUDAh1AV1zbOdcWBlE5ktzRKdTUbo0q95b1DDOffVjPAo2kze0+mad9kF0a32nop4nCum9MvufMCCR0iLx7blW3kGGfuXfd/LsZLiny0Nkg1z4XvV2THk0MB2K8zoZUZAdlqh7oIK9b08p9unbfnFim3uktGo1xod99TUqNKvfQrJ0TBaYC6z6ZgF8be6wdQysSOKCsUYO2Z7/tGoFWfB7hsydnTGdCn2kyR8bDMMqZbatW7GRftELf+6MQ4HZ7oGq2dTgTfTFPr4iRKX8eDkCgqabLcAs6faZL57wBQCrw2pMaVe7R0GbVfSaZ8zAAgstCPx0uLI3Ds6FjvlA5CKSyCLXTHgtWB4POsgsVLbnwS5/p52zQth41xbC/IxHor8Hso6rUM2fqYLmr9HIw7+Q7je0fyjdc5U72FJCwHmPlG0IZeqpB5f7Ewk4GFkL4NdDwYhmwzNzFXE296ppjXkZqYSnz9f5opSDApC4pYR7bBDa2xQzbS0yCkyineYZL8zjEdIutWrG7ZiGaYo6oWsVub78ef0Z/47nC5WvBYUitS9krYtxKNGGHzdgUY5/lb7oGlfs8Bka0R+tpk4xy3J/KCHKKx/pQp0f6+dI7JsYEwU5vfrcYBMJ+/4IRxTSWd92zQIXOGbvLZtqmk7ekoj7zbrKiKpyBz5EwbqNU7nyB0jxTFpn/VNglUrxyLwvuRXeSiCyQJLqHDIvBSsDVEe8YcmnH7wddNIa+AaNY24EQzd/SXo5zL8CmaMNTUDozlu2JbKFcPGU2sdqQb8GUknDY35lftQyiuWZs+j/2NxiYUhkeUSW8+xqbud9J4iTXv30OkOwuLhkm2nA/p6dhkbIl3yjhT6SHNjUe7wJwA7tGIJVoOgoIeVKCEE9Q9Ip8yhOws/GKcQOUmLx6XwS4NZ+mKv7a/+kvE6A9qmADBPhVmcbNxCFWFNDafRz8dhQl3taYcl+SeUAXb8dItQCNP7eXy7QXYIhJOWY75LLREehOhj47Er/NDQFmFkJolsy/lcMzVOZiHKl+iyPBSiVHPxWC/4ToDkgox4TpQU1myGJiE3fmzlKZZu/qyfCzrKs500yNKXeJBCTI/eEHWIbSVToLPLPNu/Sr13QDR3sZbrbmuyCbYft6jeD3YIRoWPhlyHWVe8KH8yidj/6YgP9AcG7kd/M1FEYiwH15tFZNl87Qg2V8rRXRXyjOmpk9UeptnRupysa3KnUP3d1ejSl3Hd7vYNoN/u3TcTKADZxBfIEF9DHnkN+tCgSY+BlonyCkaAgujoyd7o83AHgjcjy3IhlC5yDFvR6u8R7qsAUCkOO/VoWOBXMwGzQ7pURhMShtmrJHYtqSisBNOygbAZpsMKb+yt9sDSn3x8jGt6ED4btAY+n9jp0OOuwGWKsDlS8DTf7kLBl1qOQPVDgCzEnqskTujUPAnLxU8oxVoGK+EQCjonOXAAsgwHlIgp4b0SCp+9AHQ3Gm9p3Pvc3qvPInzENYDwls2seY70hcu3tvYK47KYu57/ibD4Maf38x9lBHXnLnfhRZ88onge77mkjqsLsQFPG5Xr7R+56yIRDgPQBMfJ0SLrHeDvq1Hw+AicXp/046Wyp5pnTsWugiK9pr6k8R6me6Oo7DeIzBqRF+m65brdYrZkJ0VjKm3rMyGnz5xS4q8lWUYEaymhFHGVb9PUX9kMubfEJp2l53UeY7QM/wqh5YfwNaub+pjQfkFp2dERHaiflydzN/hS+ciI0QgIFOj0Nh7fBJzNDmiPE4C6nF3Mjpmi2StgH4RafkszfJQESb19cei2ObYqhsbzm/r6/2ehW5V0PKXdmMQgQ6CfRiAEh5JMBAsxjW3p/CiQgwvf2A36taBFLJJsbgdfzYReI6KvgjQ/c5Cf0Q6PSJjyCpZ/fbhc6nCneiNwZXFQFYhpso8FDKm226pjF2m9jdLcSzLzWt3F362XjwK0urj/YHejERh72fV4ERrv093lEEuDzyR92M8RjZw2Zg8WJcCa0vjOsxE4d0OpTF8DGO0WRe/Ywdnnzh2TI5fQROAsYjQkPbaQ+1dpIuiVtgZayFg3QaPGZQIx3Bt1BYKv5o7mZOwJgknvINMKJmgplqZOZez88pq9j5y3jGPKz4N/zUBn7rdEQPgGO8YncQqZXdmaCHRecyECuaBChkiKQPfCbF/gMUTsZArNXDFTux7KUB/VCHMrVz86S8ZspB6NXOIaRjZJ6wTPOdP+cqOFsjyl1FbGWJ6OdWPI+CgSdJ/C3im/w3BAW6xcUzSt9q6RDoOqmJywTTsV8yTTLgaXWMxyQcG/LC6Xh1zzhifdrnAWAavHYRlME0g4iumBfRJe3Dqba9GlHuUTe0tsJ8jvN9ehO0y5YbtjxdO7jl246/vloQ4DpO++wyOuoBxncmfJxRmDdB6QVCUgdPRMDPfy8GAavc6evOYC0qeSu7IuWFZssxbKN299rxmOmMozoGIGNrkvwejiiXjN85XsLdFL93OIOMwmnep72EGFdmU/sav/YwQZ3Cq9gQp6EPZoNfdAnMQB98hFN0Eo/KvJPKGJVV7vMQ4GcE2mvGpsikiWQooGMBYhpt3VtuEDIgbqarmPosT7M1oNxFAS1u8MEXZUmpp3A4JJTy7FVIiIukPE/Q91JuBLhwv4teBORCYIpm4g0IHkIT2nS+pHKPqLr7oz87KR5SUaoKd0FglTvvbI94lfvcd63ZPwWjcsn+qhrZGlDuzcsCqr/zFMoxa08giZPcJVwonIPxDg+JMyC/W5MIMLKU/7wUjgCdIMh+SY6ZFL9ML9yHeSC9seVm4ov0hMK76Kom6X+b+cKmUY2ystlW/aYWbO5rhZ9CGUwyDLAIc22/jHGGmzo8GF/yCHgEsiMw0HjLtMeDnKYVvUvqtQoCuLljs7dW8BnVnlIRWA5405qKCm6xEirWgHJPRD6jZFoZgHVdH9ndBd71sQyo+y5qDQHLsNmu3HmHCg+EblSFzDShU6UpJF0Oqjrgq5qYvdeAcpeIck8yUXF8EmAhAC618PdYRHNwx9enb9kjUJsI2OChqHIPu5wKNo/39kMzd1JUde7QGu9gStZ6DSh3FXkQKl7lDgwH0Md5Anf4JBwOGn7XI5A7Apln7kkwBZ7LxBmzWUZcswzN/5EJY+43VElX1oByF/cTqg0YlMruEh/K4Yw7qhO/5/jG4Fv2CNQCAsubm/gydDOBdkxwTSWra/fS0EWlLMiHkdZWipSrslgDyj3EwvcJMNgNgojjobhBS23ojSlxdOLb9Aj0AATWNff4VoZ7dRXuQpgA1yMuw+XFHFIfR2ovFylXZbHKlXsT86WSHtRI1HZmj5doy+AUYab0tEzrQbzb6Zv2Ox6BEiGwjmknk/syKbPbRbBIe6HUe/PCXw5QS5e6h+5or8qVe9Q2JvHa28/BClAg25+VTDMOe85vPQIegewIUPfQjZk+5pkI2cKJ7ZV2ZMjeWlFntmMScjdZiFfuReFZksp1EdtYB9tZSXpJN9KGyOIt3k6f8zseAY9APghwrYyMmdn+hsLm1UTIiSGffnK91vXY8co9V9Tiu05WCLedYBK0OCVMB6rweZyd+bY9AjWMgDXJZFPuDoW3RoEUBXGK+/WwEPBMjGagOG+jve1qN8ss234r3Gv7LFwucUnSpP62Yfdtb4/5rUfAI9A1Asw/S3nFbKObsG5KGnqC6FWlK0fs7rOqfvYeBrB0QJWpJRVR7hKvcm/nn0jdn/LUrWV60L6b2kPAJuJoyXJrqSQe9mSdIRaz5dJvIxO1OhtgVfqeytRitSt36ydLuASYG7dyj36quYswZXpkvhuPQNUjwFR6nLmT1z5b7gU3UBBoCwU1xQEAyctcoSdeVUuVK3dx/VFnAKPdqLY4HkxYuavQCnsc/fk2PQK1iADzylJ5P5Fmg+x4l2HlXh+3clffhoeQJKlZVUsVK/cm0hXb8GU+hLhn7ezD8anXpKR+5l7VP38/+G5CgBQeFJf90RxKb8LMjK1xK/e2iHJPLJYeSZXuVLFyT3DBw3I+E/5yKPfwzH2ez7JTpb97P+zuRWAr031nyj08cw+n34th9Ilw0BTEz9xjQDnHJpORxVTlujLl2EaelwkWdWrMQRDK9+ic8rseAY9AFgT4NzTCJOh4Kcs1POxO3Fhu7eTaEpxKRpW7n7mXANUCm5DIarbEr9wBd5El8hlX4G34ah6BnoUAMyvR5PIf+i53cuuptHv2ggUQ9p6xx0u27R1ZUE24Jt+S9VLOhqrYLFMXAV99VQbg3E+1yJu+DL37LjwC1Y/A7uYWqNw7k7BynxO3ct+SrpBOVKys2NngquFcFSt3Ye5FR5JfO4XS705CP6gQM105Xialvw/fokeg+xCgQ8J2hk/m8S6GQb4XV1yTqHu8RPuKEbDuup1X7iVCtoBmVES5J+JV7rMR4bHBRwUM2lfxCPRkBHYwLpAPAl0GJYWDihIoR8SomwtiYWCqTZpdlc/Mz9xzfWzJDlnRoxzQubbkr/MI9FQE9jE33pVJhpeFlXuyLMo9kn+5deNqflBVrNxVZEE18mMo/VNh4IUr77kFv+8R8Ah0igDNHDsbet97Or2SJxWikyfSA8cs8lSkg2GRclUVq1i5h7xlZgGNYf7n0j8GG3hhW2Z0nRePgEcgNwQOMe6NN+Tk1pjAa5Fm14+UYyjWR5S7crOuxdBfvE1WsXLHEg408drbr0IvCNyZ+0cIMiYYcIbkdz0CHgGDAH3WDzOuj1fnhEobmGZvlnNtGZT7MJplXBfnzYA3w5GyzoAqfbdKlfsL9Hl13RLjVe7TsW0kA5OftVf6L9uPr5IQGA2APFCPAHAXLbOPMZUk2w1yWh0BwvkUstcu8IwSAJOdyosAMyx7pXO4OnarVLnPoluUS+ZPdrn4RHBAqHGF/4bKvuAR8Ah0hsAR5uR1nV2U4Vxz6JhCY6gcS0Gif9u7xtJNGRqtUuXeFs2E/mNsWAU6Me8Yp/0fILjXKftdj4BHIDsCGwLY0czYo4oze63UmabQBYLtQ+VYCnUPRyJndwLEnUjG0mscjVapcg9xvHASH59yV9pWSP5pK/9CgDm24LceAY9ApwhMNF/Z5+bg2x5uaBE8DaDdUUKwMy6NO5fqcNIQPOsMZAWgZahTrprdGlHuwgzqpZfUQurxoYYTuDFU9gWPgEcgGwJDjPsj3Rqvz3ZR1uMnYDaAB9LnGSH+PbZOl+PbuT3StPXPjxyu7GKVKneJmGVimrlPx94A3CTcz2AcnqzsR+pH5xGoGARONyO5IO9Zu70FhX/ZXb0V7BEqx1Jo+zcANyH37oBUna6sugGnnmVdlGfih5I/4ztRB8EZkXYnRcq+6BHwCGRGYF0AXKuiJ1v+s3bbZl89c3ddIseAX9SxyqjPgdAkblmguep83qtUuSejnA+lV+5vY38Aa6R/Q4K3AXQdWZeu4Hc8Aj0aAc7WqV/+HPFXzw+Uk0ACsYecSgMxHSOdcly7UdMMv+KrSqpUuatwRiQkS7ugmpq1nxZ6kgoTkfK9DR32BY+AR6ADAqT1Jfvj6wAu6XA23wMdTTP75ttE/tcnyH/jmGbUbtVmmqlS5S59Iw+rfUU9cqKg4tvgj6d91p7K0H5nQW35Sh6BnoXAAgA4a6fQGaGzhBzmsi42Kdfjmc5Ve+D8EP22c6pUu8O/BJSbBnAZoGnzUrVejnaqVLknIvkV1dySgZXykBkfas/P2kNw+IJHoBME/ghoBlWaMN1oz06qdHEq0O6Q7uSqL+ZqZ4cuKhZ7OhlezEWC/vpVI1Wq3CWq3Evndz4dYwGs6jzB1yG42yn7XY+ARyAzAuRcP8VkNOK2dJJAOLo1qeNPStd+xpYS/weAlARW3GBGe6xit/UVO7LOBxZR7m1OeqzOK3Z5VnBs6BqFCRjv2t6cs3/GwpiNswFsBGjei4VMfkj+IC5GoM+1VwjwVwAHth/Qn6xcuPkDgrgTADu9+l2PQDwI7ASA2ZboVVZaSuxxeBoB3gKwjh66wiYIsD6CDuyRJbyzhk+BZvY52DQ6GJi6ArBVbvw4JRxJIU3Vysy9NGaZ8SB/86YOkK9jfCez9lMwEwGOQx0Og+ioWXLM05Nnxw6KnY0ujZMg+kWxIBQuBLA2AhzjFbuDuN+tZgQ4UeHs9tRYbkIhyih5eCz9hBu9P1xsjVJ/h09XUKlKlbuKzNxLRAegQrNqUpNdldOzOhPToNDuXaOwZsZ60/EbKJ35fQeMxzkIEC/hWcZB+IMegdgQ4KIneZeKX0TNNETBbaEk1oJ94qcjSE4JD0VVzaJqlSp3rSAdzNvCmdKdMznvBtonl5liUiL4BYJ/2GKX23W0TTD1KSp6hh4mG5qAvSAYhwQaECDMdtdl4/4Cj4BHAIEOiLovjYTCYvgOu6TLsezUPxdp1v2yj5yqrGK1KveIjX2B6Ew+f5QFjEBbKl1R4UGkVunThzrdGYs2qLQL2GBMdDgwAmwLwV+07+84vNxpO/6kR8AjkB2BjqYZSyecvU5RZzSR2AdOExsAOp+Ec6gyd6tUuQuj1hxp6+cUCtvljNoVhfYZgnu8s/3UTP9LfYmAbHhAAPJBXwroGXs0dVhnrflzHgGPQBSBtfEYgM+cw404G8zPGqOoN5zGewE/xpw0xOmtiN0qVe4qotyTxSt3weohHCVE+xk6lbUQgF8U15jzQxHgLOM5MAYBPspaz5/wCHgEckOAX8gImUsTaMPBuVUu9CqJeMckli+0pXLWq1LlrvkmHJykeOUOrOY02IaBOoejcyjH3V640ln0ORZ12B5Bid3CchyKv8wjUJMI1IFJttv9zwWHgJQh8Yn7pUB6eq/c48PaIfDXndQtVoK+3Af2BY5FYe6Vp4NmGZupaWG0ab/fEgzPN+ER8AhoBM4EbeCuU8KKeAs7xIeOfBFuW+jyXPFSpTN35S5w8CVugwyKAdwN6Co84nUitgLA1GJsgx4zfypmUL6uR8AjkAEBpWfv7okYF1YTP7kdASrKbRU+XSGlKlXube4CR6mUu+u66LDB5fGkAmyBpP7RMdejDbjYE4GJqsujKX+pR8Aj0AkCgrsg+Na5YjQCLOeUS7kbmewpN+1mKfspaVtVqtwXIbe6o4DVeiVAxVXu7fa8XBs+Sy/I0i9+bwR4H/W4yGSfIcbH5dqMv84j4BHIAQHmMQ7P3uugEFM6PGG6P1fIfFnxUqXKfQgzs7zjoLsu8Fixdnf37UyOmNzlLKyKNjCz++EI8IKueAaYN/IW08hBMc4qch+nv9IjUFsIcGG1XQRxsTa6JltaCvKf/LWPsmx7VarcNT6POyglgPpis7N85bS3JETby51DWXYDDEUbyPtMjhh3kYd5aMhrzR8Cg6zi4dvIMix/2CNQ8wikiMTed+5zGM5FsZM8pzm7q5awe2Y7I1KuyGIVK3cVVqRAY5EIu8q9F87DwC7bC3S6rwdA5shAB1eEq4zDmwCeMAcPQeBEwIav9CWPgEegMATcFHx1mK8jzQtrKWstWTxyqio4oapYufeicncJisYUmQYrFVlqn+K8TqLe6FM7AUxK8DCARzG+E4IxhctMk1yEOdc277ceAY9ACRBQka9lwQYlaDXaRNT10Sv3KEKlLW/xHRCavS8LtGxZcB9Kz7Ld6nRnDAtt6xPwB7yFVyDa5EJb3BwEyOwaNRHrQXTyD9vOwZiAMzEB29gDfusR8AgUgYB04Grq+HdbRPOm6rrhJuTDcLkyS5GFgsocZPZRJW8H1CjnPDOUu3kPnVNd7IpO5uteFHmgAFqxNBLoDYV/OhfOQy8wQpaLvGFRmo6AiXYfTZ+gBV5hGW3TV06UXfoCv+MR8AjkgQBpPZhDOeUEIbG4HbsvDDpeuM4ceQy1vJe67n/l7bkkvT05CJjP6DEbevwF0LA8oBw3yRw7CrSNnZ9bFpNnEKBquJtzvEt/mUeg9hBIZWOy7tA/INAJc0p0n00LAepH0D0iJS8DI35VosZjbcYOONZO4mt8y68BtDjtLwNMYTal/CXAdwDc4Cim8Vo0/4Z8DY+AR6DMCLjOEIsiQCn90Ic6ip239WqZ763g7qpcuev7ZmovR4SmmULFfVEwKIJUAl48Ah6BykYg7JpYX1J3yK0jtx7JzBQ5W0HFGlDurQwecr1mdi3Ya0ZhcujZiOZiDx3yBY+AR6DiEIgk70EJ1xITI8J3G3LiCJ+qsFINKPet+Unmvk2XBpoLS2IreBhMr9cuuyOIpvRrP+n3PAIegYpAIBwx2ppeNytycI/2B2Rjp5EPgYaq8JThmGtAufM2VMQ0owrjmAgwC0r7rtvnuShUJEOTPeO3HgGPQKUgENZj9aXyQutNOgP3K8CNiq+Ue886jjAoWS+r9BPJO4EQ//pY4IHC8qoqhF8UYT/1SgfCj88j0BMR6B+66VbQu6UEIntGGvl3pFzRxRpR7o0/mGhRC/aiQN9tbSGvreD+kGlGsBuC0Ns7r+b8xR4Bj0DsCAxweqAbdIR/3Tmb8+4LDEx0dchPwKzwmlzObXXPhTWi3Ame3BaBsBjTzCPptpReeS/Mhp9uxO94BDwCMSIwyGn7RwQuHbhzJq/dmWOAUOT5A8DowrKz5dVv6S6uIeU+j6ntGKlmZQzAAIQCROGuSK09ImVf9Ah4BCoBgUCvG67kDKVEiejVAU6bnDzeES5XfqmGlPt29HJxbWL9gMTuBT0C0TlQXYJ+ZlNyF1YKatZX8gh4BEqMQD2WBUJBS5EUnIX09zjbZDY1K/TIu88WqmVbQ8qdkOuFVRf7wpR7oL8AyPhohZSf3jRj0fBbj0ClIJDEKpGh/C9SLqBYzy91VzfeDTS2FtBQt1Zxb6BbB1KazhehrZyLq0ZkG0AvjNgD+WzvjlzsTTMRQHzRI9DtCEgH5V4CP3Q5NHxfcnO4XB2lGlPuQ+YD2qRi0e8L/OJ+XtnjXW/74H6TA9VeuytS9j1b9luPgEeguxEQrBoagkKRyr1lCwDrO22+CjQ+45SrZrfGlDtxVxHbmBSWV/FUfA/ADVpYGgBJhLx4BDwClYNA2Fxah7eKG5ocEql/U6RcNcUaVO51DwKaR90+hGJyq0ZNM7vYRv3WI+AR6GYEzgeDl9wJ1/s4A58WPirtXbeXU38ekKhKkwzvoQaV+7CZgHreeUArAU2uq5RzqovdXtrE43LD79pFDX/aI+ARKBcCc7EvgF5Od+1JcZyDue8m9gOwsHP93cDwMOOkc7LSd2tQuRNycal7+Q5rKOhBnA66QD3t1F0DQSyZXpwu/K5HwCOQEwKCI0LXJXBLqJx3QX4TrqKuDZerq1Sryj2Sak82K+Kx3BOqqxDlmwid9gWPgEegDAhM1LkW3PR3b2Icniy85xZmchri1P8QGN7slKtut0aVe92L4Seh1giX8yoxMKqdUlRQTDKQvDr2F3sEPAJZEEjilNAZhatC5bwL8rtIlRsKStcZaaQ7izWq3LWdzPV3X61gkAMwKOIpp/5aCEJveOeU3/UIeARiR2AiyLHuesFNh+CawvslbzsOdOrPA6SI9pyWunG3RpW7RtT1d10OeMFdeMkXclIKuzLWLfh9j4BHoIwIJPHHUG8KVyLAnNCxvAq9uDDr8FCpe4HG6Xk1UYEX17Jy/9LBuw6YGeZ8dk52udsLJA1yU/ntBSlVtpcue/cXeAQ8AhaBiRgMwHVX/Bm98Dd7usDt78P12q4Il6uzVMvK3U2XR96ZfgU/opTXjBvQtAIm+OTZBePpK3oECkUgiQkRF+6rcBq+LbQ5YDI96biYauUNYKT7t26PV922hpW7zAo/jXqS7xcuCrdGKkf4JyJnfdEj4BEoLQITsREAlwyQFN9/Ka4TFZm1S5ELs8WNppS1a1i5J1zKXtISLFgUcAJGq7p88aQBXqSoNn1lj4BHIHcEkjiHf8hOhcsQ4GunnOfuk4MA5QYmzgLqi/SVz3MIMV5ew8pdIvzrbfOKwjFFA+wurPaFQmHZnooaiK/sEeiBCEzAdgB2SN+56DypF6TLBe3MYxCUm2v5n8BW5JSqCalh5R56aDTTlSJF1nWhpy7wppkQIL7gEYgBASbKEVwYafkvCPBd5FgexTvrABWOcEXy73k0UPGX9iDl3lrczJ2PMtD+7q86T3VTpOyAziG/6xHwCJQYgSMB7SVjm50GhSJn7YuTCnx52yCA54CR7t+2c6o6d2tZuUds7FKEH2zo4d4YKiX97D2Ehy94BEqJwLk6QX0QalLhVAQh5tfQ6dwKiaPC10lNuD+691TLyp2p8awIsGgRn3C2GQC9QQpQ18SzPy5C5EXiXO93PQIegcIRmIczAQxwGpiC8dq5wTmU727TWh1zpA6KesPl22jFXV/Lyn0xB+2ZgM7S5BwqcDflU/tfp/ai+Amru0OVAAAgAElEQVS7OWW/6xHwCJQCgbOwJgCaZKwkkcDxtlD4VrFN1+vmOmBw8WbbwgcUS81aVu7uzL2IIIcMuCuEF1aBwzJc5Q95BDwCxSDQpu3qLm3ITRiHl4tpEniG7ssHO220AupKp1wzuzWq3JvoBrmo85RKq9zXxmMAPnPaH4GzsaJT9rseAY9AMQgEGAFgJ6eJWajHOKdc4O5cui+7CTkeABqKyN5U4DDKUK1GlXuCq+DuvbmKuHhYx2qemX84DSXQimjuRee03/UIeARyRuBO1AEdvGEuLC6Fnu1dIgup6nJ7pta2rgKsoXtLhjOiQ70fw81dH+J556deEHqhxNClb9Ij0AMQeAukBCCtr5Uv0A9/toXCt5NHdeSRaXik8PYqu2aNKvdERLkLOdlLKyme9yanUZplRjtlv+sR8Ajki0CApSA4O1LtJJyECBFg5IqcilH3x9q0tVsoalS5yyr2BlNb9UG4XKKSQjTH4tElatk34xHoqQhcCAWXnvtxBB1I+wrApmklAGOcij8BdTc55ZrbrVHljohyT5Z+5s6fguCuyMLqdgiwbs39SvwNeQTKgcAEnV2JiTOszEEdfmsLxW011QBt+UbkZmDYTFuqxW2tKnfXLNMKLPxxLA8vQCvQIb1XiX6MsYzYN+oRqEwEGAgouCQyuPNwJkrw1d20AIDDnbYFSNTsQqq9z1pV7u7M/dOSBTBZ1MLbq4FQKPRBngo4DJAveQS6ROAnnArAnZS9A+D8LuvldEGCmZvcuJcmoOHtnKpW8UU1qNwfY2SqY7NT8Zhk7EMPwFyL99ii8aF1Py2dU37XI+AR6IDAWVqpnxg6rnBC8fwxtkU51u6ltrXr/ujeZw0q997u25+GcTdRtnvvpdtPdMjheLx3iywdvL6lGkegDZcBIX6muzEeD5bmrifTpfJXTlufA/3udco1u1uDyl3cfIh8cNNif3rjMBXAi04/a0JhF6fsdz0CHoFMCEzQvEztSTgALnKWgD/GdhZ1f8TVMZtpbcfdvo1kK4plPExMvSzw/+2dB3hc1dGGvyv3Ru81VIOdBAgOHUum/PQWSmihE0roCSU0r00NJaGEDgkdQwKEmoDBkiimQyimQ+jGgCnG2Ma2dv7nPXvO6mq9klVW0ko+8zzS7eeeO7s795yZb77R4pIW85mjAyXBGcGx3p7ExzzbIrVPIfEB10rAkjJaE/1fQem8Yv21NRruzXYURzO1HG/P39t0gqS789txJWogaqChBs7V/JrhRu3p/RllGlB7pI+1cL0aP3u6WtpMyYiRzRNSKuO+lKTVJUGlCRRwqDfmGHUMeKnkO0mfSZok6UVJBEVe93/f+ptQRDclPTmv/WWI7tQE/U+JVvA3W08ZDVdGj7X/zeMdoga6oAZm6Hw/8Audf0XSJWGj7cuKQyQDKRNkjDSCGNk8IWnay+Y+MCPwjSSNkDTMG/RUALNBM9QjZNSNMQ5GeZYflTM6Z5Se5kbng4AbnbqG/f2S+/GSYNTPMk36k74Z93ld2mljae3e0s8lzTdRquLF0zEySofJlC7V9R9lUnUfO6YX8S5RA+WvAWqimv6T6ih2YZgywsCXQJ7vJU39QFLq91+xtjS8YwZ7JXiCtjbRHONOgHJjScMlbShp1YKbTvUj6FclTZD0mqS3JYciKVX1o/QtMfoYeWYKzBKw4swU4H5O0YPyaEt8L00kCw2fOCNoXgDtJ+drgH7QR5IW8jfB1bRm6b6w7df12HLUQIdpIOMGbhjxNPjhAmV0fOn6ULOrpFRB++QZqXK90rVf/i3NzS2DQa9JEdtnJeHDxlg+kas7KN6OGLGOEkb7BEn5SxfN6C2deJjU+6JcF/nufMAoHxY4/ugjQU+u4a/0vnj4LzJu5H6qVwZvGEqE/aqjlBPvEzXQBTQwusCwQ+w3ssT9LqQCAZEzT8ncRu7LSRrlR7wY8ycl4fcuU6mhrynO57cOkQ75yruQtpHy/nD6T9YqkChG9s+V7IEyLlkCbH1wH5kq9Eud3gBNU7LbxYaiBrqUBjJaR3KF5gMVAIOuTZRxg8gSPcq4NaSK/6Ya+1xadPnuWG0p9YxzrM4NComLAZ7ykyU9WN6G3T3bmg2fcFVcMXdJOlJyfDO4cBhVP+srn/N2Z51hPvCrRRte34qtjL5SogtTVybK6pzUdlyNGpg3NZARMTUGU8Gwo4fLSmvYabKicNR+9bxm2J0Wutm3DOMdZLr0ZSHGnbjAWZLWlbSMd9dg3MHG/8WTgPEy2K6h/z402cxljiMjoHe4aHONdvGKZjYQT4sa6JYaAB5MbCzIp+rrBlthuwTLaiqwpeGPlNErZG8twX3Kv4m5jdzL/wnyPXyMUXe61N2r0m51+cNzrhBcBdmCoScw+2dJGGSKXeOTh7DouJR7Zc4WGtuTce2kR+9SVpcqo7nFOBprMe6PGujaGsg44AMegHpJdJhOKrWbN8HTkIZf/6u7ltGrV2TxtW5k3OtA8qRiCMn44o9cdC8on9/70fyOksZ6tw0GGt/82UBvil7Z2M5+juEujaldS4mObez0uD9qoNtqIOMSFW/y0ObwmGM00sW8wnYJlnfg7jm6YUPZixpuzztb3ci4J+sXfGxPFWw3ZxOs7T2S/s+X+RrjR+4w1sFRw0gf3P3c5UR9r6QgjdqUUY4kae7XxzOiBrqPBkCM1btMTRSsLzDCpXjYxQFNpGbvyQvSJoBA5knpRsZdpTDu6S8ByQ747sD1/1U4VuRqOwLbApUT0DDpaxquj3R0BA+kdvZXnW5QrgBwandcjRrophoY7X6X+NrrpUK/U8bRitTvK8maFQZS0wmFJblDV2qkmxj3CfDTkC0b5JMS+tkYsYO2ARZKbUd0BtwSnzyjD+7duJgOl0SiV5ANNaGUyRqh2biMGigzDZCslNUNBeiY25Ub9JS4s7UkNW6WanSy1Ou21PY8t9pNjPuXkIVBWxCkNS6ZcG1jS6aSp/mR/HU+CxV/HkUFGmeAHOUyVvHn10uiURqtAoKz+sNxLWqgm2jgT5JWST3LRPV2CYWpXaVazZKomIq52bXSBs0gGizV/cuvnW5i3Evukmnqk/pU0kGOViCH/YcojGId1FNdsuiFI10pvrR7preyDnpZ9PS4M2qgy2sg40bRGNx6SXSwTnb+9vp9JVkbO7+U7Jtqqk7qOU+7ZNBFNzXu1h4j99R3x63CoUMAZ1NPhbCLZ6c8dA69Jo76gBfC16lGRiijLVPbcTVqoHtoACpf6W8NR9K6ViOVHuCU8Fl7YdihEQ9yn7QxCZjztHQX4w5WPciP0vSXwkYHLMdJzsXCFJQv2BWepAwfYL1Qji9xkMr6fdI5sWJTWh1xvVtoYIaDAS+bfxbT/9TP5Yzkd5VuxXDFFBSlT/gNzvPSDYz7ozBEBg51PtAXpa3TNMId8SHj2ztJcrwZvFjA3D8v6YAGNzdRcf3j1L41lWiL1HZcjRro2hrIiDyRfVIPkVUP7S+gwe0iNcych6SafksaTp7KPC/dwLj32KTgU4TFsrMEww4xEoaehAoCr7fkYZMZzRDB1LRYewWY0jeJ61EDHaCBkQ5Rxnc+FdjURTpdte1394rCknwXS0lHstS236O1seVuYNytsqEOks407nSF0oC4aKgIBZfNnp7nngInEA9j7GGqDLKVcj+KsB2XUQNdTwNQayS6NVXLgGd4VfOVmjsmrZrHV5Vs69Se7yQjEzbKHIG/LqmShIpQQWZKA6AmLgehBCDuGb7w+B8fkXSsMq7yFKObILxgeQFEiRroyhogC5XvexDqLuyu49SOcMQ6fO2pWULyd2lEOqck9GWeXHbxkfujpBqvmPrknpeG8aUqF8HPuJekAyVBYgY52S36zI3e6/uYaO/6jbgWNdDFNDDKIcag6KiXREcp4+ob1+8r6dpDkIOlY1pZaTaZ5FG8Brq4ce9Z4JIpJeF/Sb8jwMJ+6bNa99DVulpTGlSCGhqTmkqq79hYR2kgo8VkurnAC3CbRrp4Uzv2oi8DIuh9gzwkbUrWeBSvgS5u3LOUAUxJluIc5SqvewMPdHI9/VUriHSoIFk3wg9bcRk1UP4ayLg8GXzcacZUuJfI9WhnscJ7RPhjgca7uHFPqlLPM0tKyp0B7htJBIBu00zN51g3KCWek/305wYUCmF/XEYNlKsGqIUKg2qQmY5sL6MpYUf7LKtJ/ktXXXtfqmynBKn2eYKOaLULF494lMrp6erpz3eRYAoYfPzw72imTne8keS2LqJFdZsgOoIDntHPP6nw3RFfgniPqIEWa2CUdpK58pv1lyY6SSNdfkf9vnZZq8jk6t2HxpNLpATW1igpDXThkXuPwuQf0ChdRcDhjtRgneeICe5wlSSltxwBGQiA8yUxpqcSVJSogfLSADS+OUhvCqmif+h0dUBhjOptJUtnpH8m9bq6vBRUHr3pwsa9MLMz+1B5qLQFvXhLJ2p1feUM/JyX9ZJcoe3d5jwU90QNdJIGztAqyrqCNmkWVniWDlCOQ6kdO/b0fFJSiIg5d15nf2xM4V3UuDv+9jS+/Vspeaaxhyzj/b31hvrMpX8NM1rncnI8HDXQbhrIaE3VCdAC9YqDkJC3kzINahaEYyVeTgdKnKq0BJWHXVPim3Sb5rqocf9ig3xKv/sokkelEWSGdjVZXdm5VnRaTdLCXe3BYn+7mQYyguYDGoF6ZIzpB8eMmnExonZ+4OodpYR8kSAm2W+lETPCjrhsqIEuatwrCvzt1vVcMrnPoXkB7bUbjJQafoJxK2qgvTWQ0e7K1S6YL3WraUr0K2X0bGpfO63WriUlhbQCV0gj/tNON+wWzTbPuJTdo1qBca97uOy62LwOQVFARm3/Rk+HGXtbPa/tdKsS3akFVaOjHIVBo5fEA1EDJdEAtX5fdzTVxzdM8xeQ3m2V0fiS3KfJRmB9tfsK+NrfkAbSpyhNaCAd7W7itHI69MRS0uxPUl+2CVLVT8uphy3sy3lSEzVVKfvd8FUGpcFDSjROplqN1BvtH8hq4RPF07u+Bs7WwprpoLmbFzzMRFVoC53uSPEKDpV6s3oJKcHHny7V94VUt4606Yelvlt3a68Ljtxnw9+ceiklXZm7GcKwaz1e/1dFv1wvS1rb4eDD4UGSdpEJdLw0Sl8qo2pn7Cs0TqfpnXBiXEYNtEoDo7WWZuouST8puH6Cemg7nSaKxrezPDFImn1PgWEnUXGPaNibp/qUkWzeBZ1/VvXNUkISkBfbqov63ghQ8WIiYYmZB+Nzihws6BOZrtMCOlbfanvH3nGQEvUOz9zk8hVJTGPvdQVDMorJHU2qKx5soIFR2lcm4IbpsnWcQo3gAzoGFQPk8ccHJUuzTBJAPUAacX2D/saNRjXQxYy7VUi1EyUt5p9ohjRw4TJjgmxU2QUHQjGP2yX9u+BY2GRmhZHeSovqSf1On8i0mZJmo2c+lOly9dF17VOYOHQzLru8Bv6kQZouikoXMpTWuUzUjM7vGPcfhn0GgVIckmk5Wqq6JL0jrjetgS5m3GvAtkO8FeRhqaqhRzoc6T5L3DBg+KnJeoIyLrGJ8nybOkMvUQSk8YBsTg9wat+iHjq7Y6bU3Uf588STjNbayjr/etq3TYb/ZFVoD410M8wOUEWjhv0UqersDuhAt7pFFzPu1dcWYF0Pl6q6EhscdAL3e2qBlnyRcNs8LamvG8Xn3Dm56zPOWbOe5HDIvPww9o1BXOG1udhRH1DyL8q8rQHQMG/oOJnOlOZw+j3lishkOorfyBl2IM18l1OSnCRVUtksSgs10IWMe/VAKQElAzgQmSnNXkrabLLfLvfF9pJL24b69+e+eEdL+gzWGGKxL3yIFV3MKWdpcc3WjjJHTrbxnCe4Pa+rh3bRaQKKGWVe1EDGBUtvlFT4HSFGgzE9XRlXMrIDtDN2fqkXrpgCw64TpSrQZFFaoYEuZNxrDvf0WuEx75Kqdg4bXWCJrv/iDXRrqRKulASxGCOcrVxF1qYePOOqwsN7TWZfoesGSCUBMtgno8xLGhil3yirS5XkB0rh6WEk/Y0yriRk2NfOy/H9pJnkqeRqDNffLRr2el20aq2LGHdLpNoJ3u/sH9RGSCM6uxh2q5TehovgoeHFsIYviHBVs9o6U0trtnux7FpwPuyUF0g6ueNGaQU9iJsdp4FztKB+FG7MXxe5KcitvZVxM8Mih9tj1x09pMXvlGyHgtZPkKpgRo3SBg10EeNeu71kYF6DvCJVYeDKWfB7EwQibZoXU6mEwOoLftS+Vov89xmHhODHXQhzq3bFjDv0h10qdcR2mqWBjHaUdKmkZQrOn6FEJ8t0sToUNusGbFD1HlTQnzhiL1BIaze7iHGvocISZGFeIBCqpC5pOQujZJjaX/I+ckbJpRJSr/FFEvTCZ0rx7ebJaA1V1rliICRLyyeq0C463c0M0vvjelfWwNlaVDOdUS82Wn9RFdpHp5d08NFMbdUc6wvGp88/T6o6Mb0jrrdeA2Cty1xqSfY5NdXJD6WBB0lXl3tyDoFTECkZyXFxpB6hzasgZwIyBm6a5pcXrNaXqnLFi5eSxMg/yHwy7acRmqmaFrQXro7L8tKAKVGi32q27lPicpzT/ZupRKdoiPbX4ZqUPtAx6zVQGhDMTQ0u4WmvisVpSvgBpJRbwlZL2lTNgz546Fu146UR+InndWHk/aJXAgQFLUO+8OMf7WBw50oqpKEgC/AwRbhk1/yO5WIsl0muslfhM7yqCh3ceTO06kWkBFINBhdeklppwObSsFlhT1y2XQON4aHb3nJJWqimCC7FcIN8K/VqXhAxXNFxSzDouGHW6aBbvunganJFtVte3oyqOSNdQhRcPaAk0rKfc/mc0aBGbfp4XC9HDVylXhqlEzVLbxUx7BhOCloP6zzDjtKSCxsadk2UsrtHw176L1SZj9xrwHWD7w5ytlR1StgosyVp2wRPcZHgBy+lj72xR8Wtxugd3Dzl+OD/aLmcpSU1y72YCuFoX3k/PEUaopSzBkarUllHHzCkSDf5juyvjOAd6kSp4XfBdynYnTop2USqhPkxSok1EJRc4mZL0Vz1ylLC6DTEBaZLs1eQNusEH2GznwcsPrhxEo06SgIlw8ceKkp1nJZLjrv7NEn8pWd0dc4/O9IltrS83XhF+2pgpJZTIlww2xa50VRJv9dIXdMxvDBFetBgVyEwAnhu9LM3UFEJN8rYuNdeIRkJOEGukKownlHm1ADuINA51FslgNt6GaW9ZI6GGDdTWi7SEP1Bu7UAmZO+Oq6XVgO4YD7XocpqZCNEcg+oh44sHy4hF0RNF9X5QrKVpBFTpeozpQrvfjUoMhigfCvZZ9Kg4xt32dT80dNuoNuZOfdicq5UGWmvU9Oj0n7x2tzaI4tLPT/wXCq0VifZatII6HHLRRaQdLc3qJ2dTLWix9IDiSTQWpyaoLmaG611lXV83qmgl7v4bs2nvXScICKL0lkayGHWoQhYtUgXPlKiYzTSfTeLHO6sXTWwm26XuvvvpSoKXuPBrJAeW14yKAjCM50u9b5A2qCJ79rz/aWp2IRFpYS40yVSJTPYKAXT7zJSSA8wsKmRo40pM8OOruCKqZL0hzJQ3PuS+HIPcNmmbe1QDuv+S2mO+pg7aYoeVkYLtfUW8fpWaGC0NlbG+awZVAQjGBoiYHqeBmhI+Rn2x+lr2m00WRoIlYaXJCtV/k/Knhz2SFqxacPOmVMJ/PeVkkqp8vho2FPaK8+Re/UCUkIJrVCM16RkDany1YZdL4stiobwQwNr3tnCTIIKORj4wX69bX3KuBcslaJSxVFcqPgN9dJWOlWx1FnbNDz3q4GsjnI8QrggCgPe4fpqVejojil9F27ZkmUNCJk0hv18qeqEOVtwWavkhzD7/FbqvVTjBr52uGS3Scm2UiWJglEKNJAOnBUc6qzNZP+UYacTY8vIsBfq65YyMezo6VufXt5Lgk2vBALOfaR+IznIZH2DiVbXbI1XRkBVo7SHBjJaShkdoVEODfVAI4b9TSXaXhltUr6GvZoZOCPsIFmprhE4c0K1JV4EyALSLMpQFpFxQyW7QUq2jIa9iHr8rjILqD7fS5r6nqRl67uc3Uza5NH67U5bw/9MQhUjjnRgqNM6VOTG6dE7U2HiFqWRjI7xRj79goNZchdlylYfpXn2jmolR8MLBwz1calElNZ1uhdf+sD51eVP+DZuZ6kizTx6v1SV9r2nn4vKkPjRP5KoNpY8I1UW0AA/vqBU94jE97Hq8YKL42ZKA419eVKndOTqD9QQTRl2jS8Tw44S/s+zMTKSLVdh9E4pMkbvRaa9beh2xvn095AEmiEIVaLuV0YHhB1x2QINZLSaRulgZXSTMs7FhVsNWmhqhxb7bVJi8nj100rK6PLyN+zooqKgbJ9d17SGhk2Tkmty59i6Um2KUwrDXweBYCYa9qa1yNEyGrk7f9trkuMg9z23XaUR6bf+3J+ofc9gxEG909nte5s2tb6w97dj4FeS9FmbWiu8OOOCyMQZmCWkhZfK77uGwUl3u4PWc5QA0ESEv2GSFm/m3cn3oILW9V2LEsJVVyIvJYAjpki2uDRiLlXAnlhKms2ss5eU3CNV7ig92Efq/6CU3CpVzuUF0UytdvPTysi4j9tCqgAKFeRtqXJ1iUh6pwn86emRaqd1pIU3hgsbFA/p5iNbeO3cT8+Isn+4qNKzLK6rUU/trVP16dwb6cZnZEB6uHgEMQnI2TDkS7TwiTFuFE8fo4z+28Jry+T02n0lg6coyI1S1b5ho+llzV2SdsrBoLNDpQq+y59IVb9v+rp4NGigjIx7DSPiFI9MclAnv6FJ6b9PEolTBLS6kiwnCXjk194Al/4FlRuJgl3+RQPF5IoqH6KRurPB/u64kXHc6ENEgNm8QTetUaTCUXOenmzSx5WoWolqdJqeL4+s0uZ0vbFzaigAsln90WQLqbKZ8SrYYC3E2r6RknHS8N06ebBX/yhdYK1MjHv1alICBCr05wtp2nLS1qU3Ss3/UOBqudVzTpfWf938PrTlTHyTYPGBMfIcpZeMK93HFDnN/xPuw8j+eGXE59q1JaMllGioTEMl98fMBQ6XQtdUS57zK0nPyfSEM+bkFHRYzdKWdLO15zrXCglFIXYwSfpiaWm3ZtYecG5arl86VxOh94aNwyJb28fufV0h1WsnPW1ycMqwA6T+eycbdvRASj9pzF0VQwvfCMb9d+1o3KfJtKdGa7zMFQ8JvlX0t7ULQmd0syr05/KF6qW+8rnkLGZsGO6cATe3XLiNNHDkQUDe9ZxPDMOQM7PqxjLrV1ISDDs/77ubb9hRywv9JC2WU1Ayl0zVbqzGNjxaGCm3oYm2XuoCJfhoCQQis6UeK0kbA4fqaCFxakpH37Sd7sdnC8c7CU34fCnN136S88OD+8c4FgoMmY8q0RiZ7lFGjFo7TzLqqQoNVlY/8wgo+sxfYQm6lvaR5wTxQsLdq0r0iir0igbr3XmPk6eQJMxlkbaA/bG6Skoo/zhL6rmwtBGw2ygt0EAZGPfaX0vQC+TlQalqm/xWx61USo5PhZqOoEG6gxBUJbgK0gKcevsKZFYT3UyBIG5jLgum5c/7GRGzotfUQ5NVoSmape+UKWG2L/35SotolnOlYLypu8uIHPcKwfLWCkac7FxenhOU6E2ZJqifJuhERSOk6p9ICTOTYF8+kSqXb5m/vAYqgrMkPS1VgfmP0kINlIFbxgoL5JLu3hnCzAHc9sqdcfN2uidIhXN8tXtQBs30d7ayN4cwytJFyjgfP7z74N8Li3FD4byu/8vdiF6FnuU4LYHKQRg1t2W6o0zjg1uIz3FZTXQIlZRrIH16s9bpFagVCpxjyIkf8PemMiIAGqWoBipAyQTDzhm3tsywu0YpxYeLtvklJHMXxP9eA+kPoBOUUruCZLC6hR/gJGngso1TfLZ7F8GFkyHbneQhn4BFxaVxHfpgGS0g028dS6G0ZIfeu+U3Ix+AYhavOHdKoteV1RtdC1fe8ocu/RUuEMpvaIX6tiuGSsNbEFh3wVjcW72lZF+pknqrUVqogU4euRvZnsGw0/UbOtiw8wXkSxSkuxl2ngusNNm1v+4E407G7Hm6QxdqgtZXItxtW3m3SGd995gNMBKnjie+8VfUWy/rZE0OX4K4bIsGamFKTRl2gsjNNezQj/ywmjSbGsm9c73IrihRd3VE58Zp2qKSTrq2k0fuNbzNV69/9mSIVNmyQs/1F7d0DagjZfFwC7HsroLvmxqpuBEYPXd+EeI/q5+m6qcy/ULmDAF9JJjNH77w/m5p6q8ktR32z/2TwoBTDQsoHX+8tHOj8iF6Z94Lbs5dYaU7o4bfUopyIDlCqgS51QypoQqYD2qTvJj9Tkq+y5HiwU8zHE6dKM3UQCca93FrSBXpzLuXpaqOZBmEXxq442G5GUMzNdY1TyMZi+cFnkiyWNcW8PV9CgKifTQjFhHp7I+1dlnJeJFCfYH86Gl7SaaL0sEa6KypMd6YhhzhEjC6jpT7/fSxnGuylkofZIti3AM3Tqna7Zx2coiacuDQ75znL9u7Zk+UkmDY6eV10gbRsHfS55X2d3d0F6A2DUJBjo4gCAMKl5Z5wbDzvLzI4OjZIv3wcT1qoHQawC+epHnb63zpu9LdIrbUIg10knF/HGKlVep7mjybK7NVv6cd1sjUBFd9RDu0Xe5NEozC54ze+YsSNVBiDSRUiqIKmBf7ZyxUHXTROctOMu51hSPIjvAD49+HD5s08HlRIHFCPH7Yb8VF1ECbNUD8TEelmjGpggLeUTpRA51k3GGHS0sWLHZ7C8kQIHPGt/eNyrR9qtcgKZY+vycuogZarQEKaFQQL0vH726K5e9ardCSXZj+QErWaNMNuVJ6I1LnfC19CaFSewiUArWphrsob8z4ftKMVaUKSufBC76oX+TbVjsAACAASURBVFLsgXX+eFHzN79/Xtbxs3+Tg0FOnyZtn5V6bC89cL7Uw8MEs59JfV+JjHupb0lcbaYG4IX6Ad516ByCfCv1Oj5sxGXnaaATjPuUIVIFeGYvkAM1lwY0XNOsJfwmJLPDqQK3ShcRR6RGaTHcJxB+rSrNXE6qaC1sdcHcg5Odz2/wv72lD/9Q73rnHTBztlQzQbLnpeQFqeJJaTg++ihlp4HxC0mzl5BmL1qATCFh7F1pBMsOkMeWlLK3SJYeqAGMOFDakByDKJ2sgU4w7hUNizvkaFDbQw24eqie3hEunzb2H3xw9tdSgkHfyCfxtLHNYpfDZEvo4a3CuCrfgzWkBN/pgbkBfw20EHdIybUdEOwu1tl5fF/1ypKtIfVYM7d0pGeLSzM94Rkv5WJSQ6YtHzBuyMelHk9IGzN7K5G4LNLDpSwDp0JyuHOlSkbyUcpAA60dDbah67WXSpZGrPyfVBWCfW1ot+ilZVwmzyqkmu2lhEAU7qPGfq1FH8zvhJ2QUdIP9dtJwcjNINHCeC8ojesvje6Tq152dFPtpo/h2nkw92PepH1pg9N3nafWma31+6VUQWHs9SVbrwX1VeemKT4/ahM/ICX3S5Oead1MmT4O2EsyXC6rFbnpJVJVs79URa6Pu0qsgU4w7oU8z7ZoiXgjYBskSedfJdZROzRXvZnHAKd9lcXuww8TXvu3JaNwyJtS8p5U8alU94X05Zct/KHC+fG+1P9V6f5RUsXykvhjNkXhZnw3jQl9uUGqOEUaDuooSqs1UL2AZBt6Y76xd78FRstWt9rMC4HFwqv+pGTjpekvNV4Y55HFpV4bStmtpWQHSYsUuccsyY6TRvy1yLG4qxM10BnGnWnjQv6ZP5aqqPdZCrlC0qHl7WMH3193oaR0Alfhs8OD/YiUPCplx5XoxRfuwecNPwfcLcQ9ZocDUnXP3PQ/Wd//kCGAKua2g6PmHMnOk0akrq9vqbzX8FnXLSDN7i3ZAKlnD2k2CTdwmMyW+kwqfXD58eWkLO42RuXDPad8S2dqvFDhkP9Mso+l5CMp8bTDxucEX/pKkkFZTeC9qRd14UdEMh8Fc0I2KTNeip//pPDEhtvJQ1L2GGnEmw33x61y0EAHG/cJvaUvIXUK9x0vVTEVLYXgL77S1/PkR1BG8tAAqQ/FB45LcY6n+4d/++9SjzHSxu1dfi0ULaZ4BayIjUj1EpIrf0hAOryM0+c+LdXtLW1axkyaUErDp2OVUrKiZCRw+QBz+lHmWMe1BQUwRg+j+pVkvBQ/lyq+yK1nZza8qqK/lCwqGQimBXP3Sqj0RKCjkNO+4aVzbvH9xWdOgHuCNOtlabMWZFM7Nw8v6U2khOdnZhZ+c3PereV7npCSc6RK6uRGKVMNlPIDb8YjOmKhdPm8u6WqXzXjwi56CtzWj+0pGQkdFPotFIz6yVLlna0oZlDYVnO3qcxEhSbolm+e+0WPLyhlT5bsyCLVi76XHOtfGfFt15L5/FvJ4NIp5hue+yN3/BlvSPaYVPGY1KNG2ogXSwkFZEvdNlIC9TODqaVa0TgvvLslu1oa8XQrro+XdLAGik2727EL2cUbDiCSFoxG5ugWqc4HSrqUci1zHO30HePWlmovkQSssVCmSsmZ0g8XNe7vLLykZNv47pFmVpxySIvjperLpARdYzSDDJLsBqlmI8mOkkYwK+skqcXdcZxkxF1a6vLoyD5T3el1KanNGfTZj7VsVN6arroYCRXOfJUzyuARvDUqYhFzgWYXg08OBYKLaqKUfCrZC1L2MWnGI53wXfXdiYvWaKCDjXtSMCW24ONrTd//JglOdgKpf2lNA+1zzZOLSTPPlpL9ixgZXkI3ST3/WPrRWbOfJrh9WsgxM4Jyc9tJ1QdJyZ99ScJw04OlZJj06K4d76apHiYlf5Jsk9CZRpbw2ONCol7A/yRL8donzGCB9RHUhPMeQ8eymDuqkeaL7v4xZ8jtdakCXqPnpBkvSFsEdFPRi9p/p/ss+Tw7mom1/R8t3iGvgQ427q4mZv7mUuKrraR2NX91tPdllolLwGXeHinNOl1KQpZo+mme86Pbzp7SttK4h0cZca30+DipDsMAZC/IWlKPF6Xq30kjmuHuCZe1don7xc6UtGsj/mRGyOj8AanHg1LdKy0PABNkBiFiC0s9Fs4t2U4WkrKpgQqFJcgENv/X4xup7tMcsqkrBp1b+5nE68pJAx3sc3ejrDTVwOVSFWyNXVjyfnUMTTF0AVWQ8Kvf0IF+9ab0icGi+DQBwtb4Xn3bLmh3oZQU+/z+Jg08UhrWDpzrT88nzThVEpjqYoMDnusKafbl7e/uaErN8VjUQOdqoIN9kz0Kf+wtgWuBsYVSoIP73NQHVDNCeozRISPVQsMOmuJ8qe9gqervZWLYeRjgi/DK4F8FEtlK2fpHacQRku0h6fuCRg6Qpr4ojSsgiCs4q0Wbd/SQavaXZgC7I5Gm0LBj1I+Sei8vVY2Mhr1Fyo0nd0MNdLBbZtZ3ORd5XpPAxporuF8orkwqNYHKTpTHhuRw3rZN8Vhu8oBUcZy08dud2Mmmbo2/FZgggbQ29nHEGOnR56Se8IwQoAsyWKr4j1Rzr1R3XOt98dX4wXeREqCkqXq74TaCDO5iqef50kaFL5n8SXElamBe00AHu2VwYdTyYwy43w+lqsIRb2OfAYkZFASg5mknoTIcWdIoSQf4QG5BXyHdsj+2I51Cwf1avUntWHzVIHmeanUrDS50MQd0c2KR2RWBxRuliiul4c3k04dbxeHs0XWxzMjsGmsMuuPee4c+s9xyfW5LkjYhrxo8SSk3zAwILDOYJ5IkaeOLtJQ9i211dw10sHFHnTUYk1Qgrsfy0sZp7HsZ6vyRhaVex0h2bMNqM/muEqQ8VaocIyVlCMvM9zOsXJXDgmubHG9M2N2ypZmBJgFl8k2SJJ6catymUgXtr9RIa+9KVitVPJujVMhOkUCrELRMQKisCYFar17JkKWX7iMzaeLEHzVzZr1ak0Tjn3jiFzUbbDAI7D3cOST9rJ4kCbGEshIzq/HcQfTtmCRJri6rDsbOdFsNdLBbBj0mNZ4YySs1u6WkYl948LcEzfCvgnzoBMGo9ySr9EjJEXAV9uGrHF59kSukoQUZi4Wndvy2GTMllyH5XpIk6dlOIBcrZPWbayfNIDzTSZJ+n4IKZs2M2cCRSQJtwoNDpf4cx5WSKr3mmmdEDuMhOQqpQX6i4cPn19FHL6Of/WyAVlihr3r2zI09vvlmtnbaaYJqa78lo/aUbLYS2OPJH3zwgWbOnKlVV12V78qmvlZsrtky+G9mzFAr33zzTfXr16/f8ssvf5WZLZEkCUivKFED3U0D1VVSjdX/1T7RyBMy4mG4dkgjx9txN4RJ1WdKNVPq+5nuc80PUs1ZEsiN8hQz29DMPrScfGVmvESD4N5Ct8WQLuGcokszu5Em6+rq7KmnnrKxY8fa559/7m9jT/oXir/20aWlmmukmmmN6DH/PVhyyfE2fXpdaMdmzpxpn332mU2dOtXte+aZ726XrMLMMux4//33bZtttrEff/yRTf5Bp1BWYmY9zezLGTNmuL6+99574fnSrKhl1efYmaiBNmjAUd1+KN1t0tYmDcDI8AfaAVItptkISTakypOk1EEybrA3RjMaMUZ1ueNPtAFC2P6PYmbLmNn3GJXx48cHgzLNzCCvQohboPNT/HazFma2O429++67tuaaa9pvf/tbO+mkk6xv3742YcKEcB9YDgukehGp5nCptkaqmVVMt9tt96q7/t5777XBgwdbRUWF+14888wzod1dzGx9M5v93Xff2VprrWWvv/56OHZ4wQ3LZtPMTqOT9HWNNdawb775hs3ZZrZO2XQydiRqoHQauPw8aZFg1AuXcE8XSwIq3e3naGnchlLNXVINxjs/mkytU6noJqm2GFpjjtY6e4eZnYcFWWeddZxur7zyymAEz/J9A77IsfNa0ldsFCPllVde2bbffnvXJsadtm6++eZwj12abpOSgdXrSTV7SNXHSLUn8jd8+IvnZrPO6Nns2bNtueWWswEDBrgRvJn9YGb9zcy9Qfbdd18755xzwv0ebvp+nXvUzPqY2Wt09swzz7S999479PslM+vAgUvn6iHefZ7RQM9/e+NSaNjDNhwm7SxQv2JcKC9X1KBj5GdKNddJIDe6jpjZA1iQzTbbzJIksTvuuCMYFDi5EQwwumam1CwxszVp5IEHHnCf0S233OLanDJlit1zzz3BCLOv1boyMyzfLGYcffr0cf33HX/LzHZg/cUXX7TFFlssuGsYAcMGWtZCH81sBi6mRRdd1GpqavxjGeRtUaIGuo0GwLYTIA2GvNgS4qJ2CPYSYHSj9JukmulNGPUfpNorpEcbQ3yU9YdhZudiPTCS+K29fM0o0ne8Ncb9cNq5/vrr3ef10ksMPBvIdDMjc7TVYmYr0CK+fL4fo0aNCjdgWvAoG1tttZWdeOKJYf8/W32zDr7QzFynjznmGNt4441D/1/u4G7E281DGmgHAzpX7ZE8M7csUwKVi3lO7bk22PQJGPSadaVkV6l2F6miqeIgn0t2WY4XvoqKNU7MDIgenNjQyQYDGQ6D4U5n3vJsQATB5bNOeyQL/TJVuBToHkFNCiLgoya+AFQOOCFTda4n9uCJp3RPAdol3LuxZTWMmX369FlkySXpuhPaq8R2/uMf/9i8d2+X4Fm5ww47MHoEScM9yVqlzzz7/UmS/C9cLMklKH3/fS5PaIEF8kCb/0gC3/5qkiQtJsQyM3SKuwv97MP9xo8f7247fDhEj06egRzuvffe07///W9dcMEFYT+QyznEzJWpg96WbFwKfUMYBgPpYI/vJzGKgP3dSZKkCMTmaKroDu8v39lnycK7fl+SJHxWeTEzXIvTkyQJKCoS747bd999F7vooos0YcIEDR069OcEgpMkicXI85qLK11ZA/yYi43WU/sqstLf0tmOLXxeAni1v5JqLpFqPmpihO7967XPSzUHS/Cl1As+UTP7s5nNDEOtTloCRznawxDrO1hkzcwOaqKPr5jZd00cTx+aZWYngX4xs5vCgQsuuMB9Tp988knYxRJUTovQKma2ObHZdCNhfbvttnNumWnTiAHbFDM7ghX87CuuuGI4DZ00yNPwfvkrzAxoZnPkodRspog2G+5C/2b2lyINv2wGTl8iaB187GYG1Gfv0IqZ3cm1yyyzjJ1xxhmhGeCiUaIGSq6BBj+OkrfeeINUZ2dk24gMk4QRSRjC3S0l1dLCrxXHkoNcqVtNssFSAi0AxaZ/2ghTYPp+DEFvk7JXS8ULPxOYBGc/bdo0XX/99frqq9xgfsaMGdpyyy31+uuv69BDqewnnXXWWXr77bc1efJkDRkyROedl4tV/vDDDzrllFPc/q+//lq//vWvtc8+boAqthmFvv/++xgFnX322a6tK664wo3sFl10Ue2www7acccd1aOHi71RH3bXJEkaLW9nZkBLNzz++OP1+eefu/vuvffe2nPPPV3bs2fPdvcBe03fTjzxRK2zzjq6+uqr9c477+iLL77QSiutpOOOO04LLLAAbIePStqcZ3v66af1r3/9S3fffbf+9Kc/afHFF9egQYNcH3v06PF6kiRzqwnr+mDmaAoIhM736quv6oYbblBdXZ2WW245HXHEEeK5f/rTn+qJJxxKFtoJ3Hj7Dxs2zOn2xhsdEeiYJEkIDIc2URBVpkZ8+umnuuqqq5x+F1tsMR177LGun7fffrueeuopt/+oo44S7Uk6LUng1p+7gHyRNBq98rnxPdh///219tqUnxUfHqPzt7PZ7HwPPfSQNt10U/Xu3ZsvzZJ8ZmZGQPvkXXfd1X0u48aN47pHkyTZbO53j2dEDXQNDZCOjYFKjdbDel+TriuGWGHft1LN11LNV1LNh1LN1LmPyhsES/Gz3yXV7iZR+q5xMbNBZjb9008/taFDh9qjjzqXrxttffvtt7bTTjs5NEoYfo0bN8723HNP9zybbrpp2O3w4LfddptVVla6YyNHjswfmz59ut144432i1/8wh0DWnjQQQfZa6+95gKU+LXXXXdd++Uvf5n2nVPVqVExs7Hc4N///rcxAkbHoDTS8s9//tO22GILd+zyyy+3ffbZxx5++GF3CiPyZZdd1oYNG2azZjF4z8lHH33kMO2HHHKIu+7UU0+1v//97+46MO9mNrmZM4tfevSLnX322bb88ss7HzsN0K+ttwYeKwex9LfewsxeBvfeq1cv+/OfmUg5aYDRN7ND2QvkEP2//fbbls1mbb/99nO6P//8841ZB/t49iWWWMI3Y/9tVJmpAz4eMOuHH35wn/2kSZMsk8nYT37yk9AOmNO92HjwwQfdM7z55ptsMutzxa/NbGd2/OlPf7KFFlooXAcEOErUQLfSABVzoB1wP4Tccv5J0l9JEGrMuLdm/49S7X+k2n2lsc2GWJqZs9DnnXee7bWX+82GH+OnTPvBK2OU0/LOO++4Z0kZd9wOBBrtpptucsdSxp2p/Pcc48fO82+yySbO+Pg2nftk4sSJNmjQIIcrx8ARJ/UxgKJfBjP7v+BGevXVV127KeMOJO9jGsH4c08ghyksPJBD+/3vf++OvfIKXhwnuEacBLcMqJWU8JxNFf12ffVuLgcLxDD269cvjY93rpTwogOV410yQAmnf/DBB65Pd999d7gtPvW8mJmzpLvuums6qcpuvfVWd93aa6/truOFCoYemKiXJurI5ptnZuXgpUA/n3/+eXfpYYcd5p4B6KaZoawLWDniiCMcjNO/HPNBU5BEHB8zZozr0xdffOHaMbOyTYar10Bc62oamFtgsz2f5z7PTAjPDCRWa0nfLSGtQfARP2Rrg0yzpORJiSmwbS4NXFCq3DLHp745KJzmimOs/Pjjj5174NtvQ8a+40BPCChuskm++I+r/o6LokAwHBBfObdAwTHm5M6ns9BCxDKlyspKJa4okK6XtChuoyWWWEKHHHKI/vvf/+raa12VNOIC6KuoJEmCu4Mkqyn9+8/B6MsxZk22yCI5Li5cIOuvvz5t4Spz2cDLLMNHIKWeeSfcF0VvKJ2TJMnKSZLgMpqb7CdpKO6d0aNHOxcMLixJj0t6iJU+ffo4Hfg+YRhRat8ff8zFK5daKp8/FoqOYHgJvg9+8skntdFGGzl3kSQXKOXzQ3BvIX379tVbb72lRx/F2+TkprAyl+VG9IGgLm4Y3GgPPPCANthgg+Ay47sFBYIefPBBrbfeeurZ0+EVXki168pK4ipCvvwyP2if44uTuiauRg20SgOdadzpML5UkBBA2pgem0TNzqpzpKo1pDp4SA6UkislaHRdNfgXJNgX+dMjkm7FD5rjFa9YW/oRY76RNOJUacQjbSgYAXulQGx8+OGHWn311Z0fGj8pfmsEv7MXXlTvFzGmjMh4tmlFDD+/7HskZQcMyHmIevXqFdq70KMsTuA4vlsEX7eXYnVZwzGMI37eH7yfPr9f0idJkrw+efLkbzxaRiusAHjJCY074+NfMJo+Pc/DRTlEyhoWk4uL7Wxknws2nHTSScpms9prr73CaRCALcM+fPDoesEFXaEjOuDefLNm5UAtQVeSpoaLJTnFYTR/9zvnrSGe8iDHn3/+eXfa9ttvH06fvfLKK78/cOBAnvUiSZQMbI7M5nM/55xz3Lkvv/yyPvroo/QLfqKknxPLIIbCS8ZLngUzSRL6NTO8zKdMcV8xTovGPWgrLkumgc6AQrag85sCYeOvMcPSgrZafOrrXLHzzjvr6KOP1iWXXKK//OUv7g/Ds8suu7igqYcEYqi/7N+/v6tLyqjOSy+gdmb2aZ8+fUAJuRGfP4ahBU0xrWfPno4C2Y/0OOxGpUmSAEn5ePDgwRBjadIkZ3tZzeMbfVvFFjODccdoevmE5bRp07LBuKeMJSPPLzhexLhjhRpA/UKDvphyarP4KjEMSetj+GprayH70hpruPwjrC+zhtUw7FOnTg0zCRoCMeWGueEZwjOl+5MkCa6ysausssrmvAw9Zw41bN2sa/nllw/34vmxunzvv/MvweIdnnPvvQMGDNiYYDNCYBkJL16MNjBSoJpIyrinR+4cSggeI6nvyRxTLHdC/Bc10AYNdPbIvQ1db/dLHaAbQwcuGcNzxhlnaNttt3Uj2muuuUZbbLFFGMXDXvkTDA9GM/WjpcQesnAYeYYfNi8DiKXwFASDVVGR/zhS9Tk1O4zoU9fmrbVvv9iiRzg/uDQkTebE+eeff1Aw4KkLiUe4/oZjoEG8MFVxQ/zQZuoZmwxMhwY8OqoXLhkEt4UXXDLkEPTE6CO4Orww82F2o6ADjL+XQoMIMdqavCSSJMHVsjgIn4kTJzp3l78GNAvnwasOfNPBXEKDc1mSzQuTpdPhPffc42YXHnHDi9FNLWpqalxf/fOht3zA1sMuewW94iLy4toMG3EZNVAKDeStSSka62ZtOBbFO++807kQhg4dqlNPPVX33XefMxgHHnignn32WedflURBBuej79evX9q4gyAB/7wQcEokjEB9shIO5J6pEXtQIVBO2sHIL8/0HwnTec9fHs5tbDkIqCMSjAk2EhraQYMG9QmupZSRxpC6l0Yw4NDpeqEfDroargvn8HIKJ81l6WYnwAiRn/88D4vHr+5wmo899pg7Foz7N984injnlgnGPeWnzhfw8C9JYIZQR19uZs9CdfzII3jtGrxICJxc9M0331TMmjWLl4Pj2qGghpldTJzZB0VzQQd3de4fNA5JkjCDrOBliVuGmIt/MeOW24LP9vHHH3cQy4ED3eMCD837tsJ3JLhjiKd4nePSiRI1UFINROPeuDodZhsD4fHInEmt1H8usMACM8BRg8sG654WjHvKKHLo1/z75BPnEXF4bn/+hmE0HEbuqXYoooGQzt8zGL1ttgm7XXalP2XOhZn9jAF6eKGkRu6MVClqEWYc6RcRvgKHtw6GO/UcDKWdPooY9+a69pwvIrzIVlzRebDoPKmuv6GPjNx5gQ0ePNj1b+RISubmJLzYCIZ6SWcagzGHYx6mRZ6BbFf95z8kz0rrrpvPhzuKlxHYfj+TWt3MmHmQT8ExXujw0L9gZo1VCBuAe4yXYqpd+HSWZHbHCykVaM85/H2HQ5lA8gnQA8FsZnCpLNb6M+Na1EAbNRCNe+MKdPA0DNzFF+djhuTD43+egUEmgEoCkBc36mXERiKTFyKGZ7AOsgJJjaKp6kTafn40H14AoFbMjLT240ic4v6rrbaa8/37QOJdrrEi/3zWphuRFjHuWEsXaCSBCgmGPFeQxAWn84Y/JG2RUUYVIc7/7rsc4Cj1HEAA3f2KdCe9C/RTlhkQknpxENSc78wzz3RJYhhMXj4kAfHMQYhzLLvssiJg6WUtlj7N/yj6uvLKK2uPPXJ5TRjZhx9+2LnJfvYz3nVOfvrKK6845JIPfhPbAD20HDM0kDu33HILJ+Lnbyxz9PPwguJF7sX5mMJMYcSIEWF/oXF3QQbcRejBt9NwdBCujMuogaiB9tFAwDWTtNOjRw8D704CTBCSj4YPH+6SlDyW/VqOHX300da7d29Lp+dfdNFFLt0cW7Tqqqu6pB2SYYL861//crjnIUOG2MUX4x3ICbzlkExBsfu///0v7G6SnMvTJRgYd/rCPX/+85+7JCyIxBCSow4++GB3DLx3dXW10R9w9E8//bTtvPPO7hgJVDAYgtfmGIlcAYe+xx57uO3vv3dQfZp1o+WmPg0zew5M+HrrrWfHHnus6wvbo0ePdtjw1Vdf3X7zm984nW677bb21VfUGHFUAv9ihXwDdO7lTu5lZquyDVafzZDW/4c//MHOOuss91kE3neSiiAeS/V5JzPbg+tJHuP6xRdfPLT/brFnMbMX+B7AJ08fg9xwww2O1x6aYk+bwKE8FMn31WXCoVcS1ry0iFO/WJ/ivqiBYhroLPqBYn0pq30UpgBnzqgZOCSuEXzsjB5xIcw///w64YQT3Ojdj2oZmr9aV1fXlwAsgTUQIfhXt9tuO4eqYGQJXA+MOS6HQIx11113OVQOaBzOGTt2rJuyv/HGGw7lQUq+H2mCU9+2KbIrEj0B+RD8DT73oNj99ttPq6yyikaNGpUeObvDpMTjJrjyyivzMwkOMEMhfZ8ROzj7lI/eXcezbbghHibtliTJP9zORv5B2wvQhLb+8Ic/uFkDuoSSAajiSy+95PqGfkApbbXVVrSEK4xA6LNAQaFRwO8+cODAd5MkWcXPVF7JZrM/RafQJ4CVB9cOkgXM+U033SSw+8wI+Mw8xv/SJEmO8hTFb3/00UfJbbfd5ugJPBJmWpIkDYLFZgbkEv/aYlAcnHzyye57wGez9NJLu2ci4M4sQNJLSZIQKHZiZrifJk2ePLk3tA185h6euV6SJMCBo0QNRA10hAbMrJ+Z5flywzCrYAmzVb5kmuccJ4jaIvnHP/7hRo1kqjYiTBn+FtLYm3p+n1nrsmIbaas9dk/0wV+Mv3NnNdZHMxvdAmIveNzn9+Rl75NdCm1AqjCIyyLzXPOgj5ojpJPC2pWPFZhZPu2V7Fwved8az+KzayElc1TK4aSwvP/++91nCNWEF6pd5cUTv7m+Mzvw2cakqMaCHXktxZVSaiD/BS9lo92hLVAOGEpJZK1gsICs4OcFBkGSEFCMq5Mkgb7XSZIk9+AmkISvvcrj0fOZSf40ICw4jvG1At3bL/jGU35ocPOgSDiXylR3JUmST4bx7RRdUKDa0+iStQO2nEAmcQIwhLNGjhz56zfeeGPnDTfc8Mqjjz7aMVcVbajhTpzWZK/mUisbHnuJkIKkv5oZMQlK/PFs+NgzSZLkI6BcliTJ6WZGpJPMXdJTP5XEjOQDX0ybbFgc8/irRyZJ4pz8ZnZz3759TyPn4LLLc2ffUAAAC25JREFULgsJUBfhDkqS5L9mBsLoRK93YknELIgV7Ctpa99lsJY3JEmCTtOCIYbOoD8ZqF4mhBW/JFB7KLEAZiuXXnqpyxwO51x44YWOcI38B0kENBy7GRuec8dlI9P3I488MkA7r0iSJAd6Dw3FZdRA1EDX1oCZ7eYLOxs+eWzAaae5cpsM/GDiaiyg19YHH8O9YDtoTkO+TFyeBCUMS5u5fK4592jOOfDpMGimmhFkXRC1ecmnCTennWLnmJkbkTP6PvdcV+eEpl2wO5zv6Y+db75///6ORC104LLLLnO+/ccffzzsOjhcx9LM9ucAcYEll1wyVJFi1ufgMulz43rUQNRAF9YALgFIw3AzQChGgA0bQKCReqe+iDL2II/hK+HjMjRltAjr5RCMmJk9Ymbv+T8Izah8BIoEwwR9YfbLL790jIwEhGE0JJiYDhpfeuml7hkgIiP47IOWOYB+iToPxxpKeeihh5zOPGEXbpY26cnMJhE03mGHHYLLhTZdVnDoupkdzL2vu+66fNCbawiAw8/+yCOo0Ml/0jzznl30U2rPEowmeO6FIi5RogaiBrqTBrxx/xYjfu2119pVV12V/7v66qvTrIZ58pUSPT+JP8ARYXG8P1iZRpZAa0IyFck9Tk444QRnxG+//fawyy0ZvVZVVVmK6ZD99UD1EjyAN5Tv0zCznRTD5lNtaZ7C25MnT06/rM4tbI+AqJm5e2PgQSIdddRRrh9QQHt5ytMs5C/nfcAx2CQDksfMKHnokt7yJ8aVqIGoge6hgVBdKFiFIss3zMylMDbniQm2mhn4eLCU1Ov8IzbQzIjwXehLw23J6HT69OmOOxg3AdDDNddc01U4At4H7fCdd7qCQXTJsXB5o4qvfArwROB+G2ywQb7LY8eOtV122YV22QeXDhW5920Ov3tzni19DiX04OPhRrxQUtTDZAm3SkBGeVcYzfLWKoyTuHb9TIeZTTFhxJ6vPcgFZkZZQ0cRnIK4op8QA2hVf+NFUQNRA2WqAW+gqoORSlkKOMkx0EPNbBEzy4AN9+4SSMQx3Dl+4NSzmRm150CWNCXZsWPHPu0NsJ1yyimuqAXY9SlT8nTt6eu/MbMGBcIx9pxw5JFHutH7Y489ZviZDzzwwFDYA9/8XPHuqa63atXMeLNQZi8IbpQ2+a8pE+iNcZPoFTPrbWa/MrNLzOwqqv/5QPIczwIVseffD/1kiE8dgyhRA1ED3U0DvmBDU7A9SiLhk38pWISC5TvANINePGRzAudQTen444+33Xff3SVKUdiCZJ7DDz88jKpdU4wiqSTlfdbswzgGCw9T5RiP+gm3cUszW4qTKUpCwQtG/CnDzqE8P0KDC9thA8ilf/k95svftcNd2t6kh8fe51/MacqEtjceW4gaiBroWA3AV+LRMFTvedCXvqP83Y2hEtITTzxh22yzjS222GI2ePBgu/7660MGLLwmI7CUjKgJtoKwYLScCrTmcvhzU3+X6khlpVCCDiPfp08fO+aYY4wygayHgB/Zk2S8EiBNCYYdlkRG3swQiA7mCdCD9swsX3oqlMMj29UL6aQxKS4oKy6jBqIGuo8GfLLN0T5gFoxeo0uM94ILLuhgdKmUeHy+ZE4aJfZWW201u+ce4PN5+UtaY2Z2F0dCOj/rpMJj9z/88EOH/gDi5+ucOjcKafxff/11/g8kRxEhcWrjgnuBorFnnnnGURQweoeGwEuu5FH6grgeNRA1EDVQzhogKchnNd7qMcuOcM3MljWz/QiQecNOFqnjFgHSSPBylVVWccFKRuebb7552j3iAnNg2zHEFJv2wv4fMbicD++LF8hoSMhpIGb2j3BCWOKGgaemmNx777229NJLGzVFC//gsdlyyy3tjjuIhzr5TbiZmZ3KngkTJrii02RYwkED7w7FqL00xqQYmonLqIGogaiB8tCAJ5aqZ/nKWTHcK9d4X3UwbM4KM9oeNmyY83W//PLL+RFzOMkvKRLNi2EK7hHQJ+uvv37+FIipfve73zliLr8T5sXVi2nEzI7PX+hXMOyHHnpo4W63/dprr9k+++xT9FjBzo+gFDAzMk7/yTEKZu+22275F9Rzzz3nXkypAuK8FaJrptgHFfdFDUQNlI8GSI4xs5mwM4Iu2XfffZ2rJBhBsNGjRpEDlBNYF0lUYXScEmB7IUGI4N+fybbkKcGBc95hhx3mjCTQROSPf/yj3XcfMTgnpNbPgZDx11N84yNcLnCaMNrHeNM0PvwgJ598clh1S/z4uGxS8h2228ye8Hw6+IG2N7NLzcy92MgI5dkKfPUOEol7hheZl1sihrt8vsOxJ1EDUQNFNGBmT2OwoINlRA62O5We7lwpGMoguGKgCE4JmGZ8FgQp+XvGG3cqMGHclyD7E8PIJm4OEl1IZPKCBW4Uv21my3FebW2t9ezZ0z744AP3ohg4cKCBlEFoK5BZTZ061TnXOR+q34KEI39LAy0TkDOO4IrsU4Kyzz/PIzjhJUUijl144YWu72SsptA3uRJIRXQad0UNRA1EDXSqBjynSvbdd9+1W265xchC7NWrlz3wwAPevpntuuuuLksx7ABeyOg7BCtTmYvhlLDM1ZPLGXiSlWzDDTekjJudfjq5Qk4mFYMjppXiIZOfM2MgoMoI/dZbb3UBzz333NPBIkMm6aRJk/CnQ6L+LK0zMwA1A5f6U0895Qw3EEeSlIKRhl4AxA3c4/wFxI1P9JkGEoeZCzMPjjPjgPvFCzVZo0QNRA10kgaif7QRxfvsSmhfXdZh4BKn4s+AAQNcmTb4zy+//HLHMU4z8LPDoR4KTIemBw0a5K5ZeOGFHV96v379PkmSZFmOmxmGfmP4xyke/dlnn8GhTt3NDZMkgXGxSTEzSM/hcC8sGJ2/btq0aZ9sttlmLz/11FN7+SxKqjENgWsernMqA1E9KrBS7r333oFrPN9GagVGzM1hV6QUamp/ehXmxf3SO+J61EDUQNRA2WgAd3hIS2d0Ci49CK4NbDMj+yCk8qdw32F3seWZPKTnCHeAc7DsBxxwQDj3/JYoAZIrj+YhBR6HP4EAIJJwwuBwbzCK9hzpZLvmSjOFuzZcEivAP0Rc4DKfjXlk8P/7e5K2D5kXgVSQRGeZ2fot6Xs8N2ogaiBqoFM0YGYOowhsMEX85IigVlhhhWAOoeh1LhsMfErgcMHPDsf6J2ZG+jmUAgRCe3jOF6P8G7Y+BYeEgrbdZ1Wk7JvZzmZ2pqe95b6sU36uaBC3Uz6EeNOogaiBqIFSa8DMXG1Ugp34lBEggfPNN5/zNXtDDmWA853vuOOO+UzRlJEPqyQG0R6B1FfDTigCMO4BLeP3txefe6lVFNuLGogaKEMNtPvosAyfuUVdMjMKJa/08ccfu/qb1MrEN00lnnvuuSf4pqGIHU990OnTp1dQq3TGjBnaf//9Xc3V3r17a4EFFnB/+N8lzZbUc9KkSbr55pudz5udQ4cO1e677+7qrFLJJ0mSOZKWWtT5eHLUQNRA1EDUwJwaMLM1GEW/8cYbBndLkGuuucbxvYBS8fVAV+Fq76OHhMshS+D7BlET/sDJe1ZGLnwxtFdkyQifAt1RogaiBqIGogZKrQEzc9WSoRH41a9geTUXQCV9f8wYiBOdXJm+r6fzzbNphZNSS/zwf+QakC6+ODP0sdR3wx8PrW7RbNT0feJ61EDUQNRAUxqIbpkmtEMBHQpkjxkzRs8884z69Omjl19+Wccdd5w23xw0oCiivEGSJBSgbiBmRoFsmBUZ1feVNNMXbb6zsGh0gwvjRtRA1EDUQNRA+2rA85fDseKSc1IJOuwiGWix9u1BbD1qIGogaiBqoF004ImzIAoDxog/HWjjcWSHtssNY6NRA1EDUQNRA1EDUQNRA1EDUQPFNPD/oAIXGFOCe08AAAAASUVORK5CYII=" - } - }, + "attachments": {}, "cell_type": "markdown", "id": "c9085e80-e7ba-48e9-8c50-12e544e3af46", "metadata": {}, @@ -644,7 +688,7 @@ "between any point in the first space to the closet point in the second. This is especially useful \n", "as a similarity metric between trajectories.\n", "\n", - "\n", + "\n", "\n", "[Hausdorff distance](https://en.wikipedia.org/wiki/Hausdorff_distance)" ] @@ -698,11 +742,7 @@ ] }, { - "attachments": { - "f73d72ad-8832-476e-9712-0676a4bbad10.png": { - "image/png": "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" - } - }, + "attachments": {}, "cell_type": "markdown", "id": "993d7566-203e-4b87-adad-088e2fd92eed", "metadata": {}, @@ -713,7 +753,7 @@ "uses the `lon/lat` ordering to better reflect the cartesian coordinates of great circle \n", "coordinates: `x/y`.\n", "\n", - "" + "" ] }, { @@ -724,6 +764,14 @@ "tags": [] }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/491857862.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] + }, { "data": { "text/plain": [ @@ -761,6 +809,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "7f2239c5-58d0-4912-9bd7-246cc6741c0a", "metadata": {}, @@ -806,6 +855,14 @@ "4 75.821029\n", "dtype: float64\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/1097934054.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] } ], "source": [ @@ -819,13 +876,14 @@ "print(zeros.head())\n", "lines1 = gpu_boundaries[0:50]\n", "lines2 = gpu_boundaries[50:100]\n", - "distances = cuspatial.core.spatial.distance.pairwise_linestring_distance(\n", + "distances = cuspatial.pairwise_linestring_distance(\n", " lines1, lines2\n", ")\n", "print(distances.head())" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "de6b73ac-1b48-422c-8463-37367ad73507", "metadata": {}, @@ -847,6 +905,14 @@ "tags": [] }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/2846028812.py:2: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\")).to_crs(3857)\n" + ] + }, { "name": "stdout", "output_type": "stream", @@ -890,6 +956,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "008d320d-ca47-459f-9fff-8769494c8a61", "metadata": {}, @@ -907,6 +974,16 @@ "tags": [] }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/3261459244.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_cities' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " cities = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_cities\")).to_crs(3857)\n", + "/tmp/ipykernel_261438/3261459244.py:2: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " countries = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\")).to_crs(3857)\n" + ] + }, { "data": { "text/html": [ @@ -1045,11 +1122,813 @@ ] }, { - "attachments": { - "351aea0c-f37e-4ab9-bad2-c67bce69b5c3.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAADlCAYAAADDa0bjAAAgAElEQVR4Ae2dB7QsRdW2H0VyzlGiBEWJAhIkg4AEFQQFxYSIElTABCZ+EQkiSlQBM4qinyDhV0EEEflAFFSCRDEASs4Z/NZ7bvW9feZM6JnpUN397rVmTc90ddWup3umd1ft2vtFWMomMBewILAoME9ofA5g1g5FngKeDN89ANwXXk90lPNHEzABEzABEzABExiKwIuGKu3CWQgsBawELA8snDrgv2H7sWDI3QM8HL6TUfd0qqw2ZwdmC98tEOpaCJCxKEmfu7uB24GbgP+E/X4zARMwARMwARMwga4E0kZE1wL+sieBmYA1gLWBRQAZeHrdGQyx24B7ex6d747Fg8H58jCyKD1eDNwFXAXcALyQb5OuzQRMwARMwARMoK4EbABmP3MajVsf2ADQNK5G7K4GrizR0Muu7bSSSwSdVwdmBh4ELg86PzdsZS5vAiZgAiZgAibQDAI2APufR42svR5YBZDBJOPpMuCh/odFu1dT0psA64Yp5GuBnwP3R6uxFTMBEzABEzABE8idgA3AqUgXA94cplLlTycD6ZapxRrxzWrAVsD8wN+BH4dRwkZ0zp0wARMwARMwARPoTsAG4DQucwJvBFYFtKDirPDenVozv102GL5acCK/wfOBZ5rZVffKBEzABEzABNpNoO0GoBZx7Bymd38CXNfuy2F67zVFvAPwLHAmcPP0Pd4wARMwARMwAROoPYE2GoBazLE7oBWz8oGT4aeYe5apBOYG3hLC2mjBi1h58chUTv7GBEzABEzABGpFoE0GoIIu7xV8+74DXF+rM1W9shoV3BW4Ffh2Kkh19ZpZAxMwARMwARMwgaEItMEA1MrXfYBZgNPCYoehILnwJAJaEf3OEPrmVOCRSXv9wQRMwARMwARMIHoCTTYANeK3b0ixdlLEsfqiv0h6KLg08P6wWObrnkbvQclfm4AJmIAJmECEBJpoAMrwOygsYPhqSLsWIfrGqCRD8H0hfMyJNgQbc17dERMwARMwAROoDQGFcjkhLPCojdINUXQd4BRgs4b0x90wARMwARMwAROInIACGmuad9PI9WyDegofIyN8+TZ01n00ARMwARMwgToSqPsUsEK6fDTk5f2Kpx+juQQ1DX9wmBY+Hng+Gs2siAmYgAmYgAmYQK0JKKft14Blat2L+JT/AbBCTmq9Iqy8XjOn+lyNCZiACZiACZhASwnMARwJ7NLS/hfZ7Q2AB4CNcmzkJcCBwMeBmXKs11WZgAmYgAmYgAm0hMBKgKYU8xqhagm2TN2UcSaj+rKCjGul3dM0/RKZtHEhEzABEzABEzABEwgx5/YG6u63GOvJ3CrETPwhsF9BSmo08JCQUaSgJlytCZiACZiACZjAIAIvHlQggv3zA18E/gAo4PB/I9CpaSosGAI6Px3eFyuog8ojfERII3ccoOl8iwmYgAmYgAmYQMkEYh9NWxE4APgccE/JbNrUnFLlzRc6vDFwV8ibXCQDhYmRb+DhwL+LbMh1m4AJmIAJlEpAETpmDy3q3tJpayiFqKJDPAs8Vqpmbmw6gc6TMn1HBBs7AUsBJ3vUr9Cz8aqQz/fvoZV3ATsD2xfa6rTKZwU+C/wcuLSE9tyECZiACZjAeATkx60HePniLxcMPRlzz4RqE6PuyfD5oS73cIUKk9/5zMBcKQNRNolm+eQu9DBwB6B70z8A1WPJkUCMBqB0+gTwZ+C8HPvqqqYS0I/vncCpqV0K5PxpQJk9yhLpoD+Q75bVoNsxARMwARPoS0CjeK8EFMZr0WCYyTjTjI0MssQwk+tQESLXJBmaibGpkUS5EcmwvA74Y9ChiLZbUWdsBqCs/k8BPws+f604CRV1cgvg86Ht1wP3A2uF7xQGRlOzR5Wo25bA6sCXujwtlqiGmzIBEzCBVhJYANgQWBvQ+gBNzf4JuCYyF6xZQrpXZQBbNpypB4HfAn9x4oHs125MBuC8YTrw6LAQIXsvXLIpBF4OvDesFH6qKZ1yP0zABEwgQgIy8jTTs23wAb8PuAS4KjWdG6HaXVXSaKGMV4Ubk2vR7cG16M6upf3lBIFYDED5+h0abvyy5C3tJSD/ko+FaWj5gFhMwARMwATyIaBZtq2B9cMon6ZRLwr+dvm0EEctihksd6alQ3KDM4Gb4lDNWqQJvBT4KjB3+ktvt5qA/E0U8kdTEhYTMAETMIHRCWigRy42ml2Tf/2qo1dVyyM1u7hnyCCmgSYtXLFEQEDOncrsoTl9iwmkCcwJnAIUFZMw3Za3TcAETKBpBGT47BsMnzeFqdGm9XHY/mhE8KDg375NGAUdtg6Xz4GAjD+lBqur8aeMFo+HpekKnWLJn4CMQF0jC+VftWs0ARMwgUYSkB+cFlMeHEKpNbKTY3ZKo6KbB0Pwo8DiY9bnw4cgsCTw5Ro/kci/4IXUsngtWFBcI0v+BPQUe2IqUHX+LbhGEzABE6g/gdcBnwm+b4qxZ8lGYBFARqCyVCn5RGukikUgGs2R8XdGiAJeR9jyoVAf0rI7cG/6C2/nRkAp4xSc+v3AE7nV6opMwARMoN4EZOhpelf3pF8AV9S7O5Vqr/vMu4FlgO+H8DeVKlR042UbgMrrq7RuCuSoVTl1Ff3oTgOURUNycXiCCB/9VgCBt4bI8XJidoiYAgC7ShMwgdoQ0L1bD8W6B/0IuL42msevqBIk7BGCYJ8O3Bi/yvFrqHQvJ4WpUqX/qrso1tAuIWWa4ik1SeSXeSxwA/CNSKZfdc0oRIxGXhXKwGICJmACbSMgw0/3ncOAVdrW+ZL7q/u6WLduajhvzgKpDA/y/ZM0wQAMXWnkm/whlPIneSlMT9WSXDMKFq0/P4sJmIAJtImAMl98Adi0TZ2OoK9KifeBMMunhYmWIQkot+zKqWOSm3nqK29GROCbKeNPRuClEeiWvmY2APaLQCerYAImYAJFE9AiBblOKWWnpToCykUsW0ahdZo261cY1b1C5PF0A+mbefp7b8dBYPuOVc4xGFud18zbgB3jwGUtTMAETCB3AprufUcI6SLjwxIHgfWAY4BXxKFOvFoozo6GTjul82beud+fqyewVfB9kA9EDNLtmtHTmKZFLCZgAibQJAIKWCy3qTWb1KkG9UUjgIpK8SH7pHc/qwqs+MXuu+wD2IOLv+5NoJsBqMUgWljkNIK9uXmPCZhAfQjIsPgwcIANi1qcNIWMOQ5YtxbalqSkllGfDMh5spt0u5l3K+fvTCAh0OuaUWghDcdbTMAETKDOBOTrp+gL69e5Ey3UPT0aaN/AkHD6ZX0uhF438z6H5L5LgZtvCfGTlBPQEjeBfteMnr7eG7f61s4ETMAEehLQAo9P9hk06Xmgd0RDQBnCFDFjuWg0qkAROeYP8hvrdzMvQ+WlgGdSK10fBry8uwzyo7cx6JqRr+nao1fvI03ABEygdAKKuar/tjeU3rIbLIKA4gMrTNmbi6g87zrzHq5UmjeNxvw4b0Vzrm9ZQNPUiSiP76LJB7/XksApIXp7L7eDWnbKSpuACTSWgO45mvJVVqyzG9vLdnXs6ZCPWf7pBwNlZ1urlLYWfSif3iAZNJoz6Phx988epn+TQMfKn9iqEzUuwAqOz3LNLBziNFWgnps0ARMwgcwENgaOBDRiZGkmgRWDgd+KED6KV5TVeTXLzbzoS0KjlfsD+wBKU9dE0WjsOcBPQl7DOvcx6zUjF4Tt6txR624CJtBoAophqvulpfkEFKHiKEAZrBorWvBxyBC9y3ozH6JKF+0gsADwYMrP8S5AI591lWGuGaVLWrCuHbXeJmACjSSgWaaDgNc1snfuVC8CMwX7SBmsGinyYxhmKHuYm3kjgZXQKY3GJlPcyXudk4cPc83I+FXqJIsJmIAJxEBAD99HAyvEoIx1qITAe4C3VNJyj0bzWASyG/BTQM6PlngI/AW4O6XOrcBtqc9N3nwghPfZrMmddN9MwARqQUA+YPL3U8DgtvwH1+LElKzk6cCTwMdKbrew5pILe9gGhhnNGbZul59BQHGJFJD7eECpheoso1wzWpSUXu1d5/5bdxMwgfoRUHDnrwFaoGYxARGQj/owLnPRUtNNeRRfq1Fu5tFCsGKlEBjlmtEqrA+Wop0bMQETMIHJBGT8KTCwU1VO5uJPsGmI/1gpi3GmgFcF/gPcX2kP3LgJ9CagTC+K8bhY7yLeYwImYAK5E1gixIM7EHg099pdYd0JXAKcG1YIj2OHVcZB04pa3TKKjDKaM0o7PqY5BEa9ZhTi5/DmYHBPTMAEIiegEGMnNji8WOT4a6XehsARVcUhHtXyVO7c/w88XyvUVraNBB4D/gas2cbOu88mYAKlEpg3BKOXo7/+eywm0I/A5cD5wKf6FYppn0b95Fw/jow6mjNOmz623gTGuWZ0zR5T7+5bexMwgcgJyNdPK32zZMOKvCtWr2QCilghd4FSZZQRQMWx+X6pWroxExiPgEaqL2Wa4+14NfloEzABE5hKQDnINZUnd5Mnpu72NybQl8CvAYVqe1ffUjnvHNYAnAVYHfhjznq4OhMomsB5wLZFN+L6TcAEWkdAGT4UeF4JEbwosnWnP7cO/yysqygtU8ywBuDuwLdy664rMoFyCVwEbF1uk27NBEyg4QSU3u0M4I6G99PdK57AacC6wCuKbwqGMQBfAiiV2A1lKOY2TKAAAhcCWxZQr6s0ARNoJwFlwlLWpWvb2X33ugACciPYC1iygLonVTmMAagL/YeTjvYHE6gfgd8AThFXv/NmjU0gNgIaqVGGj1/Eppj1qTWB/wKHAp8sekHRMAagfP+uqTVWK28C05bcK4yRxQRMwARGJaAMWG8EThq1Ah9nAn0IKGfw0cEI7FNsvF1ZDcCtAE2fNVkUMHjUwNZN5tK0vunp6kZgtaZ1zP0xARMohYDuE8rlehig/xOLCRRBQPFrZXe9s4jKVWdWA3DzBhuAMwNnh3Q9Sm23cVGwXW80BH4A7BKNNlbEBEygTgSUX/wU4Kk6KW1da0lA4WGUynStIrTXwo5BsnLDVzftAewUIGhYXz9s5Tm2NJfA0+HPW+fbYRuae57dMxPIm4BCdPw9xGzLu+5B9a0TfMM0e6HVoi8AywOaLvyQRyMH4avtfk0FnwDcBjxcdi8+DSjCeZ4yTlaHPPVQXfuHH46G8vX6Z94NuL5cCOR9zbwUOCAXzVyJCZhAGwhowYfi/VUpav8LKQUUg1BThQ5vlYLSwM3FgaPy7tegKeBZAY0SPpp3wxHVp6wmSfwmPVEpmrul+QRk6GuZvf5ALSZgAiYwiIDy+6aNr0Hli9i/IfC7VMXyR5wTeCT1nTebR+Bu4OKyXZfeDKxdAMu8R3PGVVEjnK8vK/jiuMq29PgirpkdgfVbytPdNgETyE7gbRH8V2gw5jFAriuJaGrw+OSD3xtPQA8g8gnMRQaNAK4B/CGXluKuRCOc5zvIddwnqQDtLgAcEqYAsK7SBBpEYGlgWeCKivukhQAa6VNUjreEEDTyZ9aiFEs7CChI9Efy6mo/A1A+Unfl1ZDrMYEICTwHPFN0sM0I+22VTMAEshOQr/CXshcvrKSmfzVQcWZ47RsWgdgALAx5dBU/DmjgYuc8NOtnACrI5Y/yaMR1mEDEBJSAe/uI9bNqJmAC1RFQuKhzgCeqU2F6yxsBl0z/NG3jTuDVHd/5Y7MJ/CqEhZl/3G72MwC14unecRvw8SYQOQHl8XxV5DpaPRMwgfIJzAusCVxWftNdW9QIYNoAfDmwK3Bq19L+sskEjgUOHLeDveIAyufhX+NW7uNNoCYE9HSvlXQaXreYgAmYgAjsB+hGW7VooZoWoWjEZ+8Qrkz/VysCWqip/OaWdhF4ALgJ0Kjwb/PuunwLFs270lR9RazoTFXvzQoJLBBCJZwOKFl6XlLkNaPFTs4MkteZcj0mUH8CrwTeVf9uuAcNJqAQZloB3m8md6Tua6VJkVLkzbxIvV33YAJ6GkmCamtkbYXBh/QtofA8GplTnbcWuGCj6Gu+bye90wRMICoCX3SM0KjOh5XpTkCDFyM/qHSzHOcDHuzelr81gb4EFDh8g1SJ2XOInfWdlNEnY/Krqfrz3NSKYAVVtZiACbSbwA7AeeGhs90k3PvYCVwLyBdULgFDSzcDUDGGLhy6Jh9gAqCYVNekQDwLXJ36PMrmXB0HKR5XEXIl8JoiKnadJmACtSEwM7B5x2KL2ihvRVtJQNPAHxil590MQK2I1MpIiwmMQmAn4IwQr+oNwF9HqSR1TOfDSO75EENblwIbp9r1pgmYQPsIvAPQrEMZsi1wWMesSRntuo1mEdCCXY0ALpRHt8rIhdsEH8BZCl4ok8e5bEodHw1ZWjYruEP2AywYsKs3gYgJyIVFvn9lSLKaV77NykHvjERlUG9uGwrbd+iw3esMA7NyDiM2w+pQx/LbAd8HFCdKviJvAjTdaSmGwNHBD/DXxVQ/vdaHwznVu8UETKBdBA4Jfn8fK6Hb7021odWcevhcPfWdN6cS0EiXZpcsUwkkMZsXAe6ZujvbN7ooFQOwaKn7CKBWoyYrXfW+e9HAXD9lXDNawCLj3mICJtAuAhr9U5q1caMWZKWmxWzpe4iMT0t/AmXcA/prEPfeBYGhrqNOH0AZf/+Iu49RaDd3hxadnzt25/bxSOD58Mfx+9xqdUUJAS1YUcJ1iwmYQLsIvL3kgMqfAs4G/g18C/hyu3C7twUQuD/EBNR0cCbpNAD1RGIZTOALwQhTSY0G/nDwIWOXkM+hfOGSc6b8j/uMXasrSBN4BhBniwmYQHsI6D9VWTXuKrHLmrJ7I7B4iOMWQ67hErvvpgoicBqwZ9a6E2NC5TV8qPQilsEE9LS2GqAgxQrE+NDgQ8YuoXAo8hVJyzLpD97OhYDjAeaC0ZWYQG0IbA+cUxtti1FU4bUUBqtzXUAxrbnWoghoRFm23GxZGkgbgBpRuirLQS4zQeA64IIS88fKOL8hxV4x92LIU5lSqRGbYrxqI3riTpiACWQhsB7wuywFG1pGqV81k3UFcHlW46GhLJrQLS2U2S1LR9IGoEay0kF8sxzvMuUSUIzGjwMnhMU695XbfCta+4P9AFtxnt1JExAB/afe2GIUyQrkJAuS8rcrqoWlvgSuDzOUnTOGU3qUNgCVtuvJKSX8RUwEFC9KgZAPGGepd0wdilCXO0paCR9h162SCbSOgILVn9W6Xk/usNxe0uKQZmka9dxWYoONBqmeNgAHlfV+E2gDAS2E8u+iDWfafWw7gTkAGT9yp2mr6P/uoBSDi8Lq5LbyaEq/FdJImWb6SnKj08rHzqeAvgd6pwmYgAmYgAnUmMAuwJk11j8v1ZX6blHgpcDWTmqQF9ZK61G4uMeB+ftpkRiALwNu6VfQ+0xgAAElo74bUBaNcwFFJK+rPBIygtRVf+ttAiYwmIBCv/xtcLFWlND/tjJtOBRcc063spXt2q87iQGoH8LN/Qp6nwn0IbBj8EvUarrFABlQp/cpH/su/Rb0UGQxARNoJgH9vm9vZtfcKxOYIKCHm76ZbRIDUDGA5PxuMYFRCCixuULSKIuMFhIpYLVia803SmURHKPfwnIR6GEVTMAEiiGgla4/KaZq12oC0RDQYIYG+LpKYgBqnvjBriX8pQkMJqCnjHQKwTuDT+mSgw+NssTfAQfZjvLUWCkTyIXAvGGmIpfKXIkJRErgx4BWuneVxAAcGC+m69H+0gSmEVAIIeWRTkSGnyLKyxCsozwKzFNHxa2zCZjAQAIK9K5A/hYTaDoBZSnruRAkMQCbDsH9K56AYhNqFZmMwSNDlpQyUuQV3zO3YAIm0CQC2wHnNalD7osJ9CFwWy+fdhuAfah511AEFEpAqfG0EngB4N1DHe3CJmACJlAOAU3/apTfYgJtIHA2oIWaUyRJ/Oyl31PQ+IshCfweOGbIY2Iu7t9EzGfHupnAaATk2ysfX4sJtIXA/b2mgTUCOJefhtpyHbifJmACJtBqAsqOoJkKiwm0iYDiPGrke5LIAFwQeGDSt/5gAibwDKAMORYTMIHmEFiqxovTmnMW3JOyCVwMbN7ZaGIAaojQYgKjElAcyUtGPTjS4/RQJF9GiwmYQDMIzAy80IyuuBcmMBSBa4A1O4+QAahhQa/W7CTjz20noN/ElCHztkNx/02gxgTWBq6qsf5W3QRGJSCf9pk6D5YBOBvwdOcOfzaBlhPQb0K/DUs9CCxUDzWtZYUENgEurbB9N20CVRJQsga5QEwXGYDyc5K/k8UETGAGARmA9gGcwSP2rRMA5b48OaQhnCMHhT8QwhrJgfpcYJEc6nQV1RHwgsfq2Lvl6glcDmyYVsMGYJqGt01gBgE9FM0646O3IiewO/DmYLAdCtwL/AL4ILBSD931/7c/8BbgM0DaaFTcLAU3Xw9YLKQNO71HPf46fgLKduXQTvGfJ2tYHIHrgVXS1dsATNPwtgnMINBrBFCjCDIOvhn8iZT9xFI9Ad3crwY+B6wPrAz8BzgOuClEO+jUcgtgbuDMUF4RERLZGzg25Lh+EvhoGFmcLyng91oRWBG4pVYaW1kTyJfAFD9ABYLW69l823FtIxLQKrUDRzx20GEPDiqQ2h9jWeUzXD6lY3qzCH31m5gTWA7YFdgMWDT4UCT+ZncBT6QV8XalBDTSpzhv2wCvBf4cRvYU961bpAN9J8Nu3RDE/J8p7VcIxl/ylfJaPwcoz7UXzSVU6vO+DnBlfdS1piZQCAE9zMq3/SnVLuPv+fBeSGuudCgCMjqOGuqI7IV7JoTuUkUMZTuNvcUBreLrJkXo+0rgDYBGyfWD0XunaJRwGOOz83h/zo/AtwDleNW0r9IS7pEhvukfQ2gETQHLd3D1lDrKab106rMMP/1fyhC01I+ARgC/Xz+1rbEJ5ErgOkD3Ns2WTPyhOeBtrnyjrWwYQ2WYsmV1eFXgrLIaAzQ9+D1AIwcyBNV+56pg+Ywd0UUnGQqPARohVG5k8dRLn2Nk26ULtftKU79atJGO85Y+XxNPvKleyRn6U2G0UA9dOr+dIh/AnwP3AUeGDBIe/eukVJ/P9gGsz7mypsUQ0KyI7m02AFN8NbV3BrAGcBHwLkBDpZb2EtAKYAWDPjwYeTsEA2MtIJkCVk7Rj/dApBEkjVouEfIwakRz+46cjCoj0UPY4ykjMW00ats3rgCqz5v89Xbqs3/hYMglRe4Io4V7hnN0SLIj9a6RRE0fy89TK+jendrnTRMwAROoGwGFgpk+s6GRCo8AwjHBKtbJ3A34C/D5up1Z65srARmAmuKVaFTpnPCSv5j8NFcbED5JDxC3h1eopu+bjEFNZSdGowxGfdYrPZKlSjQdLd/DZFQxbTD+u2MUrG+jDdqpUdphRFO5WiDST34ffAP7lfG++AnI+NeqcIsJtJ3ApMGEKgzAtwLvAzYGDgbkh1O1dK7kXKZqhdx+5QQUAkYPR52iTALyGVNoEBmBeYkMRr00TfyHDJX2MhhlQGpfegRbEeCTEcZOo1ErZeUHbDGBphJ4BXBDUzvnfpnAqARkAD6SmtIatZ6sx8kRV9Mqalc30J8CyiM7ySrNWlmO5RTSQ1HiFStKCzGko6XdBOYJv41eFDTSpldVMqrBmIwyakFNrxFG/Q5Uv4zF5JX4M94TVsNW1W+3awLDEpAB+D/DHlRBefmwyi9VvsW/Ad4D6PdmMYE8Ccg/XeHMHpMhJj8nxcwqQ/RDVJuJaC5acbV0k6lSZPDdGsJBXAgoYKKl3QQUE06/jaZI2mDMcn0nI4yJwahFEhv1mJJOGKWnohODUVNvdQwzpQdTSzMIKINL7IZUOvC4fjOnAQo8Lt9jiwnkSUAZkxTe7C8yxhQLa4E8a+9T12/DqIlG/yRacFG18RdU4Xcw8Uo+t+Vd/mXKgiA5LIkPFD63+U0GUJtj/A1rMOo60v9IMqooH8Z+BqOm2DWC2mk0/qvH1Hubr0X3fTwCdcgCkg48rt4qPqV+Cxog8crz8c6/j55MQAvg9IA7YQAqz+W8k/cX9knG5muAbwPnhdhbhTXmigcS0GIC/ckkGRD0J6QV0Qp4azGBYQgozIpG/fTKIjIAdd0lBqPeNUOgVdOdi15UnxblyF+x02DUYo5ksU6Wdl3GBGIk4MDjMZ6VZuokA3ADdU0jgFrh2C3IbVFdV+iMS4AvFtWA681M4PUp408HaQRHoUrOzlyDC5rAaARktA1jMKoVGYlJWJ1uBqNGbSUavVRWnUdDG2mjUQ88eui1tIeARgBjF12708NzhIwzuj878HjsZ65++k2f9U3749WvG9Z4XALp1FdJXTLQLSYQI4FkQUpW3XRTTcLqyGDsFosxqUv/hQ7endBozrseBOrig+rA48257mrRExuAtThNhSl5bVjx/PbQwneBawprzRWbQLkENBI4bCzGQQZjMsro4N3lnstRW9OsRl0WcznweO+zPHeIHGKfyN6MhtkzMSpuA3AYZM0s+w5AL8sMAvJB6xYDcEYJbzWRwCgGo0YWE6PRwbvjuypkAGrKqw7iwOPdz5J8g38NaDW3EjW8DlA8VsvoBCZC7yUGoP745gzBYkev0keaQDMIKDC4UuZYTKAfAf1v6iVfRgfv7kequn11GgGsjlLcLSvzkow/iUYAlX7zTeGz38YgkBiA8vuSA+qNY9TlQ02gKQS0RF4rpSwmkCeBUQ3GZJTRwbuHPxsyALOuTB++dh9RBoHOqBR18eksg82obUyaAtbNTtMXNgBHxenjmkRAv4Xzm9Qh96WWBNIGo4N3j3YKZTxnYTda7fkd5cDjvVkeA2wDKEWrVvQf3ruo92QkIBenWZIRwOuAfX3Ty4jOxZpOYMkQH7Hp/XT/mkVgWIOxCcG7ZRQorE+vYMlatNPmgO5NuMJvC9nKjgMO6shz3oT+VdEHxW2dNTEAk9xwVSjiNk0gNgJ1iBsWGzPrUz8CTQje/XlgMzQ5VGYAABcCSURBVOBq4FBAgxlpUQBxTxmmidRzW3FDlc5PDzmW8QmI53QDcPzqXIMJNIeADcDmnEv3JD8CMQbv1uJFBQdXLt3XAreE0FZfCxmNFAfQK/rzuwZcUzMITDEA5WhZp6CZzTgN7kVsBJSnWjlqLSZgAuMTKDp492opFeXvty6wJrAf8JuQPtAjgClI3jSBkD5z0gjgzcBKNXGY9Rk0gaIIvEpJsouq3PWagAn0JaApvqzBu+XDuElYwJiuVAMZqwArAop3pkVdWX7TawH6/dclbmC6z2Vsy1VsHGNaDwNnlaGo2xhIQKPikwzA3wFbV2wAKhSN4vvIqfcMD90PPIkukD+BVwNfzr9a12gCJpAzAfkwJn7sqloGinI9K6yZMhr9D7Ad8LmQ835Q88qIpPugFh1YphKYK8wSTt2T7ZvnsxVzqRIIzCQXifSPRz+apUpouFcTCvSoYKoLhQLbArv2KuzvTaAgAlo1aEfjguC6WhPImYAWefwqLP74IaBsGum4cZtrpMO/6Vyoy8C2NIOAfhPPpA3Aqru1Rcr4ky4aCZSScla0tJuApnnk11N0gOYXhymjdtN2702gPgRWHaCq7h8yEv1QNwCUd7eKgH4Tz+iGlxZNvcqRtgq5taNRjUja+OuA0sKPBwCXhFV+1wY/1aIwrOxg6EWhdb0mUAmBCV+nSlp2oyYQL4GuBuAVYRVVFWpr6F45/5SDVTGd3lqFEpG2qfn67wafSPHRiFhb5P2pjs4LvC31Oe/N9YMPUN71uj4TMIFqCExkPKimabdqAtESmAiP1DkCeFWFBqBIKdK3IruvA0gXyzQCmg6X4aOT9lLglBaBkVN3Wv6Z/pDztq49GdgWEzCBZhDQ1K/8ei0mYAIzCCh+5hOdBqBW6cTkFzhD3XZvLdzR/c7PHbsb9VFTwFocJMfubwPfKqh3GmVVyAiLCZhAcwjcByw4oDurA38CTgAOHlDWu02gCQR0v3u+0wBUx+4Mo0xN6GRT+vBj4K5UZ45PbTd980ZAoVmU8umdY8ah6sdq7eB60K+M95mACdSLgGL6DTIA5V6jgNJyMdkH2L5eXbS2JjAagW4G4C+BrUarzkcVREA5EPUHpWngjUJcq4Kaam218qv8dWt7746bQDMJZBkBVPzZtHR+Tu/ztgk0hkA3A/COLpHVG9PhGndET7IKjn15jfsQs+p6+n88ZgWtmwmYwNAEsowAnp6q9SHg7NRnb5pAYwl0MwDVWTnOyknQYgJtIKAnfrk+WEzABJpF4FFAGSz6ifz+dgyRFl7f4W7T7zjvM4FaE+hlAF4QUujUunNW3gQyEtgJ+GnGsi5mAiZQLwIvGqCuFn+dC1wI/GdAWe82gboTmEgDp070MgCVR3GNuvfS+ptARgJLAP/OWNbFTMAE6kVgkAFYr95YWxMYj4DudxOLSnsZgKr+WWC28drx0SYQPYHF/NQf/TmygiZgAiZgAvkQULxbZVrrOQKofecDO+TTnmsxgWgJ7AYozI7FBEygmQQ0mKHUVxYTMIFpyTYGGoBKzaaMHBYTaDKBJYHObCNN7q/7ZgJtI6DsQcqgZDEBEwAtepzIqNVvCliglBbLMZF8yTSVwLrAlU3tnPtlAiYwQeAGYFWzMAETmCAg176ntTXIAPwBoCkyiwkURUAO2p8ErgPOAjQiV5Yo4r9W/1lMwASaS0AG4Cua2z33zARGIzAo76+CaC4E6CbtPKmjMfZR/QnsnMpsoqd0+eooLEvRogTxuqafKboh128CJlApAcW1naNSDdy4CcRBQPdX+cROyKARQBVSTEDnRgzABrzJcNHimW8DWmptGUzglR1FXtXxuaiPbwe+V1TlrtcETMAEciKg+7QjcuQEs+XVrAzcnDDIYgBeCmyQHOD3ngRkuGg16XbAnl5Z2pNT5w4ZzM+nvjwntV3Upq57/RBuKaoB12sCJhAVAY30zxqVRtmUUWYSBadWRpMTsh3iUibQk4DsFLlbTUgWA1AF5UOxWjjGb90JvBpIT6lrgYEiblv6E9Bq802ArwD7AB/pXzyXvVuHke1cKnMlJmAC0RP4I7B29FpOVlCuV8pTLDcs3Vv2A7aYXMSfTGAoAqsANyZHZDUAfwi8OTnI710J/AZ4KrXnoo6RrdQub3YQuBz4EPA14LmOfUV83BT4VREVu04TMIEoCfwOWC9KzXorJaNvvo7dC3d89kcTGIaAbL7p6zmyGoAaPn8EUNYES3cCtwGbA98AjgDe0r2Yv62YgHwOb6pYBzdvAiZQLoGHgPnLbXLs1uSsf1yqFk3dnZf67E0TGIaAFkJpQdR0SU9ZTv+yx4ZGZw4EPttjv7+GK5j2Mot4CbwNODRe9ayZCZiACUwn8IngriLj9WLgsel7vGECwxFYC7g6fUjWEUAdoxFATXGWGactrau3TWBcAquHFVDpRSfj1unjTcAE6kFA6a/qmBHkMuBnNv7qcZFFrKVcIK5K6zeMAajjTgH2SlfgbROoEQGN/n23RvpaVRMwgfwIyC97yzGqm9luUGPQ86FVE9Ao8oNpJYY1AB8GXgAWTVfibROoAQEFmf5bOghmDXS2iiZgAvkR0AjgsiNWJ8NR4VjuBn5R05AyI3bdhzWAwJyd/n/q07AGoI75MrB/A4C4C+0isDdwaru67N6agAl0ENAAxqj3vWQRicJI7dFRrz+aQMwEXgsopvMkGeWHoICUdwGdGRwmVewPJhARga2ASzz6F9EZsSomUA2BUeMBzt2hbufnjt3+aAJREVBc4v/t1GgUA1B1aCTlPZ2V+bMJREhA1/iOwE8j1M0qmYAJlEtAoyCKAzqsfCG4P+m4O4Azhq3A5U2gQgLKATwlxu6oBqDiE8ma1LCixQRiJrAbcGbMClo3EzCB0ggomsW8I7T21TDrtX3IinXfCHX4EBOogoBma5XNbYqMagCqoh+F7CDDxBKcooC/MIECCcwDrAko04jFBEzABERAOcBXHAGFUmgpd7ncoCwmUBcCyid9bjdlxzEAlU7keC8I6YbV30VC4CDgqEh0sRomYAJxEDgH2CEOVayFCRROQOkEuz60jGMASutbw4qqFQrvghuoksCswJ4hBqSWk9dB1geUnu/+OihrHU3ABEojUMe0cKXBcUONIvCycB/s2qlxDUBVehLwga61+8smENA1ciHw7bD4R0nVZRDGLDMB8v1z0OeYz5J1M4HqCNwOeOCiOv5uuRwCu/RbAJmHAaj0cBpSf2s5/XErJRNYrmOxz2qAcgrGLPsCXwfkpmAxARMwgU4C8mHftfNLfzaBBhGQfafYlT1nwfIwAMXrN4AMhaUbBM9dmUbgXuCJFAwtJb8z9Tm2zbVDvL+uq55iU9b6mIAJVELgcWAOQLMFFhNoIoHNgIv7dSwvA1BtHAt8GHhRvwa9r3YEFDZBT8oyqOTzKV/Af0Tai9lChH6FbLCYgAmYQD8CSum2Tb8C3mcCNSaweXDf6tmFPA3Ap4HvAO/u2Zp31JWAQh8ol65CJ/wg4k4oReGXPPUb8RmyaiYQDwGFh9ooHnWsiQnkRkCZap5MBS/vWnGeBqAauAbQkuOVu7bmL02gOAIbAvcA/yquCddsAibQIALyEZaLy+IN6pO7YgIi8I4s2WryNgDVsEZglCZOQXgtJlAGgSWAbcNK5TLacxsmYALNIPAN4F3N6Ip7YQITBOTXuizwt0E8ijAA9VSlvImfGNS495tADgR0sSvg8+E51OUqTMAE2kVAMQHlO1yX+KbtOjvu7SgEdgR+luXAIgxAtfsgcB7w9ixKuIwJjEFAfn+nAgpHZDEBEzCBYQkoXujuwx7k8iYQKQG5Qykyy0ApygBUw3Kw1ZOVMjJYTKAIAkrn9Hfgr0VU7jpNwARaQSDJDewIFtlPtwZ3LgC+BiyQ/TCXLJiAwqBdn7WNIg1A6aCRmS2BlbIq5HImkJHAa4Bl+kU5z1iPi5mACZjAT4B1jSETgU2Dv7X8rvcG5EdpiYOAEnIoGksmeUmmUuMV+nxYGCIfrfvGq8pHm8AEARl++vP5jHmYgAmYQA4ErgQOAPYBns+hviZXoYfv9GjpVsCRJXS4Z0aLEtquQxMa/bsuxutX6UiOB2YOFD9bB5o56qgfy5eBx8LwrJ80h4ebXDNzAScG94Lha/ERJmACJtCdgAwbp4frzib97auDkaEFn3plHnFKV+Lt3AkcEXNmmyWDEaRVm8nNPHcCkVYoX7Xkx6L3P0eqZ8xq6ZqRT6kM6XljVtS6mYAJ1JaA/l/So1u17UjBimvU71vAJ0NKvYKbc/UDCKwC7DWgTOW7lUnisBYagB/oMAC1StoyHAFdN18BFPPPYgImYAJFEFBmEK8ILoKs6yySwNGpGdbM7VTxpKPpTxlEN2bWsv4FFRT7Q6knpcsApVezZCewFnBoyEec/SiXNAETMIHhCHwx+Bc/PtxhLm0ClRDQaOysIfReJQoM2+j2IVvIsMfVubymwPcDNB1cheFdZ3YHAxvUuQPW3QRMoDYElgrB5WujsBVtLQG51B1bx95vHUbF6qi7dS6PgEb9NPpnMQETMIGyCHwaWKSsxtyOCYxIYA9Ai5dqKZuEpfe1VN5KF0pAo6Qy/tYstBVXbgImYAJTCcwHaFWlxQRiJSDXsqNiVS6rXtuE2EtZy7tc8wnI+DvEgVmbf6LdQxOImMBuwOYR62fV2k1AkTEWbAICLQzRkHvRmUmawKrpfZgdOA7QsnaLCZiACVRJQP9FcrC3mEBMBNZr2jqKl4cwHzIALO0koGkXxeFavJ3dd69NwAQiI/Ay+6pHdkasjhZ+KLFG4wbMlgNOAjS3bWkXgcWAU4CF29Vt99YETCByAh8BdG+ymEAMBJSusLG+8QsFQ0BPXpZ2ENAqXwV5Vpo3iwmYgAnEROAlwS1FIy8WE6iSwKuAD1apQBlt64emFaA7ltGY26iUwDu8CKhS/m7cBExgMIEV2nDjHYzBJSokMEt4EGnc1G8vpu8F3tdrp7+vNQFdxB8H3ljrXlh5EzCBthDQvWidtnTW/YyOQCtdEV4LHGO/wOguxnEUkr+fnFhfOU4lPtYETMAESiSgh1atCvZCxRKhu6kJAsqE9c62skgCHipRt6XeBJQG8FMOrVDvk2jtTaClBLRITbmCLSZQFgFFxah9wOdxYSk48PuBfZu4/HlcODU4fuYw5fvWGuhqFU3ABEygF4GNgXf32unvTSBHAloPocgoc+ZYZ62rWj3EipNTrqUeBNYI52z5eqhrLU3ABEygL4GPAlqRaTGBIgkcBOj+aUkRkC/GnsB+gJfmp8BEtjkH8AVg58j0sjomYAImMA4B3YNOBOYfpxIfawJ9CGwHKEqGpQcBLSI41osJetCp9ms5rcpXZtlq1XDrJmACJlAIgbmBk+3PXAjbtleqmc5D2g4hS//lG6gRpsOdRSILrsLLLAMcDWxZeEtuwARMwASqJaAH3NY76Fd7ChrX+qLhHirbxpKRwAJhdekeXiSSkVi+xbTIQ3GyFKvIDqv5snVtJmAC8RLYHNg7XvWsWY0IKNizXAucDnfEk6ah088D24x4vA8bjoCeUnYF/h/ghTnDsXNpEzCBZhCQT/obmtEV96IiAvIrldvU0hW136hmFbH9CEBPZ5b8Ccjw2yUYfqvkX71rNAETMIFaEdgLkOO+xQRGIfA54GWjHOhjehPYARDYLXoX8Z4hCOgpZadg+CkelsUETMAETGAagQMBZa+ymMAwBOQ69ephDnDZ4QisFUYE93cqn+HAhdLzAopJpKlex78aCaEPMgETaAGBz/o/sgVnOb8ueuQ4P5YDa1o7rNo6GFhkYGkXkD/CocGv8uXGYQImYAImMJCAAkWvO7CUC7SdwIeBrdoOoYr+LxZWrB4JKGadZQYB+ffpolQ4lwMc7HQGGG+ZgAmYQEYCGmRYL2NZF2sfgQ8BlbpROc7MtEwi8hPUD/Uh4GzgpvZdixM9VsoZsZgNuAS4CPhvS1m42yZgAiYwDgHdXzV7cgHwx3Eq8rGNI/B+4Dbgl1X2zAbgZPryc9NS/pWA+4DzgZsnF2ncJ4XNeR0wH3AtcC7wZON66Q6ZgAmYQDUE5OD/B+Diapp3qxERkM31CeBy4NKq9bIB2PsMLAhsC6wMPAP8Nrye7X1ILfZodG+zMOKp8/+X8BTySC20t5ImYAImUD8CSlCgIL/frJ/q1jgnArMDcjn7KnBjTnWOVY0NwGz4XhKW9q8PKOPFU8DVwP8Cj2erorJSGtXcEND0rvrxdJje/T3wQmVauWETMAETaBcBxU2V77kyPVjaRUB5o2X8KdDz32Lpug3A0c7ErCFmj/wGZdWLo/wHNYX6J+DR0aod+yhN464JaFp3rlCbRvauAK4Bnhu7BVdgAiZgAiYwKgHNvigm7WFA3WeTRmXQtuOWDwtOPw3cG1PnbQDmdzY00ibja7WQx08BkzXiJrkL+HfwK5RvYfIKuwe+qa6FwktT09peMjxNahRPht3zwQiVofdn4LGBtbqACZiACZhA2QSWAj4WQmvpvmBpLgEtqpRNoNE/3aOjEhuAxZ+OmUJuPw39dxpxWVvXStzEaNT7/cCd4eVp3KwUXc4ETMAE4iAwT8hQdVrww45DK2uRJ4H3htnBr+dZqesyARMwARMwAROoNwHN7Ggk8O317oa17yAgfz/F0N2k43t/NAETMAETMAETMIHpBORL/iVA7j2WehNQUgkZf3IJs5iACZiACZiACZhAXwKLhvAgijRhqR8BudPtDewfpn3r1wNrbAImYAImYAImUAkBTQkrN+xnQjamSpRwo0MTWAY4Dlhn6CN9gAmYgAmYgAmYgAkEAssCp4aA/YYSLwEt8FQ+3wNSET/i1daamYAJmIAJmIAJRE9AxsUHgc8Cc0SvbfsUVLrYY4G12td199gETMAETMAETKBoAiuEzCE7F92Q689EYM6Qy3c/j/pl4uVCJmACJmACJmACYxDYDjgZWGWMOnzoeASUyk+jfgrkbTEBEzABEzABEzCBUggoBelBIYOIEgtYyiHw2mB8b11Oc27FBEzABEzABEzABKYSUJ53rRZWvDmFj7EUQ0CG30nAlsVUX32tTgVX/TmwBiZgAiZgAiYwLAHlg98XeCCsGn542ApcviuBNYG3ATcD3wCe7VqqAV/aAGzASXQXTMAETMAEWktgYeA9wHxhqvIfrSUxesdlC20fQu/8GjgfeGH06upxpA3Aepwna2kCJmACJmAC/QgoldxegHLRngX8qV9h75sgIL9KLe5YG7gMOKcNhl9y7m0AJiT8bgImYAImYAL1J6AYgpsB8mF7NExjaprYMoPAqmGaV3x+HKZ7Z+xtyZYNwJacaHfTBEzABEygdQQUNmY3YGbgYuBS4PnWUZjW4XmBNwIK4nwX8D3goZaymOi2DcA2n3333QRMwARMoA0EklHBTYDngJ8DVwH/bXjnNR2+DbAG8Ajw07aO9nU7zzYAu1HxdyZgAiZgAibQTAKzAIppt04wAK8FLgQeb0h3lwe2BRQrUUbfL+0P2f3M2gDszsXfmoAJmIAJmEDTCcgGUNiTLULO4aeAK8Po4BM16bxiIW4asqSoP3cAFwD31ET/ytS0AVgZejdsAiZgAiZgAlERmC2MDL4G0ApZ2Qjyl/szcD1QtVGokDerhZcCYktk6Mm38a/hs98yErABmBGUi5mACZiACZhACwksHUYJZXjNExaRKEbe3cDtwG3AnWHF8bh4ZgcWApYANJW7QmgzsVXU5jXh1eoFHOOC1vEJ1Dzqch0mYAImYAImYALtIKDROBmHywCLh/iD6Z4nC0xk1GlksZek7ZAngftSxqUMTGc46UXO35uACZiACZiACZiACZjAMAT+D1DzI94oMJxQAAAAAElFTkSuQmCC" + "attachments": {}, + "cell_type": "markdown", + "id": "e0b4d618", + "metadata": {}, + "source": [ + "### cuspatial.pairwise_linestring_polygon_distance\n", + "\n", + "Using WGS 84 Pseudo-Mercator, distances are in meters." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "5863871e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    osmidonewaylanesnamehighwaymaxspeedreversedlengthgeometryaccessbridgerefwidthtunneljunction
    uvkey
    42421769424433470195743159True3Columbus Avenueprimary25 mphFalse86.010LINESTRING (-8234860.077 4980333.535, -8234863...NaNNaNNaNNaNNaNNaN
    424217724242176905668968True2West 80th StreetresidentialNaNFalse271.702LINESTRING (-8235173.854 4980508.442, -8235160...NaNNaNNaNNaNNaNNaN
    424424690[1025731514, 195743132]True[3, 4]Amsterdam AvenueprimaryNaNFalse81.618LINESTRING (-8235173.854 4980508.442, -8235168...NaNNaNNaNNaNNaNNaN
    42421775106153152505668968True2West 80th StreetresidentialNaNFalse17.096LINESTRING (-8235369.475 4980617.398, -8235349...NaNNaNNaNNaNNaNNaN
    424286530404253364True4Broadwayprimary25 mphFalse86.209LINESTRING (-8235369.475 4980617.398, -8235373...NaNNaNNaNNaNNaNNaN
    \n", + "
    " + ], + "text/plain": [ + " osmid oneway lanes \\\n", + "u v key \n", + "42421769 42443347 0 195743159 True 3 \n", + "42421772 42421769 0 5668968 True 2 \n", + " 42442469 0 [1025731514, 195743132] True [3, 4] \n", + "42421775 1061531525 0 5668968 True 2 \n", + " 42428653 0 404253364 True 4 \n", + "\n", + " name highway maxspeed reversed \\\n", + "u v key \n", + "42421769 42443347 0 Columbus Avenue primary 25 mph False \n", + "42421772 42421769 0 West 80th Street residential NaN False \n", + " 42442469 0 Amsterdam Avenue primary NaN False \n", + "42421775 1061531525 0 West 80th Street residential NaN False \n", + " 42428653 0 Broadway primary 25 mph False \n", + "\n", + " length \\\n", + "u v key \n", + "42421769 42443347 0 86.010 \n", + "42421772 42421769 0 271.702 \n", + " 42442469 0 81.618 \n", + "42421775 1061531525 0 17.096 \n", + " 42428653 0 86.209 \n", + "\n", + " geometry \\\n", + "u v key \n", + "42421769 42443347 0 LINESTRING (-8234860.077 4980333.535, -8234863... \n", + "42421772 42421769 0 LINESTRING (-8235173.854 4980508.442, -8235160... \n", + " 42442469 0 LINESTRING (-8235173.854 4980508.442, -8235168... \n", + "42421775 1061531525 0 LINESTRING (-8235369.475 4980617.398, -8235349... \n", + " 42428653 0 LINESTRING (-8235369.475 4980617.398, -8235373... \n", + "\n", + " access bridge ref width tunnel junction \n", + "u v key \n", + "42421769 42443347 0 NaN NaN NaN NaN NaN NaN \n", + "42421772 42421769 0 NaN NaN NaN NaN NaN NaN \n", + " 42442469 0 NaN NaN NaN NaN NaN NaN \n", + "42421775 1061531525 0 NaN NaN NaN NaN NaN NaN \n", + " 42428653 0 NaN NaN NaN NaN NaN NaN " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# all driveways within 2km range of central park, nyc\n", + "graph = ox.graph_from_point((40.769361, -73.977655), dist=2000, network_type=\"drive\")\n", + "nodes, streets = ox.graph_to_gdfs(graph)\n", + "streets = streets.to_crs(3857)\n", + "streets.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "f4c67464", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    nodesaddr:cityaddr:housenumberaddr:postcodeaddr:stateaddr:streetbuildingbuilding:colourbuilding:levelsbuilding:use...officeopening_hoursphonestart_datetourismwebsitewheelchairwikidatawikipediageometry
    element_typeosmid
    way34633854[402743563, 402743567, 402743571, 402743573, 2...New York35010018NY5th Avenueofficebeige102office...yesMo-Su 08:00-02:00+1-212-736-31001931attractionhttps://www.esbnyc.com/exploreyesQ9188en:Empire State BuildingPOLYGON ((-8236139.639 4975314.625, -8235990.3...
    34633854[402743563, 402743567, 402743571, 402743573, 2...New York35010018NY5th Avenueofficebeige102office...yesMo-Su 08:00-02:00+1-212-736-31001931attractionhttps://www.esbnyc.com/exploreyesQ9188en:Empire State BuildingPOLYGON ((-8236139.639 4975314.625, -8235990.3...
    34633854[402743563, 402743567, 402743571, 402743573, 2...New York35010018NY5th Avenueofficebeige102office...yesMo-Su 08:00-02:00+1-212-736-31001931attractionhttps://www.esbnyc.com/exploreyesQ9188en:Empire State BuildingPOLYGON ((-8236139.639 4975314.625, -8235990.3...
    34633854[402743563, 402743567, 402743571, 402743573, 2...New York35010018NY5th Avenueofficebeige102office...yesMo-Su 08:00-02:00+1-212-736-31001931attractionhttps://www.esbnyc.com/exploreyesQ9188en:Empire State BuildingPOLYGON ((-8236139.639 4975314.625, -8235990.3...
    34633854[402743563, 402743567, 402743571, 402743573, 2...New York35010018NY5th Avenueofficebeige102office...yesMo-Su 08:00-02:00+1-212-736-31001931attractionhttps://www.esbnyc.com/exploreyesQ9188en:Empire State BuildingPOLYGON ((-8236139.639 4975314.625, -8235990.3...
    \n", + "

    5 rows × 35 columns

    \n", + "
    " + ], + "text/plain": [ + " nodes \\\n", + "element_type osmid \n", + "way 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", + " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", + " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", + " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", + " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", + "\n", + " addr:city addr:housenumber addr:postcode addr:state \\\n", + "element_type osmid \n", + "way 34633854 New York 350 10018 NY \n", + " 34633854 New York 350 10018 NY \n", + " 34633854 New York 350 10018 NY \n", + " 34633854 New York 350 10018 NY \n", + " 34633854 New York 350 10018 NY \n", + "\n", + " addr:street building building:colour building:levels \\\n", + "element_type osmid \n", + "way 34633854 5th Avenue office beige 102 \n", + " 34633854 5th Avenue office beige 102 \n", + " 34633854 5th Avenue office beige 102 \n", + " 34633854 5th Avenue office beige 102 \n", + " 34633854 5th Avenue office beige 102 \n", + "\n", + " building:use ... office opening_hours \\\n", + "element_type osmid ... \n", + "way 34633854 office ... yes Mo-Su 08:00-02:00 \n", + " 34633854 office ... yes Mo-Su 08:00-02:00 \n", + " 34633854 office ... yes Mo-Su 08:00-02:00 \n", + " 34633854 office ... yes Mo-Su 08:00-02:00 \n", + " 34633854 office ... yes Mo-Su 08:00-02:00 \n", + "\n", + " phone start_date tourism \\\n", + "element_type osmid \n", + "way 34633854 +1-212-736-3100 1931 attraction \n", + " 34633854 +1-212-736-3100 1931 attraction \n", + " 34633854 +1-212-736-3100 1931 attraction \n", + " 34633854 +1-212-736-3100 1931 attraction \n", + " 34633854 +1-212-736-3100 1931 attraction \n", + "\n", + " website wheelchair wikidata \\\n", + "element_type osmid \n", + "way 34633854 https://www.esbnyc.com/explore yes Q9188 \n", + " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", + " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", + " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", + " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", + "\n", + " wikipedia \\\n", + "element_type osmid \n", + "way 34633854 en:Empire State Building \n", + " 34633854 en:Empire State Building \n", + " 34633854 en:Empire State Building \n", + " 34633854 en:Empire State Building \n", + " 34633854 en:Empire State Building \n", + "\n", + " geometry \n", + "element_type osmid \n", + "way 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", + " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", + " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", + " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", + " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", + "\n", + "[5 rows x 35 columns]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" } - }, + ], + "source": [ + "# The polygon of the Empire State Building\n", + "esb = ox.geometries.geometries_from_place('Empire State Building, New York', tags={\"building\": True})\n", + "esb = pd.concat([esb.iloc[0:1]] * len(streets))\n", + "esb = esb.to_crs(3857)\n", + "esb.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "d4e68e87", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    namedist
    0Columbus Avenue4993.583717
    1West 80th Street5103.472213
    2Amsterdam Avenue5208.373183
    3West 80th Street5276.886560
    4Broadway5178.999774
    .........
    1859East 70th Street4193.471831
    1860West 65th Street3999.118604
    1861Dyer Avenue1470.617115
    1862Dyer Avenue1468.714127
    1863Dyer Avenue1548.205363
    \n", + "

    1864 rows × 2 columns

    \n", + "
    " + ], + "text/plain": [ + " name dist\n", + "0 Columbus Avenue 4993.583717\n", + "1 West 80th Street 5103.472213\n", + "2 Amsterdam Avenue 5208.373183\n", + "3 West 80th Street 5276.886560\n", + "4 Broadway 5178.999774\n", + "... ... ...\n", + "1859 East 70th Street 4193.471831\n", + "1860 West 65th Street 3999.118604\n", + "1861 Dyer Avenue 1470.617115\n", + "1862 Dyer Avenue 1468.714127\n", + "1863 Dyer Avenue 1548.205363\n", + "\n", + "[1864 rows x 2 columns]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Straight line distance between the driveways to the Empire State Building\n", + "gpu_streets = cuspatial.from_geopandas(streets.geometry)\n", + "gpu_esb = cuspatial.from_geopandas(esb.geometry)\n", + "\n", + "dist = cuspatial.pairwise_linestring_polygon_distance(gpu_streets, gpu_esb).rename(\"dist\")\n", + "pd.concat([streets[\"name\"].reset_index(drop=True), dist.to_pandas()], axis=1)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "3e1bb692", + "metadata": {}, + "source": [ + "### cuspatial.pairwise_polygon_distance\n", + "\n", + "Using WGS 84 Pseudo-Mercator, distances are in meters." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "951625da", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/3213563529.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " countries = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\")).to_crs(3857)\n" + ] + } + ], + "source": [ + "countries = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\")).to_crs(3857)\n", + "gpu_countries = cuspatial.from_geopandas(countries)\n", + "\n", + "african_countries = gpu_countries[gpu_countries.continent == \"Africa\"].sort_values(\"pop_est\", ascending=False)\n", + "asian_countries = gpu_countries[gpu_countries.continent == \"Asia\"].sort_values(\"pop_est\", ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "2f0e1118", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    AfricaAsiadist
    0NigeriaChina7.383366e+06
    1EthiopiaIndia2.883313e+06
    2EgyptIndonesia6.776043e+06
    3Dem. Rep. CongoPakistan4.227767e+06
    4South AfricaBangladesh8.189086e+06
    5TanzaniaJapan1.096947e+07
    6KenyaPhilippines8.399282e+06
    7UgandaVietnam7.773975e+06
    8AlgeriaTurkey2.000180e+06
    9SudanIran1.625828e+06
    \n", + "
    " + ], + "text/plain": [ + " Africa Asia dist\n", + "0 Nigeria China 7.383366e+06\n", + "1 Ethiopia India 2.883313e+06\n", + "2 Egypt Indonesia 6.776043e+06\n", + "3 Dem. Rep. Congo Pakistan 4.227767e+06\n", + "4 South Africa Bangladesh 8.189086e+06\n", + "5 Tanzania Japan 1.096947e+07\n", + "6 Kenya Philippines 8.399282e+06\n", + "7 Uganda Vietnam 7.773975e+06\n", + "8 Algeria Turkey 2.000180e+06\n", + "9 Sudan Iran 1.625828e+06" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Straight line distance between the top 10 most populated countries in Asia and Africa\n", + "population_top10_africa = african_countries[:10].reset_index(drop=True)\n", + "population_top10_asia = asian_countries[:10].reset_index(drop=True)\n", + "dist = cuspatial.pairwise_polygon_distance(\n", + " population_top10_africa.geometry, population_top10_asia.geometry)\n", + "\n", + "cudf.concat([\n", + " population_top10_africa[\"name\"].rename(\"Africa\"),\n", + " population_top10_asia[\"name\"].rename(\"Asia\"), \n", + " dist.rename(\"dist\")], axis=1\n", + ")" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "f5f27dc3-46ee-4a62-82de-20f76744382f", "metadata": {}, @@ -1058,14 +1937,14 @@ "\n", "The filtering module contains `points_in_spatial_window`, which returns from a set of points only those points that fall within a spatial window defined by four bounding coordinates: `min_x`, `max_x`, `min_y`, and `max_y`. The following example finds only the points of polygons that fall within 1 standard deviation of the mean of all of the polygons.\n", "\n", - "\n", + "\n", "\n", "### [cuspatial.points_in_spatial_window](https://docs.rapids.ai/api/cuspatial/nightly/api_docs/spatial.html#cuspatial.points_in_spatial_window)" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 23, "id": "d1ade9da-c9e2-45c4-9685-dffeda3fd358", "metadata": { "tags": [] @@ -1082,6 +1961,14 @@ "4 POINT (39.20222 -4.67677)\n", "dtype: geometry\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/3414785716.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] } ], "source": [ @@ -1102,6 +1989,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "5027a3dd-78bb-4d17-af94-506d0ed689c8", "metadata": {}, @@ -1110,6 +1998,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "3b33ce2b-965f-42a1-a89e-66d7ca80d907", "metadata": {}, @@ -1118,6 +2007,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "d73548f3-c9bb-43ff-9788-858f3b7d08e4", "metadata": {}, @@ -1130,12 +2020,21 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 24, "id": "cc72a44d-a9bf-4432-9898-de899ac45869", "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/199363072.py:3: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] + } + ], "source": [ "from cuspatial.core.binops.intersection import pairwise_linestring_intersection\n", "\n", @@ -1148,7 +2047,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 25, "id": "1125fd17-afe1-4b9c-b48d-8842dd3700b3", "metadata": { "tags": [] @@ -1157,15 +2056,15 @@ { "data": { "text/plain": [ - "\n", + "\n", "[\n", " 0,\n", - " 144\n", + " 142\n", "]\n", "dtype: int32" ] }, - "execution_count": 20, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -1178,7 +2077,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 26, "id": "b281e3bb-42d4-4d60-9cb2-b7dcc20b4776", "metadata": { "tags": [] @@ -1193,15 +2092,15 @@ "3 POINT (-129.98000 55.28500)\n", "4 POINT (-130.53611 54.80278)\n", " ... \n", - "139 LINESTRING (-113.00000 49.00000, -113.00000 49...\n", - "140 LINESTRING (-83.89077 46.11693, -83.61613 46.1...\n", - "141 LINESTRING (-116.04818 49.00000, -116.04818 49...\n", - "142 LINESTRING (-120.00000 49.00000, -117.03121 49...\n", - "143 LINESTRING (-122.84000 49.00000, -120.00000 49...\n", - "Length: 144, dtype: geometry" + "137 LINESTRING (-82.69009 41.67511, -82.43928 41.6...\n", + "138 LINESTRING (-117.03121 49.00000, -107.05000 49...\n", + "139 LINESTRING (-83.89077 46.11693, -83.61613 46.1...\n", + "140 LINESTRING (-120.00000 49.00000, -117.03121 49...\n", + "141 LINESTRING (-122.84000 49.00000, -120.00000 49...\n", + "Length: 142, dtype: geometry" ] }, - "execution_count": 21, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -1213,7 +2112,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 27, "id": "e19873b9-2614-4242-ad67-caa47f807d04", "metadata": { "tags": [] @@ -1272,7 +2171,7 @@ "0 [9, 10, 10, 11, 11, 28, 12, 12, 13, 13, 14, 15... " ] }, - "execution_count": 22, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -1284,6 +2183,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "a17bd64a", "metadata": {}, @@ -1305,12 +2205,20 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 28, "id": "bf7b2256", "metadata": { "tags": [] }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/1271339229.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_dataframe = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n" + ] + }, { "data": { "text/plain": [ @@ -1322,7 +2230,7 @@ "dtype: int64" ] }, - "execution_count": 23, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1347,6 +2255,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "fd9c4eef", "metadata": {}, @@ -1357,6 +2266,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "387565b3-75ae-4789-a950-daffc2d4da01", "metadata": {}, @@ -1407,7 +2317,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 29, "id": "e3a0a9a3-0bdd-4f05-bcb5-7db4b99a44a3", "metadata": { "tags": [] @@ -1454,6 +2364,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "0ab7e64d-1199-498c-b020-b3e7393337a5", "metadata": {}, @@ -1471,7 +2382,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 30, "id": "023bd25a-35be-435d-ab0b-ecbd7a47e147", "metadata": { "tags": [] @@ -1514,6 +2425,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "aa1552a1-fe4b-4d30-b76f-054a060593ae", "metadata": {}, @@ -1530,12 +2442,23 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 31, "id": "784aff8e-c9ed-4a81-aa87-bf301b3b90af", "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_261438/2951982051.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_countries = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n", + "/tmp/ipykernel_261438/2951982051.py:2: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_cities' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.\n", + " host_cities = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_cities\"))\n" + ] + } + ], "source": [ "host_countries = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_lowres\"))\n", "host_cities = geopandas.read_file(geopandas.datasets.get_path(\"naturalearth_cities\"))\n", @@ -1545,7 +2468,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 32, "id": "fea24c78-cf5c-45c6-b860-338238e61323", "metadata": { "tags": [] @@ -1606,6 +2529,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "3e4e07f6", "metadata": {}, @@ -1630,7 +2554,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.10.11" }, "vscode": { "interpreter": { From f07ac48568f50905b3722cf74f084d702d0e7ad3 Mon Sep 17 00:00:00 2001 From: Jake Awe <50372925+AyodeAwe@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:05:27 -0500 Subject: [PATCH 33/63] Run docs nightly (#1141) This PR configures `cuspatial` docs builds to also run nightly (not just on PR merges only) Authors: - Jake Awe (https://github.com/AyodeAwe) - AJ Schmidt (https://github.com/ajschmidt8) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1141 --- .github/workflows/build.yaml | 9 ++++++--- ci/build_docs.sh | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 25a77b783..0457613a5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -53,13 +53,16 @@ jobs: date: ${{ inputs.date }} sha: ${{ inputs.sha }} docs-build: - if: github.ref_type == 'branch' && github.event_name == 'push' + if: github.ref_type == 'branch' needs: python-build secrets: inherit uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.06 with: - build_type: branch - node_type: "gpu-v100-latest-1" arch: "amd64" + branch: ${{ inputs.branch }} + build_type: ${{ inputs.build_type || 'branch' }} container_image: "rapidsai/ci:latest" + date: ${{ inputs.date }} + node_type: "gpu-v100-latest-1" run_script: "ci/build_docs.sh" + sha: ${{ inputs.sha }} diff --git a/ci/build_docs.sh b/ci/build_docs.sh index 1972c931a..39a9d7d60 100755 --- a/ci/build_docs.sh +++ b/ci/build_docs.sh @@ -39,7 +39,7 @@ sphinx-build -b text source _text -W popd -if [[ ${RAPIDS_BUILD_TYPE} == "branch" ]]; then +if [[ ${RAPIDS_BUILD_TYPE} != "pull-request" ]]; then rapids-logger "Upload Docs to S3" aws s3 sync --no-progress --delete docs/_html "s3://rapidsai-docs/cuspatial/${VERSION_NUMBER}/html" aws s3 sync --no-progress --delete docs/_text "s3://rapidsai-docs/cuspatial/${VERSION_NUMBER}/txt" From 4b76c4451fbb7fa26ec83f64158d4eca8280fe14 Mon Sep 17 00:00:00 2001 From: Paul Taylor <178183+trxcllnt@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:33:29 -0700 Subject: [PATCH 34/63] cuSpatial pip packages (#1148) Initial draft PR to build statically linked cuspatial wheels. Closes https://github.com/rapidsai/cuspatial/issues/869. Authors: - Paul Taylor (https://github.com/trxcllnt) - Michael Wang (https://github.com/isVoid) Approvers: - H. Thomson Comer (https://github.com/thomcom) - Bradley Dice (https://github.com/bdice) - Ray Douglass (https://github.com/raydouglass) - Mark Harris (https://github.com/harrism) - Vyas Ramasubramani (https://github.com/vyasr) URL: https://github.com/rapidsai/cuspatial/pull/1148 --- .devcontainer/Dockerfile | 10 +- .devcontainer/conda/devcontainer.json | 12 +- .../isolated/.devcontainer/devcontainer.json | 8 +- .../unified/.devcontainer/devcontainer.json | 12 +- .devcontainer/devcontainer.json | 12 +- .../opt/cuspatial/bin/post-attach-command.sh | 9 - .../opt/cuspatial/bin/post-create-command.sh | 3 - .../cuspatial/bin/update-content-command.sh | 7 - .devcontainer/pip/devcontainer.json | 14 +- .../isolated/.devcontainer/devcontainer.json | 13 +- .../unified/.devcontainer/devcontainer.json | 12 +- setup.cfg => .flake8 | 2 +- .github/workflows/build.yaml | 21 + .github/workflows/pr.yaml | 22 + .github/workflows/test.yaml | 12 + .pre-commit-config.yaml | 4 +- README.md | 60 +- ci/release/apply_wheel_modifications.sh | 14 + ci/release/update-version.sh | 10 +- ci/wheel_smoke_test.py | 28 + cpp/CMakeLists.txt | 17 +- cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake | 65 +- dependencies.yaml | 134 +- .../user_guide/cuspatial_api_examples.ipynb | 2 +- python/cuspatial/.flake8.cython | 29 - python/cuspatial/CMakeLists.txt | 57 +- python/cuspatial/README.md | 1 + .../cmake/Modules/WheelHelpers.cmake | 71 + python/cuspatial/cuspatial/__init__.py | 6 +- .../cuspatial/cuspatial/_lib/CMakeLists.txt | 8 +- python/cuspatial/cuspatial/_version.py | 566 ----- .../cuspatial/cuspatial/utils/join_utils.py | 2 +- python/cuspatial/pyproject.toml | 97 +- python/cuspatial/setup.cfg | 57 - python/cuspatial/setup.py | 30 +- python/cuspatial/versioneer.py | 1904 ----------------- 36 files changed, 575 insertions(+), 2756 deletions(-) delete mode 100755 .devcontainer/opt/cuspatial/bin/post-attach-command.sh delete mode 100755 .devcontainer/opt/cuspatial/bin/post-create-command.sh delete mode 100755 .devcontainer/opt/cuspatial/bin/update-content-command.sh rename setup.cfg => .flake8 (95%) create mode 100755 ci/release/apply_wheel_modifications.sh create mode 100644 ci/wheel_smoke_test.py delete mode 100644 python/cuspatial/.flake8.cython create mode 120000 python/cuspatial/README.md create mode 100644 python/cuspatial/cmake/Modules/WheelHelpers.cmake delete mode 100644 python/cuspatial/cuspatial/_version.py delete mode 100644 python/cuspatial/setup.cfg delete mode 100644 python/cuspatial/versioneer.py diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 80052720b..688975418 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,8 +1,8 @@ # syntax=docker/dockerfile:1.5 ARG CUDA=11.8 -ARG LLVM=15 -ARG RAPIDS=23.04 +ARG LLVM=16 +ARG RAPIDS=23.06 ARG DISTRO=ubuntu22.04 ARG REPO=rapidsai/devcontainers @@ -19,12 +19,12 @@ ENV PYTHON_PACKAGE_MANAGER="${PYTHON_PACKAGE_MANAGER}" USER coder -COPY --chown=coder:coder opt/cuspatial /opt/cuspatial - -RUN /bin/bash -c 'mkdir -m 0755 -p ~/.{aws,cache,conda,config,local}' +RUN /bin/bash -c 'mkdir -m 0755 -p ~/.{aws,cache,conda,config/pip,local}' WORKDIR /home/coder/ +ENV PYTHONSAFEPATH="1" +ENV PYTHONUNBUFFERED="1" ENV PYTHONDONTWRITEBYTECODE="1" ENV SCCACHE_REGION="us-east-2" diff --git a/.devcontainer/conda/devcontainer.json b/.devcontainer/conda/devcontainer.json index 01eef184f..902276b71 100644 --- a/.devcontainer/conda/devcontainer.json +++ b/.devcontainer/conda/devcontainer.json @@ -1,5 +1,5 @@ { - "shutdownAction": "none", + "shutdownAction": "stopContainer", "build": { "context": "${localWorkspaceFolder}/.devcontainer", @@ -15,7 +15,7 @@ }, "features": { - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:latest": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:23.6": {} }, "overrideFeatureInstallOrder": [ @@ -23,8 +23,11 @@ ], "initializeCommand": [ - "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}-single-envs}" + "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}/single}" ], + "updateContentCommand": ["rapids-make-vscode-workspace", "--update"], + "postCreateCommand": ["rapids-make-vscode-workspace", "--update"], + "postAttachCommand": ["rapids-make-conda-env"], "containerEnv": { "DEFAULT_CONDA_ENV": "rapids" @@ -37,8 +40,7 @@ "source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.conda/pkgs,target=/home/coder/.conda/pkgs,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}-single-envs,target=/home/coder/.conda/envs,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/.devcontainer/opt/${localWorkspaceFolderBasename},target=/opt/${localWorkspaceFolderBasename},type=bind,consistency=consistent" + "source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}/single,target=/home/coder/.conda/envs,type=bind,consistency=consistent" ], "customizations": { diff --git a/.devcontainer/conda/isolated/.devcontainer/devcontainer.json b/.devcontainer/conda/isolated/.devcontainer/devcontainer.json index a23085da9..aeebb0e7c 100644 --- a/.devcontainer/conda/isolated/.devcontainer/devcontainer.json +++ b/.devcontainer/conda/isolated/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "shutdownAction": "none", + "shutdownAction": "stopContainer", "build": { "context": "${localWorkspaceFolder}/.devcontainer", @@ -15,7 +15,7 @@ }, "features": { - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:latest": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:23.6": {} }, "overrideFeatureInstallOrder": [ @@ -27,8 +27,10 @@ ], "updateContentCommand": [ - "/bin/bash", "-c", "cp -ar /workspaces/${localWorkspaceFolderBasename} /home/coder/${localWorkspaceFolderBasename}" + "/bin/bash", "-c", "cp -ar /workspaces/${localWorkspaceFolderBasename} /home/coder/${localWorkspaceFolderBasename} && rapids-make-vscode-workspace --update" ], + "postCreateCommand": ["rapids-make-vscode-workspace", "--update"], + "postAttachCommand": ["rapids-make-conda-env"], "containerEnv": { "DEFAULT_CONDA_ENV": "rapids" diff --git a/.devcontainer/conda/unified/.devcontainer/devcontainer.json b/.devcontainer/conda/unified/.devcontainer/devcontainer.json index 5a6af88c9..68ca35f5f 100644 --- a/.devcontainer/conda/unified/.devcontainer/devcontainer.json +++ b/.devcontainer/conda/unified/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "shutdownAction": "none", + "shutdownAction": "stopContainer", "build": { "context": "${localWorkspaceFolder}/.devcontainer", @@ -15,7 +15,7 @@ }, "features": { - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:latest": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:23.6": {} }, "overrideFeatureInstallOrder": [ @@ -23,8 +23,11 @@ ], "initializeCommand": [ - "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}-unified-envs}" + "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}/unified}" ], + "updateContentCommand": ["rapids-make-vscode-workspace", "--update"], + "postCreateCommand": ["rapids-make-vscode-workspace", "--update"], + "postAttachCommand": ["rapids-make-conda-env"], "containerEnv": { "DEFAULT_CONDA_ENV": "rapids" @@ -39,8 +42,7 @@ "source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.conda/pkgs,target=/home/coder/.conda/pkgs,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}-unified-envs,target=/home/coder/.conda/envs,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/.devcontainer/opt/${localWorkspaceFolderBasename},target=/opt/${localWorkspaceFolderBasename},type=bind,consistency=consistent" + "source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}/unified,target=/home/coder/.conda/envs,type=bind,consistency=consistent" ], "customizations": { diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 01eef184f..902276b71 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "shutdownAction": "none", + "shutdownAction": "stopContainer", "build": { "context": "${localWorkspaceFolder}/.devcontainer", @@ -15,7 +15,7 @@ }, "features": { - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:latest": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:23.6": {} }, "overrideFeatureInstallOrder": [ @@ -23,8 +23,11 @@ ], "initializeCommand": [ - "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}-single-envs}" + "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}/single}" ], + "updateContentCommand": ["rapids-make-vscode-workspace", "--update"], + "postCreateCommand": ["rapids-make-vscode-workspace", "--update"], + "postAttachCommand": ["rapids-make-conda-env"], "containerEnv": { "DEFAULT_CONDA_ENV": "rapids" @@ -37,8 +40,7 @@ "source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.conda/pkgs,target=/home/coder/.conda/pkgs,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}-single-envs,target=/home/coder/.conda/envs,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/.devcontainer/opt/${localWorkspaceFolderBasename},target=/opt/${localWorkspaceFolderBasename},type=bind,consistency=consistent" + "source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}/single,target=/home/coder/.conda/envs,type=bind,consistency=consistent" ], "customizations": { diff --git a/.devcontainer/opt/cuspatial/bin/post-attach-command.sh b/.devcontainer/opt/cuspatial/bin/post-attach-command.sh deleted file mode 100755 index 637734566..000000000 --- a/.devcontainer/opt/cuspatial/bin/post-attach-command.sh +++ /dev/null @@ -1,9 +0,0 @@ -#! /usr/bin/env bash - -# Source this call in case we're running in Codespaces. -# -# Codespaces runs the "postAttachCommand" in an interactive login shell. -# Once "postAttachCommand" is finished, the terminal is relenquished to -# the user. Sourcing here ensures the new conda env is already activated -# in the shell for the user. -source rapids-make-${PYTHON_PACKAGE_MANAGER}-env; diff --git a/.devcontainer/opt/cuspatial/bin/post-create-command.sh b/.devcontainer/opt/cuspatial/bin/post-create-command.sh deleted file mode 100755 index 0b1796c8e..000000000 --- a/.devcontainer/opt/cuspatial/bin/post-create-command.sh +++ /dev/null @@ -1,3 +0,0 @@ -#! /usr/bin/env bash - -rapids-make-vscode-workspace --update; diff --git a/.devcontainer/opt/cuspatial/bin/update-content-command.sh b/.devcontainer/opt/cuspatial/bin/update-content-command.sh deleted file mode 100755 index e0529489b..000000000 --- a/.devcontainer/opt/cuspatial/bin/update-content-command.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env bash - -mkdir -m 0755 -p ~/.{aws,cache,config/clangd,conda,local}; - -cp /etc/skel/.config/clangd/config.yaml ~/.config/clangd/config.yaml; - -rapids-make-vscode-workspace --update; diff --git a/.devcontainer/pip/devcontainer.json b/.devcontainer/pip/devcontainer.json index a21faaa8d..9c51daab1 100644 --- a/.devcontainer/pip/devcontainer.json +++ b/.devcontainer/pip/devcontainer.json @@ -1,5 +1,5 @@ { - "shutdownAction": "none", + "shutdownAction": "stopContainer", "build": { "context": "${localWorkspaceFolder}/.devcontainer", @@ -16,7 +16,7 @@ "features": { "ghcr.io/devcontainers/features/python:1": {}, - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:latest": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:23.6": {} }, "overrideFeatureInstallOrder": [ @@ -25,10 +25,15 @@ ], "initializeCommand": [ - "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,configlWorkspaceFolderBasename}-single-local}" + "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip,local/${localWorkspaceFolderBasename}/single}" ], + "updateContentCommand": ["rapids-make-vscode-workspace", "--update"], + "postCreateCommand": ["rapids-make-vscode-workspace", "--update"], + "postAttachCommand": ["rapids-make-pip-env"], "containerEnv": { + "PYTHONSAFEPATH": "true", + "PYTHONUNBUFFERED": "true", "DEFAULT_VIRTUAL_ENV": "rapids" }, @@ -38,8 +43,7 @@ "source=${localWorkspaceFolder}/../.aws,target=/home/coder/.aws,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/../.${localWorkspaceFolderBasename}-single-local,target=/home/coder/.local,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/.devcontainer/opt/${localWorkspaceFolderBasename},target=/opt/${localWorkspaceFolderBasename},type=bind,consistency=consistent" + "source=${localWorkspaceFolder}/../.local/${localWorkspaceFolderBasename}/single,target=/home/coder/.local,type=bind,consistency=consistent" ], "customizations": { diff --git a/.devcontainer/pip/isolated/.devcontainer/devcontainer.json b/.devcontainer/pip/isolated/.devcontainer/devcontainer.json index a6a2f5bad..c398cab0e 100644 --- a/.devcontainer/pip/isolated/.devcontainer/devcontainer.json +++ b/.devcontainer/pip/isolated/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "shutdownAction": "none", + "shutdownAction": "stopContainer", "build": { "context": "${localWorkspaceFolder}/.devcontainer", @@ -16,7 +16,7 @@ "features": { "ghcr.io/devcontainers/features/python:1": {}, - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:latest": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:23.6": {} }, "overrideFeatureInstallOrder": [ @@ -25,12 +25,14 @@ ], "initializeCommand": [ - "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,local}" + "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip}" ], "updateContentCommand": [ - "/bin/bash", "-c", "cp -ar /workspaces/${localWorkspaceFolderBasename} /home/coder/${localWorkspaceFolderBasename}" + "/bin/bash", "-c", "cp -ar /workspaces/${localWorkspaceFolderBasename} /home/coder/${localWorkspaceFolderBasename} && rapids-make-vscode-workspace --update" ], + "postCreateCommand": ["rapids-make-vscode-workspace", "--update"], + "postAttachCommand": ["rapids-make-pip-env"], "containerEnv": { "DEFAULT_VIRTUAL_ENV": "rapids" @@ -41,8 +43,7 @@ "mounts": [ "source=${localWorkspaceFolder}/../.aws,target=/home/coder/.aws,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/../.local,target=/home/coder/.local,type=bind,consistency=consistent" + "source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent" ], "customizations": { diff --git a/.devcontainer/pip/unified/.devcontainer/devcontainer.json b/.devcontainer/pip/unified/.devcontainer/devcontainer.json index 39ecc7102..6a7acb47d 100644 --- a/.devcontainer/pip/unified/.devcontainer/devcontainer.json +++ b/.devcontainer/pip/unified/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "shutdownAction": "none", + "shutdownAction": "stopContainer", "build": { "context": "${localWorkspaceFolder}/.devcontainer", @@ -16,7 +16,7 @@ "features": { "ghcr.io/devcontainers/features/python:1": {}, - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:latest": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:23.6": {} }, "overrideFeatureInstallOrder": [ @@ -25,8 +25,11 @@ ], "initializeCommand": [ - "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,${localWorkspaceFolderBasename}-unified-local}" + "/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip,local/${localWorkspaceFolderBasename}/unified}" ], + "updateContentCommand": ["rapids-make-vscode-workspace", "--update"], + "postCreateCommand": ["rapids-make-vscode-workspace", "--update"], + "postAttachCommand": ["rapids-make-pip-env"], "containerEnv": { "DEFAULT_VIRTUAL_ENV": "rapids" @@ -40,8 +43,7 @@ "source=${localWorkspaceFolder}/../.aws,target=/home/coder/.aws,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent", "source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/../.${localWorkspaceFolderBasename}-unified-local,target=/home/coder/.local,type=bind,consistency=consistent", - "source=${localWorkspaceFolder}/.devcontainer/opt/${localWorkspaceFolderBasename},target=/opt/${localWorkspaceFolderBasename},type=bind,consistency=consistent" + "source=${localWorkspaceFolder}/../.local/${localWorkspaceFolderBasename}/unified,target=/home/coder/.local,type=bind,consistency=consistent" ], "customizations": { diff --git a/setup.cfg b/.flake8 similarity index 95% rename from setup.cfg rename to .flake8 index 028c88b18..13d38d1cc 100644 --- a/setup.cfg +++ b/.flake8 @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, NVIDIA CORPORATION. +# Copyright (c) 2019-2023, NVIDIA CORPORATION. [flake8] filename = *.py, *.pyx, *.pxd, *.pxi diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0457613a5..0f3f10e22 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -66,3 +66,24 @@ jobs: node_type: "gpu-v100-latest-1" run_script: "ci/build_docs.sh" sha: ${{ inputs.sha }} + wheel-build: + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.06 + with: + build_type: ${{ inputs.build_type || 'branch' }} + branch: ${{ inputs.branch }} + sha: ${{ inputs.sha }} + date: ${{ inputs.date }} + package-name: cuspatial + package-dir: python/cuspatial + skbuild-configure-options: "-DCUSPATIAL_BUILD_WHEELS=ON" + wheel-publish: + needs: wheel-build + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.06 + with: + build_type: ${{ inputs.build_type || 'branch' }} + branch: ${{ inputs.branch }} + sha: ${{ inputs.sha }} + date: ${{ inputs.date }} + package-name: cuspatial diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 7e14bc978..69b057271 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -19,6 +19,8 @@ jobs: - conda-python-tests - conda-notebook-tests - docs-build + - wheel-build + - wheel-tests secrets: inherit uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.06 checks: @@ -70,3 +72,23 @@ jobs: arch: "amd64" container_image: "rapidsai/ci:latest" run_script: "ci/build_docs.sh" + wheel-build: + needs: checks + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.06 + with: + build_type: pull-request + package-dir: python/cuspatial + package-name: cuspatial + skbuild-configure-options: "-DCUSPATIAL_BUILD_WHEELS=ON" + wheel-tests: + needs: wheel-build + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.06 + with: + build_type: pull-request + package-name: cuspatial + test-smoketest: "python ./ci/wheel_smoke_test.py" + test-unittest: "python -m pytest -n 8 ./python/cuspatial/cuspatial/tests" + test-before-amd64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" + test-before-arm64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index eb3cb4d94..09a472e2c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -30,3 +30,15 @@ jobs: branch: ${{ inputs.branch }} date: ${{ inputs.date }} sha: ${{ inputs.sha }} + wheel-tests: + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.06 + with: + build_type: nightly + branch: ${{ inputs.branch }} + date: ${{ inputs.date }} + sha: ${{ inputs.sha }} + package-name: cuspatial + test-unittest: "python -m pytest -n 8 ./python/cuspatial/cuspatial/tests" + test-before-amd64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" + test-before-arm64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 01566030b..5d2fb2b29 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022, NVIDIA CORPORATION. +# Copyright (c) 2019-2023, NVIDIA CORPORATION. repos: - repo: https://github.com/PyCQA/isort @@ -21,7 +21,7 @@ repos: rev: 5.0.4 hooks: - id: flake8 - args: ["--config=setup.cfg"] + args: ["--config=.flake8"] files: python/.*$ types: [file] types_or: [python, cython] diff --git a/README.md b/README.md index 9639a7c05..1c1a8f6f9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ #
     cuSpatial - GPU-Accelerated Vector Geospatial Data Analysis
    -> **Note** -> +> **Note** +> > cuSpatial depends on [cuDF](https://github.com/rapidsai/cudf) and [RMM](https://github.com/rapidsai/rmm) from [RAPIDS](https://rapids.ai/). ## Resources @@ -14,7 +14,7 @@ - [cuSpatial Roadmap](https://github.com/orgs/rapidsai/projects/41/views/5): Report issues or request features. ## Overview -cuSpatial accelerates vector geospatial operations through GPU parallelization. As part of the RAPIDS libraries, cuSpatial is inherently connected to [cuDF](https://github.com/rapidsai/cudf), [cuML](https://github.com/rapidsai/cuml), and [cuGraph](https://github.com/rapidsai/cugraph), enabling GPU acceleration across entire workflows. +cuSpatial accelerates vector geospatial operations through GPU parallelization. As part of the RAPIDS libraries, cuSpatial is inherently connected to [cuDF](https://github.com/rapidsai/cudf), [cuML](https://github.com/rapidsai/cuml), and [cuGraph](https://github.com/rapidsai/cugraph), enabling GPU acceleration across entire workflows. cuSpatial represents data in [GeoArrow](https://github.com/geoarrow/geoarrow) format, which enables compatibility with the [Apache Arrow](https://arrow.apache.org) ecosystem. @@ -118,10 +118,10 @@ docker run --gpus all --rm -it \ nvcr.io/nvidia/rapidsai/rapidsai-core:23.02-cuda11.8-runtime-ubuntu22.04-py3.10 ``` -### Install from Conda +### Install with Conda To install via conda: -> **Note** cuSpatial is supported only on Linux or [through WSL](https://rapids.ai/wsl2.html), and with Python versions 3.9 and later +> **Note** cuSpatial is supported only on Linux or [through WSL](https://rapids.ai/wsl2.html), and with Python versions 3.9 and 3.10 cuSpatial can be installed with conda (miniconda, or the full Anaconda distribution) from the rapidsai channel: @@ -133,7 +133,55 @@ We also provide nightly Conda packages built from the HEAD of our latest develop See the [RAPIDS release selector](https://rapids.ai/start.html#get-rapids) for more OS and version info. -### Install from Source +### Install with pip + +To install via pip: +> **Note** cuSpatial is supported only on Linux or [through WSL](https://rapids.ai/wsl2.html), and with Python versions 3.9 and 3.10 + +The cuSpatial pip packages can be installed from NVIDIA's PyPI index: + +```shell +# If using driver 525+, with support for CUDA Toolkit 12.0+ +pip install --extra-index-url=https://pypi.nvidia.com cuspatial-cu12 + +# If using driver 450.80+, with support for CUDA Toolkit 11.2+ +pip install --extra-index-url=https://pypi.nvidia.com cuspatial-cu11 + +# Or do this if you're unsure which CUDA Toolkit is supported by your driver: +CUDA_MAJOR_VERSION="$(nvidia-smi | head -n3 | tail -n1 | tr -d '[:space:]' | cut -d':' -f3 | cut -d '.' -f1)" +pip install --extra-index-url=https://pypi.nvidia.com cuspatial-cu${CUDA_MAJOR_VERSION} +``` + +#### Troubleshooting Fiona/GDAL versions + +cuSpatial depends on [`geopandas`](https://github.com/geopandas/geopandas), which uses [`fiona >= 1.8.19`](https://pypi.org/project/Fiona/), to read common GIS formats with GDAL. + +Fiona requires GDAL is already present on your system, but its minimum required version may be newer than the version of GDAL in your OS's package manager. + +Fiona checks the GDAL version at install time and fails with an error like this if a compatible version of GDAL isn't installed: +``` +ERROR: GDAL >= 3.2 is required for fiona. Please upgrade GDAL. +``` + +There are two ways to fix this: + +1. Install a version of GDAL that meets fiona's minimum required version + * Ubuntu users can install a newer GDAL with the [UbuntuGIS PPA](https://wiki.ubuntu.com/UbuntuGIS): + ```shell + sudo -y add-apt-repository ppa:ubuntugis/ppa + sudo apt install libgdal-dev + ``` +2. Pin fiona's version to a range that's compatible with your version of `libgdal-dev` + * For Ubuntu20.04 ([GDAL v3.0.4](https://packages.ubuntu.com/focal/libgdal-dev)): + ```shell + pip install --no-binary fiona --extra-index-url=https://pypi.nvidia.com cuspatial-cu12 'fiona>=1.8.19,<1.9' + ``` + * For Ubuntu22.04 ([GDAL v3.4.1](https://packages.ubuntu.com/jammy/libgdal-dev)): + ```shell + pip install --no-binary fiona --extra-index-url=https://pypi.nvidia.com cuspatial-cu12 'fiona>=1.9' + ``` + +### Build/Install from source To build and install cuSpatial from source please see the [build documentation](https://docs.rapids.ai/api/cuspatial/stable/developer_guide/build.html). diff --git a/ci/release/apply_wheel_modifications.sh b/ci/release/apply_wheel_modifications.sh new file mode 100755 index 000000000..7e1d94ddc --- /dev/null +++ b/ci/release/apply_wheel_modifications.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# Usage: bash apply_wheel_modifications.sh + +VERSION=${1} +CUDA_SUFFIX=${2} + +sed -i "s/^version = .*/version = \"${VERSION}\"/g" python/cuspatial/pyproject.toml + +sed -i "s/^name = \"cuspatial\"/name = \"cuspatial${CUDA_SUFFIX}\"/g" python/cuspatial/pyproject.toml + +sed -i "s/rmm==/rmm${CUDA_SUFFIX}==/g" python/cuspatial/pyproject.toml +sed -i "s/cudf==/cudf${CUDA_SUFFIX}==/g" python/cuspatial/pyproject.toml diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index cae29e22e..3c5b99c73 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -37,6 +37,9 @@ sed_runner 's/'"cuspatial_version .*)"'/'"cuspatial_version ${NEXT_FULL_TAG})"'/ sed_runner 's/version = .*/version = '"'${NEXT_SHORT_TAG}'"'/g' docs/source/conf.py sed_runner 's/release = .*/release = '"'${NEXT_FULL_TAG}'"'/g' docs/source/conf.py +# Python __init__.py updates +sed_runner "s/__version__ = .*/__version__ = \"${NEXT_FULL_TAG}\"/g" python/cuspatial/cuspatial/__init__.py + # rapids-cmake version sed_runner 's/'"branch-.*\/RAPIDS.cmake"'/'"branch-${NEXT_SHORT_TAG}\/RAPIDS.cmake"'/g' fetch_rapids.cmake sed_runner 's/'"branch-.*\/RAPIDS.cmake"'/'"branch-${NEXT_SHORT_TAG}\/RAPIDS.cmake"'/g' python/cuspatial/CMakeLists.txt @@ -67,10 +70,9 @@ done # Dependency versions in dependencies.yaml sed_runner "/-cu[0-9]\{2\}==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}.*/g" dependencies.yaml -# Dependency versions in setup.py -sed_runner "s/rmm==.*\",/rmm==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/setup.py -sed_runner "s/cudf==.*\",/cudf==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/setup.py +# Python pyproject.toml updates +sed_runner "s/^version = .*/version = \"${NEXT_FULL_TAG}\"/g" python/cuspatial/pyproject.toml # Dependency versions in pyproject.toml -sed_runner "s/rmm==.*\",/rmm==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.toml sed_runner "s/cudf==.*\",/cudf==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.toml +sed_runner "s/rmm==.*\",/rmm==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.py diff --git a/ci/wheel_smoke_test.py b/ci/wheel_smoke_test.py new file mode 100644 index 000000000..df2af9abd --- /dev/null +++ b/ci/wheel_smoke_test.py @@ -0,0 +1,28 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +import numpy as np +import cudf +import cuspatial +import pyarrow as pa +from shapely.geometry import Point + +if __name__ == '__main__': + order, quadtree = cuspatial.quadtree_on_points( + cuspatial.GeoSeries([Point(0.5, 0.5), Point(1.5, 1.5)]), + *(0, 2, 0, 2), # bbox + 1, # scale + 1, # max_depth + 1, # min_size + ) + cudf.testing.assert_frame_equal( + quadtree, + cudf.DataFrame( + { + "key": cudf.Series(pa.array([0, 3], type=pa.uint32())), + "level": cudf.Series(pa.array([0, 0], type=pa.uint8())), + "is_internal_node": cudf.Series(pa.array([False, False], type=pa.bool_())), + "length": cudf.Series(pa.array([1, 1], type=pa.uint32())), + "offset": cudf.Series(pa.array([0, 1], type=pa.uint32())), + } + ), + ) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 983123252..cb93425f0 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -51,6 +51,9 @@ option(CUDA_ENABLE_LINEINFO "Enable the -lineinfo option for nvcc (useful for cu # cudart can be statically linked or dynamically linked. The python ecosystem wants dynamic linking option(CUDA_STATIC_RUNTIME "Statically link the CUDA toolkit runtime and libraries" OFF) +option(CUSPATIAL_USE_CUDF_STATIC "Build and statically link cuDF" OFF) +option(CUSPATIAL_EXCLUDE_CUDF_FROM_ALL "Exclude cuDF targets from cuSpatial's 'all' target" OFF) + message(STATUS "CUSPATIAL: Build with NVTX support: ${USE_NVTX}") message(STATUS "CUSPATIAL: Configure CMake to build tests: ${BUILD_TESTS}") message(STATUS "CUSPATIAL: Configure CMake to build (google) benchmarks: ${BUILD_BENCHMARKS}") @@ -174,14 +177,16 @@ target_include_directories(cuspatial PRIVATE "$" INTERFACE "$") -# Add Conda library paths if specified -if(CONDA_LINK_DIRS) - target_link_directories(cuspatial PUBLIC "$") +# Add Conda library, and include paths if specified +if(TARGET conda_env) + target_link_libraries(cuspatial PRIVATE conda_env) endif() -# Add Conda include paths if specified -if(CONDA_INCLUDE_DIRS) - target_include_directories(cuspatial PUBLIC "$") +# Workaround until https://github.com/rapidsai/rapids-cmake/issues/176 is resolved +if(NOT BUILD_SHARED_LIBS) + if(TARGET conda_env) + install(TARGETS conda_env EXPORT cuspatial-exports) + endif() endif() # Per-thread default stream diff --git a/cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake b/cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake index 6ab168bbc..49db92353 100644 --- a/cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake +++ b/cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (c) 2021, NVIDIA CORPORATION. +# Copyright (c) 2021-2023, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,39 +14,64 @@ # limitations under the License. #============================================================================= -function(find_and_configure_cudf VERSION) +function(find_and_configure_cudf) if(TARGET cudf::cudf) - return() + return() endif() - if(${VERSION} MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=]) - set(MAJOR_AND_MINOR "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}") - else() - set(MAJOR_AND_MINOR "${VERSION}") - endif() + set(oneValueArgs VERSION GIT_REPO GIT_TAG USE_CUDF_STATIC EXCLUDE_FROM_ALL PER_THREAD_DEFAULT_STREAM) + cmake_parse_arguments(PKG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(global_targets cudf::cudf) - set(find_package_args "") + set(cudf_components "") + if(BUILD_TESTS) list(APPEND global_targets cudf::cudftestutil) - set(find_package_args "COMPONENTS testing") + set(cudf_components COMPONENTS testing) + endif() + + set(BUILD_SHARED ON) + if(${PKG_USE_CUDF_STATIC}) + set(BUILD_SHARED OFF) endif() - rapids_cpm_find( - cudf ${VERSION} - GLOBAL_TARGETS "${global_targets}" + rapids_cpm_find(cudf ${PKG_VERSION} ${cudf_components} + GLOBAL_TARGETS ${global_targets} BUILD_EXPORT_SET cuspatial-exports INSTALL_EXPORT_SET cuspatial-exports CPM_ARGS - GIT_REPOSITORY https://github.com/rapidsai/cudf.git - GIT_TAG branch-${MAJOR_AND_MINOR} - GIT_SHALLOW TRUE - OPTIONS "BUILD_TESTS OFF" "BUILD_BENCHMARKS OFF" - FIND_PACKAGE_ARGUMENTS "${find_package_args}" + GIT_REPOSITORY ${PKG_GIT_REPO} + GIT_TAG ${PKG_GIT_TAG} + GIT_SHALLOW TRUE + SOURCE_SUBDIR cpp + EXCLUDE_FROM_ALL ${PKG_EXCLUDE_FROM_ALL} + OPTIONS "BUILD_TESTS OFF" + "BUILD_BENCHMARKS OFF" + "BUILD_SHARED_LIBS ${BUILD_SHARED}" + "CUDF_BUILD_TESTUTIL ${BUILD_TESTS}" + "CUDF_BUILD_STREAMS_TEST_UTIL ${BUILD_TESTS}" + "CUDF_USE_PER_THREAD_DEFAULT_STREAM ${PKG_PER_THREAD_DEFAULT_STREAM}" ) + + if(TARGET cudf) + set_property(TARGET cudf PROPERTY SYSTEM TRUE) + endif() endfunction() -set(CUSPATIAL_MIN_VERSION_cudf "${CUSPATIAL_VERSION_MAJOR}.${CUSPATIAL_VERSION_MINOR}.00") +set(CUSPATIAL_MIN_VERSION_cudf "${CUSPATIAL_VERSION_MAJOR}.${CUSPATIAL_VERSION_MINOR}") + +if(NOT DEFINED CUSPATIAL_CUDF_GIT_REPO) + set(CUSPATIAL_CUDF_GIT_REPO https://github.com/rapidsai/cudf.git) +endif() + +if(NOT DEFINED CUSPATIAL_CUDF_GIT_TAG) + set(CUSPATIAL_CUDF_GIT_TAG branch-${CUSPATIAL_MIN_VERSION_cudf}) +endif() -find_and_configure_cudf(${CUSPATIAL_MIN_VERSION_cudf}) +find_and_configure_cudf(VERSION ${CUSPATIAL_MIN_VERSION_cudf}.00 + GIT_REPO ${CUSPATIAL_CUDF_GIT_REPO} + GIT_TAG ${CUSPATIAL_CUDF_GIT_TAG} + USE_CUDF_STATIC ${CUSPATIAL_USE_CUDF_STATIC} + EXCLUDE_FROM_ALL ${CUSPATIAL_EXCLUDE_CUDF_FROM_ALL} + PER_THREAD_DEFAULT_STREAM ${PER_THREAD_DEFAULT_STREAM}) diff --git a/dependencies.yaml b/dependencies.yaml index ce7ed798a..d63e97c38 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -41,6 +41,30 @@ files: - cudatoolkit - docs - py_version + py_build: + output: [pyproject] + pyproject_dir: python/cuspatial + extras: + table: build-system + includes: + - build_cpp + - build_python + - build_wheels + py_run: + output: [pyproject] + pyproject_dir: python/cuspatial + extras: + table: project + includes: + - run_python + py_test: + output: [pyproject] + pyproject_dir: python/cuspatial + extras: + table: project.optional-dependencies + key: test + includes: + - test_python channels: - rapidsai - rapidsai-nightly @@ -49,16 +73,18 @@ channels: dependencies: build_cpp: common: + - output_types: [conda, requirements, pyproject] + packages: + - ninja + - cmake>=3.23.1,!=3.25.0 - output_types: conda packages: - - &cmake_ver cmake>=3.23.1,!=3.25.0 - c-compiler - cxx-compiler - gmock>=1.13.0 - gtest>=1.13.0 - libcudf==23.6.* - librmm==23.6.* - - ninja specific: - output_types: conda matrices: @@ -86,15 +112,20 @@ dependencies: - nvcc_linux-aarch64=11.8 build_python: common: - - output_types: [conda, requirements] + - output_types: [conda, requirements, pyproject] packages: - - *cmake_ver - cython>=0.29,<0.30 - scikit-build>=0.13.1 - setuptools - output_types: conda - packages: + packages: &build_python_packages_conda - &cudf_conda cudf==23.6.* + - &rmm_conda rmm==23.6.* + - output_types: requirements + packages: + # pip recognizes the index as a global option for the requirements.txt file + # This index is needed for cudf and rmm. + - --extra-index-url=https://pypi.nvidia.com specific: - output_types: conda matrices: @@ -108,28 +139,22 @@ dependencies: packages: - *gcc_aarch64 - *sysroot_aarch64 - - output_types: requirements + - output_types: [requirements, pyproject] matrices: - - matrix: - cuda: "11.8" - packages: - - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* - - matrix: - cuda: "11.5" - packages: - - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* - - matrix: - cuda: "11.4" - packages: - - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* - - matrix: - cuda: "11.2" - packages: - - "--extra-index-url=https://pypi.nvidia.com" - - cudf-cu11==23.6.* + - matrix: {cuda: "11.8"} + packages: &build_python_packages_cu11 + - &cudf_cu11 cudf-cu11==23.6.* + - &rmm_cu11 rmm-cu11==23.6.* + - {matrix: {cuda: "11.5"}, packages: *build_python_packages_cu11} + - {matrix: {cuda: "11.4"}, packages: *build_python_packages_cu11} + - {matrix: {cuda: "11.2"}, packages: *build_python_packages_cu11} + - {matrix: null, packages: [*cudf_conda, *rmm_conda] } + build_wheels: + common: + - output_types: [requirements, pyproject] + packages: + - wheel + - setuptools cudatoolkit: specific: - output_types: conda @@ -160,6 +185,8 @@ dependencies: - output_types: [conda] packages: - doxygen + - output_types: [conda, requirements] + packages: - ipython - myst-parser - nbsphinx @@ -168,9 +195,8 @@ dependencies: - sphinx<6 notebooks: common: - - output_types: [conda, requirements] + - output_types: [conda, requirements, pyproject] packages: - - cuml==23.6.* - ipython - ipywidgets - notebook @@ -178,6 +204,19 @@ dependencies: - pydeck - shapely - scikit-image + - output_types: conda + packages: + - &cuml_conda cuml==23.6.* + specific: + - output_types: [requirements, pyproject] + matrices: + - {matrix: null, packages: [*cuml_conda]} + - matrix: {cuda: "11.8"} + packages: ¬ebooks_packages_cu11 + - &cuml_cu11 cuml-cu11==23.6.* + - {matrix: {cuda: "11.5"}, packages: *notebooks_packages_cu11} + - {matrix: {cuda: "11.4"}, packages: *notebooks_packages_cu11} + - {matrix: {cuda: "11.2"}, packages: *notebooks_packages_cu11} py_version: specific: - output_types: conda @@ -195,39 +234,32 @@ dependencies: - python>=3.9,<3.11 run_python: common: - - output_types: [conda, requirements] + - output_types: [conda, requirements, pyproject] packages: - geopandas>=0.11.0 - output_types: conda packages: - *cudf_conda - - rmm==23.6.* - specific: + - *rmm_conda - output_types: requirements + packages: + # pip recognizes the index as a global option for the requirements.txt file + # This index is needed for cudf and rmm. + - --extra-index-url=https://pypi.nvidia.com + specific: + - output_types: [requirements, pyproject] matrices: - - matrix: - cuda: "11.8" - packages: - - "--extra-index-url=https://pypi.nvidia.com" - - rmm-cu11==23.6.* - - matrix: - cuda: "11.5" - packages: - - "--extra-index-url=https://pypi.nvidia.com" - - rmm-cu11==23.6.* - - matrix: - cuda: "11.4" - packages: - - "--extra-index-url=https://pypi.nvidia.com" - - rmm-cu11==23.6.* - - matrix: - cuda: "11.2" - packages: - - "--extra-index-url=https://pypi.nvidia.com" + - matrix: {cuda: "11.8"} + packages: &run_python_packages_cu11 + - cudf-cu11==23.6.* - rmm-cu11==23.6.* + - {matrix: {cuda: "11.5"}, packages: *run_python_packages_cu11} + - {matrix: {cuda: "11.4"}, packages: *run_python_packages_cu11} + - {matrix: {cuda: "11.2"}, packages: *run_python_packages_cu11} + - {matrix: null, packages: [*cudf_conda, *rmm_conda]} test_python: common: - - output_types: [conda, requirements] + - output_types: [conda, requirements, pyproject] packages: - pytest - pytest-cov diff --git a/docs/source/user_guide/cuspatial_api_examples.ipynb b/docs/source/user_guide/cuspatial_api_examples.ipynb index bc40c82b0..28c81abb8 100644 --- a/docs/source/user_guide/cuspatial_api_examples.ipynb +++ b/docs/source/user_guide/cuspatial_api_examples.ipynb @@ -25,7 +25,7 @@ "This guide provides a working example for all of the python API components of cuSpatial. \n", "The following list links to each subsection.\n", "\n", - "* [Installing cuSpatial](#Installing-cuspatial)\n", + "* [Installing cuSpatial](#Installing-cuSpatial)\n", "* [GPU accelerated memory layout](#GPU-accelerated-memory-layout)\n", "* [Input / Output](#Input-/-Output)\n", "* [Geopandas and cuDF integration](#Geopandas-and-cuDF-integration)\n", diff --git a/python/cuspatial/.flake8.cython b/python/cuspatial/.flake8.cython deleted file mode 100644 index 4c5cf4965..000000000 --- a/python/cuspatial/.flake8.cython +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (c) 2018-2019, NVIDIA CORPORATION. -# -# 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. -# - -[flake8] -filename = *.pyx, *.pxd -exclude = *.egg, build, docs, .git -ignore = E999, E225, E226, E227, W503, W504, E211 - -# Rules ignored: -# E999: invalid syntax (works for Python, not Cython) -# E211: whitespace before '(' (used in multi-line imports) -# E225: Missing whitespace around operators (breaks cython casting syntax like ) -# E226: Missing whitespace around arithmetic operators (breaks cython pointer syntax like int*) -# E227: Missing whitespace around bitwise or shift operator (Can also break casting syntax) -# W503: line break before binary operator (breaks lines that start with a pointer) -# W504: line break after binary operator (breaks lines that end with a pointer) diff --git a/python/cuspatial/CMakeLists.txt b/python/cuspatial/CMakeLists.txt index 9f06c3ad9..bba6f318d 100644 --- a/python/cuspatial/CMakeLists.txt +++ b/python/cuspatial/CMakeLists.txt @@ -1,5 +1,5 @@ # ============================================================================= -# Copyright (c) 2022, NVIDIA CORPORATION. +# Copyright (c) 2022-2023, NVIDIA CORPORATION. # # 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 @@ -32,6 +32,8 @@ project( option(FIND_CUSPATIAL_CPP "Search for existing cuspatial C++ installations before defaulting to local files" OFF) +option(CUSPATIAL_BUILD_WHEELS "Whether this build is generating a Python wheel." OFF) + # If the user requested it we attempt to find cuspatial. if(FIND_CUSPATIAL_CPP) find_package(cuspatial ${cuspatial_version}) @@ -40,22 +42,49 @@ else() endif() if(NOT cuspatial_FOUND) - # TODO: This will not be necessary once we upgrade to CMake 3.22, which will - # pull in the required languages for the C++ project even if this project - # does not require those languages. - include(rapids-cuda) - rapids_cuda_init_architectures(cuspatial) - enable_language(CUDA) - # Since cuspatial only enables CUDA optionally we need to manually include the file that - # rapids_cuda_init_architectures relies on `project` including. - include("${CMAKE_PROJECT_cuspatial_INCLUDE}") - - add_subdirectory(../../cpp cuspatial-cpp) - - install(TARGETS cuspatial DESTINATION cuspatial/_lib) + set(BUILD_TESTS OFF) + set(BUILD_BENCHMARKS OFF) + set(_exclude_from_all "") + if(CUSPATIAL_BUILD_WHEELS) + + # Statically link cudart if building wheels + set(CUDA_STATIC_RUNTIME ON) + set(CUSPATIAL_USE_CUDF_STATIC ON) + set(CUSPATIAL_EXCLUDE_CUDF_FROM_ALL ON) + + # Always build wheels against the pyarrow libarrow. + set(USE_LIBARROW_FROM_PYARROW ON) + + # Need to set this so all the nvcomp targets are global, not only nvcomp::nvcomp + # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_PACKAGE_TARGETS_GLOBAL.html#variable:CMAKE_FIND_PACKAGE_TARGETS_GLOBAL + set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON) + + # Don't install the cuSpatial C++ targets into wheels + set(_exclude_from_all EXCLUDE_FROM_ALL) + endif() + + add_subdirectory(../../cpp cuspatial-cpp ${_exclude_from_all}) + + set(cython_lib_dir cuspatial) + + if(CUSPATIAL_BUILD_WHEELS) + include(cmake/Modules/WheelHelpers.cmake) + get_target_property(_nvcomp_link_libs nvcomp::nvcomp INTERFACE_LINK_LIBRARIES) + # Ensure all the shared objects we need at runtime are in the wheel + add_target_libs_to_wheel(LIB_DIR ${cython_lib_dir} TARGETS arrow_shared nvcomp::nvcomp ${_nvcomp_link_libs}) + endif() + + # Since there are multiple subpackages of cuspatial._lib that require access to libcuspatial, we place the + # library in the cuspatial directory as a single source of truth and modify the other rpaths + # appropriately. + install(TARGETS cuspatial DESTINATION ${cython_lib_dir}) endif() include(rapids-cython) rapids_cython_init() add_subdirectory(cuspatial/_lib) + +if(DEFINED cython_lib_dir) + rapids_cython_add_rpath_entries(TARGET cuspatial PATHS "${cython_lib_dir}") +endif() diff --git a/python/cuspatial/README.md b/python/cuspatial/README.md new file mode 120000 index 000000000..fe8400541 --- /dev/null +++ b/python/cuspatial/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/python/cuspatial/cmake/Modules/WheelHelpers.cmake b/python/cuspatial/cmake/Modules/WheelHelpers.cmake new file mode 100644 index 000000000..41d720c52 --- /dev/null +++ b/python/cuspatial/cmake/Modules/WheelHelpers.cmake @@ -0,0 +1,71 @@ +# ============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +# ============================================================================= +include_guard(GLOBAL) + +# Making libraries available inside wheels by installing the associated targets. +function(add_target_libs_to_wheel) + list(APPEND CMAKE_MESSAGE_CONTEXT "add_target_libs_to_wheel") + + set(options "") + set(one_value "LIB_DIR") + set(multi_value "TARGETS") + cmake_parse_arguments(_ "${options}" "${one_value}" "${multi_value}" ${ARGN}) + + message(VERBOSE "Installing targets '${__TARGETS}' into lib_dir '${__LIB_DIR}'") + + foreach(target IN LISTS __TARGETS) + + if(NOT TARGET ${target}) + message(VERBOSE "No target named ${target}") + continue() + endif() + + get_target_property(alias_target ${target} ALIASED_TARGET) + if(alias_target) + set(target ${alias_target}) + endif() + + get_target_property(is_imported ${target} IMPORTED) + if(NOT is_imported) + # If the target isn't imported, install it into the the wheel + install(TARGETS ${target} DESTINATION ${__LIB_DIR}) + message(VERBOSE "install(TARGETS ${target} DESTINATION ${__LIB_DIR})") + else() + # If the target is imported, make sure it's global + get_target_property(already_global ${target} IMPORTED_GLOBAL) + if(NOT already_global) + set_target_properties(${target} PROPERTIES IMPORTED_GLOBAL TRUE) + endif() + + # Find the imported target's library so we can copy it into the wheel + set(lib_loc) + foreach(prop IN ITEMS IMPORTED_LOCATION IMPORTED_LOCATION_RELEASE IMPORTED_LOCATION_DEBUG) + get_target_property(lib_loc ${target} ${prop}) + if(lib_loc) + message(VERBOSE "Found ${prop} for ${target}: ${lib_loc}") + break() + endif() + message(VERBOSE "${target} has no value for property ${prop}") + endforeach() + + if(NOT lib_loc) + message(FATAL_ERROR "Found no libs to install for target ${target}") + endif() + + # Copy the imported library into the wheel + install(FILES ${lib_loc} DESTINATION ${__LIB_DIR}) + message(VERBOSE "install(FILES ${lib_loc} DESTINATION ${__LIB_DIR})") + endif() + endforeach() +endfunction() diff --git a/python/cuspatial/cuspatial/__init__.py b/python/cuspatial/cuspatial/__init__.py index c72dc00bb..92da6ee06 100644 --- a/python/cuspatial/cuspatial/__init__.py +++ b/python/cuspatial/cuspatial/__init__.py @@ -1,4 +1,5 @@ -from ._version import get_versions +# Copyright (c) 2023, NVIDIA CORPORATION. + from .core.geodataframe import GeoDataFrame from .core.geoseries import GeoSeries from .core.spatial import ( @@ -28,5 +29,4 @@ ) from .io.geopandas import from_geopandas -__version__ = get_versions()["version"] -del get_versions +__version__ = "23.06.00" diff --git a/python/cuspatial/cuspatial/_lib/CMakeLists.txt b/python/cuspatial/cuspatial/_lib/CMakeLists.txt index e124dfb86..d3730c940 100644 --- a/python/cuspatial/cuspatial/_lib/CMakeLists.txt +++ b/python/cuspatial/cuspatial/_lib/CMakeLists.txt @@ -31,5 +31,9 @@ set(cython_sources ) set(linked_libraries cuspatial::cuspatial) -rapids_cython_create_modules(SOURCE_FILES "${cython_sources}" LINKED_LIBRARIES "${linked_libraries}" - CXX) +rapids_cython_create_modules( + CXX + ASSOCIATED_TARGETS cuspatial + SOURCE_FILES "${cython_sources}" + LINKED_LIBRARIES "${linked_libraries}" +) diff --git a/python/cuspatial/cuspatial/_version.py b/python/cuspatial/cuspatial/_version.py deleted file mode 100644 index 2db1c5542..000000000 --- a/python/cuspatial/cuspatial/_version.py +++ /dev/null @@ -1,566 +0,0 @@ -# This file helps to compute a version number in source trees obtained from -# git-archive tarball (such as those provided by githubs download-from-tag -# feature). Distribution tarballs (built by setup.py sdist) and build -# directories (produced by setup.py build) will contain a much shorter file -# that just contains the computed version number. - -# This file is released into the public domain. Generated by -# versioneer-0.18 (https://github.com/warner/python-versioneer) - -"""Git implementation of _version.py.""" - -import errno -import os -import re -import subprocess -import sys - - -def get_keywords(): - """Get the keywords needed to look up the version information.""" - # these strings will be replaced by git during git-archive. - # setup.py/versioneer.py will grep for the variable names, so they must - # each be defined on a line of their own. _version.py will just call - # get_keywords(). - git_refnames = "$Format:%d$" - git_full = "$Format:%H$" - git_date = "$Format:%ci$" - keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} - return keywords - - -class VersioneerConfig: - """Container for Versioneer configuration parameters.""" - - -def get_config(): - """Create, populate and return the VersioneerConfig() object.""" - # these strings are filled in when 'setup.py versioneer' creates - # _version.py - cfg = VersioneerConfig() - cfg.VCS = "git" - cfg.style = "pep440" - cfg.tag_prefix = "v" - cfg.parentdir_prefix = "cudf-" - cfg.versionfile_source = "cudf/_version.py" - cfg.verbose = False - return cfg - - -class NotThisMethod(Exception): - """Exception raised if a method is not valid for the current scenario.""" - - -LONG_VERSION_PY = {} -HANDLERS = {} - - -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - - def decorate(f): - """Store f in HANDLERS[vcs][method].""" - if vcs not in HANDLERS: - HANDLERS[vcs] = {} - HANDLERS[vcs][method] = f - return f - - return decorate - - -def run_command( - commands, args, cwd=None, verbose=False, hide_stderr=False, env=None -): - """Call the given command(s).""" - assert isinstance(commands, list) - p = None - for c in commands: - try: - dispcmd = str([c] + args) - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen( - [c] + args, - cwd=cwd, - env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr else None), - ) - break - except EnvironmentError: - e = sys.exc_info()[1] - if e.errno == errno.ENOENT: - continue - if verbose: - print("unable to run %s" % dispcmd) - print(e) - return None, None - else: - if verbose: - print("unable to find command, tried %s" % (commands,)) - return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: - if verbose: - print("unable to run %s (error)" % dispcmd) - print("stdout was %s" % stdout) - return None, p.returncode - return stdout, p.returncode - - -def versions_from_parentdir(parentdir_prefix, root, verbose): - """Try to determine the version from the parent directory name. - - Source tarballs conventionally unpack into a directory that includes both - the project name and a version string. We will also support searching up - two directory levels for an appropriately named parent directory - """ - rootdirs = [] - - for i in range(3): - dirname = os.path.basename(root) - if dirname.startswith(parentdir_prefix): - return { - "version": dirname[len(parentdir_prefix) :], - "full-revisionid": None, - "dirty": False, - "error": None, - "date": None, - } - else: - rootdirs.append(root) - root = os.path.dirname(root) # up a level - - if verbose: - print( - "Tried directories %s but none started with prefix %s" - % (str(rootdirs), parentdir_prefix) - ) - raise NotThisMethod("rootdir doesn't start with parentdir_prefix") - - -@register_vcs_handler("git", "get_keywords") -def git_get_keywords(versionfile_abs): - """Extract version information from the given file.""" - # the code embedded in _version.py can just fetch the value of these - # keywords. When used from setup.py, we don't want to import _version.py, - # so we do it with a regexp instead. This function is not used from - # _version.py. - keywords = {} - try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["full"] = mo.group(1) - if line.strip().startswith("git_date ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["date"] = mo.group(1) - f.close() - except EnvironmentError: - pass - return keywords - - -@register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): - """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") - date = keywords.get("date") - if date is not None: - # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant - # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 - # -like" string, which we must then edit to make compliant), because - # it's been around since git-1.5.3, and it's too difficult to - # discover which version we're using, or to work around using an - # older one. - date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - refnames = keywords["refnames"].strip() - if refnames.startswith("$Format"): - if verbose: - print("keywords are unexpanded, not using") - raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = set([r.strip() for r in refnames.strip("()").split(",")]) - # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of - # just "foo-1.0". If we see a "tag: " prefix, prefer those. - TAG = "tag: " - tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) - if not tags: - # Either we're using git < 1.8.3, or there really are no tags. We use - # a heuristic: assume all version tags have a digit. The old git %d - # expansion behaves like git log --decorate=short and strips out the - # refs/heads/ and refs/tags/ prefixes that would let us distinguish - # between branches and tags. By ignoring refnames without digits, we - # filter out many common branch names like "release" and - # "stabilization", as well as "HEAD" and "master". - tags = set([r for r in refs if re.search(r"\d", r)]) - if verbose: - print("discarding '%s', no digits" % ",".join(refs - tags)) - if verbose: - print("likely tags: %s" % ",".join(sorted(tags))) - for ref in sorted(tags): - # sorting will prefer e.g. "2.0" over "2.0rc1" - if ref.startswith(tag_prefix): - r = ref[len(tag_prefix) :] - if verbose: - print("picking %s" % r) - return { - "version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": None, - "date": date, - } - # no suitable tags, so version is "0+unknown", but full hex is still there - if verbose: - print("no suitable tags, using unknown + full revision id") - return { - "version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": "no suitable tags", - "date": None, - } - - -@register_vcs_handler("git", "pieces_from_vcs") -def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): - """Get version from 'git describe' in the root of the source tree. - - This only gets called if the git-archive 'subst' keywords were *not* - expanded, and _version.py hasn't already been rewritten with a short - version string, meaning we're inside a checked out source tree. - """ - GITS = ["git"] - if sys.platform == "win32": - GITS = ["git.cmd", "git.exe"] - - out, rc = run_command( - GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True - ) - if rc != 0: - if verbose: - print("Directory %s not under git control" % root) - raise NotThisMethod("'git rev-parse --git-dir' returned error") - - # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] - # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = run_command( - GITS, - [ - "describe", - "--tags", - "--dirty", - "--always", - "--long", - "--match", - "%s*" % tag_prefix, - ], - cwd=root, - ) - # --long was added in git-1.5.5 - if describe_out is None: - raise NotThisMethod("'git describe' failed") - describe_out = describe_out.strip() - full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) - if full_out is None: - raise NotThisMethod("'git rev-parse' failed") - full_out = full_out.strip() - - pieces = {} - pieces["long"] = full_out - pieces["short"] = full_out[:7] # maybe improved later - pieces["error"] = None - - # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] - # TAG might have hyphens. - git_describe = describe_out - - # look for -dirty suffix - dirty = git_describe.endswith("-dirty") - pieces["dirty"] = dirty - if dirty: - git_describe = git_describe[: git_describe.rindex("-dirty")] - - # now we have TAG-NUM-gHEX or HEX - - if "-" in git_describe: - # TAG-NUM-gHEX - mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) - if not mo: - # unparseable. Maybe git-describe is misbehaving? - pieces["error"] = ( - "unable to parse git-describe output: '%s'" % describe_out - ) - return pieces - - # tag - full_tag = mo.group(1) - if not full_tag.startswith(tag_prefix): - if verbose: - fmt = "tag '%s' doesn't start with prefix '%s'" - print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( - full_tag, - tag_prefix, - ) - return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix) :] - - # distance: number of commits since tag - pieces["distance"] = int(mo.group(2)) - - # commit: short hex revision ID - pieces["short"] = mo.group(3) - - else: - # HEX: no tags - pieces["closest-tag"] = None - count_out, rc = run_command( - GITS, ["rev-list", "HEAD", "--count"], cwd=root - ) - pieces["distance"] = int(count_out) # total number of commits - - # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ - 0 - ].strip() - pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - - return pieces - - -def plus_or_dot(pieces): - """Return a + if we don't already have one, else return a .""" - if "+" in pieces.get("closest-tag", ""): - return "." - return "+" - - -def render_pep440(pieces): - """Build up version string, with post-release "local version identifier". - - Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you - get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty - - Exceptions: - 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += plus_or_dot(pieces) - rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - else: - # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - return rendered - - -def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. - - Exceptions: - 1: no tags. 0.post.devDISTANCE - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] - else: - # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] - return rendered - - -def render_pep440_post(pieces): - """TAG[.postDISTANCE[.dev0]+gHEX] . - - The ".dev0" means dirty. Note that .dev0 sorts backwards - (a dirty tree will appear "older" than the corresponding clean one), - but you shouldn't be releasing software with -dirty anyways. - - Exceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += plus_or_dot(pieces) - rendered += "g%s" % pieces["short"] - else: - # exception #1 - rendered = "0.post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += "+g%s" % pieces["short"] - return rendered - - -def render_pep440_old(pieces): - """TAG[.postDISTANCE[.dev0]] . - - The ".dev0" means dirty. - - Eexceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - else: - # exception #1 - rendered = "0.post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - return rendered - - -def render_git_describe(pieces): - """TAG[-DISTANCE-gHEX][-dirty]. - - Like 'git describe --tags --dirty --always'. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render_git_describe_long(pieces): - """TAG-DISTANCE-gHEX[-dirty]. - - Like 'git describe --tags --dirty --always -long'. - The distance/hash is unconditional. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render(pieces, style): - """Render the given version pieces into the requested style.""" - if pieces["error"]: - return { - "version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None, - } - - if not style or style == "default": - style = "pep440" # the default - - if style == "pep440": - rendered = render_pep440(pieces) - elif style == "pep440-pre": - rendered = render_pep440_pre(pieces) - elif style == "pep440-post": - rendered = render_pep440_post(pieces) - elif style == "pep440-old": - rendered = render_pep440_old(pieces) - elif style == "git-describe": - rendered = render_git_describe(pieces) - elif style == "git-describe-long": - rendered = render_git_describe_long(pieces) - else: - raise ValueError("unknown style '%s'" % style) - - return { - "version": rendered, - "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], - "error": None, - "date": pieces.get("date"), - } - - -def get_versions(): - """Get version information or return default if unable to do so.""" - # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have - # __file__, we can work backwards from there to the root. Some - # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which - # case we can only use expanded keywords. - - cfg = get_config() - verbose = cfg.verbose - - try: - return git_versions_from_keywords( - get_keywords(), cfg.tag_prefix, verbose - ) - except NotThisMethod: - pass - - try: - root = os.path.realpath(__file__) - # versionfile_source is the relative path from the top of the source - # tree (where the .git directory might live) to this file. Invert - # this to find the root from __file__. - for i in cfg.versionfile_source.split("/"): - root = os.path.dirname(root) - except NameError: - return { - "version": "0+unknown", - "full-revisionid": None, - "dirty": None, - "error": "unable to find root of source tree", - "date": None, - } - - try: - pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) - return render(pieces, cfg.style) - except NotThisMethod: - pass - - try: - if cfg.parentdir_prefix: - return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) - except NotThisMethod: - pass - - return { - "version": "0+unknown", - "full-revisionid": None, - "dirty": None, - "error": "unable to compute version", - "date": None, - } diff --git a/python/cuspatial/cuspatial/utils/join_utils.py b/python/cuspatial/cuspatial/utils/join_utils.py index a50d7c3f2..46bd476df 100644 --- a/python/cuspatial/cuspatial/utils/join_utils.py +++ b/python/cuspatial/cuspatial/utils/join_utils.py @@ -2,9 +2,9 @@ import operator -import rmm from numba import cuda +import rmm from cudf.core.buffer import acquire_spill_lock diff --git a/python/cuspatial/pyproject.toml b/python/cuspatial/pyproject.toml index 0261c0b09..8c701a27e 100644 --- a/python/cuspatial/pyproject.toml +++ b/python/cuspatial/pyproject.toml @@ -1,4 +1,4 @@ -# Copyright (c) 2022, NVIDIA CORPORATION. +# Copyright (c) 2022-2023, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,12 +13,97 @@ # limitations under the License. [build-system] - +build-backend = "setuptools.build_meta" requires = [ - "wheel", - "setuptools", - "cython>=0.29,<0.30", - "scikit-build>=0.13.1", "cmake>=3.23.1,!=3.25.0", + "cudf==23.6.*", + "cython>=0.29,<0.30", "ninja", + "rmm==23.6.*", + "scikit-build>=0.13.1", + "setuptools", + "wheel", +] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. + +[project] +name = "cuspatial" +version = "23.6.0" +description = "cuSpatial: GPU-Accelerated Spatial and Trajectory Data Management and Analytics Library" +readme = { file = "README.md", content-type = "text/markdown" } +authors = [ + { name = "NVIDIA Corporation" }, +] +license = { text = "Apache 2.0" } +requires-python = ">=3.9" +dependencies = [ + "cudf==23.6.*", + "geopandas>=0.11.0", + "rmm==23.6.*", +] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. +classifiers = [ + "Intended Audience :: Developers", + "Topic :: Database", + "Topic :: Scientific/Engineering", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", +] + +[project.optional-dependencies] +test = [ + "pytest", + "pytest-cov", + "pytest-xdist", +] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. + +[project.urls] +Homepage = "https://github.com/rapidsai/cuspatial" +Documentation = "https://docs.rapids.ai/api/cuspatial/stable/" + +[tool.setuptools] +license-files = ["LICENSE"] + +[tool.isort] +line_length = 79 +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +combine_as_imports = true +order_by_type = true +known_dask = [ + "dask", + "distributed", + "dask_cuda", +] +known_rapids = [ + "rmm", + "cudf", +] +known_first_party = [ + "cuspatial", +] +default_section = "THIRDPARTY" +sections = [ + "FUTURE", + "STDLIB", + "THIRDPARTY", + "DASK", + "RAPIDS", + "FIRSTPARTY", + "LOCALFOLDER", +] +skip = [ + "thirdparty", + ".eggs", + ".git", + ".hg", + ".mypy_cache", + ".tox", + ".venv", + "_build", + "buck-out", + "build", + "dist", + "__init__.py", ] diff --git a/python/cuspatial/setup.cfg b/python/cuspatial/setup.cfg deleted file mode 100644 index 8603312fa..000000000 --- a/python/cuspatial/setup.cfg +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2018, NVIDIA CORPORATION. - -# See the docstring in versioneer.py for instructions. Note that you must -# re-run 'versioneer.py setup' after changing this section, and commit the -# resulting files. - -[versioneer] -VCS = git -style = pep440 -versionfile_source = cuspatial/_version.py -versionfile_build = cuspatial/_version.py -tag_prefix = v -parentdir_prefix = cuspatial- - -[flake8] -exclude = __init__.py -ignore = - # line break before binary operator - W503 - # whitespace before : - E203 - -[isort] -line_length=79 -multi_line_output=3 -include_trailing_comma=True -force_grid_wrap=0 -combine_as_imports=True -order_by_type=True -known_dask= - dask - distributed - dask_cuda -known_rapids= - librmm_cffi - nvtext - cuml - cugraph - cudf - dask_cudf -known_first_party= - cuspatial -default_section=THIRDPARTY -sections=FUTURE,STDLIB,THIRDPARTY,DASK,RAPIDS,FIRSTPARTY,LOCALFOLDER -skip= - thirdparty - .eggs - .git - .hg - .mypy_cache - .tox - .venv - _build - buck-out - build - dist - __init__.py diff --git a/python/cuspatial/setup.py b/python/cuspatial/setup.py index c7dc01a4d..2ea444b56 100644 --- a/python/cuspatial/setup.py +++ b/python/cuspatial/setup.py @@ -1,31 +1,11 @@ -# Copyright (c) 2018-2022, NVIDIA CORPORATION. -import versioneer +# Copyright (c) 2018-2023, NVIDIA CORPORATION. from setuptools import find_packages from skbuild import setup +packages = find_packages(include=["cuspatial*"]) + setup( - name="cuspatial", - version=versioneer.get_version(), - description=( - "cuSpatial: GPU-Accelerated Spatial and Trajectory Data Management and" - " Analytics Library" - ), - url="https://github.com/rapidsai/cuspatial", - author="NVIDIA Corporation", - license="Apache 2.0", - classifiers=[ - "Intended Audience :: Developers", - "Topic :: Database", - "Topic :: Scientific/Engineering", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - ], - packages=find_packages(include=["cuspatial", "cuspatial.*"]), - package_data={"cuspatial._lib": ["*.pxd"]}, - cmdclass=versioneer.get_cmdclass(), - install_requires=["numba"], + packages=packages, + package_data={key: ["*.pxd", "*.hpp", "*.cuh"] for key in packages}, zip_safe=False, ) diff --git a/python/cuspatial/versioneer.py b/python/cuspatial/versioneer.py deleted file mode 100644 index 07ee33d5b..000000000 --- a/python/cuspatial/versioneer.py +++ /dev/null @@ -1,1904 +0,0 @@ -# Version: 0.18 - -"""The Versioneer - like a rocketeer, but for versions. - -The Versioneer -============== - -* like a rocketeer, but for versions! -* https://github.com/warner/python-versioneer -* Brian Warner -* License: Public Domain -* Compatible With: python2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, and pypy -* [![Latest Version] -(https://pypip.in/version/versioneer/badge.svg?style=flat) -](https://pypi.python.org/pypi/versioneer/) -* [![Build Status] -(https://travis-ci.org/warner/python-versioneer.png?branch=master) -](https://travis-ci.org/warner/python-versioneer) - -This is a tool for managing a recorded version number in distutils-based -python projects. The goal is to remove the tedious and error-prone "update -the embedded version string" step from your release process. Making a new -release should be as easy as recording a new tag in your version-control -system, and maybe making new tarballs. - - -## Quick Install - -* `pip install versioneer` to somewhere to your $PATH -* add a `[versioneer]` section to your setup.cfg (see below) -* run `versioneer install` in your source tree, commit the results - -## Version Identifiers - -Source trees come from a variety of places: - -* a version-control system checkout (mostly used by developers) -* a nightly tarball, produced by build automation -* a snapshot tarball, produced by a web-based VCS browser, like github's - "tarball from tag" feature -* a release tarball, produced by "setup.py sdist", distributed through PyPI - -Within each source tree, the version identifier (either a string or a number, -this tool is format-agnostic) can come from a variety of places: - -* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows - about recent "tags" and an absolute revision-id -* the name of the directory into which the tarball was unpacked -* an expanded VCS keyword ($Id$, etc) -* a `_version.py` created by some earlier build step - -For released software, the version identifier is closely related to a VCS -tag. Some projects use tag names that include more than just the version -string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool -needs to strip the tag prefix to extract the version identifier. For -unreleased software (between tags), the version identifier should provide -enough information to help developers recreate the same tree, while also -giving them an idea of roughly how old the tree is (after version 1.2, before -version 1.3). Many VCS systems can report a description that captures this, -for example `git describe --tags --dirty --always` reports things like -"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the -0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has -uncommitted changes. - -The version identifier is used for multiple purposes: - -* to allow the module to self-identify its version: `myproject.__version__` -* to choose a name and prefix for a 'setup.py sdist' tarball - -## Theory of Operation - -Versioneer works by adding a special `_version.py` file into your source -tree, where your `__init__.py` can import it. This `_version.py` knows how to -dynamically ask the VCS tool for version information at import time. - -`_version.py` also contains `$Revision$` markers, and the installation -process marks `_version.py` to have this marker rewritten with a tag name -during the `git archive` command. As a result, generated tarballs will -contain enough information to get the proper version. - -To allow `setup.py` to compute a version too, a `versioneer.py` is added to -the top level of your source tree, next to `setup.py` and the `setup.cfg` -that configures it. This overrides several distutils/setuptools commands to -compute the version when invoked, and changes `setup.py build` and `setup.py -sdist` to replace `_version.py` with a small static file that contains just -the generated version data. - -## Installation - -See [INSTALL.md](./INSTALL.md) for detailed installation instructions. - -## Version-String Flavors - -Code which uses Versioneer can learn about its version string at runtime by -importing `_version` from your main `__init__.py` file and running the -`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can -import the top-level `versioneer.py` and run `get_versions()`. - -Both functions return a dictionary with different flavors of version -information: - -* `['version']`: A condensed version string, rendered using the selected - style. This is the most commonly used value for the project's version - string. The default "pep440" style yields strings like `0.11`, - `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section - below for alternative styles. - -* `['full-revisionid']`: detailed revision identifier. For Git, this is the - full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". - -* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the - commit date in ISO 8601 format. This will be None if the date is not - available. - -* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that - this is only accurate if run in a VCS checkout, otherwise it is likely to - be False or None - -* `['error']`: if the version string could not be computed, this will be set - to a string describing the problem, otherwise it will be None. It may be - useful to throw an exception in setup.py if this is set, to avoid e.g. - creating tarballs with a version string of "unknown". - -Some variants are more useful than others. Including `full-revisionid` in a -bug report should allow developers to reconstruct the exact code being tested -(or indicate the presence of local changes that should be shared with the -developers). `version` is suitable for display in an "about" box or a CLI -`--version` output: it can be easily compared against release notes and lists -of bugs fixed in various releases. - -The installer adds the following text to your `__init__.py` to place a basic -version in `YOURPROJECT.__version__`: - - from cuspatial._version import get_versions - __version__ = get_versions()['version'] - del get_versions - -## Styles - -The setup.cfg `style=` configuration controls how the VCS information is -rendered into a version string. - -The default style, "pep440", produces a PEP440-compliant string, equal to the -un-prefixed tag name for actual releases, and containing an additional "local -version" section with more detail for in-between builds. For Git, this is -TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags ---dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the -tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and -that this commit is two revisions ("+2") beyond the "0.11" tag. For released -software (exactly equal to a known tag), the identifier will only contain the -stripped tag, e.g. "0.11". - -Other styles are available. See [details.md](details.md) in the Versioneer -source tree for descriptions. - -## Debugging - -Versioneer tries to avoid fatal errors: if something goes wrong, it will tend -to return a version of "0+unknown". To investigate the problem, run `setup.py -version`, which will run the version-lookup code in a verbose mode, and will -display the full contents of `get_versions()` (including the `error` string, -which may help identify what went wrong). - -## Known Limitations - -Some situations are known to cause problems for Versioneer. This details the -most significant ones. More can be found on Github -[issues page](https://github.com/warner/python-versioneer/issues). - -### Subprojects - -Versioneer has limited support for source trees in which `setup.py` is not in -the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are -two common reasons why `setup.py` might not be in the root: - -* Source trees which contain multiple subprojects, such as - [Buildbot](https://github.com/buildbot/buildbot), which contains both - "master" and "slave" subprojects, each with their own `setup.py`, - `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI - distributions (and upload multiple independently-installable tarballs). -* Source trees whose main purpose is to contain a C library, but which also - provide bindings to Python (and perhaps other languages) in subdirectories. - -Versioneer will look for `.git` in parent directories, and most operations -should get the right version string. However `pip` and `setuptools` have bugs -and implementation details which frequently cause `pip install .` from a -subproject directory to fail to find a correct version string (so it usually -defaults to `0+unknown`). - -`pip install --editable .` should work correctly. `setup.py install` might -work too. - -Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in -some later version. - -[Bug #38](https://github.com/warner/python-versioneer/issues/38) is tracking -this issue. The discussion in -[PR #61](https://github.com/warner/python-versioneer/pull/61) describes the -issue from the Versioneer side in more detail. -[pip PR#3176](https://github.com/pypa/pip/pull/3176) and -[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve -pip to let Versioneer work correctly. - -Versioneer-0.16 and earlier only looked for a `.git` directory next to the -`setup.cfg`, so subprojects were completely unsupported with those releases. - -### Editable installs with setuptools <= 18.5 - -`setup.py develop` and `pip install --editable .` allow you to install a -project into a virtualenv once, then continue editing the source code (and -test) without re-installing after every change. - -"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a -convenient way to specify executable scripts that should be installed along -with the python package. - -These both work as expected when using modern setuptools. When using -setuptools-18.5 or earlier, however, certain operations will cause -`pkg_resources.DistributionNotFound` errors when running the entrypoint -script, which must be resolved by re-installing the package. This happens -when the install happens with one version, then the egg_info data is -regenerated while a different version is checked out. Many setup.py commands -cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into -a different virtualenv), so this can be surprising. - -[Bug #83](https://github.com/warner/python-versioneer/issues/83) describes -this one, but upgrading to a newer version of setuptools should probably -resolve it. - -### Unicode version strings - -While Versioneer works (and is continually tested) with both Python 2 and -Python 3, it is not entirely consistent with bytes-vs-unicode distinctions. -Newer releases probably generate unicode version strings on py2. It's not -clear that this is wrong, but it may be surprising for applications when then -write these strings to a network connection or include them in bytes-oriented -APIs like cryptographic checksums. - -[Bug #71](https://github.com/warner/python-versioneer/issues/71) investigates -this question. - - -## Updating Versioneer - -To upgrade your project to a new release of Versioneer, do the following: - -* install the new Versioneer (`pip install -U versioneer` or equivalent) -* edit `setup.cfg`, if necessary, to include any new configuration settings - indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. -* re-run `versioneer install` in your source tree, to replace - `SRC/_version.py` -* commit any changed files - -## Future Directions - -This tool is designed to make it easily extended to other version-control -systems: all VCS-specific components are in separate directories like -src/git/ . The top-level `versioneer.py` script is assembled from these -components by running make-versioneer.py . In the future, make-versioneer.py -will take a VCS name as an argument, and will construct a version of -`versioneer.py` that is specific to the given VCS. It might also take the -configuration arguments that are currently provided manually during -installation by editing setup.py . Alternatively, it might go the other -direction and include code from all supported VCS systems, reducing the -number of intermediate scripts. - - -## License - -To make Versioneer easier to embed, all its code is dedicated to the public -domain. The `_version.py` that it creates is also in the public domain. -Specifically, both are released under the Creative Commons "Public Domain -Dedication" license (CC0-1.0), as described in -https://creativecommons.org/publicdomain/zero/1.0/ . - -""" - -from __future__ import print_function - -import errno -import json -import os -import re -import subprocess -import sys - -try: - import configparser -except ImportError: - import ConfigParser as configparser - - -class VersioneerConfig: - """Container for Versioneer configuration parameters.""" - - -def get_root(): - """Get the project root directory. - - We require that all commands are run from the project root, i.e. the - directory that contains setup.py, setup.cfg, and versioneer.py . - """ - root = os.path.realpath(os.path.abspath(os.getcwd())) - setup_py = os.path.join(root, "setup.py") - versioneer_py = os.path.join(root, "versioneer.py") - if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): - # allow 'python path/to/setup.py COMMAND' - root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) - setup_py = os.path.join(root, "setup.py") - versioneer_py = os.path.join(root, "versioneer.py") - if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): - err = ( - "Versioneer was unable to run the project root directory. " - "Versioneer requires setup.py to be executed from " - "its immediate directory (like 'python setup.py COMMAND'), " - "or in a way that lets it use sys.argv[0] to find the root " - "(like 'python path/to/setup.py COMMAND')." - ) - raise VersioneerBadRootError(err) - try: - # Certain runtime workflows (setup.py install/develop in a setuptools - # tree) execute all dependencies in a single python process, so - # "versioneer" may be imported multiple times, and python's shared - # module-import table will cache the first one. So we can't use - # os.path.dirname(__file__), as that will find whichever - # versioneer.py was first imported, even in later projects. - me = os.path.realpath(os.path.abspath(__file__)) - me_dir = os.path.normcase(os.path.splitext(me)[0]) - vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) - if me_dir != vsr_dir: - print( - "Warning: build in %s is using versioneer.py from %s" - % (os.path.dirname(me), versioneer_py) - ) - except NameError: - pass - return root - - -def get_config_from_root(root): - """Read the project setup.cfg file to determine Versioneer config.""" - # This might raise EnvironmentError (if setup.cfg is missing), or - # configparser.NoSectionError (if it lacks a [versioneer] section), or - # configparser.NoOptionError (if it lacks "VCS="). See the docstring at - # the top of versioneer.py for instructions on writing your setup.cfg . - setup_cfg = os.path.join(root, "setup.cfg") - parser = configparser.SafeConfigParser() - with open(setup_cfg, "r") as f: - parser.readfp(f) - VCS = parser.get("versioneer", "VCS") # mandatory - - def get(parser, name): - if parser.has_option("versioneer", name): - return parser.get("versioneer", name) - return None - - cfg = VersioneerConfig() - cfg.VCS = VCS - cfg.style = get(parser, "style") or "" - cfg.versionfile_source = get(parser, "versionfile_source") - cfg.versionfile_build = get(parser, "versionfile_build") - cfg.tag_prefix = get(parser, "tag_prefix") - if cfg.tag_prefix in ("''", '""'): - cfg.tag_prefix = "" - cfg.parentdir_prefix = get(parser, "parentdir_prefix") - cfg.verbose = get(parser, "verbose") - return cfg - - -class NotThisMethod(Exception): - """Exception raised if a method is not valid for the current scenario.""" - - -# these dictionaries contain VCS-specific tools -LONG_VERSION_PY = {} -HANDLERS = {} - - -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - - def decorate(f): - """Store f in HANDLERS[vcs][method].""" - if vcs not in HANDLERS: - HANDLERS[vcs] = {} - HANDLERS[vcs][method] = f - return f - - return decorate - - -def run_command( - commands, args, cwd=None, verbose=False, hide_stderr=False, env=None -): - """Call the given command(s).""" - assert isinstance(commands, list) - p = None - for c in commands: - try: - dispcmd = str([c] + args) - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen( - [c] + args, - cwd=cwd, - env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr else None), - ) - break - except EnvironmentError: - e = sys.exc_info()[1] - if e.errno == errno.ENOENT: - continue - if verbose: - print("unable to run %s" % dispcmd) - print(e) - return None, None - else: - if verbose: - print("unable to find command, tried %s" % (commands,)) - return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: - if verbose: - print("unable to run %s (error)" % dispcmd) - print("stdout was %s" % stdout) - return None, p.returncode - return stdout, p.returncode - - -LONG_VERSION_PY[ - "git" -] = r''' -# This file helps to compute a version number in source trees obtained from -# git-archive tarball (such as those provided by githubs download-from-tag -# feature). Distribution tarballs (built by setup.py sdist) and build -# directories (produced by setup.py build) will contain a much shorter file -# that just contains the computed version number. - -# This file is released into the public domain. Generated by -# versioneer-0.18 (https://github.com/warner/python-versioneer) - -"""Git implementation of _version.py.""" - -import errno -import os -import re -import subprocess -import sys - - -def get_keywords(): - """Get the keywords needed to look up the version information.""" - # these strings will be replaced by git during git-archive. - # setup.py/versioneer.py will grep for the variable names, so they must - # each be defined on a line of their own. _version.py will just call - # get_keywords(). - git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" - git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" - git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" - keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} - return keywords - - -class VersioneerConfig: - """Container for Versioneer configuration parameters.""" - - -def get_config(): - """Create, populate and return the VersioneerConfig() object.""" - # these strings are filled in when 'setup.py versioneer' creates - # _version.py - cfg = VersioneerConfig() - cfg.VCS = "git" - cfg.style = "%(STYLE)s" - cfg.tag_prefix = "%(TAG_PREFIX)s" - cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" - cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" - cfg.verbose = False - return cfg - - -class NotThisMethod(Exception): - """Exception raised if a method is not valid for the current scenario.""" - - -LONG_VERSION_PY = {} -HANDLERS = {} - - -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - def decorate(f): - """Store f in HANDLERS[vcs][method].""" - if vcs not in HANDLERS: - HANDLERS[vcs] = {} - HANDLERS[vcs][method] = f - return f - return decorate - - -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, - env=None): - """Call the given command(s).""" - assert isinstance(commands, list) - p = None - for c in commands: - try: - dispcmd = str([c] + args) - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen([c] + args, cwd=cwd, env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr - else None)) - break - except EnvironmentError: - e = sys.exc_info()[1] - if e.errno == errno.ENOENT: - continue - if verbose: - print("unable to run %%s" %% dispcmd) - print(e) - return None, None - else: - if verbose: - print("unable to find command, tried %%s" %% (commands,)) - return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: - if verbose: - print("unable to run %%s (error)" %% dispcmd) - print("stdout was %%s" %% stdout) - return None, p.returncode - return stdout, p.returncode - - -def versions_from_parentdir(parentdir_prefix, root, verbose): - """Try to determine the version from the parent directory name. - - Source tarballs conventionally unpack into a directory that includes both - the project name and a version string. We will also support searching up - two directory levels for an appropriately named parent directory - """ - rootdirs = [] - - for i in range(3): - dirname = os.path.basename(root) - if dirname.startswith(parentdir_prefix): - return {"version": dirname[len(parentdir_prefix):], - "full-revisionid": None, - "dirty": False, "error": None, "date": None} - else: - rootdirs.append(root) - root = os.path.dirname(root) # up a level - - if verbose: - print("Tried directories %%s but none started with prefix %%s" %% - (str(rootdirs), parentdir_prefix)) - raise NotThisMethod("rootdir doesn't start with parentdir_prefix") - - -@register_vcs_handler("git", "get_keywords") -def git_get_keywords(versionfile_abs): - """Extract version information from the given file.""" - # the code embedded in _version.py can just fetch the value of these - # keywords. When used from setup.py, we don't want to import _version.py, - # so we do it with a regexp instead. This function is not used from - # _version.py. - keywords = {} - try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["full"] = mo.group(1) - if line.strip().startswith("git_date ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["date"] = mo.group(1) - f.close() - except EnvironmentError: - pass - return keywords - - -@register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): - """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") - date = keywords.get("date") - if date is not None: - # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant - # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 - # -like" string, which we must then edit to make compliant), because - # it's been around since git-1.5.3, and it's too difficult to - # discover which version we're using, or to work around using an - # older one. - date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - refnames = keywords["refnames"].strip() - if refnames.startswith("$Format"): - if verbose: - print("keywords are unexpanded, not using") - raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = set([r.strip() for r in refnames.strip("()").split(",")]) - # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of - # just "foo-1.0". If we see a "tag: " prefix, prefer those. - TAG = "tag: " - tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) - if not tags: - # Either we're using git < 1.8.3, or there really are no tags. We use - # a heuristic: assume all version tags have a digit. The old git %%d - # expansion behaves like git log --decorate=short and strips out the - # refs/heads/ and refs/tags/ prefixes that would let us distinguish - # between branches and tags. By ignoring refnames without digits, we - # filter out many common branch names like "release" and - # "stabilization", as well as "HEAD" and "master". - tags = set([r for r in refs if re.search(r'\d', r)]) - if verbose: - print("discarding '%%s', no digits" %% ",".join(refs - tags)) - if verbose: - print("likely tags: %%s" %% ",".join(sorted(tags))) - for ref in sorted(tags): - # sorting will prefer e.g. "2.0" over "2.0rc1" - if ref.startswith(tag_prefix): - r = ref[len(tag_prefix):] - if verbose: - print("picking %%s" %% r) - return {"version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": None, - "date": date} - # no suitable tags, so version is "0+unknown", but full hex is still there - if verbose: - print("no suitable tags, using unknown + full revision id") - return {"version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": "no suitable tags", "date": None} - - -@register_vcs_handler("git", "pieces_from_vcs") -def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): - """Get version from 'git describe' in the root of the source tree. - - This only gets called if the git-archive 'subst' keywords were *not* - expanded, and _version.py hasn't already been rewritten with a short - version string, meaning we're inside a checked out source tree. - """ - GITS = ["git"] - if sys.platform == "win32": - GITS = ["git.cmd", "git.exe"] - - out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, - hide_stderr=True) - if rc != 0: - if verbose: - print("Directory %%s not under git control" %% root) - raise NotThisMethod("'git rev-parse --git-dir' returned error") - - # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] - # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", - "--always", "--long", - "--match", "%%s*" %% tag_prefix], - cwd=root) - # --long was added in git-1.5.5 - if describe_out is None: - raise NotThisMethod("'git describe' failed") - describe_out = describe_out.strip() - full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) - if full_out is None: - raise NotThisMethod("'git rev-parse' failed") - full_out = full_out.strip() - - pieces = {} - pieces["long"] = full_out - pieces["short"] = full_out[:7] # maybe improved later - pieces["error"] = None - - # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] - # TAG might have hyphens. - git_describe = describe_out - - # look for -dirty suffix - dirty = git_describe.endswith("-dirty") - pieces["dirty"] = dirty - if dirty: - git_describe = git_describe[:git_describe.rindex("-dirty")] - - # now we have TAG-NUM-gHEX or HEX - - if "-" in git_describe: - # TAG-NUM-gHEX - mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) - if not mo: - # unparseable. Maybe git-describe is misbehaving? - pieces["error"] = ("unable to parse git-describe output: '%%s'" - %% describe_out) - return pieces - - # tag - full_tag = mo.group(1) - if not full_tag.startswith(tag_prefix): - if verbose: - fmt = "tag '%%s' doesn't start with prefix '%%s'" - print(fmt %% (full_tag, tag_prefix)) - pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" - %% (full_tag, tag_prefix)) - return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix):] - - # distance: number of commits since tag - pieces["distance"] = int(mo.group(2)) - - # commit: short hex revision ID - pieces["short"] = mo.group(3) - - else: - # HEX: no tags - pieces["closest-tag"] = None - count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], - cwd=root) - pieces["distance"] = int(count_out) # total number of commits - - # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], - cwd=root)[0].strip() - pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - - return pieces - - -def plus_or_dot(pieces): - """Return a + if we don't already have one, else return a .""" - if "+" in pieces.get("closest-tag", ""): - return "." - return "+" - - -def render_pep440(pieces): - """Build up version string, with post-release "local version identifier". - - Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you - get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty - - Exceptions: - 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += plus_or_dot(pieces) - rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - else: - # exception #1 - rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], - pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - return rendered - - -def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. - - Exceptions: - 1: no tags. 0.post.devDISTANCE - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += ".post.dev%%d" %% pieces["distance"] - else: - # exception #1 - rendered = "0.post.dev%%d" %% pieces["distance"] - return rendered - - -def render_pep440_post(pieces): - """TAG[.postDISTANCE[.dev0]+gHEX] . - - The ".dev0" means dirty. Note that .dev0 sorts backwards - (a dirty tree will appear "older" than the corresponding clean one), - but you shouldn't be releasing software with -dirty anyways. - - Exceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%%d" %% pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += plus_or_dot(pieces) - rendered += "g%%s" %% pieces["short"] - else: - # exception #1 - rendered = "0.post%%d" %% pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += "+g%%s" %% pieces["short"] - return rendered - - -def render_pep440_old(pieces): - """TAG[.postDISTANCE[.dev0]] . - - The ".dev0" means dirty. - - Eexceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%%d" %% pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - else: - # exception #1 - rendered = "0.post%%d" %% pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - return rendered - - -def render_git_describe(pieces): - """TAG[-DISTANCE-gHEX][-dirty]. - - Like 'git describe --tags --dirty --always'. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render_git_describe_long(pieces): - """TAG-DISTANCE-gHEX[-dirty]. - - Like 'git describe --tags --dirty --always -long'. - The distance/hash is unconditional. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render(pieces, style): - """Render the given version pieces into the requested style.""" - if pieces["error"]: - return {"version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None} - - if not style or style == "default": - style = "pep440" # the default - - if style == "pep440": - rendered = render_pep440(pieces) - elif style == "pep440-pre": - rendered = render_pep440_pre(pieces) - elif style == "pep440-post": - rendered = render_pep440_post(pieces) - elif style == "pep440-old": - rendered = render_pep440_old(pieces) - elif style == "git-describe": - rendered = render_git_describe(pieces) - elif style == "git-describe-long": - rendered = render_git_describe_long(pieces) - else: - raise ValueError("unknown style '%%s'" %% style) - - return {"version": rendered, "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], "error": None, - "date": pieces.get("date")} - - -def get_versions(): - """Get version information or return default if unable to do so.""" - # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have - # __file__, we can work backwards from there to the root. Some - # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which - # case we can only use expanded keywords. - - cfg = get_config() - verbose = cfg.verbose - - try: - return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, - verbose) - except NotThisMethod: - pass - - try: - root = os.path.realpath(__file__) - # versionfile_source is the relative path from the top of the source - # tree (where the .git directory might live) to this file. Invert - # this to find the root from __file__. - for i in cfg.versionfile_source.split('/'): - root = os.path.dirname(root) - except NameError: - return {"version": "0+unknown", "full-revisionid": None, - "dirty": None, - "error": "unable to find root of source tree", - "date": None} - - try: - pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) - return render(pieces, cfg.style) - except NotThisMethod: - pass - - try: - if cfg.parentdir_prefix: - return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) - except NotThisMethod: - pass - - return {"version": "0+unknown", "full-revisionid": None, - "dirty": None, - "error": "unable to compute version", "date": None} -''' - - -@register_vcs_handler("git", "get_keywords") -def git_get_keywords(versionfile_abs): - """Extract version information from the given file.""" - # the code embedded in _version.py can just fetch the value of these - # keywords. When used from setup.py, we don't want to import _version.py, - # so we do it with a regexp instead. This function is not used from - # _version.py. - keywords = {} - try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["full"] = mo.group(1) - if line.strip().startswith("git_date ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["date"] = mo.group(1) - f.close() - except EnvironmentError: - pass - return keywords - - -@register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): - """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") - date = keywords.get("date") - if date is not None: - # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant - # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 - # -like" string, which we must then edit to make compliant), because - # it's been around since git-1.5.3, and it's too difficult to - # discover which version we're using, or to work around using an - # older one. - date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - refnames = keywords["refnames"].strip() - if refnames.startswith("$Format"): - if verbose: - print("keywords are unexpanded, not using") - raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = set([r.strip() for r in refnames.strip("()").split(",")]) - # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of - # just "foo-1.0". If we see a "tag: " prefix, prefer those. - TAG = "tag: " - tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) - if not tags: - # Either we're using git < 1.8.3, or there really are no tags. We use - # a heuristic: assume all version tags have a digit. The old git %d - # expansion behaves like git log --decorate=short and strips out the - # refs/heads/ and refs/tags/ prefixes that would let us distinguish - # between branches and tags. By ignoring refnames without digits, we - # filter out many common branch names like "release" and - # "stabilization", as well as "HEAD" and "master". - tags = set([r for r in refs if re.search(r"\d", r)]) - if verbose: - print("discarding '%s', no digits" % ",".join(refs - tags)) - if verbose: - print("likely tags: %s" % ",".join(sorted(tags))) - for ref in sorted(tags): - # sorting will prefer e.g. "2.0" over "2.0rc1" - if ref.startswith(tag_prefix): - r = ref[len(tag_prefix) :] - if verbose: - print("picking %s" % r) - return { - "version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": None, - "date": date, - } - # no suitable tags, so version is "0+unknown", but full hex is still there - if verbose: - print("no suitable tags, using unknown + full revision id") - return { - "version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": "no suitable tags", - "date": None, - } - - -@register_vcs_handler("git", "pieces_from_vcs") -def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): - """Get version from 'git describe' in the root of the source tree. - - This only gets called if the git-archive 'subst' keywords were *not* - expanded, and _version.py hasn't already been rewritten with a short - version string, meaning we're inside a checked out source tree. - """ - GITS = ["git"] - if sys.platform == "win32": - GITS = ["git.cmd", "git.exe"] - - out, rc = run_command( - GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True - ) - if rc != 0: - if verbose: - print("Directory %s not under git control" % root) - raise NotThisMethod("'git rev-parse --git-dir' returned error") - - # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] - # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = run_command( - GITS, - [ - "describe", - "--tags", - "--dirty", - "--always", - "--long", - "--match", - "%s*" % tag_prefix, - ], - cwd=root, - ) - # --long was added in git-1.5.5 - if describe_out is None: - raise NotThisMethod("'git describe' failed") - describe_out = describe_out.strip() - full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) - if full_out is None: - raise NotThisMethod("'git rev-parse' failed") - full_out = full_out.strip() - - pieces = {} - pieces["long"] = full_out - pieces["short"] = full_out[:7] # maybe improved later - pieces["error"] = None - - # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] - # TAG might have hyphens. - git_describe = describe_out - - # look for -dirty suffix - dirty = git_describe.endswith("-dirty") - pieces["dirty"] = dirty - if dirty: - git_describe = git_describe[: git_describe.rindex("-dirty")] - - # now we have TAG-NUM-gHEX or HEX - - if "-" in git_describe: - # TAG-NUM-gHEX - mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) - if not mo: - # unparseable. Maybe git-describe is misbehaving? - pieces["error"] = ( - "unable to parse git-describe output: '%s'" % describe_out - ) - return pieces - - # tag - full_tag = mo.group(1) - if not full_tag.startswith(tag_prefix): - if verbose: - fmt = "tag '%s' doesn't start with prefix '%s'" - print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( - full_tag, - tag_prefix, - ) - return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix) :] - - # distance: number of commits since tag - pieces["distance"] = int(mo.group(2)) - - # commit: short hex revision ID - pieces["short"] = mo.group(3) - - else: - # HEX: no tags - pieces["closest-tag"] = None - count_out, rc = run_command( - GITS, ["rev-list", "HEAD", "--count"], cwd=root - ) - pieces["distance"] = int(count_out) # total number of commits - - # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ - 0 - ].strip() - pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - - return pieces - - -def do_vcs_install(manifest_in, versionfile_source, ipy): - """Git-specific installation logic for Versioneer. - - For Git, this means creating/changing .gitattributes to mark _version.py - for export-subst keyword substitution. - """ - GITS = ["git"] - if sys.platform == "win32": - GITS = ["git.cmd", "git.exe"] - files = [manifest_in, versionfile_source] - if ipy: - files.append(ipy) - try: - me = __file__ - if me.endswith(".pyc") or me.endswith(".pyo"): - me = os.path.splitext(me)[0] + ".py" - versioneer_file = os.path.relpath(me) - except NameError: - versioneer_file = "versioneer.py" - files.append(versioneer_file) - present = False - try: - f = open(".gitattributes", "r") - for line in f.readlines(): - if line.strip().startswith(versionfile_source): - if "export-subst" in line.strip().split()[1:]: - present = True - f.close() - except EnvironmentError: - pass - if not present: - f = open(".gitattributes", "a+") - f.write("%s export-subst\n" % versionfile_source) - f.close() - files.append(".gitattributes") - run_command(GITS, ["add", "--"] + files) - - -def versions_from_parentdir(parentdir_prefix, root, verbose): - """Try to determine the version from the parent directory name. - - Source tarballs conventionally unpack into a directory that includes both - the project name and a version string. We will also support searching up - two directory levels for an appropriately named parent directory - """ - rootdirs = [] - - for i in range(3): - dirname = os.path.basename(root) - if dirname.startswith(parentdir_prefix): - return { - "version": dirname[len(parentdir_prefix) :], - "full-revisionid": None, - "dirty": False, - "error": None, - "date": None, - } - else: - rootdirs.append(root) - root = os.path.dirname(root) # up a level - - if verbose: - print( - "Tried directories %s but none started with prefix %s" - % (str(rootdirs), parentdir_prefix) - ) - raise NotThisMethod("rootdir doesn't start with parentdir_prefix") - - -SHORT_VERSION_PY = """ -# This file was generated by 'versioneer.py' (0.18) from -# revision-control system data, or from the parent directory name of an -# unpacked source archive. Distribution tarballs contain a pre-generated copy -# of this file. - -import json - -version_json = ''' -%s -''' # END VERSION_JSON - - -def get_versions(): - return json.loads(version_json) -""" - - -def versions_from_file(filename): - """Try to determine the version from _version.py if present.""" - try: - with open(filename) as f: - contents = f.read() - except EnvironmentError: - raise NotThisMethod("unable to read _version.py") - mo = re.search( - r"version_json = '''\n(.*)''' # END VERSION_JSON", - contents, - re.M | re.S, - ) - if not mo: - mo = re.search( - r"version_json = '''\r\n(.*)''' # END VERSION_JSON", - contents, - re.M | re.S, - ) - if not mo: - raise NotThisMethod("no version_json in _version.py") - return json.loads(mo.group(1)) - - -def write_to_version_file(filename, versions): - """Write the given version number to the given _version.py file.""" - os.unlink(filename) - contents = json.dumps( - versions, sort_keys=True, indent=1, separators=(",", ": ") - ) - with open(filename, "w") as f: - f.write(SHORT_VERSION_PY % contents) - - print("set %s to '%s'" % (filename, versions["version"])) - - -def plus_or_dot(pieces): - """Return a + if we don't already have one, else return a .""" - if "+" in pieces.get("closest-tag", ""): - return "." - return "+" - - -def render_pep440(pieces): - """Build up version string, with post-release "local version identifier". - - Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you - get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty - - Exceptions: - 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += plus_or_dot(pieces) - rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - else: - # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) - if pieces["dirty"]: - rendered += ".dirty" - return rendered - - -def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. - - Exceptions: - 1: no tags. 0.post.devDISTANCE - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] - else: - # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] - return rendered - - -def render_pep440_post(pieces): - """TAG[.postDISTANCE[.dev0]+gHEX] . - - The ".dev0" means dirty. Note that .dev0 sorts backwards - (a dirty tree will appear "older" than the corresponding clean one), - but you shouldn't be releasing software with -dirty anyways. - - Exceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += plus_or_dot(pieces) - rendered += "g%s" % pieces["short"] - else: - # exception #1 - rendered = "0.post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - rendered += "+g%s" % pieces["short"] - return rendered - - -def render_pep440_old(pieces): - """TAG[.postDISTANCE[.dev0]] . - - The ".dev0" means dirty. - - Eexceptions: - 1: no tags. 0.postDISTANCE[.dev0] - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"] or pieces["dirty"]: - rendered += ".post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - else: - # exception #1 - rendered = "0.post%d" % pieces["distance"] - if pieces["dirty"]: - rendered += ".dev0" - return rendered - - -def render_git_describe(pieces): - """TAG[-DISTANCE-gHEX][-dirty]. - - Like 'git describe --tags --dirty --always'. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render_git_describe_long(pieces): - """TAG-DISTANCE-gHEX[-dirty]. - - Like 'git describe --tags --dirty --always -long'. - The distance/hash is unconditional. - - Exceptions: - 1: no tags. HEX[-dirty] (note: no 'g' prefix) - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) - else: - # exception #1 - rendered = pieces["short"] - if pieces["dirty"]: - rendered += "-dirty" - return rendered - - -def render(pieces, style): - """Render the given version pieces into the requested style.""" - if pieces["error"]: - return { - "version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None, - } - - if not style or style == "default": - style = "pep440" # the default - - if style == "pep440": - rendered = render_pep440(pieces) - elif style == "pep440-pre": - rendered = render_pep440_pre(pieces) - elif style == "pep440-post": - rendered = render_pep440_post(pieces) - elif style == "pep440-old": - rendered = render_pep440_old(pieces) - elif style == "git-describe": - rendered = render_git_describe(pieces) - elif style == "git-describe-long": - rendered = render_git_describe_long(pieces) - else: - raise ValueError("unknown style '%s'" % style) - - return { - "version": rendered, - "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], - "error": None, - "date": pieces.get("date"), - } - - -class VersioneerBadRootError(Exception): - """The project root directory is unknown or missing key files.""" - - -def get_versions(verbose=False): - """Get the project version from whatever source is available. - - Returns dict with two keys: 'version' and 'full'. - """ - if "versioneer" in sys.modules: - # see the discussion in cmdclass.py:get_cmdclass() - del sys.modules["versioneer"] - - root = get_root() - cfg = get_config_from_root(root) - - assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" - handlers = HANDLERS.get(cfg.VCS) - assert handlers, "unrecognized VCS '%s'" % cfg.VCS - verbose = verbose or cfg.verbose - assert ( - cfg.versionfile_source is not None - ), "please set versioneer.versionfile_source" - assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" - - versionfile_abs = os.path.join(root, cfg.versionfile_source) - - # extract version from first of: _version.py, VCS command (e.g. 'git - # describe'), parentdir. This is meant to work for developers using a - # source checkout, for users of a tarball created by 'setup.py sdist', - # and for users of a tarball/zipball created by 'git archive' or github's - # download-from-tag feature or the equivalent in other VCSes. - - get_keywords_f = handlers.get("get_keywords") - from_keywords_f = handlers.get("keywords") - if get_keywords_f and from_keywords_f: - try: - keywords = get_keywords_f(versionfile_abs) - ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) - if verbose: - print("got version from expanded keyword %s" % ver) - return ver - except NotThisMethod: - pass - - try: - ver = versions_from_file(versionfile_abs) - if verbose: - print("got version from file %s %s" % (versionfile_abs, ver)) - return ver - except NotThisMethod: - pass - - from_vcs_f = handlers.get("pieces_from_vcs") - if from_vcs_f: - try: - pieces = from_vcs_f(cfg.tag_prefix, root, verbose) - ver = render(pieces, cfg.style) - if verbose: - print("got version from VCS %s" % ver) - return ver - except NotThisMethod: - pass - - try: - if cfg.parentdir_prefix: - ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) - if verbose: - print("got version from parentdir %s" % ver) - return ver - except NotThisMethod: - pass - - if verbose: - print("unable to compute version") - - return { - "version": "0+unknown", - "full-revisionid": None, - "dirty": None, - "error": "unable to compute version", - "date": None, - } - - -def get_version(): - """Get the short version string for this project.""" - return get_versions()["version"] - - -def get_cmdclass(): - """Get the custom setuptools/distutils subclasses used by Versioneer.""" - if "versioneer" in sys.modules: - del sys.modules["versioneer"] - # this fixes the "python setup.py develop" case (also 'install' and - # 'easy_install .'), in which subdependencies of the main project are - # built (using setup.py bdist_egg) in the same python process. Assume - # a main project A and a dependency B, which use different versions - # of Versioneer. A's setup.py imports A's Versioneer, leaving it in - # sys.modules by the time B's setup.py is executed, causing B to run - # with the wrong versioneer. Setuptools wraps the sub-dep builds in a - # sandbox that restores sys.modules to it's pre-build state, so the - # parent is protected against the child's "import versioneer". By - # removing ourselves from sys.modules here, before the child build - # happens, we protect the child from the parent's versioneer too. - # Also see https://github.com/warner/python-versioneer/issues/52 - - cmds = {} - - # we add "version" to both distutils and setuptools - from distutils.core import Command - - class cmd_version(Command): - description = "report generated version string" - user_options = [] - boolean_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - vers = get_versions(verbose=True) - print("Version: %s" % vers["version"]) - print(" full-revisionid: %s" % vers.get("full-revisionid")) - print(" dirty: %s" % vers.get("dirty")) - print(" date: %s" % vers.get("date")) - if vers["error"]: - print(" error: %s" % vers["error"]) - - cmds["version"] = cmd_version - - # we override "build_py" in both distutils and setuptools - # - # most invocation pathways end up running build_py: - # distutils/build -> build_py - # distutils/install -> distutils/build ->.. - # setuptools/bdist_wheel -> distutils/install ->.. - # setuptools/bdist_egg -> distutils/install_lib -> build_py - # setuptools/install -> bdist_egg ->.. - # setuptools/develop -> ? - # pip install: - # copies source tree to a tempdir before running egg_info/etc - # if .git isn't copied too, 'git describe' will fail - # then does setup.py bdist_wheel, or sometimes setup.py install - # setup.py egg_info -> ? - - # we override different "build_py" commands for both environments - if "setuptools" in sys.modules: - from setuptools.command.build_py import build_py as _build_py - else: - from distutils.command.build_py import build_py as _build_py - - class cmd_build_py(_build_py): - def run(self): - root = get_root() - cfg = get_config_from_root(root) - versions = get_versions() - _build_py.run(self) - # now locate _version.py in the new build/ directory and replace - # it with an updated value - if cfg.versionfile_build: - target_versionfile = os.path.join( - self.build_lib, cfg.versionfile_build - ) - print("UPDATING %s" % target_versionfile) - write_to_version_file(target_versionfile, versions) - - cmds["build_py"] = cmd_build_py - - if "cx_Freeze" in sys.modules: # cx_freeze enabled? - from cx_Freeze.dist import build_exe as _build_exe - - # nczeczulin reports that py2exe won't like the pep440-style string - # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. - # setup(console=[{ - # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION - # "product_version": versioneer.get_version(), - # ... - - class cmd_build_exe(_build_exe): - def run(self): - root = get_root() - cfg = get_config_from_root(root) - versions = get_versions() - target_versionfile = cfg.versionfile_source - print("UPDATING %s" % target_versionfile) - write_to_version_file(target_versionfile, versions) - - _build_exe.run(self) - os.unlink(target_versionfile) - with open(cfg.versionfile_source, "w") as f: - LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - - cmds["build_exe"] = cmd_build_exe - del cmds["build_py"] - - if "py2exe" in sys.modules: # py2exe enabled? - try: - from py2exe.distutils_buildexe import py2exe as _py2exe # py3 - except ImportError: - from py2exe.build_exe import py2exe as _py2exe # py2 - - class cmd_py2exe(_py2exe): - def run(self): - root = get_root() - cfg = get_config_from_root(root) - versions = get_versions() - target_versionfile = cfg.versionfile_source - print("UPDATING %s" % target_versionfile) - write_to_version_file(target_versionfile, versions) - - _py2exe.run(self) - os.unlink(target_versionfile) - with open(cfg.versionfile_source, "w") as f: - LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - - cmds["py2exe"] = cmd_py2exe - - # we override different "sdist" commands for both environments - if "setuptools" in sys.modules: - from setuptools.command.sdist import sdist as _sdist - else: - from distutils.command.sdist import sdist as _sdist - - class cmd_sdist(_sdist): - def run(self): - versions = get_versions() - self._versioneer_generated_versions = versions - # unless we update this, the command will keep using the old - # version - self.distribution.metadata.version = versions["version"] - return _sdist.run(self) - - def make_release_tree(self, base_dir, files): - root = get_root() - cfg = get_config_from_root(root) - _sdist.make_release_tree(self, base_dir, files) - # now locate _version.py in the new base_dir directory - # (remembering that it may be a hardlink) and replace it with an - # updated value - target_versionfile = os.path.join(base_dir, cfg.versionfile_source) - print("UPDATING %s" % target_versionfile) - write_to_version_file( - target_versionfile, self._versioneer_generated_versions - ) - - cmds["sdist"] = cmd_sdist - - return cmds - - -CONFIG_ERROR = """ -setup.cfg is missing the necessary Versioneer configuration. You need -a section like: - - [versioneer] - VCS = git - style = pep440 - versionfile_source = src/myproject/_version.py - versionfile_build = myproject/_version.py - tag_prefix = - parentdir_prefix = myproject- - -You will also need to edit your setup.py to use the results: - - import versioneer - setup(version=versioneer.get_version(), - cmdclass=versioneer.get_cmdclass(), ...) - -Please read the docstring in ./versioneer.py for configuration instructions, -edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. -""" - -SAMPLE_CONFIG = """ -# See the docstring in versioneer.py for instructions. Note that you must -# re-run 'versioneer.py setup' after changing this section, and commit the -# resulting files. - -[versioneer] -#VCS = git -#style = pep440 -#versionfile_source = -#versionfile_build = -#tag_prefix = -#parentdir_prefix = - -""" - -INIT_PY_SNIPPET = """ -from cuspatial._version import get_versions -__version__ = get_versions()['version'] -del get_versions -""" - - -def do_setup(): - """Main VCS-independent setup function for installing Versioneer.""" - root = get_root() - try: - cfg = get_config_from_root(root) - except ( - EnvironmentError, - configparser.NoSectionError, - configparser.NoOptionError, - ) as e: - if isinstance(e, (EnvironmentError, configparser.NoSectionError)): - print( - "Adding sample versioneer config to setup.cfg", file=sys.stderr - ) - with open(os.path.join(root, "setup.cfg"), "a") as f: - f.write(SAMPLE_CONFIG) - print(CONFIG_ERROR, file=sys.stderr) - return 1 - - print(" creating %s" % cfg.versionfile_source) - with open(cfg.versionfile_source, "w") as f: - LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - - ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") - if os.path.exists(ipy): - try: - with open(ipy, "r") as f: - old = f.read() - except EnvironmentError: - old = "" - if INIT_PY_SNIPPET not in old: - print(" appending to %s" % ipy) - with open(ipy, "a") as f: - f.write(INIT_PY_SNIPPET) - else: - print(" %s unmodified" % ipy) - else: - print(" %s doesn't exist, ok" % ipy) - ipy = None - - # Make sure both the top-level "versioneer.py" and versionfile_source - # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so - # they'll be copied into source distributions. Pip won't be able to - # install the package without this. - manifest_in = os.path.join(root, "MANIFEST.in") - simple_includes = set() - try: - with open(manifest_in, "r") as f: - for line in f: - if line.startswith("include "): - for include in line.split()[1:]: - simple_includes.add(include) - except EnvironmentError: - pass - # That doesn't cover everything MANIFEST.in can do - # (http://docs.python.org/2/distutils/sourcedist.html#commands), so - # it might give some false negatives. Appending redundant 'include' - # lines is safe, though. - if "versioneer.py" not in simple_includes: - print(" appending 'versioneer.py' to MANIFEST.in") - with open(manifest_in, "a") as f: - f.write("include versioneer.py\n") - else: - print(" 'versioneer.py' already in MANIFEST.in") - if cfg.versionfile_source not in simple_includes: - print( - " appending versionfile_source ('%s') to MANIFEST.in" - % cfg.versionfile_source - ) - with open(manifest_in, "a") as f: - f.write("include %s\n" % cfg.versionfile_source) - else: - print(" versionfile_source already in MANIFEST.in") - - # Make VCS-specific changes. For git, this means creating/changing - # .gitattributes to mark _version.py for export-subst keyword - # substitution. - do_vcs_install(manifest_in, cfg.versionfile_source, ipy) - return 0 - - -def scan_setup_py(): - """Validate the contents of setup.py against Versioneer's expectations.""" - found = set() - setters = False - errors = 0 - with open("setup.py", "r") as f: - for line in f.readlines(): - if "import versioneer" in line: - found.add("import") - if "versioneer.get_cmdclass()" in line: - found.add("cmdclass") - if "versioneer.get_version()" in line: - found.add("get_version") - if "versioneer.VCS" in line: - setters = True - if "versioneer.versionfile_source" in line: - setters = True - if len(found) != 3: - print("") - print("Your setup.py appears to be missing some important items") - print("(but I might be wrong). Please make sure it has something") - print("roughly like the following:") - print("") - print(" import versioneer") - print(" setup( version=versioneer.get_version(),") - print(" cmdclass=versioneer.get_cmdclass(), ...)") - print("") - errors += 1 - if setters: - print("You should remove lines like 'versioneer.VCS = ' and") - print("'versioneer.versionfile_source = ' . This configuration") - print("now lives in setup.cfg, and should be removed from setup.py") - print("") - errors += 1 - return errors - - -if __name__ == "__main__": - cmd = sys.argv[1] - if cmd == "setup": - errors = do_setup() - errors += scan_setup_py() - if errors: - sys.exit(1) From 9f990eadd31b2033c48faedf722961ca33429ac8 Mon Sep 17 00:00:00 2001 From: AJ Schmidt Date: Mon, 5 Jun 2023 13:37:52 -0400 Subject: [PATCH 35/63] Remove documentation build scripts for Jenkins (#1169) We recently created new scripts for building documentation with GitHub Actions. This PR removes the old scripts that were used by Jenkins and are no longer in use. Authors: - AJ Schmidt (https://github.com/ajschmidt8) Approvers: - Ray Douglass (https://github.com/raydouglass) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1169 --- ci/docs/build.sh | 59 ------------------------------------------------ 1 file changed, 59 deletions(-) delete mode 100644 ci/docs/build.sh diff --git a/ci/docs/build.sh b/ci/docs/build.sh deleted file mode 100644 index 6c9b75c93..000000000 --- a/ci/docs/build.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -# Copyright (c) 2020, NVIDIA CORPORATION. -################################# -# cuSpatial Docs build script for CI # -################################# - -if [ -z "$PROJECT_WORKSPACE" ]; then - echo ">>>> ERROR: Could not detect PROJECT_WORKSPACE in environment" - echo ">>>> WARNING: This script contains git commands meant for automated building, do not run locally" - exit 1 -fi - -export DOCS_WORKSPACE="$WORKSPACE/docs" -export PATH=/opt/conda/bin:/usr/local/cuda/bin:$PATH -export HOME="$WORKSPACE" -export PROJECT_WORKSPACE=/rapids/cuspatial -export LIBCUDF_KERNEL_CACHE_PATH="$HOME/.jitify-cache" -export PROJECTS=(cuspatial libcuspatial) - -gpuci_logger "Check environment" -env - -gpuci_logger "Check GPU usage" -nvidia-smi - -gpuci_logger "Activate conda env" -. /opt/conda/etc/profile.d/conda.sh -conda activate rapids - -gpuci_logger "Check versions" -python --version -$CC --version -$CXX --version - -gpuci_logger "Show conda info" -conda info -conda config --show-sources -conda list --show-channel-urls - -# Build C++ docs -gpuci_logger "Build Doxygen docs" -cd "$PROJECT_WORKSPACE/cpp/doxygen" -doxygen Doxyfile - -# Build Python docs -gpuci_logger "Build Sphinx docs" -cd "$PROJECT_WORKSPACE/docs" -make html - -#Commit to Website -cd "$DOCS_WORKSPACE" - -for PROJECT in ${PROJECTS[@]}; do - mkdir -p "$DOCS_WORKSPACE/api/$PROJECT/$BRANCH_VERSION" - rm -rf "$DOCS_WORKSPACE/api/$PROJECT/$BRANCH_VERSION/"* -done - -mv "$PROJECT_WORKSPACE/docs/build/html/"* "$DOCS_WORKSPACE/api/cuspatial/$BRANCH_VERSION" -mv "$PROJECT_WORKSPACE/cpp/doxygen/html/"* "$DOCS_WORKSPACE/api/libcuspatial/$BRANCH_VERSION" From 663ac384740d9a7a7d4cfc947f84bf4984d23cf4 Mon Sep 17 00:00:00 2001 From: ptaylor Date: Mon, 5 Jun 2023 15:14:44 -0700 Subject: [PATCH 36/63] more 23.06 -> 23.08 --- .github/workflows/build.yaml | 4 ++-- .github/workflows/pr.yaml | 4 ++-- .github/workflows/test.yaml | 2 +- python/cuspatial/cuspatial/__init__.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 246c25965..a872e289f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -68,7 +68,7 @@ jobs: sha: ${{ inputs.sha }} wheel-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -80,7 +80,7 @@ jobs: wheel-publish: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index acf8bb4fc..53cc04bd2 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -75,7 +75,7 @@ jobs: wheel-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 with: build_type: pull-request package-dir: python/cuspatial @@ -84,7 +84,7 @@ jobs: wheel-tests: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 with: build_type: pull-request package-name: cuspatial diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0c960bacb..00a4c0446 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -32,7 +32,7 @@ jobs: sha: ${{ inputs.sha }} wheel-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.06 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 with: build_type: nightly branch: ${{ inputs.branch }} diff --git a/python/cuspatial/cuspatial/__init__.py b/python/cuspatial/cuspatial/__init__.py index 92da6ee06..d8f07d5d0 100644 --- a/python/cuspatial/cuspatial/__init__.py +++ b/python/cuspatial/cuspatial/__init__.py @@ -29,4 +29,4 @@ ) from .io.geopandas import from_geopandas -__version__ = "23.06.00" +__version__ = "23.08.00" From d42885004b1320c86bba00777b3aeaad3be76c51 Mon Sep 17 00:00:00 2001 From: ptaylor Date: Mon, 5 Jun 2023 15:17:57 -0700 Subject: [PATCH 37/63] pyproject.toml not pyproject.py --- ci/release/update-version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 3c5b99c73..1c618d1f0 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -75,4 +75,4 @@ sed_runner "s/^version = .*/version = \"${NEXT_FULL_TAG}\"/g" python/cuspatial/p # Dependency versions in pyproject.toml sed_runner "s/cudf==.*\",/cudf==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.toml -sed_runner "s/rmm==.*\",/rmm==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.py +sed_runner "s/rmm==.*\",/rmm==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.toml From e9a227dc18f44e93b2b502cc3167dd348a62d62f Mon Sep 17 00:00:00 2001 From: anon Date: Mon, 5 Jun 2023 22:58:18 +0000 Subject: [PATCH 38/63] handle yaml anchors --- ci/release/update-version.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 1c618d1f0..e1e77a5a1 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -59,12 +59,11 @@ NEXT_SHORT_TAG_PEP440=$(python -c "from setuptools.extern import packaging; prin # bump rapids libraries for FILE in dependencies.yaml conda/environments/*.yaml; do - sed_runner "/- &cudf_conda cudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- cudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- cuml==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- rmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- libcudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- librmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/-.* cudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/-.* cuml==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/-.* libcudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/-.* librmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} + sed_runner "/-.* rmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} done # Dependency versions in dependencies.yaml From 73d3c3ed57ebbed62763500146f8543e7110b0be Mon Sep 17 00:00:00 2001 From: Ray Douglass Date: Wed, 7 Jun 2023 10:41:02 -0400 Subject: [PATCH 39/63] update changelog --- CHANGELOG.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3d3524f2..efe15c5aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,70 @@ +# cuSpatial 23.06.00 (7 Jun 2023) + +## 🚨 Breaking Changes + +- Reorganize cuSpatial headers ([#1097](https://github.com/rapidsai/cuspatial/pull/1097)) [@harrism](https://github.com/harrism) +- Update minimum Python version to Python 3.9 ([#1089](https://github.com/rapidsai/cuspatial/pull/1089)) [@shwina](https://github.com/shwina) +- Move `experimental` headers into main `include/cuspatial` directory ([#1081](https://github.com/rapidsai/cuspatial/pull/1081)) [@harrism](https://github.com/harrism) +- Improve Hausdorff Many Column Performance ([#916](https://github.com/rapidsai/cuspatial/pull/916)) [@isVoid](https://github.com/isVoid) + +## 🐛 Bug Fixes + +- Fix scatter bug due to overlapping range in `pairwise_linestring_intersection` ([#1152](https://github.com/rapidsai/cuspatial/pull/1152)) [@isVoid](https://github.com/isVoid) +- Pin cuml dependency in notebook testing environment to nightlies ([#1110](https://github.com/rapidsai/cuspatial/pull/1110)) [@isVoid](https://github.com/isVoid) +- Fix a bug in point-in-polygon kernel: if the point is collinear with an edge, result is asserted false ([#1108](https://github.com/rapidsai/cuspatial/pull/1108)) [@isVoid](https://github.com/isVoid) +- Fix a bug in segment intersection primitive where two collinear segment touch at endpoints is miscomputed as a degenerate segment ([#1093](https://github.com/rapidsai/cuspatial/pull/1093)) [@isVoid](https://github.com/isVoid) +- Update `CMAKE_CUDA_ARCHITECTURE` to use new value ([#1070](https://github.com/rapidsai/cuspatial/pull/1070)) [@isVoid](https://github.com/isVoid) +- Bug fix in `pairwise_linestring_intersection` ([#1069](https://github.com/rapidsai/cuspatial/pull/1069)) [@isVoid](https://github.com/isVoid) + +## 📖 Documentation + +- Add documentation for `pairwise_linestring_polygon_distance`, `pairwise_polygon_distance` ([#1145](https://github.com/rapidsai/cuspatial/pull/1145)) [@isVoid](https://github.com/isVoid) +- Make User Guide appear in Docs page header ([#1133](https://github.com/rapidsai/cuspatial/pull/1133)) [@jarmak-nv](https://github.com/jarmak-nv) +- Add Hausdorff Clustering Notebooks ([#922](https://github.com/rapidsai/cuspatial/pull/922)) [@isVoid](https://github.com/isVoid) + +## 🚀 New Features + +- Add Benchmark to `pairwise_linestring_polygon_distance` ([#1153](https://github.com/rapidsai/cuspatial/pull/1153)) [@isVoid](https://github.com/isVoid) +- Adds `pairwise_point_polygon_distance` benchmark ([#1131](https://github.com/rapidsai/cuspatial/pull/1131)) [@isVoid](https://github.com/isVoid) +- Reorganize cuSpatial headers ([#1097](https://github.com/rapidsai/cuspatial/pull/1097)) [@harrism](https://github.com/harrism) +- Python API for `pairwise_polygon_distance` ([#1074](https://github.com/rapidsai/cuspatial/pull/1074)) [@isVoid](https://github.com/isVoid) +- Column API for `pairwise_polygon_distance` ([#1073](https://github.com/rapidsai/cuspatial/pull/1073)) [@isVoid](https://github.com/isVoid) +- Header only API for polygon-polygon distance ([#1065](https://github.com/rapidsai/cuspatial/pull/1065)) [@isVoid](https://github.com/isVoid) +- Python API for linestring polygon distance ([#1031](https://github.com/rapidsai/cuspatial/pull/1031)) [@isVoid](https://github.com/isVoid) +- Column API for linestring-polygon distance ([#1030](https://github.com/rapidsai/cuspatial/pull/1030)) [@isVoid](https://github.com/isVoid) + +## 🛠️ Improvements + +- Fix `cudf::column` constructor args ([#1151](https://github.com/rapidsai/cuspatial/pull/1151)) [@trxcllnt](https://github.com/trxcllnt) +- cuSpatial pip packages ([#1148](https://github.com/rapidsai/cuspatial/pull/1148)) [@trxcllnt](https://github.com/trxcllnt) +- Refactor `ST_Distance` header only API ([#1143](https://github.com/rapidsai/cuspatial/pull/1143)) [@isVoid](https://github.com/isVoid) +- Run docs nightly ([#1141](https://github.com/rapidsai/cuspatial/pull/1141)) [@AyodeAwe](https://github.com/AyodeAwe) +- Add `multilinestring_segment_manager` for segment related methods in multilinestring ranges ([#1134](https://github.com/rapidsai/cuspatial/pull/1134)) [@isVoid](https://github.com/isVoid) +- Improve zipcode counting notebook by adding GPU backed WKT parser ([#1130](https://github.com/rapidsai/cuspatial/pull/1130)) [@isVoid](https://github.com/isVoid) +- Delete add_issue_to_project.yml ([#1129](https://github.com/rapidsai/cuspatial/pull/1129)) [@jarmak-nv](https://github.com/jarmak-nv) +- Bump Gtest version following Rapids-cmake change ([#1126](https://github.com/rapidsai/cuspatial/pull/1126)) [@isVoid](https://github.com/isVoid) +- Refactor ST_Distance Column API and Cython ([#1124](https://github.com/rapidsai/cuspatial/pull/1124)) [@isVoid](https://github.com/isVoid) +- Reorganize src, tests, and benchmarks ([#1115](https://github.com/rapidsai/cuspatial/pull/1115)) [@harrism](https://github.com/harrism) +- Add Legal Terms to Trajectory Clustering Notebook ([#1111](https://github.com/rapidsai/cuspatial/pull/1111)) [@isVoid](https://github.com/isVoid) +- Enable sccache hits from local builds ([#1109](https://github.com/rapidsai/cuspatial/pull/1109)) [@AyodeAwe](https://github.com/AyodeAwe) +- Revert to branch-23.06 for shared-action-workflows ([#1107](https://github.com/rapidsai/cuspatial/pull/1107)) [@shwina](https://github.com/shwina) +- Update minimum Python version to Python 3.9 ([#1089](https://github.com/rapidsai/cuspatial/pull/1089)) [@shwina](https://github.com/shwina) +- Remove usage of rapids-get-rapids-version-from-git ([#1088](https://github.com/rapidsai/cuspatial/pull/1088)) [@jjacobelli](https://github.com/jjacobelli) +- Add `contains`predicate. ([#1086](https://github.com/rapidsai/cuspatial/pull/1086)) [@thomcom](https://github.com/thomcom) +- Binary Predicate Test Dispatching ([#1085](https://github.com/rapidsai/cuspatial/pull/1085)) [@thomcom](https://github.com/thomcom) +- Move `experimental` headers into main `include/cuspatial` directory ([#1081](https://github.com/rapidsai/cuspatial/pull/1081)) [@harrism](https://github.com/harrism) +- Update clang-format to 15.0.7 ([#1072](https://github.com/rapidsai/cuspatial/pull/1072)) [@bdice](https://github.com/bdice) +- Use ARC V2 self-hosted runners for GPU jobs ([#1066](https://github.com/rapidsai/cuspatial/pull/1066)) [@jjacobelli](https://github.com/jjacobelli) +- Implement and Test All non-multi-Feature Spatial Predicate Combinations ([#1064](https://github.com/rapidsai/cuspatial/pull/1064)) [@thomcom](https://github.com/thomcom) +- Reduced equals time and fixed a bug. ([#1051](https://github.com/rapidsai/cuspatial/pull/1051)) [@thomcom](https://github.com/thomcom) +- use make_device_vector in pairwise_point_in_polygon_test ([#1049](https://github.com/rapidsai/cuspatial/pull/1049)) [@cwharris](https://github.com/cwharris) +- Use thrust::host_vector instead of std::vector<bool> in tests ([#1048](https://github.com/rapidsai/cuspatial/pull/1048)) [@cwharris](https://github.com/cwharris) +- Branch 23.06 merge 23.04 (2) ([#1035](https://github.com/rapidsai/cuspatial/pull/1035)) [@harrism](https://github.com/harrism) +- Pairwise Multipoint Equals Count function ([#1022](https://github.com/rapidsai/cuspatial/pull/1022)) [@thomcom](https://github.com/thomcom) +- Branch 23.06 merge 23.04 ([#1021](https://github.com/rapidsai/cuspatial/pull/1021)) [@harrism](https://github.com/harrism) +- Add GTC 2023 Reverse GeoCoding Demo Notebook ([#1001](https://github.com/rapidsai/cuspatial/pull/1001)) [@thomcom](https://github.com/thomcom) +- Improve Hausdorff Many Column Performance ([#916](https://github.com/rapidsai/cuspatial/pull/916)) [@isVoid](https://github.com/isVoid) + # cuSpatial 23.04.00 (6 Apr 2023) ## 🚨 Breaking Changes From 34dc2a3c3a425f24e314ff35053407dc436c9d5f Mon Sep 17 00:00:00 2001 From: Ray Douglass <3107146+raydouglass@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:27:03 -0400 Subject: [PATCH 40/63] Fix update version (#1187) Updates `update-version.sh` to follow the pattern from https://github.com/rapidsai/cugraph/pull/3638 Required for `23.06` because `python/cuspatial/pyproject.py` does not exist thus breaking the script. This means any hotfixes to this version will have issues during release. Also updates a version in `cpp/doxygen/Doxyfile` which was outdated. Skipped CI since this script is not tested by CI. Authors: - Ray Douglass (https://github.com/raydouglass) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) --- ci/release/update-version.sh | 33 ++++++++++++++++++--------------- cpp/doxygen/Doxyfile | 2 +- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 3c5b99c73..64b22c463 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -56,23 +56,26 @@ sed_runner "s/VERSION_NUMBER=\".*/VERSION_NUMBER=\"${NEXT_SHORT_TAG}\"/g" ci/bui # Need to distutils-normalize the original version NEXT_SHORT_TAG_PEP440=$(python -c "from setuptools.extern import packaging; print(packaging.version.Version('${NEXT_SHORT_TAG}'))") - -# bump rapids libraries -for FILE in dependencies.yaml conda/environments/*.yaml; do - sed_runner "/- &cudf_conda cudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- cudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- cuml==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- rmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- libcudf==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} - sed_runner "/- librmm==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}\.*/g" ${FILE} +NEXT_FULL_TAG_PEP440=$(python -c "from setuptools.extern import packaging; print(packaging.version.Version('${NEXT_FULL_TAG}'))") + +DEPENDENCIES=( + cudf + cuml + libcudf + librmm + rmm +) + +for DEP in "${DEPENDENCIES[@]}"; do + for FILE in dependencies.yaml conda/environments/*.yaml; do + sed_runner "/-.* ${DEP}==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}.*/g" ${FILE} + done + sed_runner "s/${DEP}==.*\",/${DEP}==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.toml done +# Version in pyproject.toml +sed_runner "s/^version = .*/version = \"${NEXT_FULL_TAG_PEP440}\"/g" python/cuspatial/pyproject.toml + # Dependency versions in dependencies.yaml sed_runner "/-cu[0-9]\{2\}==/ s/==.*/==${NEXT_SHORT_TAG_PEP440}.*/g" dependencies.yaml -# Python pyproject.toml updates -sed_runner "s/^version = .*/version = \"${NEXT_FULL_TAG}\"/g" python/cuspatial/pyproject.toml - -# Dependency versions in pyproject.toml -sed_runner "s/cudf==.*\",/cudf==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.toml -sed_runner "s/rmm==.*\",/rmm==${NEXT_SHORT_TAG_PEP440}.*\",/g" python/cuspatial/pyproject.py diff --git a/cpp/doxygen/Doxyfile b/cpp/doxygen/Doxyfile index 1c66cb038..ba56ceb73 100644 --- a/cpp/doxygen/Doxyfile +++ b/cpp/doxygen/Doxyfile @@ -2171,7 +2171,7 @@ SKIP_FUNCTION_MACROS = YES # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = rmm.tag=https://docs.rapids.ai/api/librmm/22.10 "libcudf.tag=https://docs.rapids.ai/api/libcudf/22.10" +TAGFILES = rmm.tag=https://docs.rapids.ai/api/librmm/23.06 "libcudf.tag=https://docs.rapids.ai/api/libcudf/23.06" # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to From 400b310d997037597e14c4bf675f5f1c944a1128 Mon Sep 17 00:00:00 2001 From: Jake Awe <50372925+AyodeAwe@users.noreply.github.com> Date: Wed, 7 Jun 2023 16:50:37 -0500 Subject: [PATCH 41/63] use rapids-upload-docs script (#1181) This PR updates the `build_docs.sh` script to use the new consolidatory `rapids-upload-script` [shared script](https://github.com/rapidsai/gha-tools/pull/56). The shared script enables docs uploads to applicable S3 buckets for branch. nightly and PR builds. Authors: - Jake Awe (https://github.com/AyodeAwe) - AJ Schmidt (https://github.com/ajschmidt8) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1181 --- ci/build_docs.sh | 21 +++++++++++---------- ci/release/update-version.sh | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ci/build_docs.sh b/ci/build_docs.sh index 5ce3fad53..c4f318f26 100755 --- a/ci/build_docs.sh +++ b/ci/build_docs.sh @@ -19,7 +19,6 @@ rapids-print-env rapids-logger "Downloading artifacts from previous jobs" CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp) PYTHON_CHANNEL=$(rapids-download-conda-from-s3 python) -VERSION_NUMBER="23.08" rapids-mamba-retry install \ --channel "${CPP_CHANNEL}" \ @@ -27,21 +26,23 @@ rapids-mamba-retry install \ libcuspatial \ cuspatial -rapids-logger "Build Doxygen docs" +export RAPIDS_VERSION_NUMBER="23.08" +export RAPIDS_DOCS_DIR="$(mktemp -d)" + +rapids-logger "Build CPP docs" pushd cpp/doxygen doxygen Doxyfile +mkdir -p "${RAPIDS_DOCS_DIR}/libcuspatial/html" +mv html/* "${RAPIDS_DOCS_DIR}/libcuspatial/html" popd -rapids-logger "Build Sphinx docs" +rapids-logger "Build Python docs" pushd docs sphinx-build -b dirhtml source _html -W sphinx-build -b text source _text -W +mkdir -p "${RAPIDS_DOCS_DIR}/cuspatial/"{html,txt} +mv _html/* "${RAPIDS_DOCS_DIR}/cuspatial/html" +mv _text/* "${RAPIDS_DOCS_DIR}/cuspatial/txt" popd - -if [[ ${RAPIDS_BUILD_TYPE} != "pull-request" ]]; then - rapids-logger "Upload Docs to S3" - aws s3 sync --no-progress --delete docs/_html "s3://rapidsai-docs/cuspatial/${VERSION_NUMBER}/html" - aws s3 sync --no-progress --delete docs/_text "s3://rapidsai-docs/cuspatial/${VERSION_NUMBER}/txt" - aws s3 sync --no-progress --delete cpp/doxygen/html "s3://rapidsai-docs/libcuspatial/${VERSION_NUMBER}/html" -fi \ No newline at end of file +rapids-upload-docs diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 8b8d67021..3bd74f52f 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -52,7 +52,7 @@ sed_runner "/TAGFILES/ s|[0-9]\+.[0-9]\+|${NEXT_SHORT_TAG}|g" cpp/doxygen/Doxyfi for FILE in .github/workflows/*.yaml; do sed_runner "/shared-action-workflows/ s/@.*/@branch-${NEXT_SHORT_TAG}/g" "${FILE}" done -sed_runner "s/VERSION_NUMBER=\".*/VERSION_NUMBER=\"${NEXT_SHORT_TAG}\"/g" ci/build_docs.sh +sed_runner "s/RAPIDS_VERSION_NUMBER=\".*/RAPIDS_VERSION_NUMBER=\"${NEXT_SHORT_TAG}\"/g" ci/build_docs.sh # Need to distutils-normalize the original version NEXT_SHORT_TAG_PEP440=$(python -c "from setuptools.extern import packaging; print(packaging.version.Version('${NEXT_SHORT_TAG}'))") From 1d2c17422e4e4308d21ab868137be5f0670f7a6d Mon Sep 17 00:00:00 2001 From: "H. Thomson Comer" Date: Thu, 8 Jun 2023 09:17:30 -0500 Subject: [PATCH 42/63] Better support for binary predicates with large inputs. (#1166) Closes #1142 This PR adds a few bugfixes and optimizations that improve performance when large `GeoSeries` are used with binary predicates. It also corrects a few errors in the predicate logic that were revealed when the size of the feature space increased by combining all possible features in the `dispatch_list`. Changes: `contains.py` - Add `pairwise_point_in_polygon` and steps to resemble `quadtree` results. `contains_geometry_processor.py` - Drop `is True` and add a TODO for future optimization. `feature_contains.py` - Refactor `_compute_polygon_linestring_contains` to handle `GeoSeries` containing `LineStrings` of varying lengths. `feature_contains_properly.py` - Add `pairwise_point_in_polygon` as default mode with documentation. - Add `PointMultiPointContains` which is needed by internal methods. `feature_crosses.py` - Drop extraneous `intersection` `feature_disjoint.py` - Add `PointPointDisjoint` and drop extraneous `intersections`. `feature_equals.py` - Fix LineStringLineStringEquals which wasn't properly handling LineStrings with varying lengths. `feature_intersects.py` - Drop extraneous `intersection` `feature_touches.py` - Fix LineStringLineStringTouches. It is slow and needs further optimization. - Fix PolygonPolygonTouches. It is also slow and needs further optimization. `geoseries.py` - Drop index from `input_types`. - Fix `point_indices` for `Point` type. - Optimize `reset_index` which was doing a host->device copy. `binpred_test_dispatch.py` - Add test case `test_binpred_large_examples.py` - Test large sets of all the dispatched tests together. `test_equals_only_binpreds.py` - Test corrections to input_types indexes. `test_binpred_large_examples.py` - Use the features from `test_dispatch` to create large `GeoSeries` and compare results with `GeoPandas`. `test_feature_groups.py` - Test each of the `dispatch_list` feature sets combined into a single GeoSeries. `binpred_utils.py` - Don't count hits when point and polygon indexes don't match (a bug in `_basic_contains_count`). - Optimize mask generation in `_points_and_lines_to_multipoints` `column_utils.py` - Optimize `contains_only` calls. Authors: - H. Thomson Comer (https://github.com/thomcom) Approvers: - Mark Harris (https://github.com/harrism) - Michael Wang (https://github.com/isVoid) URL: https://github.com/rapidsai/cuspatial/pull/1166 --- .../cuspatial/core/binpreds/contains.py | 77 ++++++++++++++---- .../binpreds/contains_geometry_processor.py | 6 +- .../core/binpreds/feature_contains.py | 71 ++++++++++------ .../binpreds/feature_contains_properly.py | 53 +++++++++--- .../core/binpreds/feature_crosses.py | 11 +-- .../core/binpreds/feature_disjoint.py | 17 ++-- .../cuspatial/core/binpreds/feature_equals.py | 5 +- .../core/binpreds/feature_intersects.py | 19 ++--- .../core/binpreds/feature_touches.py | 17 +++- python/cuspatial/cuspatial/core/geoseries.py | 18 +++-- .../tests/binpreds/binpred_test_dispatch.py | 13 +++ .../test_binpred_cartesian_dispatch_list.py | 80 +++++++++++++++++++ .../test_binpred_each_dispatch_list.py | 73 +++++++++++++++++ .../binpreds/test_equals_only_binpreds.py | 25 ++++++ .../cuspatial/utils/binpred_utils.py | 12 ++- .../cuspatial/cuspatial/utils/column_utils.py | 20 ++--- 16 files changed, 410 insertions(+), 107 deletions(-) create mode 100644 python/cuspatial/cuspatial/tests/binpreds/test_binpred_cartesian_dispatch_list.py create mode 100644 python/cuspatial/cuspatial/tests/binpreds/test_binpred_each_dispatch_list.py diff --git a/python/cuspatial/cuspatial/core/binpreds/contains.py b/python/cuspatial/cuspatial/core/binpreds/contains.py index 398f134ff..8111074a5 100644 --- a/python/cuspatial/cuspatial/core/binpreds/contains.py +++ b/python/cuspatial/cuspatial/core/binpreds/contains.py @@ -2,10 +2,14 @@ from math import ceil, sqrt +import cudf from cudf import DataFrame, Series from cudf.core.column import as_column import cuspatial +from cuspatial._lib.pairwise_point_in_polygon import ( + pairwise_point_in_polygon as cpp_pairwise_point_in_polygon, +) from cuspatial._lib.point_in_polygon import ( point_in_polygon as cpp_byte_point_in_polygon, ) @@ -35,7 +39,7 @@ def _quadtree_contains_properly(points, polygons): within its corresponding polygon. """ - scale = -1 + # Set the scale to the default minimum scale without triggering a warning. max_depth = 15 min_size = ceil(sqrt(len(points))) if len(polygons) == 0: @@ -44,6 +48,7 @@ def _quadtree_contains_properly(points, polygons): x_min = polygons.polygons.x.min() y_max = polygons.polygons.y.max() y_min = polygons.polygons.y.min() + scale = max(x_max - x_min, y_max - y_min) / ((1 << max_depth) + 2) point_indices, quadtree = cuspatial.quadtree_on_points( points, x_min, @@ -115,24 +120,64 @@ def _brute_force_contains_properly(points, polygons): return final_result -def contains_properly(polygons, points, quadtree=True): - if quadtree: +def _pairwise_contains_properly(points, polygons): + """Compute from a series of polygons and an equal-length series of points + which points are properly contained within the corresponding polygon. + Polygon A contains Point B properly if B intersects the interior of A + but not the boundary (or exterior). + + Note that polygons must be closed: the first and last vertex of each + polygon must be the same. + + + Parameters + ---------- + points : GeoSeries + A GeoSeries of points. + polygons : GeoSeries + A GeoSeries of polygons. + + Returns + ------- + result : cudf.DataFrame + A DataFrame of boolean values indicating whether each point falls + within its corresponding polygon. + """ + result_column = cpp_pairwise_point_in_polygon( + as_column(points.points.x), + as_column(points.points.y), + as_column(polygons.polygons.part_offset), + as_column(polygons.polygons.ring_offset), + as_column(polygons.polygons.x), + as_column(polygons.polygons.y), + ) + # Pairwise returns a boolean column with a True value for each (polygon, + # point) pair where the point is contained properly by the polygon. We can + # use this to create a dataframe with only (polygon, point) pairs that + # satisfy the relationship. + pip_result = cudf.Series(result_column, dtype="bool") + trues = pip_result[pip_result].index + true_pairs = cudf.DataFrame( + { + "pairwise_index": trues, + "point_index": trues, + "result": True, + } + ) + return true_pairs + + +def contains_properly(polygons, points, mode="pairwise"): + if mode == "quadtree": return _quadtree_contains_properly(points, polygons) + elif mode == "pairwise": + return _pairwise_contains_properly(points, polygons) else: # Use stack to convert the result to the same shape as quadtree's # result, name the columns appropriately, and return the # two-column DataFrame. bitmask_result = _brute_force_contains_properly(points, polygons) - quadtree_shaped_result = bitmask_result.stack().reset_index() - quadtree_shaped_result.columns = [ - "point_index", - "part_index", - "result", - ] - result = quadtree_shaped_result[["point_index", "part_index"]][ - quadtree_shaped_result["result"] - ] - result = result.sort_values(["point_index", "part_index"]).reset_index( - drop=True - ) - return result + bitmask_result_df = bitmask_result.stack().reset_index() + trues = bitmask_result_df[bitmask_result_df[0]] + trues.columns = ["point_index", "part_index", "result"] + return trues diff --git a/python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py b/python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py index 12b2fc37d..8a1996613 100644 --- a/python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py +++ b/python/cuspatial/cuspatial/core/binpreds/contains_geometry_processor.py @@ -49,10 +49,10 @@ def _preprocess_multipoint_rhs(self, lhs, rhs): if contains_only_linestrings(rhs): # condition for linestrings geom = rhs.lines - elif contains_only_polygons(rhs) is True: + elif contains_only_polygons(rhs): # polygon in polygon geom = rhs.polygons - elif contains_only_multipoints(rhs) is True: + elif contains_only_multipoints(rhs): # mpoint in polygon geom = rhs.multipoints else: @@ -150,6 +150,7 @@ def _reindex_allpairs(self, lhs, op_result) -> DataFrame: # once their index is converted to a polygon index. allpairs_result = polygon_indices.drop_duplicates() + # TODO: This is slow and needs optimization # Replace the polygon index with the original index allpairs_result["polygon_index"] = allpairs_result[ "polygon_index" @@ -212,7 +213,6 @@ def _postprocess_multipoint_rhs( result_df = hits.reset_index().merge( expected_count.reset_index(), on="rhs_index" ) - # Handling for the basic predicates if mode == "basic_none": none_result = _true_series(len(rhs)) diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_contains.py b/python/cuspatial/cuspatial/core/binpreds/feature_contains.py index 562ce03b7..0617c12b3 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_contains.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_contains.py @@ -78,38 +78,57 @@ def _compute_polygon_polygon_contains(self, lhs, rhs, preprocessor_result): # A closed polygon has an extra line segment that is not used in # counting the number of points. We need to subtract this from the # number of points in the polygon. - polygon_size_reduction = rhs.polygons.part_offset.take( - rhs.polygons.geometry_offset[1:] - ) - rhs.polygons.part_offset.take(rhs.polygons.geometry_offset[:-1]) - return contains + intersects >= rhs.sizes - polygon_size_reduction + multipolygon_part_offset = rhs.polygons.part_offset.take( + rhs.polygons.geometry_offset + ) + polygon_size_reduction = ( + multipolygon_part_offset[1:] - multipolygon_part_offset[:-1] + ) + result = contains + intersects >= rhs.sizes - polygon_size_reduction + return result + + def _test_interior(self, lhs, rhs): + # We only need to test linestrings that are length 2. + # Divide the linestring in half and test the point for containment + # in the polygon. + size_two = rhs.sizes == 2 + if (size_two).any(): + center_points = _linestrings_to_center_point(rhs[size_two]) + size_two_results = _false_series(len(lhs)) + size_two_results.iloc[rhs.index[size_two]] = ( + _basic_contains_count(lhs, center_points) > 0 + ) + return size_two_results + else: + return _false_series(len(lhs)) def _compute_polygon_linestring_contains( self, lhs, rhs, preprocessor_result ): contains = _basic_contains_count(lhs, rhs).reset_index(drop=True) intersects = self._intersection_results_for_contains(lhs, rhs) - if (contains == 0).all() and (intersects != 0).all(): - # The hardest case. We need to check if the linestring is - # contained in the boundary of the polygon, the interior, - # or the exterior. - # We only need to test linestrings that are length 2. - # Divide the linestring in half and test the point for containment - # in the polygon. - - if (rhs.sizes == 2).any(): - center_points = _linestrings_to_center_point( - rhs[rhs.sizes == 2] - ) - size_two_results = _false_series(len(lhs)) - size_two_results[rhs.sizes == 2] = ( - _basic_contains_count(lhs, center_points) > 0 - ) - return size_two_results - else: - line_intersections = _false_series(len(lhs)) - line_intersections[intersects == rhs.sizes] = True - return line_intersections - return contains + intersects >= rhs.sizes + + # If a linestring has intersection but not containment, we need to + # test if the linestring is in the interior of the polygon. + final_result = _false_series(len(lhs)) + intersection_with_no_containment = (contains == 0) & (intersects != 0) + interior_tests = self._test_interior( + lhs[intersection_with_no_containment].reset_index(drop=True), + rhs[intersection_with_no_containment].reset_index(drop=True), + ) + interior_tests.index = intersection_with_no_containment[ + intersection_with_no_containment + ].index + # LineStrings that have intersection but no containment are set + # according to the `intersection_with_no_containment` mask. + final_result[intersection_with_no_containment] = interior_tests + # LineStrings that do not are contained if the sum of intersecting + # and containing points is greater than or equal to the number of + # points that make up the linestring. + final_result[~intersection_with_no_containment] = ( + contains + intersects >= rhs.sizes + ) + return final_result def _compute_predicate(self, lhs, rhs, preprocessor_result): if contains_only_points(rhs): diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py b/python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py index 0c81ead59..04fb5788c 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_contains_properly.py @@ -2,6 +2,10 @@ from typing import TypeVar +import cupy as cp + +import cudf + from cuspatial.core.binpreds.basic_predicates import ( _basic_equals_all, _basic_intersects, @@ -60,7 +64,7 @@ def _preprocess(self, lhs, rhs): preprocessor_result = super()._preprocess_multipoint_rhs(lhs, rhs) return self._compute_predicate(lhs, rhs, preprocessor_result) - def _should_use_quadtree(self, lhs): + def _pip_mode(self, lhs, rhs): """Determine if the quadtree should be used for the binary predicate. Returns @@ -70,18 +74,21 @@ def _should_use_quadtree(self, lhs): Notes ----- - 1. Quadtree is always used if user requests `allpairs=True`. - 2. If the number of polygons in the lhs is less than 32, we use the + 1. If the number of polygons in the lhs is less than 32, we use the brute-force algorithm because it is faster and has less memory overhead. - 3. If the lhs contains more than 32 polygons, we use the quadtree - because it does not have a polygon-count limit. - 4. If the lhs contains multipolygons, we use quadtree because the - performance between quadtree and brute-force is similar, but - code complexity would be higher if we did multipolygon - reconstruction on both code paths. + 2. If the lhs contains multipolygons, or `allpairs=True` is specified, + we use quadtree because the quadtree code path already handles + multipolygons. + 3. Otherwise default to pairwise to match the default GeoPandas + behavior. """ - return len(lhs) >= 32 or has_multipolygons(lhs) or self.config.allpairs + if len(lhs) <= 31: + return "brute_force" + elif self.config.allpairs or has_multipolygons(lhs): + return "quadtree" + else: + return "pairwise" def _compute_predicate( self, @@ -97,10 +104,30 @@ def _compute_predicate( raise TypeError( "`.contains` can only be called with polygon series." ) - use_quadtree = self._should_use_quadtree(lhs) + mode = self._pip_mode(lhs, preprocessor_result.final_rhs) + lhs_indices = lhs.index + # Duplicates the lhs polygon for each point in the final_rhs result + # that was computed by _preprocess. Will always ensure that the + # number of points in the rhs is equal to the number of polygons in the + # lhs. + if mode == "pairwise": + lhs_indices = preprocessor_result.point_indices pip_result = contains_properly( - lhs, preprocessor_result.final_rhs, quadtree=use_quadtree + lhs[lhs_indices], preprocessor_result.final_rhs, mode=mode ) + # If the mode is pairwise or brute_force, we need to replace the + # `pairwise_index` of each repeated polygon with the `part_index` + # from the preprocessor result. + if "pairwise_index" in pip_result.columns: + pairwise_index_df = cudf.DataFrame( + { + "pairwise_index": cp.arange(len(lhs_indices)), + "part_index": rhs.point_indices, + } + ) + pip_result = pip_result.merge( + pairwise_index_df, on="pairwise_index" + )[["part_index", "point_index"]] op_result = ContainsOpResult(pip_result, preprocessor_result) return self._postprocess(lhs, rhs, preprocessor_result, op_result) @@ -168,7 +195,7 @@ def _preprocess(self, lhs, rhs): left and right hand side types. """ DispatchDict = { (Point, Point): ContainsProperlyByIntersection, - (Point, MultiPoint): ImpossiblePredicate, + (Point, MultiPoint): ContainsProperlyByIntersection, (Point, LineString): ImpossiblePredicate, (Point, Polygon): ImpossiblePredicate, (MultiPoint, Point): NotImplementedPredicate, diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py b/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py index 0316f3cbd..f9b8505e2 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_crosses.py @@ -44,11 +44,12 @@ def _compute_predicate(self, lhs, rhs, preprocessor_result): # intersection are in the boundary of the other pli = _basic_intersects_pli(rhs, lhs) intersections = _points_and_lines_to_multipoints(pli[1], pli[0]) - equals = (_basic_equals_count(intersections, lhs) > 0) | ( - _basic_equals_count(intersections, rhs) > 0 - ) - intersects = _basic_intersects_count(rhs, lhs) > 0 - return intersects & ~equals + equals_lhs_count = _basic_equals_count(intersections, lhs) + equals_rhs_count = _basic_equals_count(intersections, rhs) + equals_lhs = equals_lhs_count != intersections.sizes + equals_rhs = equals_rhs_count != intersections.sizes + equals = equals_lhs & equals_rhs + return equals class LineStringPolygonCrosses(BinPred): diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py b/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py index a0347b76a..2ada86abb 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_disjoint.py @@ -2,6 +2,7 @@ from cuspatial.core.binpreds.basic_predicates import ( _basic_contains_any, + _basic_equals_any, _basic_intersects, ) from cuspatial.core.binpreds.binpred_interface import ( @@ -23,13 +24,17 @@ def _preprocess(self, lhs, rhs): and then negate the result. Used by: - (Point, Point) (Point, Polygon) (Polygon, Point) """ return ~_basic_contains_any(lhs, rhs) +class PointPointDisjoint(BinPred): + def _preprocess(self, lhs, rhs): + return ~_basic_equals_any(lhs, rhs) + + class PointLineStringDisjoint(BinPred): def _preprocess(self, lhs, rhs): """Disjoint is the opposite of intersects, so just implement intersects @@ -40,9 +45,7 @@ def _preprocess(self, lhs, rhs): class PointPolygonDisjoint(BinPred): def _preprocess(self, lhs, rhs): - intersects = _basic_intersects(lhs, rhs) - contains = _basic_contains_any(lhs, rhs) - return ~intersects & ~contains + return ~_basic_contains_any(lhs, rhs) class LineStringPointDisjoint(PointLineStringDisjoint): @@ -61,9 +64,7 @@ def _postprocess(self, lhs, rhs, op_result): class LineStringPolygonDisjoint(BinPred): def _preprocess(self, lhs, rhs): - intersects = _basic_intersects(lhs, rhs) - contains = _basic_contains_any(rhs, lhs) - return ~intersects & ~contains + return ~_basic_contains_any(rhs, lhs) class PolygonPolygonDisjoint(BinPred): @@ -72,7 +73,7 @@ def _preprocess(self, lhs, rhs): DispatchDict = { - (Point, Point): DisjointByWayOfContains, + (Point, Point): PointPointDisjoint, (Point, MultiPoint): NotImplementedPredicate, (Point, LineString): PointLineStringDisjoint, (Point, Polygon): PointPolygonDisjoint, diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_equals.py b/python/cuspatial/cuspatial/core/binpreds/feature_equals.py index bf6997e0a..0bf109980 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_equals.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_equals.py @@ -324,8 +324,11 @@ def _compute_predicate(self, lhs, rhs, preprocessor_result): lhs_reversed, rhs_lengths_equal.lines.xy ) result = forward_result | reverse_result + original_point_indices = cudf.Series( + lhs_lengths_equal.point_indices + ).replace(cudf.Series(lhs_lengths_equal.index)) return self._postprocess( - lhs, rhs, EqualsOpResult(result, lhs_lengths_equal.point_indices) + lhs, rhs, EqualsOpResult(result, original_point_indices) ) diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py b/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py index c35947826..25c463b7c 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_intersects.py @@ -92,16 +92,12 @@ class IntersectsByEquals(EqualsPredicateBase): class PolygonPointIntersects(BinPred): def _preprocess(self, lhs, rhs): - contains = _basic_contains_any(lhs, rhs) - intersects = _basic_intersects(lhs, rhs) - return contains | intersects + return _basic_contains_any(lhs, rhs) class PointPolygonIntersects(BinPred): def _preprocess(self, lhs, rhs): - contains = _basic_contains_any(rhs, lhs) - intersects = _basic_intersects(rhs, lhs) - return contains | intersects + return _basic_contains_any(rhs, lhs) class LineStringPointIntersects(IntersectsPredicateBase): @@ -117,25 +113,20 @@ def _preprocess(self, lhs, rhs): class LineStringPolygonIntersects(BinPred): def _preprocess(self, lhs, rhs): - intersects = _basic_intersects(lhs, rhs) - contains = _basic_contains_any(rhs, lhs) - return intersects | contains + return _basic_contains_any(rhs, lhs) class PolygonLineStringIntersects(BinPred): def _preprocess(self, lhs, rhs): - intersects = _basic_intersects(lhs, rhs) - contains = _basic_contains_any(lhs, rhs) - return intersects | contains + return _basic_contains_any(lhs, rhs) class PolygonPolygonIntersects(BinPred): def _preprocess(self, lhs, rhs): - intersects = _basic_intersects(lhs, rhs) contains_rhs = _basic_contains_any(rhs, lhs) contains_lhs = _basic_contains_any(lhs, rhs) - return intersects | contains_rhs | contains_lhs + return contains_rhs | contains_lhs """ Type dispatch dictionary for intersects binary predicates. """ diff --git a/python/cuspatial/cuspatial/core/binpreds/feature_touches.py b/python/cuspatial/cuspatial/core/binpreds/feature_touches.py index c1ddc1312..d76dc6200 100644 --- a/python/cuspatial/cuspatial/core/binpreds/feature_touches.py +++ b/python/cuspatial/cuspatial/core/binpreds/feature_touches.py @@ -92,7 +92,7 @@ def _preprocess(self, lhs, rhs): equals_lhs = _basic_equals_count(points, lhs) > 0 equals_rhs = _basic_equals_count(points, rhs) > 0 touches = point_intersection & (equals_lhs | equals_rhs) - return touches + return touches & ~lhs.crosses(rhs) class LineStringPolygonTouches(BinPred): @@ -127,9 +127,20 @@ class PolygonPolygonTouches(BinPred): def _preprocess(self, lhs, rhs): contains_lhs_none = _basic_contains_count(lhs, rhs) == 0 contains_rhs_none = _basic_contains_count(rhs, lhs) == 0 + contains_lhs = lhs.contains(rhs) + contains_rhs = rhs.contains(lhs) equals = lhs.geom_equals(rhs) - intersects = _basic_intersects_count(lhs, rhs) > 0 - return ~equals & contains_lhs_none & contains_rhs_none & intersects + intersect_count = _basic_intersects_count(lhs, rhs) + intersects = (intersect_count > 0) & (intersect_count < rhs.sizes - 1) + result = ( + ~equals + & contains_lhs_none + & contains_rhs_none + & ~contains_lhs + & ~contains_rhs + & intersects + ) + return result DispatchDict = { diff --git a/python/cuspatial/cuspatial/core/geoseries.py b/python/cuspatial/cuspatial/core/geoseries.py index c13b673ed..2a66ccec3 100644 --- a/python/cuspatial/cuspatial/core/geoseries.py +++ b/python/cuspatial/cuspatial/core/geoseries.py @@ -109,7 +109,7 @@ def __init__( @property def feature_types(self): - return self._column._meta.input_types + return self._column._meta.input_types.reset_index(drop=True) @property def type(self): @@ -251,7 +251,9 @@ def point_indices(self): sizes = offsets[1:] - offsets[:-1] return cp.repeat(self._series.index, sizes) """ - return self._meta.input_types.index[self._meta.input_types != -1] + return self._meta.input_types.reset_index(drop=True).index[ + self._meta.input_types != -1 + ] def column(self): """Return the ListColumn reordered by union offset.""" @@ -323,8 +325,7 @@ def point_indices(self): self.geometry_offset ) sizes = offsets[1:] - offsets[:-1] - - return self._series.index.repeat(sizes).values + return self._meta.input_types.index.repeat(sizes) @property def points(self): @@ -403,6 +404,13 @@ def __getitem__(self, indexes): union_offsets = self._sr._column._meta.union_offsets.iloc[indexes] union_types = self._sr._column._meta.input_types.iloc[indexes] + # Very important to reset the index if it has been constructed from + # a slice. + if isinstance(union_offsets, cudf.Series): + union_offsets = union_offsets.reset_index(drop=True) + if isinstance(union_types, cudf.Series): + union_types = union_types.reset_index(drop=True) + points = self._sr._column.points mpoints = self._sr._column.mpoints lines = self._sr._column.lines @@ -967,7 +975,7 @@ def reset_index( # and use `cudf` reset_index to identify what our result # should look like. cudf_series = cudf.Series( - np.arange(len(geo_series.index)), index=geo_series.index + cp.arange(len(geo_series.index)), index=geo_series.index ) cudf_result = cudf_series.reset_index(level, drop, name, inplace) diff --git a/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py b/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py index 55ceeaea3..a5a62e238 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py +++ b/python/cuspatial/cuspatial/tests/binpreds/binpred_test_dispatch.py @@ -171,6 +171,18 @@ def predicate(request): LineString([(0.5, 0.0), (0.5, 1.0)]), LineString([(0.0, 0.5), (1.0, 0.5)]), ), + "linestring-linestring-touch-and-cross": ( + """ + x + | + x + |\\ + x---x + x + """, + LineString([(0.0, 0.0), (1.0, 1.0)]), + LineString([(0.5, 0.5), (1.0, 0.1), (-1.0, 0.1)]), + ), "linestring-polygon-disjoint": ( """ point_polygon above is drawn as @@ -493,6 +505,7 @@ def predicate(request): "linestring-linestring-touch-edge", "linestring-linestring-touch-edge-twice", "linestring-linestring-crosses", + "linestring-linestring-touch-and-cross", ] linestring_polygon_dispatch_list = [ diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_binpred_cartesian_dispatch_list.py b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_cartesian_dispatch_list.py new file mode 100644 index 000000000..772853ef2 --- /dev/null +++ b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_cartesian_dispatch_list.py @@ -0,0 +1,80 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +import geopandas +import numpy as np +from binpred_test_dispatch import ( # noqa: F401 + features, + linestring_linestring_dispatch_list, + linestring_polygon_dispatch_list, + point_linestring_dispatch_list, + point_point_dispatch_list, + point_polygon_dispatch_list, + polygon_polygon_dispatch_list, + predicate, +) + +import cuspatial + + +def sample_test_data(features, dispatch_list, size, lib=cuspatial): + """Creates either a cuspatial or geopandas GeoSeries object using the + Feature objects in `features`, the list of features to sample from in + `dispatch_list`, and the size of the resultant GeoSeries. + """ + geometry_tuples = [features[key][1:3] for key in dispatch_list] + geometries = [ + [lhs_geo for lhs_geo, _ in geometry_tuples], + [rhs_geo for _, rhs_geo in geometry_tuples], + ] + lhs = lib.GeoSeries(list(geometries[0])) + rhs = lib.GeoSeries(list(geometries[1])) + lhs_picks = np.repeat(np.arange(len(lhs)), len(lhs)) + rhs_picks = np.tile(np.arange(len(rhs)), len(rhs)) + return ( + lhs[lhs_picks].reset_index(drop=True), + rhs[rhs_picks].reset_index(drop=True), + ) + + +def run_test(pred, dispatch_list): + size = 10000 + lhs, rhs = sample_test_data(features, dispatch_list, size, cuspatial) + gpdlhs, gpdrhs = sample_test_data(features, dispatch_list, size, geopandas) + + # Reverse + pred_fn = getattr(rhs, pred) + got = pred_fn(lhs) + gpd_pred_fn = getattr(gpdrhs, pred) + expected = gpd_pred_fn(gpdlhs) + assert (got.values_host == expected.values).all() + + # Forward + pred_fn = getattr(lhs, pred) + got = pred_fn(rhs) + gpd_pred_fn = getattr(gpdlhs, pred) + expected = gpd_pred_fn(gpdrhs) + assert (got.values_host == expected.values).all() + + +def test_point_point_large_examples(predicate): # noqa: F811 + run_test(predicate, point_point_dispatch_list) + + +def test_point_linestring_large_examples(predicate): # noqa: F811 + run_test(predicate, point_linestring_dispatch_list) + + +def test_point_polygon_large_examples(predicate): # noqa: F811 + run_test(predicate, point_polygon_dispatch_list) + + +def test_linestring_linestring_large_examples(predicate): # noqa: F811 + run_test(predicate, linestring_linestring_dispatch_list) + + +def test_linestring_polygon_large_examples(predicate): # noqa: F811 + run_test(predicate, linestring_polygon_dispatch_list) + + +def test_polygon_polygon_large_examples(predicate): # noqa: F811 + run_test(predicate, polygon_polygon_dispatch_list) diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_binpred_each_dispatch_list.py b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_each_dispatch_list.py new file mode 100644 index 000000000..9f7aa3219 --- /dev/null +++ b/python/cuspatial/cuspatial/tests/binpreds/test_binpred_each_dispatch_list.py @@ -0,0 +1,73 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + +import geopandas +from binpred_test_dispatch import ( # noqa: F401 + features, + linestring_linestring_dispatch_list, + linestring_polygon_dispatch_list, + point_linestring_dispatch_list, + point_point_dispatch_list, + point_polygon_dispatch_list, + polygon_polygon_dispatch_list, + predicate, +) + +import cuspatial + + +def sample_test_data(features, dispatch_list, lib=cuspatial): + """Creates either a cuSpatial or geopandas GeoSeries object using the + features in `features` and the list of features to sample from + `dispatch_list`. + """ + geometry_tuples = [features[key][1:3] for key in dispatch_list] + geometries = [ + [lhs_geo for lhs_geo, _ in geometry_tuples], + [rhs_geo for _, rhs_geo in geometry_tuples], + ] + lhs = lib.GeoSeries(list(geometries[0])) + rhs = lib.GeoSeries(list(geometries[1])) + return (lhs, rhs) + + +def run_test(pred, dispatch_list): + lhs, rhs = sample_test_data(features, dispatch_list, cuspatial) + gpdlhs, gpdrhs = sample_test_data(features, dispatch_list, geopandas) + + # Reverse + pred_fn = getattr(rhs, pred) + got = pred_fn(lhs) + gpd_pred_fn = getattr(gpdrhs, pred) + expected = gpd_pred_fn(gpdlhs) + assert (got.values_host == expected.values).all() + + # Forward + pred_fn = getattr(lhs, pred) + got = pred_fn(rhs) + gpd_pred_fn = getattr(gpdlhs, pred) + expected = gpd_pred_fn(gpdrhs) + assert (got.values_host == expected.values).all() + + +def test_point_point_all_examples(predicate): # noqa: F811 + run_test(predicate, point_point_dispatch_list) + + +def test_point_linestring_all_examples(predicate): # noqa: F811 + run_test(predicate, point_linestring_dispatch_list) + + +def test_point_polygon_all_examples(predicate): # noqa: F811 + run_test(predicate, point_polygon_dispatch_list) + + +def test_linestring_linestring_all_examples(predicate): # noqa: F811 + run_test(predicate, linestring_linestring_dispatch_list) + + +def test_linestring_polygon_all_examples(predicate): # noqa: F811 + run_test(predicate, linestring_polygon_dispatch_list) + + +def test_polygon_polygon_all_examples(predicate): # noqa: F811 + run_test(predicate, polygon_polygon_dispatch_list) diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py b/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py index 47a07bee9..7aec17920 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_equals_only_binpreds.py @@ -722,3 +722,28 @@ def test_linestring_orders(): got = linestring1.geom_equals(linestring2) expected = gpdlinestring1.geom_equals(gpdlinestring2) pd.testing.assert_series_equal(expected, got.to_pandas()) + + +def test_linestring_indexes(): + linestring1 = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 0), (1, 1), (0, 0)]), + LineString([(0, 0), (1, 1), (1, 0), (0, 0)]), + ] + ) + linestring2 = cuspatial.GeoSeries( + [ + LineString([(0, 0), (1, 0), (1, 1), (0, 0)]), + LineString([(0, 0), (1, 1), (1, 0), (0, 0)]), + ] + ) + index1 = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] + index2 = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] + linestring1 = linestring1[index1].reset_index(drop=True) + linestring2 = linestring2[index2].reset_index(drop=True) + + gpdlinestring1 = linestring1.to_geopandas() + gpdlinestring2 = linestring2.to_geopandas() + got = linestring1.geom_equals(linestring2) + expected = gpdlinestring1.geom_equals(gpdlinestring2) + pd.testing.assert_series_equal(expected, got.to_pandas()) diff --git a/python/cuspatial/cuspatial/utils/binpred_utils.py b/python/cuspatial/cuspatial/utils/binpred_utils.py index 22b495513..42bb48f5e 100644 --- a/python/cuspatial/cuspatial/utils/binpred_utils.py +++ b/python/cuspatial/cuspatial/utils/binpred_utils.py @@ -7,6 +7,7 @@ import cuspatial from cuspatial.core._column.geocolumn import ColumnType +from cuspatial.core._column.geometa import Feature_Enum """Column-Type objects to use for simple syntax in the `DispatchDict` contained in each `feature_.py` file. For example, instead of writing out @@ -61,7 +62,12 @@ def _count_results_in_multipoint_geometries(point_indices, point_result): index=cudf.RangeIndex(len(point_indices), name="point_index"), ).reset_index() with_rhs_indices = point_result.merge(point_indices_df, on="point_index") - points_grouped_by_original_polygon = with_rhs_indices[ + # Because we are doing pairwise operations, we're only interested in the + # results where polygon_index and rhs_index match + pairwise_matches = with_rhs_indices[ + with_rhs_indices["polygon_index"] == with_rhs_indices["rhs_index"] + ] + points_grouped_by_original_polygon = pairwise_matches[ ["point_index", "rhs_index"] ].drop_duplicates() hits = ( @@ -348,8 +354,8 @@ def _points_and_lines_to_multipoints(geoseries, offsets): 1 MULTIPOINT (3.00000 3.00000, 4.00000, 4.0000, ... dtype: geometry """ - points_mask = geoseries.type == "Point" - lines_mask = geoseries.type == "Linestring" + points_mask = geoseries.feature_types == Feature_Enum.POINT.value + lines_mask = geoseries.feature_types == Feature_Enum.LINESTRING.value if (points_mask + lines_mask).sum() != len(geoseries): raise ValueError("Geoseries must contain only points and lines") points = geoseries[points_mask] diff --git a/python/cuspatial/cuspatial/utils/column_utils.py b/python/cuspatial/cuspatial/utils/column_utils.py index c3cb1dd1a..36deac4eb 100644 --- a/python/cuspatial/cuspatial/utils/column_utils.py +++ b/python/cuspatial/cuspatial/utils/column_utils.py @@ -78,34 +78,34 @@ def contains_only_points(gs: GeoSeries): """ Returns true if `gs` contains only points or multipoints """ - - return contain_single_type_geometry(gs) and ( - len(gs.points.xy) > 0 or len(gs.multipoints.xy) > 0 - ) + points = gs._column._meta.input_types == Feature_Enum.POINT.value + mpoints = gs._column._meta.input_types == Feature_Enum.MULTIPOINT.value + return (points | mpoints).all() def contains_only_multipoints(gs: GeoSeries): """ Returns true if `gs` contains only multipoints """ - - return contain_single_type_geometry(gs) and (len(gs.multipoints.xy) > 0) + return ( + gs._column._meta.input_types == Feature_Enum.MULTIPOINT.value + ).all() def contains_only_linestrings(gs: GeoSeries): """ Returns true if `gs` contains only linestrings """ - - return contain_single_type_geometry(gs) and len(gs.lines.xy) > 0 + return ( + gs._column._meta.input_types == Feature_Enum.LINESTRING.value + ).all() def contains_only_polygons(gs: GeoSeries): """ Returns true if `gs` contains only polygons """ - - return contain_single_type_geometry(gs) and len(gs.polygons.xy) > 0 + return (gs._column._meta.input_types == Feature_Enum.POLYGON.value).all() def has_same_geometry(lhs: GeoSeries, rhs: GeoSeries): From 77ca81bf9bdfcff46b76682cd8a8ba0370f2b762 Mon Sep 17 00:00:00 2001 From: Ben Jarmak <104460670+jarmak-nv@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:18:21 -0500 Subject: [PATCH 43/63] External issue triage GHA (#1177) closes #1176 This PR: - Removes the https://github.com/rapidsai/cuspatial/labels/Needs%20Triage label from the issue templates - Adds in a GHA that automatically adds the label, and comments automatically when an issue is filed from someone outside the team. ~TODO: Before we merge, we need to remove the `? -` from the https://github.com/rapidsai/cuspatial/labels/Needs%20Triage label, it breaks some integrations we have.~ DONE Authors: - Ben Jarmak (https://github.com/jarmak-nv) - Mark Harris (https://github.com/harrism) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1177 --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .../ISSUE_TEMPLATE/documentation_request.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/workflows/external-issue-labeler.yml | 45 +++++++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/external-issue-labeler.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 963b12901..e3746af4a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -16,7 +16,7 @@ name: Bug Report description: File a bug report for cuSpatial title: "[BUG]: " -labels: ["bug", "? - Needs Triage"] +labels: ["bug"] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/documentation_request.yml b/.github/ISSUE_TEMPLATE/documentation_request.yml index b9cac318e..acce2592e 100644 --- a/.github/ISSUE_TEMPLATE/documentation_request.yml +++ b/.github/ISSUE_TEMPLATE/documentation_request.yml @@ -16,7 +16,7 @@ name: Documentation Request description: Request updates or additions to cuSpatial's documentation title: "[DOC]: " -labels: ["doc", "? - Needs Triage"] +labels: ["doc"] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 77f4d9802..43d009030 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -16,7 +16,7 @@ name: Feature Request description: Request new or improved functionality or changes to existing cuSpatial functionality title: "[FEA]: " -labels: ["feature request", "? - Needs Triage"] +labels: ["feature request"] body: - type: markdown diff --git a/.github/workflows/external-issue-labeler.yml b/.github/workflows/external-issue-labeler.yml new file mode 100644 index 000000000..287118623 --- /dev/null +++ b/.github/workflows/external-issue-labeler.yml @@ -0,0 +1,45 @@ +# SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +name: Triage outside issues + +on: + issues: + types: + - opened + +env: + GITHUB_TOKEN: ${{ secrets.ISSUE_PR_WRITE_GITHUB_TOKEN }} + +jobs: + Label-Issue: + runs-on: ubuntu-latest + # Only run if the issue author is not part of RAPIDS + if: ${{ ! contains(fromJSON('["OWNER", "MEMBER", "CONTRIBUTOR", "COLLABORATOR"]'), github.event.issue.author_association)}} + steps: + - name: add-external-labels + run: | + issue_url=${{ github.event.issue.html_url }} + gh issue edit ${issue_url} --add-label "Needs Triage,External" + + - name: add-comment-to-issue + run: | + issue_url=${{ github.event.issue.html_url }} + author=${{ github.event.issue.user.login }} + echo ${author} + gh issue comment ${issue_url} --body "Hi @${author}! + + Thanks for submitting this issue - our team has been notified and we'll get back to you as soon as we can! + In the mean time, feel free to add any relevant information to this issue." From 72edee13c71d6344c4d8381a1a12159e8d929efc Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Fri, 9 Jun 2023 17:02:57 -0400 Subject: [PATCH 44/63] Remove `osmnx` dependency and use a small local dataset (#1195) close #1194 This PR removes `osmnx` dependency and instead use a small locally hosted dataset. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - H. Thomson Comer (https://github.com/thomcom) - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1195 --- .../all_cuda-118_arch-x86_64.yaml | 1 - dependencies.yaml | 1 - .../user_guide/cuspatial_api_examples.ipynb | 434 +--- notebooks/esb_3857.csv | 3 + notebooks/streets_3857.csv | 1865 +++++++++++++++++ 5 files changed, 1927 insertions(+), 377 deletions(-) create mode 100644 notebooks/esb_3857.csv create mode 100644 notebooks/streets_3857.csv diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 18c0b1af9..0fbe91c42 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -28,7 +28,6 @@ dependencies: - notebook - numpydoc - nvcc_linux-64=11.8 -- osmnx - pre-commit - pydata-sphinx-theme - pydeck diff --git a/dependencies.yaml b/dependencies.yaml index 8d28e9730..f17e1af12 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -200,7 +200,6 @@ dependencies: - ipython - ipywidgets - notebook - - osmnx - pydeck - shapely - scikit-image diff --git a/docs/source/user_guide/cuspatial_api_examples.ipynb b/docs/source/user_guide/cuspatial_api_examples.ipynb index 28c81abb8..083da03f9 100644 --- a/docs/source/user_guide/cuspatial_api_examples.ipynb +++ b/docs/source/user_guide/cuspatial_api_examples.ipynb @@ -109,9 +109,9 @@ "import cupy\n", "import geopandas\n", "import pandas as pd\n", - "import osmnx as ox\n", "import numpy as np\n", - "from shapely.geometry import *" + "from shapely.geometry import *\n", + "from shapely import wkt" ] }, { @@ -1134,7 +1134,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 4, "id": "5863871e", "metadata": {}, "outputs": [ @@ -1159,206 +1159,82 @@ " \n", " \n", " \n", - " \n", - " \n", - " osmid\n", - " oneway\n", - " lanes\n", " name\n", - " highway\n", - " maxspeed\n", - " reversed\n", - " length\n", " geometry\n", - " access\n", - " bridge\n", - " ref\n", - " width\n", - " tunnel\n", - " junction\n", " \n", " \n", - " u\n", - " v\n", - " key\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " index\n", " \n", " \n", " \n", " \n", " \n", " \n", - " 42421769\n", - " 42443347\n", " 0\n", - " 195743159\n", - " True\n", - " 3\n", " Columbus Avenue\n", - " primary\n", - " 25 mph\n", - " False\n", - " 86.010\n", " LINESTRING (-8234860.077 4980333.535, -8234863...\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", " \n", " \n", - " 42421772\n", - " 42421769\n", - " 0\n", - " 5668968\n", - " True\n", - " 2\n", + " 1\n", " West 80th Street\n", - " residential\n", - " NaN\n", - " False\n", - " 271.702\n", " LINESTRING (-8235173.854 4980508.442, -8235160...\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", " \n", " \n", - " 42442469\n", - " 0\n", - " [1025731514, 195743132]\n", - " True\n", - " [3, 4]\n", + " 2\n", " Amsterdam Avenue\n", - " primary\n", - " NaN\n", - " False\n", - " 81.618\n", " LINESTRING (-8235173.854 4980508.442, -8235168...\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", " \n", " \n", - " 42421775\n", - " 1061531525\n", - " 0\n", - " 5668968\n", - " True\n", - " 2\n", + " 3\n", " West 80th Street\n", - " residential\n", - " NaN\n", - " False\n", - " 17.096\n", " LINESTRING (-8235369.475 4980617.398, -8235349...\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", " \n", " \n", - " 42428653\n", - " 0\n", - " 404253364\n", - " True\n", - " 4\n", + " 4\n", " Broadway\n", - " primary\n", - " 25 mph\n", - " False\n", - " 86.209\n", " LINESTRING (-8235369.475 4980617.398, -8235373...\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", " \n", " \n", "\n", "" ], "text/plain": [ - " osmid oneway lanes \\\n", - "u v key \n", - "42421769 42443347 0 195743159 True 3 \n", - "42421772 42421769 0 5668968 True 2 \n", - " 42442469 0 [1025731514, 195743132] True [3, 4] \n", - "42421775 1061531525 0 5668968 True 2 \n", - " 42428653 0 404253364 True 4 \n", - "\n", - " name highway maxspeed reversed \\\n", - "u v key \n", - "42421769 42443347 0 Columbus Avenue primary 25 mph False \n", - "42421772 42421769 0 West 80th Street residential NaN False \n", - " 42442469 0 Amsterdam Avenue primary NaN False \n", - "42421775 1061531525 0 West 80th Street residential NaN False \n", - " 42428653 0 Broadway primary 25 mph False \n", - "\n", - " length \\\n", - "u v key \n", - "42421769 42443347 0 86.010 \n", - "42421772 42421769 0 271.702 \n", - " 42442469 0 81.618 \n", - "42421775 1061531525 0 17.096 \n", - " 42428653 0 86.209 \n", - "\n", - " geometry \\\n", - "u v key \n", - "42421769 42443347 0 LINESTRING (-8234860.077 4980333.535, -8234863... \n", - "42421772 42421769 0 LINESTRING (-8235173.854 4980508.442, -8235160... \n", - " 42442469 0 LINESTRING (-8235173.854 4980508.442, -8235168... \n", - "42421775 1061531525 0 LINESTRING (-8235369.475 4980617.398, -8235349... \n", - " 42428653 0 LINESTRING (-8235369.475 4980617.398, -8235373... \n", - "\n", - " access bridge ref width tunnel junction \n", - "u v key \n", - "42421769 42443347 0 NaN NaN NaN NaN NaN NaN \n", - "42421772 42421769 0 NaN NaN NaN NaN NaN NaN \n", - " 42442469 0 NaN NaN NaN NaN NaN NaN \n", - "42421775 1061531525 0 NaN NaN NaN NaN NaN NaN \n", - " 42428653 0 NaN NaN NaN NaN NaN NaN " + " name geometry\n", + "index \n", + "0 Columbus Avenue LINESTRING (-8234860.077 4980333.535, -8234863...\n", + "1 West 80th Street LINESTRING (-8235173.854 4980508.442, -8235160...\n", + "2 Amsterdam Avenue LINESTRING (-8235173.854 4980508.442, -8235168...\n", + "3 West 80th Street LINESTRING (-8235369.475 4980617.398, -8235349...\n", + "4 Broadway LINESTRING (-8235369.475 4980617.398, -8235373..." ] }, - "execution_count": 18, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# all driveways within 2km range of central park, nyc\n", - "graph = ox.graph_from_point((40.769361, -73.977655), dist=2000, network_type=\"drive\")\n", - "nodes, streets = ox.graph_to_gdfs(graph)\n", - "streets = streets.to_crs(3857)\n", + "\n", + "# The dataset is downloaded and processed as follows:\n", + "# import osmnx as ox\n", + "# graph = ox.graph_from_point((40.769361, -73.977655), dist=2000, network_type=\"drive\")\n", + "# nodes, streets = ox.graph_to_gdfs(graph)\n", + "# streets = streets.to_crs(3857)\n", + "# streets = streets.reset_index(drop=True)\n", + "# streets.index.name = \"index\"\n", + "# streets[[\"name\", \"geometry\"]].to_csv(\"streets_3857.csv\")\n", + "\n", + "# The data is under notebooks/streets_3857.csv\n", + "streets = pd.read_csv(\"./streets_3857.csv\", index_col=\"index\")\n", + "streets.geometry = streets.geometry.apply(wkt.loads)\n", + "streets = geopandas.GeoDataFrame(streets)\n", "streets.head()" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 5, "id": "f4c67464", "metadata": {}, "outputs": [ @@ -1383,266 +1259,74 @@ " \n", " \n", " \n", - " \n", - " nodes\n", - " addr:city\n", - " addr:housenumber\n", - " addr:postcode\n", - " addr:state\n", - " addr:street\n", - " building\n", - " building:colour\n", - " building:levels\n", - " building:use\n", - " ...\n", - " office\n", - " opening_hours\n", - " phone\n", - " start_date\n", - " tourism\n", - " website\n", - " wheelchair\n", - " wikidata\n", - " wikipedia\n", " geometry\n", " \n", " \n", - " element_type\n", - " osmid\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " index\n", " \n", " \n", " \n", " \n", " \n", - " way\n", - " 34633854\n", - " [402743563, 402743567, 402743571, 402743573, 2...\n", - " New York\n", - " 350\n", - " 10018\n", - " NY\n", - " 5th Avenue\n", - " office\n", - " beige\n", - " 102\n", - " office\n", - " ...\n", - " yes\n", - " Mo-Su 08:00-02:00\n", - " +1-212-736-3100\n", - " 1931\n", - " attraction\n", - " https://www.esbnyc.com/explore\n", - " yes\n", - " Q9188\n", - " en:Empire State Building\n", + " 0\n", " POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", " \n", " \n", - " 34633854\n", - " [402743563, 402743567, 402743571, 402743573, 2...\n", - " New York\n", - " 350\n", - " 10018\n", - " NY\n", - " 5th Avenue\n", - " office\n", - " beige\n", - " 102\n", - " office\n", - " ...\n", - " yes\n", - " Mo-Su 08:00-02:00\n", - " +1-212-736-3100\n", - " 1931\n", - " attraction\n", - " https://www.esbnyc.com/explore\n", - " yes\n", - " Q9188\n", - " en:Empire State Building\n", + " 0\n", " POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", " \n", " \n", - " 34633854\n", - " [402743563, 402743567, 402743571, 402743573, 2...\n", - " New York\n", - " 350\n", - " 10018\n", - " NY\n", - " 5th Avenue\n", - " office\n", - " beige\n", - " 102\n", - " office\n", - " ...\n", - " yes\n", - " Mo-Su 08:00-02:00\n", - " +1-212-736-3100\n", - " 1931\n", - " attraction\n", - " https://www.esbnyc.com/explore\n", - " yes\n", - " Q9188\n", - " en:Empire State Building\n", + " 0\n", " POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", " \n", " \n", - " 34633854\n", - " [402743563, 402743567, 402743571, 402743573, 2...\n", - " New York\n", - " 350\n", - " 10018\n", - " NY\n", - " 5th Avenue\n", - " office\n", - " beige\n", - " 102\n", - " office\n", - " ...\n", - " yes\n", - " Mo-Su 08:00-02:00\n", - " +1-212-736-3100\n", - " 1931\n", - " attraction\n", - " https://www.esbnyc.com/explore\n", - " yes\n", - " Q9188\n", - " en:Empire State Building\n", + " 0\n", " POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", " \n", " \n", - " 34633854\n", - " [402743563, 402743567, 402743571, 402743573, 2...\n", - " New York\n", - " 350\n", - " 10018\n", - " NY\n", - " 5th Avenue\n", - " office\n", - " beige\n", - " 102\n", - " office\n", - " ...\n", - " yes\n", - " Mo-Su 08:00-02:00\n", - " +1-212-736-3100\n", - " 1931\n", - " attraction\n", - " https://www.esbnyc.com/explore\n", - " yes\n", - " Q9188\n", - " en:Empire State Building\n", + " 0\n", " POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", " \n", " \n", "\n", - "

    5 rows × 35 columns

    \n", "" ], "text/plain": [ - " nodes \\\n", - "element_type osmid \n", - "way 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", - " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", - " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", - " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", - " 34633854 [402743563, 402743567, 402743571, 402743573, 2... \n", - "\n", - " addr:city addr:housenumber addr:postcode addr:state \\\n", - "element_type osmid \n", - "way 34633854 New York 350 10018 NY \n", - " 34633854 New York 350 10018 NY \n", - " 34633854 New York 350 10018 NY \n", - " 34633854 New York 350 10018 NY \n", - " 34633854 New York 350 10018 NY \n", - "\n", - " addr:street building building:colour building:levels \\\n", - "element_type osmid \n", - "way 34633854 5th Avenue office beige 102 \n", - " 34633854 5th Avenue office beige 102 \n", - " 34633854 5th Avenue office beige 102 \n", - " 34633854 5th Avenue office beige 102 \n", - " 34633854 5th Avenue office beige 102 \n", - "\n", - " building:use ... office opening_hours \\\n", - "element_type osmid ... \n", - "way 34633854 office ... yes Mo-Su 08:00-02:00 \n", - " 34633854 office ... yes Mo-Su 08:00-02:00 \n", - " 34633854 office ... yes Mo-Su 08:00-02:00 \n", - " 34633854 office ... yes Mo-Su 08:00-02:00 \n", - " 34633854 office ... yes Mo-Su 08:00-02:00 \n", - "\n", - " phone start_date tourism \\\n", - "element_type osmid \n", - "way 34633854 +1-212-736-3100 1931 attraction \n", - " 34633854 +1-212-736-3100 1931 attraction \n", - " 34633854 +1-212-736-3100 1931 attraction \n", - " 34633854 +1-212-736-3100 1931 attraction \n", - " 34633854 +1-212-736-3100 1931 attraction \n", - "\n", - " website wheelchair wikidata \\\n", - "element_type osmid \n", - "way 34633854 https://www.esbnyc.com/explore yes Q9188 \n", - " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", - " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", - " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", - " 34633854 https://www.esbnyc.com/explore yes Q9188 \n", - "\n", - " wikipedia \\\n", - "element_type osmid \n", - "way 34633854 en:Empire State Building \n", - " 34633854 en:Empire State Building \n", - " 34633854 en:Empire State Building \n", - " 34633854 en:Empire State Building \n", - " 34633854 en:Empire State Building \n", - "\n", - " geometry \n", - "element_type osmid \n", - "way 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", - " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", - " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", - " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", - " 34633854 POLYGON ((-8236139.639 4975314.625, -8235990.3... \n", - "\n", - "[5 rows x 35 columns]" + " geometry\n", + "index \n", + "0 POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", + "0 POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", + "0 POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", + "0 POLYGON ((-8236139.639 4975314.625, -8235990.3...\n", + "0 POLYGON ((-8236139.639 4975314.625, -8235990.3..." ] }, - "execution_count": 19, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The polygon of the Empire State Building\n", - "esb = ox.geometries.geometries_from_place('Empire State Building, New York', tags={\"building\": True})\n", + "\n", + "# The dataset is downloaded and processed as follows:\n", + "# esb = ox.geometries.geometries_from_place('Empire State Building, New York', tags={\"building\": True})\n", + "# esb = esb.to_crs(3857)\n", + "# esb = esb.geometry.reset_index(drop=True)\n", + "# esb.index.name = \"index\"\n", + "# esb.to_csv(\"esb_3857.csv\")\n", + "\n", + "# The data is under notebooks/esb_3857.csv\n", + "esb = pd.read_csv(\"./esb_3857.csv\", index_col=\"index\")\n", + "esb.geometry = esb.geometry.apply(wkt.loads)\n", + "esb = geopandas.GeoDataFrame(esb)\n", "esb = pd.concat([esb.iloc[0:1]] * len(streets))\n", - "esb = esb.to_crs(3857)\n", "esb.head()" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 7, "id": "d4e68e87", "metadata": {}, "outputs": [ @@ -1749,7 +1433,7 @@ "[1864 rows x 2 columns]" ] }, - "execution_count": 20, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/esb_3857.csv b/notebooks/esb_3857.csv new file mode 100644 index 000000000..33a28c1ce --- /dev/null +++ b/notebooks/esb_3857.csv @@ -0,0 +1,3 @@ +index,geometry +0,"POLYGON ((-8236139.639159924 4975314.625364609, -8235990.35972277 4975231.530874815, -8235952.110345733 4975300.239901917, -8236101.367518989 4975383.320281857, -8236120.046929544 4975349.758897243, -8236123.4087781655 4975343.719623545, -8236137.713332732 4975318.078466567, -8236139.639159924 4975314.625364609))" +1,"POLYGON ((-8236120.046929544 4975349.758897243, -8236145.36098175 4975363.806468019, -8236127.483071529 4975396.838910679, -8236114.280579922 4975387.699140014, -8236112.866822389 4975388.85997858, -8236110.529113081 4975388.8893669, -8236101.122616109 4975383.643553196, -8236101.367518989 4975383.320281857, -8236120.046929544 4975349.758897243))" diff --git a/notebooks/streets_3857.csv b/notebooks/streets_3857.csv new file mode 100644 index 000000000..62fa4a678 --- /dev/null +++ b/notebooks/streets_3857.csv @@ -0,0 +1,1865 @@ +index,name,geometry +0,Columbus Avenue,"LINESTRING (-8234860.077273001 4980333.535141255, -8234863.606100859 4980327.125245653, -8234906.920514727 4980247.839889491, -8234914.890990266 4980233.902904723)" +1,West 80th Street,"LINESTRING (-8235173.853521699 4980508.441645807, -8235160.951592717 4980501.237735307, -8234872.53392402 4980340.474299034, -8234860.077273001 4980333.535141255)" +2,Amsterdam Avenue,"LINESTRING (-8235173.853521699 4980508.441645807, -8235168.565845888 4980517.997861814, -8235145.901197561 4980559.030889457, -8235134.735852635 4980579.304885429, -8235126.052932353 4980594.359714606, -8235121.332985944 4980602.7104501715)" +3,West 80th Street,"LINESTRING (-8235369.475262869 4980617.397764739, -8235349.727185204 4980606.400654257)" +4,Broadway,"LINESTRING (-8235369.475262869 4980617.397764739, -8235373.549556233 4980610.149667802, -8235417.108872982 4980532.5233280575, -8235425.2574597085 4980517.997861814)" +5,West 80th Street,"LINESTRING (-8235490.869167581 4980685.924156031, -8235475.918959967 4980677.749774716, -8235380.71853144 4980623.660830522, -8235369.475262869 4980617.397764739)" +6,West End Avenue,"LINESTRING (-8235490.869167581 4980685.924156031, -8235486.394124051 4980694.010331332, -8235463.963246655 4980734.044348783, -8235443.8144188225 4980770.755819384, -8235439.216923854 4980779.621285317)" +7,West End Avenue,"LINESTRING (-8235490.869167581 4980685.924156031, -8235495.143836027 4980678.205540402, -8235521.882777716 4980629.909198275, -8235538.213347016 4980599.902367521, -8235546.139294758 4980585.714946578)" +8,West 80th Street,"LINESTRING (-8235639.024277877 4980767.712452337, -8235628.482322101 4980761.890361499, -8235504.962215115 4980693.642777762, -8235490.869167581 4980685.924156031)" +9,Riverside Drive,"LINESTRING (-8235639.024277877 4980767.712452337, -8235700.9624425545 4980689.761412929, -8235711.137044013 4980677.279306935)" +10,Riverside Drive,"LINESTRING (-8235639.024277877 4980767.712452337, -8235597.457580015 4980821.12588712, -8235591.145764886 4980829.785565924, -8235584.934137301 4980839.253882267, -8235580.659468856 4980847.149053692, -8235576.4627240505 4980856.191017635)" +11,Central Park West,"LINESTRING (-8234337.5213193195 4980531.802934991, -8234332.111192067 4980541.300366208, -8234290.11034819 4980617.838825577, -8234285.9803950805 4980625.322160852)" +12,Central Park West,"LINESTRING (-8234337.5213193195 4980531.802934991, -8234342.152210135 4980523.496365725, -8234383.941546979 4980447.855453934, -8234389.073375505 4980438.5786399795)" +13,Columbus Avenue,"LINESTRING (-8234653.345846648 4980707.477503603, -8234658.288432041 4980698.509188124, -8234699.677018717 4980623.352087748, -8234704.897902836 4980613.869278743)" +14,West 84th Street,"LINESTRING (-8234653.345846648 4980707.477503603, -8234638.139604205 4980699.02376338, -8234350.423248303 4980538.845147037, -8234337.5213193195 4980531.802934991)" +15,West 84th Street,"LINESTRING (-8234967.901331782 4980881.096893321, -8234955.889958726 4980874.480804444, -8234834.507185966 4980807.467428015, -8234666.359095122 4980714.652161917, -8234653.345846648 4980707.477503603)" +16,Amsterdam Avenue,"LINESTRING (-8234967.901331782 4980881.096893321, -8234962.402148937 4980891.035737481, -8234920.05621464 4980967.665153757, -8234916.026449073 4980974.957623791)" +17,West 84th Street,"LINESTRING (-8235159.081425273 4980987.690054286, -8235139.555986586 4980976.7954447195)" +18,Broadway,"LINESTRING (-8235159.081425273 4980987.690054286, -8235163.055531093 4980980.691626231, -8235207.494271816 4980904.620801189, -8235212.470253055 4980896.166890275)" +19,Central Park West,"LINESTRING (-8235533.771699333 4978372.141712271, -8235528.895905635 4978380.343561215, -8235485.269797194 4978455.057136741, -8235480.906073155 4978463.597127373)" +20,West 61st Street,"LINESTRING (-8235664.839267793 4978445.179566528, -8235640.070681091 4978431.083468001)" +21,Broadway,"LINESTRING (-8235664.839267793 4978445.179566528, -8235664.382857881 4978432.626835461, -8235661.1434606975 4978337.320677582, -8235660.842898073 4978321.402111682)" +22,West 61st Street,"LINESTRING (-8235845.588724992 4978546.189952219, -8235831.551337204 4978538.267243059, -8235808.074056596 4978525.008846191, -8235800.493199273 4978520.966655605, -8235793.268564321 4978516.939165554, -8235782.414913968 4978510.883234739, -8235682.116052764 4978454.836655154, -8235677.529689742 4978452.087985122, -8235664.839267793 4978445.179566528)" +23,Columbus Avenue,"LINESTRING (-8235845.588724992 4978546.189952219, -8235850.509046487 4978537.355911434, -8235889.303889028 4978467.374715973, -8235896.8736144025 4978453.7195485225)" +24,Amsterdam Avenue,"LINESTRING (-8236159.209126406 4978719.7562211165, -8236154.099561778 4978728.72271954, -8236114.792649579 4978800.072821683, -8236108.803660973 4978810.891506497)" +25,West 61st Street,"LINESTRING (-8236159.209126406 4978719.7562211165, -8236145.973238949 4978712.4654350225, -8236111.920606717 4978693.327147422, -8236081.463594035 4978676.570152206, -8236077.033078303 4978659.871982064)" +26,West 61st Street,"LINESTRING (-8236477.939092444 4978896.559450165, -8236463.467558641 4978889.15093668, -8236406.694618337 4978857.56192141, -8236398.790934491 4978853.049213283, -8236350.867893704 4978825.973008312, -8236250.001303096 4978769.689432636, -8236242.375917978 4978765.544246102, -8236177.343071456 4978729.398882051, -8236159.209126406 4978719.7562211165)" +27,West 61st Street,"LINESTRING (-8236477.939092444 4978896.559450165, -8236494.358717338 4978905.570209262, -8236581.510746677 4978955.857159421, -8236591.618556444 4978961.663474054)" +28,West End Avenue,"LINESTRING (-8236477.939092444 4978896.559450165, -8236472.239534517 4978906.246384016, -8236452.380137358 4978942.451200597, -8236431.129246566 4978980.890484869, -8236426.8657100685 4978988.578359877)" +29,West End Avenue,"LINESTRING (-8236477.939092444 4978896.559450165, -8236482.870545888 4978887.710393042, -8236508.273653687 4978841.363219845, -8236523.379708587 4978814.18415208, -8236528.667384399 4978804.997085704)" +30,Central Park West,"LINESTRING (-8234073.460355208 4981009.346986329, -8234077.746155604 4981001.495791566, -8234118.900971349 4980925.365994468, -8234123.810160893 4980916.720933372)" +31,West 79th Street,"LINESTRING (-8235711.137044013 4980677.279306935, -8235724.873869178 4980685.07143248, -8235732.688497431 4980689.614391563)" +32,Riverside Drive,"LINESTRING (-8235711.137044013 4980677.279306935, -8235721.745791486 4980663.738665826, -8235722.892382242 4980662.283158291, -8235775.958383502 4980595.241834223, -8235783.24981015 4980585.935476279)" +33,Riverside Drive,"LINESTRING (-8235711.137044013 4980677.279306935, -8235700.9624425545 4980689.761412929, -8235639.024277877 4980767.712452337)" +34,West 79th Street,"LINESTRING (-8235711.137044013 4980677.279306935, -8235699.3149140915 4980670.560441408, -8235660.330828416 4980648.889558727, -8235559.720272637 4980592.904217412, -8235546.139294758 4980585.714946578)" +35,,"LINESTRING (-8236009.506675187 4980464.8360157795, -8235974.307452198 4980508.662173764, -8235966.270184963 4980520.835324675, -8235958.5668762 4980531.567704612, -8235950.540740913 4980541.903144664, -8235941.334619024 4980552.650249687, -8235932.173024933 4980563.015115945, -8235921.163527292 4980574.982507124, -8235909.586300251 4980586.126602025, -8235897.029461689 4980598.108723528, -8235880.977191116 4980611.737485738, -8235867.073386718 4980622.646390016, -8235853.369957399 4980632.673183405, -8235838.686916565 4980642.714689155, -8235829.603246115 4980648.419092337, -8235820.219013041 4980654.329328014, -8235810.745724375 4980660.121950531, -8235802.140727738 4980664.900131591, -8235792.834418306 4980669.5606981395, -8235782.414913968 4980673.80960775, -8235771.6948470045 4980677.617455651, -8235761.164023177 4980680.969539202, -8235754.050707715 4980683.130751575, -8235732.688497431 4980689.614391563)" +36,Queensboro Bridge Approach,"LINESTRING (-8233691.534314247 4976856.461252469, -8233683.407991418 4976870.54038251, -8233673.71206377 4976887.323672597, -8233639.069438235 4976945.4334654, -8233634.839297585 4976953.384275769)" +37,East 57th Street,"LINESTRING (-8233691.534314247 4976856.461252469, -8233680.279913725 4976850.171209278, -8233529.653510733 4976766.181885139, -8233514.848018458 4976757.937302738)" +38,East 57th Street,"LINESTRING (-8233691.534314247 4976856.461252469, -8233697.823865476 4976859.767935676, -8233710.247120648 4976866.748715011, -8233732.488754909 4976879.225951977, -8233763.346517757 4976896.14152483, -8233780.434059593 4976905.503153324)" +39,East 58th Street,"LINESTRING (-8233634.839297585 4976953.384275769, -8233625.410536715 4976949.357432001, -8233534.084026468 4976898.684007034, -8233475.452050666 4976865.60239722, -8233459.911849751 4976856.975625339)" +40,Queensboro Bridge Approach,"LINESTRING (-8233634.839297585 4976953.384275769, -8233627.88182941 4976966.184947094, -8233622.716605037 4976977.471890489, -8233607.3099875115 4977007.77622229)" +41,,"LINESTRING (-8233250.87610994 4976943.273079966, -8233294.680329568 4976972.298706481, -8233390.214716567 4977027.557859133, -8233500.287429063 4977091.223844874, -8233505.374729792 4977094.574697722, -8233508.146585112 4977096.926174091, -8233510.295051285 4977098.910232718, -8233512.4546494065 4977101.4233742235, -8233513.97972643 4977104.671353386, -8233514.725567019 4977107.199193117, -8233515.493671506 4977110.020968476, -8233515.638386843 4977112.490022583, -8233515.538199302 4977116.090727607, -8233515.048393542 4977119.426892222, -8233514.1467056675 4977123.24805133, -8233512.554836949 4977128.186166855)" +42,Ed Koch Queensboro Bridge Lower Level,"LINESTRING (-8233250.87610994 4976943.273079966, -8233393.9550514575 4977021.003166706, -8233535.943061964 4977101.188226453)" +43,Central Park South,"LINESTRING (-8235313.069676885 4978016.499703622, -8235325.9048141735 4978023.672385238, -8235371.545805399 4978049.173662735, -8235503.314686651 4978122.7970328415)" +44,Central Park South,"LINESTRING (-8235313.069676885 4978016.499703622, -8235300.112088157 4978009.268234865, -8235153.537714631 4977927.517734824, -8235092.924251894 4977893.712442142, -8235058.326154154 4977874.414081865, -8235050.778692679 4977870.210483694, -8235017.527560778 4977851.661760917, -8235012.384600304 4977848.795677735, -8234997.812878959 4977840.667764359)" +45,7th Avenue,"LINESTRING (-8235313.069676885 4978016.499703622, -8235320.450159125 4978002.330733284, -8235359.345189208 4977927.738204509, -8235363.842496636 4977919.110494583)" +46,East 62nd Street,"LINESTRING (-8233411.777301933 4977311.236228266, -8233402.01458259 4977305.680744378, -8233271.258708703 4977233.592013753, -8233255.150778388 4977224.685675393)" +47,Queensboro Bridge Exit,"LINESTRING (-8233411.777301933 4977311.236228266, -8233407.613952976 4977319.628248279, -8233368.930429927 4977397.199660737, -8233364.555573939 4977406.047367605)" +48,,"LINESTRING (-8237475.896063508 4976826.862813516, -8237505.6072356 4976831.727297573, -8237527.971321302 4976835.827574535, -8237553.274241557 4976839.648622717)" +49,Galvin Avenue,"LINESTRING (-8237303.217269389 4976915.908239164, -8237309.86304299 4976908.280781088, -8237367.159184902 4976842.411535408, -8237372.714027492 4976836.312553645)" +50,West 41st Street,"LINESTRING (-8237303.217269389 4976915.908239164, -8237323.210249935 4976927.22451742, -8237485.770102341 4977017.035081503, -8237491.3472088305 4977020.003796948, -8237500.185976399 4977024.7067143535)" +51,Lincoln Tunnel,"LINESTRING (-8237553.274241557 4976839.648622717, -8237580.1467666365 4976846.541209561, -8237603.635179194 4976854.183315799, -8237627.50207802 4976863.985795437)" +52,West 39th Street,"LINESTRING (-8237292.441542681 4976672.170544482, -8237308.182118678 4976679.856602624, -8237403.415943052 4976733.571001838)" +53,10th Avenue,"LINESTRING (-8237292.441542681 4976672.170544482, -8237285.651053743 4976684.280130224, -8237273.417041704 4976706.427190549, -8237247.501864248 4976753.219817543, -8237242.180792588 4976762.831144928)" +54,West 72nd Street,"LINESTRING (-8236048.913774927 4979991.390793099, -8236056.995569959 4979995.47769562, -8236087.775409162 4980011.987035083, -8236111.475328755 4980025.732588342, -8236146.496440557 4980045.402729229, -8236154.734082876 4980048.254755936, -8236160.990238259 4980050.121804797, -8236166.133198733 4980050.974472901, -8236172.701048689 4980051.547818735, -8236179.83662805 4980051.621324615, -8236187.695784099 4980051.239094051, -8236194.6643842235 4980049.813080157)" +55,West 72nd Street,"LINESTRING (-8236048.913774927 4979991.390793099, -8236037.381075681 4979985.333947904, -8235968.218276051 4979948.3020076575, -8235929.345509867 4979926.309306116, -8235914.706996826 4979918.135560684)" +56,Riverside Drive,"LINESTRING (-8236048.913774927 4979991.390793099, -8236042.857994628 4980010.913853663, -8236017.4103590315 4980092.593587535, -8236014.05964236 4980103.0755754905)" +57,,"LINESTRING (-8233674.43564046 4977097.205411948, -8233658.739592259 4977101.379284016, -8233651.526089255 4977103.642581589, -8233644.490697436 4977105.582551353, -8233637.332854179 4977107.096315907, -8233628.004280849 4977108.507203469)" +58,East 59th Street,"LINESTRING (-8233674.43564046 4977097.205411948, -8233600.842325096 4977055.819509347, -8233569.917770554 4977038.903660004, -8233542.421856329 4977024.001276599, -8233512.877663471 4977009.451634261)" +59,2nd Avenue,"LINESTRING (-8233674.43564046 4977097.205411948, -8233678.955211787 4977088.490255242, -8233690.2986678975 4977067.6503336355, -8233719.876256601 4977012.861245469, -8233724.184320896 4977004.675241246)" +60,West 54th Street,"LINESTRING (-8237089.1053607995 4978385.252914954, -8237082.236948216 4978377.888885271, -8237076.270223509 4978372.112314975, -8237068.65597034 4978366.144665789)" +61,12th Avenue,"LINESTRING (-8237089.1053607995 4978385.252914954, -8237098.600913363 4978366.27695354, -8237126.586633348 4978314.317402792)" +62,West 77th Street,"LINESTRING (-8234702.7494366625 4979870.18109849, -8234715.35080302 4979878.634121174, -8234719.336040791 4979880.795155973, -8234829.842899302 4979942.274591212, -8234886.626971555 4979973.587795239, -8234999.104185053 4980036.214504527, -8235003.334325703 4980038.463781135, -8235020.054513221 4980044.447153457)" +63,Central Park West,"LINESTRING (-8234702.7494366625 4979870.18109849, -8234696.337433992 4979881.868323092, -8234603.085096556 4980050.768656455, -8234532.675518627 4980177.2877839925, -8234504.5116874585 4980227.904714869, -8234494.47066939 4980245.399445575)" +64,Central Park West,"LINESTRING (-8234702.7494366625 4979870.18109849, -8234708.894272555 4979858.993717983, -8234711.688391774 4979853.995418087, -8234752.164158626 4979779.9179733815, -8234756.95089673 4979771.229824088)" +65,York Avenue,"LINESTRING (-8233107.808300372 4976903.048847969, -8233103.110617861 4976911.411124434, -8233083.963665444 4976945.506947906, -8233061.855614575 4976984.849561058, -8233057.157932062 4976993.226604116)" +66,"['FDR Drive', 'East 60th Street']","LINESTRING (-8233107.808300372 4976903.048847969, -8233092.223571662 4976898.272506979, -8233067.833471229 4976885.839334923, -8233042.864509444 4976871.965932298, -8233041.027737846 4976871.1429344565, -8233039.5360566685 4976870.687346397, -8233038.244750576 4976870.393418626, -8233036.920048636 4976870.305240297, -8233035.272520172 4976870.4669005675, -8233033.925554333 4976870.716739173, -8233032.923678916 4976870.9518813975, -8233031.78822011 4976871.407469469, -8233030.46351817 4976872.186378161, -8233029.350323262 4976873.171036407, -8233028.025621322 4976875.404888316, -8232985.713082871 4976953.09034551)" +67,York Avenue,"LINESTRING (-8233107.808300372 4976903.048847969, -8233112.851073306 4976893.907668178, -8233154.117208542 4976819.23542496, -8233158.681307665 4976810.976101488)" +68,Dyer Avenue,"LINESTRING (-8237064.737524263 4976662.809139579, -8237061.464731233 4976668.099728375, -8237059.34966091 4976671.538612628, -8237056.989687703 4976675.344900459, -8237052.058234262 4976688.644875367, -8237047.327155903 4976710.2040996775, -8237040.759305946 4976724.503461469, -8237033.723914129 4976737.436098589, -8237026.32116799 4976750.750854236, -8237018.272768806 4976766.387632383)" +69,West 40th Street,"LINESTRING (-8237064.737524263 4976662.809139579, -8237032.644115068 4976645.012207739, -8237027.156064171 4976642.043606244, -8237024.584583934 4976640.647482091, -8236941.273077024 4976595.574823184, -8236927.480592116 4976587.594912088)" +70,Central Park West,"LINESTRING (-8234285.9803950805 4980625.322160852, -8234290.11034819 4980617.838825577, -8234332.111192067 4980541.300366208, -8234337.5213193195 4980531.802934991)" +71,West 85th Street,"LINESTRING (-8234285.9803950805 4980625.322160852, -8234299.294206182 4980632.673183405, -8234586.565284122 4980791.588941984, -8234603.207547995 4980800.792579816)" +72,Central Park West,"LINESTRING (-8234285.9803950805 4980625.322160852, -8234280.603663676 4980634.408025535, -8234267.72399859 4980657.196234668, -8234236.9552913355 4980710.726682227, -8234229.752920281 4980724.340899442)" +73,West 79th Street,"LINESTRING (-8235875.934418184 4980769.3297004085, -8235812.838530801 4980734.16196641, -8235793.435543557 4980723.444065974, -8235759.071216748 4980704.213623901, -8235732.688497431 4980689.614391563)" +74,5th Avenue,"LINESTRING (-8234690.482028778 4977542.879203456, -8234695.791968488 4977533.223016415, -8234700.411727356 4977524.742628667, -8234736.735277203 4977458.060876172, -8234745.162162656 4977442.746330331)" +75,East 58th Street,"LINESTRING (-8234690.482028778 4977542.879203456, -8234676.210870057 4977535.3541375445, -8234578.706128072 4977480.415453078, -8234522.879403439 4977449.360094784, -8234510.545203859 4977442.599357837)" +76,West 58th Street,"LINESTRING (-8234763.151392367 4977582.885608238, -8234704.909034783 4977550.227906231, -8234690.482028778 4977542.879203456)" +77,79th Street Transverse,"LINESTRING (-8234494.47066939 4980245.399445575, -8234490.0735495025 4980242.591465677, -8234485.253415552 4980239.3865472, -8234480.377621855 4980235.167229524, -8234477.060301028 4980231.888806248, -8234472.963743768 4980227.434268762, -8234469.212276927 4980222.068244454, -8234465.616657375 4980216.114166141, -8234463.189892476 4980210.953967873, -8234461.642551553 4980206.087800493, -8234459.917099446 4980200.765892119, -8234458.525605812 4980194.576604535, -8234457.891084714 4980189.166494137, -8234457.757501325 4980181.595284887, -8234458.013536155 4980175.876453054, -8234458.859564284 4980169.510765007, -8234459.805779955 4980163.791940252, -8234461.0080304565 4980157.911404151, -8234462.611031123 4980152.016170262, -8234480.210642618 4980092.505380111, -8234483.060421582 4980082.023403503, -8234485.164359958 4980072.2470960505, -8234486.511325796 4980064.308447575, -8234487.001131555 4980055.69355116, -8234487.257166386 4980047.152168194, -8234486.555853594 4980038.199160332, -8234485.921332496 4980029.907712094, -8234484.830401486 4980022.615947831, -8234483.405512003 4980016.11804959, -8234481.5019487105 4980009.370236761, -8234479.320086691 4980003.84262014, -8234475.82465468 4979997.888674887, -8234472.062055893 4979992.625684328, -8234467.898706934 4979986.759952382, -8234461.854058587 4979979.424117138, -8234453.727735758 4979971.2650283, -8234445.334246153 4979963.032441067, -8234405.459604549 4979927.661797029, -8234397.489129009 4979921.0316531565, -8234384.976818245 4979912.078760928, -8234374.579577804 4979905.286917123, -8234365.173080832 4979899.553546161, -8234354.775840391 4979893.849580442, -8234344.27841241 4979888.792458983, -8234334.871915437 4979884.499788171, -8234321.135090274 4979878.722326667, -8234275.861453368 4979861.389962663, -8234265.519872674 4979857.112004781, -8234255.256215623 4979852.466526864, -8234245.649343568 4979847.380025099, -8234229.0070796935 4979837.942072195, -8234179.71480917 4979810.289804752, -8234145.884815919 4979791.384578193, -8234134.697207094 4979784.9750384595, -8234078.658975429 4979754.1769647, -8234010.587106807 4979716.866588271, -8234001.3141932255 4979711.677252487, -8233992.31957837 4979707.16414967, -8233982.824025804 4979702.974463254, -8233973.228285697 4979699.387505085, -8233965.191018463 4979696.800191813, -8233940.633938793 4979689.508676281, -8233893.645981731 4979675.601889574, -8233886.165311949 4979673.661409282, -8233877.994461323 4979672.220749922, -8233868.454380964 4979671.338713681, -8233859.6156133935 4979670.941797402, -8233849.697046764 4979670.70658776, -8233837.986236334 4979669.662845048, -8233828.078801652 4979667.9575755065, -8233818.1936308695 4979665.825988996, -8233809.143356267 4979663.253385208, -8233799.4919564165 4979660.10745921, -8233790.4305498665 4979656.476415043, -8233781.80328933 4979652.492558421, -8233772.7975425245 4979647.920680683, -8233764.726879441 4979643.054793868, -8233755.710000688 4979636.939362518, -8233746.036336938 4979629.442084115, -8233736.618708018 4979620.959876078, -8233728.60370468 4979613.6684171725, -8233703.300784423 4979588.515865836, -8233694.8516350705 4979579.739684034, -8233685.077783779 4979569.346460509, -8233675.404120029 4979559.070851519, -8233662.836149519 4979546.854798248, -8233652.561360519 4979537.711143824, -8233642.921092615 4979529.670027155, -8233633.937609709 4979522.628542858, -8233625.443932561 4979516.5719884, -8233618.107978119 4979511.706167032, -8233603.614180417 4979503.385765111)" +78,Central Park West,"LINESTRING (-8234494.47066939 4980245.399445575, -8234486.177367324 4980260.042118227, -8234446.703475889 4980333.373423655, -8234444.198787346 4980338.033831964, -8234440.436188557 4980345.002396175)" +79,West 81st Street,"LINESTRING (-8234494.47066939 4980245.399445575, -8234501.071915192 4980249.265932304, -8234508.552584974 4980253.264733879, -8234540.300903749 4980271.082943151, -8234554.093388657 4980278.845341517, -8234599.16665048 4980304.102581933, -8234646.878184234 4980330.66832963, -8234745.240086299 4980385.152596127, -8234795.211405716 4980413.335753442, -8234800.487949579 4980417.231710123, -8234805.998264374 4980421.627527262, -8234809.337849097 4980424.641382966)" +80,Central Park West,"LINESTRING (-8234494.47066939 4980245.399445575, -8234504.5116874585 4980227.904714869, -8234532.675518627 4980177.2877839925, -8234603.085096556 4980050.768656455, -8234696.337433992 4979881.868323092, -8234702.7494366625 4979870.18109849)" +81,York Avenue,"LINESTRING (-8233057.157932062 4976993.226604116, -8233061.855614575 4976984.849561058, -8233083.963665444 4976945.506947906, -8233103.110617861 4976911.411124434, -8233107.808300372 4976903.048847969)" +82,East 61st Street,"LINESTRING (-8233057.157932062 4976993.226604116, -8233071.373431037 4977001.074577287, -8233122.636056547 4977029.703566578, -8233134.124227997 4977036.096601825, -8233141.927724302 4977040.446807514, -8233191.87677982 4977068.25289774, -8233292.888085766 4977124.4972767485, -8233307.938480922 4977132.874439557)" +83,York Avenue,"LINESTRING (-8233057.157932062 4976993.226604116, -8233052.193082773 4977002.294393909, -8233045.235614598 4977014.992253081, -8233011.494676938 4977076.585922223, -8233006.808126376 4977085.139404481)" +84,York Avenue,"LINESTRING (-8233006.808126376 4977085.139404481, -8233011.494676938 4977076.585922223, -8233045.235614598 4977014.992253081, -8233052.193082773 4977002.294393909, -8233057.157932062 4976993.226604116)" +85,York Avenue,"LINESTRING (-8233006.808126376 4977085.139404481, -8233001.620638105 4977094.780451882, -8232955.968514931 4977179.566231241)" +86,East 62nd Street,"LINESTRING (-8233006.808126376 4977085.139404481, -8232993.049037314 4977077.247273677, -8232966.955748672 4977062.579978615, -8232924.999432593 4977040.035301488)" +87,East 63rd Street,"LINESTRING (-8232955.968514931 4977179.566231241, -8232969.927979077 4977186.326786147, -8233190.730189065 4977310.207434717, -8233204.032868214 4977317.188535937)" +88,East 63rd Street,"LINESTRING (-8232955.968514931 4977179.566231241, -8232941.496981128 4977167.176791676, -8232895.53316338 4977141.677816637)" +89,York Avenue,"LINESTRING (-8232955.968514931 4977179.566231241, -8233001.620638105 4977094.780451882, -8233006.808126376 4977085.139404481)" +90,York Avenue,"LINESTRING (-8232955.968514931 4977179.566231241, -8232950.046318022 4977191.147358588, -8232910.63921828 4977261.663199336, -8232906.030591361 4977269.908206866)" +91,York Avenue,"LINESTRING (-8232906.030591361 4977269.908206866, -8232900.820839191 4977279.299587558, -8232859.276405227 4977354.2251985, -8232854.812493647 4977362.279221485)" +92,York Avenue,"LINESTRING (-8232906.030591361 4977269.908206866, -8232910.63921828 4977261.663199336, -8232950.046318022 4977191.147358588, -8232955.968514931 4977179.566231241)" +93,York Avenue,"LINESTRING (-8232854.812493647 4977362.279221485, -8232859.276405227 4977354.2251985, -8232900.820839191 4977279.299587558, -8232906.030591361 4977269.908206866)" +94,York Avenue,"LINESTRING (-8232854.812493647 4977362.279221485, -8232850.437637659 4977370.18627971, -8232808.793016154 4977445.288954801, -8232803.727979322 4977454.415953295)" +95,East 66th Street,"LINESTRING (-8232803.727979322 4977454.415953295, -8232817.075186267 4977461.99974597, -8232862.348823173 4977486.882269877, -8233038.511917355 4977584.796278252, -8233052.549305143 4977592.703516596)" +96,York Avenue,"LINESTRING (-8232803.727979322 4977454.415953295, -8232808.793016154 4977445.288954801, -8232850.437637659 4977370.18627971, -8232854.812493647 4977362.279221485)" +97,York Avenue,"LINESTRING (-8232803.727979322 4977454.415953295, -8232798.31785207 4977464.174943406, -8232757.474730899 4977537.83799655, -8232753.08874296 4977545.745196882)" +98,East 67th Street,"LINESTRING (-8232753.08874296 4977545.745196882, -8232766.435949906 4977553.329060461, -8232987.382875233 4977676.993899318, -8233000.318200062 4977684.107541187)" +99,York Avenue,"LINESTRING (-8232753.08874296 4977545.745196882, -8232757.474730899 4977537.83799655, -8232798.31785207 4977464.174943406, -8232803.727979322 4977454.415953295)" +100,York Avenue,"LINESTRING (-8232753.08874296 4977545.745196882, -8232748.268609009 4977554.431366705, -8232729.010337101 4977589.161425765, -8232706.880022332 4977629.06513739, -8232702.082152279 4977637.707288676)" +101,East 68th Street,"LINESTRING (-8232702.082152279 4977637.707288676, -8232688.067028387 4977630.226242306, -8232657.142473846 4977613.706230931, -8232617.79103385 4977592.688819121, -8232577.248475304 4977570.010641575, -8232574.287376848 4977569.114097724, -8232571.459861782 4977568.864241257, -8232568.376311887 4977568.702569426, -8232564.4801297095 4977568.540897601, -8232559.459620673 4977568.864241257, -8232554.583826977 4977569.995944135, -8232549.24049142 4977571.465688326, -8232545.177330004 4977572.920735294)" +102,York Avenue,"LINESTRING (-8232702.082152279 4977637.707288676, -8232706.880022332 4977629.06513739, -8232729.010337101 4977589.161425765, -8232748.268609009 4977554.431366705, -8232753.08874296 4977545.745196882)" +103,York Avenue,"LINESTRING (-8232702.082152279 4977637.707288676, -8232697.306546125 4977646.334750053, -8232655.38362589 4977722.086245759, -8232651.487443713 4977729.111734384)" +104,East 69th Street,"LINESTRING (-8232651.487443713 4977729.111734384, -8232664.83465066 4977736.534065722, -8232886.204590051 4977860.406994288, -8232900.097262503 4977868.2115705125)" +105,York Avenue,"LINESTRING (-8232651.487443713 4977729.111734384, -8232655.38362589 4977722.086245759, -8232697.306546125 4977646.334750053, -8232702.082152279 4977637.707288676)" +106,York Avenue,"LINESTRING (-8232651.487443713 4977729.111734384, -8232645.8212816315 4977739.341325183, -8232605.779660794 4977811.6983487345, -8232600.7146239625 4977820.825689593)" +107,East 70th Street,"LINESTRING (-8232600.7146239625 4977820.825689593, -8232586.321013804 4977812.859475359, -8232538.409104965 4977786.271180048, -8232527.900545035 4977780.450866351)" +108,York Avenue,"LINESTRING (-8232600.7146239625 4977820.825689593, -8232605.779660794 4977811.6983487345, -8232645.8212816315 4977739.341325183, -8232651.487443713 4977729.111734384)" +109,York Avenue,"LINESTRING (-8232600.7146239625 4977820.825689593, -8232595.460343997 4977830.320484787, -8232554.105153167 4977905.044551131, -8232548.772949558 4977914.671709823)" +110,East 71st Street,"LINESTRING (-8232548.772949558 4977914.671709823, -8232562.565434468 4977922.608611147, -8232778.781281434 4978043.367890536, -8232783.590283438 4978046.057652923, -8232797.928233852 4978054.024057346)" +111,York Avenue,"LINESTRING (-8232548.772949558 4977914.671709823, -8232554.105153167 4977905.044551131, -8232595.460343997 4977830.320484787, -8232600.7146239625 4977820.825689593)" +112,Columbus Avenue,"LINESTRING (-8234970.47281202 4980133.815944461, -8234974.70295267 4980126.127167825, -8234982.395129484 4980112.160954236, -8234987.972235973 4980102.031786565, -8235015.078531981 4980052.797418749, -8235020.054513221 4980044.447153457)" +113,West 78th Street,"LINESTRING (-8235284.6720747845 4980307.92498722, -8235271.391659532 4980300.559507598, -8234983.230025666 4980140.887272105, -8234970.47281202 4980133.815944461)" +114,Amsterdam Avenue,"LINESTRING (-8235284.6720747845 4980307.92498722, -8235279.796281087 4980316.922347116, -8235262.920246284 4980348.08973634, -8235237.138652216 4980395.7231083, -8235229.769301924 4980409.160465743)" +115,West 78th Street,"LINESTRING (-8235480.594378582 4980417.12879804, -8235459.521598974 4980405.499739618)" +116,Broadway,"LINESTRING (-8235480.594378582 4980417.12879804, -8235483.867171609 4980408.572397197, -8235513.255517178 4980330.241983357, -8235514.858517847 4980325.890312122, -8235517.864144097 4980317.863247976)" +117,West 78th Street,"LINESTRING (-8235601.899227698 4980484.668761328, -8235587.694860673 4980476.876795708, -8235492.6948072305 4980423.891594388, -8235480.594378582 4980417.12879804)" +118,West End Avenue,"LINESTRING (-8235601.899227698 4980484.668761328, -8235606.21842394 4980477.067919318, -8235648.130212224 4980400.677580392, -8235652.349220925 4980393.400240945)" +119,West End Avenue,"LINESTRING (-8235601.899227698 4980484.668761328, -8235596.7117394265 4980493.84270618, -8235572.933896193 4980537.036812351, -8235553.597700643 4980572.247942244, -8235546.139294758 4980585.714946578)" +120,West 78th Street,"LINESTRING (-8235783.24981015 4980585.935476279, -8235772.485215391 4980579.363693312, -8235620.801277234 4980494.8424314605, -8235616.159254468 4980492.240205577, -8235601.899227698 4980484.668761328)" +121,Riverside Drive,"LINESTRING (-8235783.24981015 4980585.935476279, -8235775.958383502 4980595.241834223, -8235722.892382242 4980662.283158291, -8235721.745791486 4980663.738665826, -8235711.137044013 4980677.279306935)" +122,Riverside Drive,"LINESTRING (-8235783.24981015 4980585.935476279, -8235789.183139008 4980578.5697869435, -8235849.284532088 4980503.090168929)" +123,West 37th Street,"LINESTRING (-8236253.374283669 4975857.350416595, -8236257.148014404 4975859.407697841, -8236264.8624551175 4975863.860243736, -8236428.947384547 4975953.102622822, -8236444.854939781 4975961.772681686)" +124,Broadway,"LINESTRING (-8236253.374283669 4975857.350416595, -8236255.099735775 4975846.446833225, -8236268.625053906 4975757.719743296, -8236270.105603134 4975748.550245656)" +125,West 38th Street,"LINESTRING (-8236232.624330583 4975960.112144393, -8236215.38094146 4975950.501606663, -8236093.152140568 4975885.3147837445, -8236077.945898126 4975876.835826342)" +126,Broadway,"LINESTRING (-8236232.624330583 4975960.112144393, -8236234.205067352 4975952.970367746, -8236251.515248171 4975866.769829277, -8236253.374283669 4975857.350416595)" +127,Broadway,"LINESTRING (-8236202.913158491 4976068.63546276, -8236205.428978982 4976058.686829427, -8236206.197083469 4976055.23346572, -8236212.219467921 4976030.530929435, -8236213.32153088 4976027.195136637, -8236220.067492022 4976010.281068224, -8236221.169554981 4976006.724856001, -8236228.961919337 4975973.807911745, -8236229.518516791 4975971.442010647, -8236230.798690935 4975966.724905202, -8236232.624330583 4975960.112144393)" +128,West 39th Street,"LINESTRING (-8236202.913158491 4976068.63546276, -8236209.2472375175 4976072.103526392, -8236214.456989686 4976074.998478755, -8236221.002575744 4976078.642887012, -8236253.296360023 4976096.673910766, -8236293.137605779 4976118.657991267, -8236329.572475114 4976138.966858252, -8236342.441008251 4976145.814864885)" +129,West 40th Street,"LINESTRING (-8236183.766206075 4976173.427369514, -8236178.25589128 4976170.35604396, -8236164.519066116 4976162.787949228, -8235992.986862753 4976068.121131394, -8235976.94572413 4976059.274636136)" +130,West 41st Street,"LINESTRING (-8236158.563473359 4976279.028652642, -8236170.597110313 4976285.803279903, -8236231.366420338 4976318.530233068, -8236244.925134317 4976325.922101609)" +131,Broadway,"LINESTRING (-8236158.563473359 4976279.028652642, -8236160.8009951245 4976269.329628297, -8236181.027746601 4976184.243145658, -8236183.766206075 4976173.427369514)" +132,Broadway,"LINESTRING (-8236131.145482777 4976391.508647355, -8236134.796762074 4976376.254555971, -8236156.259159899 4976288.330907763, -8236158.563473359 4976279.028652642)" +133,West 42nd Street,"LINESTRING (-8236131.145482777 4976391.508647355, -8236140.474056104 4976396.637436803, -8236176.307800191 4976416.3443576945, -8236189.476895953 4976423.368907339)" +134,West 42nd Street,"LINESTRING (-8236131.145482777 4976391.508647355, -8236116.061691774 4976383.117424582, -8236087.252207557 4976366.996304028, -8236074.851216282 4976360.059968639, -8236039.462750158 4976340.264987734, -8235889.849354533 4976256.559260929, -8235874.342549466 4976247.888940469)" +135,7th Avenue,"LINESTRING (-8236031.915288683 4976706.60354425, -8236038.071256525 4976696.066416197, -8236078.535891427 4976626.62746744, -8236085.1371372305 4976615.340929383)" +136,West 45th Street,"LINESTRING (-8236031.915288683 4976706.60354425, -8236044.806085718 4976713.56951799, -8236048.635476199 4976715.685764159, -8236054.012207605 4976718.669084193, -8236109.126487496 4976749.119575251, -8236164.930948233 4976779.864086259, -8236335.338824738 4976874.552497394, -8236349.431872273 4976882.385678826)" +137,West 47th Street,"LINESTRING (-8235987.788242534 4976923.3152561765, -8235995.536079092 4976927.386178633, -8236011.0094883125 4976935.616207551, -8236201.900151124 4977040.299841073, -8236233.715261593 4977057.994616341, -8236248.075475905 4977065.989608367)" +138,West 48th Street,"LINESTRING (-8235952.555623697 4977022.531614772, -8235946.933989412 4977019.415932432, -8235938.429180315 4977014.713017573, -8235895.393065174 4976990.786973292, -8235880.576440949 4976982.5422013365)" +139,Broadway,"LINESTRING (-8235952.555623697 4977022.531614772, -8235960.804397965 4977013.698951854, -8235985.227894246 4976931.839211277, -8235987.788242534 4976923.3152561765)" +140,West 49th Street,"LINESTRING (-8235919.1597764585 4977124.071070412, -8235967.461303514 4977151.260132592, -8235985.561852716 4977161.32745319, -8236019.235998683 4977180.051227416, -8236131.22340642 4977242.307299909, -8236146.863794877 4977251.007896881)" +141,Broadway,"LINESTRING (-8235919.1597764585 4977124.071070412, -8235923.73500753 4977115.664521636, -8235933.163768401 4977091.400205521, -8235927.653453606 4977076.703495812, -8235943.494217147 4977029.791746346, -8235952.555623697 4977022.531614772)" +142,West 50th Street,"LINESTRING (-8235872.149555497 4977219.056756162, -8235863.77832979 4977214.603592593, -8235856.676146275 4977210.591338047, -8235826.308189188 4977193.719311323, -8235799.880942074 4977179.125325649, -8235794.003272959 4977175.877321733, -8235777.761759254 4977166.809370815)" +143,Broadway,"LINESTRING (-8235872.149555497 4977219.056756162, -8235876.813842161 4977209.900583767, -8235914.250586914 4977133.036104173, -8235919.1597764585 4977124.071070412)" +144,West 51st Street,"LINESTRING (-8235825.384237414 4977312.456083618, -8235831.762844236 4977316.0127711715, -8235834.412248118 4977317.482477151, -8235953.25693649 4977383.575383603, -8236030.089649034 4977426.300122137, -8236044.672502329 4977434.412993495)" +145,Broadway,"LINESTRING (-8235825.384237414 4977312.456083618, -8235829.892676791 4977303.182247364, -8235830.527197889 4977301.918302058, -8235847.9932259945 4977267.233355176, -8235867.507532731 4977228.477481822, -8235872.149555497 4977219.056756162)" +146,West 52nd Street,"LINESTRING (-8235778.919481957 4977408.325432965, -8235760.317995046 4977396.567681981, -8235756.844826933 4977394.363105247, -8235695.774954284 4977360.603749004, -8235693.1144184545 4977359.222219279, -8235677.21799517 4977350.933045031)" +147,Broadway,"LINESTRING (-8235778.919481957 4977408.325432965, -8235781.490962195 4977402.475950081, -8235783.183018454 4977398.419526823, -8235820.541839564 4977322.567661547, -8235825.384237414 4977312.456083618)" +148,West 53rd Street,"LINESTRING (-8235739.122763999 4977502.9611465605, -8235747.271350726 4977507.487928318, -8235886.532033707 4977585.281294547, -8235930.013426811 4977609.576232452, -8235943.727988077 4977617.24833066)" +149,Broadway,"LINESTRING (-8235739.122763999 4977502.9611465605, -8235742.48461262 4977494.877612926, -8235760.507238179 4977451.3883167785, -8235774.66707741 4977417.231938755, -8235778.919481957 4977408.325432965)" +150,Broadway,"LINESTRING (-8235696.186836399 4977602.315669967, -8235700.116414425 4977593.276718137, -8235734.013199372 4977514.82190711, -8235739.122763999 4977502.9611465605)" +151,West 54th Street,"LINESTRING (-8235696.186836399 4977602.315669967, -8235684.798852492 4977595.2461800985, -8235678.765336092 4977591.792273188, -8235639.502951687 4977569.70199532, -8235621.458062231 4977559.840017806, -8235590.61143133 4977542.982085258, -8235575.427452787 4977534.325320388)" +152,Broadway,"LINESTRING (-8235666.965470066 4977709.152305021, -8235669.21412378 4977700.583578713, -8235670.472034026 4977695.777452495, -8235693.337057435 4977612.368757924, -8235696.186836399 4977602.315669967)" +153,West 55th Street,"LINESTRING (-8235666.965470066 4977709.152305021, -8235675.837633483 4977714.634530083, -8235724.584438501 4977741.560677474, -8235816.589997643 4977792.7235015575, -8235825.5623486005 4977797.323906513, -8235841.26952875 4977805.378294844)" +154,Broadway,"LINESTRING (-8235642.842536411 4977809.596562918, -8235644.712703858 4977802.100687114, -8235664.73908025 4977716.221877326, -8235666.965470066 4977709.152305021)" +155,West 56th Street,"LINESTRING (-8235642.842536411 4977809.596562918, -8235631.109462082 4977803.496977269, -8235627.858932951 4977801.9096158445, -8235568.202817834 4977768.677969703, -8235490.6465286 4977725.760663867, -8235475.084063787 4977717.147830002)" +156,West 57th Street,"LINESTRING (-8235626.623286603 4977931.941827437, -8235613.031176778 4977925.121964578, -8235609.190654346 4977922.81438275, -8235513.533815906 4977869.828338496, -8235469.217526622 4977844.974234799, -8235450.972262081 4977834.744533376, -8235435.409797268 4977826.014020807, -8235419.9363880465 4977817.342307294)" +157,Broadway,"LINESTRING (-8235626.623286603 4977931.941827437, -8235628.716093029 4977916.582444738, -8235640.894445322 4977823.897534086, -8235642.842536411 4977809.596562918)" +158,West 57th Street,"LINESTRING (-8235626.623286603 4977931.941827437, -8235637.777499581 4977938.041493296, -8235722.803326648 4977985.692508049, -8235735.716387581 4977992.938657429)" +159,Broadway,"LINESTRING (-8235610.6600716235 4978054.626682299, -8235612.140620851 4978042.368416175, -8235619.020165381 4977989.190648457, -8235623.907091028 4977951.446073577, -8235626.623286603 4977931.941827437)" +160,West 58th Street,"LINESTRING (-8235610.6600716235 4978054.626682299, -8235602.144130577 4978049.937967181, -8235596.867586713 4978047.042429502, -8235592.670841912 4978044.969989355, -8235377.122911888 4977926.415386479, -8235363.842496636 4977919.110494583)" +161,West 60th Street,"LINESTRING (-8235660.842898073 4978321.402111682, -8235675.592730604 4978329.221754846, -8235757.49047998 4978374.287715093, -8235764.603795442 4978378.285749005, -8235784.741491327 4978389.618420201, -8235818.181866361 4978408.329850321, -8235848.327184467 4978425.189276423, -8235882.802830767 4978444.503423693, -8235896.8736144025 4978453.7195485225)" +162,Broadway,"LINESTRING (-8235660.842898073 4978321.402111682, -8235660.709314683 4978308.30569326, -8235660.16384918 4978267.31151836, -8235660.108189434 4978258.1984587535, -8235660.876293919 4978249.232392276, -8235662.189863912 4978241.897862048, -8235664.104559152 4978235.312957839, -8235667.867157943 4978226.596785656)" +163,West 62nd Street,"LINESTRING (-8235666.1305738855 4978565.563134524, -8235680.546447943 4978572.853810958, -8235714.354177297 4978592.109454321, -8235724.740285789 4978597.827358781, -8235742.807439144 4978607.778578384, -8235751.390171884 4978612.4969593175, -8235771.839562343 4978623.75640714, -8235781.268323212 4978628.945164878, -8235795.6730653215 4978636.882646639)" +164,Broadway,"LINESTRING (-8235666.1305738855 4978565.563134524, -8235666.186233632 4978554.156764568, -8235664.794739996 4978459.687251219, -8235664.839267793 4978445.179566528)" +165,Broadway,"LINESTRING (-8235666.9988659145 4978685.433717147, -8235666.93207422 4978675.673506781, -8235666.230761427 4978578.424714562, -8235666.1305738855 4978565.563134524)" +166,West 63rd Street,"LINESTRING (-8235666.9988659145 4978685.433717147, -8235680.546447943 4978691.945429186, -8235730.729274393 4978719.741521946, -8235745.4345791275 4978728.458134223)" +167,Columbus Avenue,"LINESTRING (-8235670.43863818 4978866.058165822, -8235699.047747313 4978812.743619501, -8235738.577298494 4978741.011245506, -8235745.4345791275 4978728.458134223)" +168,Broadway,"LINESTRING (-8235670.43863818 4978866.058165822, -8235670.06015191 4978843.097743775, -8235669.225255731 4978802.410009372, -8235668.835637513 4978796.662586564, -8235667.27716464 4978699.530182768, -8235666.9988659145 4978685.433717147)" +169,Broadway,"LINESTRING (-8235673.2104935 4978929.177555548, -8235672.687291895 4978915.271851514, -8235672.197486133 4978896.735843412, -8235671.473909444 4978888.048479795, -8235670.43863818 4978866.058165822)" +170,West 65th Street,"LINESTRING (-8235673.2104935 4978929.177555548, -8235656.022764121 4978919.519997897, -8235650.35660204 4978916.344912537)" +171,Broadway,"LINESTRING (-8235674.056521631 4979052.286528288, -8235673.956334088 4979040.761992646, -8235674.156709173 4978954.21081261, -8235673.900674342 4978943.744757224, -8235673.2104935 4978929.177555548)" +172,West 66th Street,"LINESTRING (-8235674.056521631 4979052.286528288, -8235688.81748611 4979060.606545893, -8235816.267171119 4979130.900687779, -8235892.999696123 4979172.9862766825, -8235904.487867573 4979181.438695904)" +173,West 67th Street,"LINESTRING (-8235671.65202063 4979169.693510129, -8235685.845255705 4979177.631431383, -8235800.738102153 4979241.767131799, -8235806.682562961 4979244.868823151, -8235842.783473825 4979264.463891295, -8235854.783714933 4979271.225889424)" +174,Broadway,"LINESTRING (-8235671.65202063 4979169.693510129, -8235671.596360885 4979160.094513974, -8235674.368216205 4979062.870297492, -8235674.056521631 4979052.286528288)" +175,West 68th Street,"LINESTRING (-8235667.755838451 4979288.307305554, -8235646.248912829 4979276.459091191)" +176,Broadway,"LINESTRING (-8235667.755838451 4979288.307305554, -8235667.978477433 4979277.194091665, -8235671.262402411 4979182.041390423, -8235671.65202063 4979169.693510129)" +177,Broadway,"LINESTRING (-8235663.53682975 4979406.084629968, -8235663.703808986 4979395.897393895, -8235667.199240997 4979300.140834248, -8235667.755838451 4979288.307305554)" +178,West 69th Street,"LINESTRING (-8235663.53682975 4979406.084629968, -8235679.077030665 4979415.110559409, -8235700.4281089995 4979426.312131649, -8235740.647841022 4979448.362508248, -8235754.306742543 4979453.595804936)" +179,West 70th Street,"LINESTRING (-8235662.746461365 4979525.730323415, -8235638.668055507 4979512.308881933)" +180,Broadway,"LINESTRING (-8235662.746461365 4979525.730323415, -8235663.447774158 4979516.263280629, -8235664.026635509 4979419.682328153, -8235664.171350848 4979417.477294729, -8235663.53682975 4979406.084629968)" +181,West 72nd Street,"LINESTRING (-8235644.3787453845 4979767.304723641, -8235655.56635421 4979773.993566171, -8235900.536025649 4979910.593963501, -8235914.706996826 4979918.135560684)" +182,Broadway,"LINESTRING (-8235644.3787453845 4979767.304723641, -8235647.506823076 4979750.046061001, -8235655.610882006 4979686.789059986, -8235657.358598011 4979662.635960398, -8235658.193494193 4979643.745720248)" +183,West 72nd Street,"LINESTRING (-8235644.3787453845 4979767.304723641, -8235635.083567903 4979762.056558096, -8235611.806662379 4979749.178718453, -8235595.153266557 4979740.005473176)" +184,West 73rd Street,"LINESTRING (-8235619.832797665 4979884.543890943, -8235630.597392424 4979890.6006736215, -8235845.03212754 4980010.369912442, -8235859.448001597 4980018.411424946)" +185,Broadway,"LINESTRING (-8235619.832797665 4979884.543890943, -8235622.18163892 4979874.473763008, -8235641.028028711 4979783.56376422, -8235644.3787453845 4979767.304723641)" +186,West 74th Street,"LINESTRING (-8235597.6579551 4979994.786744353, -8235574.125014746 4979982.173217074)" +187,Broadway,"LINESTRING (-8235597.6579551 4979994.786744353, -8235599.606046188 4979984.128459747, -8235617.127734037 4979895.510786609, -8235619.832797665 4979884.543890943)" +188,West 75th Street,"LINESTRING (-8235574.637084402 4980101.237919004, -8235585.357151367 4980107.897587753, -8235742.072730504 4980197.266959464, -8235756.110118294 4980205.220417439)" +189,Broadway,"LINESTRING (-8235574.637084402 4980101.237919004, -8235576.251217019 4980094.4753461145, -8235595.821183502 4980004.871697466, -8235597.6579551 4979994.786744353)" +190,West 76th Street,"LINESTRING (-8235546.885135348 4980210.571731073, -8235525.289154134 4980198.443071141)" +191,Broadway,"LINESTRING (-8235546.885135348 4980210.571731073, -8235549.323032197 4980201.574469171, -8235571.609194253 4980113.792795003, -8235574.637084402 4980101.237919004)" +192,West 77th Street,"LINESTRING (-8235517.864144097 4980317.863247976, -8235528.873641737 4980324.625975573, -8235634.838665024 4980383.4177982835, -8235639.168993217 4980385.740663264, -8235652.349220925 4980393.400240945)" +193,Broadway,"LINESTRING (-8235517.864144097 4980317.863247976, -8235520.925430095 4980307.836777851, -8235521.938437461 4980304.029074152, -8235544.213467568 4980220.730414197, -8235546.885135348 4980210.571731073)" +194,West 79th Street,"LINESTRING (-8235425.2574597085 4980517.997861814, -8235405.086367975 4980506.809739085)" +195,West 79th Street,"LINESTRING (-8235425.2574597085 4980517.997861814, -8235436.890346494 4980524.466690266, -8235531.267010789 4980577.3201196445, -8235546.139294758 4980585.714946578)" +196,Broadway,"LINESTRING (-8235425.2574597085 4980517.997861814, -8235433.239067197 4980503.575330172, -8235475.807640477 4980426.640819459, -8235477.633280125 4980423.391735366, -8235480.594378582 4980417.12879804)" +197,West 81st Street,"LINESTRING (-8235317.555852365 4980711.638216697, -8235327.641398231 4980717.29855361, -8235424.845577591 4980771.843786577, -8235439.216923854 4980779.621285317)" +198,Broadway,"LINESTRING (-8235317.555852365 4980711.638216697, -8235322.81013233 4980702.081811171, -8235364.009475873 4980627.306936395, -8235369.475262869 4980617.397764739)" +199,West 82nd Street,"LINESTRING (-8235263.81080221 4980803.968277948, -8235242.960661584 4980792.353461089)" +200,Broadway,"LINESTRING (-8235263.81080221 4980803.968277948, -8235268.7311237035 4980795.646774846, -8235282.256441833 4980772.343663436, -8235312.591003076 4980720.062563478, -8235317.555852365 4980711.638216697)" +201,Broadway,"LINESTRING (-8235212.470253055 4980896.166890275, -8235216.9007687885 4980887.815903723, -8235259.035196055 4980812.716155463, -8235263.81080221 4980803.968277948)" +202,West 83rd Street,"LINESTRING (-8235212.470253055 4980896.166890275, -8235222.834097649 4980902.1507882, -8235321.696937422 4980957.211642703, -8235336.669408934 4980965.48917585)" +203,5th Avenue,"LINESTRING (-8233235.714395294 4980171.216122137, -8233242.883370501 4980157.970209494, -8233284.97326997 4980080.862007067, -8233290.7173556965 4980070.674067043)" +204,East 86th Street,"LINESTRING (-8233235.714395294 4980171.216122137, -8233224.660369857 4980165.291477524, -8233208.0737657305 4980156.059036013, -8233176.214127464 4980138.6967771305, -8233145.779378681 4980121.849093961, -8233070.12665274 4980079.700610771, -8233056.1003968995 4980072.114785189)" +205,East 86th Street,"LINESTRING (-8233056.1003968995 4980072.114785189, -8233070.12665274 4980079.700610771, -8233145.779378681 4980121.849093961, -8233176.214127464 4980138.6967771305, -8233208.0737657305 4980156.059036013, -8233224.660369857 4980165.291477524, -8233235.714395294 4980171.216122137)" +206,East 86th Street,"LINESTRING (-8233056.1003968995 4980072.114785189, -8233044.422982315 4980065.631555206, -8233036.485902622 4980061.250599513, -8232900.587068262 4979985.319246829, -8232888.798334186 4979978.659661678)" +207,Madison Avenue,"LINESTRING (-8233056.1003968995 4980072.114785189, -8233047.873886529 4980086.5072771115, -8233006.084549686 4980162.365909922, -8233001.253283785 4980171.201420781)" +208,East 86th Street,"LINESTRING (-8232868.727429997 4979967.663270532, -8232888.798334186 4979978.659661678)" +209,Park Avenue,"LINESTRING (-8232868.727429997 4979967.663270532, -8232860.93506564 4979981.879195654, -8232818.533471597 4980058.2662583385, -8232813.757865443 4980066.704742638)" +210,East 86th Street,"LINESTRING (-8232868.727429997 4979967.663270532, -8232855.936820504 4979960.4891610565, -8232708.750189777 4979879.339765138, -8232697.863143578 4979873.2388867205)" +211,East 86th Street,"LINESTRING (-8232697.863143578 4979873.2388867205, -8232687.054021021 4979867.314422894, -8232668.396874365 4979856.832688008, -8232578.083371484 4979806.423491835, -8232535.136311936 4979782.402403281, -8232519.072909415 4979773.302630577)" +212,East 86th Street,"LINESTRING (-8232697.863143578 4979873.2388867205, -8232708.750189777 4979879.339765138, -8232855.936820504 4979960.4891610565, -8232868.727429997 4979967.663270532)" +213,Lexington Avenue,"LINESTRING (-8232697.863143578 4979873.2388867205, -8232705.811355221 4979858.537990534, -8232746.175802582 4979786.180502033, -8232748.891998159 4979780.961727879, -8232753.56741677 4979772.141270859)" +214,East 86th Street,"LINESTRING (-8232519.072909415 4979773.302630577, -8232535.136311936 4979782.402403281, -8232578.083371484 4979806.423491835, -8232668.396874365 4979856.832688008, -8232687.054021021 4979867.314422894, -8232697.863143578 4979873.2388867205)" +215,East 70th Street,"LINESTRING (-8234079.427079916 4978644.276269712, -8234068.584561512 4978638.470143764, -8234003.830013717 4978602.516336918, -8233913.59443448 4978552.378195195, -8233901.360422442 4978545.572598028)" +216,5th Avenue,"LINESTRING (-8234079.427079916 4978644.276269712, -8234082.755532689 4978638.205560892, -8234125.491085204 4978560.859475195, -8234130.288955256 4978552.863259539)" +217,East 70th Street,"LINESTRING (-8233901.360422442 4978545.572598028, -8233889.983570482 4978539.222671468, -8233744.867482284 4978458.437855031, -8233732.421963215 4978451.500034412)" +218,Madison Avenue,"LINESTRING (-8233901.360422442 4978545.572598028, -8233896.629344084 4978554.024474275, -8233854.4281251235 4978629.239145568, -8233849.496671681 4978638.161463749)" +219,East 70th Street,"LINESTRING (-8233712.495774361 4978440.226086416, -8233700.139310884 4978433.229483774, -8233553.99908337 4978351.901695151, -8233542.266009041 4978345.404908424)" +220,Park Avenue,"LINESTRING (-8233712.495774361 4978440.226086416, -8233707.5420570215 4978449.104135639, -8233663.092184347 4978522.892208002, -8233657.815640484 4978532.564072356)" +221,East 70th Street,"LINESTRING (-8233542.266009041 4978345.404908424, -8233530.610858355 4978338.90812602, -8233379.784080278 4978254.994191428, -8233364.878400463 4978246.616066233)" +222,Lexington Avenue,"LINESTRING (-8233542.266009041 4978345.404908424, -8233546.462753843 4978337.805731244, -8233588.34114628 4978261.740792203, -8233592.649210574 4978253.641932137)" +223,East 70th Street,"LINESTRING (-8233364.878400463 4978246.616066233, -8233349.460650986 4978237.708804169, -8233264.41256002 4978191.0854461705, -8233203.0309927985 4978156.926481503, -8233132.866317751 4978117.652638779, -8233128.502593712 4978115.256821896, -8233116.112734387 4978108.348641539)" +224,3rd Avenue,"LINESTRING (-8233364.878400463 4978246.616066233, -8233360.002606766 4978255.288160864, -8233318.135346278 4978330.074272714, -8233312.79201072 4978340.1134111155)" +225,East 70th Street,"LINESTRING (-8233116.112734387 4978108.348641539, -8233102.086478545 4978100.35279633, -8232865.877651031 4977968.907330743, -8232849.302178853 4977959.485890971)" +226,2nd Avenue,"LINESTRING (-8233116.112734387 4978108.348641539, -8233120.064576308 4978100.926027663, -8233132.610282922 4978077.364777819, -8233160.707322397 4978024.613065185, -8233165.371609061 4978015.8382885745)" +227,East 70th Street,"LINESTRING (-8232849.302178853 4977959.485890971, -8232835.621013434 4977951.842919984, -8232642.359245469 4977843.915989328, -8232614.117490654 4977828.26278845, -8232600.7146239625 4977820.825689593)" +228,1st Avenue,"LINESTRING (-8232849.302178853 4977959.485890971, -8232844.726947781 4977968.539879723, -8232829.665420677 4977995.452028956, -8232810.819030886 4978030.360033704, -8232802.982138735 4978044.70542256, -8232797.928233852 4978054.024057346)" +229,5th Avenue,"LINESTRING (-8234435.0928529985 4978000.4787739515, -8234439.144882463 4977993.203222822, -8234481.446288966 4977918.228616657, -8234486.611513338 4977909.012997076)" +230,East 63rd Street,"LINESTRING (-8234256.51412587 4977901.149596495, -8234268.759269856 4977907.954744667, -8234270.106235695 4977908.807225767, -8234423.72713299 4977994.1585979145, -8234435.0928529985 4978000.4787739515)" +231,Madison Avenue,"LINESTRING (-8234256.51412587 4977901.149596495, -8234251.805311408 4977909.67440489, -8234210.539176172 4977984.3549841065, -8234209.448245161 4977986.339222988, -8234205.552062984 4977993.379599755)" +232,East 63rd Street,"LINESTRING (-8234067.827588974 4977797.162230901, -8234088.087736299 4977808.273760887)" +233,Park Avenue,"LINESTRING (-8234067.827588974 4977797.162230901, -8234062.807079939 4977806.421838345, -8234021.841507329 4977880.734180423, -8234017.032505324 4977889.45004398)" +234,East 63rd Street,"LINESTRING (-8233897.6312195 4977702.406085908, -8233909.631460607 4977709.122909721, -8234053.556430255 4977789.210733737, -8234067.827588974 4977797.162230901)" +235,Lexington Avenue,"LINESTRING (-8233897.6312195 4977702.406085908, -8233902.184186674 4977694.16071332, -8233944.006919365 4977618.409434171, -8233948.370643403 4977610.267014995)" +236,East 63rd Street,"LINESTRING (-8233718.952304829 4977602.168695074, -8233734.88212396 4977611.104772611, -8233885.887013221 4977695.821545386, -8233897.6312195 4977702.406085908)" +237,3rd Avenue,"LINESTRING (-8233718.952304829 4977602.168695074, -8233713.764816558 4977611.604487714, -8233672.576604962 4977686.018231001, -8233668.1572211785 4977694.072527555)" +238,East 63rd Street,"LINESTRING (-8233469.507589858 4977463.425382072, -8233484.680436455 4977471.861624709, -8233704.358319585 4977594.070381864, -8233718.952304829 4977602.168695074)" +239,2nd Avenue,"LINESTRING (-8233469.507589858 4977463.425382072, -8233473.771126355 4977456.003258252, -8233504.094555648 4977403.3577814475, -8233517.230255561 4977380.518374731, -8233521.5605837535 4977373.008131035)" +240,1st Avenue,"LINESTRING (-8233204.032868214 4977317.188535937, -8233199.73593587 4977325.110254736, -8233159.738842827 4977400.888653823, -8233155.564361923 4977408.575285328)" +241,East 63rd Street,"LINESTRING (-8233204.032868214 4977317.188535937, -8233221.064750307 4977326.124352784, -8233263.043330284 4977349.698487764, -8233356.006237046 4977401.30017505, -8233364.555573939 4977406.047367605)" +242,Amsterdam Avenue,"LINESTRING (-8235854.783714933 4979271.225889424, -8235851.5554497 4979277.252891704, -8235849.51830302 4979280.927894921, -8235808.318959477 4979355.604259827, -8235803.9552354375 4979363.527632054)" +243,5th Avenue,"LINESTRING (-8233813.852170729 4979123.271499849, -8233818.026651635 4979115.715816712, -8233860.561829066 4979038.821638494, -8233865.159324036 4979030.50163945)" +244,East 75th Street,"LINESTRING (-8233635.98588834 4979024.709983522, -8233648.765365884 4979031.780508097, -8233804.568125198 4979118.214777413, -8233813.852170729 4979123.271499849)" +245,Madison Avenue,"LINESTRING (-8233635.98588834 4979024.709983522, -8233630.898587611 4979034.294146967, -8233590.155653981 4979111.291187862, -8233585.869853585 4979119.405458914)" +246,East 75th Street,"LINESTRING (-8233447.366143139 4978920.122676254, -8233467.737609955 4978931.26488281)" +247,Park Avenue,"LINESTRING (-8233447.366143139 4978920.122676254, -8233442.490349443 4978929.001161715, -8233400.534033364 4979005.571084047, -8233396.025593986 4979013.788164557)" +248,East 75th Street,"LINESTRING (-8233277.136377819 4978825.429133085, -8233289.10322308 4978832.117330543, -8233435.0876033055 4978913.302123368, -8233447.366143139 4978920.122676254)" +249,Lexington Avenue,"LINESTRING (-8233277.136377819 4978825.429133085, -8233281.622553297 4978817.2857076395, -8233324.068675137 4978740.290984587, -8233328.788621546 4978731.647857692)" +250,East 75th Street,"LINESTRING (-8233097.822942047 4978726.179760954, -8233113.76389313 4978734.999273335, -8233266.549894245 4978819.578801482, -8233277.136377819 4978825.429133085)" +251,3rd Avenue,"LINESTRING (-8233097.822942047 4978726.179760954, -8233093.748648687 4978733.544053243, -8233050.935172527 4978811.023800271, -8233046.29314976 4978819.4318082705)" +252,East 75th Street,"LINESTRING (-8232848.25577564 4978587.729159594, -8232863.094663762 4978595.960587549, -8233083.55178333 4978718.2569057895, -8233097.822942047 4978726.179760954)" +253,2nd Avenue,"LINESTRING (-8232848.25577564 4978587.729159594, -8232853.042513742 4978578.9685760345, -8232869.350819144 4978549.144433532, -8232886.93929869 4978517.306637206, -8232895.366184143 4978501.56416407, -8232900.152922247 4978492.833055457)" +254,East 75th Street,"LINESTRING (-8232584.595561695 4978441.4754802715, -8232596.083733146 4978447.854740807, -8232600.2470821 4978450.1624466805, -8232834.296311494 4978580.056299069, -8232838.504188246 4978582.3199392855, -8232848.25577564 4978587.729159594)" +255,1st Avenue,"LINESTRING (-8232584.595561695 4978441.4754802715, -8232580.454476638 4978448.98654553, -8232553.559687662 4978497.624875043, -8232538.242125728 4978525.346920389, -8232533.845005843 4978533.093232385)" +256,West 37th Street,"LINESTRING (-8236128.262307965 4975786.16875228, -8236143.624397694 4975794.897442096, -8236216.516400267 4975836.366172632, -8236230.6094478015 4975844.389554708, -8236234.138275659 4975846.373358985, -8236249.46696954 4975855.131492308, -8236253.374283669 4975857.350416595)" +257,6th Avenue,"LINESTRING (-8236128.262307965 4975786.16875228, -8236122.99689605 4975795.661570195, -8236082.676976484 4975868.283401895, -8236077.945898126 4975876.835826342)" +258,6th Avenue,"LINESTRING (-8236077.945898126 4975876.835826342, -8236073.303875361 4975885.05027543, -8236031.536802416 4975959.186358238, -8236026.360446092 4975968.9291598005)" +259,West 39th Street,"LINESTRING (-8236026.360446092 4975968.9291598005, -8236041.945174804 4975977.7167930715, -8236189.543687645 4976060.920495112, -8236202.913158491 4976068.63546276)" +260,6th Avenue,"LINESTRING (-8236026.360446092 4975968.9291598005, -8236022.208229086 4975976.159118371, -8235981.743594184 4976050.472234354, -8235976.94572413 4976059.274636136)" +261,West 40th Street,"LINESTRING (-8235976.94572413 4976059.274636136, -8235962.374002785 4976051.177601818, -8235923.924250664 4976029.810868338, -8235788.381638674 4975954.498648729, -8235631.254177421 4975867.195980767, -8235618.91997784 4975860.3481694115)" +262,6th Avenue,"LINESTRING (-8235976.94572413 4976059.274636136, -8235972.003138737 4976068.341559119, -8235966.370372504 4976078.731058197, -8235932.08396934 4976141.832439842, -8235927.553266064 4976150.164674166)" +263,West 41st Street,"LINESTRING (-8235927.553266064 4976150.164674166, -8235942.269702748 4976158.349962424, -8236003.295047601 4976192.281508782, -8236006.456521138 4976194.044953129, -8236016.363955819 4976199.834930979, -8236019.725804442 4976201.804112045, -8236026.471765584 4976205.580826095, -8236140.863674324 4976269.359019266, -8236146.062294544 4976272.254030079, -8236153.632019917 4976276.354072239, -8236158.563473359 4976279.028652642)" +264,6th Avenue,"LINESTRING (-8235927.553266064 4976150.164674166, -8235922.788791859 4976158.952470447, -8235902.595436229 4976196.014133028, -8235880.943795269 4976235.7798956195, -8235874.342549466 4976247.888940469)" +265,6th Avenue,"LINESTRING (-8235874.342549466 4976247.888940469, -8235865.949059859 4976262.951790264, -8235864.691149613 4976265.214893607, -8235824.337834201 4976337.9283890715, -8235819.350721015 4976346.93678825)" +266,West 42nd Street,"LINESTRING (-8235874.342549466 4976247.888940469, -8235889.849354533 4976256.559260929, -8236039.462750158 4976340.264987734, -8236074.851216282 4976360.059968639, -8236087.252207557 4976366.996304028, -8236116.061691774 4976383.117424582, -8236131.145482777 4976391.508647355)" +267,West 42nd Street,"LINESTRING (-8235874.342549466 4976247.888940469, -8235857.655757796 4976238.660201044, -8235820.430520074 4976218.071914092, -8235705.8716321 4976154.1911885375, -8235683.919428514 4976141.935306889, -8235529.797593512 4976055.747796408, -8235513.800982684 4976047.812411671)" +268,6th Avenue,"LINESTRING (-8235819.350721015 4976346.93678825, -8235814.597378756 4976355.4896316985, -8235773.008416996 4976430.657985114, -8235768.422053975 4976438.946378544)" +269,West 43rd Street,"LINESTRING (-8235819.350721015 4976346.93678825, -8235834.2341369325 4976355.239806269, -8235983.914324252 4976438.4614191605, -8236014.248885495 4976455.37622886, -8236059.466862654 4976480.594192399, -8236083.389421227 4976493.93798965, -8236087.57503408 4976496.245233974, -8236115.916976435 4976511.896300623, -8236123.531229606 4976516.128706051, -8236134.830157923 4976522.403838308)" +270,West 44th Street,"LINESTRING (-8235768.422053975 4976438.946378544, -8235753.97278407 4976430.878421018, -8235466.868685365 4976271.2988233715, -8235423.242576924 4976247.051299749, -8235409.572543454 4976239.189236827)" +271,6th Avenue,"LINESTRING (-8235768.422053975 4976438.946378544, -8235763.134378164 4976448.616179767, -8235722.714271056 4976522.447925903, -8235717.805081513 4976531.397711709)" +272,6th Avenue,"LINESTRING (-8235717.805081513 4976531.397711709, -8235713.1185309505 4976539.803757733, -8235672.408993167 4976612.387032904, -8235671.663152577 4976613.709673008, -8235666.8096227795 4976622.365622111)" +273,West 45th Street,"LINESTRING (-8235717.805081513 4976531.397711709, -8235731.809073454 4976539.2012262205, -8235803.06467951 4976578.953689742, -8235953.468443522 4976662.853227806, -8236014.037378462 4976696.595476748, -8236018.968831904 4976699.373045116, -8236021.462388499 4976700.783873795, -8236031.915288683 4976706.60354425)" +274,West 46th Street,"LINESTRING (-8235666.8096227795 4976622.365622111, -8235652.315825079 4976614.253425103, -8235558.161799767 4976561.62718021, -8235321.429770645 4976431.142944111, -8235307.136348027 4976423.545255931)" +275,6th Avenue,"LINESTRING (-8235666.8096227795 4976622.365622111, -8235661.599870609 4976631.800468408, -8235660.876293919 4976633.123111139, -8235620.333735374 4976706.574151965, -8235616.02567108 4976714.377806403)" +276,West 47th Street,"LINESTRING (-8235616.02567108 4976714.377806403, -8235631.432288606 4976722.975060034, -8235694.528175986 4976758.172442247, -8235917.890734264 4976884.72240771, -8235930.158142149 4976891.659115616)" +277,6th Avenue,"LINESTRING (-8235616.02567108 4976714.377806403, -8235610.927238402 4976723.665779885, -8235599.761893475 4976743.946512163, -8235569.8280824 4976798.32259633, -8235565.208323533 4976806.772960907)" +278,West 48th Street,"LINESTRING (-8235565.208323533 4976806.772960907, -8235550.258115918 4976798.46955913, -8235355.22636805 4976690.2320559025, -8235349.860768593 4976687.219352328, -8235333.596990989 4976678.063678387, -8235219.8062074995 4976614.488561154, -8235205.635236322 4976606.596810556)" +279,6th Avenue,"LINESTRING (-8235565.208323533 4976806.772960907, -8235560.187814498 4976815.869970247, -8235518.754700026 4976890.9536874695, -8235514.201732851 4976899.271864286)" +280,6th Avenue,"LINESTRING (-8235514.201732851 4976899.271864286, -8235494.030641119 4976935.70438647, -8235467.77037324 4976983.100670519, -8235462.415905734 4976992.771010362)" +281,West 49th Street,"LINESTRING (-8235514.201732851 4976899.271864286, -8235530.654753589 4976908.413049095, -8235567.03396318 4976928.65007548, -8235655.8112570895 4976978.000966282, -8235716.98131728 4977012.008842555, -8235776.514980956 4977045.105644807, -8235816.85716442 4977067.532760157, -8235828.501183156 4977073.999303633)" +282,West 50th Street,"LINESTRING (-8235462.415905734 4976992.771010362, -8235447.910976084 4976984.658505774, -8235422.68597947 4976968.727447527, -8235259.07972385 4976878.4323463235, -8235256.285604633 4976876.8745280085, -8235246.177794868 4976871.231112793, -8235192.243501578 4976840.721455743, -8235159.393119846 4976822.644969783, -8235119.173387823 4976800.394772011, -8235104.946756899 4976791.88562787)" +283,6th Avenue,"LINESTRING (-8235462.415905734 4976992.771010362, -8235450.994525978 4977013.728345063, -8235447.176267444 4977020.738627643, -8235412.834204535 4977083.037774985)" +284,6th Avenue,"LINESTRING (-8235412.834204535 4977083.037774985, -8235367.2711369535 4977165.736501976, -8235366.926046533 4977166.339072132, -8235364.666260868 4977170.43948954, -8235361.426863685 4977176.318227178)" +285,West 51st Street,"LINESTRING (-8235412.834204535 4977083.037774985, -8235500.988109294 4977132.653987812, -8235567.456977246 4977170.3660053415, -8235591.090105141 4977183.769532219, -8235600.363018724 4977188.913434478, -8235673.433132482 4977228.63914802, -8235713.808711792 4977250.596381984, -8235728.413828985 4977258.532743754)" +286,6th Avenue,"LINESTRING (-8235361.426863685 4977176.318227178, -8235357.697660744 4977183.7107447805, -8235356.773708971 4977184.754221871, -8235339.018250189 4977216.984491674, -8235318.791498711 4977253.682744129, -8235311.678183249 4977266.586687844)" +287,West 52nd Street,"LINESTRING (-8235361.426863685 4977176.318227178, -8235347.055517426 4977168.514203732, -8235345.508176503 4977167.6470904, -8235276.746127039 4977129.538270351, -8235268.063206759 4977124.732425081, -8235252.4450822 4977115.44407028, -8235213.50552432 4977093.69289423, -8235197.219482817 4977084.654413019, -8235050.544921747 4977003.352548209, -8235015.167587575 4976983.747319085, -8235002.8667838415 4976976.413738991)" +288,West 53rd Street,"LINESTRING (-8235311.678183249 4977266.586687844, -8235326.795370102 4977274.978669499, -8235363.942684178 4977295.583880957, -8235424.700862253 4977329.284224183, -8235450.894338436 4977343.702068984, -8235454.556749684 4977345.715571938, -8235487.0286451485 4977363.601963123, -8235499.340580829 4977370.539011082, -8235552.874123953 4977400.359555127, -8235586.971283983 4977419.304245723, -8235594.351766223 4977423.404769315, -8235614.010788295 4977434.310112838, -8235627.157620159 4977441.6146421945)" +289,6th Avenue,"LINESTRING (-8235311.678183249 4977266.586687844, -8235305.1659930395 4977278.403070389, -8235265.6809696555 4977350.065915506, -8235265.135504151 4977351.050621922, -8235261.027814941 4977358.502060245)" +290,West 54th Street,"LINESTRING (-8235261.027814941 4977358.502060245, -8235246.856843763 4977350.65379992, -8235215.79870583 4977333.428801242, -8234915.202684841 4977167.735271413, -8234901.699630607 4977159.79898341)" +291,6th Avenue,"LINESTRING (-8235261.027814941 4977358.502060245, -8235255.550895993 4977368.422623047, -8235223.023340782 4977427.461202951, -8235214.251364908 4977443.304825824, -8235208.985952993 4977452.931529449)" +292,West 55th Street,"LINESTRING (-8235208.985952993 4977452.931529449, -8235223.791445269 4977461.147303864, -8235330.379857703 4977520.436299405, -8235339.496924 4977525.595076323, -8235340.187104843 4977525.977208055, -8235351.22999833 4977532.135409951, -8235396.09175312 4977557.135691881, -8235404.919388739 4977562.132816459, -8235510.695168891 4977620.217228521, -8235524.109167533 4977628.065705422)" +293,6th Avenue,"LINESTRING (-8235208.985952993 4977452.931529449, -8235204.744680394 4977460.530018248, -8235163.122322787 4977535.118979327, -8235159.114821119 4977542.276610074)" +294,6th Avenue,"LINESTRING (-8235159.114821119 4977542.276610074, -8235153.459790986 4977552.417820728, -8235111.447815162 4977627.683569696, -8235103.789034195 4977641.411070138)" +295,West 56th Street,"LINESTRING (-8235159.114821119 4977542.276610074, -8235145.266676464 4977534.604570749, -8235109.744626952 4977514.924788615, -8235069.703006114 4977492.731803304, -8235016.937567477 4977463.484171195, -8234815.1932543125 4977350.712588365, -8234800.521345425 4977342.511603927)" +296,West 57th Street,"LINESTRING (-8235103.789034195 4977641.411070138, -8235119.373762905 4977650.097325032, -8235151.689811083 4977668.08715668, -8235294.04517591 4977747.380967999, -8235404.607694165 4977808.832277278, -8235419.9363880465 4977817.342307294)" +297,6th Avenue,"LINESTRING (-8235103.789034195 4977641.411070138, -8235095.562523826 4977656.446673594, -8235053.795450878 4977732.874341249, -8235049.153428113 4977741.36960739)" +298,West 57th Street,"LINESTRING (-8235103.789034195 4977641.411070138, -8235088.760902938 4977633.077563822, -8234985.790373952 4977575.933712029, -8234759.288606036 4977450.56527012, -8234745.162162656 4977442.746330331)" +299,West 58th Street,"LINESTRING (-8235049.153428113 4977741.36960739, -8235033.8692620285 4977732.903736621, -8234774.661827715 4977589.293702994, -8234763.151392367 4977582.885608238)" +300,6th Avenue,"LINESTRING (-8235049.153428113 4977741.36960739, -8235043.743300861 4977751.1729773255, -8235002.833387995 4977825.279129532, -8234997.812878959 4977840.667764359)" +301,Central Park South,"LINESTRING (-8234997.812878959 4977840.667764359, -8234984.510199809 4977833.289447406, -8234720.927909508 4977687.26752839, -8234707.62523036 4977679.904024911)" +302,Central Park South,"LINESTRING (-8234997.812878959 4977840.667764359, -8235012.384600304 4977848.795677735, -8235017.527560778 4977851.661760917, -8235050.778692679 4977870.210483694, -8235058.326154154 4977874.414081865, -8235092.924251894 4977893.712442142, -8235153.537714631 4977927.517734824, -8235300.112088157 4978009.268234865, -8235313.069676885 4978016.499703622)" +303,West 36th Street,"LINESTRING (-8237757.300604285 4976573.060615622, -8237743.307744292 4976565.154202562, -8237645.580363324 4976512.087346662, -8237633.580122217 4976505.547695917)" +304,11th Avenue,"LINESTRING (-8237757.300604285 4976573.060615622, -8237751.823685338 4976583.171428265, -8237725.385306274 4976631.359587537, -8237711.971307633 4976655.843202032, -8237707.396076561 4976664.1317865085)" +305,11th Avenue,"LINESTRING (-8237707.396076561 4976664.1317865085, -8237711.971307633 4976655.843202032, -8237725.385306274 4976631.359587537, -8237751.823685338 4976583.171428265, -8237757.300604285 4976573.060615622)" +306,11th Avenue,"LINESTRING (-8237707.396076561 4976664.1317865085, -8237701.919157616 4976673.992859824, -8237661.243015679 4976747.370726912, -8237656.623256811 4976755.497730671)" +307,11th Avenue,"LINESTRING (-8237656.623256811 4976755.497730671, -8237651.625011674 4976765.03557915, -8237612.251307782 4976836.679962076, -8237607.086083409 4976846.291371574)" +308,West 38th Street,"LINESTRING (-8237656.623256811 4976755.497730671, -8237643.164730375 4976747.5764737595, -8237567.578796126 4976703.429178117, -8237520.134429149 4976676.358931056, -8237481.027892034 4976654.770389308, -8237444.170008632 4976633.666864314, -8237360.580202996 4976587.492040348, -8237343.22549438 4976580.114669852)" +309,11th Avenue,"LINESTRING (-8237656.623256811 4976755.497730671, -8237661.243015679 4976747.370726912, -8237701.919157616 4976673.992859824, -8237707.396076561 4976664.1317865085)" +310,West 40th Street,"LINESTRING (-8237564.328266994 4976940.43665628, -8237547.407704394 4976932.529945893)" +311,11th Avenue,"LINESTRING (-8237564.328266994 4976940.43665628, -8237571.664221437 4976927.841769338, -8237602.154629967 4976870.790221117, -8237604.52573512 4976857.666354663, -8237607.086083409 4976846.291371574)" +312,11th Avenue,"LINESTRING (-8237513.154697077 4977031.423072198, -8237517.8969073845 4977022.987209914, -8237558.116639408 4976951.06222697, -8237564.328266994 4976940.43665628)" +313,West 42nd Street,"LINESTRING (-8237458.340979812 4977131.6693034135, -8237446.630169378 4977124.717728309)" +314,11th Avenue,"LINESTRING (-8237458.340979812 4977131.6693034135, -8237467.636157291 4977115.179528658, -8237507.744569824 4977041.3579994915, -8237513.154697077 4977031.423072198)" +315,West 42nd Street,"LINESTRING (-8237458.340979812 4977131.6693034135, -8237469.96273465 4977138.562096296, -8237519.856130422 4977166.045135465, -8237618.496331214 4977220.379478405, -8237681.046753091 4977254.814410494, -8237714.6318434635 4977271.113360065, -8237744.888481061 4977287.250669662, -8237757.723618349 4977295.363425541)" +316,11th Avenue,"LINESTRING (-8237398.3843020685 4977225.464612252, -8237402.948401192 4977216.940400946)" +317,West 43rd Street,"LINESTRING (-8237398.3843020685 4977225.464612252, -8237415.282600772 4977234.914737964, -8237661.977724318 4977372.964039602, -8237673.866645936 4977379.607151118)" +318,West 44th Street,"LINESTRING (-8237346.6096069 4977316.674138836, -8237333.529566734 4977309.443188148, -8237332.394107927 4977308.796518022, -8237133.45504593 4977197.9667090345, -8237092.734376198 4977175.054298286, -8237090.474590534 4977173.79036956, -8237048.618461996 4977150.510595269, -8237032.944677693 4977141.810087805)" +319,11th Avenue,"LINESTRING (-8237346.6096069 4977316.674138836, -8237351.919546613 4977307.429692669, -8237353.366699992 4977304.975286334, -8237392.985306766 4977234.503223745, -8237398.3843020685 4977225.464612252)" +320,West 45th Street,"LINESTRING (-8237296.115085877 4977408.575285328, -8237309.974362481 4977416.335408927, -8237314.193371182 4977418.672265538, -8237380.283752865 4977455.092027596, -8237439.194027394 4977488.557764018, -8237509.414362186 4977528.740314869, -8237515.581461976 4977532.326475941, -8237526.8581263935 4977538.073154831)" +321,11th Avenue,"LINESTRING (-8237296.115085877 4977408.575285328, -8237300.155983393 4977401.226689114, -8237341.477778376 4977326.006776192, -8237346.6096069 4977316.674138836)" +322,11th Avenue,"LINESTRING (-8237245.66509265 4977500.712453806, -8237249.472219235 4977493.745918752, -8237290.8830698095 4977418.113771454, -8237296.115085877 4977408.575285328)" +323,West 46th Street,"LINESTRING (-8237245.66509265 4977500.712453806, -8237233.497872307 4977494.201535872, -8237168.186727057 4977459.163171665, -8237022.191214881 4977377.990464269, -8236993.237015327 4977361.926490413, -8236945.258314794 4977335.192451588, -8236930.6420656545 4977327.0355714075)" +324,West 47th Street,"LINESTRING (-8237194.981328492 4977592.674121646, -8237212.658863629 4977602.932964543, -8237404.851964483 4977709.975373466, -8237410.529258514 4977713.135369036, -8237423.89872936 4977720.8075485835)" +325,11th Avenue,"LINESTRING (-8237194.981328492 4977592.674121646, -8237199.434108122 4977584.502328995, -8237240.321757092 4977510.398003412, -8237245.66509265 4977500.712453806)" +326,West 48th Street,"LINESTRING (-8237143.785494676 4977684.680748092, -8237132.041288397 4977678.11091712, -8237089.550638761 4977654.315526046, -8236922.515742827 4977560.751258232, -8236844.324932491 4977517.9230501, -8236829.764343097 4977509.677833232)" +327,11th Avenue,"LINESTRING (-8237143.785494676 4977684.680748092, -8237148.271670154 4977676.62645928, -8237189.971951406 4977601.68367794, -8237194.981328492 4977592.674121646)" +328,West 49th Street,"LINESTRING (-8237093.06833467 4977777.481919791, -8237110.690210063 4977787.402908113, -8237146.2233915245 4977807.641755536, -8237273.806659922 4977877.970974039, -8237309.707195703 4977897.504508278, -8237322.497805196 4977904.603612794)" +329,11th Avenue,"LINESTRING (-8237093.06833467 4977777.481919791, -8237097.498850404 4977769.368763496, -8237115.632795454 4977736.0490419185, -8237138.854041234 4977693.36704146, -8237143.785494676 4977684.680748092)" +330,West 50th Street,"LINESTRING (-8237041.872500854 4977869.813640605, -8237029.148683057 4977862.905633832, -8236956.7576181935 4977823.588879812, -8236822.795742973 4977747.410363414, -8236743.536265528 4977703.376130199, -8236727.851349275 4977694.660432673)" +331,11th Avenue,"LINESTRING (-8237041.872500854 4977869.813640605, -8237046.6258431105 4977861.244773358, -8237088.35952021 4977785.786153773, -8237093.06833467 4977777.481919791)" +332,11th Avenue,"LINESTRING (-8236991.812125843 4977960.911599682, -8236995.875287259 4977953.5184938805, -8237004.547075591 4977937.732835414, -8237037.241610037 4977878.235536319, -8237041.872500854 4977869.813640605)" +333,West 51st Street,"LINESTRING (-8236991.812125843 4977960.911599682, -8237004.69179093 4977968.157730677, -8237009.7568277605 4977971.009150841, -8237114.708843681 4978030.080769171, -8237145.755849663 4978047.351090837, -8237169.25539417 4978060.491253906, -8237188.213103451 4978070.70649356, -8237207.5715629 4978081.3773884075, -8237221.597818741 4978088.82938387)" +334,11th Avenue,"LINESTRING (-8236939.6032846635 4978053.979962839, -8236944.5458700545 4978045.131669068, -8236986.613505624 4977970.156664312, -8236991.812125843 4977960.911599682)" +335,West 52nd Street,"LINESTRING (-8236939.6032846635 4978053.979962839, -8236926.723619579 4978046.939542391, -8236743.14664731 4977945.846131551, -8236697.149433714 4977920.359821783, -8236640.031402989 4977888.39179369, -8236624.29082699 4977879.587743638)" +336,11th Avenue,"LINESTRING (-8236889.531777704 4978145.256019233, -8236894.440967247 4978136.922083047, -8236935.28408842 4978061.711202829, -8236939.6032846635 4978053.979962839)" +337,West 54th Street,"LINESTRING (-8236839.259895662 4978236.091975293, -8236827.014751674 4978229.507074998, -8236695.936051266 4978156.750101617, -8236539.688013988 4978070.015678456, -8236524.938181457 4978061.593617383)" +338,11th Avenue,"LINESTRING (-8236839.259895662 4978236.091975293, -8236844.002105969 4978228.037231788, -8236884.399949178 4978154.236688584, -8236889.531777704 4978145.256019233)" +339,11th Avenue,"LINESTRING (-8236787.563124136 4978331.191365203, -8236791.1698756395 4978324.5329079125, -8236792.639292918 4978321.813671692, -8236833.192983413 4978246.821844659, -8236839.259895662 4978236.091975293)" +340,West 55th Street,"LINESTRING (-8236787.563124136 4978331.191365203, -8236806.097819354 4978341.495079583, -8236839.248763713 4978359.941842174, -8236879.513023533 4978382.136797924, -8236932.701476234 4978412.151513669, -8236940.83893101 4978416.561127083, -8237004.124061526 4978450.853288673, -8237012.07227317 4978455.204124469)" +341,West 56th Street,"LINESTRING (-8236738.8051871685 4978421.823268362, -8236725.658355307 4978414.679691782, -8236647.356225481 4978372.009424442, -8236525.160820439 4978303.940224356, -8236496.629634949 4978288.051109903, -8236438.120110588 4978255.464542529, -8236423.247826617 4978247.189306148)" +342,11th Avenue,"LINESTRING (-8236738.8051871685 4978421.823268362, -8236743.057591718 4978414.003551061, -8236764.186031071 4978375.140236893, -8236783.544490519 4978338.746441444, -8236787.563124136 4978331.191365203)" +343,West 57th Street,"LINESTRING (-8236684.214108886 4978522.260156409, -8236700.878636656 4978531.329365735, -8236760.545883721 4978564.490112039, -8236799.786004227 4978586.141670714, -8236891.2572298115 4978636.544568581, -8236926.077966531 4978656.050221785)" +344,11th Avenue,"LINESTRING (-8236684.214108886 4978522.260156409, -8236676.7445710525 4978535.988914156, -8236659.423258285 4978567.856169267, -8236635.055421751 4978612.673347434, -8236630.691697711 4978620.713709124)" +345,West 57th Street,"LINESTRING (-8236684.214108886 4978522.260156409, -8236669.775970928 4978513.999392846, -8236616.008656875 4978483.866773588, -8236566.3824278815 4978456.321231269, -8236383.217337729 4978353.959501804, -8236368.93504706 4978345.96345553)" +346,11th Avenue,"LINESTRING (-8236684.214108886 4978522.260156409, -8236692.01760519 4978507.914066148, -8236695.858127622 4978500.843920809, -8236733.205816782 4978432.127078352, -8236738.8051871685 4978421.823268362)" +347,West 58th Street,"LINESTRING (-8236630.691697711 4978620.713709124, -8236645.964731849 4978629.239145568, -8236746.4083083905 4978685.286725954, -8236800.442789222 4978715.434665799, -8236930.185655742 4978787.828319225, -8236936.664450105 4978791.444341164)" +348,West 58th Street,"LINESTRING (-8236630.691697711 4978620.713709124, -8236615.964129078 4978612.511658327, -8236329.193988847 4978453.293284183, -8236311.894939977 4978443.768485884)" +349,11th Avenue,"LINESTRING (-8236630.691697711 4978620.713709124, -8236626.2166541815 4978630.165184802, -8236619.036547027 4978643.188539524, -8236607.403660238 4978664.399300021, -8236588.089728584 4978698.751128349, -8236584.549768777 4978704.4249978, -8236579.306620762 4978712.81821487)" +350,11th Avenue,"LINESTRING (-8236630.691697711 4978620.713709124, -8236635.055421751 4978612.673347434, -8236659.423258285 4978567.856169267, -8236676.7445710525 4978535.988914156, -8236684.214108886 4978522.260156409)" +351,West End Avenue,"LINESTRING (-8236579.306620762 4978712.81821487, -8236573.740646222 4978721.94639784, -8236558.445348186 4978749.7866736315, -8236549.673372312 4978766.044020272, -8236533.676761485 4978795.8688251125, -8236528.667384399 4978804.997085704)" +352,11th Avenue,"LINESTRING (-8236579.306620762 4978712.81821487, -8236584.549768777 4978704.4249978, -8236588.089728584 4978698.751128349, -8236607.403660238 4978664.399300021, -8236619.036547027 4978643.188539524, -8236626.2166541815 4978630.165184802, -8236630.691697711 4978620.713709124)" +353,West 59th Street,"LINESTRING (-8236579.306620762 4978712.81821487, -8236595.603794212 4978721.961097014, -8236614.260940869 4978732.441613925, -8236726.894001653 4978793.414044733)" +354,West 62nd Street,"LINESTRING (-8236426.8657100685 4978988.578359877, -8236443.2408071635 4978997.780298535, -8236498.811496968 4979028.590686606, -8236501.794859322 4979030.237045957)" +355,West End Avenue,"LINESTRING (-8236426.8657100685 4978988.578359877, -8236421.733881542 4978997.809697714, -8236397.121142128 4979042.6288489, -8236381.002079863 4979072.263402265, -8236376.037230573 4979081.171425466)" +356,West End Avenue,"LINESTRING (-8236426.8657100685 4978988.578359877, -8236431.129246566 4978980.890484869, -8236452.380137358 4978942.451200597, -8236472.239534517 4978906.246384016, -8236477.939092444 4978896.559450165)" +357,West 63rd Street,"LINESTRING (-8236376.037230573 4979081.171425466, -8236392.167424789 4979089.888360327, -8236490.317819821 4979145.379991474)" +358,West 63rd Street,"LINESTRING (-8236376.037230573 4979081.171425466, -8236361.409849483 4979073.071885882, -8236305.58312485 4979040.276904072, -8236248.899240138 4979007.849522493)" +359,West End Avenue,"LINESTRING (-8236376.037230573 4979081.171425466, -8236370.50465188 4979090.711545134, -8236351.112796584 4979126.4319527, -8236329.906433588 4979164.916060634, -8236325.442522007 4979172.824578298)" +360,West End Avenue,"LINESTRING (-8236376.037230573 4979081.171425466, -8236381.002079863 4979072.263402265, -8236397.121142128 4979042.6288489, -8236421.733881542 4978997.809697714, -8236426.8657100685 4978988.578359877)" +361,West 64th Street,"LINESTRING (-8236325.442522007 4979172.824578298, -8236311.193627185 4979164.504465094, -8236280.235676796 4979147.393865872, -8236135.164116395 4979065.457442818, -8236085.805054177 4979037.777963312, -8236025.32517483 4979004.306918427, -8236007.937070366 4978994.649286485)" +362,West 64th Street,"LINESTRING (-8236325.442522007 4979172.824578298, -8236341.394605038 4979181.703293494, -8236439.667451509 4979236.401649085)" +363,West End Avenue,"LINESTRING (-8236325.442522007 4979172.824578298, -8236329.906433588 4979164.916060634, -8236351.112796584 4979126.4319527, -8236370.50465188 4979090.711545134, -8236376.037230573 4979081.171425466)" +364,West End Avenue,"LINESTRING (-8236325.442522007 4979172.824578298, -8236320.154846194 4979182.438286835, -8236298.81489981 4979220.922615467, -8236279.768134935 4979255.937900323, -8236274.614042511 4979265.595790654)" +365,West End Avenue,"LINESTRING (-8236274.614042511 4979265.595790654, -8236268.814297039 4979275.900490869, -8236247.574538196 4979314.311687473, -8236228.394189932 4979349.106805397, -8236221.837471926 4979361.10210926)" +366,West End Avenue,"LINESTRING (-8236274.614042511 4979265.595790654, -8236279.768134935 4979255.937900323, -8236298.81489981 4979220.922615467, -8236320.154846194 4979182.438286835, -8236325.442522007 4979172.824578298)" +367,West 65th Street,"LINESTRING (-8236274.614042511 4979265.595790654, -8236259.519119558 4979257.466698156, -8236221.770680231 4979236.5927484175, -8236168.381852447 4979207.178194975, -8235973.394632373 4979098.32600789, -8235956.095583503 4979087.771599714)" +368,West 66th Street,"LINESTRING (-8236221.837471926 4979361.10210926, -8236237.043714369 4979369.6722924905, -8236264.561892494 4979385.004560151, -8236307.809514666 4979409.083472048, -8236350.300164301 4979432.750836468)" +369,West End Avenue,"LINESTRING (-8236221.837471926 4979361.10210926, -8236215.648108237 4979372.171318175, -8236187.4508812195 4979423.4896870395, -8236175.907050025 4979443.849527117, -8236172.1889790315 4979450.773352441, -8236156.348215493 4979479.042015046, -8236145.817391663 4979498.31414551, -8236140.240285175 4979508.486788063, -8236117.041303292 4979550.132991549, -8236103.616172703 4979574.741527068, -8236088.743888734 4979601.55519909, -8236082.287358266 4979613.374406846, -8236078.079481514 4979621.106881354, -8236063.240593392 4979648.097087502, -8236028.475516418 4979710.398294799, -8236022.108041544 4979721.820715941)" +370,West End Avenue,"LINESTRING (-8236221.837471926 4979361.10210926, -8236228.394189932 4979349.106805397, -8236247.574538196 4979314.311687473, -8236268.814297039 4979275.900490869, -8236274.614042511 4979265.595790654)" +371,West 70th Street,"LINESTRING (-8236022.108041544 4979721.820715941, -8236008.393480279 4979713.676543, -8235960.091953224 4979690.464217321, -8235949.549997445 4979685.157290574, -8235935.746380587 4979677.777580055, -8235887.088631162 4979650.346274715, -8235792.3112167 4979598.05648113, -8235718.038852442 4979556.512976284, -8235701.942054072 4979547.075304488)" +372,West 70th Street,"LINESTRING (-8236022.108041544 4979721.820715941, -8236037.0248533115 4979732.155298963, -8236079.637954386 4979755.05900842, -8236140.440660258 4979788.062201568, -8236197.224732512 4979821.006702938, -8236207.043111599 4979826.225498493)" +373,West End Avenue,"LINESTRING (-8236022.108041544 4979721.820715941, -8236015.551323537 4979734.65441741, -8235973.995757624 4979809.628268214, -8235969.754485025 4979817.155086599)" +374,West End Avenue,"LINESTRING (-8236022.108041544 4979721.820715941, -8236028.475516418 4979710.398294799, -8236063.240593392 4979648.097087502, -8236078.079481514 4979621.106881354, -8236082.287358266 4979613.374406846, -8236088.743888734 4979601.55519909, -8236103.616172703 4979574.741527068, -8236117.041303292 4979550.132991549, -8236140.240285175 4979508.486788063, -8236145.817391663 4979498.31414551, -8236156.348215493 4979479.042015046, -8236172.1889790315 4979450.773352441, -8236175.907050025 4979443.849527117, -8236187.4508812195 4979423.4896870395, -8236215.648108237 4979372.171318175, -8236221.837471926 4979361.10210926)" +375,West 71st Street,"LINESTRING (-8235969.754485025 4979817.155086599, -8235984.67129679 4979825.402251686, -8236171.621249629 4979930.675500277)" +376,West End Avenue,"LINESTRING (-8235969.754485025 4979817.155086599, -8235973.995757624 4979809.628268214, -8236015.551323537 4979734.65441741, -8236022.108041544 4979721.820715941)" +377,West End Avenue,"LINESTRING (-8235969.754485025 4979817.155086599, -8235965.112462259 4979826.37250686, -8235945.275328998 4979862.051502709, -8235922.4548333865 4979903.478699764, -8235914.706996826 4979918.135560684)" +378,West 72nd Street,"LINESTRING (-8235914.706996826 4979918.135560684, -8235900.536025649 4979910.593963501, -8235655.56635421 4979773.993566171, -8235644.3787453845 4979767.304723641)" +379,West End Avenue,"LINESTRING (-8235914.706996826 4979918.135560684, -8235906.847840777 4979933.174669529, -8235883.615463047 4979974.337549243, -8235864.000968771 4980010.01708572, -8235859.448001597 4980018.411424946)" +380,West 72nd Street,"LINESTRING (-8235914.706996826 4979918.135560684, -8235929.345509867 4979926.309306116, -8235968.218276051 4979948.3020076575, -8236037.381075681 4979985.333947904, -8236048.913774927 4979991.390793099)" +381,West End Avenue,"LINESTRING (-8235914.706996826 4979918.135560684, -8235922.4548333865 4979903.478699764, -8235945.275328998 4979862.051502709, -8235965.112462259 4979826.37250686, -8235969.754485025 4979817.155086599)" +382,West 73rd Street,"LINESTRING (-8235859.448001597 4980018.411424946, -8235873.663500573 4980026.320633833, -8236001.703178883 4980097.459698356, -8236007.992730112 4980100.458752759, -8236014.05964236 4980103.0755754905)" +383,West End Avenue,"LINESTRING (-8235859.448001597 4980018.411424946, -8235864.000968771 4980010.01708572, -8235883.615463047 4979974.337549243, -8235906.847840777 4979933.174669529, -8235914.706996826 4979918.135560684)" +384,West End Avenue,"LINESTRING (-8235859.448001597 4980018.411424946, -8235854.817110781 4980026.952782776, -8235811.892315132 4980104.501597162, -8235808.129716341 4980111.602306109)" +385,West 74th Street,"LINESTRING (-8235808.129716341 4980111.602306109, -8235793.457807455 4980103.222588023, -8235607.854820455 4980000.431964638, -8235597.6579551 4979994.786744353)" +386,West End Avenue,"LINESTRING (-8235808.129716341 4980111.602306109, -8235811.892315132 4980104.501597162, -8235854.817110781 4980026.952782776, -8235859.448001597 4980018.411424946)" +387,West End Avenue,"LINESTRING (-8235808.129716341 4980111.602306109, -8235803.031283664 4980120.717095348, -8235781.646809483 4980159.322732492, -8235760.462710384 4980197.443376207, -8235756.110118294 4980205.220417439)" +388,West 75th Street,"LINESTRING (-8235756.110118294 4980205.220417439, -8235770.114110237 4980213.365000344, -8235935.768644487 4980305.116989344, -8235947.523982714 4980311.629781468)" +389,West End Avenue,"LINESTRING (-8235756.110118294 4980205.220417439, -8235760.462710384 4980197.443376207, -8235781.646809483 4980159.322732492, -8235803.031283664 4980120.717095348, -8235808.129716341 4980111.602306109)" +390,West End Avenue,"LINESTRING (-8235756.110118294 4980205.220417439, -8235751.668470612 4980213.482611699, -8235709.378196058 4980290.841787491, -8235704.958812275 4980298.618903111)" +391,West 76th Street,"LINESTRING (-8235704.958812275 4980298.618903111, -8235690.197847796 4980290.724175205, -8235557.182188247 4980216.584611704, -8235546.885135348 4980210.571731073)" +392,West End Avenue,"LINESTRING (-8235704.958812275 4980298.618903111, -8235709.378196058 4980290.841787491, -8235751.668470612 4980213.482611699, -8235756.110118294 4980205.220417439)" +393,West End Avenue,"LINESTRING (-8235704.958812275 4980298.618903111, -8235700.361317305 4980306.660652998, -8235677.485161947 4980347.575179579, -8235657.826139873 4980383.814743524, -8235652.349220925 4980393.400240945)" +394,West 77th Street,"LINESTRING (-8235652.349220925 4980393.400240945, -8235666.364344817 4980401.1921399515, -8235831.785108135 4980493.342843579, -8235837.295422929 4980496.4155288, -8235849.284532088 4980503.090168929)" +395,West End Avenue,"LINESTRING (-8235652.349220925 4980393.400240945, -8235648.130212224 4980400.677580392, -8235606.21842394 4980477.067919318, -8235601.899227698 4980484.668761328)" +396,West End Avenue,"LINESTRING (-8235652.349220925 4980393.400240945, -8235657.826139873 4980383.814743524, -8235677.485161947 4980347.575179579, -8235700.361317305 4980306.660652998, -8235704.958812275 4980298.618903111)" +397,West 79th Street,"LINESTRING (-8235546.139294758 4980585.714946578, -8235559.720272637 4980592.904217412, -8235660.330828416 4980648.889558727, -8235699.3149140915 4980670.560441408, -8235711.137044013 4980677.279306935)" +398,West 79th Street,"LINESTRING (-8235546.139294758 4980585.714946578, -8235531.267010789 4980577.3201196445, -8235436.890346494 4980524.466690266, -8235425.2574597085 4980517.997861814)" +399,West End Avenue,"LINESTRING (-8235546.139294758 4980585.714946578, -8235538.213347016 4980599.902367521, -8235521.882777716 4980629.909198275, -8235495.143836027 4980678.205540402, -8235490.869167581 4980685.924156031)" +400,West End Avenue,"LINESTRING (-8235546.139294758 4980585.714946578, -8235553.597700643 4980572.247942244, -8235572.933896193 4980537.036812351, -8235596.7117394265 4980493.84270618, -8235601.899227698 4980484.668761328)" +401,West 81st Street,"LINESTRING (-8235439.216923854 4980779.621285317, -8235453.387895032 4980787.178256001, -8235565.987559969 4980850.310064524, -8235576.4627240505 4980856.191017635)" +402,West End Avenue,"LINESTRING (-8235439.216923854 4980779.621285317, -8235443.8144188225 4980770.755819384, -8235463.963246655 4980734.044348783, -8235486.394124051 4980694.010331332, -8235490.869167581 4980685.924156031)" +403,West End Avenue,"LINESTRING (-8235439.216923854 4980779.621285317, -8235435.042442949 4980787.3840879705, -8235392.473869667 4980863.630428394, -8235387.698263513 4980872.4665738335)" +404,West 82nd Street,"LINESTRING (-8235387.698263513 4980872.4665738335, -8235372.525416918 4980864.14501235, -8235275.343501457 4980810.481402815, -8235263.81080221 4980803.968277948)" +405,West End Avenue,"LINESTRING (-8235387.698263513 4980872.4665738335, -8235392.473869667 4980863.630428394, -8235435.042442949 4980787.3840879705, -8235439.216923854 4980779.621285317)" +406,West End Avenue,"LINESTRING (-8235387.698263513 4980872.4665738335, -8235383.267747779 4980880.597010894, -8235361.727426313 4980919.088032672, -8235340.921813482 4980957.432180795, -8235336.669408934 4980965.48917585)" +407,West End Avenue,"LINESTRING (-8235336.669408934 4980965.48917585, -8235340.921813482 4980957.432180795, -8235361.727426313 4980919.088032672, -8235383.267747779 4980880.597010894, -8235387.698263513 4980872.4665738335)" +408,East 56th Street,"LINESTRING (-8234800.521345425 4977342.511603927, -8234786.695464669 4977334.883812754, -8234620.896215081 4977243.350783259)" +409,5th Avenue,"LINESTRING (-8234800.521345425 4977342.511603927, -8234804.684694382 4977335.104269064, -8234845.884037925 4977261.6925932905, -8234851.216241534 4977252.198350784)" +410,7th Avenue,"LINESTRING (-8235475.084063787 4977717.147830002, -8235478.245537324 4977711.430441068, -8235520.413360436 4977635.120521503, -8235524.109167533 4977628.065705422)" +411,West 56th Street,"LINESTRING (-8235475.084063787 4977717.147830002, -8235460.4344187975 4977709.152305021, -8235383.546046507 4977667.161208655, -8235373.627479877 4977661.73780055, -8235360.758946741 4977654.6094774045, -8235352.276401543 4977649.906256736, -8235343.081411605 4977644.776809272, -8235296.839295127 4977619.012032251, -8235290.861438473 4977615.675697013, -8235227.086502198 4977580.151881021, -8235173.541827125 4977550.316090698, -8235159.114821119 4977542.276610074)" +412,8th Avenue,"LINESTRING (-8235791.810278992 4977892.433722499, -8235785.765630641 4977903.266099954, -8235745.857593192 4977974.757152834, -8235742.317633385 4977981.106712436, -8235735.716387581 4977992.938657429)" +413,West 56th Street,"LINESTRING (-8235791.810278992 4977892.433722499, -8235776.982522818 4977884.188189503, -8235653.117325412 4977815.284613691, -8235642.842536411 4977809.596562918)" +414,9th Avenue,"LINESTRING (-8236106.9334935285 4978071.044552034, -8236111.864946971 4978062.416715528, -8236138.403513576 4978015.985269692, -8236154.344464657 4977988.073595083, -8236158.207250988 4977981.3271833295)" +415,West 56th Street,"LINESTRING (-8236106.9334935285 4978071.044552034, -8236092.328376337 4978062.607791893, -8235952.4888320025 4977981.37127751, -8235933.4531990765 4977970.935660618, -8235892.521022312 4977947.8891546475, -8235808.508202611 4977901.619930556, -8235791.810278992 4977892.433722499)" +416,West 56th Street,"LINESTRING (-8236423.247826617 4978247.189306148, -8236409.611188996 4978239.59020538, -8236122.696333426 4978079.81937824, -8236106.9334935285 4978071.044552034)" +417,10th Avenue,"LINESTRING (-8236423.247826617 4978247.189306148, -8236418.639199698 4978255.464542529, -8236401.763164896 4978286.14030232, -8236376.293265401 4978332.602429583, -8236368.93504706 4978345.96345553)" +418,East 64th Street,"LINESTRING (-8234383.774567743 4978092.636223983, -8234372.876389595 4978086.56585802, -8234219.711902212 4978001.257772676, -8234218.364936374 4978000.508170128, -8234205.552062984 4977993.379599755)" +419,5th Avenue,"LINESTRING (-8234383.774567743 4978092.636223983, -8234387.859993056 4978085.301811345, -8234430.061212014 4978009.5181026, -8234435.0928529985 4978000.4787739515)" +420,East 64th Street,"LINESTRING (-8234205.552062984 4977993.379599755, -8234195.154822544 4977987.5885587875, -8234193.685405265 4977986.780165017, -8234048.691768507 4977906.896492371, -8234037.170201209 4977900.54698101)" +421,Madison Avenue,"LINESTRING (-8234205.552062984 4977993.379599755, -8234200.731929032 4978002.080865735, -8234159.120703373 4978077.3500796165, -8234153.777367815 4978087.256674295)" +422,East 64th Street,"LINESTRING (-8234017.032505324 4977889.45004398, -8234003.718694226 4977882.012898536, -8233858.713925519 4977800.954259555, -8233846.4353856845 4977794.105092594)" +423,Park Avenue,"LINESTRING (-8234017.032505324 4977889.45004398, -8234012.5574617945 4977897.504508278, -8233970.823784697 4977972.787614352, -8233965.513844986 4977982.223765016)" +424,East 64th Street,"LINESTRING (-8233846.4353856845 4977794.105092594, -8233835.60399923 4977788.020214385, -8233683.875533279 4977702.891108043, -8233668.1572211785 4977694.072527555)" +425,Lexington Avenue,"LINESTRING (-8233846.4353856845 4977794.105092594, -8233851.344575228 4977785.301127524, -8233893.067120377 4977710.592674848, -8233897.6312195 4977702.406085908)" +426,East 64th Street,"LINESTRING (-8233668.1572211785 4977694.072527555, -8233653.841534663 4977686.179904771, -8233432.939137133 4977563.382098003, -8233419.035332733 4977555.313211788)" +427,3rd Avenue,"LINESTRING (-8233668.1572211785 4977694.072527555, -8233663.459538667 4977702.597155231, -8233621.926236653 4977777.849363622, -8233617.373269478 4977786.109504621)" +428,East 64th Street,"LINESTRING (-8233419.035332733 4977555.313211788, -8233409.684495506 4977550.110326942, -8233405.532278499 4977547.802833704, -8233171.182486483 4977417.261333179, -8233155.564361923 4977408.575285328)" +429,2nd Avenue,"LINESTRING (-8233419.035332733 4977555.313211788, -8233423.176417791 4977547.77343889, -8233432.148768748 4977531.429935549, -8233464.954622685 4977471.685257193, -8233469.507589858 4977463.425382072)" +430,East 64th Street,"LINESTRING (-8233155.564361923 4977408.575285328, -8233140.324723632 4977400.09500579, -8232919.70062483 4977277.227310292, -8232906.030591361 4977269.908206866)" +431,1st Avenue,"LINESTRING (-8233155.564361923 4977408.575285328, -8233150.933471106 4977417.14375549, -8233108.81017579 4977493.613642818, -8233104.335132261 4977501.550202027)" +432,East 68th Street,"LINESTRING (-8234180.727816536 4978461.127731724, -8234169.651527204 4978454.954245333, -8234014.294045851 4978368.437653716, -8234002.527575675 4978361.867362827)" +433,5th Avenue,"LINESTRING (-8234180.727816536 4978461.127731724, -8234185.303047609 4978452.881718634, -8234227.192571993 4978377.271541718, -8234231.689879422 4978369.231380431)" +434,Madison Avenue,"LINESTRING (-8234002.527575675 4978361.867362827, -8233997.495934691 4978370.921724576, -8233956.285459198 4978446.473057296, -8233952.2890894795 4978453.793042376)" +435,East 68th Street,"LINESTRING (-8234002.527575675 4978361.867362827, -8233991.061668122 4978355.4146653395, -8233846.702552463 4978275.057625711, -8233833.8896790715 4978267.928854964)" +436,East 68th Street,"LINESTRING (-8233813.885566575 4978256.787405122, -8233801.929853266 4978250.1289985515, -8233653.017770432 4978167.21531371, -8233643.332974733 4978161.821024614)" +437,Park Avenue,"LINESTRING (-8233813.885566575 4978256.787405122, -8233809.321467455 4978265.26842845, -8233767.921748827 4978340.627862118, -8233763.468969195 4978348.712095697)" +438,East 68th Street,"LINESTRING (-8233643.332974733 4978161.821024614, -8233631.366129473 4978155.162682785, -8233480.951233513 4978071.397308714, -8233464.698587856 4978062.357922801)" +439,Lexington Avenue,"LINESTRING (-8233643.332974733 4978161.821024614, -8233647.674434873 4978153.795738996, -8233689.842257985 4978077.541156272, -8233693.949947196 4978070.192056776)" +440,East 68th Street,"LINESTRING (-8233464.698587856 4978062.357922801, -8233449.826303887 4978054.068151853, -8233377.00109301 4978013.515987205, -8233330.848032126 4977987.823727896, -8233272.728125983 4977955.458632437, -8233230.248608296 4977931.809545569, -8233214.97557416 4977923.299415827)" +441,3rd Avenue,"LINESTRING (-8233464.698587856 4978062.357922801, -8233459.845058058 4978071.103344813, -8233418.244964348 4978146.373090584, -8233413.948032004 4978154.192593625)" +442,East 68th Street,"LINESTRING (-8233214.97557416 4977923.299415827, -8233201.572707468 4977915.832848689, -8232967.2340474 4977785.345220817, -8232949.434060822 4977775.438932335)" +443,2nd Avenue,"LINESTRING (-8233214.97557416 4977923.299415827, -8233219.561937179 4977915.097950657, -8233246.857476324 4977866.271449288, -8233261.217690635 4977840.315016012, -8233266.549894245 4977830.864304605)" +444,East 68th Street,"LINESTRING (-8232949.434060822 4977775.438932335, -8232936.932882004 4977768.486899088, -8232725.3145300085 4977650.641134815, -8232715.507282869 4977645.188340774, -8232702.082152279 4977637.707288676)" +445,1st Avenue,"LINESTRING (-8232949.434060822 4977775.438932335, -8232945.3041077135 4977783.22874291, -8232912.030711915 4977847.061330372, -8232904.34966705 4977860.759743362, -8232900.097262503 4977868.2115705125)" +446,East 41st Street,"LINESTRING (-8235569.58317952 4975950.148926559, -8235555.44560419 4975942.272407556, -8235401.958290283 4975856.894875806, -8235389.501639265 4975849.9295128435)" +447,5th Avenue,"LINESTRING (-8235569.58317952 4975950.148926559, -8235573.724264579 4975942.610392383, -8235613.821545161 4975869.620636151, -8235618.91997784 4975860.3481694115)" +448,East 41st Street,"LINESTRING (-8235389.501639265 4975849.9295128435, -8235379.716656025 4975844.507113469, -8235231.472490133 4975762.010600917, -8235225.271994498 4975758.572036783)" +449,Madison Avenue,"LINESTRING (-8235389.501639265 4975849.9295128435, -8235384.213963453 4975859.246054298, -8235342.068404238 4975933.411331267, -8235333.652650733 4975948.238576218)" +450,West 73rd Street,"LINESTRING (-8234911.785176475 4979490.405364257, -8234924.575785967 4979497.69673113, -8235000.896428854 4979540.886431207, -8235211.512905436 4979658.122880247, -8235217.323782855 4979661.31290737, -8235227.643099652 4979666.972635474)" +451,Central Park West,"LINESTRING (-8234911.785176475 4979490.405364257, -8234908.523515395 4979496.211996708, -8234863.650628654 4979576.22627343, -8234859.253508768 4979584.267428433)" +452,Central Park West,"LINESTRING (-8234911.785176475 4979490.405364257, -8234915.748150347 4979483.27570635, -8234959.48557828 4979403.5267948015, -8234966.532102046 4979390.9581317445)" +453,Columbus Avenue,"LINESTRING (-8235227.643099652 4979666.972635474, -8235232.507761398 4979657.887670915, -8235255.4618404005 4979615.006164266, -8235274.564265021 4979579.577978915, -8235282.28983768 4979565.862454532)" +454,West 73rd Street,"LINESTRING (-8235227.643099652 4979666.972635474, -8235240.667480073 4979674.220032358, -8235528.606474959 4979834.237457662, -8235540.205965901 4979840.411815998)" +455,Amsterdam Avenue,"LINESTRING (-8235540.205965901 4979840.411815998, -8235534.595463564 4979849.217633813, -8235493.718946544 4979925.956482432, -8235489.31069471 4979933.997925423)" +456,West 73rd Street,"LINESTRING (-8235540.205965901 4979840.411815998, -8235556.915021468 4979849.305839039, -8235585.846957127 4979865.682623316, -8235597.201545187 4979872.018711495)" +457,Riverside Drive,"LINESTRING (-8236014.05964236 4980103.0755754905, -8236017.4103590315 4980092.593587535, -8236042.857994628 4980010.913853663, -8236048.913774927 4979991.390793099)" +458,Riverside Drive,"LINESTRING (-8236014.05964236 4980103.0755754905, -8236010.653265943 4980113.484068352, -8235984.281678572 4980197.443376207, -8235981.543219099 4980206.028994861)" +459,West 49th Street,"LINESTRING (-8235155.708444701 4976698.697023111, -8235169.801492235 4976706.5888481075, -8235198.978330772 4976722.901579199, -8235210.188203495 4976729.176844271, -8235242.882737941 4976747.4736003345, -8235280.954003791 4976768.768422227, -8235298.386636051 4976778.526727411, -8235310.464800802 4976785.2870047875, -8235499.463032271 4976891.027169566, -8235514.201732851 4976899.271864286)" +460,5th Avenue,"LINESTRING (-8235155.708444701 4976698.697023111, -8235160.806877378 4976689.291504443, -8235200.915289912 4976615.311537375, -8235205.635236322 4976606.596810556)" +461,West 49th Street,"LINESTRING (-8235828.501183156 4977073.999303633, -8235844.341946696 4977082.743840825, -8235866.7394282445 4977095.265443846, -8235901.49337327 4977114.591658415, -8235909.040834746 4977118.706750865, -8235919.1597764585 4977124.071070412)" +462,7th Avenue,"LINESTRING (-8235828.501183156 4977073.999303633, -8235833.343581007 4977065.387044402, -8235875.233105392 4976991.9186092, -8235880.576440949 4976982.5422013365)" +463,West 49th Street,"LINESTRING (-8236146.863794877 4977251.007896881, -8236158.329702428 4977257.371683017, -8236162.370599944 4977259.620319758, -8236195.332301168 4977277.947463335, -8236278.5213566385 4977324.199036291, -8236316.648282234 4977345.392235669, -8236346.070023652 4977361.750124881, -8236440.212917015 4977414.086736115, -8236448.906969246 4977418.922118164, -8236462.5213429695 4977426.49118606)" +464,8th Avenue,"LINESTRING (-8236146.863794877 4977251.007896881, -8236141.442535675 4977260.663804956, -8236100.220928233 4977333.957896312, -8236095.100231658 4977343.070093689)" +465,West 49th Street,"LINESTRING (-8236462.5213429695 4977426.49118606, -8236478.306446764 4977435.26543327, -8236764.931871659 4977594.6141885305, -8236778.646432926 4977602.24218252)" +466,9th Avenue,"LINESTRING (-8236462.5213429695 4977426.49118606, -8236466.8294072645 4977418.525293408, -8236499.345830524 4977359.56025313, -8236508.529688514 4977342.967213993, -8236513.438878059 4977334.031381741)" +467,West 49th Street,"LINESTRING (-8236778.646432926 4977602.24218252, -8236792.884195797 4977610.428687511, -8236820.9589713765 4977626.257909621, -8237047.304892005 4977752.040142457, -8237080.366780771 4977770.412303149, -8237093.06833467 4977777.481919791)" +468,10th Avenue,"LINESTRING (-8236778.646432926 4977602.24218252, -8236773.425548807 4977611.339932657, -8236732.582427634 4977686.047626231, -8236727.851349275 4977694.660432673)" +469,12th Avenue,"LINESTRING (-8237346.0196135985 4977917.743583831, -8237365.511656438 4977882.203971372, -8237397.204315466 4977825.49959691)" +470,5th Avenue,"LINESTRING (-8235359.100286328 4976331.859113394, -8235363.953816127 4976322.953597069, -8235404.195812048 4976249.064576691, -8235409.572543454 4976239.189236827)" +471,West 45th Street,"LINESTRING (-8235359.100286328 4976331.859113394, -8235372.903903187 4976339.721250888, -8235418.032824755 4976364.997698411, -8235607.053320122 4976470.468790126, -8235673.422000533 4976506.987888291, -8235702.376200089 4976522.918193589, -8235717.805081513 4976531.397711709)" +472,West 45th Street,"LINESTRING (-8236349.431872273 4976882.385678826, -8236365.617726235 4976891.394580055, -8236628.353988403 4977037.713232092, -8236650.562226819 4977050.073114147, -8236665.679413668 4977058.126886376)" +473,8th Avenue,"LINESTRING (-8236349.431872273 4976882.385678826, -8236344.277779849 4976891.673812038, -8236321.1567216115 4976933.602789121, -8236303.067304358 4976966.3760020165, -8236298.525469133 4976974.591367237)" +474,West 45th Street,"LINESTRING (-8236665.679413668 4977058.126886376, -8236680.262266961 4977066.239451974, -8236969.080685825 4977226.728547666, -8236982.06053845 4977233.94474019)" +475,9th Avenue,"LINESTRING (-8236665.679413668 4977058.126886376, -8236669.954082115 4977050.293564029, -8236703.717283673 4976988.450219036, -8236711.665495315 4976974.5325810565, -8236716.541289011 4976965.979195643)" +476,10th Avenue,"LINESTRING (-8236982.06053845 4977233.94474019, -8236977.2960642455 4977242.542451077, -8236935.573519097 4977318.099753729, -8236930.6420656545 4977327.0355714075)" +477,West 45th Street,"LINESTRING (-8236982.06053845 4977233.94474019, -8236997.389232334 4977242.660026663, -8237046.314148537 4977270.598965389, -8237077.439078162 4977287.970823444, -8237283.970129433 4977401.873365361, -8237296.115085877 4977408.575285328)" +478,East 57th Street,"LINESTRING (-8234745.162162656 4977442.746330331, -8234731.247226307 4977435.015580224, -8234652.165860046 4977391.085635423, -8234578.027079178 4977349.816064641, -8234566.03797002 4977343.128882087)" +479,5th Avenue,"LINESTRING (-8234745.162162656 4977442.746330331, -8234752.787547774 4977428.9456229275, -8234794.454433179 4977353.505039833, -8234800.521345425 4977342.511603927)" +480,West 57th Street,"LINESTRING (-8234745.162162656 4977442.746330331, -8234759.288606036 4977450.56527012, -8234985.790373952 4977575.933712029, -8235088.760902938 4977633.077563822, -8235103.789034195 4977641.411070138)" +481,East 57th Street,"LINESTRING (-8234566.03797002 4977343.128882087, -8234553.559055102 4977336.147762326, -8234409.344654778 4977255.505167947, -8234397.166302486 4977248.700474294)" +482,Madison Avenue,"LINESTRING (-8234566.03797002 4977343.128882087, -8234557.622216516 4977358.0464494545, -8234519.027749058 4977426.388305484, -8234515.354205861 4977433.340095267, -8234510.545203859 4977442.599357837)" +483,East 57th Street,"LINESTRING (-8234566.03797002 4977343.128882087, -8234578.027079178 4977349.816064641, -8234652.165860046 4977391.085635423, -8234731.247226307 4977435.015580224, -8234745.162162656 4977442.746330331)" +484,East 57th Street,"LINESTRING (-8234377.429356768 4977237.751247154, -8234397.166302486 4977248.700474294)" +485,Park Avenue,"LINESTRING (-8234377.429356768 4977237.751247154, -8234369.124922756 4977252.595168786, -8234326.823516253 4977328.240731654, -8234321.981118403 4977336.882616802)" +486,East 57th Street,"LINESTRING (-8234377.429356768 4977237.751247154, -8234364.171205414 4977230.388082517, -8234290.756001237 4977189.618884142, -8234218.754554591 4977149.614089918, -8234206.19771603 4977142.647805247)" +487,East 57th Street,"LINESTRING (-8234206.19771603 4977142.647805247, -8234218.754554591 4977149.614089918, -8234290.756001237 4977189.618884142, -8234364.171205414 4977230.388082517, -8234377.429356768 4977237.751247154)" +488,East 57th Street,"LINESTRING (-8234206.19771603 4977142.647805247, -8234194.876523816 4977136.357577787, -8234116.874956617 4977093.002148216, -8234042.268633887 4977051.513386796, -8234032.862136915 4977046.29607362)" +489,Lexington Avenue,"LINESTRING (-8234206.19771603 4977142.647805247, -8234213.867628945 4977128.818128248, -8234256.2803549385 4977051.381116848, -8234260.84445406 4977043.062810515)" +490,East 57th Street,"LINESTRING (-8234032.862136915 4977046.29607362, -8234019.303422937 4977038.756693587)" +491,3rd Avenue,"LINESTRING (-8234032.862136915 4977046.29607362, -8234024.59109875 4977060.728197437, -8234019.7264370015 4977069.237575749)" +492,East 57th Street,"LINESTRING (-8234032.862136915 4977046.29607362, -8234042.268633887 4977051.513386796, -8234116.874956617 4977093.002148216, -8234194.876523816 4977136.357577787, -8234206.19771603 4977142.647805247)" +493,East 57th Street,"LINESTRING (-8233780.434059593 4976905.503153324, -8233763.346517757 4976896.14152483, -8233732.488754909 4976879.225951977, -8233710.247120648 4976866.748715011, -8233697.823865476 4976859.767935676, -8233691.534314247 4976856.461252469)" +494,East 57th Street,"LINESTRING (-8233780.434059593 4976905.503153324, -8233794.326732044 4976913.321663119, -8233899.612706437 4976972.151741067, -8234012.902552217 4977035.18541034, -8234019.303422937 4977038.756693587)" +495,2nd Avenue,"LINESTRING (-8233780.434059593 4976905.503153324, -8233788.738493607 4976890.468705648, -8233809.321467455 4976853.125177654, -8233813.8299068315 4976844.9686999805, -8233821.733590677 4976830.625072876, -8233830.505566552 4976814.708962121, -8233834.724575253 4976807.066886763)" +496,Sutton Place,"LINESTRING (-8233264.434823919 4976618.912059155, -8233258.011689301 4976630.580698047, -8233214.3744489085 4976709.821999854, -8233209.799217838 4976718.1400224455)" +497,East 57th Street,"LINESTRING (-8233264.434823919 4976618.912059155, -8233250.085741556 4976611.035000983, -8233218.849492438 4976593.870090247)" +498,East 57th Street,"LINESTRING (-8233264.434823919 4976618.912059155, -8233278.906357722 4976626.671555504, -8233499.441400934 4976749.369410754, -8233514.848018458 4976757.937302738)" +499,Sutton Place South,"LINESTRING (-8233264.434823919 4976618.912059155, -8233271.392292093 4976606.332282714, -8233314.550858675 4976528.208706631, -8233319.270805083 4976519.670407837)" +500,East 57th Street,"LINESTRING (-8233218.849492438 4976593.870090247, -8233250.085741556 4976611.035000983, -8233264.434823919 4976618.912059155)" +501,Central Park West,"LINESTRING (-8234440.436188557 4980345.002396175, -8234444.198787346 4980338.033831964, -8234446.703475889 4980333.373423655, -8234486.177367324 4980260.042118227, -8234494.47066939 4980245.399445575)" +502,Central Park West,"LINESTRING (-8234440.436188557 4980345.002396175, -8234436.027936721 4980353.14709567, -8234393.192196665 4980431.110149569, -8234389.073375505 4980438.5786399795)" +503,Columbus Avenue,"LINESTRING (-8234756.127132497 4980521.467505631, -8234760.769155264 4980512.602274087, -8234777.166516257 4980481.272639698, -8234802.42490872 4980437.181973032, -8234809.337849097 4980424.641382966)" +504,West 82nd Street,"LINESTRING (-8234756.127132497 4980521.467505631, -8234740.453348194 4980512.705187177, -8234453.315853642 4980352.073876755, -8234440.436188557 4980345.002396175)" +505,West 82nd Street,"LINESTRING (-8235070.137152128 4980695.921610108, -8235057.713896955 4980689.0116039915, -8234829.230642102 4980561.941873963, -8234768.917741989 4980528.553815905, -8234756.127132497 4980521.467505631)" +506,Amsterdam Avenue,"LINESTRING (-8235070.137152128 4980695.921610108, -8235065.350414024 4980704.625284344, -8235033.000969999 4980763.551715348, -8235023.928431499 4980779.797712581, -8235019.130561445 4980788.383843305)" +507,Riverside Drive,"LINESTRING (-8235552.506769633 4980958.931839956, -8235553.553172847 4980949.463407556, -8235555.401076393 4980932.334977862, -8235556.480875454 4980923.028298621, -8235558.128403917 4980912.707157607, -8235560.377057632 4980901.562689961, -8235562.503259905 4980892.829435285, -8235565.152663787 4980883.052316002, -8235569.11563766 4980872.569490716, -8235572.310507045 4980864.791917936, -8235576.4627240505 4980856.191017635)" +508,West 82nd Street,"LINESTRING (-8235552.506769633 4980958.931839956, -8235545.52703756 4980957.858554455, -8235540.617848016 4980956.476515765, -8235535.864505759 4980954.4916733075, -8235401.223581646 4980880.097128492, -8235387.698263513 4980872.4665738335)" +509,7th Avenue,"LINESTRING (-8236395.3288983265 4976051.177601818, -8236399.080365168 4976044.197405205, -8236439.133117954 4975972.088592257, -8236444.854939781 4975961.772681686)" +510,West 38th Street,"LINESTRING (-8236395.3288983265 4976051.177601818, -8236381.358302233 4976043.286306226, -8236246.105120919 4975967.533131829, -8236232.624330583 4975960.112144393)" +511,West 38th Street,"LINESTRING (-8236710.908522776 4976228.050100566, -8236694.77832856 4976219.174069682, -8236409.210438829 4976059.039513449, -8236395.3288983265 4976051.177601818)" +512,8th Avenue,"LINESTRING (-8236710.908522776 4976228.050100566, -8236705.620846964 4976237.587434129, -8236691.928549596 4976262.290493933, -8236665.3120593475 4976310.300723975, -8236660.146834975 4976319.603008872)" +513,West 38th Street,"LINESTRING (-8237026.989084936 4976404.896409997, -8237012.383967743 4976396.725610858, -8236764.197163019 4976257.867157396, -8236726.248348608 4976236.66162168, -8236723.710264219 4976235.221469156, -8236710.908522776 4976228.050100566)" +514,9th Avenue,"LINESTRING (-8237026.989084936 4976404.896409997, -8237031.553184058 4976396.828480589, -8237063.401690373 4976340.397248052)" +515,West 38th Street,"LINESTRING (-8237343.22549438 4976580.114669852, -8237327.9413282955 4976571.297102861, -8237222.722145597 4976513.263014675, -8237199.378448377 4976500.595199278, -8237158.078917294 4976477.96364421, -8237108.653063381 4976450.409061898, -8237081.090357461 4976435.0667041475, -8237042.395702462 4976413.478695587, -8237026.989084936 4976404.896409997)" +516,10th Avenue,"LINESTRING (-8237343.22549438 4976580.114669852, -8237337.603860096 4976590.269577696, -8237297.361864174 4976663.088365027, -8237292.441542681 4976672.170544482)" +517,86th Street Transverse,"LINESTRING (-8233492.873550975 4980169.040321711, -8233469.84154833 4980146.223849164, -8233462.861816258 4980139.167218962, -8233457.652064089 4980133.124983407, -8233452.375520226 4980126.391791011, -8233447.655573815 4980119.261668755, -8233436.47909694 4980099.312055379, -8233429.209934192 4980087.845088982, -8233422.118882628 4980077.230806446, -8233416.497248343 4980069.306855121, -8233406.656605357 4980056.178690177, -8233396.036725935 4980042.8447266035, -8233385.038360244 4980028.996241264, -8233353.100798337 4979991.890630006, -8233347.178601424 4979985.62796943, -8233341.245272567 4979979.776942754)" +518,86th Street Transverse,"LINESTRING (-8233492.873550975 4980169.040321711, -8233523.441883147 4980194.444292017, -8233530.020865053 4980201.295142546, -8233536.154568995 4980208.101893648, -8233542.778078699 4980216.49640316, -8233548.767067304 4980224.979128507, -8233555.68000768 4980236.166928322, -8233562.926906531 4980249.354141144, -8233567.568929298 4980259.204133356, -8233572.066236726 4980270.05383777, -8233575.316765856 4980279.99205998, -8233578.222204568 4980289.842083097, -8233580.303879044 4980297.722108745, -8233582.441213269 4980307.880882537, -8233589.532264832 4980345.796283552, -8233591.346772532 4980354.720170181, -8233593.9405166665 4980365.511174134, -8233596.8014275795 4980374.508587088, -8233599.751394086 4980382.300471021, -8233603.157770504 4980389.945344318, -8233607.899980812 4980399.486742657, -8233613.031809338 4980407.925521837, -8233618.8872145545 4980416.423115211, -8233626.056189761 4980423.847489178, -8233634.6389224995 4980431.1836583065, -8233643.911836083 4980438.049376692, -8233653.51870814 4980444.429941573, -8233663.682177648 4980450.707598189, -8233676.250148159 4980457.867366047, -8233688.896042315 4980464.350856459, -8233696.844253956 4980468.305640707, -8233706.662633044 4980472.6426736, -8233717.516283398 4980477.259042933, -8233805.97075078 4980510.852751733, -8233878.094648866 4980538.212964955, -8233893.055988428 4980544.196643511, -8233907.739029263 4980550.680191247, -8233921.197555702 4980557.237252972, -8233933.097609268 4980563.25034708, -8233944.0514471615 4980569.601589864, -8233953.624923371 4980575.291248367, -8233962.374635345 4980581.304353593, -8233971.736604521 4980587.964349765, -8234007.603744455 4980615.971668161, -8234027.507669408 4980631.614635817, -8234037.103409515 4980638.318772483, -8234046.387455047 4980644.728872372, -8234055.4265976995 4980650.286255958, -8234063.964802642 4980654.843900939, -8234071.790562846 4980658.651741446, -8234082.065351848 4980662.988858887, -8234092.117501865 4980666.605575243, -8234106.333000839 4980671.471972128, -8234145.695572784 4980683.909964316, -8234158.653161513 4980688.379412186, -8234172.33432693 4980693.701586332, -8234182.174969918 4980697.876995705, -8234195.8672672855 4980704.595880026, -8234205.908285353 4980710.035680348, -8234214.969691904 4980715.152035849, -8234229.752920281 4980724.340899442)" +519,East 46th Street,"LINESTRING (-8235307.136348027 4976423.545255931, -8235293.900460571 4976416.241487758, -8235140.056924296 4976331.330072593, -8235127.355370396 4976324.320284691)" +520,5th Avenue,"LINESTRING (-8235307.136348027 4976423.545255931, -8235312.457419687 4976414.154697855, -8235354.825617883 4976339.765337658, -8235359.100286328 4976331.859113394)" +521,Madison Avenue,"LINESTRING (-8235127.355370396 4976324.320284691, -8235123.782014742 4976330.859814127, -8235099.458706004 4976376.76890356, -8235082.482483657 4976407.982504976, -8235077.985176229 4976416.123922119)" +522,East 46th Street,"LINESTRING (-8235127.355370396 4976324.320284691, -8235116.190025469 4976318.148148564, -8235077.49537047 4976296.795526754, -8235038.667132081 4976275.384169637, -8235036.707909042 4976274.282007705, -8235027.846877576 4976269.417801204)" +523,Vanderbilt Avenue,"LINESTRING (-8235027.846877576 4976269.417801204, -8235023.716924468 4976276.8537190715, -8234982.127962707 4976351.874511391, -8234977.842162311 4976359.560317552)" +524,Vanderbilt Avenue,"LINESTRING (-8235027.846877576 4976269.417801204, -8235033.023233898 4976259.939218448, -8235074.2782371845 4976184.698701709, -8235079.17629478 4976175.734538148)" +525,East 46th Street,"LINESTRING (-8235027.846877576 4976269.417801204, -8235018.017366539 4976263.745345921, -8235002.410373929 4976254.707632524, -8234972.276187772 4976237.528652383, -8234962.346489193 4976231.856215618)" +526,Lexington Avenue,"LINESTRING (-8234769.184908767 4976123.22821742, -8234773.737875941 4976114.998872832, -8234814.72571245 4976040.979168867, -8234820.146971653 4976031.133429576)" +527,East 46th Street,"LINESTRING (-8234769.184908767 4976123.22821742, -8234758.765404428 4976117.423589714, -8234674.329570664 4976070.413579977, -8234606.836563396 4976033.705076941, -8234591.140515194 4976025.181905413)" +528,3rd Avenue,"LINESTRING (-8234591.140515194 4976025.181905413, -8234586.799055053 4976033.058491254, -8234545.711031001 4976108.121497314, -8234540.924292896 4976116.879865269)" +529,East 46th Street,"LINESTRING (-8234591.140515194 4976025.181905413, -8234576.20143953 4976016.820387467, -8234493.825016341 4975970.677868801, -8234356.534688346 4975894.734223384, -8234340.693924807 4975885.946664746)" +530,2nd Avenue,"LINESTRING (-8234340.693924807 4975885.946664746, -8234345.925940874 4975876.483148899, -8234387.637354074 4975801.495396309, -8234392.2682448905 4975793.163459323)" +531,Columbus Avenue,"LINESTRING (-8234491.921453049 4981000.437203989, -8234496.307440988 4980992.306667135, -8234519.7179299 4980949.463407556, -8234537.228485802 4980915.779974802, -8234545.532919815 4980900.812864758)" +532,5th Avenue,"LINESTRING (-8232773.193042997 4981008.097263893, -8232777.534503137 4981000.2460701335, -8232819.546478963 4980924.366225107, -8232824.08831419 4980916.16223921)" +533,Madison Avenue,"LINESTRING (-8232594.280357394 4980909.325589564, -8232589.961161151 4980917.4119498795, -8232547.3814559225 4980995.12956524, -8232539.689279108 4981008.758881633)" +534,East 95th Street,"LINESTRING (-8232594.280357394 4980909.325589564, -8232606.53663333 4980916.059321869, -8232761.693739598 4981001.980977574, -8232773.193042997 4981008.097263893)" +535,West 34th Street,"LINESTRING (-8237376.36530679 4976116.189188316, -8237333.640886224 4976092.764981846, -8237312.501314921 4976081.141070877, -8237295.013022918 4976071.51571891, -8237246.121502562 4976044.6676498735, -8237232.384677399 4976037.129042769)" +536,Dyer Avenue,"LINESTRING (-8237376.36530679 4976116.189188316, -8237368.316907605 4976130.164384671, -8237345.463016145 4976171.722710236)" +537,West 34th Street,"LINESTRING (-8237376.36530679 4976116.189188316, -8237389.890624922 4976123.624989567, -8237430.53337101 4976145.932427272, -8237463.450544436 4976163.948879885, -8237472.9906247975 4976169.26858921, -8237532.323913392 4976202.480099667, -8237547.530155835 4976211.0034258645)" +538,West 36th Street,"LINESTRING (-8237269.220296901 4976303.467297585, -8237241.223444967 4976287.963519951)" +539,,"LINESTRING (-8237269.220296901 4976303.467297585, -8237285.317095269 4976303.3203422325, -8237291.428535315 4976302.629652099, -8237294.166994789 4976302.321045885, -8237303.996505825 4976299.323157458, -8237323.655527899 4976288.213343661, -8237335.911803835 4976280.58637563, -8237361.493022821 4976265.170807173, -8237375.53041061 4976256.58865186, -8237391.204194912 4976245.478886657, -8237404.217443385 4976236.323626681, -8237412.032071641 4976229.416774911, -8237422.418180131 4976218.6744257985, -8237432.114107779 4976207.358968235, -8237448.956746736 4976181.245293461, -8237455.157242374 4976165.580061165)" +540,Dyer Avenue,"LINESTRING (-8237269.220296901 4976303.467297585, -8237275.676827367 4976294.047463882, -8237322.108186978 4976225.419620374, -8237326.282667883 4976216.778718359)" +541,Dyer Avenue,"LINESTRING (-8237018.272768806 4976766.387632383, -8237010.925682414 4976778.805956166, -8236975.281181462 4976841.764896198, -8236967.3663656665 4976855.68234503)" +542,West 41st Street,"LINESTRING (-8237018.272768806 4976766.387632383, -8237031.3639409235 4976770.502578159, -8237115.265441135 4976817.6188308485, -8237133.121087459 4976827.715200274, -8237173.641382107 4976850.229994709, -8237174.776840912 4976850.861938121, -8237190.417229369 4976856.62291251)" +543,West 42nd Street,"LINESTRING (-8236967.3663656665 4976855.68234503, -8236954.37538109 4976848.437039204, -8236838.848013546 4976784.037822747, -8236823.652903054 4976775.558085344)" +544,West 42nd Street,"LINESTRING (-8236967.3663656665 4976855.68234503, -8236977.407383735 4976861.281662139, -8236983.496559882 4976864.676525256, -8237123.759118282 4976942.876274532, -8237138.3308396265 4976951.003440932)" +545,West 63rd Street,"LINESTRING (-8235428.931002904 4978554.52423762, -8235441.4878414655 4978561.329841027, -8235535.697526523 4978613.746375211, -8235548.042858053 4978620.757806189, -8235555.490131985 4978624.917630303, -8235629.851551836 4978666.427774332, -8235644.412141231 4978673.630331449)" +546,Central Park West,"LINESTRING (-8235428.931002904 4978554.52423762, -8235423.966153613 4978563.490584353, -8235395.156669396 4978615.495557729, -8235382.577566938 4978638.205560892, -8235377.95780807 4978646.304739843)" +547,Central Park West,"LINESTRING (-8235428.931002904 4978554.52423762, -8235433.495102026 4978546.204651128, -8235457.328605005 4978504.503933038, -8235476.442161574 4978472.313511054, -8235480.906073155 4978463.597127373)" +548,Central Park West,"LINESTRING (-8235377.95780807 4978646.304739843, -8235373.171069965 4978654.697906968, -8235362.5734544415 4978674.041906302, -8235331.415128968 4978730.48662184, -8235327.051404929 4978738.115502947)" +549,Central Park West,"LINESTRING (-8235377.95780807 4978646.304739843, -8235382.577566938 4978638.205560892, -8235395.156669396 4978615.495557729, -8235423.966153613 4978563.490584353, -8235428.931002904 4978554.52423762)" +550,West 71st Street,"LINESTRING (-8235022.1473196475 4979290.424109636, -8235035.884144811 4979297.906427731, -8235323.856535543 4979457.094471142, -8235338.272409601 4979465.062026588)" +551,Central Park West,"LINESTRING (-8235022.1473196475 4979290.424109636, -8235017.449637135 4979298.7737302, -8234977.363488501 4979371.730313596, -8234974.023903778 4979377.62507645, -8234966.532102046 4979390.9581317445)" +552,Central Park West,"LINESTRING (-8235022.1473196475 4979290.424109636, -8235026.922925802 4979282.11859626, -8235068.467359765 4979207.016496025, -8235073.042590838 4979198.872752395)" +553,West 72nd Street,"LINESTRING (-8234966.532102046 4979390.9581317445, -8234979.812517298 4979398.087722255, -8235007.408619066 4979412.979028086, -8235018.22887357 4979418.991417628, -8235055.843729509 4979439.909858, -8235267.039067442 4979557.38030172, -8235282.28983768 4979565.862454532)" +554,Central Park West,"LINESTRING (-8234966.532102046 4979390.9581317445, -8234959.48557828 4979403.5267948015, -8234915.748150347 4979483.27570635, -8234911.785176475 4979490.405364257)" +555,Central Park West,"LINESTRING (-8234966.532102046 4979390.9581317445, -8234974.023903778 4979377.62507645, -8234977.363488501 4979371.730313596, -8235017.449637135 4979298.7737302, -8235022.1473196475 4979290.424109636)" +556,Central Park West,"LINESTRING (-8234859.253508768 4979584.267428433, -8234855.190347355 4979591.7058702195, -8234812.844413058 4979669.0601204345, -8234808.313709782 4979677.292459839)" +557,Central Park West,"LINESTRING (-8234859.253508768 4979584.267428433, -8234863.650628654 4979576.22627343, -8234908.523515395 4979496.211996708, -8234911.785176475 4979490.405364257)" +558,West 75th Street,"LINESTRING (-8234808.313709782 4979677.292459839, -8234821.249034612 4979684.686870614, -8235110.8021621145 4979845.660023658, -8235124.783890157 4979853.275075077)" +559,Central Park West,"LINESTRING (-8234808.313709782 4979677.292459839, -8234803.883194049 4979685.421901811, -8234761.103113736 4979763.614836648, -8234756.95089673 4979771.229824088)" +560,Central Park West,"LINESTRING (-8234808.313709782 4979677.292459839, -8234812.844413058 4979669.0601204345, -8234855.190347355 4979591.7058702195, -8234859.253508768 4979584.267428433)" +561,Central Park West,"LINESTRING (-8234756.95089673 4979771.229824088, -8234752.164158626 4979779.9179733815, -8234711.688391774 4979853.995418087, -8234708.894272555 4979858.993717983, -8234702.7494366625 4979870.18109849)" +562,Central Park West,"LINESTRING (-8234756.95089673 4979771.229824088, -8234761.103113736 4979763.614836648, -8234803.883194049 4979685.421901811, -8234808.313709782 4979677.292459839)" +563,Central Park West,"LINESTRING (-8234389.073375505 4980438.5786399795, -8234383.941546979 4980447.855453934, -8234342.152210135 4980523.496365725, -8234337.5213193195 4980531.802934991)" +564,Central Park West,"LINESTRING (-8234389.073375505 4980438.5786399795, -8234393.192196665 4980431.110149569, -8234436.027936721 4980353.14709567, -8234440.436188557 4980345.002396175)" +565,West 83rd Street,"LINESTRING (-8234389.073375505 4980438.5786399795, -8234401.908512794 4980445.591381252, -8234689.680528444 4980605.415619564, -8234704.897902836 4980613.869278743)" +566,East 84th Street,"LINESTRING (-8233341.245272567 4979979.776942754, -8233336.747965139 4979976.101676536, -8233332.061414575 4979972.573422266, -8233325.705071651 4979967.986693624, -8233318.636283985 4979963.444070264, -8233246.312010817 4979923.148594392, -8233221.621347759 4979909.47669034, -8233183.639137501 4979889.336393432, -8233176.982231951 4979885.602357549, -8233164.347469746 4979878.737027583)" +567,5th Avenue,"LINESTRING (-8233341.245272567 4979979.776942754, -8233347.234261172 4979968.9569629645, -8233389.034729964 4979893.099832619, -8233393.554301291 4979884.264573387)" +568,East 84th Street,"LINESTRING (-8233164.347469746 4979878.737027583, -8233152.313832791 4979871.974608779, -8233076.549787357 4979830.047716725, -8233008.3332034 4979792.104916637, -8232995.865420432 4979784.930936137)" +569,Madison Avenue,"LINESTRING (-8233164.347469746 4979878.737027583, -8233159.8724262165 4979886.455011286, -8233117.38177658 4979962.782523348, -8233112.839941357 4979971.103316697)" +570,East 84th Street,"LINESTRING (-8232975.81678014 4979773.773054808, -8232962.8925872585 4979766.599087774, -8232816.863679235 4979685.568908058, -8232805.375507785 4979679.203539622)" +571,Park Avenue,"LINESTRING (-8232975.81678014 4979773.773054808, -8232971.107965679 4979782.32889943, -8232928.995802313 4979858.861410012, -8232924.687738018 4979866.064846616)" +572,East 84th Street,"LINESTRING (-8232805.375507785 4979679.203539622, -8232793.030176257 4979672.294252944, -8232642.593016398 4979587.986648617, -8232626.507349979 4979578.975259861)" +573,Lexington Avenue,"LINESTRING (-8232805.375507785 4979679.203539622, -8232810.03979445 4979670.780090772, -8232852.474784341 4979594.1020493135, -8232856.905300073 4979586.075586687)" +574,3rd Avenue,"LINESTRING (-8232626.507349979 4979578.975259861, -8232621.141750522 4979588.662870622, -8232579.0629830025 4979664.635240872, -8232574.766050658 4979672.397157179)" +575,West 33rd Street,"LINESTRING (-8236968.034282611 4975761.481590971, -8236983.641275221 4975770.1514798, -8237010.569460043 4975785.125424556, -8237270.288964013 4975929.5612475565, -8237285.873692724 4975938.245980518)" +576,8th Avenue,"LINESTRING (-8236968.034282611 4975761.481590971, -8236963.603766878 4975769.578385218, -8236921.235568682 4975846.358664136, -8236914.066593475 4975859.437087577)" +577,West 34th Street,"LINESTRING (-8236914.066593475 4975859.437087577, -8236930.6977254 4975868.018894042, -8237032.543927526 4975923.462835625, -8237041.237979757 4975928.1946151545, -8237050.321650206 4975933.146821651, -8237102.931241556 4975962.316397499, -8237111.191147773 4975967.1510610515, -8237119.016907974 4975971.985726997, -8237157.043646029 4975995.659460134, -8237166.294295713 4976000.89090735, -8237174.376090745 4976005.446383328, -8237214.684878362 4976027.812331696, -8237232.384677399 4976037.129042769)" +578,8th Avenue,"LINESTRING (-8236914.066593475 4975859.437087577, -8236906.786298777 4975872.486138746, -8236872.700270696 4975934.116690279, -8236864.752059054 4975948.48839124, -8236860.3994669635 4975956.3649152545)" +579,West 35th Street,"LINESTRING (-8236860.3994669635 4975956.3649152545, -8236872.455367817 4975963.095233715, -8236875.861744233 4975964.990891935, -8237047.939413103 4976060.847019261, -8237069.435206774 4976072.823590605, -8237106.6159167 4976093.529133241, -8237113.161502758 4976097.17354841, -8237161.741328541 4976124.403838643, -8237179.541315119 4976134.631749236)" +580,8th Avenue,"LINESTRING (-8236860.3994669635 4975956.3649152545, -8236855.0227355575 4975966.122409033, -8236815.181489804 4976038.436909862, -8236810.216640513 4976047.430337753)" +581,West 36th Street,"LINESTRING (-8236810.216640513 4976047.430337753, -8236795.2886967985 4976039.156971595, -8236702.52616512 4975987.841684686, -8236508.095542501 4975880.259737199, -8236494.369849285 4975872.6624773955)" +582,8th Avenue,"LINESTRING (-8236810.216640513 4976047.430337753, -8236805.385374613 4976056.17395614, -8236765.04319115 4976129.385535138, -8236760.557015671 4976137.526720128)" +583,West 37th Street,"LINESTRING (-8236760.557015671 4976137.526720128, -8236774.271576935 4976145.182967076, -8236775.841181756 4976146.049989659, -8237016.469393055 4976279.895687104, -8237029.159815006 4976286.934834155, -8237063.245843087 4976305.862670164, -8237078.318502141 4976313.974611105)" +584,8th Avenue,"LINESTRING (-8236760.557015671 4976137.526720128, -8236755.24707596 4976147.225613629, -8236715.416962154 4976219.732495229, -8236710.908522776 4976228.050100566)" +585,8th Avenue,"LINESTRING (-8236660.146834975 4976319.603008872, -8236655.315569075 4976328.405653128, -8236614.349996462 4976402.883100941, -8236610.14211971 4976410.510164445)" +586,West 39th Street,"LINESTRING (-8236660.146834975 4976319.603008872, -8236673.917055986 4976327.538614362, -8236751.98541488 4976372.536558501, -8236942.375139983 4976477.919556816, -8236962.512835868 4976489.058977969, -8236976.3832444195 4976496.304017276)" +587,8th Avenue,"LINESTRING (-8236610.14211971 4976410.510164445, -8236604.398033986 4976420.753070271, -8236564.723767467 4976492.571278301, -8236559.84797377 4976501.388774238)" +588,West 40th Street,"LINESTRING (-8236610.14211971 4976410.510164445, -8236594.368147866 4976401.766228943, -8236308.354980171 4976243.112919774, -8236294.028161706 4976235.162687425)" +589,West 41st Street,"LINESTRING (-8236559.84797377 4976501.388774238, -8236576.868723912 4976510.838199552, -8236704.496520108 4976583.009772749, -8236833.059400025 4976655.064310591, -8236856.892903002 4976676.065009134, -8236860.766821282 4976679.268758575, -8236871.186325621 4976688.46852199)" +590,8th Avenue,"LINESTRING (-8236559.84797377 4976501.388774238, -8236555.083499565 4976510.044623825, -8236535.457873338 4976545.682115893, -8236513.171711281 4976586.140011873, -8236505.902548533 4976599.336993476)" +591,8th Avenue,"LINESTRING (-8236505.902548533 4976599.336993476, -8236497.987732737 4976613.636192998, -8236466.272809811 4976670.980161256, -8236455.630666489 4976690.217359784, -8236450.766004742 4976699.005641847)" +592,West 42nd Street,"LINESTRING (-8236505.902548533 4976599.336993476, -8236491.063660408 4976591.06315994, -8236383.540164253 4976531.280144682, -8236364.359815989 4976520.610942965, -8236353.060887673 4976514.335811861, -8236342.997605705 4976508.736693598, -8236249.055087425 4976456.507802753, -8236216.160177896 4976438.211591609, -8236202.902026542 4976430.819638109, -8236189.476895953 4976423.368907339)" +593,West 42nd Street,"LINESTRING (-8236505.902548533 4976599.336993476, -8236521.119922923 4976607.40509012, -8236566.215448643 4976632.505877841, -8236603.26257518 4976652.8892933065, -8236671.991228796 4976691.7604522165, -8236802.079185737 4976764.139109172, -8236806.977243331 4976766.872608044, -8236811.185120083 4976769.2093092995, -8236823.652903054 4976775.558085344)" +594,8th Avenue,"LINESTRING (-8236400.3160115145 4976790.210253214, -8236395.507009512 4976798.925143824, -8236354.140686733 4976873.847070483, -8236349.431872273 4976882.385678826)" +595,West 44th Street,"LINESTRING (-8236400.3160115145 4976790.210253214, -8236386.846353129 4976782.729855838, -8236216.21583764 4976687.86598131, -8236102.759012623 4976624.922729085, -8236102.102227628 4976624.570024636, -8236096.747760122 4976621.689605435, -8236093.675342177 4976619.999563954, -8236085.1371372305 4976615.340929383)" +596,8th Avenue,"LINESTRING (-8236298.525469133 4976974.591367237, -8236293.282321118 4976984.026553706, -8236260.24269625 4977043.944609438, -8236251.993921982 4977058.891113281, -8236248.075475905 4977065.989608367)" +597,West 46th Street,"LINESTRING (-8236298.525469133 4976974.591367237, -8236283.920351941 4976966.449484681, -8236241.975167809 4976943.0526325, -8236223.206701662 4976932.588731822, -8236141.242160591 4976887.867439923, -8236058.275744103 4976842.191090218, -8236027.273265918 4976824.6289727045, -8236020.905791044 4976821.204730876, -8235993.098182243 4976806.052842598, -8235981.376239863 4976799.689350454)" +598,West 47th Street,"LINESTRING (-8236248.075475905 4977065.989608367, -8236260.298355996 4977072.779478059, -8236263.882843599 4977074.763531783, -8236549.205830451 4977233.239287326, -8236564.3230173 4977241.822300643)" +599,8th Avenue,"LINESTRING (-8236248.075475905 4977065.989608367, -8236242.932515431 4977075.439579809, -8236201.666380194 4977150.040297369, -8236197.135676919 4977158.241120227)" +600,West 48th Street,"LINESTRING (-8236197.135676919 4977158.241120227, -8236182.653011167 4977150.20196227, -8236054.3239021795 4977078.878607454, -8236018.30091496 4977058.861719938, -8235966.147733523 4977030.173858684, -8235952.555623697 4977022.531614772)" +601,8th Avenue,"LINESTRING (-8236197.135676919 4977158.241120227, -8236191.603098228 4977168.308448019, -8236166.110934834 4977214.632986407, -8236157.450278451 4977230.388082517, -8236151.06053968 4977242.836390045, -8236146.863794877 4977251.007896881)" +602,West 50th Street,"LINESTRING (-8236095.100231658 4977343.070093689, -8236079.3151278645 4977334.295929289, -8236064.754538467 4977326.212535227, -8236008.226501043 4977294.804938506, -8236003.551082429 4977292.203565112, -8235881.199830098 4977224.215373924, -8235872.149555497 4977219.056756162)" +603,8th Avenue,"LINESTRING (-8236095.100231658 4977343.070093689, -8236090.146514316 4977352.050025548, -8236056.572555894 4977412.852170868, -8236048.813587385 4977426.917405591, -8236044.672502329 4977434.412993495)" +604,West 51st Street,"LINESTRING (-8236044.672502329 4977434.412993495, -8236056.650479537 4977441.070844048, -8236060.157043498 4977443.025578072, -8236218.586942794 4977531.135987898, -8236254.365027136 4977551.021566462, -8236346.904919832 4977602.521434821, -8236360.975703468 4977610.3111074995)" +605,8th Avenue,"LINESTRING (-8236044.672502329 4977434.412993495, -8236039.741048886 4977443.584073579, -8236024.401223055 4977472.170267871, -8235998.998115255 4977519.510365375, -8235997.361718741 4977522.552720375, -8235994.100057662 4977528.62273584)" +606,West 52nd Street,"LINESTRING (-8235994.100057662 4977528.62273584, -8235978.6489123395 4977520.039470525, -8235787.246179869 4977413.778094787, -8235778.919481957 4977408.325432965)" +607,8th Avenue,"LINESTRING (-8235994.100057662 4977528.62273584, -8235989.9367087055 4977535.883243552, -8235956.051055708 4977594.922835571, -8235947.613038306 4977610.193527488, -8235943.727988077 4977617.24833066)" +608,8th Avenue,"LINESTRING (-8235943.727988077 4977617.24833066, -8235937.716735574 4977627.962822726, -8235909.775543385 4977677.831662659, -8235895.793815341 4977702.773526916, -8235891.129528676 4977711.09239504)" +609,West 53rd Street,"LINESTRING (-8235943.727988077 4977617.24833066, -8235955.483326305 4977623.847515741, -8235959.579883565 4977626.140329419, -8236245.147773298 4977786.506344309, -8236259.196293035 4977794.531328166)" +610,West 54th Street,"LINESTRING (-8235891.129528676 4977711.09239504, -8235877.381571564 4977703.1850608615, -8235876.034605726 4977702.406085908, -8235705.626729219 4977607.048262715, -8235696.186836399 4977602.315669967)" +611,8th Avenue,"LINESTRING (-8235891.129528676 4977711.09239504, -8235886.643353199 4977719.543549238, -8235853.670520026 4977781.597291502, -8235846.7353157485 4977795.251519348, -8235845.165710928 4977798.338053583, -8235841.26952875 4977805.378294844)" +612,8th Avenue,"LINESTRING (-8235841.26952875 4977805.378294844, -8235837.373346573 4977812.242167517, -8235795.160995665 4977886.52515804, -8235791.810278992 4977892.433722499)" +613,West 55th Street,"LINESTRING (-8235841.26952875 4977805.378294844, -8235852.27902639 4977811.25741461, -8235855.407104082 4977812.93296439, -8235858.91366804 4977814.814283785, -8235889.9940698715 4977831.804965982, -8236142.466674991 4977972.728822164, -8236145.728336071 4977974.55138014, -8236158.207250988 4977981.3271833295)" +614,West 57th Street,"LINESTRING (-8235735.716387581 4977992.938657429, -8235722.803326648 4977985.692508049, -8235637.777499581 4977938.041493296, -8235626.623286603 4977931.941827437)" +615,8th Avenue,"LINESTRING (-8235735.716387581 4977992.938657429, -8235727.0223353505 4978008.312858295, -8235701.5969636515 4978053.230356245, -8235684.565081561 4978083.346948787, -8235679.054766766 4978093.488721199)" +616,West 57th Street,"LINESTRING (-8235735.716387581 4977992.938657429, -8235751.846581796 4978001.875092463, -8235829.903808741 4978045.131669068, -8235836.783353272 4978048.967888473, -8235879.396454348 4978072.749542774, -8235885.930908457 4978076.394696387, -8235906.992556116 4978088.153265704, -8236037.770693899 4978161.130203066, -8236043.336668438 4978164.246249588, -8236052.487130581 4978169.361271508)" +617,West 58th Street,"LINESTRING (-8235679.054766766 4978093.488721199, -8235666.342080917 4978085.169527399, -8235621.2242912995 4978060.932199283, -8235610.6600716235 4978054.626682299)" +618,8th Avenue,"LINESTRING (-8235679.054766766 4978093.488721199, -8235673.299549093 4978103.527616439, -8235668.000741331 4978113.595918512, -8235663.592489496 4978121.85634344, -8235653.518075579 4978140.949416401)" +619,5th Avenue,"LINESTRING (-8233972.3933895165 4978836.61532965, -8233978.950107525 4978823.84160557, -8234023.221869012 4978745.861983695, -8234027.685780594 4978737.865616574)" +620,East 72nd Street,"LINESTRING (-8233972.3933895165 4978836.61532965, -8233962.363503396 4978830.779690685, -8233926.418439819 4978810.671016877, -8233807.429036111 4978744.788941404, -8233794.449183485 4978737.806819782)" +621,East 72nd Street,"LINESTRING (-8233794.449183485 4978737.806819782, -8233782.315358988 4978731.2803779775, -8233637.889451632 4978651.317120743, -8233625.900342474 4978644.540852748)" +622,East 72nd Street,"LINESTRING (-8233794.449183485 4978737.806819782, -8233807.429036111 4978744.788941404, -8233926.418439819 4978810.671016877, -8233962.363503396 4978830.779690685, -8233972.3933895165 4978836.61532965)" +623,Madison Avenue,"LINESTRING (-8233794.449183485 4978737.806819782, -8233786.15588142 4978752.755915754, -8233743.186557974 4978830.1917171795, -8233739.023209019 4978837.703081381)" +624,East 72nd Street,"LINESTRING (-8233603.736631857 4978632.031962573, -8233625.900342474 4978644.540852748)" +625,East 72nd Street,"LINESTRING (-8233603.736631857 4978632.031962573, -8233593.116752435 4978626.0200574845, -8233447.4885945795 4978544.9993405985, -8233435.855707791 4978538.193748571)" +626,Park Avenue,"LINESTRING (-8233603.736631857 4978632.031962573, -8233595.61030903 4978646.260642663, -8233554.72266006 4978726.591338022, -8233550.659498648 4978734.014427391)" +627,East 72nd Street,"LINESTRING (-8233435.855707791 4978538.193748571, -8233424.6235711705 4978531.932020138, -8233273.318119286 4978447.678355668, -8233256.820570747 4978438.491634034)" +628,East 72nd Street,"LINESTRING (-8233435.855707791 4978538.193748571, -8233447.4885945795 4978544.9993405985, -8233593.116752435 4978626.0200574845, -8233603.736631857 4978632.031962573)" +629,Lexington Avenue,"LINESTRING (-8233435.855707791 4978538.193748571, -8233443.280717827 4978524.729567514, -8233486.494944153 4978446.208479625, -8233490.535841669 4978439.094282707)" +630,East 72nd Street,"LINESTRING (-8233256.820570747 4978438.491634034, -8233273.318119286 4978447.678355668, -8233424.6235711705 4978531.932020138, -8233435.855707791 4978538.193748571)" +631,3rd Avenue,"LINESTRING (-8233256.820570747 4978438.491634034, -8233248.827831309 4978452.925814942, -8233205.691528628 4978530.976592443, -8233200.993846115 4978539.472552759)" +632,East 72nd Street,"LINESTRING (-8233256.820570747 4978438.491634034, -8233241.358293477 4978429.878171678, -8233022.359459239 4978307.74714831, -8233009.702433135 4978301.088707001)" +633,2nd Avenue,"LINESTRING (-8233009.702433135 4978301.088707001, -8233016.971595885 4978287.786536522, -8233035.695534237 4978254.215172467, -8233060.664496021 4978208.94398859, -8233064.382567014 4978202.065138754)" +634,East 72nd Street,"LINESTRING (-8233009.702433135 4978301.088707001, -8232997.568608641 4978294.19509374, -8232992.692814944 4978291.5493586, -8232760.324509862 4978161.953309599, -8232755.571167604 4978159.30761028, -8232744.127523951 4978152.943236516)" +635,East 72nd Street,"LINESTRING (-8233009.702433135 4978301.088707001, -8233022.359459239 4978307.74714831, -8233241.358293477 4978429.878171678, -8233256.820570747 4978438.491634034)" +636,1st Avenue,"LINESTRING (-8232744.127523951 4978152.943236516, -8232735.9789372245 4978167.670962244, -8232716.397838795 4978203.094026242, -8232701.7259299075 4978229.639360897, -8232693.209988862 4978245.028632794, -8232688.801737026 4978253.009897969)" +637,East 72nd Street,"LINESTRING (-8232744.127523951 4978152.943236516, -8232755.571167604 4978159.30761028, -8232760.324509862 4978161.953309599, -8232992.692814944 4978291.5493586, -8232997.568608641 4978294.19509374, -8233009.702433135 4978301.088707001)" +638,5th Avenue,"LINESTRING (-8234538.408472405 4977818.033104527, -8234542.827856189 4977810.022799166, -8234580.921385938 4977740.605327087, -8234587.311124709 4977728.905966864)" +639,East 61st Street,"LINESTRING (-8234358.037501472 4977717.588759879, -8234370.672263677 4977724.614245269, -8234371.718666892 4977725.202152225, -8234436.617930024 4977761.343800313, -8234524.838626477 4977810.463733235, -8234538.408472405 4977818.033104527)" +640,Madison Avenue,"LINESTRING (-8234358.037501472 4977717.588759879, -8234352.883409048 4977726.936477953, -8234312.09594762 4977800.91016619, -8234311.439162626 4977802.100687114, -8234307.453924855 4977809.317304698)" +641,East 61st Street,"LINESTRING (-8234169.673791101 4977612.897868102, -8234190.011862069 4977624.259046362)" +642,Park Avenue,"LINESTRING (-8234169.673791101 4977612.897868102, -8234164.998372488 4977621.378332384, -8234122.975264713 4977697.805725656, -8234118.956631095 4977705.110452051)" +643,East 61st Street,"LINESTRING (-8233999.18799095 4977518.0406289995, -8234010.152960794 4977524.18412852, -8234157.517702706 4977606.13701797, -8234169.673791101 4977612.897868102)" +644,Lexington Avenue,"LINESTRING (-8233999.18799095 4977518.0406289995, -8234004.086048546 4977508.766597571, -8234018.668901841 4977482.4730761405, -8234044.840114126 4977435.147855366, -8234048.825351896 4977428.24015598)" +645,East 61st Street,"LINESTRING (-8233820.2641734 4977418.584082259, -8233834.86929059 4977426.69694721, -8233987.510576366 4977511.544396869, -8233999.18799095 4977518.0406289995)" +646,3rd Avenue,"LINESTRING (-8233820.2641734 4977418.584082259, -8233815.855921563 4977426.608763859, -8233774.968272595 4977501.16807125, -8233769.981159409 4977510.265727252)" +647,East 61st Street,"LINESTRING (-8233572.277743758 4977280.34307486, -8233586.303999598 4977288.02961151, -8233788.627174115 4977400.932745382, -8233805.9373549335 4977410.588801653, -8233820.2641734 4977418.584082259)" +648,2nd Avenue,"LINESTRING (-8233572.277743758 4977280.34307486, -8233576.830710933 4977272.215634462, -8233600.942512639 4977229.153540486, -8233603.703236009 4977224.215373924, -8233618.853818706 4977197.143683728, -8233623.918855538 4977188.105106801)" +649,East 61st Street,"LINESTRING (-8233307.938480922 4977132.874439557, -8233323.734716664 4977141.721907025, -8233453.04343717 4977214.309654475, -8233464.119726503 4977220.7322043665)" +650,1st Avenue,"LINESTRING (-8233307.938480922 4977132.874439557, -8233302.840048241 4977141.736603823, -8233260.182419371 4977215.691163707, -8233255.150778388 4977224.685675393)" +651,5th Avenue,"LINESTRING (-8233077.8076976035 4980454.76528939, -8233082.149157745 4980447.032154717, -8233124.250189163 4980371.582956803, -8233129.448809383 4980362.08569066)" +652,Madison Avenue,"LINESTRING (-8232900.59820021 4980356.116825335, -8232895.711274564 4980364.908406568, -8232887.117409876 4980380.330446948, -8232863.584469522 4980422.627245149, -8232853.743826536 4980440.313447624, -8232849.780852663 4980447.487909632)" +653,East 89th Street,"LINESTRING (-8232900.59820021 4980356.116825335, -8232913.266358262 4980363.158910675, -8233068.156297753 4980449.502052577, -8233077.8076976035 4980454.76528939)" +654,East 89th Street,"LINESTRING (-8232711.555440945 4980251.427049128, -8232732.138414793 4980262.703088204)" +655,Park Avenue,"LINESTRING (-8232711.555440945 4980251.427049128, -8232707.1026613135 4980259.556969083, -8232665.380116163 4980335.416946267, -8232661.261295006 4980342.885363484)" +656,Lexington Avenue,"LINESTRING (-8232541.737557739 4980156.00023068, -8232546.001094237 4980148.164423363, -8232558.446613308 4980125.759635631, -8232587.567792099 4980072.467614154, -8232592.243210712 4980064.176136821)" +657,East 89th Street,"LINESTRING (-8232541.737557739 4980156.00023068, -8232553.526291816 4980162.704040807, -8232698.775963402 4980244.149820914, -8232711.555440945 4980251.427049128)" +658,West 53rd Street,"LINESTRING (-8234953.296214592 4977065.9308216395, -8234964.5060873125 4977071.941766607, -8235066.430213085 4977129.214941235, -8235154.717701232 4977179.125325649, -8235161.341210933 4977182.873023817, -8235201.661130501 4977205.667877761, -8235218.637352846 4977215.0738936, -8235267.907359472 4977243.453661905, -8235296.984010466 4977258.459258893, -8235311.678183249 4977266.586687844)" +659,5th Avenue,"LINESTRING (-8234953.296214592 4977065.9308216395, -8234955.756375338 4977060.463657298, -8234998.447400057 4976984.658505774, -8235002.8667838415 4976976.413738991)" +660,East 53rd Street,"LINESTRING (-8234773.726743992 4976966.596450008, -8234785.949624081 4976973.3274644455, -8234940.227306372 4977058.538393162, -8234953.296214592 4977065.9308216395)" +661,Madison Avenue,"LINESTRING (-8234773.726743992 4976966.596450008, -8234768.516991822 4976976.369649349, -8234726.805578623 4977051.7338367095, -8234722.00770857 4977060.448960623)" +662,East 53rd Street,"LINESTRING (-8234584.6394569315 4976862.663121447, -8234603.7307496015 4976873.318000332)" +663,Park Avenue,"LINESTRING (-8234584.6394569315 4976862.663121447, -8234579.708003489 4976871.921843126, -8234538.34168071 4976946.329952012, -8234533.5326787075 4976954.971499315)" +664,East 53rd Street,"LINESTRING (-8234413.140649415 4976767.048962836, -8234426.2763493275 4976774.382385765, -8234494.882551503 4976812.622087103, -8234568.765297544 4976853.815906707, -8234571.114138799 4976855.123883134, -8234584.6394569315 4976862.663121447)" +665,Lexington Avenue,"LINESTRING (-8234413.140649415 4976767.048962836, -8234417.660220741 4976758.907253248, -8234458.325230728 4976685.764437275, -8234459.004279622 4976684.500571851, -8234463.379135611 4976676.329538865)" +666,East 53rd Street,"LINESTRING (-8234235.753040835 4976668.511218734, -8234251.8721031025 4976677.417050053, -8234310.515210853 4976709.880784441, -8234320.923583242 4976715.626979537, -8234401.162672205 4976760.362179193, -8234413.140649415 4976767.048962836)" +667,3rd Avenue,"LINESTRING (-8234235.753040835 4976668.511218734, -8234230.966302732 4976677.622795428, -8234190.36808444 4976751.485664679, -8234184.768714053 4976761.670143107)" +668,East 53rd Street,"LINESTRING (-8233987.287937385 4976530.163258007, -8234000.824387467 4976538.819133088, -8234127.572759683 4976608.889385492, -8234194.24200272 4976645.673529978, -8234221.459618218 4976660.590032353, -8234235.753040835 4976668.511218734)" +669,2nd Avenue,"LINESTRING (-8233987.287937385 4976530.163258007, -8233992.007883796 4976521.713132687, -8234025.092036459 4976462.356719244, -8234034.164574957 4976445.750508194, -8234037.582083325 4976439.475425172)" +670,East 53rd Street,"LINESTRING (-8233720.844736172 4976382.9998593405, -8233737.253229114 4976392.067082753, -8233903.252853786 4976483.739094515, -8233972.159618585 4976521.801307869, -8233987.287937385 4976530.163258007)" +671,1st Avenue,"LINESTRING (-8233720.844736172 4976382.9998593405, -8233715.813095188 4976392.125865427, -8233675.136953251 4976465.76613952, -8233669.927201084 4976475.200834585)" +672,East 53rd Street,"LINESTRING (-8233512.766343981 4976268.080512227, -8233707.453001429 4976375.607947614, -8233720.844736172 4976382.9998593405)" +673,East 78th Street,"LINESTRING (-8233659.051286833 4979403.159289805, -8233650.045540027 4979398.117122639, -8233495.099940793 4979311.724476222, -8233482.8102690065 4979304.962450049)" +674,5th Avenue,"LINESTRING (-8233659.051286833 4979403.159289805, -8233663.748969344 4979394.662578122, -8233705.87226466 4979318.50120715, -8233709.812974635 4979311.37167474)" +675,East 78th Street,"LINESTRING (-8233482.8102690065 4979304.962450049, -8233468.795145119 4979297.171425699, -8233324.603008692 4979216.865436924, -8233312.769746822 4979210.485674075)" +676,Madison Avenue,"LINESTRING (-8233482.8102690065 4979304.962450049, -8233477.311086162 4979315.017290661, -8233434.675721188 4979392.972056784, -8233427.172787509 4979406.687338351)" +677,East 78th Street,"LINESTRING (-8233293.099592798 4979199.578347242, -8233280.865580761 4979192.786998955, -8233134.602901807 4979111.541083789, -8233122.435681462 4979104.749796722)" +678,Park Avenue,"LINESTRING (-8233293.099592798 4979199.578347242, -8233288.101347662 4979208.706985175, -8233244.898253285 4979287.440004015, -8233237.272868166 4979300.949336731)" +679,East 78th Street,"LINESTRING (-8233122.435681462 4979104.749796722, -8233111.448447722 4979098.590603226, -8232959.608662278 4979013.582369969, -8232944.836565851 4979005.306491229)" +680,Lexington Avenue,"LINESTRING (-8233122.435681462 4979104.749796722, -8233125.942245424 4979098.399506593, -8233126.72148186 4979096.973631831, -8233169.5126941195 4979020.094300799, -8233173.308688755 4979013.009085069)" +681,East 78th Street,"LINESTRING (-8232944.836565851 4979005.306491229, -8232928.773163329 4978996.383837636, -8232709.017356555 4978873.937042675, -8232696.861268161 4978867.337012938)" +682,3rd Avenue,"LINESTRING (-8232944.836565851 4979005.306491229, -8232939.90511241 4979014.052757604, -8232895.689010667 4979092.563711204, -8232888.074757496 4979106.102173856)" +683,2nd Avenue,"LINESTRING (-8232696.861268161 4978867.337012938, -8232700.968957371 4978859.561037077, -8232743.147912432 4978783.198049188, -8232747.222205795 4978775.4662380805)" +684,West 83rd Street,"LINESTRING (-8234704.897902836 4980613.869278743, -8234717.877755461 4980621.073272341, -8235006.440139496 4980781.326749006, -8235019.130561445 4980788.383843305)" +685,Columbus Avenue,"LINESTRING (-8234704.897902836 4980613.869278743, -8234709.506529755 4980605.445023584, -8234743.225203515 4980543.932009001, -8234751.685484816 4980529.421227681, -8234756.127132497 4980521.467505631)" +686,West 83rd Street,"LINESTRING (-8235019.130561445 4980788.383843305, -8235027.023113344 4980792.794529831, -8235029.906288154 4980794.397079762, -8235033.891525924 4980796.617126431, -8235179.330440647 4980877.744741064, -8235190.818612097 4980884.096188422)" +687,Amsterdam Avenue,"LINESTRING (-8235019.130561445 4980788.383843305, -8235014.0098648695 4980797.646287312, -8234971.897701503 4980873.863303045, -8234967.901331782 4980881.096893321)" +688,East 42nd Street,"LINESTRING (-8235513.800982684 4976047.812411671, -8235501.043769039 4976041.464108522, -8235348.625122245 4975956.217965122, -8235333.652650733 4975948.238576218)" +689,West 42nd Street,"LINESTRING (-8235513.800982684 4976047.812411671, -8235529.797593512 4976055.747796408, -8235683.919428514 4976141.935306889, -8235705.8716321 4976154.1911885375, -8235820.430520074 4976218.071914092, -8235857.655757796 4976238.660201044, -8235874.342549466 4976247.888940469)" +690,5th Avenue,"LINESTRING (-8235513.800982684 4976047.812411671, -8235521.392971957 4976034.51330911, -8235563.6721145585 4975960.494214896, -8235569.58317952 4975950.148926559)" +691,7th Avenue,"LINESTRING (-8236189.476895953 4976423.368907339, -8236196.790586498 4976410.52486014, -8236239.926889179 4976334.768838309, -8236244.925134317 4976325.922101609)" +692,West 42nd Street,"LINESTRING (-8236189.476895953 4976423.368907339, -8236176.307800191 4976416.3443576945, -8236140.474056104 4976396.637436803, -8236131.145482777 4976391.508647355)" +693,West 42nd Street,"LINESTRING (-8236189.476895953 4976423.368907339, -8236202.902026542 4976430.819638109, -8236216.160177896 4976438.211591609, -8236249.055087425 4976456.507802753, -8236342.997605705 4976508.736693598, -8236353.060887673 4976514.335811861, -8236364.359815989 4976520.610942965, -8236383.540164253 4976531.280144682, -8236491.063660408 4976591.06315994, -8236505.902548533 4976599.336993476)" +694,West 42nd Street,"LINESTRING (-8236823.652903054 4976775.558085344, -8236838.848013546 4976784.037822747, -8236954.37538109 4976848.437039204, -8236967.3663656665 4976855.68234503)" +695,9th Avenue,"LINESTRING (-8236823.652903054 4976775.558085344, -8236830.632635127 4976762.919322288, -8236864.985829985 4976700.636912465, -8236871.186325621 4976688.46852199)" +696,West 42nd Street,"LINESTRING (-8236823.652903054 4976775.558085344, -8236811.185120083 4976769.2093092995, -8236806.977243331 4976766.872608044, -8236802.079185737 4976764.139109172, -8236671.991228796 4976691.7604522165, -8236603.26257518 4976652.8892933065, -8236566.215448643 4976632.505877841, -8236521.119922923 4976607.40509012, -8236505.902548533 4976599.336993476)" +697,West 42nd Street,"LINESTRING (-8237138.3308396265 4976951.003440932, -8237153.993491981 4976959.821350641, -8237330.601864126 4977059.258530085, -8237344.7505714055 4977067.238826464, -8237346.13093309 4977068.017750768, -8237438.16988808 4977119.706130722, -8237446.630169378 4977124.717728309)" +698,West 42nd Street,"LINESTRING (-8237138.3308396265 4976951.003440932, -8237123.759118282 4976942.876274532, -8236983.496559882 4976864.676525256, -8236977.407383735 4976861.281662139, -8236967.3663656665 4976855.68234503)" +699,10th Avenue,"LINESTRING (-8237138.3308396265 4976951.003440932, -8237129.380752566 4976967.19900788, -8237087.947638093 4977042.151618379, -8237082.604302537 4977051.792623354)" +700,West 42nd Street,"LINESTRING (-8237787.802144763 4977308.032271564, -8237757.723618349 4977295.363425541)" +701,West 71st Street,"LINESTRING (-8235338.272409601 4979465.062026588, -8235351.697540191 4979472.559178793, -8235620.534110456 4979622.738640064, -8235635.3173388345 4979630.956239877)" +702,Columbus Avenue,"LINESTRING (-8235338.272409601 4979465.062026588, -8235342.435758557 4979457.49137873, -8235383.445858966 4979382.755434052, -8235388.410708254 4979373.700134205)" +703,5th Avenue,"LINESTRING (-8234231.689879422 4978369.231380431, -8234235.608325497 4978362.1613354795, -8234258.395425263 4978321.255125968, -8234274.481091683 4978292.401873177, -8234277.765016661 4978286.390177136, -8234282.8745812895 4978277.600466846)" +704,Madison Avenue,"LINESTRING (-8234052.89964526 4978269.957246935, -8234049.059122826 4978277.012526639, -8234006.535077343 4978354.547446641, -8234002.527575675 4978361.867362827)" +705,East 67th Street,"LINESTRING (-8234052.89964526 4978269.957246935, -8234066.914769149 4978277.703356386, -8234220.2351038195 4978363.043253489, -8234231.689879422 4978369.231380431)" +706,East 67th Street,"LINESTRING (-8233864.769705818 4978165.363323114, -8233884.562311282 4978176.298891724)" +707,Park Avenue,"LINESTRING (-8233864.769705818 4978165.363323114, -8233860.239002543 4978173.447411631, -8233818.249290615 4978248.982518409, -8233813.885566575 4978256.787405122)" +708,East 67th Street,"LINESTRING (-8233693.949947196 4978070.192056776, -8233705.816604914 4978076.8650388885, -8233725.241856058 4978087.668224439, -8233852.290790901 4978158.396314012, -8233864.769705818 4978165.363323114)" +709,Lexington Avenue,"LINESTRING (-8233693.949947196 4978070.192056776, -8233698.413858777 4978062.1815446215, -8233740.79318892 4977985.369150595, -8233744.822954487 4977978.064214612)" +710,3rd Avenue,"LINESTRING (-8233515.738574384 4977969.656930865, -8233511.08541967 4977978.034818503, -8233469.2404230805 4978054.1122463625, -8233464.698587856 4978062.357922801)" +711,East 67th Street,"LINESTRING (-8233515.738574384 4977969.656930865, -8233530.866893183 4977979.093078505, -8233682.918185658 4978063.915930183, -8233693.949947196 4978070.192056776)" +712,2nd Avenue,"LINESTRING (-8233266.549894245 4977830.864304605, -8233270.624187607 4977823.294923368, -8233312.279941063 4977747.983574032, -8233316.899699929 4977739.576488315)" +713,East 67th Street,"LINESTRING (-8233266.549894245 4977830.864304605, -8233281.956511769 4977838.227921883, -8233500.9776099045 4977960.602941076, -8233515.738574384 4977969.656930865)" +714,East 67th Street,"LINESTRING (-8233000.318200062 4977684.107541187, -8233017.851019862 4977693.954946536, -8233252.334395271 4977824.220886195, -8233266.549894245 4977830.864304605)" +715,1st Avenue,"LINESTRING (-8233000.318200062 4977684.107541187, -8232995.38674662 4977692.779136421, -8232965.230296563 4977745.8083134, -8232953.675333421 4977767.472755116, -8232949.434060822 4977775.438932335)" +716,9th Avenue,"LINESTRING (-8237232.384677399 4976037.129042769, -8237240.522132175 4976022.022455787, -8237272.916103996 4975962.2135323435, -8237281.46544089 4975946.607431221, -8237285.873692724 4975938.245980518)" +717,West 34th Street,"LINESTRING (-8237232.384677399 4976037.129042769, -8237214.684878362 4976027.812331696, -8237174.376090745 4976005.446383328, -8237166.294295713 4976000.89090735, -8237157.043646029 4975995.659460134, -8237119.016907974 4975971.985726997, -8237111.191147773 4975967.1510610515, -8237102.931241556 4975962.316397499, -8237050.321650206 4975933.146821651, -8237041.237979757 4975928.1946151545, -8237032.543927526 4975923.462835625, -8236930.6977254 4975868.018894042, -8236914.066593475 4975859.437087577)" +718,West 34th Street,"LINESTRING (-8237232.384677399 4976037.129042769, -8237246.121502562 4976044.6676498735, -8237295.013022918 4976071.51571891, -8237312.501314921 4976081.141070877, -8237333.640886224 4976092.764981846, -8237376.36530679 4976116.189188316)" +719,West 34th Street,"LINESTRING (-8237547.530155835 4976211.0034258645, -8237562.124141077 4976219.188765091, -8237690.854000229 4976289.96210981, -8237700.037858221 4976295.223105657)" +720,10th Avenue,"LINESTRING (-8237547.530155835 4976211.0034258645, -8237539.659867834 4976225.8310920885, -8237527.1030292725 4976247.095386099, -8237497.714683703 4976300.307757967, -8237493.017001192 4976308.801778423)" +721,West 34th Street,"LINESTRING (-8237547.530155835 4976211.0034258645, -8237532.323913392 4976202.480099667, -8237472.9906247975 4976169.26858921, -8237463.450544436 4976163.948879885, -8237430.53337101 4976145.932427272, -8237389.890624922 4976123.624989567, -8237376.36530679 4976116.189188316)" +722,West 30th Street,"LINESTRING (-8237751.422935171 4975841.230163544, -8237736.261220526 4975832.736549573, -8237733.177670631 4975831.061339384, -8237718.394442252 4975823.008578627, -8237645.446779935 4975782.803653406)" +723,10th Avenue,"LINESTRING (-8237751.422935171 4975841.230163544, -8237747.849579516 4975847.6518108435, -8237743.062841413 4975856.233606958, -8237738.977416099 4975863.448787263)" +724,Freedom Place,"LINESTRING (-8236279.267197227 4979628.927565219, -8236243.288737801 4979728.803541108)" +725,West 68th Street,"LINESTRING (-8236371.050117385 4979680.45309199, -8236360.35231432 4979674.425840866, -8236295.252676105 4979637.733192331, -8236290.844424268 4979635.307601432, -8236279.267197227 4979628.927565219)" +726,Riverside Boulevard,"LINESTRING (-8236371.050117385 4979680.45309199, -8236374.000083891 4979669.47173724, -8236385.744290171 4979624.517404376, -8236393.525522578 4979596.9245432345, -8236399.815073807 4979575.020835773)" +727,Riverside Boulevard,"LINESTRING (-8236371.050117385 4979680.45309199, -8236368.31165791 4979690.861134397, -8236351.212984127 4979755.044307692, -8236346.626621104 4979770.347778906, -8236342.307424862 4979783.343252639)" +728,Riverside Boulevard,"LINESTRING (-8236435.159012133 4979480.365043382, -8236441.459695311 4979468.193189457, -8236468.632783014 4979413.537636249, -8236478.261918969 4979395.691591255, -8236481.044906237 4979391.149234103, -8236486.054283323 4979382.946536249)" +729,Riverside Boulevard,"LINESTRING (-8236435.159012133 4979480.365043382, -8236430.038315556 4979492.772117828, -8236416.256962597 4979528.4204940805, -8236408.831952561 4979548.82465418, -8236399.815073807 4979575.020835773)" +730,West 66th Street,"LINESTRING (-8236435.159012133 4979480.365043382, -8236425.084598216 4979474.734824041, -8236350.300164301 4979432.750836468)" +731,West 67th Street,"LINESTRING (-8236399.815073807 4979575.020835773, -8236389.696132093 4979569.728672211, -8236383.039226543 4979566.112362092, -8236362.400592949 4979554.528418373)" +732,Riverside Boulevard,"LINESTRING (-8236399.815073807 4979575.020835773, -8236408.831952561 4979548.82465418, -8236416.256962597 4979528.4204940805, -8236430.038315556 4979492.772117828, -8236435.159012133 4979480.365043382)" +733,Riverside Boulevard,"LINESTRING (-8236399.815073807 4979575.020835773, -8236393.525522578 4979596.9245432345, -8236385.744290171 4979624.517404376, -8236374.000083891 4979669.47173724, -8236371.050117385 4979680.45309199)" +734,Riverside Boulevard,"LINESTRING (-8236306.42915298 4979880.11891374, -8236311.616641251 4979867.329123793, -8236317.104692147 4979854.0248198435, -8236342.307424862 4979783.343252639)" +735,Riverside Boulevard,"LINESTRING (-8236306.42915298 4979880.11891374, -8236301.8316580085 4979891.423925927, -8236293.582883743 4979908.212407707, -8236285.311845575 4979925.868276512, -8236277.018543512 4979942.2598902015, -8236255.934631955 4979979.629932079)" +736,West 70th Street,"LINESTRING (-8236306.42915298 4979880.11891374, -8236295.620030423 4979874.694276648, -8236207.043111599 4979826.225498493)" +737,East 80th Street,"LINESTRING (-8233548.299525441 4979603.77497458, -8233538.1805837285 4979598.085882117, -8233384.481762789 4979512.367683391, -8233370.923048813 4979504.8116992125)" +738,5th Avenue,"LINESTRING (-8233548.299525441 4979603.77497458, -8233550.603838902 4979599.805839953, -8233552.351554907 4979596.512929487, -8233562.2144617895 4979579.034061719, -8233565.899136936 4979572.00724228, -8233576.619203899 4979552.470358745, -8233594.664093357 4979519.703167784, -8233603.614180417 4979503.385765111)" +739,East 80th Street,"LINESTRING (-8233370.923048813 4979504.8116992125, -8233358.789224315 4979498.093640369, -8233214.385580859 4979418.315207372, -8233202.307416108 4979411.744210156)" +740,Madison Avenue,"LINESTRING (-8233370.923048813 4979504.8116992125, -8233365.657636897 4979514.337532365, -8233323.233778956 4979591.103150418, -8233319.382124575 4979598.071181624)" +741,East 80th Street,"LINESTRING (-8233182.247643867 4979400.425053059, -8233170.380986147 4979393.69236584, -8233079.789184541 4979343.741263709, -8233023.261147114 4979312.121377904, -8233011.349961601 4979305.462251823)" +742,Park Avenue,"LINESTRING (-8233182.247643867 4979400.425053059, -8233177.438641864 4979409.098172258, -8233134.680825451 4979486.597979285, -8233130.395025055 4979494.345053746)" +743,East 80th Street,"LINESTRING (-8233011.349961601 4979305.462251823, -8232999.672547017 4979298.964830754, -8232848.634261908 4979214.778048621, -8232832.771234469 4979205.928703163)" +744,Lexington Avenue,"LINESTRING (-8233011.349961601 4979305.462251823, -8233015.3574632695 4979298.244528685, -8233033.970082129 4979264.69909115, -8233059.306398235 4979219.05572513, -8233066.620088778 4979205.781704136)" +745,East 80th Street,"LINESTRING (-8232832.771234469 4979205.928703163, -8232817.965742195 4979197.623261646, -8232598.120879826 4979073.953868089, -8232585.063103557 4979066.6775172725)" +746,3rd Avenue,"LINESTRING (-8232832.771234469 4979205.928703163, -8232828.06242001 4979214.410550726, -8232785.772145458 4979290.82101045, -8232781.909359127 4979297.803527444)" +747,2nd Avenue,"LINESTRING (-8232585.063103557 4979066.6775172725, -8232588.6587231085 4979060.165555382, -8232605.9021122325 4979030.663335475, -8232633.1753874775 4978982.448638779, -8232640.6337933615 4978968.675154804)" +748,5th Avenue,"LINESTRING (-8233916.822699712 4978937.100581818, -8233919.7837981675 4978931.735266481, -8233964.233670843 4978851.358785694, -8233972.3933895165 4978836.61532965)" +749,East 73rd Street,"LINESTRING (-8233739.023209019 4978837.703081381, -8233752.270228422 4978845.09685648, -8233907.149035963 4978931.588271581, -8233916.822699712 4978937.100581818)" +750,Madison Avenue,"LINESTRING (-8233739.023209019 4978837.703081381, -8233733.980436086 4978846.875479159, -8233691.679029583 4978923.768146129, -8233687.4377569845 4978931.470675663)" +751,East 73rd Street,"LINESTRING (-8233550.659498648 4978734.014427391, -8233570.385312416 4978744.994730327)" +752,Park Avenue,"LINESTRING (-8233550.659498648 4978734.014427391, -8233546.0731356265 4978742.23127943, -8233503.437770653 4978818.726240887, -8233499.085178562 4978826.531582901)" +753,East 73rd Street,"LINESTRING (-8233379.828608076 4978639.146300027, -8233391.795453336 4978645.819670861, -8233538.013604492 4978727.002915106, -8233550.659498648 4978734.014427391)" +754,Lexington Avenue,"LINESTRING (-8233379.828608076 4978639.146300027, -8233402.74929123 4978597.753863844, -8233428.0633434355 4978552.054818981, -8233435.855707791 4978538.193748571)" +755,East 73rd Street,"LINESTRING (-8233200.993846115 4978539.472552759, -8233217.201963976 4978548.335993282, -8233368.986089673 4978633.090293436, -8233379.828608076 4978639.146300027)" +756,3rd Avenue,"LINESTRING (-8233200.993846115 4978539.472552759, -8233196.3963511465 4978547.777434604, -8233154.773993539 4978624.8441351615, -8233150.699700177 4978632.428836633)" +757,East 73rd Street,"LINESTRING (-8232951.571395045 4978400.774720254, -8232966.85556113 4978408.520933452, -8233186.433256721 4978531.329365735, -8233200.993846115 4978539.472552759)" +758,2nd Avenue,"LINESTRING (-8232951.571395045 4978400.774720254, -8232955.879459339 4978392.940321125, -8232968.54761739 4978374.611085421, -8233002.333082846 4978314.508484084, -8233009.702433135 4978301.088707001)" +759,East 73rd Street,"LINESTRING (-8232688.801737026 4978253.009897969, -8232703.729680742 4978261.5350134615, -8232937.467215561 4978393.293089431, -8232951.571395045 4978400.774720254)" +760,1st Avenue,"LINESTRING (-8232688.801737026 4978253.009897969, -8232683.6587765515 4978262.314033006, -8232651.565367356 4978320.358513162, -8232641.769252166 4978338.085004575, -8232637.227416943 4978346.30152353)" +761,Freedom Place,"LINESTRING (-8236350.300164301 4979432.750836468, -8236345.58021789 4979445.20195121, -8236324.963848197 4979500.960207582, -8236317.416386721 4979521.158505023, -8236311.99512752 4979536.4910105225, -8236279.267197227 4979628.927565219)" +762,West 66th Street,"LINESTRING (-8236350.300164301 4979432.750836468, -8236307.809514666 4979409.083472048, -8236264.561892494 4979385.004560151, -8236237.043714369 4979369.6722924905, -8236221.837471926 4979361.10210926)" +763,West 66th Street,"LINESTRING (-8236350.300164301 4979432.750836468, -8236425.084598216 4979474.734824041, -8236435.159012133 4979480.365043382)" +764,Freedom Place,"LINESTRING (-8236243.288737801 4979728.803541108, -8236216.672247552 4979800.851887696, -8236213.288135032 4979809.745874707, -8236207.043111599 4979826.225498493)" +765,West 69th Street,"LINESTRING (-8236243.288737801 4979728.803541108, -8236252.216560962 4979733.72827344, -8236325.743084633 4979774.33168361, -8236331.598489849 4979777.521748694, -8236342.307424862 4979783.343252639)" +766,West 70th Street,"LINESTRING (-8236207.043111599 4979826.225498493, -8236197.224732512 4979821.006702938, -8236140.440660258 4979788.062201568, -8236079.637954386 4979755.05900842, -8236037.0248533115 4979732.155298963, -8236022.108041544 4979721.820715941)" +767,West 70th Street,"LINESTRING (-8236207.043111599 4979826.225498493, -8236295.620030423 4979874.694276648, -8236306.42915298 4979880.11891374)" +768,West 77th Street,"LINESTRING (-8235020.054513221 4980044.447153457, -8235003.334325703 4980038.463781135, -8234999.104185053 4980036.214504527, -8234886.626971555 4979973.587795239, -8234829.842899302 4979942.274591212, -8234719.336040791 4979880.795155973, -8234715.35080302 4979878.634121174, -8234702.7494366625 4979870.18109849)" +769,West 77th Street,"LINESTRING (-8235020.054513221 4980044.447153457, -8235032.98983805 4980049.033918016, -8235318.268297106 4980207.440330156, -8235322.487305807 4980209.54263207, -8235335.110936063 4980216.555208855)" +770,Columbus Avenue,"LINESTRING (-8235020.054513221 4980044.447153457, -8235026.3551964 4980032.583320508, -8235058.660112628 4979969.162777686, -8235067.020206386 4979954.314726794, -8235072.018451522 4979944.891371554)" +771,West 77th Street,"LINESTRING (-8235335.110936063 4980216.555208855, -8235349.760581052 4980224.699801212, -8235484.234525929 4980299.309875878, -8235496.435142119 4980306.028485948)" +772,Amsterdam Avenue,"LINESTRING (-8235335.110936063 4980216.555208855, -8235331.303809478 4980223.553089242, -8235288.879951537 4980300.3389843395, -8235284.6720747845 4980307.92498722)" +773,Riverside Drive,"LINESTRING (-8235849.284532088 4980503.090168929, -8235889.53765996 4980450.001912936, -8235898.176052445 4980438.328710089, -8235903.842214525 4980430.051623832, -8235908.428577548 4980422.627245149, -8235912.892489127 4980414.1737515405)" +774,Riverside Drive,"LINESTRING (-8235849.284532088 4980503.090168929, -8235789.183139008 4980578.5697869435, -8235783.24981015 4980585.935476279)" +775,Madison Avenue,"LINESTRING (-8234976.038786559 4976599.689697015, -8234971.162992862 4976608.389721678, -8234936.486971482 4976670.127788173, -8234929.952517373 4976682.869303927, -8234925.343890454 4976691.143215216)" +776,East 49th Street,"LINESTRING (-8234976.038786559 4976599.689697015, -8234988.595625123 4976606.596810556, -8235004.625631795 4976615.443801417, -8235032.845122713 4976630.992186825, -8235141.782376401 4976691.0256462665, -8235155.708444701 4976698.697023111)" +777,East 49th Street,"LINESTRING (-8234787.641680341 4976495.363484486, -8234806.799764708 4976506.150225353)" +778,Park Avenue,"LINESTRING (-8234787.641680341 4976495.363484486, -8234783.289088252 4976503.196361888, -8234741.065605394 4976579.291696596, -8234737.169423216 4976586.28697148)" +779,East 49th Street,"LINESTRING (-8234616.654942483 4976398.959353829, -8234628.042926391 4976405.322584961, -8234650.718706666 4976417.975581115, -8234710.218974494 4976451.217328539, -8234775.518987794 4976488.441753773, -8234787.641680341 4976495.363484486)" +780,Lexington Avenue,"LINESTRING (-8234616.654942483 4976398.959353829, -8234620.56225661 4976391.655604036, -8234661.238398546 4976315.767468529, -8234666.937956474 4976305.142588775)" +781,East 49th Street,"LINESTRING (-8234438.977903227 4976300.440017745, -8234456.711098112 4976310.241941793, -8234474.9897585 4976320.323091325, -8234505.2018683 4976337.0907406295, -8234605.1333751865 4976392.581431172, -8234616.654942483 4976398.959353829)" +782,3rd Avenue,"LINESTRING (-8234438.977903227 4976300.440017745, -8234434.436068005 4976308.493172013, -8234392.6022033645 4976384.645772852, -8234388.17168763 4976393.022301268)" +783,2nd Avenue,"LINESTRING (-8234188.965458856 4976161.039205842, -8234193.429370436 4976152.868610642, -8234224.854862687 4976095.468902435, -8234234.6732417755 4976077.5701376675, -8234239.393188185 4976068.899976044)" +784,East 49th Street,"LINESTRING (-8234188.965458856 4976161.039205842, -8234204.527923669 4976169.709449229, -8234231.945914251 4976184.992608849, -8234313.643288543 4976230.504236356, -8234378.787454557 4976266.802005354, -8234422.947896554 4976291.4757479895, -8234438.977903227 4976300.440017745)" +785,East 49th Street,"LINESTRING (-8233736.796819202 4975909.6054944685, -8233761.676725395 4975923.477530587, -8233841.804494867 4975968.17971318, -8233856.331688416 4975976.276678717, -8233877.1039053975 4975987.73881926, -8233909.865231538 4976005.916626132, -8233920.073228844 4976011.677102301)" +786,East 82nd Street,"LINESTRING (-8233445.395788153 4979790.7965468485, -8233436.890979055 4979785.857084962, -8233279.841441445 4979698.431963172, -8233267.596297457 4979691.610866692)" +787,5th Avenue,"LINESTRING (-8233445.395788153 4979790.7965468485, -8233449.614796855 4979783.490260361, -8233492.127710387 4979706.5761234, -8233497.114823575 4979697.505822638)" +788,East 82nd Street,"LINESTRING (-8233267.596297457 4979691.610866692, -8233255.551528554 4979684.892679343, -8233110.324120865 4979604.598202705, -8233099.214435684 4979598.335790501)" +789,Madison Avenue,"LINESTRING (-8233267.596297457 4979691.610866692, -8233262.7205037605 4979700.416550327, -8233220.04061099 4979777.448244878, -8233215.8216022905 4979785.07794388)" +790,East 82nd Street,"LINESTRING (-8233078.943156411 4979587.339827615, -8233066.208206663 4979580.195398473, -8232919.611569237 4979498.7404554635, -8232908.368300667 4979492.242905799)" +791,Park Avenue,"LINESTRING (-8233078.943156411 4979587.339827615, -8233074.111890511 4979596.086615267, -8233031.565581129 4979672.911678363, -8233027.368836325 4979680.467792607)" +792,East 82nd Street,"LINESTRING (-8232908.368300667 4979492.242905799, -8232896.356927611 4979485.539555927, -8232745.274114706 4979401.307064829, -8232729.733913792 4979392.192947048)" +793,Lexington Avenue,"LINESTRING (-8232908.368300667 4979492.242905799, -8232912.676364961 4979484.495833004, -8232955.144750699 4979407.84865461, -8232960.109599988 4979398.91093304)" +794,3rd Avenue,"LINESTRING (-8232729.733913792 4979392.192947048, -8232724.55755747 4979401.556968178, -8232682.6346372375 4979477.454381281, -8232678.192989554 4979485.466054307)" +795,West 66th Street,"LINESTRING (-8235904.487867573 4979181.438695904, -8235920.840700769 4979193.566092782, -8235951.331109299 4979210.809072091, -8235987.899562024 4979230.918569792, -8236014.593975916 4979245.736120911, -8236057.641223005 4979269.844089425, -8236159.320445896 4979326.542149945, -8236184.935060727 4979340.668941163, -8236207.477257613 4979353.222839377, -8236221.837471926 4979361.10210926)" +796,Amsterdam Avenue,"LINESTRING (-8235904.487867573 4979181.438695904, -8235899.088872268 4979191.890306136, -8235858.891404143 4979263.64069184, -8235854.783714933 4979271.225889424)" +797,East 74th Street,"LINESTRING (-8233865.159324036 4979030.50163945, -8233855.6860353695 4979025.224470586, -8233700.79609588 4978938.923319753, -8233687.4377569845 4978931.470675663)" +798,5th Avenue,"LINESTRING (-8233865.159324036 4979030.50163945, -8233868.799471385 4979023.916203534, -8233912.291996438 4978945.273506188, -8233916.822699712 4978937.100581818)" +799,East 74th Street,"LINESTRING (-8233687.4377569845 4978931.470675663, -8233675.960717483 4978925.076399762, -8233531.790844958 4978844.758771216, -8233518.911179871 4978837.585486593)" +800,Madison Avenue,"LINESTRING (-8233687.4377569845 4978931.470675663, -8233682.695546676 4978940.069880888, -8233640.238292889 4979017.036779688, -8233635.98588834 4979024.709983522)" +801,East 74th Street,"LINESTRING (-8233499.085178562 4978826.531582901, -8233487.084937455 4978819.843389268, -8233340.421508335 4978738.130202145, -8233328.788621546 4978731.647857692)" +802,Park Avenue,"LINESTRING (-8233499.085178562 4978826.531582901, -8233494.142593171 4978835.468780662, -8233451.763263024 4978912.155565376, -8233447.366143139 4978920.122676254)" +803,East 74th Street,"LINESTRING (-8233328.788621546 4978731.647857692, -8233317.088943064 4978725.136119182, -8233165.649907789 4978640.748496573, -8233150.699700177 4978632.428836633)" +804,Lexington Avenue,"LINESTRING (-8233328.788621546 4978731.647857692, -8233332.751595419 4978724.445257789, -8233375.286772851 4978647.377771315, -8233379.828608076 4978639.146300027)" +805,East 74th Street,"LINESTRING (-8233150.699700177 4978632.428836633, -8233135.627041121 4978624.035688647, -8232915.526143926 4978501.402476803, -8232900.152922247 4978492.833055457)" +806,3rd Avenue,"LINESTRING (-8233150.699700177 4978632.428836633, -8233145.701455038 4978641.2923615165, -8233102.787791339 4978717.374955705, -8233097.822942047 4978726.179760954)" +807,East 74th Street,"LINESTRING (-8232900.152922247 4978492.833055457, -8232887.072882079 4978485.542438754, -8232652.789881756 4978355.017802536, -8232637.227416943 4978346.30152353)" +808,2nd Avenue,"LINESTRING (-8232900.152922247 4978492.833055457, -8232904.416458745 4978485.189667116, -8232947.408046089 4978408.226959404, -8232951.571395045 4978400.774720254)" +809,1st Avenue,"LINESTRING (-8232637.227416943 4978346.30152353, -8232631.795025791 4978356.120199254, -8232598.432574401 4978416.45823608, -8232589.938897253 4978431.818404856, -8232584.595561695 4978441.4754802715)" +810,West 35th Street,"LINESTRING (-8236544.0517380275 4975780.114514091, -8236558.846098353 4975788.358271384, -8236619.081074822 4975821.921162537, -8236636.680686316 4975831.7226065295, -8236809.314952639 4975927.91541071, -8236845.237752317 4975947.929981197, -8236860.3994669635 4975956.3649152545)" +811,7th Avenue,"LINESTRING (-8236494.369849285 4975872.6624773955, -8236499.423754168 4975863.228364161, -8236539.153680432 4975789.254651828, -8236544.0517380275 4975780.114514091)" +812,West 36th Street,"LINESTRING (-8236494.369849285 4975872.6624773955, -8236480.499440734 4975864.991749119, -8236281.14849662 4975754.7954955185, -8236270.105603134 4975748.550245656)" +813,West 37th Street,"LINESTRING (-8236444.854939781 4975961.772681686, -8236459.7606195975 4975970.075372388, -8236706.51140289 4976107.44551622, -8236745.985294326 4976129.414925684, -8236760.557015671 4976137.526720128)" +814,7th Avenue,"LINESTRING (-8236444.854939781 4975961.772681686, -8236449.151872125 4975954.043103411, -8236489.716694569 4975881.009177075, -8236494.369849285 4975872.6624773955)" +815,West 39th Street,"LINESTRING (-8236342.441008251 4976145.814864885, -8236356.868014258 4976153.382946469, -8236647.000003112 4976312.269927306, -8236660.146834975 4976319.603008872)" +816,7th Avenue,"LINESTRING (-8236342.441008251 4976145.814864885, -8236348.552448296 4976134.705225645, -8236388.404825999 4976063.3598937495, -8236395.3288983265 4976051.177601818)" +817,West 40th Street,"LINESTRING (-8236294.028161706 4976235.162687425, -8236280.881329843 4976227.770887552, -8236249.533761236 4976210.239265281, -8236195.655127692 4976180.128446801, -8236187.706916048 4976175.69045212, -8236183.766206075 4976173.427369514)" +818,7th Avenue,"LINESTRING (-8236294.028161706 4976235.162687425, -8236298.447545489 4976227.006725657, -8236337.153332438 4976155.513766613, -8236342.441008251 4976145.814864885)" +819,West 41st Street,"LINESTRING (-8236244.925134317 4976325.922101609, -8236254.9772843355 4976331.521115102, -8236355.921798585 4976387.761252757, -8236366.686393346 4976393.771780477, -8236544.363432601 4976492.762323962, -8236559.84797377 4976501.388774238)" +820,7th Avenue,"LINESTRING (-8236244.925134317 4976325.922101609, -8236249.155274967 4976318.104061891, -8236272.19840956 4976275.516429078, -8236289.586514022 4976243.3774377825, -8236294.028161706 4976235.162687425)" +821,West 43rd Street,"LINESTRING (-8236134.830157923 4976522.403838308, -8236146.819267081 4976529.002283834, -8236348.953198463 4976642.058302289, -8236436.672957208 4976691.113822977, -8236450.766004742 4976699.005641847)" +822,7th Avenue,"LINESTRING (-8236134.830157923 4976522.403838308, -8236140.340472716 4976512.719268201, -8236181.818114985 4976437.256368674, -8236189.476895953 4976423.368907339)" +823,7th Avenue,"LINESTRING (-8236085.1371372305 4976615.340929383, -8236090.090854572 4976606.067754879, -8236128.128724576 4976534.954114913, -8236134.830157923 4976522.403838308)" +824,West 44th Street,"LINESTRING (-8236085.1371372305 4976615.340929383, -8236072.647090364 4976608.53668162, -8236068.617324798 4976606.302890731, -8236053.489005999 4976597.926179448, -8236049.37018484 4976595.64830306, -8235865.837740369 4976493.261981862, -8235783.22754625 4976447.175996, -8235768.422053975 4976438.946378544)" +825,7th Avenue,"LINESTRING (-8235981.376239863 4976799.689350454, -8235987.1759853335 4976788.975766808, -8235999.710559997 4976765.902656744, -8236026.16007101 4976717.199468299, -8236031.915288683 4976706.60354425)" +826,West 46th Street,"LINESTRING (-8235981.376239863 4976799.689350454, -8235968.897324946 4976792.75270785, -8235892.131404094 4976749.736815916, -8235716.803206095 4976650.155826327, -8235682.071524968 4976630.845226546, -8235666.8096227795 4976622.365622111)" +827,West 47th Street,"LINESTRING (-8235930.158142149 4976891.659115616, -8235943.5276129935 4976899.418828604, -8235968.797137403 4976913.644985088, -8235987.788242534 4976923.3152561765)" +828,7th Avenue,"LINESTRING (-8235930.158142149 4976891.659115616, -8235936.436561431 4976880.622110225, -8235975.554230495 4976810.138412487, -8235981.376239863 4976799.689350454)" +829,7th Avenue,"LINESTRING (-8235880.576440949 4976982.5422013365, -8235885.129408122 4976974.223953618, -8235926.339883615 4976898.669310602, -8235930.158142149 4976891.659115616)" +830,West 48th Street,"LINESTRING (-8235880.576440949 4976982.5422013365, -8235867.173574259 4976975.002870507, -8235767.7652689805 4976919.0973708015, -8235751.81318595 4976910.279497849, -8235653.662790918 4976856.020361457, -8235581.115878766 4976815.884666554, -8235565.208323533 4976806.772960907)" +831,West 50th Street,"LINESTRING (-8235777.761759254 4977166.809370815, -8235765.23831654 4977159.843073882, -8235666.364344817 4977105.391493708, -8235617.072074293 4977078.173165787, -8235477.455168941 4977001.118667043, -8235462.415905734 4976992.771010362)" +832,7th Avenue,"LINESTRING (-8235777.761759254 4977166.809370815, -8235782.648684898 4977157.844306058, -8235801.906956807 4977122.48381939, -8235823.792368696 4977083.0671684025, -8235828.501183156 4977073.999303633)" +833,7th Avenue,"LINESTRING (-8235728.413828985 4977258.532743754, -8235732.822080819 4977250.331836702, -8235773.231055979 4977175.230660447, -8235777.761759254 4977166.809370815)" +834,West 51st Street,"LINESTRING (-8235728.413828985 4977258.532743754, -8235742.495744569 4977266.3662330825, -8235771.282964889 4977282.371261762, -8235807.138972873 4977302.315122079, -8235812.3932528375 4977305.239833094, -8235825.384237414 4977312.456083618)" +835,West 52nd Street,"LINESTRING (-8235677.21799517 4977350.933045031, -8235663.314190769 4977344.466318231, -8235659.607251726 4977342.746757508, -8235555.033722073 4977284.531722188, -8235548.688511099 4977280.872167054, -8235475.173119379 4977239.485486339, -8235377.267627226 4977183.960591398, -8235361.426863685 4977176.318227178)" +836,7th Avenue,"LINESTRING (-8235677.21799517 4977350.933045031, -8235679.923058796 4977346.097696634, -8235681.982469374 4977342.423421336, -8235722.480500124 4977269.261539357, -8235728.413828985 4977258.532743754)" +837,West 53rd Street,"LINESTRING (-8235627.157620159 4977441.6146421945, -8235641.907452688 4977449.801012573, -8235720.3876936985 4977493.36378828, -8235723.972181302 4977495.3332301, -8235739.122763999 4977502.9611465605)" +838,7th Avenue,"LINESTRING (-8235627.157620159 4977441.6146421945, -8235631.176253777 4977434.339507312, -8235646.182121136 4977407.193748817, -8235669.10280429 4977365.718350113, -8235672.520312657 4977359.530858881, -8235677.21799517 4977350.933045031)" +839,West 54th Street,"LINESTRING (-8235575.427452787 4977534.325320388, -8235562.3140167715 4977527.094208587, -8235509.570842034 4977497.434948299, -8235460.467814644 4977470.9063007, -8235452.497339104 4977466.629389742, -8235443.903474416 4977461.544130353, -8235413.324010294 4977443.922110351, -8235391.805952723 4977431.517638271, -8235382.221344568 4977425.991480425, -8235276.757258989 4977367.26154925, -8235274.697848409 4977366.115172724, -8235261.027814941 4977358.502060245)" +840,7th Avenue,"LINESTRING (-8235575.427452787 4977534.325320388, -8235580.292114535 4977525.62447107, -8235621.56938172 4977451.623472979, -8235627.157620159 4977441.6146421945)" +841,7th Avenue,"LINESTRING (-8235524.109167533 4977628.065705422, -8235527.927426065 4977620.8492217455, -8235528.8847736865 4977619.056124794, -8235552.840728106 4977575.492788547, -8235566.499629625 4977550.654131161, -8235570.184304772 4977543.952113716, -8235575.427452787 4977534.325320388)" +842,West 55th Street,"LINESTRING (-8235524.109167533 4977628.065705422, -8235539.170694636 4977636.928318944, -8235628.092703882 4977686.312183312, -8235652.571859907 4977700.862833825, -8235666.965470066 4977709.152305021)" +843,West 57th Street,"LINESTRING (-8235419.9363880465 4977817.342307294, -8235435.409797268 4977826.014020807, -8235450.972262081 4977834.744533376, -8235469.217526622 4977844.974234799, -8235513.533815906 4977869.828338496, -8235609.190654346 4977922.81438275, -8235613.031176778 4977925.121964578, -8235626.623286603 4977931.941827437)" +844,West 57th Street,"LINESTRING (-8235419.9363880465 4977817.342307294, -8235404.607694165 4977808.832277278, -8235294.04517591 4977747.380967999, -8235151.689811083 4977668.08715668, -8235119.373762905 4977650.097325032, -8235103.789034195 4977641.411070138)" +845,7th Avenue,"LINESTRING (-8235419.9363880465 4977817.342307294, -8235426.938384019 4977804.614009535, -8235448.846059806 4977764.81246491, -8235465.900205796 4977733.82969088, -8235466.623782486 4977732.521596794, -8235475.084063787 4977717.147830002)" +846,West 58th Street,"LINESTRING (-8235363.842496636 4977919.110494583, -8235350.12793537 4977911.364669508, -8235063.658357765 4977749.556228983, -8235049.153428113 4977741.36960739)" +847,7th Avenue,"LINESTRING (-8235363.842496636 4977919.110494583, -8235370.57732583 4977906.896492371, -8235382.176816771 4977885.834355962, -8235411.765537422 4977832.157714023, -8235419.9363880465 4977817.342307294)" +848,East 50th Street,"LINESTRING (-8235104.946756899 4976791.88562787, -8235090.597674536 4976784.096607781, -8235071.862604233 4976773.809232271, -8234937.7560136765 4976698.579454073, -8234925.343890454 4976691.143215216)" +849,5th Avenue,"LINESTRING (-8235104.946756899 4976791.88562787, -8235109.087841955 4976784.287659142, -8235126.809904889 4976751.750196453, -8235134.023407894 4976738.508920392, -8235150.843782952 4976707.617578093, -8235155.708444701 4976698.697023111)" +850,West 50th Street,"LINESTRING (-8236411.447960594 4977518.848983978, -8236397.2658574665 4977510.956502773, -8236265.029434353 4977437.499413717, -8236246.761905915 4977427.358322367, -8236226.891376808 4977416.291317299, -8236111.742495532 4977352.314573583, -8236107.178396408 4977349.771973312, -8236095.100231658 4977343.070093689)" +851,9th Avenue,"LINESTRING (-8236411.447960594 4977518.848983978, -8236416.2124348 4977510.236332551, -8236457.645549273 4977435.147855366, -8236462.5213429695 4977426.49118606)" +852,West 50th Street,"LINESTRING (-8236727.851349275 4977694.660432673, -8236715.149795377 4977687.590875974, -8236705.420471882 4977682.196851746, -8236442.795529202 4977536.265375686, -8236430.7396283485 4977529.578065492, -8236426.776654475 4977527.373458741, -8236411.447960594 4977518.848983978)" +853,10th Avenue,"LINESTRING (-8236727.851349275 4977694.660432673, -8236722.697256852 4977703.949338236, -8236681.119427042 4977778.848810917, -8236677.089661473 4977786.109504621)" +854,West 50th Street,"LINESTRING (-8237294.99075902 4978009.812064647, -8237271.713853496 4977996.818950585)" +855,12th Avenue,"LINESTRING (-8237294.99075902 4978009.812064647, -8237301.358233893 4977998.421041769, -8237346.0196135985 4977917.743583831)" +856,79th Street Transverse,"LINESTRING (-8233603.614180417 4979503.385765111, -8233618.107978119 4979511.706167032, -8233625.443932561 4979516.5719884, -8233633.937609709 4979522.628542858, -8233642.921092615 4979529.670027155, -8233652.561360519 4979537.711143824, -8233662.836149519 4979546.854798248, -8233675.404120029 4979559.070851519, -8233685.077783779 4979569.346460509, -8233694.8516350705 4979579.739684034, -8233703.300784423 4979588.515865836, -8233728.60370468 4979613.6684171725, -8233736.618708018 4979620.959876078, -8233746.036336938 4979629.442084115, -8233755.710000688 4979636.939362518, -8233764.726879441 4979643.054793868, -8233772.7975425245 4979647.920680683, -8233781.80328933 4979652.492558421, -8233790.4305498665 4979656.476415043, -8233799.4919564165 4979660.10745921, -8233809.143356267 4979663.253385208, -8233818.1936308695 4979665.825988996, -8233828.078801652 4979667.9575755065, -8233837.986236334 4979669.662845048, -8233849.697046764 4979670.70658776, -8233859.6156133935 4979670.941797402, -8233868.454380964 4979671.338713681, -8233877.994461323 4979672.220749922, -8233886.165311949 4979673.661409282, -8233893.645981731 4979675.601889574, -8233940.633938793 4979689.508676281, -8233965.191018463 4979696.800191813, -8233973.228285697 4979699.387505085, -8233982.824025804 4979702.974463254, -8233992.31957837 4979707.16414967, -8234001.3141932255 4979711.677252487, -8234010.587106807 4979716.866588271, -8234078.658975429 4979754.1769647, -8234134.697207094 4979784.9750384595, -8234145.884815919 4979791.384578193, -8234179.71480917 4979810.289804752, -8234229.0070796935 4979837.942072195, -8234245.649343568 4979847.380025099, -8234255.256215623 4979852.466526864, -8234265.519872674 4979857.112004781, -8234275.861453368 4979861.389962663, -8234321.135090274 4979878.722326667, -8234334.871915437 4979884.499788171, -8234344.27841241 4979888.792458983, -8234354.775840391 4979893.849580442, -8234365.173080832 4979899.553546161, -8234374.579577804 4979905.286917123, -8234384.976818245 4979912.078760928, -8234397.489129009 4979921.0316531565, -8234405.459604549 4979927.661797029, -8234445.334246153 4979963.032441067, -8234453.727735758 4979971.2650283, -8234461.854058587 4979979.424117138, -8234467.898706934 4979986.759952382, -8234472.062055893 4979992.625684328, -8234475.82465468 4979997.888674887, -8234479.320086691 4980003.84262014, -8234481.5019487105 4980009.370236761, -8234483.405512003 4980016.11804959, -8234484.830401486 4980022.615947831, -8234485.921332496 4980029.907712094, -8234486.555853594 4980038.199160332, -8234487.257166386 4980047.152168194, -8234487.001131555 4980055.69355116, -8234486.511325796 4980064.308447575, -8234485.164359958 4980072.2470960505, -8234483.060421582 4980082.023403503, -8234480.210642618 4980092.505380111, -8234462.611031123 4980152.016170262, -8234461.0080304565 4980157.911404151, -8234459.805779955 4980163.791940252, -8234458.859564284 4980169.510765007, -8234458.013536155 4980175.876453054, -8234457.757501325 4980181.595284887, -8234457.891084714 4980189.166494137, -8234458.525605812 4980194.576604535, -8234459.917099446 4980200.765892119, -8234461.642551553 4980206.087800493, -8234463.189892476 4980210.953967873, -8234465.616657375 4980216.114166141, -8234469.212276927 4980222.068244454, -8234472.963743768 4980227.434268762, -8234477.060301028 4980231.888806248, -8234480.377621855 4980235.167229524, -8234485.253415552 4980239.3865472, -8234490.0735495025 4980242.591465677, -8234494.47066939 4980245.399445575)" +857,5th Avenue,"LINESTRING (-8233603.614180417 4979503.385765111, -8233610.449197152 4979491.022778177, -8233622.516229953 4979469.207510037, -8233654.1532292375 4979412.008813985, -8233659.051286833 4979403.159289805)" +858,East 79th Street,"LINESTRING (-8233603.614180417 4979503.385765111, -8233594.185419546 4979498.005438316, -8233575.060731029 4979487.538800144, -8233539.249250841 4979467.987385293, -8233497.693684927 4979445.20195121, -8233472.446424416 4979431.486615553, -8233438.460583876 4979413.008428515, -8233427.172787509 4979406.687338351)" +859,West 51st Street,"LINESTRING (-8235053.183193679 4976884.76649694, -8235066.419081135 4976892.717257934, -8235176.291418548 4976953.207917614, -8235193.768578602 4976962.981103558, -8235202.184332106 4976967.7574761845, -8235357.441625917 4977053.908942793, -8235412.834204535 4977083.037774985)" +860,5th Avenue,"LINESTRING (-8235053.183193679 4976884.76649694, -8235058.5821889825 4976874.684764947, -8235100.850199636 4976799.557083918, -8235104.946756899 4976791.88562787)" +861,Madison Avenue,"LINESTRING (-8234874.203716383 4976783.670416293, -8234869.906784037 4976791.518221124, -8234828.818759985 4976866.836893309, -8234823.987494085 4976875.640030652)" +862,East 51st Street,"LINESTRING (-8234874.203716383 4976783.670416293, -8234887.840354004 4976791.444739775, -8234987.860916482 4976847.261330855, -8235039.99183402 4976876.654082041, -8235053.183193679 4976884.76649694)" +863,East 51st Street,"LINESTRING (-8234685.61736703 4976679.533288393, -8234705.098277918 4976690.3496248415)" +864,Park Avenue,"LINESTRING (-8234685.61736703 4976679.533288393, -8234681.131191551 4976687.689627946, -8234639.341854707 4976763.169158144, -8234637.672062345 4976766.181885139, -8234634.621908297 4976772.207341919)" +865,Lexington Avenue,"LINESTRING (-8234515.053643235 4976583.333083785, -8234519.050012955 4976575.456054301, -8234560.638974715 4976500.404153463, -8234565.6706157 4976491.2486545965)" +866,East 51st Street,"LINESTRING (-8234515.053643235 4976583.333083785, -8234527.120676039 4976590.049138196, -8234566.516643829 4976611.990240909, -8234623.122604899 4976644.4684539335, -8234670.823006703 4976671.053641699, -8234673.238639654 4976672.390985836, -8234685.61736703 4976679.533288393)" +867,3rd Avenue,"LINESTRING (-8234337.354340083 4976484.459189068, -8234322.437528317 4976511.293770833, -8234291.000904117 4976568.842881465, -8234285.468325424 4976579.071257343)" +868,East 51st Street,"LINESTRING (-8234337.354340083 4976484.459189068, -8234352.326811594 4976492.718236501, -8234416.647213374 4976528.532015854, -8234437.619805439 4976540.215242689, -8234503.520943989 4976576.910952924, -8234515.053643235 4976583.333083785)" +869,East 51st Street,"LINESTRING (-8234087.353027659 4976345.143925109, -8234102.937756371 4976353.535115267, -8234321.858666965 4976475.935624303, -8234337.354340083 4976484.459189068)" +870,2nd Avenue,"LINESTRING (-8234087.353027659 4976345.143925109, -8234091.905994833 4976336.885002427, -8234107.936001508 4976307.714308263, -8234122.808285478 4976280.630462134, -8234133.439296848 4976261.4969383925, -8234137.981132072 4976253.032349984)" +871,East 51st Street,"LINESTRING (-8233823.414514988 4976197.292630638, -8233839.489049459 4976206.300900145, -8234072.84809801 4976337.031958286, -8234076.599564849 4976339.118731717, -8234087.353027659 4976345.143925109)" +872,1st Avenue,"LINESTRING (-8233823.414514988 4976197.292630638, -8233818.126839176 4976206.859324957, -8233776.7159886 4976281.835493302, -8233771.973778292 4976290.417670792)" +873,East 51st Street,"LINESTRING (-8233673.444896992 4976114.6021010345, -8233667.188741609 4976111.192803304, -8233637.566625109 4976095.028045766)" +874,East 51st Street,"LINESTRING (-8233673.444896992 4976114.6021010345, -8233809.24354381 4976189.474693849, -8233823.414514988 4976197.292630638)" +875,East 51st Street,"LINESTRING (-8233637.566625109 4976095.028045766, -8233667.188741609 4976111.192803304, -8233673.444896992 4976114.6021010345)" +876,Sutton Place South,"LINESTRING (-8233423.143021942 4976338.266387586, -8233431.959525613 4976329.772341513, -8233467.759873854 4976266.640355071, -8233471.255305865 4976260.468255383, -8233472.580007805 4976258.484367026, -8233474.160744574 4976257.05890675, -8233476.119967611 4976256.1771788495, -8233478.090322598 4976255.751010394, -8233480.761990378 4976255.868574102, -8233484.36874188 4976256.632738256, -8233490.235279043 4976258.454976089, -8233512.766343981 4976268.080512227)" +877,Sutton Place South,"LINESTRING (-8233423.143021942 4976338.266387586, -8233416.118762074 4976344.570796797, -8233374.941682429 4976419.32758632, -8233369.854381699 4976428.13032043)" +878,East 55th Street,"LINESTRING (-8233369.854381699 4976428.13032043, -8233355.694542471 4976420.165241811, -8233324.591876743 4976402.692057038)" +879,Sutton Place South,"LINESTRING (-8233369.854381699 4976428.13032043, -8233374.941682429 4976419.32758632, -8233416.118762074 4976344.570796797, -8233423.143021942 4976338.266387586)" +880,East 55th Street,"LINESTRING (-8233369.854381699 4976428.13032043, -8233384.092144573 4976436.124797012, -8233604.103986176 4976559.760798065, -8233618.842686758 4976568.034605091)" +881,Sutton Place South,"LINESTRING (-8233369.854381699 4976428.13032043, -8233365.401602068 4976436.1835799515, -8233324.046411238 4976511.029245571, -8233319.270805083 4976519.670407837)" +882,East 56th Street,"LINESTRING (-8233319.270805083 4976519.670407837, -8233304.899458824 4976511.808125529, -8233269.488728801 4976492.027532978)" +883,Sutton Place South,"LINESTRING (-8233319.270805083 4976519.670407837, -8233324.046411238 4976511.029245571, -8233365.401602068 4976436.1835799515, -8233369.854381699 4976428.13032043)" +884,Sutton Place South,"LINESTRING (-8233319.270805083 4976519.670407837, -8233314.550858675 4976528.208706631, -8233271.392292093 4976606.332282714, -8233264.434823919 4976618.912059155)" +885,West 59th Street,"LINESTRING (-8235946.755878227 4978362.646390374, -8235960.414779748 4978370.127997723, -8236029.0321138725 4978407.756600947, -8236068.450345561 4978429.363715976, -8236217.406956192 4978511.030223306, -8236250.43544911 4978529.036339568, -8236261.378155055 4978535.004088281)" +886,9th Avenue,"LINESTRING (-8235946.755878227 4978362.646390374, -8235952.678075136 4978351.6812158935, -8235971.891819247 4978316.110627377, -8235990.760472937 4978281.201601376, -8235997.038892218 4978269.5897845905)" +887,West 59th Street,"LINESTRING (-8236261.378155055 4978535.004088281, -8236278.354377401 4978544.528975554, -8236402.130519213 4978614.069753467, -8236564.857350856 4978704.763078208, -8236579.306620762 4978712.81821487)" +888,Amsterdam Avenue,"LINESTRING (-8236261.378155055 4978535.004088281, -8236255.734256872 4978545.205125313, -8236240.027076721 4978573.618156384, -8236214.735288413 4978619.2879041005, -8236209.024598534 4978629.636019515)" +889,5th Avenue,"LINESTRING (-8234851.216241534 4977252.198350784, -8234856.526181244 4977242.748208354, -8234897.647601143 4977167.6176967295, -8234901.699630607 4977159.79898341)" +890,West 55th Street,"LINESTRING (-8234851.216241534 4977252.198350784, -8234863.895531535 4977259.311683312, -8235178.662523702 4977436.073781398, -8235194.269516311 4977444.833339962, -8235208.985952993 4977452.931529449)" +891,9th Avenue,"LINESTRING (-8236158.207250988 4977981.3271833295, -8236161.758342746 4977974.50728599, -8236163.361343413 4977971.582374581, -8236192.950064064 4977917.655396046, -8236204.338047974 4977895.373308138, -8236209.124786077 4977886.819116387)" +892,West 55th Street,"LINESTRING (-8236158.207250988 4977981.3271833295, -8236172.111055388 4977989.058365814, -8236459.638168159 4978148.768915098, -8236472.907451461 4978156.176867009)" +893,West 55th Street,"LINESTRING (-8236472.907451461 4978156.176867009, -8236488.180485599 4978164.599009635, -8236766.857698849 4978318.88865628, -8236774.58327151 4978323.474610483, -8236787.563124136 4978331.191365203)" +894,10th Avenue,"LINESTRING (-8236472.907451461 4978156.176867009, -8236468.677310811 4978164.09926624, -8236427.633814556 4978239.016965911, -8236423.247826617 4978247.189306148)" +895,Riverside Drive,"LINESTRING (-8235576.4627240505 4980856.191017635, -8235580.659468856 4980847.149053692, -8235584.934137301 4980839.253882267, -8235591.145764886 4980829.785565924, -8235597.457580015 4980821.12588712, -8235639.024277877 4980767.712452337)" +896,Riverside Drive,"LINESTRING (-8235576.4627240505 4980856.191017635, -8235572.310507045 4980864.791917936, -8235569.11563766 4980872.569490716, -8235565.152663787 4980883.052316002, -8235562.503259905 4980892.829435285, -8235560.377057632 4980901.562689961, -8235558.128403917 4980912.707157607, -8235556.480875454 4980923.028298621, -8235555.401076393 4980932.334977862, -8235553.553172847 4980949.463407556, -8235552.506769633 4980958.931839956)" +897,West 74th Street,"LINESTRING (-8235981.543219099 4980206.028994861, -8235974.51895923 4980203.191623478, -8235969.854672567 4980201.05992013, -8235965.44642073 4980199.031127032, -8235821.888805403 4980119.790914763, -8235808.129716341 4980111.602306109)" +898,Riverside Drive,"LINESTRING (-8235981.543219099 4980206.028994861, -8235984.281678572 4980197.443376207, -8236010.653265943 4980113.484068352, -8236014.05964236 4980103.0755754905)" +899,Riverside Drive,"LINESTRING (-8235981.543219099 4980206.028994861, -8235977.980995394 4980216.966848739, -8235947.523982714 4980311.629781468)" +900,West 76th Street,"LINESTRING (-8235912.892489127 4980414.1737515405, -8235901.938651234 4980408.1019423865, -8235717.8718732055 4980305.940276597, -8235704.958812275 4980298.618903111)" +901,Riverside Drive,"LINESTRING (-8235912.892489127 4980414.1737515405, -8235916.73301156 4980405.191003744, -8235919.716373912 4980397.354996456, -8235947.523982714 4980311.629781468)" +902,Riverside Drive,"LINESTRING (-8235912.892489127 4980414.1737515405, -8235908.428577548 4980422.627245149, -8235903.842214525 4980430.051623832, -8235898.176052445 4980438.328710089, -8235889.53765996 4980450.001912936, -8235849.284532088 4980503.090168929)" +903,Riverside Drive,"LINESTRING (-8235947.523982714 4980311.629781468, -8235977.980995394 4980216.966848739, -8235981.543219099 4980206.028994861)" +904,Riverside Drive,"LINESTRING (-8235947.523982714 4980311.629781468, -8235919.716373912 4980397.354996456, -8235916.73301156 4980405.191003744, -8235912.892489127 4980414.1737515405)" +905,Amsterdam Avenue,"LINESTRING (-8236007.937070366 4978994.649286485, -8236001.72544278 4979005.512285641, -8235962.9528641375 4979075.659033913, -8235956.095583503 4979087.771599714)" +906,West 65th Street,"LINESTRING (-8235956.095583503 4979087.771599714, -8235943.594404688 4979080.45113946, -8235908.3729178 4979060.415450002, -8235867.819227305 4979037.13117875, -8235863.444371316 4979034.632238796, -8235825.55121665 4979013.611769197, -8235806.849542197 4979003.248547338, -8235796.853051924 4978997.63330264, -8235696.442871228 4978942.216008501, -8235688.472395688 4978937.747359756, -8235673.2104935 4978929.177555548)" +907,Amsterdam Avenue,"LINESTRING (-8235956.095583503 4979087.771599714, -8235951.141866164 4979096.944232352, -8235933.686970007 4979128.401723831, -8235909.641959997 4979171.957287016, -8235904.487867573 4979181.438695904)" +908,West 68th Street,"LINESTRING (-8235803.9552354375 4979363.527632054, -8235792.044049921 4979356.98607196, -8235763.16777401 4979341.2275451915, -8235756.343889224 4979337.523119083, -8235751.022817564 4979334.641899748, -8235749.898490706 4979334.024495715, -8235733.523393613 4979325.116241871, -8235682.39435149 4979296.701024428, -8235667.755838451 4979288.307305554)" +909,Amsterdam Avenue,"LINESTRING (-8235803.9552354375 4979363.527632054, -8235799.034913943 4979372.333019859, -8235759.115744545 4979444.364036261, -8235754.306742543 4979453.595804936)" +910,West 70th Street,"LINESTRING (-8235701.942054072 4979547.075304488, -8235690.053132457 4979540.607123479, -8235674.90254976 4979532.169093783, -8235662.746461365 4979525.730323415)" +911,Amsterdam Avenue,"LINESTRING (-8235701.942054072 4979547.075304488, -8235695.151565135 4979558.409331998, -8235682.3609556435 4979581.871251752, -8235669.8597768275 4979605.347928379, -8235658.961598678 4979622.7533405945)" +912,West 74th Street,"LINESTRING (-8235489.31069471 4979933.997925423, -8235477.744599616 4979927.602993073, -8235188.881652958 4979767.90745432, -8235177.104050831 4979761.395024824)" +913,Amsterdam Avenue,"LINESTRING (-8235489.31069471 4979933.997925423, -8235484.390373217 4979943.641785349, -8235451.5733873295 4980005.180420685, -8235439.305979446 4980028.14357508)" +914,West 75th Street,"LINESTRING (-8235439.305979446 4980028.14357508, -8235449.65869209 4980033.759412349, -8235454.200527314 4980036.214504527, -8235539.727292091 4980082.493842605, -8235552.1394153135 4980089.094693641)" +915,Amsterdam Avenue,"LINESTRING (-8235439.305979446 4980028.14357508, -8235434.753012272 4980036.376217206, -8235391.906140265 4980113.92510643, -8235388.644479185 4980119.82031732)" +916,West 76th Street,"LINESTRING (-8235388.644479185 4980119.82031732, -8235375.809341897 4980112.734303664, -8235086.812811848 4979953.065139383, -8235072.018451522 4979944.891371554)" +917,Amsterdam Avenue,"LINESTRING (-8235388.644479185 4980119.82031732, -8235382.978317104 4980130.037711207, -8235347.779094116 4980193.694521113, -8235340.231632639 4980207.410927336, -8235335.110936063 4980216.555208855)" +918,West 79th Street,"LINESTRING (-8235229.769301924 4980409.160465743, -8235215.55380295 4980401.456770592, -8234989.419389352 4980275.184664246, -8234928.093481875 4980241.38594576, -8234914.890990266 4980233.902904723)" +919,Amsterdam Avenue,"LINESTRING (-8235229.769301924 4980409.160465743, -8235222.054861213 4980423.009490251, -8235178.028002605 4980501.046611224, -8235173.853521699 4980508.441645807)" +920,West 79th Street,"LINESTRING (-8235229.769301924 4980409.160465743, -8235244.1295162365 4980417.246411849, -8235392.5629252605 4980499.841059398, -8235405.086367975 4980506.809739085)" +921,West 81st Street,"LINESTRING (-8235121.332985944 4980602.7104501715, -8235136.483568641 4980611.193511046, -8235283.258317252 4980692.437202157, -8235296.995142415 4980699.949998908)" +922,Amsterdam Avenue,"LINESTRING (-8235121.332985944 4980602.7104501715, -8235116.579643687 4980611.296425173, -8235074.489744218 4980687.9824545635, -8235070.137152128 4980695.921610108)" +923,West 81st Street,"LINESTRING (-8235121.332985944 4980602.7104501715, -8235108.731619585 4980595.594682092, -8234890.333910598 4980474.068749245, -8234870.674888524 4980461.939762016, -8234820.224895298 4980434.153411704, -8234815.504948887 4980430.904325112, -8234811.653294506 4980427.243590835, -8234809.337849097 4980424.641382966)" +924,East 45th Street,"LINESTRING (-8234392.2682448905 4975793.163459323, -8234407.619202671 4975801.348448505, -8234601.1592693655 4975909.767138844, -8234626.640300808 4975924.300448605, -8234642.1471058745 4975932.926396977)" +925,2nd Avenue,"LINESTRING (-8234291.245806996 4975975.63009683, -8234295.019537735 4975968.79690451, -8234325.409758721 4975913.822944043, -8234331.254031987 4975903.095636851, -8234336.17435348 4975894.131731654, -8234340.693924807 4975885.946664746)" +926,East 47th Street,"LINESTRING (-8234291.245806996 4975975.63009683, -8234306.630160624 4975985.211269164, -8234344.478787495 4976004.182605908, -8234398.33515714 4976034.248796757, -8234443.096724388 4976063.212942007, -8234525.28390444 4976108.297840216, -8234540.924292896 4976116.879865269)" +927,2nd Avenue,"LINESTRING (-8234239.393188185 4976068.899976044, -8234243.92389146 4976060.7441530675, -8234285.768888049 4975985.490475248, -8234291.245806996 4975975.63009683)" +928,East 48th Street,"LINESTRING (-8234239.393188185 4976068.899976044, -8234228.873496305 4976062.96312405, -8234224.242605487 4976060.420859324, -8234046.59896208 4975962.786638225, -8234004.564722356 4975939.642004304, -8234001.503436359 4975938.304760462, -8233998.842900529 4975938.040250713, -8233989.224896526 4975938.583965206)" +929,2nd Avenue,"LINESTRING (-8234137.981132072 4976253.032349984, -8234142.634286788 4976244.626550696, -8234155.625271362 4976221.187340881, -8234183.95608177 4976170.076832593, -8234188.965458856 4976161.039205842)" +930,East 50th Street,"LINESTRING (-8234137.981132072 4976253.032349984, -8234127.238801211 4976247.007213396, -8234123.899216486 4976245.126195906, -8233890.306397005 4976114.190634005, -8233886.3100272855 4976111.95695614, -8233872.60659797 4976104.3301257)" +931,2nd Avenue,"LINESTRING (-8234037.582083325 4976439.475425172, -8234042.524668717 4976430.114243237, -8234082.321386675 4976354.255200224, -8234087.353027659 4976345.143925109)" +932,East 52nd Street,"LINESTRING (-8234037.582083325 4976439.475425172, -8234021.140194534 4976430.62859366, -8233793.514099762 4976303.5701663345, -8233787.892465477 4976300.440017745, -8233771.973778292 4976290.417670792)" +933,East 54th Street,"LINESTRING (-8233935.60229781 4976621.013588808, -8233920.852465279 4976612.827912918, -8233687.081534615 4976484.606147144, -8233669.927201084 4976475.200834585)" +934,2nd Avenue,"LINESTRING (-8233935.60229781 4976621.013588808, -8233939.799042613 4976613.41575297, -8233951.153630674 4976592.958940008, -8233982.423275637 4976538.642782414, -8233987.287937385 4976530.163258007)" +935,East 55th Street,"LINESTRING (-8233885.018721193 4976716.22952193, -8233899.234220168 4976724.327107445, -8233981.989129623 4976769.738373811, -8233995.514447755 4976777.248153737, -8234004.687173796 4976782.347753178, -8234050.962686119 4976808.066234739, -8234117.498345764 4976844.9686999805, -8234134.329852774 4976854.359672167)" +936,2nd Avenue,"LINESTRING (-8233885.018721193 4976716.22952193, -8233891.408459966 4976704.237465691, -8233921.82094485 4976647.113743007, -8233931.1161223315 4976629.992856963, -8233935.60229781 4976621.013588808)" +937,2nd Avenue,"LINESTRING (-8233834.724575253 4976807.066886763, -8233840.034514965 4976797.587782365, -8233881.100275118 4976723.313071869, -8233885.018721193 4976716.22952193)" +938,East 56th Street,"LINESTRING (-8233834.724575253 4976807.066886763, -8233818.638908833 4976798.175633532, -8233787.269076327 4976780.525417627, -8233728.659364426 4976747.502992742, -8233585.858721636 4976667.982159703, -8233569.004950729 4976658.591366673)" +939,East 58th Street,"LINESTRING (-8233724.184320896 4977004.675241246, -8233708.766571419 4976996.077739707)" +940,2nd Avenue,"LINESTRING (-8233724.184320896 4977004.675241246, -8233728.926531204 4976996.312884948, -8233740.058480283 4976976.692973403, -8233772.61943134 4976919.288424804, -8233780.434059593 4976905.503153324)" +941,East 62nd Street,"LINESTRING (-8233521.5605837535 4977373.008131035, -8233507.378480626 4977365.11576766, -8233420.103999844 4977316.071559407, -8233411.777301933 4977311.236228266)" +942,2nd Avenue,"LINESTRING (-8233521.5605837535 4977373.008131035, -8233526.636752534 4977363.734237296, -8233567.401950061 4977289.249463963, -8233572.277743758 4977280.34307486)" +943,East 65th Street,"LINESTRING (-8233368.897034079 4977646.95204741, -8233354.703799004 4977640.014803152, -8233119.519110805 4977509.766017334, -8233104.335132261 4977501.550202027)" +944,2nd Avenue,"LINESTRING (-8233368.897034079 4977646.95204741, -8233373.049251085 4977639.279925872, -8233400.545165312 4977589.073240947, -8233413.725393022 4977564.998815533, -8233419.035332733 4977555.313211788)" +945,East 66th Street,"LINESTRING (-8233316.899699929 4977739.576488315, -8233332.016886778 4977747.939480908, -8233339.931702574 4977752.290003611, -8233358.822620162 4977762.651898257)" +946,2nd Avenue,"LINESTRING (-8233316.899699929 4977739.576488315, -8233321.719833881 4977730.684386296, -8233324.591876743 4977725.554896415)" +947,2nd Avenue,"LINESTRING (-8233165.371609061 4978015.8382885745, -8233169.746465052 4978007.622047604, -8233201.862138145 4977947.315932298, -8233210.188836056 4977932.147599234, -8233214.97557416 4977923.299415827)" +948,East 69th Street,"LINESTRING (-8233165.371609061 4978015.8382885745, -8233179.408996851 4978023.6576871155, -8233330.035399844 4978107.496143024, -8233398.931032697 4978145.8292531995, -8233413.948032004 4978154.192593625)" +949,East 71st Street,"LINESTRING (-8233064.382567014 4978202.065138754, -8233076.750162442 4978208.81170297, -8233212.994087224 4978284.788038718, -8233252.557034251 4978306.6594556, -8233296.58389286 4978331.000283584, -8233312.79201072 4978340.1134111155)" +950,2nd Avenue,"LINESTRING (-8233064.382567014 4978202.065138754, -8233069.314020458 4978192.908044889, -8233100.127255509 4978136.848591578, -8233111.34826018 4978117.285182163, -8233116.112734387 4978108.348641539)" +951,East 76th Street,"LINESTRING (-8232798.918977319 4978682.30280523, -8232787.6645768015 4978675.8939933535, -8232782.388032937 4978672.924774598, -8232549.374074809 4978541.456904416, -8232533.845005843 4978533.093232385)" +952,2nd Avenue,"LINESTRING (-8232798.918977319 4978682.30280523, -8232803.705715423 4978673.8802161785, -8232843.892051601 4978595.63720989, -8232848.25577564 4978587.729159594)" +953,East 77th Street,"LINESTRING (-8232747.222205795 4978775.4662380805, -8232758.777168941 4978782.080905, -8232980.614650194 4978905.276220253, -8232995.553725856 4978913.684309396)" +954,2nd Avenue,"LINESTRING (-8232747.222205795 4978775.4662380805, -8232751.964416103 4978766.67608764, -8232771.389667247 4978731.677256069, -8232784.436311568 4978708.026289704, -8232794.532989382 4978690.063940837, -8232798.918977319 4978682.30280523)" +955,2nd Avenue,"LINESTRING (-8232640.6337933615 4978968.675154804, -8232648.748984239 4978953.946221184, -8232666.548970817 4978921.342732553, -8232683.035387404 4978891.973226869, -8232692.0856620055 4978875.862664665, -8232696.861268161 4978867.337012938)" +956,East 79th Street,"LINESTRING (-8232640.6337933615 4978968.675154804, -8232653.023652687 4978975.187055693, -8232722.342299603 4979013.49417229, -8232819.067805153 4979067.544799207, -8232872.968702596 4979097.679219316, -8232888.074757496 4979106.102173856)" +957,East 81st Street,"LINESTRING (-8232532.698415087 4979161.549797625, -8232545.934302543 4979168.620421271, -8232767.359901681 4979289.836108455, -8232781.909359127 4979297.803527444)" +958,2nd Avenue,"LINESTRING (-8232532.698415087 4979161.549797625, -8232537.12893082 4979153.2884933185, -8232570.5804378055 4979092.85770585, -8232579.697504101 4979076.379319565, -8232585.063103557 4979066.6775172725)" +959,West 81st Street,"LINESTRING (-8234809.337849097 4980424.641382966, -8234805.998264374 4980421.627527262, -8234800.487949579 4980417.231710123, -8234795.211405716 4980413.335753442, -8234745.240086299 4980385.152596127, -8234646.878184234 4980330.66832963, -8234599.16665048 4980304.102581933, -8234554.093388657 4980278.845341517, -8234540.300903749 4980271.082943151, -8234508.552584974 4980253.264733879, -8234501.071915192 4980249.265932304, -8234494.47066939 4980245.399445575)" +960,Columbus Avenue,"LINESTRING (-8234809.337849097 4980424.641382966, -8234815.460421091 4980414.467785978, -8234854.678277697 4980343.267605465, -8234860.077273001 4980333.535141255)" +961,Columbus Avenue,"LINESTRING (-8235745.4345791275 4978728.458134223, -8235749.286233508 4978722.225682155, -8235778.195905267 4978669.279398351, -8235788.91597223 4978649.406242091, -8235795.6730653215 4978636.882646639)" +962,West 68th Street,"LINESTRING (-8235490.691056395 4979189.244327804, -8235475.573869546 4979180.836001422, -8235250.318879926 4979055.549855903, -8235188.670145924 4979021.255571088, -8235174.866529066 4979013.552970743)" +963,Columbus Avenue,"LINESTRING (-8235490.691056395 4979189.244327804, -8235494.821009503 4979181.87969189, -8235537.089020159 4979106.499067182, -8235542.076133345 4979097.605720617)" +964,West 69th Street,"LINESTRING (-8235439.539750376 4979281.163095173, -8235453.810909095 4979289.159907143, -8235629.395141924 4979387.562390467, -8235642.363862602 4979394.63317775)" +965,Columbus Avenue,"LINESTRING (-8235439.539750376 4979281.163095173, -8235443.447064502 4979274.062990035, -8235476.931967333 4979213.146358075, -8235485.592623717 4979198.402355859, -8235490.691056395 4979189.244327804)" +966,Columbus Avenue,"LINESTRING (-8235388.410708254 4979373.700134205, -8235392.618585006 4979366.08545674, -8235434.40792185 4979290.453509693, -8235439.539750376 4979281.163095173)" +967,West 70th Street,"LINESTRING (-8235388.410708254 4979373.700134205, -8235374.551431651 4979366.026656166, -8235086.05583931 4979206.1639016075, -8235073.042590838 4979198.872752395)" +968,West 72nd Street,"LINESTRING (-8235282.28983768 4979565.862454532, -8235267.039067442 4979557.38030172, -8235055.843729509 4979439.909858, -8235018.22887357 4979418.991417628, -8235007.408619066 4979412.979028086, -8234979.812517298 4979398.087722255, -8234966.532102046 4979390.9581317445)" +969,West 72nd Street,"LINESTRING (-8235282.28983768 4979565.862454532, -8235296.1045864895 4979573.550790051, -8235583.743018751 4979733.404858106, -8235595.153266557 4979740.005473176)" +970,Columbus Avenue,"LINESTRING (-8235282.28983768 4979565.862454532, -8235289.703715769 4979552.514460016, -8235312.53534333 4979511.397459413, -8235332.984733788 4979474.57312066, -8235338.272409601 4979465.062026588)" +971,Columbus Avenue,"LINESTRING (-8235177.104050831 4979761.395024824, -8235181.890788936 4979752.456979673, -8235223.268243662 4979675.146170683, -8235227.643099652 4979666.972635474)" +972,West 74th Street,"LINESTRING (-8235177.104050831 4979761.395024824, -8235159.526703235 4979751.604337636, -8234872.433736478 4979591.602966837, -8234859.253508768 4979584.267428433)" +973,West 75th Street,"LINESTRING (-8235124.783890157 4979853.275075077, -8235137.32959677 4979860.257994244, -8235426.604425545 4980021.087030209, -8235439.305979446 4980028.14357508)" +974,Columbus Avenue,"LINESTRING (-8235124.783890157 4979853.275075077, -8235128.880447419 4979846.659682579, -8235164.235517695 4979783.710771944, -8235172.706930945 4979769.010010533, -8235177.104050831 4979761.395024824)" +975,Columbus Avenue,"LINESTRING (-8235072.018451522 4979944.891371554, -8235075.992557343 4979937.996597895, -8235119.8635686645 4979861.963297367, -8235124.783890157 4979853.275075077)" +976,West 76th Street,"LINESTRING (-8235072.018451522 4979944.891371554, -8235059.33916152 4979937.937793876, -8234770.075464696 4979778.49199911, -8234756.95089673 4979771.229824088)" +977,Columbus Avenue,"LINESTRING (-8234914.890990266 4980233.902904723, -8234922.4050558945 4980220.348177014, -8234966.320595015 4980141.298908798, -8234970.47281202 4980133.815944461)" +978,West 79th Street,"LINESTRING (-8234914.890990266 4980233.902904723, -8234928.093481875 4980241.38594576, -8234989.419389352 4980275.184664246, -8235215.55380295 4980401.456770592, -8235229.769301924 4980409.160465743)" +979,West 85th Street,"LINESTRING (-8234603.207547995 4980800.792579816, -8234615.4081641855 4980807.585046526, -8234902.823957466 4980967.606343538, -8234916.026449073 4980974.957623791)" +980,Columbus Avenue,"LINESTRING (-8234603.207547995 4980800.792579816, -8234607.304105256 4980793.029766502, -8234639.876188263 4980731.324441556, -8234648.3476015115 4980716.357614259, -8234653.345846648 4980707.477503603)" +981,West 86th Street,"LINESTRING (-8234545.532919815 4980900.812864758, -8234530.961198471 4980892.755923074, -8234460.262189867 4980853.147623958, -8234356.11167428 4980795.8232024, -8234286.97113855 4980757.376773262, -8234242.565793673 4980732.280084549, -8234229.752920281 4980724.340899442)" +982,Columbus Avenue,"LINESTRING (-8234545.532919815 4980900.812864758, -8234553.414339764 4980887.12488931, -8234597.764024895 4980810.143249499, -8234603.207547995 4980800.792579816)" +983,East 48th Street,"LINESTRING (-8235205.635236322 4976606.596810556, -8235193.445752079 4976599.792568884, -8235039.245993432 4976513.365885632, -8235027.646502492 4976506.767450667)" +984,5th Avenue,"LINESTRING (-8235205.635236322 4976606.596810556, -8235210.154807647 4976598.264186956, -8235250.953401023 4976523.006368784, -8235255.305993114 4976514.967733546)" +985,West 48th Street,"LINESTRING (-8236513.438878059 4977334.031381741, -8236500.036011368 4977326.550567935, -8236300.50695607 4977215.691163707, -8236214.0451075705 4977167.661787235, -8236209.425348703 4977165.089841362, -8236197.135676919 4977158.241120227)" +986,9th Avenue,"LINESTRING (-8236513.438878059 4977334.031381741, -8236517.4575116765 4977326.741629907, -8236559.013077589 4977251.434108756, -8236564.3230173 4977241.822300643)" +987,West 48th Street,"LINESTRING (-8236829.764343097 4977509.677833232, -8236816.216761068 4977502.005819511, -8236527.943807709 4977342.114782275, -8236513.438878059 4977334.031381741)" +988,10th Avenue,"LINESTRING (-8236829.764343097 4977509.677833232, -8236824.3096880475 4977519.245812813, -8236783.522226622 4977593.423692897, -8236778.646432926 4977602.24218252)" +989,West 48th Street,"LINESTRING (-8237397.204315466 4977825.49959691, -8237373.148173505 4977812.683101687)" +990,12th Avenue,"LINESTRING (-8237397.204315466 4977825.49959691, -8237404.106123895 4977812.418541182, -8237409.126632932 4977803.232417013)" +991,East 44th Street,"LINESTRING (-8235409.572543454 4976239.189236827, -8235395.958169729 4976231.577002494, -8235242.381800233 4976145.653216605, -8235229.969677009 4976138.702343069)" +992,5th Avenue,"LINESTRING (-8235409.572543454 4976239.189236827, -8235414.014191138 4976231.033271696, -8235455.0576873915 4976156.63061046, -8235459.577258718 4976148.474714249)" +993,West 44th Street,"LINESTRING (-8236716.541289011 4976965.979195643, -8236701.858248175 4976957.822623744, -8236470.736721391 4976829.346492384, -8236416.546393272 4976799.233765723, -8236400.3160115145 4976790.210253214)" +994,9th Avenue,"LINESTRING (-8236716.541289011 4976965.979195643, -8236721.049728388 4976957.807927224, -8236762.193412185 4976883.238070429, -8236767.180525373 4976874.199783933)" +995,West 44th Street,"LINESTRING (-8237032.944677693 4977141.810087805, -8237019.352567867 4977134.608660123, -8236732.1705455175 4976974.664849963, -8236716.541289011 4976965.979195643)" +996,10th Avenue,"LINESTRING (-8237032.944677693 4977141.810087805, -8237027.267383662 4977152.112547656, -8236986.557845879 4977225.743853783, -8236982.06053845 4977233.94474019)" +997,West 44th Street,"LINESTRING (-8237617.360872408 4977469.583544534, -8237610.8152863495 4977464.748137406, -8237604.52573512 4977460.412440039, -8237595.865078736 4977455.47415657)" +998,12th Avenue,"LINESTRING (-8237617.360872408 4977469.583544534, -8237630.440912575 4977457.326012581, -8237688.393839483 4977404.592345495, -8237699.147302295 4977393.187331192)" +999,Madison Avenue,"LINESTRING (-8234620.896215081 4977243.350783259, -8234573.3071327675 4977329.916198584, -8234566.03797002 4977343.128882087)" +1000,East 56th Street,"LINESTRING (-8234620.896215081 4977243.350783259, -8234561.607454286 4977211.120426465, -8234546.957809296 4977203.066528103, -8234522.2448823415 4977189.471915458, -8234489.049410187 4977171.218422072, -8234462.967253493 4977156.815528661, -8234450.989276285 4977150.216659078)" +1001,East 56th Street,"LINESTRING (-8234431.853455817 4977139.590871769, -8234419.1073741205 4977132.301265031, -8234272.789035422 4977049.793877638, -8234260.84445406 4977043.062810515)" +1002,Park Avenue,"LINESTRING (-8234431.853455817 4977139.590871769, -8234427.378412287 4977147.6447177995, -8234385.399832309 4977223.377649487, -8234377.429356768 4977237.751247154)" +1003,East 56th Street,"LINESTRING (-8234260.84445406 4977043.062810515, -8234250.358158027 4977037.272332901, -8234097.405177678 4976952.91398736, -8234087.163784525 4976947.329314236)" +1004,Lexington Avenue,"LINESTRING (-8234260.84445406 4977043.062810515, -8234265.297233692 4977034.979657435, -8234306.329597998 4976960.62965943, -8234310.748981784 4976952.575967581)" +1005,East 56th Street,"LINESTRING (-8234087.163784525 4976947.329314236, -8234074.384306981 4976940.333780825)" +1006,3rd Avenue,"LINESTRING (-8234087.163784525 4976947.329314236, -8234083.044963365 4976954.92740977, -8234040.788084661 4977031.819881231, -8234032.862136915 4977046.29607362)" +1007,1st Avenue,"LINESTRING (-8233569.004950729 4976658.591366673, -8233564.351796015 4976667.688238031, -8233550.960061272 4976692.627523309, -8233523.04113298 4976742.947170746, -8233514.848018458 4976757.937302738)" +1008,East 56th Street,"LINESTRING (-8233569.004950729 4976658.591366673, -8233554.566812772 4976650.64079622, -8233533.672144351 4976638.869261089, -8233333.619887448 4976527.723742816, -8233319.270805083 4976519.670407837)" +1009,East 56th Street,"LINESTRING (-8233269.488728801 4976492.027532978, -8233304.899458824 4976511.808125529, -8233319.270805083 4976519.670407837)" +1010,Vanderbilt Avenue,"LINESTRING (-8235130.093829869 4976082.831019146, -8235124.995397191 4976092.1183922505, -8235096.597795091 4976143.816304512, -8235083.684734157 4976167.475758672, -8235079.17629478 4976175.734538148)" +1011,Vanderbilt Avenue,"LINESTRING (-8235130.093829869 4976082.831019146, -8235134.457553907 4976074.719270115, -8235172.0390139995 4976004.887970029, -8235173.196736704 4976002.742487651, -8235178.996482175 4975991.970997631)" +1012,Vanderbilt Avenue,"LINESTRING (-8235079.17629478 4976175.734538148, -8235074.2782371845 4976184.698701709, -8235033.023233898 4976259.939218448, -8235027.846877576 4976269.417801204)" +1013,Vanderbilt Avenue,"LINESTRING (-8235079.17629478 4976175.734538148, -8235083.684734157 4976167.475758672, -8235096.597795091 4976143.816304512, -8235124.995397191 4976092.1183922505, -8235130.093829869 4976082.831019146)" +1014,East 45th Street,"LINESTRING (-8235079.17629478 4976175.734538148, -8235088.571659802 4976181.03955854, -8235166.528699205 4976225.008148676, -8235178.506676416 4976232.179515033)" +1015,Vanderbilt Avenue,"LINESTRING (-8234977.842162311 4976359.560317552, -8234982.127962707 4976351.874511391, -8235023.716924468 4976276.8537190715, -8235027.846877576 4976269.417801204)" +1016,East 47th Street,"LINESTRING (-8234977.842162311 4976359.560317552, -8235066.519268678 4976409.64311839, -8235077.985176229 4976416.123922119)" +1017,West 37th Street,"LINESTRING (-8237393.742279303 4976488.6327993525, -8237408.5589035265 4976499.845711875, -8237521.57045058 4976562.215017181, -8237574.035326591 4976590.916200261)" +1018,10th Avenue,"LINESTRING (-8237393.742279303 4976488.6327993525, -8237387.063109856 4976500.727461767, -8237347.566954521 4976572.237642962, -8237343.22549438 4976580.114669852)" +1019,Madison Avenue,"LINESTRING (-8235178.506676416 4976232.179515033, -8235174.198612122 4976239.953399674, -8235136.416776946 4976308.008219105, -8235132.887949088 4976314.356695447, -8235127.355370396 4976324.320284691)" +1020,East 45th Street,"LINESTRING (-8235178.506676416 4976232.179515033, -8235191.3863415 4976239.674186319, -8235345.307801419 4976324.011677791, -8235359.100286328 4976331.859113394)" +1021,East 45th Street,"LINESTRING (-8234820.146971653 4976031.133429576, -8234830.210253621 4976036.7616644045, -8234933.759643958 4976094.763531774, -8234939.603917223 4976098.040566735, -8234958.338987524 4976108.224364006, -8234999.738706151 4976131.531045325, -8235070.871860767 4976171.017334069, -8235079.17629478 4976175.734538148)" +1022,Lexington Avenue,"LINESTRING (-8234820.146971653 4976031.133429576, -8234824.955973655 4976022.404528711, -8234866.8788938895 4975946.078411281, -8234870.686020475 4975939.142374715)" +1023,East 45th Street,"LINESTRING (-8234642.1471058745 4975932.926396977, -8234657.33108442 4975941.302538118, -8234809.1374740135 4976025.064344478, -8234820.146971653 4976031.133429576)" +1024,3rd Avenue,"LINESTRING (-8234642.1471058745 4975932.926396977, -8234638.061680563 4975940.685348526, -8234596.238947872 4976015.894595936, -8234591.140515194 4976025.181905413)" +1025,East 94th Street,"LINESTRING (-8232824.08831419 4980916.16223921, -8232813.368247224 4980910.104820357, -8232657.610015707 4980823.404749219, -8232645.609774599 4980816.788699435)" +1026,5th Avenue,"LINESTRING (-8232824.08831419 4980916.16223921, -8232828.674677209 4980907.870045418, -8232870.174583375 4980832.9171664305, -8232874.72755055 4980824.698555034)" +1027,Madison Avenue,"LINESTRING (-8232645.609774599 4980816.788699435, -8232640.945487935 4980825.271946302, -8232598.978039907 4980901.121616305, -8232594.280357394 4980909.325589564)" +1028,East 90th Street,"LINESTRING (-8233028.871649452 4980546.534248661, -8233018.240638082 4980541.241558557, -8232862.88315673 4980454.882903652, -8232849.780852663 4980447.487909632)" +1029,5th Avenue,"LINESTRING (-8233028.871649452 4980546.534248661, -8233034.025741875 4980537.095619977, -8233073.911515426 4980462.527833777, -8233077.8076976035 4980454.76528939)" +1030,Madison Avenue,"LINESTRING (-8232849.780852663 4980447.487909632, -8232844.726947781 4980456.588310623, -8232802.770631702 4980532.479222356, -8232797.805782411 4980541.432683427)" +1031,East 90th Street,"LINESTRING (-8232849.780852663 4980447.487909632, -8232838.426264603 4980441.269062135, -8232692.953954034 4980360.777244501, -8232681.27653945 4980354.132104914)" +1032,Park Avenue,"LINESTRING (-8232661.261295006 4980342.885363484, -8232656.029278939 4980352.117981641, -8232614.674088108 4980427.390608249, -8232609.664711023 4980436.564499287)" +1033,9th Avenue,"LINESTRING (-8237285.873692724 4975938.245980518, -8237291.651174297 4975927.621511301, -8237382.933156747 4975766.125123693, -8237388.0649852725 4975756.808671031)" +1034,West 33rd Street,"LINESTRING (-8237285.873692724 4975938.245980518, -8237300.5678655105 4975946.01963129, -8237352.631991353 4975974.204677823, -8237435.6874634335 4976020.376603364, -8237452.1070883265 4976029.3553195065, -8237463.528468082 4976035.615443992, -8237470.79763083 4976039.583130604, -8237475.406257749 4976042.110694766)" +1035,9th Avenue,"LINESTRING (-8237179.541315119 4976134.631749236, -8237184.506164408 4976125.652936345, -8237209.107771873 4976081.03820447, -8237225.560792613 4976049.913818483, -8237232.384677399 4976037.129042769)" +1036,West 35th Street,"LINESTRING (-8237179.541315119 4976134.631749236, -8237191.875514699 4976141.7001822125, -8237248.726378646 4976173.442064854, -8237299.866552716 4976202.5388812, -8237314.983739567 4976210.518477795)" +1037,9th Avenue,"LINESTRING (-8237128.312085455 4976224.978757841, -8237133.855796097 4976215.573695215, -8237159.158716355 4976170.752818021, -8237162.95471099 4976164.022356513, -8237165.01412157 4976160.37791641, -8237174.364958797 4976143.816304512, -8237179.541315119 4976134.631749236)" +1038,West 36th Street,"LINESTRING (-8237128.312085455 4976224.978757841, -8237111.803404971 4976215.441436587, -8237046.291884639 4976178.071098021, -8237023.304409789 4976165.344935919, -8236853.286151501 4976071.2659007395, -8236825.612126091 4976055.953528691, -8236822.383860857 4976054.160718945, -8236810.216640513 4976047.430337753)" +1039,West 39th Street,"LINESTRING (-8236976.3832444195 4976496.304017276, -8236991.533827119 4976504.651249752, -8237046.9598015845 4976535.1892490545, -8237093.636064073 4976560.921775893, -8237142.137966212 4976588.667717435, -8237199.445240073 4976621.425077185, -8237276.311348465 4976665.366257139, -8237292.441542681 4976672.170544482)" +1040,9th Avenue,"LINESTRING (-8236976.3832444195 4976496.304017276, -8236981.192246423 4976487.618788241, -8237011.137189448 4976433.52365226, -8237022.001971748 4976413.9048709255, -8237026.989084936 4976404.896409997)" +1041,West 40th Street,"LINESTRING (-8236927.480592116 4976587.594912088, -8236914.9571494 4976580.61433222, -8236913.120377803 4976579.585615608, -8236883.698636386 4976563.25842789, -8236776.164008279 4976503.549061957, -8236626.628536298 4976420.370981769, -8236610.14211971 4976410.510164445)" +1042,9th Avenue,"LINESTRING (-8236927.480592116 4976587.594912088, -8236932.322989965 4976578.850818095, -8236955.510839897 4976535.409687319, -8236971.830277247 4976504.842295649, -8236976.3832444195 4976496.304017276)" +1043,West 41st Street,"LINESTRING (-8236871.186325621 4976688.46852199, -8236883.687504439 4976701.445199808, -8236968.8691787915 4976749.633942468, -8236993.2815431245 4976760.612014982, -8237001.730692475 4976763.5218675975, -8237018.272768806 4976766.387632383)" +1044,9th Avenue,"LINESTRING (-8236871.186325621 4976688.46852199, -8236879.869245903 4976671.7149657, -8236913.910746188 4976611.652232924, -8236922.482346979 4976596.559453551, -8236927.480592116 4976587.594912088)" +1045,West 43rd Street,"LINESTRING (-8236767.180525373 4976874.199783933, -8236783.466566876 4976883.076409946, -8237012.90716935 4977012.523223614, -8237068.923137117 4977044.062182633, -8237082.604302537 4977051.792623354)" +1046,9th Avenue,"LINESTRING (-8236767.180525373 4976874.199783933, -8236772.4682011865 4976865.029238375, -8236790.435167 4976833.579035343, -8236814.936586923 4976790.7687114, -8236823.652903054 4976775.558085344)" +1047,9th Avenue,"LINESTRING (-8236614.505843751 4977150.907409138, -8236618.446553725 4977143.764761949, -8236660.881543614 4977066.827319309, -8236665.679413668 4977058.126886376)" +1048,West 46th Street,"LINESTRING (-8236614.505843751 4977150.907409138, -8236600.657699095 4977143.603097155, -8236458.357994014 4977064.064343145, -8236423.2812224645 4977044.429598878, -8236420.3757837545 4977042.812967502, -8236314.4218924185 4976983.512174147, -8236310.6481616795 4976981.381173403, -8236298.525469133 4976974.591367237)" +1049,West 47th Street,"LINESTRING (-8236564.3230173 4977241.822300643, -8236580.163780841 4977250.831533351, -8236868.4144703 4977411.073809299, -8236880.5037670005 4977417.80513)" +1050,9th Avenue,"LINESTRING (-8236564.3230173 4977241.822300643, -8236568.2748592235 4977234.650193107, -8236599.622427831 4977178.125939713, -8236610.442682336 4977158.314604332, -8236614.505843751 4977150.907409138)" +1051,West 51st Street,"LINESTRING (-8236360.975703468 4977610.3111074995, -8236376.860994804 4977619.276587516, -8236663.8537740195 4977778.745926633, -8236677.089661473 4977786.109504621)" +1052,9th Avenue,"LINESTRING (-8236360.975703468 4977610.3111074995, -8236365.150184373 4977602.7418971695, -8236390.809327001 4977556.268544052, -8236406.894993421 4977527.12360334, -8236411.447960594 4977518.848983978)" +1053,9th Avenue,"LINESTRING (-8236309.067424912 4977704.478453375, -8236314.600003605 4977694.439968249, -8236356.010854179 4977619.350075092, -8236360.975703468 4977610.3111074995)" +1054,West 52nd Street,"LINESTRING (-8236309.067424912 4977704.478453375, -8236294.94098153 4977696.953262972, -8236212.965308509 4977650.655832376, -8236202.055998412 4977644.571043528, -8236008.694042903 4977536.8532713065, -8236004.920312167 4977534.7515446255, -8235994.100057662 4977528.62273584)" +1055,West 54th Street,"LINESTRING (-8236209.124786077 4977886.819116387, -8236197.113413019 4977880.146264106, -8236194.297029903 4977878.588286037, -8236190.400847726 4977876.442392121, -8236027.796467523 4977787.123650526, -8235938.740874889 4977737.371834167, -8235907.103875605 4977720.278432559, -8235903.307880969 4977718.103178093, -8235891.129528676 4977711.09239504)" +1056,9th Avenue,"LINESTRING (-8236209.124786077 4977886.819116387, -8236213.555301812 4977878.8087546155, -8236241.975167809 4977826.440257772, -8236254.476346626 4977803.4381861, -8236259.196293035 4977794.531328166)" +1057,West 57th Street,"LINESTRING (-8236052.487130581 4978169.361271508, -8236043.336668438 4978164.246249588, -8236037.770693899 4978161.130203066, -8235906.992556116 4978088.153265704, -8235885.930908457 4978076.394696387, -8235879.396454348 4978072.749542774, -8235836.783353272 4978048.967888473, -8235829.903808741 4978045.131669068, -8235751.846581796 4978001.875092463, -8235735.716387581 4977992.938657429)" +1058,9th Avenue,"LINESTRING (-8236052.487130581 4978169.361271508, -8236059.912140618 4978155.7359173335, -8236091.126125837 4978098.559611355, -8236101.812796953 4978079.951662114, -8236106.9334935285 4978071.044552034)" +1059,West 57th Street,"LINESTRING (-8236052.487130581 4978169.361271508, -8236067.73790082 4978177.871615636, -8236354.374457664 4978337.849827033, -8236355.253881641 4978338.334880721, -8236368.93504706 4978345.96345553)" +1060,West 58th Street,"LINESTRING (-8235997.038892218 4978269.5897845905, -8235987.777110583 4978265.121443582, -8235982.856789092 4978262.710892044, -8235979.984746228 4978261.314536243, -8235946.611162888 4978243.147230535, -8235931.293600957 4978235.092481213, -8235918.324880278 4978227.919644341, -8235862.67626683 4978197.5821302505, -8235854.95069417 4978193.363694619, -8235696.075516909 4978104.144942691, -8235679.054766766 4978093.488721199)" +1061,9th Avenue,"LINESTRING (-8235997.038892218 4978269.5897845905, -8236001.992609559 4978260.6090091765, -8236023.644250517 4978221.437638502, -8236044.271752162 4978184.221307277, -8236052.487130581 4978169.361271508)" +1062,5th Avenue,"LINESTRING (-8234027.685780594 4978737.865616574, -8234032.238747767 4978729.53117472, -8234074.562418167 4978653.0516109215, -8234079.427079916 4978644.276269712)" +1063,Madison Avenue,"LINESTRING (-8233849.496671681 4978638.161463749, -8233845.544829758 4978645.290504725, -8233801.707214284 4978724.695143819, -8233794.449183485 4978737.806819782)" +1064,East 71st Street,"LINESTRING (-8233849.496671681 4978638.161463749, -8233862.220489479 4978645.09941696, -8234016.865526089 4978731.883044716, -8234027.685780594 4978737.865616574)" +1065,East 71st Street,"LINESTRING (-8233657.815640484 4978532.564072356, -8233680.7585875355 4978545.146329679)" +1066,Park Avenue,"LINESTRING (-8233657.815640484 4978532.564072356, -8233654.197757033 4978539.222671468, -8233611.751635193 4978617.994390445, -8233603.736631857 4978632.031962573)" +1067,East 71st Street,"LINESTRING (-8233490.535841669 4978439.094282707, -8233502.068540915 4978445.517637962, -8233648.587254698 4978527.331269176, -8233657.815640484 4978532.564072356)" +1068,Lexington Avenue,"LINESTRING (-8233490.535841669 4978439.094282707, -8233495.767857737 4978429.52540205, -8233537.55719458 4978354.0329949055, -8233542.266009041 4978345.404908424)" +1069,East 71st Street,"LINESTRING (-8233312.79201072 4978340.1134111155, -8233327.630898842 4978348.432822063, -8233478.513336662 4978432.347559425, -8233490.535841669 4978439.094282707)" +1070,3rd Avenue,"LINESTRING (-8233312.79201072 4978340.1134111155, -8233309.151863369 4978346.507304058, -8233264.368032225 4978425.218673877, -8233256.820570747 4978438.491634034)" +1071,East 71st Street,"LINESTRING (-8232797.928233852 4978054.024057346, -8232814.036164168 4978062.813566443, -8233048.319164493 4978193.157917319, -8233064.382567014 4978202.065138754)" +1072,1st Avenue,"LINESTRING (-8232797.928233852 4978054.024057346, -8232793.887336336 4978061.329050138, -8232776.031690013 4978095.311301707, -8232764.621442206 4978115.638976697, -8232752.0089439005 4978138.61238699, -8232744.127523951 4978152.943236516)" +1073,West 39th Street,"LINESTRING (-8235669.258651577 4975768.72609077, -8235683.296039366 4975776.617164613, -8235796.797392178 4975840.451337042, -8236012.289662456 4975960.714640193, -8236026.360446092 4975968.9291598005)" +1074,East 88th Street,"LINESTRING (-8233129.448809383 4980362.08569066, -8233119.886465123 4980356.660785818, -8232964.061441912 4980271.3328687595, -8232951.126117081 4980264.187939172)" +1075,5th Avenue,"LINESTRING (-8233129.448809383 4980362.08569066, -8233133.367255459 4980355.23472732, -8233175.935828738 4980279.374596176, -8233180.49992786 4980270.7301070085)" +1076,East 88th Street,"LINESTRING (-8232951.126117081 4980264.187939172, -8232939.2037996175 4980257.292940061, -8232856.493417958 4980211.086280617, -8232794.8335520085 4980176.640923955, -8232783.100477678 4980170.275235407)" +1077,Madison Avenue,"LINESTRING (-8232951.126117081 4980264.187939172, -8232946.439566519 4980272.817721038, -8232905.140035435 4980347.869212009, -8232900.59820021 4980356.116825335)" +1078,East 88th Street,"LINESTRING (-8232762.962781794 4980159.087511088, -8232749.838213828 4980151.8544556685, -8232603.475347334 4980070.306536937, -8232592.243210712 4980064.176136821)" +1079,Park Avenue,"LINESTRING (-8232762.962781794 4980159.087511088, -8232758.231703435 4980167.849512225, -8232755.704750993 4980172.392230676, -8232716.286519303 4980243.194225692, -8232711.555440945 4980251.427049128)" +1080,Lexington Avenue,"LINESTRING (-8232592.243210712 4980064.176136821, -8232596.874101531 4980055.8258617995, -8232615.475588442 4980022.174913879, -8232638.485327189 4979980.467892959, -8232643.42791258 4979971.367935684)" +1081,Madison Avenue,"LINESTRING (-8235440.352382658 4975760.423571167, -8235436.11111006 4975767.888491128, -8235398.106635904 4975834.793825636, -8235394.14366203 4975841.759177808, -8235389.501639265 4975849.9295128435)" +1082,East 42nd Street,"LINESTRING (-8235333.652650733 4975948.238576218, -8235322.7990003815 4975941.493573, -8235301.024907983 4975929.179178263, -8235264.523246951 4975906.72528605, -8235245.053468011 4975895.63061359, -8235236.904881285 4975891.075188811, -8235228.667238966 4975886.475681431, -8235169.601117152 4975853.118296538, -8235158.881050188 4975847.681200545, -8235145.634030784 4975840.539506078, -8235103.032061657 4975817.512720169, -8235062.0219612485 4975795.132558428, -8234988.172611057 4975753.781560564, -8234977.00726613 4975747.53631135)" +1083,East 42nd Street,"LINESTRING (-8235333.652650733 4975948.238576218, -8235348.625122245 4975956.217965122, -8235501.043769039 4976041.464108522, -8235513.800982684 4976047.812411671)" +1084,Madison Avenue,"LINESTRING (-8235333.652650733 4975948.238576218, -8235326.416883831 4975961.537561344, -8235296.605524199 4976016.2913637245, -8235286.2750754515 4976035.292151082, -8235284.60528309 4976039.127581318, -8235280.219295153 4976048.1650953)" +1085,East 43rd Street,"LINESTRING (-8235280.219295153 4976048.1650953, -8235292.9097171035 4976054.763220544, -8235446.397031008 4976141.171151709, -8235459.577258718 4976148.474714249)" +1086,Madison Avenue,"LINESTRING (-8235280.219295153 4976048.1650953, -8235274.987279085 4976057.5993871065, -8235234.544908081 4976130.458290172, -8235229.969677009 4976138.702343069)" +1087,East 44th Street,"LINESTRING (-8235229.969677009 4976138.702343069, -8235220.129034023 4976133.206307031, -8235139.711833875 4976088.2094651535, -8235130.093829869 4976082.831019146)" +1088,Madison Avenue,"LINESTRING (-8235229.969677009 4976138.702343069, -8235225.105015261 4976147.460738439, -8235199.557192124 4976193.50122442, -8235183.382470113 4976223.21530791, -8235178.506676416 4976232.179515033)" +1089,Madison Avenue,"LINESTRING (-8235077.985176229 4976416.123922119, -8235074.133521848 4976423.060297311, -8235032.900782457 4976497.303333465, -8235027.646502492 4976506.767450667)" +1090,East 47th Street,"LINESTRING (-8235077.985176229 4976416.123922119, -8235089.33976429 4976422.516555858, -8235243.584050734 4976508.266426594, -8235255.305993114 4976514.967733546)" +1091,East 48th Street,"LINESTRING (-8235027.646502492 4976506.767450667, -8235015.33456681 4976500.124932665, -8234869.361318533 4976421.282115913, -8234857.4835288655 4976414.8747872785)" +1092,Madison Avenue,"LINESTRING (-8235027.646502492 4976506.767450667, -8235022.848632438 4976515.393913311, -8234980.847788563 4976591.033768005, -8234976.038786559 4976599.689697015)" +1093,Madison Avenue,"LINESTRING (-8234925.343890454 4976691.143215216, -8234920.568284299 4976700.063763298, -8234888.307895866 4976758.304708222, -8234878.188954153 4976776.483948862, -8234874.203716383 4976783.670416293)" +1094,East 50th Street,"LINESTRING (-8234925.343890454 4976691.143215216, -8234913.39930909 4976684.7504057, -8234880.125913293 4976666.233325889, -8234847.008364782 4976647.686889068, -8234768.505859875 4976603.760484617, -8234756.5278826635 4976597.32364435)" +1095,East 52nd Street,"LINESTRING (-8234823.987494085 4976875.640030652, -8234811.720086201 4976868.8356015915, -8234810.172745278 4976867.983211244, -8234666.74871334 4976790.386608427, -8234665.813629617 4976789.857542795, -8234653.991499695 4976783.2148323115)" +1096,Madison Avenue,"LINESTRING (-8234823.987494085 4976875.640030652, -8234818.766609967 4976884.91346104, -8234788.342993133 4976940.025154468, -8234781.340997163 4976952.517181533, -8234778.201787523 4976958.204733265, -8234777.867829049 4976958.807290619, -8234773.726743992 4976966.596450008)" +1097,Madison Avenue,"LINESTRING (-8234722.00770857 4977060.448960623, -8234718.066998595 4977067.94426734, -8234717.577192836 4977068.855461882, -8234676.121814465 4977143.6618843535, -8234671.223756869 4977152.671026532)" +1098,East 54th Street,"LINESTRING (-8234722.00770857 4977060.448960623, -8234709.161439332 4977053.276986245, -8234566.305136798 4976973.665484943, -8234565.336657226 4976973.121712844, -8234552.913402054 4976966.199643626)" +1099,East 55th Street,"LINESTRING (-8234671.223756869 4977152.671026532, -8234836.299429767 4977243.953358201, -8234851.216241534 4977252.198350784)" +1100,Madison Avenue,"LINESTRING (-8234671.223756869 4977152.671026532, -8234666.693053595 4977161.709570673, -8234629.300836639 4977228.286421772, -8234620.896215081 4977243.350783259)" +1101,East 58th Street,"LINESTRING (-8234510.545203859 4977442.599357837, -8234499.034768512 4977436.014992441, -8234395.630093512 4977378.0198585745, -8234353.261895317 4977354.504443712, -8234342.107682341 4977348.184685618)" +1102,Madison Avenue,"LINESTRING (-8234510.545203859 4977442.599357837, -8234506.170347871 4977451.285435942, -8234464.614781957 4977526.094787053, -8234461.074822149 4977533.134832103)" +1103,East 59th Street,"LINESTRING (-8234461.074822149 4977533.134832103, -8234449.3306158725 4977525.918418556, -8234425.28560586 4977511.970620112, -8234304.092076234 4977445.876844947, -8234291.9359878395 4977439.1161104115)" +1104,Madison Avenue,"LINESTRING (-8234461.074822149 4977533.134832103, -8234455.809410237 4977543.026177459, -8234448.707226723 4977556.709466666, -8234428.458211347 4977594.04098691, -8234420.999805464 4977607.107052703, -8234414.721386184 4977618.527014282, -8234408.7880573245 4977628.433143634)" +1105,East 60th Street,"LINESTRING (-8234408.7880573245 4977628.433143634, -8234421.233576396 4977635.532052598, -8234439.823931358 4977646.040798942, -8234532.887025661 4977697.144332188, -8234573.796938527 4977720.410711562, -8234587.311124709 4977728.905966864)" +1106,Madison Avenue,"LINESTRING (-8234408.7880573245 4977628.433143634, -8234404.825083451 4977635.370379666, -8234362.423489409 4977709.872489908, -8234358.037501472 4977717.588759879)" +1107,East 62nd Street,"LINESTRING (-8234307.453924855 4977809.317304698, -8234295.3757601045 4977802.600411987, -8234150.794005462 4977722.96810598, -8234139.305834013 4977716.339458613)" +1108,Madison Avenue,"LINESTRING (-8234307.453924855 4977809.317304698, -8234302.411151923 4977818.400549886, -8234260.9335096525 4977893.168618825, -8234256.51412587 4977901.149596495)" +1109,East 65th Street,"LINESTRING (-8234153.777367815 4978087.256674295, -8234142.734474329 4978081.186311675, -8234141.855050352 4978080.701270756, -8233996.994996982 4978000.096623656, -8233985.384374092 4977993.64416516)" +1110,Madison Avenue,"LINESTRING (-8234153.777367815 4978087.256674295, -8234150.025900975 4978093.826780462, -8234108.080716845 4978169.66993671, -8234103.594541366 4978177.901012348)" +1111,Madison Avenue,"LINESTRING (-8234103.594541366 4978177.901012348, -8234098.596296229 4978186.881711714, -8234057.341292941 4978261.917173984, -8234052.89964526 4978269.957246935)" +1112,East 66th Street,"LINESTRING (-8234103.594541366 4978177.901012348, -8234116.83042882 4978185.132605952, -8234117.910227882 4978185.808730831, -8234270.050575949 4978270.633377686, -8234282.8745812895 4978277.600466846)" +1113,Madison Avenue,"LINESTRING (-8233952.2890894795 4978453.793042376, -8233947.825177899 4978461.847972058, -8233905.412451906 4978538.267243059, -8233901.360422442 4978545.572598028)" +1114,East 69th Street,"LINESTRING (-8233952.2890894795 4978453.793042376, -8233964.022163809 4978460.319298759, -8234054.146423556 4978510.486365618, -8234119.14587423 4978546.660317343, -8234130.288955256 4978552.863259539)" +1115,East 76th Street,"LINESTRING (-8233585.869853585 4979119.405458914, -8233572.711889773 4979112.08497495, -8233428.297114367 4979031.633511694, -8233415.840463346 4979024.695283891)" +1116,Madison Avenue,"LINESTRING (-8233585.869853585 4979119.405458914, -8233580.971795989 4979128.622220625, -8233538.748313132 4979204.017715992, -8233533.605352658 4979213.646155151)" +1117,East 77th Street,"LINESTRING (-8233533.605352658 4979213.646155151, -8233545.605593765 4979220.217019077, -8233700.751568085 4979306.329554964, -8233709.812974635 4979311.37167474)" +1118,Madison Avenue,"LINESTRING (-8233533.605352658 4979213.646155151, -8233529.508795396 4979221.01081502, -8233487.296444487 4979296.848024824, -8233482.8102690065 4979304.962450049)" +1119,Madison Avenue,"LINESTRING (-8233427.172787509 4979406.687338351, -8233419.4360829 4979420.1821358, -8233374.852626837 4979497.961337288, -8233370.923048813 4979504.8116992125)" +1120,East 79th Street,"LINESTRING (-8233427.172787509 4979406.687338351, -8233438.460583876 4979413.008428515, -8233472.446424416 4979431.486615553, -8233497.693684927 4979445.20195121, -8233539.249250841 4979467.987385293, -8233575.060731029 4979487.538800144, -8233594.185419546 4979498.005438316, -8233603.614180417 4979503.385765111)" +1121,East 79th Street,"LINESTRING (-8233427.172787509 4979406.687338351, -8233412.088996506 4979398.440526868, -8233404.3077641 4979394.192172156, -8233380.106906801 4979380.579809295, -8233372.125299313 4979376.125660125, -8233323.289438701 4979349.16560587, -8233307.504334907 4979340.330838742, -8233269.477596851 4979318.927509252, -8233257.020945832 4979311.91557703)" +1122,East 81st Street,"LINESTRING (-8233319.382124575 4979598.071181624, -8233332.8183871135 4979605.583136446, -8233487.084937455 4979691.757873033, -8233497.114823575 4979697.505822638)" +1123,Madison Avenue,"LINESTRING (-8233319.382124575 4979598.071181624, -8233314.038789016 4979607.7000092985, -8233271.54813938 4979684.466361264, -8233267.596297457 4979691.610866692)" +1124,East 83rd Street,"LINESTRING (-8233215.8216022905 4979785.07794388, -8233228.857114661 4979792.472436272, -8233384.5596864335 4979879.0898495605, -8233393.554301291 4979884.264573387)" +1125,Madison Avenue,"LINESTRING (-8233215.8216022905 4979785.07794388, -8233211.146183675 4979793.560294472, -8233168.755721582 4979870.416312937, -8233164.347469746 4979878.737027583)" +1126,East 85th Street,"LINESTRING (-8233112.839941357 4979971.103316697, -8233125.196404836 4979978.174526514, -8233280.008420682 4980064.867092997, -8233290.7173556965 4980070.674067043)" +1127,Madison Avenue,"LINESTRING (-8233112.839941357 4979971.103316697, -8233107.59679334 4979980.747213267, -8233064.605205996 4980057.442991967, -8233056.1003968995 4980072.114785189)" +1128,East 87th Street,"LINESTRING (-8233001.253283785 4980171.201420781, -8233014.611622682 4980178.640309666, -8233170.781736316 4980265.466969392, -8233180.49992786 4980270.7301070085)" +1129,Madison Avenue,"LINESTRING (-8233001.253283785 4980171.201420781, -8232996.711448561 4980179.5958985705, -8232956.024174676 4980255.469956035, -8232951.126117081 4980264.187939172)" +1130,East 91st Street,"LINESTRING (-8232797.805782411 4980541.432683427, -8232810.362620972 4980548.489604342, -8232885.002339551 4980590.301965394, -8232897.82634489 4980597.505941604, -8232962.625420481 4980633.746433161, -8232965.965005204 4980635.598891922, -8232976.29545395 4980641.24448269)" +1131,Madison Avenue,"LINESTRING (-8232797.805782411 4980541.432683427, -8232793.597905659 4980549.06297939, -8232751.953284153 4980624.557654824, -8232747.789935198 4980632.085101398)" +1132,East 92nd Street,"LINESTRING (-8232747.789935198 4980632.085101398, -8232736.301763749 4980625.675009809, -8232591.196807499 4980544.711210634, -8232579.575052659 4980538.242368772)" +1133,Madison Avenue,"LINESTRING (-8232747.789935198 4980632.085101398, -8232743.203572178 4980640.318252731, -8232700.690658644 4980716.636955621, -8232696.338066553 4980724.752560733)" +1134,Madison Avenue,"LINESTRING (-8232696.338066553 4980724.752560733, -8232691.195106078 4980733.809113534, -8232649.717463811 4980809.305217417, -8232645.609774599 4980816.788699435)" +1135,East 93rd Street,"LINESTRING (-8232696.338066553 4980724.752560733, -8232708.650002235 4980731.177419565, -8232864.163330874 4980818.729406908, -8232874.72755055 4980824.698555034)" +1136,5th Avenue,"LINESTRING (-8235002.8667838415 4976976.413738991, -8235007.7648414355 4976967.169614812, -8235049.108900316 4976892.364543816, -8235053.183193679 4976884.76649694)" +1137,East 52nd Street,"LINESTRING (-8235002.8667838415 4976976.413738991, -8234988.684680714 4976969.168343623, -8234836.188110277 4976882.5914285155, -8234834.952463928 4976881.871304617, -8234823.987494085 4976875.640030652)" +1138,10th Avenue,"LINESTRING (-8236624.29082699 4977879.587743638, -8236620.494832354 4977886.7456268, -8236597.329246321 4977930.516122956, -8236579.673975079 4977962.528383007, -8236576.467973745 4977968.290013038)" +1139,West 52nd Street,"LINESTRING (-8236624.29082699 4977879.587743638, -8236612.958502828 4977873.238250028, -8236324.752341164 4977712.694439361, -8236309.067424912 4977704.478453375)" +1140,West 52nd Street,"LINESTRING (-8237192.810598421 4978194.2896925295, -8237169.878783317 4978181.604998647)" +1141,12th Avenue,"LINESTRING (-8237192.810598421 4978194.2896925295, -8237195.716037131 4978188.954181971, -8237199.634483207 4978182.016552767, -8237244.418314353 4978101.308181902)" +1142,5th Avenue,"LINESTRING (-8233709.812974635 4979311.37167474, -8233713.430858084 4979304.8301495835, -8233742.86373145 4979251.616107744, -8233756.990174832 4979226.067590681, -8233761.95502412 4979217.100635635)" +1143,East 77th Street,"LINESTRING (-8233343.816752803 4979108.086640643, -8233363.709545809 4979119.287860734)" +1144,Park Avenue,"LINESTRING (-8233343.816752803 4979108.086640643, -8233339.174730037 4979116.509604159, -8233297.095962518 4979192.61060036, -8233293.099592798 4979199.578347242)" +1145,East 77th Street,"LINESTRING (-8233173.308688755 4979013.009085069, -8233185.275534016 4979019.623912874, -8233331.961227033 4979101.368854704, -8233343.816752803 4979108.086640643)" +1146,Lexington Avenue,"LINESTRING (-8233173.308688755 4979013.009085069, -8233178.173350503 4979003.880630058, -8233201.060637811 4978962.324953155, -8233221.053618357 4978926.414052536, -8233225.228099261 4978918.932019049)" +1147,East 77th Street,"LINESTRING (-8232995.553725856 4978913.684309396, -8233010.336954233 4978922.004208922, -8233162.221267472 4979006.908747844, -8233173.308688755 4979013.009085069)" +1148,3rd Avenue,"LINESTRING (-8232995.553725856 4978913.684309396, -8232991.501696391 4978920.989945174, -8232948.766143878 4978998.206586637, -8232944.836565851 4979005.306491229)" +1149,East 40th Street,"LINESTRING (-8235618.91997784 4975860.3481694115, -8235605.238812421 4975852.692145662, -8235450.638303608 4975766.183902603, -8235440.352382658 4975760.423571167)" +1150,5th Avenue,"LINESTRING (-8235618.91997784 4975860.3481694115, -8235624.296709245 4975850.53200185, -8235663.7594687315 4975778.689123605, -8235669.258651577 4975768.72609077)" +1151,West 40th Street,"LINESTRING (-8237242.180792588 4976762.831144928, -8237227.375300313 4976754.424907003, -8237210.220966781 4976744.666625894, -8237064.737524263 4976662.809139579)" +1152,10th Avenue,"LINESTRING (-8237242.180792588 4976762.831144928, -8237237.31613084 4976771.648884793, -8237196.896023734 4976844.88052188, -8237190.417229369 4976856.62291251)" +1153,,"LINESTRING (-8237372.714027492 4976836.312553645, -8237379.560176176 4976829.037869531, -8237384.213330892 4976824.966988057, -8237389.445346959 4976821.204730876, -8237395.656974545 4976817.413082527, -8237401.15615739 4976814.797139949, -8237408.347396494 4976812.710264911, -8237417.186164064 4976811.446383064, -8237426.102855276 4976811.946057264, -8237433.8952196315 4976813.004190947, -8237440.808160012 4976814.591391686, -8237475.896063508 4976826.862813516)" +1154,West 40th Street,"LINESTRING (-8237372.714027492 4976836.312553645, -8237361.392835278 4976829.684507899, -8237342.924931756 4976818.662268836, -8237330.490544636 4976811.755005361, -8237279.261314971 4976783.361794885, -8237257.487222573 4976771.237390087, -8237242.180792588 4976762.831144928)" +1155,West 33rd Street,"LINESTRING (-8237601.620296411 4976112.192080101, -8237616.49258038 4976120.494898627, -8237736.6731026415 4976187.035263726, -8237755.808923108 4976197.5865381565, -8237761.141126717 4976200.540309225)" +1156,10th Avenue,"LINESTRING (-8237601.620296411 4976112.192080101, -8237596.633183221 4976121.22966167, -8237571.653089489 4976166.46178089, -8237554.676867142 4976197.998008701, -8237547.530155835 4976211.0034258645)" +1157,East 42nd Street,"LINESTRING (-8234977.00726613 4975747.53631135, -8234988.172611057 4975753.781560564, -8235062.0219612485 4975795.132558428, -8235103.032061657 4975817.512720169, -8235145.634030784 4975840.539506078, -8235158.881050188 4975847.681200545, -8235169.601117152 4975853.118296538, -8235228.667238966 4975886.475681431, -8235236.904881285 4975891.075188811, -8235245.053468011 4975895.63061359, -8235264.523246951 4975906.72528605, -8235301.024907983 4975929.179178263, -8235322.7990003815 4975941.493573, -8235333.652650733 4975948.238576218)" +1158,Lexington Avenue,"LINESTRING (-8234920.935638617 4975848.107351202, -8234926.0340712955 4975838.908379062, -8234968.758491862 4975762.377968952, -8234977.00726613 4975747.53631135)" +1159,East 44th Street,"LINESTRING (-8234870.686020475 4975939.142374715, -8234859.72105063 4975933.043956802, -8234708.081640271 4975848.651060689, -8234693.565578671 4975840.598285434)" +1160,Lexington Avenue,"LINESTRING (-8234870.686020475 4975939.142374715, -8234875.350307138 4975930.707455525, -8234915.681358652 4975857.600229296, -8234920.935638617 4975848.107351202)" +1161,Lexington Avenue,"LINESTRING (-8234718.456616815 4976214.162936603, -8234722.297139247 4976207.344272844, -8234764.554017952 4976131.531045325, -8234769.184908767 4976123.22821742)" +1162,East 47th Street,"LINESTRING (-8234718.456616815 4976214.162936603, -8234729.889128518 4976220.731783127, -8234763.184788214 4976239.835836156, -8234875.595210018 4976304.02572795, -8234889.042604504 4976311.682105375)" +1163,East 48th Street,"LINESTRING (-8234666.937956474 4976305.142588775, -8234656.741091117 4976299.646459106, -8234583.292491092 4976260.071477679, -8234505.413375333 4976216.92567241, -8234490.140341196 4976208.431731831)" +1164,Lexington Avenue,"LINESTRING (-8234666.937956474 4976305.142588775, -8234670.722819162 4976298.470816798, -8234713.035357612 4976223.700256609, -8234718.456616815 4976214.162936603)" +1165,East 50th Street,"LINESTRING (-8234565.6706157 4976491.2486545965, -8234554.761305602 4976485.193979482, -8234533.154192438 4976473.275685786, -8234439.890723052 4976421.781770157, -8234403.066235498 4976401.295967089, -8234388.17168763 4976393.022301268)" +1166,Lexington Avenue,"LINESTRING (-8234565.6706157 4976491.2486545965, -8234570.156791179 4976483.136566461, -8234611.801412685 4976407.732678203, -8234616.654942483 4976398.959353829)" +1167,Lexington Avenue,"LINESTRING (-8234463.379135611 4976676.329538865, -8234466.629664741 4976670.686239496, -8234468.611151678 4976667.247355541, -8234510.790106739 4976591.048463972, -8234515.053643235 4976583.333083785)" +1168,East 52nd Street,"LINESTRING (-8234463.379135611 4976676.329538865, -8234452.146998988 4976670.950769081, -8234450.054192562 4976669.95143513, -8234370.88377071 4976625.539961904, -8234300.229289903 4976586.478018975, -8234285.468325424 4976579.071257343)" +1169,East 54th Street,"LINESTRING (-8234362.067267039 4976859.297651773, -8234350.80173457 4976853.09578493, -8234198.371955829 4976769.165220592, -8234184.768714053 4976761.670143107)" +1170,Lexington Avenue,"LINESTRING (-8234362.067267039 4976859.297651773, -8234367.076644124 4976850.215298352, -8234407.240716403 4976777.48329371, -8234413.140649415 4976767.048962836)" +1171,East 58th Street,"LINESTRING (-8234151.139095883 4977242.571844973, -8234139.506209095 4977236.399128681, -8234101.423811295 4977215.588285353, -8234053.378319069 4977189.662974749, -8233987.22114569 4977152.362393465, -8233972.961118919 4977144.044001144)" +1172,Lexington Avenue,"LINESTRING (-8234151.139095883 4977242.571844973, -8234156.6271467805 4977232.798379311, -8234198.2940321835 4977157.035980952, -8234206.19771603 4977142.647805247)" +1173,East 59th Street,"LINESTRING (-8234100.978533332 4977333.70804586, -8234087.631326387 4977327.0355714075, -8234070.321145568 4977317.364900664, -8234004.7984932875 4977280.886864061, -8233936.025311874 4977242.792299198, -8233923.023195351 4977235.443827699)" +1174,Lexington Avenue,"LINESTRING (-8234100.978533332 4977333.70804586, -8234105.308861524 4977324.93388987, -8234129.398399331 4977281.621714381, -8234146.686316253 4977250.713957667, -8234151.139095883 4977242.571844973)" +1175,East 60th Street,"LINESTRING (-8234048.825351896 4977428.24015598, -8234059.857113433 4977434.251323892, -8234207.121667804 4977514.189920744, -8234220.246235768 4977521.553299305)" +1176,Lexington Avenue,"LINESTRING (-8234048.825351896 4977428.24015598, -8234054.780944654 4977417.908010485, -8234075.3639185 4977381.503084214, -8234096.436698107 4977342.893728497, -8234100.978533332 4977333.70804586)" +1177,East 62nd Street,"LINESTRING (-8233948.370643403 4977610.267014995, -8233937.350013817 4977604.094066353, -8233785.955506337 4977519.216418082, -8233769.981159409 4977510.265727252)" +1178,Lexington Avenue,"LINESTRING (-8233948.370643403 4977610.267014995, -8233953.068325915 4977601.771862871, -8233994.802003014 4977526.359339801, -8233999.18799095 4977518.0406289995)" +1179,East 65th Street,"LINESTRING (-8233795.417663053 4977887.598106047, -8233784.34137372 4977881.6307528755, -8233632.423664634 4977795.663057189, -8233617.373269478 4977786.109504621)" +1180,Lexington Avenue,"LINESTRING (-8233795.417663053 4977887.598106047, -8233800.705338866 4977877.60352644, -8233841.826758766 4977802.512225242, -8233846.4353856845 4977794.105092594)" +1181,East 66th Street,"LINESTRING (-8233744.822954487 4977978.064214612, -8233756.27773009 4977984.604851202, -8233902.562672942 4978066.0030725375, -8233915.5647894675 4978073.205186901)" +1182,Lexington Avenue,"LINESTRING (-8233744.822954487 4977978.064214612, -8233749.6876162365 4977969.377668069, -8233791.287709946 4977894.814786797, -8233795.417663053 4977887.598106047)" +1183,East 69th Street,"LINESTRING (-8233592.649210574 4978253.641932137, -8233602.823812032 4978259.3302414995, -8233698.213483692 4978312.391891512, -8233750.299873436 4978341.362792166, -8233763.468969195 4978348.712095697)" +1184,Lexington Avenue,"LINESTRING (-8233592.649210574 4978253.641932137, -8233596.589920548 4978246.2045093905, -8233615.469706187 4978212.177637623, -8233639.180757726 4978169.405366537, -8233643.332974733 4978161.821024614)" +1185,East 76th Street,"LINESTRING (-8233225.228099261 4978918.932019049, -8233062.568059314 4978828.486594211, -8233046.29314976 4978819.4318082705)" +1186,Lexington Avenue,"LINESTRING (-8233225.228099261 4978918.932019049, -8233230.070497111 4978909.84775034, -8233272.282848021 4978834.131140346, -8233277.136377819 4978825.429133085)" +1187,Lexington Avenue,"LINESTRING (-8233066.620088778 4979205.781704136, -8233074.167550256 4979192.228403418, -8233098.802553568 4979147.59966328, -8233117.559887766 4979113.216856648, -8233122.435681462 4979104.749796722)" +1188,East 79th Street,"LINESTRING (-8233066.620088778 4979205.781704136, -8233054.38607674 4979199.019751318, -8233040.604723781 4979191.375810293, -8232995.909948228 4979166.4154445315, -8232956.424924843 4979144.380404336, -8232904.394194845 4979115.245424181, -8232888.074757496 4979106.102173856)" +1189,East 79th Street,"LINESTRING (-8233066.620088778 4979205.781704136, -8233078.854100819 4979212.4995618975, -8233101.374033805 4979224.832796382, -8233131.062941999 4979241.326133109, -8233183.082540047 4979270.667289402, -8233224.3041474875 4979293.555216511, -8233237.272868166 4979300.949336731)" +1190,East 81st Street,"LINESTRING (-8232960.109599988 4979398.91093304, -8232972.154368892 4979405.673024264, -8233117.626679461 4979487.185992311, -8233130.395025055 4979494.345053746)" +1191,Lexington Avenue,"LINESTRING (-8232960.109599988 4979398.91093304, -8232964.940865889 4979390.076120909, -8233006.440772056 4979314.429288002, -8233007.119820951 4979313.194482531, -8233011.349961601 4979305.462251823)" +1192,East 83rd Street,"LINESTRING (-8232856.905300073 4979586.075586687, -8232867.7923462745 4979592.058681829, -8233014.789733866 4979673.499702609, -8233027.368836325 4979680.467792607)" +1193,Lexington Avenue,"LINESTRING (-8232856.905300073 4979586.075586687, -8232862.037128599 4979576.681987704, -8232880.516164071 4979542.532876923, -8232903.592694512 4979500.886705847, -8232908.368300667 4979492.242905799)" +1194,East 85th Street,"LINESTRING (-8232753.56741677 4979772.141270859, -8232765.200303559 4979778.712510581, -8232911.95278827 4979859.126025955, -8232924.687738018 4979866.064846616)" +1195,Lexington Avenue,"LINESTRING (-8232753.56741677 4979772.141270859, -8232758.276231232 4979763.776544813, -8232800.73348502 4979687.538791971, -8232805.375507785 4979679.203539622)" +1196,East 87th Street,"LINESTRING (-8232643.42791258 4979971.367935684, -8232654.582125557 4979977.6011849865, -8232801.011783748 4980059.427652086, -8232813.757865443 4980066.704742638)" +1197,Lexington Avenue,"LINESTRING (-8232643.42791258 4979971.367935684, -8232648.025407549 4979963.252956705, -8232667.261415558 4979928.55855741, -8232690.627376676 4979886.719627978, -8232697.863143578 4979873.2388867205)" +1198,65th Street Transverse,"LINESTRING (-8234282.8745812895 4978277.600466846, -8234294.295961043 4978283.009518396, -8234304.971500211 4978288.095205466, -8234317.016269114 4978292.754637851, -8234328.894058783 4978296.120601432, -8234342.252397677 4978298.82513196, -8234357.313924782 4978300.912324512, -8234369.392089535 4978301.764839908, -8234380.323663529 4978301.573758864, -8234391.110522187 4978301.191596787, -8234426.899738477 4978299.01621295, -8234463.134232731 4978296.7085427875, -8234473.208646648 4978296.561557446, -8234482.3257129425 4978296.443969173, -8234492.188619828 4978297.076006153, -8234502.463408828 4978298.340080235, -8234512.548954693 4978299.986316494, -8234523.324681403 4978301.9412224125, -8234533.02060905 4978303.793238906, -8234542.905779832 4978306.042116549, -8234565.42571282 4978310.481079168)" +1199,5th Avenue,"LINESTRING (-8234282.8745812895 4978277.600466846, -8234287.883958375 4978268.340412721, -8234328.56010031 4978195.186293764, -8234333.803248326 4978185.794032465)" +1200,East 66th Street,"LINESTRING (-8233915.5647894675 4978073.205186901, -8233935.6245617075 4978084.25823805)" +1201,Park Avenue,"LINESTRING (-8233915.5647894675 4978073.205186901, -8233910.867106956 4978081.347991985, -8233869.779082904 4978156.691308322, -8233864.769705818 4978165.363323114)" +1202,East 66th Street,"LINESTRING (-8233566.422338542 4977878.588286037, -8233582.574796657 4977887.99494986, -8233732.700261941 4977971.229621505, -8233744.822954487 4977978.064214612)" +1203,3rd Avenue,"LINESTRING (-8233566.422338542 4977878.588286037, -8233561.969558911 4977886.436970539, -8233560.889759851 4977888.318304091, -8233519.91305529 4977962.146234199, -8233515.738574384 4977969.656930865)" +1204,East 66th Street,"LINESTRING (-8233052.549305143 4977592.703516596, -8233068.8464785945 4977601.889442782, -8233207.673015564 4977679.095656604, -8233275.5556410495 4977716.736295469, -8233303.240798411 4977732.139456981, -8233316.899699929 4977739.576488315)" +1205,1st Avenue,"LINESTRING (-8233052.549305143 4977592.703516596, -8233047.929546275 4977600.787131183, -8233013.008622015 4977661.6937078135, -8233005.216257658 4977675.538836848, -8233000.318200062 4977684.107541187)" +1206,5th Avenue,"LINESTRING (-8233393.554301291 4979884.264573387, -8233397.7844419405 4979876.473086853, -8233440.597918099 4979799.264201611, -8233445.395788153 4979790.7965468485)" +1207,East 83rd Street,"LINESTRING (-8233027.368836325 4979680.467792607, -8233047.439740516 4979691.669669228)" +1208,Park Avenue,"LINESTRING (-8233027.368836325 4979680.467792607, -8233022.426250935 4979689.449873758, -8232980.358615363 4979765.555334814, -8232975.81678014 4979773.773054808)" +1209,East 83rd Street,"LINESTRING (-8232678.192989554 4979485.466054307, -8232693.933565552 4979494.330353409, -8232844.838267271 4979579.239868221, -8232856.905300073 4979586.075586687)" +1210,3rd Avenue,"LINESTRING (-8232678.192989554 4979485.466054307, -8232673.539834839 4979493.90404365, -8232630.97126156 4979570.90470831, -8232626.507349979 4979578.975259861)" +1211,East 59th Street,"LINESTRING (-8234272.009798986 4977427.6963585755, -8234259.486356272 4977420.685783947, -8234239.070361662 4977409.6628780365, -8234112.555760375 4977339.498699188, -8234100.978533332 4977333.70804586)" +1212,Park Avenue,"LINESTRING (-8234272.009798986 4977427.6963585755, -8234266.276845212 4977437.7198723415, -8234225.745418614 4977511.720765105, -8234220.246235768 4977521.553299305)" +1213,East 59th Street,"LINESTRING (-8233407.168675014 4976950.5184561275, -8233422.519632795 4976960.203460242, -8233460.0343011925 4976980.9255802, -8233463.1401149845 4976982.645077237, -8233501.9906172715 4977003.587693625, -8233512.877663471 4977009.451634261)" +1214,East 59th Street,"LINESTRING (-8233407.168675014 4976950.5184561275, -8233393.843731966 4976942.126753196, -8233291.552251876 4976885.075121553, -8233171.761347834 4976818.383038942, -8233158.681307665 4976810.976101488)" +1215,1st Avenue,"LINESTRING (-8233407.168675014 4976950.5184561275, -8233401.680624118 4976960.203460242, -8233362.85238573 4977031.672914921, -8233356.67415399 4977042.901147388)" +1216,Sutton Place,"LINESTRING (-8233158.681307665 4976810.976101488, -8233163.946719579 4976801.408815589, -8233205.201722868 4976726.502140634, -8233209.799217838 4976718.1400224455)" +1217,East 59th Street,"LINESTRING (-8233158.681307665 4976810.976101488, -8233144.688447673 4976803.304636476, -8233081.8263312215 4976768.312838941)" +1218,East 59th Street,"LINESTRING (-8233158.681307665 4976810.976101488, -8233171.761347834 4976818.383038942, -8233291.552251876 4976885.075121553, -8233393.843731966 4976942.126753196, -8233407.168675014 4976950.5184561275)" +1219,York Avenue,"LINESTRING (-8233158.681307665 4976810.976101488, -8233154.117208542 4976819.23542496, -8233112.851073306 4976893.907668178, -8233107.808300372 4976903.048847969)" +1220,East 55th Street,"LINESTRING (-8234482.303449045 4977048.456481837, -8234501.327950021 4977059.082170018)" +1221,Park Avenue,"LINESTRING (-8234482.303449045 4977048.456481837, -8234478.14010009 4977055.981172688, -8234436.684721717 4977130.905070811, -8234431.853455817 4977139.590871769)" +1222,East 55th Street,"LINESTRING (-8234134.329852774 4976854.359672167, -8234148.044414041 4976862.031177271, -8234240.806945718 4976913.498020554, -8234248.243087702 4976917.657117675, -8234299.839671684 4976946.476917039, -8234310.748981784 4976952.575967581)" +1223,3rd Avenue,"LINESTRING (-8234134.329852774 4976854.359672167, -8234131.513469656 4976862.677817824, -8234117.086463651 4976894.407346594, -8234092.42919644 4976937.600233417, -8234087.163784525 4976947.329314236)" +1224,3rd Avenue,"LINESTRING (-8234134.329852774 4976854.359672167, -8234128.429919763 4976860.9730382785, -8234107.056577531 4976887.588208049, -8234080.09499686 4976931.060297829, -8234074.384306981 4976940.333780825)" +1225,East 55th Street,"LINESTRING (-8233618.842686758 4976568.034605091, -8233635.039672666 4976577.087304288, -8233868.109290541 4976706.868074806, -8233885.018721193 4976716.22952193)" +1226,1st Avenue,"LINESTRING (-8233618.842686758 4976568.034605091, -8233614.668205854 4976575.926324538, -8233591.769786597 4976618.10377864, -8233574.081119509 4976649.30345506, -8233569.004950729 4976658.591366673)" +1227,East 55th Street,"LINESTRING (-8233324.591876743 4976402.692057038, -8233355.694542471 4976420.165241811, -8233369.854381699 4976428.13032043)" +1228,East 92nd Street,"LINESTRING (-8232926.324134531 4980731.515570148, -8232915.848970448 4980725.664096512, -8232760.5360168945 4980639.20089607, -8232747.789935198 4980632.085101398)" +1229,5th Avenue,"LINESTRING (-8232926.324134531 4980731.515570148, -8232930.487483488 4980723.988046921, -8232972.388139822 4980648.301475742, -8232976.29545395 4980641.24448269)" +1230,East 48th Street,"LINESTRING (-8234837.969222129 4976403.808929143, -8234825.490307211 4976396.710915182, -8234806.220903355 4976385.7332515735, -8234760.668967723 4976358.8843190605, -8234678.971593429 4976312.034798529, -8234666.937956474 4976305.142588775)" +1231,Park Avenue,"LINESTRING (-8234837.969222129 4976403.808929143, -8234833.650025887 4976411.6711245375, -8234791.927480737 4976487.56000499, -8234787.641680341 4976495.363484486)" +1232,East 48th Street,"LINESTRING (-8234490.140341196 4976208.431731831, -8234474.288445707 4976199.614500287, -8234420.5767914 4976169.738839898, -8234255.000180795 4976077.584832863, -8234239.393188185 4976068.899976044)" +1233,3rd Avenue,"LINESTRING (-8234490.140341196 4976208.431731831, -8234484.908325129 4976217.807396769, -8234443.5531343 4976292.137046297, -8234438.977903227 4976300.440017745)" +1234,86th Street Transverse,"LINESTRING (-8233290.7173556965 4980070.674067043, -8233304.5766323 4980078.509812179, -8233317.946103143 4980085.684008361, -8233328.677302056 4980091.255775015, -8233339.775855289 4980096.886349826, -8233352.55533283 4980102.678641659, -8233365.590845203 4980108.206314229, -8233382.288768821 4980114.616066125, -8233409.673363557 4980124.892259712, -8233423.744147194 4980130.508152623, -8233435.733256352 4980136.006438338, -8233446.6536984 4980141.431220597, -8233456.293966301 4980146.679590039, -8233464.531608621 4980151.075285384, -8233492.873550975 4980169.040321711)" +1235,5th Avenue,"LINESTRING (-8233290.7173556965 4980070.674067043, -8233295.214663123 4980062.926535351, -8233335.400999299 4979989.994190113, -8233341.245272567 4979979.776942754)" +1236,10th Avenue,"LINESTRING (-8236576.467973745 4977968.290013038, -8236570.445589294 4977979.137172674, -8236529.01247482 4978054.200435378, -8236524.938181457 4978061.593617383)" +1237,West 53rd Street,"LINESTRING (-8236576.467973745 4977968.290013038, -8236590.282722553 4977979.063682392, -8236677.156453168 4978024.142725199, -8236704.819346631 4978039.781541837, -8236877.620592189 4978138.274326178, -8236889.531777704 4978145.256019233)" +1238,3rd Avenue,"LINESTRING (-8234743.035960381 4975750.166662885, -8234739.139778203 4975757.308291295, -8234698.519296012 4975831.2376772845, -8234693.565578671 4975840.598285434)" +1239,East 43rd Street,"LINESTRING (-8234743.035960381 4975750.166662885, -8234757.552021981 4975758.160584746, -8234849.546449171 4975808.813399733, -8234909.380675474 4975841.715093284, -8234920.935638617 4975848.107351202)" +1240,3rd Avenue,"LINESTRING (-8234693.565578671 4975840.598285434, -8234688.500541841 4975849.033126832, -8234647.423649738 4975923.639175193, -8234642.1471058745 4975932.926396977)" +1241,3rd Avenue,"LINESTRING (-8234540.924292896 4976116.879865269, -8234536.2934020795 4976125.197383047, -8234494.826891759 4976199.996580156, -8234490.140341196 4976208.431731831)" +1242,East 47th Street,"LINESTRING (-8234540.924292896 4976116.879865269, -8234556.7873203335 4976125.417812059, -8234707.525042817 4976208.181910161, -8234718.456616815 4976214.162936603)" +1243,East 50th Street,"LINESTRING (-8234388.17168763 4976393.022301268, -8234372.542431123 4976384.572294564, -8234341.706932174 4976367.510651127, -8234161.235773699 4976266.067231365, -8234154.9350905195 4976262.525621513, -8234137.981132072 4976253.032349984)" +1244,3rd Avenue,"LINESTRING (-8234388.17168763 4976393.022301268, -8234383.084386902 4976402.177708087, -8234341.729196072 4976476.596935097, -8234337.354340083 4976484.459189068)" +1245,3rd Avenue,"LINESTRING (-8234285.468325424 4976579.071257343, -8234281.828178076 4976585.655045181, -8234240.328271908 4976660.119758039, -8234235.753040835 4976668.511218734)" +1246,East 52nd Street,"LINESTRING (-8234285.468325424 4976579.071257343, -8234269.649825782 4976571.091359726, -8234218.620971202 4976542.463714361, -8234208.991835249 4976534.910027262, -8234051.151929255 4976447.029038484, -8234037.582083325 4976439.475425172)" +1247,East 54th Street,"LINESTRING (-8234184.768714053 4976761.670143107, -8234169.4622840695 4976752.8671084605, -8234108.403543368 4976718.125326285, -8234046.743677418 4976683.471844301, -8234033.262887082 4976675.903352078, -8233950.886463896 4976629.757720539, -8233935.60229781 4976621.013588808)" +1248,3rd Avenue,"LINESTRING (-8234184.768714053 4976761.670143107, -8234180.349330267 4976769.738373811, -8234140.363369175 4976843.48436874, -8234134.329852774 4976854.359672167)" +1249,East 58th Street,"LINESTRING (-8233972.961118919 4977144.044001144, -8233957.988647408 4977135.44637695, -8233738.856229783 4977012.875942072, -8233724.184320896 4977004.675241246)" +1250,3rd Avenue,"LINESTRING (-8233972.961118919 4977144.044001144, -8233969.476818857 4977150.672260175, -8233927.464843034 4977226.71385074, -8233923.023195351 4977235.443827699)" +1251,East 62nd Street,"LINESTRING (-8233769.981159409 4977510.265727252, -8233754.541146034 4977501.74126742, -8233713.052371817 4977478.813446851, -8233534.451380787 4977380.136248688, -8233521.5605837535 4977373.008131035)" +1252,3rd Avenue,"LINESTRING (-8233769.981159409 4977510.265727252, -8233765.461588081 4977518.39336571, -8233723.4273483595 4977594.099776818, -8233718.952304829 4977602.168695074)" +1253,East 65th Street,"LINESTRING (-8233617.373269478 4977786.109504621, -8233603.836819398 4977777.085080467, -8233551.561186523 4977747.674922157, -8233534.518172482 4977738.10671883, -8233473.2145289015 4977703.84645474, -8233429.310121733 4977679.757048851, -8233383.268380342 4977654.080364967, -8233368.897034079 4977646.95204741)" +1254,3rd Avenue,"LINESTRING (-8233617.373269478 4977786.109504621, -8233612.408420189 4977794.766492628, -8233574.749036455 4977863.21428935, -8233573.724897139 4977864.933941697)" +1255,3rd Avenue,"LINESTRING (-8233413.948032004 4978154.192593625, -8233408.860731273 4978163.393746196, -8233369.141936959 4978238.737695411, -8233364.878400463 4978246.616066233)" +1256,East 69th Street,"LINESTRING (-8233413.948032004 4978154.192593625, -8233429.955774779 4978163.114477861, -8233466.190269033 4978183.265913594, -8233536.655506705 4978222.481226454, -8233581.1499071745 4978247.248099987, -8233592.649210574 4978253.641932137)" +1257,East 76th Street,"LINESTRING (-8233046.29314976 4978819.4318082705, -8233031.020115623 4978810.950303729, -8232811.49807978 4978689.035002049, -8232798.918977319 4978682.30280523)" +1258,3rd Avenue,"LINESTRING (-8233046.29314976 4978819.4318082705, -8233041.996217415 4978827.4135428425, -8233000.006505489 4978905.408515305, -8232995.553725856 4978913.684309396)" +1259,3rd Avenue,"LINESTRING (-8232888.074757496 4979106.102173856, -8232880.482768224 4979119.80235278, -8232837.235146051 4979197.887859673, -8232832.771234469 4979205.928703163)" +1260,East 79th Street,"LINESTRING (-8232888.074757496 4979106.102173856, -8232904.394194845 4979115.245424181, -8232956.424924843 4979144.380404336, -8232995.909948228 4979166.4154445315, -8233040.604723781 4979191.375810293, -8233054.38607674 4979199.019751318, -8233066.620088778 4979205.781704136)" +1261,East 79th Street,"LINESTRING (-8232888.074757496 4979106.102173856, -8232872.968702596 4979097.679219316, -8232819.067805153 4979067.544799207, -8232722.342299603 4979013.49417229, -8232653.023652687 4978975.187055693, -8232640.6337933615 4978968.675154804)" +1262,East 81st Street,"LINESTRING (-8232781.909359127 4979297.803527444, -8232796.648059708 4979306.1678543715, -8232948.677088284 4979392.42814998, -8232960.109599988 4979398.91093304)" +1263,3rd Avenue,"LINESTRING (-8232781.909359127 4979297.803527444, -8232776.577155518 4979307.446759121, -8232733.730283513 4979384.372452766, -8232729.733913792 4979392.192947048)" +1264,East 85th Street,"LINESTRING (-8232574.766050658 4979672.397157179, -8232590.228327929 4979680.820607422, -8232616.521991655 4979694.786204116, -8232650.095950078 4979713.485434331, -8232741.96792583 4979765.672940776, -8232753.56741677 4979772.141270859)" +1265,3rd Avenue,"LINESTRING (-8232574.766050658 4979672.397157179, -8232569.767805521 4979681.629141423, -8232526.86527377 4979759.248717182, -8232519.072909415 4979773.302630577)" +1266,West 58th Street,"LINESTRING (-8236311.894939977 4978443.768485884, -8236301.119213269 4978437.595010465, -8236268.035060605 4978419.133402493, -8236120.436547762 4978336.79152816, -8236018.456762247 4978279.643559334, -8236012.812864063 4978276.997828136, -8235997.038892218 4978269.5897845905)" +1267,10th Avenue,"LINESTRING (-8236311.894939977 4978443.768485884, -8236306.596132215 4978453.293284183, -8236286.302589045 4978490.260760635, -8236265.530372062 4978527.551752399, -8236261.378155055 4978535.004088281)" +1268,West 58th Street,"LINESTRING (-8236936.664450105 4978791.444341164, -8236930.185655742 4978787.828319225, -8236800.442789222 4978715.434665799, -8236746.4083083905 4978685.286725954, -8236645.964731849 4978629.239145568, -8236630.691697711 4978620.713709124)" +1269,12th Avenue,"LINESTRING (-8236936.664450105 4978791.444341164, -8236891.980806502 4978874.069337304, -8236888.207075763 4978880.757568072)" +1270,East 54th Street,"LINESTRING (-8234901.699630607 4977159.79898341, -8234888.953548912 4977152.75920741, -8234734.95416535 4977067.591546896, -8234722.00770857 4977060.448960623)" +1271,5th Avenue,"LINESTRING (-8234901.699630607 4977159.79898341, -8234906.052222699 4977151.74512736, -8234947.719108101 4977075.601243474, -8234953.296214592 4977065.9308216395)" +1272,10th Avenue,"LINESTRING (-8236524.938181457 4978061.593617383, -8236519.617109798 4978071.220930372, -8236487.557096449 4978129.690525135, -8236478.306446764 4978146.593565208, -8236476.425147371 4978149.930081792, -8236472.907451461 4978156.176867009)" +1273,West 54th Street,"LINESTRING (-8236524.938181457 4978061.593617383, -8236512.32568315 4978054.406209751, -8236224.66498699 4977895.373308138, -8236209.124786077 4977886.819116387)" +1274,,"LINESTRING (-8232924.999432593 4977040.035301488, -8232922.327764813 4977038.933053289, -8232918.554034076 4977037.860198492, -8232914.468608762 4977037.389906017, -8232910.87298921 4977037.287029541, -8232906.186438648 4977037.433995936, -8232900.130658349 4977037.904288413, -8232895.4107119385 4977038.5656372495, -8232890.1786958715 4977039.7413686225, -8232885.436485564 4977041.196336391, -8232881.306532457 4977042.783574207, -8232877.566197566 4977045.120341459, -8232873.814730725 4977047.765739022, -8232858.920182858 4977060.052150427, -8232825.758106549 4977086.653165868, -8232811.765246557 4977097.969641911, -8232800.087831973 4977108.301449019, -8232789.211917723 4977118.236454497, -8232763.652962637 4977136.710300716)" +1275,FDR Drive,"LINESTRING (-8232924.999432593 4977040.035301488, -8232932.346518985 4977032.025634069, -8232940.4171820665 4977022.369951985, -8232947.430309986 4977013.551985817, -8232954.343250366 4977004.13146742, -8232962.536364888 4976992.3595063435, -8232968.681200779 4976983.3211188875, -8232975.33810633 4976972.871871619, -8232980.603518243 4976963.613054264, -8232985.713082871 4976953.09034551)" +1276,10th Avenue,"LINESTRING (-8237701.37369211 4975931.57445908, -8237695.963564858 4975941.331928099, -8237692.701903778 4975947.239316188, -8237616.926726395 4976084.476882091, -8237605.215915963 4976105.682087503, -8237601.620296411 4976112.192080101)" +1277,West 47th Street,"LINESTRING (-8235255.305993114 4976514.967733546, -8235269.065082175 4976522.859410128, -8235270.534499452 4976523.68237863, -8235600.997539822 4976706.074483157, -8235616.02567108 4976714.377806403)" +1278,5th Avenue,"LINESTRING (-8235255.305993114 4976514.967733546, -8235260.181786811 4976506.355967121, -8235302.549985006 4976431.6719903145, -8235307.136348027 4976423.545255931)" +1279,10th Avenue,"LINESTRING (-8236880.5037670005 4977417.80513, -8236875.294014832 4977427.240744558, -8236834.428629762 4977501.329741961, -8236829.764343097 4977509.677833232)" +1280,West 47th Street,"LINESTRING (-8236880.5037670005 4977417.80513, -8236895.342655123 4977426.417699935, -8236947.128482239 4977456.400084531, -8236972.242159363 4977470.230225304, -8237182.057135611 4977585.575243828, -8237194.981328492 4977592.674121646)" +1281,5th Avenue,"LINESTRING (-8232874.72755055 4980824.698555034, -8232880.037490261 4980815.097931878, -8232921.793431256 4980739.675294262, -8232926.324134531 4980731.515570148)" +1282,Park Avenue,"LINESTRING (-8234634.621908297 4976772.207341919, -8234630.414031545 4976779.819997503, -8234589.125632411 4976854.565421268, -8234584.6394569315 4976862.663121447)" +1283,East 52nd Street,"LINESTRING (-8234634.621908297 4976772.207341919, -8234620.92961093 4976764.300767686, -8234607.86070271 4976757.099618285, -8234545.321412783 4976722.28434023, -8234507.50618176 4976700.166636222, -8234481.045538799 4976685.30885786, -8234477.093696876 4976683.295491017, -8234463.379135611 4976676.329538865)" +1284,East 52nd Street,"LINESTRING (-8233771.973778292 4976290.417670792, -8233758.593175499 4976283.025829111, -8233598.13726147 4976194.397642037, -8233543.234488611 4976164.0811378155)" +1285,1st Avenue,"LINESTRING (-8233771.973778292 4976290.417670792, -8233767.020060952 4976299.411330633, -8233746.670858036 4976336.238396675, -8233726.444106558 4976372.874558214, -8233720.844736172 4976382.9998593405)" +1286,5th Avenue,"LINESTRING (-8233497.114823575 4979697.505822638, -8233500.81063067 4979690.846433763, -8233543.1231691195 4979613.477310459, -8233548.299525441 4979603.77497458)" +1287,East 81st Street,"LINESTRING (-8233130.395025055 4979494.345053746, -8233150.443665346 4979505.473215105)" +1288,Park Avenue,"LINESTRING (-8233130.395025055 4979494.345053746, -8233125.240932631 4979503.723873178, -8233083.518387482 4979579.47507566, -8233078.943156411 4979587.339827615)" +1289,West 36th Street,"LINESTRING (-8237442.923230335 4976399.503093972, -8237427.828307384 4976391.200038335, -8237412.477349603 4976382.676554934, -8237324.835514502 4976334.136928278, -8237312.278675941 4976327.0389649365, -8237291.695702094 4976315.561730775, -8237269.220296901 4976303.467297585)" +1290,10th Avenue,"LINESTRING (-8237442.923230335 4976399.503093972, -8237438.0585685875 4976408.232331754, -8237431.880336849 4976419.489239128, -8237423.330999956 4976434.963834015, -8237417.308615505 4976445.868074192, -8237397.849968513 4976481.182024494, -8237393.742279303 4976488.6327993525)" +1291,East 50th Street,"LINESTRING (-8233725.097140719 4976023.345015971, -8233681.827254648 4975999.774081304)" +1292,"['Beekman Place', 'Mitchell Place']","LINESTRING (-8233725.097140719 4976023.345015971, -8233729.471996707 4976015.703559601, -8233768.511742129 4975943.697821906, -8233904.054354119 4976018.87770229, -8233913.494246938 4976024.2561130915)" +1293,Beekman Place,"LINESTRING (-8233725.097140719 4976023.345015971, -8233720.343798464 4976031.7359297555, -8233680.669531943 4976101.831935907, -8233677.519190355 4976107.4014305, -8233673.444896992 4976114.6021010345)" +1294,12th Avenue,"LINESTRING (-8237699.147302295 4977393.187331192, -8237713.307141523 4977378.886990579, -8237742.23907718 4977352.696698537, -8237754.6957282 4977341.056591279, -8237766.272955243 4977329.416497892, -8237770.269324963 4977324.889798654, -8237787.802144763 4977308.032271564)" +1295,West 46th Street,"LINESTRING (-8237498.393732598 4977641.763811304, -8237474.649285212 4977628.286168349)" +1296,12th Avenue,"LINESTRING (-8237498.393732598 4977641.763811304, -8237505.417992466 4977628.947557153, -8237520.768950246 4977601.154568369, -8237533.782198721 4977577.094810629, -8237548.921649469 4977550.72761822, -8237566.643712403 4977525.139457739, -8237587.070838965 4977499.771824311, -8237605.349499352 4977480.72409651, -8237617.360872408 4977469.583544534)" +1297,12th Avenue,"LINESTRING (-8237244.418314353 4978101.308181902, -8237265.034684048 4978064.768424893, -8237294.99075902 4978009.812064647)" +1298,10th Avenue,"LINESTRING (-8236677.089661473 4977786.109504621, -8236672.069152439 4977795.192728228, -8236653.656908663 4977828.527349383, -8236629.912461275 4977869.828338496, -8236627.930974339 4977873.267645821, -8236624.29082699 4977879.587743638)" +1299,West 51st Street,"LINESTRING (-8236677.089661473 4977786.109504621, -8236692.418355357 4977794.751794849, -8236747.465843554 4977825.7935534185, -8236792.683820713 4977850.956263442, -8236953.251054233 4977939.614178846, -8236968.223525746 4977947.8891546475, -8236979.400002622 4977954.062320557, -8236991.812125843 4977960.911599682)" +1300,West 62nd Street,"LINESTRING (-8236501.794859322 4979030.237045957, -8236498.811496968 4979028.590686606, -8236443.2408071635 4978997.780298535, -8236426.8657100685 4978988.578359877)" +1301,5th Avenue,"LINESTRING (-8233180.49992786 4980270.7301070085, -8233184.841388001 4980262.17383445, -8233228.233725513 4980185.888086304, -8233235.714395294 4980171.216122137)" +1302,East 87th Street,"LINESTRING (-8232813.757865443 4980066.704742638, -8232834.006880818 4980078.112879346)" +1303,Park Avenue,"LINESTRING (-8232813.757865443 4980066.704742638, -8232809.115842677 4980075.349051189, -8232767.460089221 4980150.825362855, -8232762.962781794 4980159.087511088)" +1304,West 43rd Street,"LINESTRING (-8235459.577258718 4976148.474714249, -8235473.892945235 4976156.410180743, -8235649.800004587 4976252.459227076, -8235805.079562294 4976338.9864714155, -8235819.350721015 4976346.93678825)" +1305,5th Avenue,"LINESTRING (-8235459.577258718 4976148.474714249, -8235464.475316314 4976139.14320171, -8235505.975222481 4976061.919766771, -8235507.088417389 4976059.906528389, -8235513.800982684 4976047.812411671)" +1306,West 43rd Street,"LINESTRING (-8237082.604302537 4977051.792623354, -8237098.51185777 4977060.537140668, -8237274.352125428 4977157.256433248)" +1307,10th Avenue,"LINESTRING (-8237082.604302537 4977051.792623354, -8237078.151522904 4977059.861093673, -8237037.352929527 4977133.770943371, -8237032.944677693 4977141.810087805)" +1308,Sutton Place,"LINESTRING (-8233209.799217838 4976718.1400224455, -8233214.3744489085 4976709.821999854, -8233258.011689301 4976630.580698047, -8233264.434823919 4976618.912059155)" +1309,Sutton Place,"LINESTRING (-8233209.799217838 4976718.1400224455, -8233205.201722868 4976726.502140634, -8233163.946719579 4976801.408815589, -8233158.681307665 4976810.976101488)" +1310,"['Riverview Terrace', 'Sutton Square']","LINESTRING (-8233209.799217838 4976718.1400224455, -8233195.550323016 4976709.954265175, -8233140.213404142 4976678.842571662, -8233138.565875678 4976677.946109597, -8233136.740236031 4976677.431746151, -8233135.126103413 4976677.387657858, -8233133.456311052 4976677.666883723, -8233132.2651925 4976678.137158881, -8233131.474824115 4976678.475169166, -8233131.062941999 4976678.710306762, -8233130.639927935 4976679.063013167, -8233130.194649971 4976679.592072799, -8233129.8829553975 4976680.077044152, -8233126.81053745 4976685.5146034)" +1311,East 76th Street,"LINESTRING (-8233761.95502412 4979217.100635635, -8233752.915881468 4979212.132064088, -8233597.246705543 4979125.726363137, -8233585.869853585 4979119.405458914)" +1312,5th Avenue,"LINESTRING (-8233761.95502412 4979217.100635635, -8233766.296484262 4979209.236181838, -8233809.143356267 4979131.767975417, -8233813.852170729 4979123.271499849)" +1313,East 76th Street,"LINESTRING (-8233396.025593986 4979013.788164557, -8233383.357435933 4979006.747052211, -8233225.228099261 4978918.932019049)" +1314,Park Avenue,"LINESTRING (-8233396.025593986 4979013.788164557, -8233391.428099016 4979022.093449737, -8233348.859525737 4979098.987496247, -8233343.816752803 4979108.086640643)" +1315,10th Avenue,"LINESTRING (-8236368.93504706 4978345.96345553, -8236358.437619079 4978359.236307983, -8236316.781865622 4978435.860558549, -8236311.894939977 4978443.768485884)" +1316,West 57th Street,"LINESTRING (-8236368.93504706 4978345.96345553, -8236383.217337729 4978353.959501804, -8236566.3824278815 4978456.321231269, -8236616.008656875 4978483.866773588, -8236669.775970928 4978513.999392846, -8236684.214108886 4978522.260156409)" +1317,West 57th Street,"LINESTRING (-8236368.93504706 4978345.96345553, -8236355.253881641 4978338.334880721, -8236354.374457664 4978337.849827033, -8236067.73790082 4978177.871615636, -8236052.487130581 4978169.361271508)" +1318,East 65th Street,"LINESTRING (-8234333.803248326 4978185.794032465, -8234321.90319476 4978179.150372649, -8234270.440194167 4978152.311208863, -8234167.169102559 4978094.635183091, -8234166.234018834 4978094.120745046, -8234153.777367815 4978087.256674295)" +1319,5th Avenue,"LINESTRING (-8234333.803248326 4978185.794032465, -8234338.756965666 4978176.534065377, -8234379.46650345 4978100.661459352, -8234383.774567743 4978092.636223983)" +1320,East 65th Street,"LINESTRING (-8233965.513844986 4977982.223765016, -8233952.589652105 4977975.109906037, -8233807.2397929765 4977894.065192419, -8233795.417663053 4977887.598106047)" +1321,Park Avenue,"LINESTRING (-8233965.513844986 4977982.223765016, -8233961.47294747 4977989.646288687, -8233920.195680284 4978065.194672276, -8233915.5647894675 4978073.205186901)" +1322,East 65th Street,"LINESTRING (-8233104.335132261 4977501.550202027, -8233089.262473207 4977493.1139337495, -8232868.426867372 4977369.745365515, -8232854.812493647 4977362.279221485)" +1323,1st Avenue,"LINESTRING (-8233104.335132261 4977501.550202027, -8233100.104991609 4977509.295702138, -8233064.883504723 4977570.657328992, -8233057.280383502 4977584.384749295, -8233052.549305143 4977592.703516596)" +1324,5th Avenue,"LINESTRING (-8234130.288955256 4978552.863259539, -8234134.452304215 4978545.293318763, -8234176.419752243 4978468.962185549, -8234180.727816536 4978461.127731724)" +1325,East 69th Street,"LINESTRING (-8233763.468969195 4978348.712095697, -8233783.239310761 4978359.706664104)" +1326,Park Avenue,"LINESTRING (-8233763.468969195 4978348.712095697, -8233758.671099143 4978356.899226343, -8233716.948553992 4978432.788521589, -8233712.495774361 4978440.226086416)" +1327,East 69th Street,"LINESTRING (-8232900.097262503 4977868.2115705125, -8232916.4834915465 4977877.324266276, -8233153.638534732 4978009.31232917, -8233165.371609061 4978015.8382885745)" +1328,1st Avenue,"LINESTRING (-8232900.097262503 4977868.2115705125, -8232895.076753467 4977877.015610312, -8232853.699298739 4977951.57835571, -8232849.302178853 4977959.485890971)" +1329,West 35th Street,"LINESTRING (-8237493.017001192 4976308.801778423, -8237507.956076859 4976317.134155145, -8237625.899077352 4976382.823511479, -8237639.457791331 4976390.377080993)" +1330,10th Avenue,"LINESTRING (-8237493.017001192 4976308.801778423, -8237488.252526986 4976317.413370713, -8237476.174362236 4976339.280383198, -8237465.175996545 4976359.178231442, -8237448.222038098 4976389.994993678, -8237442.923230335 4976399.503093972)" +1331,West 41st Street,"LINESTRING (-8237190.417229369 4976856.62291251, -8237207.237604428 4976862.868870722, -8237207.872125526 4976863.2362801535, -8237273.172138824 4976899.565792924, -8237291.562118704 4976909.676943488, -8237303.217269389 4976915.908239164)" +1332,10th Avenue,"LINESTRING (-8237190.417229369 4976856.62291251, -8237183.982962801 4976867.880336553, -8237146.334711014 4976936.512693263, -8237138.3308396265 4976951.003440932)" +1333,West 46th Street,"LINESTRING (-8236930.6420656545 4977327.0355714075, -8236917.985039551 4977319.995674888, -8236630.569246271 4977159.372775534, -8236614.505843751 4977150.907409138)" +1334,10th Avenue,"LINESTRING (-8236930.6420656545 4977327.0355714075, -8236926.233813818 4977335.001389453, -8236884.578060364 4977410.412435245, -8236880.5037670005 4977417.80513)" +1335,1st Avenue,"LINESTRING (-8234045.597086662 4975837.48298, -8234042.546932615 4975843.243356866, -8233993.054287007 4975932.470852665, -8233989.224896526 4975938.583965206)" +1336,East 47th Street,"LINESTRING (-8234045.597086662 4975837.48298, -8234048.346678085 4975839.892933174, -8234052.587950683 4975842.640868311, -8234098.2512058085 4975868.121758206, -8234277.008044125 4975966.739600231, -8234291.245806996 4975975.63009683)" +1337,East 50th Street,"LINESTRING (-8233872.60659797 4976104.3301257, -8233860.539565168 4976097.687881305, -8233733.234595497 4976027.812331696, -8233725.097140719 4976023.345015971)" +1338,1st Avenue,"LINESTRING (-8233872.60659797 4976104.3301257, -8233867.942311306 4976113.059099759, -8233847.893671014 4976151.340298628, -8233827.076926235 4976190.209462078, -8233823.414514988 4976197.292630638)" +1339,East 54th Street,"LINESTRING (-8233669.927201084 4976475.200834585, -8233655.93434109 4976467.441458539, -8233434.6979850875 4976344.717752771, -8233423.143021942 4976338.266387586)" +1340,1st Avenue,"LINESTRING (-8233669.927201084 4976475.200834585, -8233665.652532635 4976482.401776202, -8233646.182753696 4976518.1273425855, -8233624.453189094 4976557.938504032, -8233618.842686758 4976568.034605091)" +1341,East 58th Street,"LINESTRING (-8233459.911849751 4976856.975625339, -8233444.772399005 4976848.657484536, -8233344.005995937 4976792.649833949, -8233224.114904353 4976726.178824859, -8233209.799217838 4976718.1400224455)" +1342,1st Avenue,"LINESTRING (-8233459.911849751 4976856.975625339, -8233454.869076819 4976865.793450176, -8233438.004173964 4976896.77347121, -8233412.957288535 4976940.319084331, -8233407.168675014 4976950.5184561275)" +1343,East 62nd Street,"LINESTRING (-8233255.150778388 4977224.685675393, -8233241.491876867 4977217.116763863, -8233169.612881662 4977177.067766481, -8233090.342272269 4977132.93322669, -8233022.60436212 4977094.221976316, -8233006.808126376 4977085.139404481)" +1344,1st Avenue,"LINESTRING (-8233255.150778388 4977224.685675393, -8233250.731394602 4977232.577925313, -8233216.968193045 4977293.67326751, -8233209.053377249 4977307.929392238, -8233204.032868214 4977317.188535937)" +1345,5th Avenue,"LINESTRING (-8232976.29545395 4980641.24448269, -8232981.583129763 4980631.732252209, -8233022.292667545 4980558.384004129, -8233028.871649452 4980546.534248661)" +1346,East 91st Street,"LINESTRING (-8232609.664711023 4980436.564499287, -8232629.624295722 4980447.899559251)" +1347,Park Avenue,"LINESTRING (-8232609.664711023 4980436.564499287, -8232605.056084104 4980444.694573387, -8232561.073753291 4980518.747657619, -8232557.255494758 4980525.819264029)" +1348,East 58th Street,"LINESTRING (-8234321.981118403 4977336.882616802, -8234308.667307305 4977329.489983286, -8234195.600100506 4977266.718960704, -8234162.627267334 4977248.377141235, -8234151.139095883 4977242.571844973)" +1349,Park Avenue,"LINESTRING (-8234321.981118403 4977336.882616802, -8234317.55060267 4977344.966019695, -8234275.917113114 4977420.78866446, -8234272.009798986 4977427.6963585755)" +1350,East 54th Street,"LINESTRING (-8234533.5326787075 4976954.971499315, -8234519.96283278 4976947.4027967565, -8234374.73542509 4976866.366609066, -8234362.067267039 4976859.297651773)" +1351,Park Avenue,"LINESTRING (-8234533.5326787075 4976954.971499315, -8234528.846128145 4976963.5395716205, -8234487.7024443485 4977038.624423815, -8234482.303449045 4977048.456481837)" +1352,East 62nd Street,"LINESTRING (-8234486.611513338 4977909.012997076, -8234474.355237402 4977902.178452286, -8234321.201881968 4977816.960164163, -8234320.155478755 4977816.372251684, -8234307.453924855 4977809.317304698)" +1353,5th Avenue,"LINESTRING (-8234486.611513338 4977909.012997076, -8234490.730334497 4977901.8550975965, -8234533.298907778 4977827.072264338, -8234538.408472405 4977818.033104527)" +1354,West 63rd Street,"LINESTRING (-8236248.899240138 4979007.849522493, -8236305.58312485 4979040.276904072, -8236361.409849483 4979073.071885882, -8236376.037230573 4979081.171425466)" +1355,Park Avenue,"LINESTRING (-8234908.545779292 4976322.115949913, -8234912.8093157895 4976314.165653275, -8234956.646931265 4976238.910023493, -8234962.346489193 4976231.856215618)" +1356,East 47th Street,"LINESTRING (-8234908.545779292 4976322.115949913, -8234919.944895148 4976328.2586974, -8234977.842162311 4976359.560317552)" +1357,65th Street Transverse,"LINESTRING (-8234565.42571282 4978310.481079168, -8234545.46612812 4978301.500266155, -8234513.740073245 4978290.71154262, -8234501.739832137 4978286.301986025, -8234488.03640282 4978280.290293736, -8234474.9118348565 4978273.837650143, -8234465.483073987 4978268.781367481, -8234453.872451096 4978262.475716315, -8234439.489972886 4978253.7448214255, -8234425.274473911 4978243.691073338, -8234413.251968906 4978234.989592122, -8234400.194192636 4978226.273420228, -8234389.429597877 4978218.527351565, -8234377.629731852 4978211.325130046, -8234364.917046004 4978203.740755576, -8234344.734822323 4978192.055538993, -8234333.803248326 4978185.794032465)" +1358,65th Street Transverse,"LINESTRING (-8234565.42571282 4978310.481079168, -8234604.476590189 4978324.635797947, -8234653.312450802 4978342.053626464, -8234665.590990636 4978347.256933161, -8234676.377849293 4978351.931092386, -8234686.006985248 4978356.443568982, -8234699.343060244 4978363.293130273, -8234711.833107112 4978370.186792303, -8234729.221211574 4978380.608137102, -8234748.112129161 4978393.102006597, -8234758.208806976 4978400.333759536, -8234767.359269119 4978407.565517831, -8234778.357634811 4978416.193659222, -8234788.699215504 4978424.821808237, -8234830.510816247 4978461.333514671, -8234927.180662052 4978545.822479481, -8234945.771017013 4978561.0799591765, -8234965.28532375 4978576.161075247, -8234985.011137518 4978591.139321762, -8235060.90876634 4978647.936335689, -8235080.434205026 4978662.782400509, -8235101.362269294 4978679.304186305, -8235150.576616175 4978722.56376318, -8235155.942215632 4978726.767728199)" +1359,East 85th Street,"LINESTRING (-8232924.687738018 4979866.064846616, -8232944.73637831 4979877.266936139)" +1360,Park Avenue,"LINESTRING (-8232924.687738018 4979866.064846616, -8232919.311006612 4979875.458723969, -8232876.965072315 4979953.006335274, -8232868.727429997 4979967.663270532)" +1361,West 67th Street,"LINESTRING (-8236362.400592949 4979554.528418373, -8236383.039226543 4979566.112362092, -8236389.696132093 4979569.728672211, -8236399.815073807 4979575.020835773)" +1362,East 50th Street,"LINESTRING (-8234737.169423216 4976586.28697148, -8234725.425216937 4976579.659095362, -8234577.860099941 4976497.376812599, -8234565.6706157 4976491.2486545965)" +1363,Park Avenue,"LINESTRING (-8234737.169423216 4976586.28697148, -8234732.683247736 4976595.089856026, -8234690.649008013 4976670.509886444, -8234688.678653026 4976674.036948102, -8234685.61736703 4976679.533288393)" +1364,East 62nd Street,"LINESTRING (-8234118.956631095 4977705.110452051, -8234107.54638329 4977698.761071856, -8234104.663208477 4977697.15902982, -8233959.569384178 4977616.498757582, -8233948.370643403 4977610.267014995)" +1365,Park Avenue,"LINESTRING (-8234118.956631095 4977705.110452051, -8234113.902726214 4977714.178902683, -8234072.447347843 4977788.843289478, -8234067.827588974 4977797.162230901)" +1366,East 79th Street,"LINESTRING (-8233237.272868166 4979300.949336731, -8233257.020945832 4979311.91557703)" +1367,Park Avenue,"LINESTRING (-8233237.272868166 4979300.949336731, -8233229.591823301 4979315.12019113, -8233186.600235956 4979392.722153653, -8233182.247643867 4979400.425053059)" +1368,East 79th Street,"LINESTRING (-8233237.272868166 4979300.949336731, -8233224.3041474875 4979293.555216511, -8233183.082540047 4979270.667289402, -8233131.062941999 4979241.326133109, -8233101.374033805 4979224.832796382, -8233078.854100819 4979212.4995618975, -8233066.620088778 4979205.781704136)" +1369,East 50th Street,"LINESTRING (-8233681.827254648 4975999.774081304, -8233725.097140719 4976023.345015971)" +1370,,"LINESTRING (-8235769.112234819 4981024.946476306, -8235790.763875779 4980981.147406057, -8235797.743607851 4980964.268864128, -8235804.478437043 4980947.478566525, -8235809.910828194 4980935.010833568, -8235816.567733743 4980921.660967347, -8235823.51406997 4980908.575763764, -8235831.696052543 4980895.681709523, -8235839.310305714 4980884.787202619, -8235847.035878374 4980874.201458569, -8235855.5963472165 4980864.39495314, -8235864.557566224 4980855.029529114, -8235873.2293545585 4980848.413457902, -8235883.760178387 4980841.371022581, -8235894.302134164 4980835.122519504, -8235906.8033129815 4980827.947772667, -8235924.736882948 4980818.758811569, -8235919.98354069 4980819.861486443, -8235914.595677337 4980820.302556428, -8235909.46384881 4980819.817379448, -8235904.198436896 4980818.494169617, -8235898.632462357 4980816.038880743, -8235894.535905095 4980813.069011192, -8235890.695382663 4980809.2464081505, -8235888.034846833 4980804.571072618, -8235886.086755744 4980799.087112725, -8235884.828845498 4980794.058927003, -8235884.160928554 4980787.766347351, -8235883.159053137 4980782.252992342, -8235881.7898234 4980777.210113022, -8235879.429850195 4980773.108181035, -8235875.934418184 4980769.3297004085)" +1371,"['Henry Hudson Parkway', 'West Side Highway']","LINESTRING (-8235769.112234819 4981024.946476306, -8235777.895342643 4980992.541908614, -8235786.756374108 4980962.386937916, -8235796.16287108 4980931.3205052875, -8235806.382000336 4980900.91578194, -8235816.901692217 4980871.687346043, -8235828.890801376 4980841.988521926, -8235841.859522052 4980813.274843706, -8235861.841370649 4980776.989579001, -8235874.331417517 4980752.598546948, -8235893.211203154 4980714.078777145, -8235908.172542717 4980685.438985726, -8235922.978034993 4980656.681661616, -8235937.649943879 4980628.835948941, -8235952.5890195435 4980600.710977627, -8235967.583754954 4980572.718404964, -8235982.901316887 4980545.402200814, -8235998.3190663615 4980517.350979204, -8236014.126434054 4980488.3148153005, -8236022.753694591 4980472.7014808385, -8236160.322321314 4980223.523686374, -8236168.5043038875 4980209.233902389, -8236175.584223502 4980198.0461334335, -8236191.80347331 4980174.523927765, -8236197.002093529 4980166.761612327, -8236265.663955451 4980073.614308383, -8236284.031671431 4980047.607904444, -8236302.3659915645 4980020.734203101, -8236319.909943314 4979992.875602811, -8236336.6078669345 4979964.620153779, -8236352.571081914 4979936.320683498, -8236753.911242071 4979210.235775615, -8236801.43353269 4979122.53651096, -8236880.770933779 4978973.966992668, -8236882.184691311 4978971.3210733775, -8236975.203257819 4978805.026484303, -8236994.906807689 4978769.380748471)" +1372,Henry Hudson Parkway,"LINESTRING (-8236166.122066783 4980184.976600914, -8236156.581986422 4980199.795599746, -8236148.589246983 4980213.394403182, -8236141.687438553 4980225.7142003765, -8236126.38100857 4980253.352942755, -8236009.506675187 4980464.8360157795)" +1373,12th Avenue,"LINESTRING (-8236997.7899825005 4978699.2215008205, -8236989.351965098 4978701.617460949, -8236982.728455397 4978706.0419042045, -8236936.664450105 4978791.444341164)" +1374,West Side Highway,"LINESTRING (-8236997.7899825005 4978699.2215008205, -8236990.164597381 4978719.873814484, -8236984.531831146 4978733.558752435, -8236978.498314746 4978746.24416317, -8236953.885575331 4978793.222954073, -8236900.9976852555 4978888.460063684, -8236885.179185614 4978916.991689101, -8236769.774269509 4979145.850385456, -8236749.0243164245 4979185.775157301, -8236730.5786768 4979220.540417416, -8236347.53944093 4979914.460317665, -8236331.3313230695 4979943.55357927, -8236315.791122154 4979970.882800883, -8236298.603392777 4979998.667832948, -8236280.614163064 4980026.364737246, -8236261.778905222 4980053.444270583, -8236242.687612552 4980080.141647322, -8236214.423593839 4980118.1884755455, -8236194.085522871 4980144.915431929, -8236184.4452549685 4980157.852598807, -8236178.200231535 4980167.099743364, -8236166.122066783 4980184.976600914)" +1375,Riverside Boulevard,"LINESTRING (-8236255.934631955 4979979.629932079, -8236238.791430375 4980011.3107837625, -8236234.00469227 4980019.396400426, -8236229.039842981 4980026.55585204, -8236224.008201997 4980032.524515919, -8236218.842977624 4980037.0083668, -8236212.531162496 4980041.271702334, -8236206.308402961 4980044.667670935, -8236199.929796137 4980047.534398597, -8236194.6643842235 4980049.813080157)" +1376,Riverside Boulevard,"LINESTRING (-8236255.934631955 4979979.629932079, -8236277.018543512 4979942.2598902015, -8236285.311845575 4979925.868276512, -8236293.582883743 4979908.212407707, -8236301.8316580085 4979891.423925927, -8236306.42915298 4979880.11891374)" +1377,West 71st Street,"LINESTRING (-8236255.934631955 4979979.629932079, -8236246.427947442 4979973.690702647, -8236240.361035193 4979970.309459783, -8236190.868389587 4979942.406900312)" +1378,12th Avenue,"LINESTRING (-8236936.720109851 4978907.025454984, -8236941.495716006 4978898.632071015, -8236991.711938304 4978809.744960528, -8237043.687008554 4978717.551345715, -8237049.019212163 4978705.4539382085, -8237053.616707133 4978692.709783931, -8237058.1028826125 4978679.612867623, -8237060.2847446315 4978670.675812479, -8237063.746780795 4978642.894558414)" +1379,West 59th Street,"LINESTRING (-8236936.720109851 4978907.025454984, -8236925.421181536 4978900.910484516, -8236888.207075763 4978880.757568072)" +1380,,"LINESTRING (-8236994.906807689 4978769.380748471, -8237010.13531403 4978754.72561152, -8237022.480645558 4978738.835763706, -8237032.599587272 4978720.344187974, -8237040.536666964 4978704.263307174, -8237046.113773454 4978690.137436468, -8237052.191817651 4978672.630792593, -8237063.746780795 4978642.894558414)" +1381,West Side Highway,"LINESTRING (-8236994.906807689 4978769.380748471, -8237005.381971773 4978746.258862382, -8237014.243003239 4978725.635891285, -8237020.543686419 4978709.084628803, -8237027.000216885 4978688.329444086, -8237034.325039378 4978660.959714108, -8237042.395702462 4978625.549688539, -8237048.262239627 4978596.416256085)" +1382,West 56th Street,"LINESTRING (-8237048.262239627 4978596.416256085, -8237019.998220913 4978580.203288677)" +1383,12th Avenue,"LINESTRING (-8237048.262239627 4978596.416256085, -8237052.280873245 4978569.046783674, -8237058.726271762 4978492.465584728, -8237061.431335387 4978476.57616358)" +1384,West 56th Street,"LINESTRING (-8237019.998220913 4978580.203288677, -8236999.470906811 4978568.605815358)" +1385,12th Avenue,"LINESTRING (-8237019.998220913 4978580.203288677, -8237017.01485856 4978610.615486273, -8237015.033371624 4978626.872601257, -8237012.3060441 4978641.571643524, -8237009.1779664075 4978658.269782381, -8237001.897671711 4978687.050620409, -8236997.7899825005 4978699.2215008205)" +1386,West 55th Street,"LINESTRING (-8237033.434483452 4978464.287970316, -8237061.431335387 4978476.57616358)" +1387,12th Avenue,"LINESTRING (-8237033.434483452 4978464.287970316, -8237030.80734347 4978479.545322643, -8237029.271134496 4978487.938346465, -8237019.998220913 4978580.203288677)" +1388,12th Avenue,"LINESTRING (-8237169.878783317 4978181.604998647, -8237074.834202079 4978353.82721422, -8237068.65597034 4978366.144665789)" +1389,West 52nd Street,"LINESTRING (-8237169.878783317 4978181.604998647, -8237156.386861035 4978173.961853855, -8236958.215903524 4978063.915930183, -8236939.6032846635 4978053.979962839)" +1390,West 51st Street,"LINESTRING (-8237221.597818741 4978088.82938387, -8237244.418314353 4978101.308181902)" +1391,12th Avenue,"LINESTRING (-8237221.597818741 4978088.82938387, -8237176.591348613 4978169.816920143, -8237173.129312448 4978176.196003253, -8237169.878783317 4978181.604998647)" +1392,12th Avenue,"LINESTRING (-8237068.65597034 4978366.144665789, -8237061.01945327 4978380.358259876)" +1393,West 54th Street,"LINESTRING (-8237068.65597034 4978366.144665789, -8237063.07886385 4978361.661581975, -8237055.509138477 4978356.634651098, -8236858.106285453 4978246.439684726, -8236853.1303042155 4978243.838057886, -8236839.259895662 4978236.091975293)" +1394,West 44th Street,"LINESTRING (-8237595.865078736 4977455.47415657, -8237585.568025837 4977449.903893393, -8237409.24908437 4977352.020631322, -8237369.374442768 4977329.651651155, -8237363.719412637 4977326.3007176705, -8237346.6096069 4977316.674138836)" +1395,12th Avenue,"LINESTRING (-8237595.865078736 4977455.47415657, -8237585.7684009215 4977466.320746755, -8237564.673357416 4977489.762944192, -8237545.771307879 4977512.617303688, -8237526.8581263935 4977538.073154831)" +1396,West 46th Street,"LINESTRING (-8237474.649285212 4977628.286168349, -8237461.71396038 4977621.143172097, -8237384.747664448 4977578.696832974, -8237329.733572096 4977547.758741484, -8237264.344503204 4977511.000594827, -8237259.045695443 4977507.943546078, -8237245.66509265 4977500.712453806)" +1397,12th Avenue,"LINESTRING (-8237474.649285212 4977628.286168349, -8237462.1815022435 4977651.420105641, -8237423.89872936 4977720.8075485835)" +1398,12th Avenue,"LINESTRING (-8237373.148173505 4977812.683101687, -8237359.1887093615 4977838.56597231, -8237322.497805196 4977904.603612794)" +1399,West 48th Street,"LINESTRING (-8237373.148173505 4977812.683101687, -8237360.2573764725 4977805.3488992555, -8237219.19331774 4977726.804198861, -8237161.808120235 4977694.836804216, -8237158.190236784 4977692.808531672, -8237143.785494676 4977684.680748092)" +1400,12th Avenue,"LINESTRING (-8237271.713853496 4977996.818950585, -8237236.202935931 4978061.314351958, -8237221.597818741 4978088.82938387)" +1401,West 50th Street,"LINESTRING (-8237271.713853496 4977996.818950585, -8237259.012299595 4977989.308233031, -8237241.078729629 4977979.563416321, -8237208.974188484 4977961.264352385, -8237117.035421038 4977910.629771813, -8237066.641087557 4977883.262220992, -8237060.919265729 4977880.1609620135, -8237041.872500854 4977869.813640605)" +1402,West 43rd Street,"LINESTRING (-8237673.866645936 4977379.607151118, -8237699.147302295 4977393.187331192)" +1403,12th Avenue,"LINESTRING (-8237673.866645936 4977379.607151118, -8237664.671655996 4977388.983940103, -8237637.754603122 4977415.468273598, -8237607.676076709 4977443.907413099, -8237595.865078736 4977455.47415657)" +1404,12th Avenue,"LINESTRING (-8237526.8581263935 4977538.073154831, -8237508.612861852 4977567.703143635, -8237498.00411438 4977586.089655091, -8237481.473169998 4977615.984344717, -8237474.649285212 4977628.286168349)" +1405,12th Avenue,"LINESTRING (-8237423.89872936 4977720.8075485835, -8237385.749539863 4977790.151391106)" +1406,West 49th Street,"LINESTRING (-8237322.497805196 4977904.603612794, -8237346.0196135985 4977917.743583831)" +1407,12th Avenue,"LINESTRING (-8237322.497805196 4977904.603612794, -8237277.803029641 4977985.266264136, -8237271.713853496 4977996.818950585)" +1408,West 42nd Street,"LINESTRING (-8237757.723618349 4977295.363425541, -8237787.802144763 4977308.032271564)" +1409,12th Avenue,"LINESTRING (-8237757.723618349 4977295.363425541, -8237744.231696066 4977310.9275901895, -8237731.841836741 4977323.008573613, -8237673.866645936 4977379.607151118)" +1410,West 42nd Street,"LINESTRING (-8237757.723618349 4977295.363425541, -8237744.888481061 4977287.250669662, -8237714.6318434635 4977271.113360065, -8237681.046753091 4977254.814410494, -8237618.496331214 4977220.379478405, -8237519.856130422 4977166.045135465, -8237469.96273465 4977138.562096296, -8237458.340979812 4977131.6693034135)" +1411,East 47th Street,"LINESTRING (-8234889.042604504 4976311.682105375, -8234908.545779292 4976322.115949913)" +1412,Park Avenue,"LINESTRING (-8234889.042604504 4976311.682105375, -8234884.979443091 4976319.029882058, -8234842.833883876 4976395.035608292, -8234837.969222129 4976403.808929143)" +1413,East 46th Street,"LINESTRING (-8234937.299603763 4976217.542879454, -8234924.486730374 4976210.694822544, -8234817.842658194 4976150.473275575, -8234808.469557069 4976145.227052968, -8234780.661948268 4976129.797002808, -8234769.184908767 4976123.22821742)" +1414,Park Avenue,"LINESTRING (-8234937.299603763 4976217.542879454, -8234934.1269982755 4976226.389518015, -8234893.439724391 4976303.349733302, -8234889.042604504 4976311.682105375)" +1415,12th Avenue,"LINESTRING (-8237061.01945327 4978380.358259876, -8237052.7261512065 4978399.775209322, -8237044.254737958 4978425.365661156, -8237038.599707825 4978444.503423693, -8237033.434483452 4978464.287970316)" +1416,,"LINESTRING (-8237061.01945327 4978380.358259876, -8237038.944798246 4978403.185305867, -8237015.166955013 4978445.106072739, -8237012.617738673 4978452.867019866, -8237012.07227317 4978455.204124469)" +1417,12th Avenue,"LINESTRING (-8237077.739640788 4978484.925088396, -8237083.339011174 4978464.978813306, -8237084.4633380305 4978443.694992105, -8237088.760270377 4978426.791437872, -8237099.458073441 4978394.557175965, -8237108.998153803 4978371.715451493, -8237121.254429739 4978346.007551354, -8237126.586633348 4978314.317402792)" +1418,West 55th Street,"LINESTRING (-8237012.07227317 4978455.204124469, -8237033.434483452 4978464.287970316)" +1419,12th Avenue,"LINESTRING (-8237012.07227317 4978455.204124469, -8237009.166834461 4978467.477607512, -8236999.470906811 4978568.605815358)" +1420,West 56th Street,"LINESTRING (-8236999.470906811 4978568.605815358, -8236989.3630970465 4978561.8590026125, -8236981.648656336 4978558.037280687, -8236859.074765023 4978489.878591178, -8236754.99104113 4978431.3921414735, -8236748.946392782 4978427.982035081, -8236738.8051871685 4978421.823268362)" +1421,12th Avenue,"LINESTRING (-8236999.470906811 4978568.605815358, -8236996.23150963 4978606.39687225, -8236995.018127181 4978613.658181142, -8236992.914188804 4978622.389397768, -8236990.108937634 4978629.974097335, -8236986.301811052 4978637.5441037435, -8236977.351723991 4978653.036911851, -8236972.5983817335 4978660.3129545, -8236970.260672428 4978662.341427961, -8236967.232782277 4978664.781476309, -8236963.002641627 4978666.119093431, -8236958.995139959 4978666.41307524, -8236954.252929651 4978665.266546233, -8236949.91146951 4978663.723142011, -8236926.077966531 4978656.050221785)" +1422,West 59th Street,"LINESTRING (-8236888.207075763 4978880.757568072, -8236925.421181536 4978900.910484516, -8236936.720109851 4978907.025454984)" +1423,West 59th Street,"LINESTRING (-8236888.207075763 4978880.757568072, -8236880.236600223 4978876.450640921, -8236815.081302261 4978841.172128246, -8236756.527250104 4978809.53917024, -8236726.894001653 4978793.414044733)" +1424,12th Avenue,"LINESTRING (-8237063.746780795 4978642.894558414, -8237065.850719171 4978622.345300695, -8237077.617189349 4978494.729204643, -8237077.739640788 4978484.925088396)" +1425,65th Street Transverse,"LINESTRING (-8235155.942215632 4978726.767728199, -8235150.576616175 4978722.56376318, -8235101.362269294 4978679.304186305, -8235080.434205026 4978662.782400509, -8235060.90876634 4978647.936335689, -8234985.011137518 4978591.139321762, -8234965.28532375 4978576.161075247, -8234945.771017013 4978561.0799591765, -8234927.180662052 4978545.822479481, -8234830.510816247 4978461.333514671, -8234788.699215504 4978424.821808237, -8234778.357634811 4978416.193659222, -8234767.359269119 4978407.565517831, -8234758.208806976 4978400.333759536, -8234748.112129161 4978393.102006597, -8234729.221211574 4978380.608137102, -8234711.833107112 4978370.186792303, -8234699.343060244 4978363.293130273, -8234686.006985248 4978356.443568982, -8234676.377849293 4978351.931092386, -8234665.590990636 4978347.256933161, -8234653.312450802 4978342.053626464, -8234604.476590189 4978324.635797947, -8234565.42571282 4978310.481079168)" +1426,65th Street Transverse,"LINESTRING (-8235155.942215632 4978726.767728199, -8235167.363595386 4978739.159146105, -8235185.9428184 4978754.22583793, -8235203.842992519 4978769.072064317, -8235219.149422504 4978783.418538188, -8235253.29111033 4978818.946730691, -8235256.441451918 4978821.460314782, -8235260.1149951145 4978823.915102208, -8235263.8887258535 4978825.840714335, -8235275.5216126405 4978831.558755636)" +1427,1st Avenue,"LINESTRING (-8233991.47355024 4975847.857538745, -8233971.847924011 4975888.915036513, -8233967.651179209 4975897.599733346, -8233963.443302457 4975907.386558314, -8233948.370643403 4975940.038768995, -8233931.572532244 4975980.80275312, -8233925.616939485 4975994.57202483, -8233923.156778739 4976001.831392539, -8233920.073228844 4976011.677102301)" +1428,,"LINESTRING (-8233991.47355024 4975847.857538745, -8233972.9722508695 4975864.227615598, -8233964.033295758 4975882.09659974)" +1429,,"LINESTRING (-8233604.1596459225 4976005.108396329, -8233639.214153572 4975975.145160444, -8233645.871059122 4975966.475089712, -8233652.527964673 4975958.113622007, -8233659.251661915 4975950.501606663, -8233666.554220512 4975942.786732296, -8233673.511688685 4975934.322420001, -8233696.421239891 4975903.3013659185, -8233698.62536581 4975900.744447807, -8233700.573456899 4975898.613683226, -8233702.566075784 4975897.394004397, -8233705.14868797 4975896.218410489, -8233707.998466932 4975896.306580028, -8233711.1710724225 4975897.247055151, -8233714.243490368 4975898.525513667, -8233736.796819202 4975909.6054944685)" +1430,FDR Drive,"LINESTRING (-8233561.780315776 4976031.618368742, -8233537.390215344 4976074.822136455, -8233518.6551450435 4976104.609335187, -8233429.209934192 4976238.498551228, -8233419.458346798 4976252.576790747, -8233410.12977347 4976264.524206167, -8233399.999699808 4976277.074151507, -8233388.36681302 4976289.609417453, -8233375.086397769 4976302.952953856, -8233362.206732682 4976316.34059515, -8233312.491448095 4976372.183863164, -8233285.808166151 4976404.822931557, -8233260.07109988 4976438.402636206, -8233234.9574227575 4976474.495436508, -8233211.424482403 4976512.160825908, -8233185.687416132 4976554.22043742, -8233087.971167115 4976716.214825774, -8233009.947336017 4976860.679110801)" +1431,East 52nd Street,"LINESTRING (-8233543.234488611 4976164.0811378155, -8233598.13726147 4976194.397642037, -8233758.593175499 4976283.025829111, -8233771.973778292 4976290.417670792)" +1432,East 59th Street,"LINESTRING (-8233512.877663471 4977009.451634261, -8233501.9906172715 4977003.587693625, -8233463.1401149845 4976982.645077237, -8233460.0343011925 4976980.9255802, -8233422.519632795 4976960.203460242, -8233407.168675014 4976950.5184561275)" +1433,,"LINESTRING (-8232756.083237262 4977166.956339158, -8232791.226800505 4977150.099084606, -8232828.652413311 4977130.126141492, -8232831.568983968 4977129.141457347, -8232834.797249202 4977128.391921723, -8232837.669292064 4977128.142076526, -8232840.730578062 4977128.318437839, -8232843.391113891 4977128.994489574, -8232846.741830564 4977130.199625387, -8232850.214998677 4977131.948542262, -8232884.712908874 4977150.569382507, -8232936.03119413 4977177.111857031, -8232955.968514931 4977179.566231241)" +1434,FDR Drive,"LINESTRING (-8232756.083237262 4977166.956339158, -8232793.186023544 4977133.638672312, -8232837.8585351985 4977093.545926988, -8232869.584590076 4977066.048395097, -8232887.4179725 4977050.146597441, -8232908.991689817 4977028.395566778, -8232929.541267816 4977005.351284423, -8232939.749265122 4976991.992092056, -8232956.202285862 4976967.992620745, -8232973.200772106 4976938.114610558, -8232989.308702423 4976909.324228758)" +1435,,"LINESTRING (-8233009.947336017 4976860.679110801, -8232992.247536981 4976932.632821267, -8232991.0898142755 4976936.248156486, -8232985.713082871 4976953.09034551)" +1436,FDR Drive,"LINESTRING (-8233009.947336017 4976860.679110801, -8232977.709211484 4976917.81877873, -8232966.666317995 4976933.191287596, -8232951.215172674 4976952.531878045, -8232941.5303769745 4976964.333184188, -8232930.843705858 4976976.7370630475, -8232920.001187456 4976987.730087334, -8232908.167925584 4976999.119931694, -8232884.980075652 4977020.723931029, -8232784.15801284 4977112.872138155, -8232763.652962637 4977136.710300716)" +1437,FDR Drive,"LINESTRING (-8232989.308702423 4976909.324228758, -8233007.565098913 4976878.579310328, -8233019.075534262 4976856.946232602, -8233094.149398854 4976718.25759172, -8233169.50156217 4976596.427189765, -8233183.884040381 4976573.883588353, -8233196.129184369 4976555.484285991, -8233219.138923115 4976523.388461299, -8233242.148661862 4976491.307437869, -8233269.087978634 4976452.246031633, -8233293.010537206 4976421.061680225, -8233327.820141977 4976376.254555971, -8233349.31593565 4976351.433643152, -8233375.453752087 4976323.453246285, -8233384.9938324485 4976313.430875724, -8233397.149920843 4976301.307054109, -8233408.159418482 4976289.5947219385, -8233418.122512908 4976277.323974938)" +1438,Lincoln Tunnel Expressway,"LINESTRING (-8237490.367597311 4976816.193288989, -8237508.000604652 4976822.6596661, -8237529.039988413 4976830.551591233, -8237553.274241557 4976839.648622717)" +1439,West 39th Street,"LINESTRING (-8237403.415943052 4976733.571001838, -8237464.663926887 4976768.107091658)" +1440,,"LINESTRING (-8237403.415943052 4976733.571001838, -8237405.441957785 4976740.492906229, -8237407.712875398 4976745.107511879, -8237411.330758847 4976749.824993157, -8237433.171642941 4976768.665548581)" +1441,,"LINESTRING (-8237395.489995309 4976767.84255944, -8237406.109874729 4976769.018258233, -8237419.468213626 4976769.018258233, -8237433.171642941 4976768.665548581)" +1442,Lincoln Tunnel Expressway,"LINESTRING (-8237395.489995309 4976767.84255944, -8237415.18241323 4976778.688386162, -8237437.847061555 4976790.900977818, -8237449.190517667 4976796.735398234, -8237463.572995878 4976805.215154018, -8237476.10757054 4976810.843834799, -8237490.367597311 4976816.193288989)" +1443,West 39th Street,"LINESTRING (-8237464.663926887 4976768.107091658, -8237520.869137789 4976799.189676882, -8237572.922131684 4976827.524148064, -8237593.349258245 4976838.972591006, -8237607.086083409 4976846.291371574)" +1444,Lincoln Tunnel Expressway,"LINESTRING (-8237082.236948216 4976457.801030218, -8237083.361275073 4976471.40932052, -8237084.062587864 4976477.625640863, -8237086.734255645 4976487.6481798645, -8237091.086847734 4976497.714816632, -8237100.504476655 4976510.896982942)" +1445,Lincoln Tunnel Expressway,"LINESTRING (-8237082.236948216 4976457.801030218, -8237079.309245609 4976471.967760485, -8237079.888106961 4976482.284209765, -8237082.281476012 4976493.629377393, -8237086.16652624 4976507.663897027, -8237091.242695021 4976518.7004810795, -8237096.908857103 4976529.751773475, -8237106.949875172 4976543.639386031, -8237122.890826254 4976558.423469346, -8237147.369982279 4976579.321088497, -8237170.357457127 4976596.353709884, -8237199.623351257 4976618.427090839, -8237223.211951357 4976636.650159301, -8237247.691107381 4976655.461104335, -8237270.689714179 4976675.462469216, -8237301.859171603 4976705.765864197, -8237317.566351755 4976718.272287878, -8237332.271656486 4976728.809439882, -8237344.171710053 4976737.406706212, -8237358.81022309 4976746.944537027, -8237372.769687236 4976755.0862366455, -8237391.070611523 4976765.153148987, -8237395.489995309 4976767.84255944)" +1446,Lincoln Tunnel Expressway,"LINESTRING (-8237098.300350738 4976418.754453657, -8237094.771522879 4976424.2212588955, -8237090.385534942 4976432.201036549, -8237086.578408357 4976441.047869486, -8237083.984664222 4976449.365663242, -8237082.236948216 4976457.801030218)" +1447,Lincoln Tunnel Expressway,"LINESTRING (-8237408.080229716 4976203.258955028, -8237388.332152051 4976219.703104409, -8237371.266874112 4976229.299211521, -8237353.834241854 4976237.5580432555, -8237335.021247909 4976244.376728101, -8237319.2250121655 4976249.182140322, -8237275.020042373 4976262.114148253, -8237260.092098657 4976266.963655638, -8237247.83582272 4976271.489864704, -8237231.126767153 4976278.867002157, -8237217.957671391 4976285.685715831, -8237204.510276904 4976293.136341603, -8237193.244744436 4976299.984456296, -8237183.971830852 4976308.140478986, -8237173.975340579 4976317.7954551885, -8237165.470531483 4976327.406354217, -8237157.700431025 4976336.679264229, -8237112.348870476 4976392.978214258, -8237098.300350738 4976418.754453657)" +1448,West 31st Street,"LINESTRING (-8237573.779291763 4975860.877184711, -8237582.896358059 4975865.65301856)" +1449,Lincoln Tunnel Expressway,"LINESTRING (-8237573.779291763 4975860.877184711, -8237569.426699672 4975868.94467156, -8237567.957282393 4975871.575055779, -8237480.48242653 4976032.250259206, -8237469.918206853 4976058.5398777565, -8237460.945855894 4976088.3123316355, -8237454.901207543 4976106.60788754, -8237448.7897675 4976123.624989567, -8237441.442681107 4976141.244628166, -8237430.154884743 4976164.463216295, -8237420.5702765845 4976181.3187702205, -8237408.080229716 4976203.258955028)" +1450,Lincoln Tunnel Expressway,"LINESTRING (-8237281.420913092 4976648.054290406, -8237260.581904416 4976624.393672415, -8237253.76915158 4976617.280802183, -8237247.958274159 4976611.564056929, -8237242.136264793 4976606.640898531, -8237235.946901103 4976602.717069583, -8237228.900377337 4976598.719762313, -8237150.687303105 4976555.322630932, -8237139.332715045 4976549.003389817, -8237132.542226107 4976544.330093203, -8237125.384382848 4976538.775045417, -8237117.413907307 4976531.5593663715, -8237112.18189124 4976526.680335903, -8237108.218917367 4976522.315663119, -8237105.0463118795 4976517.730554418, -8237100.504476655 4976510.896982942)" +1451,,"LINESTRING (-8237281.420913092 4976648.054290406, -8237272.192527306 4976627.465140705, -8237258.544757735 4976610.006281168, -8237250.307115415 4976599.116553771, -8237241.434951998 4976589.71113097, -8237228.666606406 4976579.394568248, -8237202.350678783 4976558.2324224, -8237191.9089105455 4976551.354734871, -8237184.439372712 4976547.475015835, -8237176.37984158 4976545.3881979, -8237167.719185196 4976544.506443977, -8237159.659654061 4976544.212526021, -8237152.791241481 4976545.3881979, -8237145.922828898 4976547.783629793, -8237139.956104193 4976551.354734871, -8237135.180498038 4976555.543069649, -8237127.599640714 4976564.948459555, -8237112.938863777 4976578.821426195)" +1452,,"LINESTRING (-8237281.420913092 4976648.054290406, -8237263.609794566 4976633.784432571, -8237223.601569574 4976609.006953452, -8237164.134697592 4976576.602338047, -8237151.655782674 4976573.854196467, -8237138.76498564 4976574.765344927, -8237127.343605886 4976578.057236842, -8237118.2710673865 4976582.686461723, -8237103.198408334 4976595.075160052)" +1453,Lincoln Tunnel,"LINESTRING (-8237281.420913092 4976648.054290406, -8237291.896077176 4976660.134454111, -8237306.734965299 4976673.91937936, -8237322.1304508755 4976686.1759283785, -8237337.815367128 4976695.978239441, -8237523.819104295 4976798.175633532, -8237548.966177266 4976806.699479446, -8237588.740631325 4976814.826532559, -8237611.616786683 4976822.953592434, -8237637.576491936 4976834.725349377)" +1454,Lincoln Tunnel Expressway,"LINESTRING (-8237100.504476655 4976510.896982942, -8237097.30960727 4976495.672096799, -8237096.073960922 4976487.060347381, -8237094.983029911 4976478.889479525, -8237094.415300509 4976470.718618505, -8237094.526619999 4976462.88576714, -8237095.172273045 4976456.169800148, -8237096.875461255 4976447.3229535185, -8237098.979399631 4976441.136043941, -8237101.651067411 4976435.0667041475, -8237105.068575778 4976429.144325371, -8237109.454563715 4976422.060988718, -8237114.441676903 4976416.138617823, -8237119.618033224 4976411.083296625, -8237127.210022497 4976404.191016995)" +1455,Lincoln Tunnel Expressway,"LINESTRING (-8237100.504476655 4976510.896982942, -8237105.0463118795 4976517.730554418, -8237108.218917367 4976522.315663119, -8237112.18189124 4976526.680335903, -8237117.413907307 4976531.5593663715, -8237125.384382848 4976538.775045417, -8237132.542226107 4976544.330093203, -8237139.332715045 4976549.003389817, -8237150.687303105 4976555.322630932, -8237228.900377337 4976598.719762313, -8237235.946901103 4976602.717069583, -8237242.136264793 4976606.640898531, -8237247.958274159 4976611.564056929, -8237253.76915158 4976617.280802183, -8237260.581904416 4976624.393672415, -8237281.420913092 4976648.054290406)" +1456,,"LINESTRING (-8237127.210022497 4976404.191016995, -8237153.681797407 4976390.171341668, -8237224.013451691 4976348.42104405, -8237252.399921843 4976330.154426472)" +1457,Lincoln Tunnel Expressway,"LINESTRING (-8237127.210022497 4976404.191016995, -8237148.115822867 4976382.60307666, -8237190.984958772 4976347.304178279, -8237214.261864298 4976327.230007361, -8237235.334643904 4976312.931227022, -8237245.921127479 4976306.259449725, -8237262.852822028 4976296.38405205, -8237277.45793922 4976288.580731481, -8237305.922333017 4976274.972695836, -8237358.454000721 4976250.328385788, -8237377.367182208 4976240.879212435, -8237386.439720707 4976235.677027585, -8237396.124516406 4976229.240429824, -8237404.083859996 4976223.56799787, -8237412.054335538 4976217.175494304, -8237422.19554115 4976207.652876059)" +1458,,"LINESTRING (-8237422.19554115 4976207.652876059, -8237442.700591354 4976169.430237883, -8237452.953116455 4976149.562166683, -8237461.480189449 4976129.782307533, -8237466.745601365 4976114.4845390245, -8237476.608508249 4976082.625286298, -8237478.91282171 4976074.969088373, -8237481.250531014 4976068.723633855, -8237483.7886154065 4976064.638374, -8237486.40462344 4976062.757391619, -8237489.16534681 4976061.478911616, -8237494.953960332 4976059.289331306, -8237502.712928841 4976057.58469194)" +1459,Lincoln Tunnel Expressway,"LINESTRING (-8237422.19554115 4976207.652876059, -8237434.262573952 4976192.751760577, -8237444.526231002 4976179.628804914, -8237455.157242374 4976165.580061165)" +1460,Lincoln Tunnel Expressway,"LINESTRING (-8237455.157242374 4976165.580061165, -8237469.895942953 4976136.63030773, -8237478.077925527 4976118.8196391, -8237483.565976424 4976102.346269047, -8237487.094804283 4976086.56360158, -8237489.2210065555 4976071.809622646, -8237488.530825715 4976057.187922478, -8237489.154214862 4976046.769056009, -8237491.658903405 4976036.5118471235, -8237576.97416115 4975876.674182513, -8237578.566029866 4975873.705814465, -8237582.896358059 4975865.65301856)" +1461,West 31st Street,"LINESTRING (-8237582.896358059 4975865.65301856, -8237589.475339965 4975869.312043616, -8237686.367824751 4975923.242411167, -8237701.37369211 4975931.57445908)" +1462,Dyer Avenue,"LINESTRING (-8237582.896358059 4975865.65301856, -8237586.948387524 4975857.350416595, -8237601.108226752 4975825.932846821, -8237604.837429694 4975816.234272256, -8237606.329110869 4975812.0462543955, -8237607.5202294225 4975806.829603082)" +1463,Dyer Avenue,"LINESTRING (-8237607.5202294225 4975806.829603082, -8237604.8040338475 4975807.961101862, -8237601.887463189 4975809.327717448, -8237598.202788042 4975811.840527248, -8237596.777898561 4975814.1476104995, -8237595.286217384 4975816.08732423, -8237592.892848332 4975821.612571506)" +1464,Dyer Avenue,"LINESTRING (-8237592.892848332 4975821.612571506, -8237578.009432415 4975852.177825662, -8237573.779291763 4975860.877184711)" +1465,,"LINESTRING (-8237198.332045165 4976324.849325112, -8237173.541194564 4976346.172617036, -8237147.459037872 4976368.509954144, -8237136.995005737 4976377.47429458, -8237117.202400274 4976398.136395833, -8237098.300350738 4976418.754453657)" +1466,West 36th Street,"LINESTRING (-8237241.223444967 4976287.963519951, -8237233.709379338 4976283.89286393, -8237167.6857893495 4976247.227645158, -8237140.880055966 4976232.091342464, -8237128.312085455 4976224.978757841)" +1467,,"LINESTRING (-8237241.223444967 4976287.963519951, -8237232.763163666 4976295.737448979, -8237213.00395405 4976315.326601919, -8237198.332045165 4976324.849325112)" +1468,Dyer Avenue,"LINESTRING (-8237252.399921843 4976330.154426472, -8237258.9566398505 4976318.162844121, -8237263.131120755 4976311.873147497, -8237269.220296901 4976303.467297585)" +1469,West 33rd Street,"LINESTRING (-8237475.406257749 4976042.110694766, -8237502.712928841 4976057.58469194)" +1470,,"LINESTRING (-8237475.406257749 4976042.110694766, -8237477.031522315 4976046.151859755, -8237478.233772815 4976049.619915404, -8237478.578863236 4976055.468588317, -8237477.955474088 4976060.317993135, -8237476.341341471 4976066.0638062, -8237461.903203515 4976111.95695614, -8237456.782506938 4976127.107767988, -8237448.511468773 4976147.196223026, -8237437.568762829 4976165.844577074, -8237425.112111809 4976184.478271359, -8237408.080229716 4976203.258955028)" +1471,West 33rd Street,"LINESTRING (-8237502.712928841 4976057.58469194, -8237586.135755242 4976103.639449635, -8237601.620296411 4976112.192080101)" +1472,,"LINESTRING (-8237317.020886249 4976584.611632081, -8237290.716090574 4976582.745245546, -8237279.662065138 4976580.026494142, -8237265.624677349 4976576.190851558, -8237255.294228605 4976572.898960272, -8237244.896988163 4976569.621766033, -8237234.833706196 4976565.124810703, -8237205.990826131 4976549.635313744, -8237188.23536735 4976541.199867476, -8237178.606231397 4976538.657478303, -8237170.290665434 4976537.0703223925, -8237162.531696925 4976536.61474991, -8237153.960096135 4976537.4083277965, -8237145.4998148335 4976540.391593389, -8237138.520082761 4976543.962695765, -8237132.7092053415 4976548.312682315, -8237128.12284232 4976553.632600931, -8237123.024409642 4976561.112822892, -8237112.938863777 4976578.821426195)" +1473,,"LINESTRING (-8237317.020886249 4976584.611632081, -8237293.577001487 4976574.64777738, -8237280.6082808105 4976570.591697846, -8237265.591281502 4976564.889675842, -8237253.090102687 4976559.848973592, -8237242.024945301 4976554.249829245, -8237201.371067263 4976531.191969414)" +1474,,"LINESTRING (-8237112.938863777 4976578.821426195, -8237103.198408334 4976595.075160052)" +1475,East 41st Street,"LINESTRING (-8235225.271994498 4975758.572036783, -8235198.510788909 4975743.671606189)" +1476,East 61st Street,"LINESTRING (-8233464.119726503 4977220.7322043665, -8233470.943611289 4977224.200677003, -8233491.838279712 4977235.781857267, -8233556.381320475 4977271.539572817, -8233572.277743758 4977280.34307486)" +1477,11th Avenue,"LINESTRING (-8237607.086083409 4976846.291371574, -8237612.251307782 4976836.679962076, -8237651.625011674 4976765.03557915, -8237656.623256811 4976755.497730671)" +1478,11th Avenue,"LINESTRING (-8237607.086083409 4976846.291371574, -8237599.026552275 4976854.565421268, -8237590.62193072 4976862.854174345, -8237581.605051966 4976879.549272817, -8237561.923765994 4976916.011114362, -8237559.274362111 4976918.788745113, -8237556.8921250105 4976920.346570113, -8237554.020082147 4976920.90503574, -8237551.526525554 4976920.53762414, -8237548.109017186 4976919.641139894, -8237523.039867859 4976906.179189638, -8237431.657697867 4976857.107892652, -8237427.6279323 4976853.845299435, -8237424.689097744 4976849.436391411, -8237423.542506989 4976845.306716037, -8237423.598166734 4976841.368094887, -8237424.889472826 4976838.0467215665, -8237427.216050183 4976835.371988121, -8237429.887717964 4976833.285108688, -8237434.251442003 4976830.948392107, -8237439.928736033 4976829.331796057, -8237455.457804998 4976827.891556164, -8237475.896063508 4976826.862813516)" +1479,12th Avenue,"LINESTRING (-8237409.126632932 4977803.232417013, -8237453.053303998 4977723.849966279, -8237498.393732598 4977641.763811304)" +1480,,"LINESTRING (-8237433.171642941 4976768.665548581, -8237464.663926887 4976768.107091658)" +1481,,"LINESTRING (-8237433.171642941 4976768.665548581, -8237446.240551161 4976780.731165172, -8237456.7602430405 4976789.857542795, -8237465.454295273 4976797.0881089, -8237473.491562507 4976803.613258514, -8237490.367597311 4976816.193288989)" +1482,,"LINESTRING (-8237201.371067263 4976531.191969414, -8237176.413237427 4976521.125298155, -8237162.208870402 4976519.317707187, -8237148.783739811 4976522.007049967, -8237138.019145052 4976527.238779025, -8237128.779627318 4976535.747692665, -8237122.590263628 4976547.283969105, -8237112.938863777 4976578.821426195)" +1483,Dyer Avenue,"LINESTRING (-8237201.371067263 4976531.191969414, -8237195.526793998 4976526.548073062, -8237190.561944707 4976521.904178917, -8237186.498783293 4976517.554204126, -8237183.03674713 4976512.043259113, -8237180.977336551 4976506.458838006, -8237178.750946734 4976499.669361906, -8237177.481904538 4976492.923977986, -8237176.925307084 4976484.914759118, -8237176.7471958995 4976476.670414076, -8237177.237001658 4976471.394624732, -8237178.038501992 4976467.04467243, -8237178.183217331 4976466.2364044795, -8237179.964329182 4976460.975316542, -8237185.274268895 4976450.820543088, -8237229.612822078 4976371.111081586, -8237252.399921843 4976330.154426472)" +1484,,"LINESTRING (-8237103.198408334 4976595.075160052, -8237091.198167225 4976616.590089855, -8237064.737524263 4976662.809139579)" +1485,1st Avenue,"LINESTRING (-8233989.224896526 4975938.583965206, -8233979.929719045 4975945.284881425, -8233974.552987639 4975949.840331479, -8233965.524976935 4975963.15401381, -8233941.936376836 4976004.535287962, -8233937.76189593 4976010.442714265, -8233930.7265041135 4976017.5110573955)" +1486,East 49th Street,"LINESTRING (-8233920.073228844 4976011.677102301, -8233930.7265041135 4976017.5110573955)" +1487,1st Avenue,"LINESTRING (-8233920.073228844 4976011.677102301, -8233915.698372857 4976019.9945305195, -8233913.494246938 4976024.2561130915)" +1488,East 47th Street,"LINESTRING (-8234019.203235396 4975807.461479008, -8234032.327803359 4975815.661174969, -8234034.320422245 4975817.17473967, -8234036.32417308 4975819.085064386, -8234038.116416881 4975821.3039804865, -8234041.622980842 4975830.547020524, -8234045.597086662 4975837.48298)" +1489,1st Avenue,"LINESTRING (-8234019.203235396 4975807.461479008, -8234008.060154367 4975817.439246147, -8233991.47355024 4975847.857538745)" +1490,Riverside Boulevard,"LINESTRING (-8236342.307424862 4979783.343252639, -8236317.104692147 4979854.0248198435, -8236311.616641251 4979867.329123793, -8236306.42915298 4979880.11891374)" +1491,Riverside Boulevard,"LINESTRING (-8236342.307424862 4979783.343252639, -8236346.626621104 4979770.347778906, -8236351.212984127 4979755.044307692, -8236368.31165791 4979690.861134397, -8236371.050117385 4979680.45309199)" +1492,,"LINESTRING (-8236194.6643842235 4980049.813080157, -8236197.747934118 4980061.956256674, -8236205.384451186 4980089.815054046, -8236206.041236184 4980093.181637052, -8236206.185951521 4980096.724636143, -8236205.70727771 4980100.370545263, -8236204.582950853 4980103.707729402, -8236203.002214083 4980107.441848687, -8236186.86088792 4980135.9329318255, -8236177.087036627 4980152.986457892, -8236172.400486065 4980163.65962815, -8236166.122066783 4980184.976600914)" +1493,West 72nd Street,"LINESTRING (-8236194.6643842235 4980049.813080157, -8236187.695784099 4980051.239094051, -8236179.83662805 4980051.621324615, -8236172.701048689 4980051.547818735, -8236166.133198733 4980050.974472901, -8236160.990238259 4980050.121804797, -8236154.734082876 4980048.254755936, -8236146.496440557 4980045.402729229, -8236111.475328755 4980025.732588342, -8236087.775409162 4980011.987035083, -8236056.995569959 4979995.47769562, -8236048.913774927 4979991.390793099)" +1494,Riverside Boulevard,"LINESTRING (-8236194.6643842235 4980049.813080157, -8236199.929796137 4980047.534398597, -8236206.308402961 4980044.667670935, -8236212.531162496 4980041.271702334, -8236218.842977624 4980037.0083668, -8236224.008201997 4980032.524515919, -8236229.039842981 4980026.55585204, -8236234.00469227 4980019.396400426, -8236238.791430375 4980011.3107837625, -8236255.934631955 4979979.629932079)" +1495,Riverside Boulevard,"LINESTRING (-8236486.054283323 4979382.946536249, -8236481.044906237 4979391.149234103, -8236478.261918969 4979395.691591255, -8236468.632783014 4979413.537636249, -8236441.459695311 4979468.193189457, -8236435.159012133 4979480.365043382)" +1496,Riverside Boulevard,"LINESTRING (-8236486.054283323 4979382.946536249, -8236490.874417276 4979374.90554701, -8236496.329072325 4979366.011956022, -8236506.114055565 4979350.253414688, -8236515.409233046 4979336.126609605, -8236538.352180098 4979304.565548658, -8236545.198328783 4979295.14282038)" +1497,West 65th Street,"LINESTRING (-8236486.054283323 4979382.946536249, -8236475.523459495 4979377.301672911, -8236455.7865137765 4979366.702862801)" +1498,West 71st Street,"LINESTRING (-8236171.621249629 4979930.675500277, -8235984.67129679 4979825.402251686, -8235969.754485025 4979817.155086599)" +1499,West 71st Street,"LINESTRING (-8236190.868389587 4979942.406900312, -8236240.361035193 4979970.309459783, -8236246.427947442 4979973.690702647, -8236255.934631955 4979979.629932079)" +1500,Thelonius Monk Circle,"LINESTRING (-8236439.667451509 4979236.401649085, -8236444.109099193 4979228.434280188, -8236445.055314864 4979226.72908769, -8236485.219387143 4979154.537978397, -8236490.317819821 4979145.379991474)" +1501,West 64th Street,"LINESTRING (-8236439.667451509 4979236.401649085, -8236341.394605038 4979181.703293494, -8236325.442522007 4979172.824578298)" +1502,West 63rd Street,"LINESTRING (-8236490.317819821 4979145.379991474, -8236392.167424789 4979089.888360327, -8236376.037230573 4979081.171425466)" +1503,Thelonius Monk Circle,"LINESTRING (-8236490.317819821 4979145.379991474, -8236485.219387143 4979154.537978397, -8236445.055314864 4979226.72908769, -8236444.109099193 4979228.434280188, -8236439.667451509 4979236.401649085)" +1504,West 63rd Street,"LINESTRING (-8236490.317819821 4979145.379991474, -8236500.937699243 4979151.304017347, -8236603.808040684 4979208.795184617, -8236613.158877911 4979215.615943872)" +1505,Riverside Boulevard,"LINESTRING (-8236545.198328783 4979295.14282038, -8236538.352180098 4979304.565548658, -8236515.409233046 4979336.126609605, -8236506.114055565 4979350.253414688, -8236496.329072325 4979366.011956022, -8236490.874417276 4979374.90554701, -8236486.054283323 4979382.946536249)" +1506,Riverside Boulevard,"LINESTRING (-8236545.198328783 4979295.14282038, -8236550.786567219 4979288.233805421, -8236585.384664959 4979245.456821624, -8236603.61879755 4979225.86179162, -8236613.158877911 4979215.615943872)" +1507,West 64th Street,"LINESTRING (-8236545.198328783 4979295.14282038, -8236534.934671731 4979289.439207679, -8236456.34311123 4979245.692021022, -8236449.619413988 4979241.943531281, -8236439.667451509 4979236.401649085)" +1508,West 62nd Street,"LINESTRING (-8236689.023110887 4979134.810832651, -8236678.3920995165 4979129.401309334, -8236609.084584548 4979090.5939473, -8236591.117618735 4979080.701034599, -8236565.992809662 4979066.66281758, -8236557.510264465 4979062.150012834)" +1509,Riverside Boulevard,"LINESTRING (-8236689.023110887 4979134.810832651, -8236620.338985069 4979207.971989857, -8236613.158877911 4979215.615943872)" +1510,"['Riverside Boulevard', 'West 61st Street']","LINESTRING (-8236689.023110887 4979134.810832651, -8236752.953894449 4979065.780836032, -8236762.148884388 4979055.843849435, -8236659.111563711 4979000.440924586, -8236657.018757283 4978999.235557997, -8236601.759762054 4978967.484491681, -8236591.618556444 4978961.663474054)" +1511,East 46th Street,"LINESTRING (-8234962.346489193 4976231.856215618, -8234937.299603763 4976217.542879454)" +1512,Park Avenue,"LINESTRING (-8234962.346489193 4976231.856215618, -8234968.201894408 4976224.596676995, -8234970.829034392 4976221.348990411, -8235001.386234615 4976164.272177053, -8235004.558840102 4976162.523433401, -8235007.842765081 4976161.671104676, -8235012.473655897 4976162.773253905, -8235043.643113318 4976179.981493302, -8235046.481760334 4976181.010167837, -8235048.908525234 4976181.3187702205, -8235051.48000547 4976181.098339945, -8235053.439228509 4976180.672174764, -8235055.086756972 4976179.702281661, -8235056.344667218 4976178.0857933685, -8235138.264680493 4976031.059953948, -8235195.226863932 4975928.826498929, -8235196.32892689 4975925.946284845, -8235197.631364933 4975922.05211919, -8235197.90966366 4975917.952225707, -8235197.564573239 4975913.98458849, -8235196.017232317 4975909.517324811, -8235193.946689787 4975906.357912587, -8235190.184090999 4975902.757653391, -8235187.222992545 4975900.37707457, -8235180.721934282 4975896.45352926, -8235150.331713295 4975877.173808907, -8235149.073803049 4975875.557370666, -8235148.417018053 4975873.911542915, -8235148.294566615 4975871.707309754, -8235148.439281952 4975869.885144048, -8235150.910574647 4975858.687649356)" +1513,East 49th Street,"LINESTRING (-8234806.799764708 4976506.150225353, -8234819.300943523 4976513.057272763, -8234964.094205197 4976593.017723891, -8234976.038786559 4976599.689697015)" +1514,Park Avenue,"LINESTRING (-8234806.799764708 4976506.150225353, -8234811.185752645 4976498.229170612, -8234853.008485336 4976422.898644444, -8234857.4835288655 4976414.8747872785)" +1515,East 50th Street,"LINESTRING (-8234756.5278826635 4976597.32364435, -8234737.169423216 4976586.28697148)" +1516,Park Avenue,"LINESTRING (-8234756.5278826635 4976597.32364435, -8234760.624439926 4976590.093226096, -8234802.558492109 4976513.880240439, -8234806.799764708 4976506.150225353)" +1517,Park Avenue,"LINESTRING (-8234705.098277918 4976690.3496248415, -8234709.684640939 4976682.119802542, -8234751.819068206 4976605.656267149, -8234756.5278826635 4976597.32364435)" +1518,East 51st Street,"LINESTRING (-8234705.098277918 4976690.3496248415, -8234717.810963767 4976697.315586991, -8234826.46991873 4976757.45232752, -8234862.927051964 4976777.336331226, -8234874.203716383 4976783.670416293)" +1519,East 48th Street,"LINESTRING (-8234857.4835288655 4976414.8747872785, -8234837.969222129 4976403.808929143)" +1520,Park Avenue,"LINESTRING (-8234857.4835288655 4976414.8747872785, -8234862.203475274 4976406.263109081, -8234904.304506692 4976329.816428239, -8234908.545779292 4976322.115949913)" +1521,East 53rd Street,"LINESTRING (-8234603.7307496015 4976873.318000332, -8234616.332115959 4976880.240003738, -8234761.258961024 4976959.762564551, -8234773.726743992 4976966.596450008)" +1522,Park Avenue,"LINESTRING (-8234603.7307496015 4976873.318000332, -8234608.239188978 4976864.999845615, -8234649.9951299755 4976790.357215892, -8234653.991499695 4976783.2148323115)" +1523,East 55th Street,"LINESTRING (-8234501.327950021 4977059.082170018, -8234513.584225957 4977065.88673159, -8234658.934085087 4977146.645335084, -8234671.223756869 4977152.671026532)" +1524,Park Avenue,"LINESTRING (-8234501.327950021 4977059.082170018, -8234506.67128558 4977049.4852478225, -8234548.438358525 4976974.268043252, -8234552.913402054 4976966.199643626)" +1525,East 52nd Street,"LINESTRING (-8234653.991499695 4976783.2148323115, -8234634.621908297 4976772.207341919)" +1526,Park Avenue,"LINESTRING (-8234653.991499695 4976783.2148323115, -8234659.156724067 4976773.823928515, -8234700.8124775225 4976698.065089542, -8234705.098277918 4976690.3496248415)" +1527,East 54th Street,"LINESTRING (-8234552.913402054 4976966.199643626, -8234533.5326787075 4976954.971499315)" +1528,Park Avenue,"LINESTRING (-8234552.913402054 4976966.199643626, -8234557.92277914 4976957.043708224, -8234598.598921075 4976882.53264289, -8234603.7307496015 4976873.318000332)" +1529,Park Avenue,"LINESTRING (-8234190.011862069 4977624.259046362, -8234236.06473541 4977540.571711926, -8234240.328271908 4977532.8114896305)" +1530,East 61st Street,"LINESTRING (-8234190.011862069 4977624.259046362, -8234201.778332245 4977630.799446048, -8234346.382350786 4977711.107092693, -8234347.339698408 4977711.63620822, -8234358.037501472 4977717.588759879)" +1531,East 57th Street,"LINESTRING (-8234397.166302486 4977248.700474294, -8234377.429356768 4977237.751247154)" +1532,East 57th Street,"LINESTRING (-8234397.166302486 4977248.700474294, -8234409.344654778 4977255.505167947, -8234553.559055102 4977336.147762326, -8234566.03797002 4977343.128882087)" +1533,Park Avenue,"LINESTRING (-8234397.166302486 4977248.700474294, -8234405.0031946385 4977234.370951323, -8234446.503100807 4977158.417482084, -8234450.989276285 4977150.216659078)" +1534,East 58th Street,"LINESTRING (-8234342.107682341 4977348.184685618, -8234321.981118403 4977336.882616802)" +1535,Park Avenue,"LINESTRING (-8234342.107682341 4977348.184685618, -8234347.083663577 4977339.263545687, -8234388.884132371 4977263.676685381, -8234397.166302486 4977248.700474294)" +1536,East 59th Street,"LINESTRING (-8234291.9359878395 4977439.1161104115, -8234272.009798986 4977427.6963585755)" +1537,Park Avenue,"LINESTRING (-8234291.9359878395 4977439.1161104115, -8234296.032545102 4977431.502941038, -8234337.955465333 4977356.062338196, -8234342.107682341 4977348.184685618)" +1538,East 56th Street,"LINESTRING (-8234450.989276285 4977150.216659078, -8234431.853455817 4977139.590871769)" +1539,Park Avenue,"LINESTRING (-8234450.989276285 4977150.216659078, -8234455.698090745 4977141.633726248, -8234497.042149626 4977066.812622625, -8234501.327950021 4977059.082170018)" +1540,East 64th Street,"LINESTRING (-8234037.170201209 4977900.54698101, -8234017.032505324 4977889.45004398)" +1541,Park Avenue,"LINESTRING (-8234037.170201209 4977900.54698101, -8234041.89014762 4977891.992784729, -8234083.278734296 4977816.960164163, -8234088.087736299 4977808.273760887)" +1542,Park Avenue,"LINESTRING (-8233884.562311282 4978176.298891724, -8233889.349049386 4978167.23001205, -8233931.160650127 4978092.739111573, -8233935.6245617075 4978084.25823805)" +1543,East 67th Street,"LINESTRING (-8233884.562311282 4978176.298891724, -8233896.918774758 4978183.001343053, -8233980.1412260765 4978229.5217734305, -8234041.7676961785 4978263.798579859, -8234052.89964526 4978269.957246935)" +1544,Park Avenue,"LINESTRING (-8233935.6245617075 4978084.25823805, -8233939.72111897 4978076.379998183, -8233981.554983609 4978000.625754838, -8233985.384374092 4977993.64416516)" +1545,East 66th Street,"LINESTRING (-8233935.6245617075 4978084.25823805, -8233947.1016012095 4978090.637265283, -8234092.952398046 4978172.00697355, -8234103.594541366 4978177.901012348)" +1546,East 62nd Street,"LINESTRING (-8234139.305834013 4977716.339458613, -8234118.956631095 4977705.110452051)" +1547,Park Avenue,"LINESTRING (-8234139.305834013 4977716.339458613, -8234143.93672483 4977707.917702483, -8234190.011862069 4977624.259046362)" +1548,East 63rd Street,"LINESTRING (-8234088.087736299 4977808.273760887, -8234099.019310295 4977814.299860477, -8234245.582551872 4977895.064651603, -8234256.51412587 4977901.149596495)" +1549,Park Avenue,"LINESTRING (-8234088.087736299 4977808.273760887, -8234092.42919644 4977800.469232552, -8234134.519095908 4977724.937594091, -8234139.305834013 4977716.339458613)" +1550,East 70th Street,"LINESTRING (-8233732.421963215 4978451.500034412, -8233712.495774361 4978440.226086416)" +1551,Park Avenue,"LINESTRING (-8233732.421963215 4978451.500034412, -8233736.986062335 4978443.797883395, -8233778.552760198 4978368.349461861, -8233783.239310761 4978359.706664104)" +1552,East 68th Street,"LINESTRING (-8233833.8896790715 4978267.928854964, -8233813.885566575 4978256.787405122)" +1553,Park Avenue,"LINESTRING (-8233833.8896790715 4978267.928854964, -8233838.208875315 4978260.021069994, -8233879.920288513 4978184.882733727, -8233884.562311282 4978176.298891724)" +1554,Park Avenue,"LINESTRING (-8233680.7585875355 4978545.146329679, -8233685.957207756 4978535.739032956, -8233727.646357059 4978460.142913395, -8233732.421963215 4978451.500034412)" +1555,East 71st Street,"LINESTRING (-8233680.7585875355 4978545.146329679, -8233693.315426098 4978552.098915738, -8233838.01963218 4978631.884972185, -8233849.496671681 4978638.161463749)" +1556,Park Avenue,"LINESTRING (-8233783.239310761 4978359.706664104, -8233787.625298699 4978351.9751882395, -8233829.425767491 4978276.365792455, -8233833.8896790715 4978267.928854964)" +1557,East 69th Street,"LINESTRING (-8233783.239310761 4978359.706664104, -8233794.994648988 4978366.247556262, -8233939.776778715 4978446.825827535, -8233952.2890894795 4978453.793042376)" +1558,East 65th Street,"LINESTRING (-8233985.384374092 4977993.64416516, -8233965.513844986 4977982.223765016)" +1559,Park Avenue,"LINESTRING (-8233985.384374092 4977993.64416516, -8233990.916952785 4977983.899344123, -8234032.628365985 4977908.733736012, -8234037.170201209 4977900.54698101)" +1560,East 76th Street,"LINESTRING (-8233415.840463346 4979024.695283891, -8233396.025593986 4979013.788164557)" +1561,Park Avenue,"LINESTRING (-8233415.840463346 4979024.695283891, -8233420.404562468 4979016.478194205, -8233462.861816258 4978940.02578238, -8233467.737609955 4978931.26488281)" +1562,Park Avenue,"LINESTRING (-8233467.737609955 4978931.26488281, -8233472.14586179 4978923.180167026, -8233514.2468932085 4978846.155210432, -8233518.911179871 4978837.585486593)" +1563,East 75th Street,"LINESTRING (-8233467.737609955 4978931.26488281, -8233480.038413686 4978938.10014774, -8233623.629424861 4979017.830559117, -8233635.98588834 4979024.709983522)" +1564,East 77th Street,"LINESTRING (-8233363.709545809 4979119.287860734, -8233375.709786916 4979125.829261612, -8233520.3026735075 4979206.252101027, -8233533.605352658 4979213.646155151)" +1565,Park Avenue,"LINESTRING (-8233363.709545809 4979119.287860734, -8233368.88590213 4979109.8800109755, -8233411.254100326 4979033.000578348, -8233415.840463346 4979024.695283891)" +1566,East 72nd Street,"LINESTRING (-8233625.900342474 4978644.540852748, -8233603.736631857 4978632.031962573)" +1567,East 72nd Street,"LINESTRING (-8233625.900342474 4978644.540852748, -8233637.889451632 4978651.317120743, -8233782.315358988 4978731.2803779775, -8233794.449183485 4978737.806819782)" +1568,Park Avenue,"LINESTRING (-8233625.900342474 4978644.540852748, -8233633.870818016 4978630.459165531, -8233676.9848568 4978552.0254211435, -8233680.7585875355 4978545.146329679)" +1569,East 73rd Street,"LINESTRING (-8233570.385312416 4978744.994730327, -8233582.7974356385 4978751.829864896, -8233726.544294099 4978830.838488039, -8233739.023209019 4978837.703081381)" +1570,Park Avenue,"LINESTRING (-8233570.385312416 4978744.994730327, -8233574.68224476 4978737.233551068, -8233617.84081134 4978659.0341344895, -8233625.900342474 4978644.540852748)" +1571,East 83rd Street,"LINESTRING (-8233047.439740516 4979691.669669228, -8233059.7294123 4979698.329058664, -8233203.943812622 4979778.653707522, -8233215.8216022905 4979785.07794388)" +1572,Park Avenue,"LINESTRING (-8233047.439740516 4979691.669669228, -8233051.825728453 4979683.790132628, -8233094.305246139 4979607.185491548, -8233099.214435684 4979598.335790501)" +1573,East 78th Street,"LINESTRING (-8233312.769746822 4979210.485674075, -8233293.099592798 4979199.578347242)" +1574,Park Avenue,"LINESTRING (-8233312.769746822 4979210.485674075, -8233316.866304083 4979203.370920421, -8233359.21223838 4979127.402138432, -8233363.709545809 4979119.287860734)" +1575,East 80th Street,"LINESTRING (-8233202.307416108 4979411.744210156, -8233182.247643867 4979400.425053059)" +1576,Park Avenue,"LINESTRING (-8233202.307416108 4979411.744210156, -8233206.559820656 4979403.835499012, -8233249.295373171 4979325.998246841, -8233257.020945832 4979311.91557703)" +1577,East 79th Street,"LINESTRING (-8233257.020945832 4979311.91557703, -8233237.272868166 4979300.949336731)" +1578,Park Avenue,"LINESTRING (-8233257.020945832 4979311.91557703, -8233265.113872814 4979298.597329692, -8233307.96074482 4979219.526122662, -8233312.769746822 4979210.485674075)" +1579,East 79th Street,"LINESTRING (-8233257.020945832 4979311.91557703, -8233269.477596851 4979318.927509252, -8233307.504334907 4979340.330838742, -8233323.289438701 4979349.16560587, -8233372.125299313 4979376.125660125, -8233380.106906801 4979380.579809295, -8233404.3077641 4979394.192172156, -8233412.088996506 4979398.440526868, -8233427.172787509 4979406.687338351)" +1580,East 81st Street,"LINESTRING (-8233150.443665346 4979505.473215105, -8233162.955976113 4979512.323582298, -8233307.493202957 4979591.441261522, -8233319.382124575 4979598.071181624)" +1581,Park Avenue,"LINESTRING (-8233150.443665346 4979505.473215105, -8233154.851917183 4979497.53502737, -8233197.665393341 4979420.314437827, -8233202.307416108 4979411.744210156)" +1582,East 88th Street,"LINESTRING (-8232783.100477678 4980170.275235407, -8232762.962781794 4980159.087511088)" +1583,Park Avenue,"LINESTRING (-8232783.100477678 4980170.275235407, -8232787.809292139 4980162.013077708, -8232829.309198307 4980086.463173428, -8232834.006880818 4980078.112879346)" +1584,East 87th Street,"LINESTRING (-8232834.006880818 4980078.112879346, -8232845.918066333 4980084.684324971, -8232990.577744619 4980165.335581564, -8233001.253283785 4980171.201420781)" +1585,Park Avenue,"LINESTRING (-8232834.006880818 4980078.112879346, -8232838.704563329 4980069.556775565, -8232881.128421271 4979993.1843256485, -8232888.798334186 4979978.659661678)" +1586,East 84th Street,"LINESTRING (-8232995.865420432 4979784.930936137, -8232975.81678014 4979773.773054808)" +1587,Park Avenue,"LINESTRING (-8232995.865420432 4979784.930936137, -8233000.251408369 4979776.992521235, -8233042.653002412 4979700.313645799, -8233047.439740516 4979691.669669228)" +1588,East 82nd Street,"LINESTRING (-8233099.214435684 4979598.335790501, -8233078.943156411 4979587.339827615)" +1589,Park Avenue,"LINESTRING (-8233099.214435684 4979598.335790501, -8233103.533631927 4979590.471029689, -8233145.389760465 4979514.646240077, -8233150.443665346 4979505.473215105)" +1590,Park Avenue,"LINESTRING (-8232944.73637831 4979877.266936139, -8232949.122366248 4979869.857678639, -8232961.356378285 4979848.659000727, -8232991.368113003 4979793.222176368, -8232995.865420432 4979784.930936137)" +1591,East 85th Street,"LINESTRING (-8232944.73637831 4979877.266936139, -8232956.480584588 4979883.661835526, -8233101.30724211 4979964.664256913, -8233112.839941357 4979971.103316697)" +1592,Park Avenue,"LINESTRING (-8232528.256767404 4980631.658741963, -8232532.609359494 4980623.410895894, -8232574.543411678 4980547.342854346, -8232579.575052659 4980538.242368772)" +1593,East 93rd Street,"LINESTRING (-8232528.256767404 4980631.658741963, -8232539.711543008 4980637.980625129, -8232685.039138238 4980718.239493051, -8232696.338066553 4980724.752560733)" +1594,Park Avenue,"LINESTRING (-8232732.138414793 4980262.703088204, -8232736.5577985775 4980254.382046375, -8232778.202420083 4980179.066649321, -8232783.100477678 4980170.275235407)" +1595,East 89th Street,"LINESTRING (-8232732.138414793 4980262.703088204, -8232743.77130158 4980269.17174753, -8232855.224375763 4980330.815345588, -8232888.653618848 4980349.456987295, -8232900.59820021 4980356.116825335)" +1596,East 90th Street,"LINESTRING (-8232681.27653945 4980354.132104914, -8232661.261295006 4980342.885363484)" +1597,Park Avenue,"LINESTRING (-8232681.27653945 4980354.132104914, -8232685.707055182 4980346.619574235, -8232727.863746346 4980270.906525077, -8232732.138414793 4980262.703088204)" +1598,East 91st Street,"LINESTRING (-8232629.624295722 4980447.899559251, -8232641.502085388 4980454.500657302, -8232786.2619512165 4980534.905036123, -8232797.805782411 4980541.432683427)" +1599,Park Avenue,"LINESTRING (-8232629.624295722 4980447.899559251, -8232634.867443737 4980438.696254047, -8232676.322822109 4980363.320628769, -8232681.27653945 4980354.132104914)" +1600,East 86th Street,"LINESTRING (-8232888.798334186 4979978.659661678, -8232868.727429997 4979967.663270532)" +1601,East 86th Street,"LINESTRING (-8232888.798334186 4979978.659661678, -8232900.587068262 4979985.319246829, -8233036.485902622 4980061.250599513, -8233044.422982315 4980065.631555206, -8233056.1003968995 4980072.114785189)" +1602,Park Avenue,"LINESTRING (-8232888.798334186 4979978.659661678, -8232896.9580528615 4979964.355534974, -8232906.242098394 4979948.331409698, -8232939.626813683 4979886.48441314, -8232944.73637831 4979877.266936139)" +1603,East 92nd Street,"LINESTRING (-8232579.575052659 4980538.242368772, -8232557.255494758 4980525.819264029)" +1604,Park Avenue,"LINESTRING (-8232579.575052659 4980538.242368772, -8232583.560290431 4980531.27366665, -8232625.04906465 4980456.088449929, -8232629.624295722 4980447.899559251)" +1605,East 74th Street,"LINESTRING (-8233518.911179871 4978837.585486593, -8233499.085178562 4978826.531582901)" +1606,Park Avenue,"LINESTRING (-8233518.911179871 4978837.585486593, -8233523.464147046 4978829.36855433, -8233566.021588375 4978752.873509519, -8233570.385312416 4978744.994730327)" +1607,West 60th Street,"LINESTRING (-8235638.111458053 4978313.47958486, -8235645.324961057 4978315.228713606, -8235653.451283886 4978318.094933656, -8235660.842898073 4978321.402111682)" +1608,Broadway,"LINESTRING (-8235638.111458053 4978313.47958486, -8235638.322965086 4978326.0321628, -8235638.957486182 4978364.513117014, -8235639.1467293175 4978375.3460180275, -8235639.937097702 4978420.617973182, -8235640.070681091 4978431.083468001)" +1609,West 63rd Street,"LINESTRING (-8235644.412141231 4978673.630331449, -8235666.9988659145 4978685.433717147)" +1610,Broadway,"LINESTRING (-8235644.412141231 4978673.630331449, -8235644.91307894 4978687.3152046045, -8235645.536468089 4978732.294622024, -8235646.104197493 4978772.967365077, -8235647.618142568 4978784.153501556, -8235649.009636202 4978795.2367558535)" +1611,Broadway,"LINESTRING (-8235658.193494193 4979643.745720248, -8235658.59424436 4979632.602700778, -8235658.961598678 4979622.7533405945)" +1612,West 71st Street,"LINESTRING (-8235658.193494193 4979643.745720248, -8235670.883916143 4979650.875495311, -8235682.605858524 4979657.270246445, -8235730.194940838 4979683.775432005, -8235956.763500448 4979809.9222844485, -8235969.754485025 4979817.155086599)" +1613,West 79th Street,"LINESTRING (-8235405.086367975 4980506.809739085, -8235425.2574597085 4980517.997861814)" +1614,West 79th Street,"LINESTRING (-8235405.086367975 4980506.809739085, -8235392.5629252605 4980499.841059398, -8235244.1295162365 4980417.246411849, -8235229.769301924 4980409.160465743)" +1615,Broadway,"LINESTRING (-8235405.086367975 4980506.809739085, -8235397.127024383 4980521.452803749, -8235354.035249499 4980598.740909489, -8235349.727185204 4980606.400654257)" +1616,Amsterdam Avenue,"LINESTRING (-8235626.567626857 4979679.232940853, -8235602.645068286 4979725.525287829, -8235595.153266557 4979740.005473176)" +1617,West 74th Street,"LINESTRING (-8235574.125014746 4979982.173217074, -8235563.482871425 4979975.469530885, -8235505.941826635 4979943.421270152, -8235501.043769039 4979940.701583141, -8235489.31069471 4979933.997925423)" +1618,Broadway,"LINESTRING (-8235574.125014746 4979982.173217074, -8235571.854097132 4979991.728918063, -8235553.475249203 4980081.788183961, -8235552.1394153135 4980089.094693641)" +1619,West 62nd Street,"LINESTRING (-8235642.920460055 4978552.78976494, -8235666.1305738855 4978565.563134524)" +1620,Broadway,"LINESTRING (-8235642.920460055 4978552.78976494, -8235643.143099037 4978565.5778334625, -8235644.289689792 4978662.5619142335, -8235644.412141231 4978673.630331449)" +1621,West 80th Street,"LINESTRING (-8235349.727185204 4980606.400654257, -8235336.135075378 4980598.829121486, -8235188.992972448 4980516.762904143, -8235184.662644257 4980514.469411737, -8235173.853521699 4980508.441645807)" +1622,Broadway,"LINESTRING (-8235349.727185204 4980606.400654257, -8235344.2168704085 4980616.192198548, -8235301.982255601 4980691.275733116, -8235296.995142415 4980699.949998908)" +1623,West 67th Street,"LINESTRING (-8235650.512449327 4979157.713141196, -8235671.65202063 4979169.693510129)" +1624,Broadway,"LINESTRING (-8235650.512449327 4979157.713141196, -8235650.078303314 4979169.664110434, -8235646.527211557 4979265.56639067, -8235646.248912829 4979276.459091191)" +1625,West 83rd Street,"LINESTRING (-8235190.818612097 4980884.096188422, -8235212.470253055 4980896.166890275)" +1626,Broadway,"LINESTRING (-8235190.818612097 4980884.096188422, -8235185.441880691 4980893.1234841375, -8235143.763863338 4980969.679404008, -8235139.555986586 4980976.7954447195)" +1627,West 76th Street,"LINESTRING (-8235525.289154134 4980198.443071141, -8235512.787975319 4980191.268792115, -8235403.527895103 4980128.405867726, -8235388.644479185 4980119.82031732)" +1628,Broadway,"LINESTRING (-8235525.289154134 4980198.443071141, -8235522.30579178 4980209.013381196, -8235499.396240575 4980295.943221802, -8235496.435142119 4980306.028485948)" +1629,West 70th Street,"LINESTRING (-8235638.668055507 4979512.308881933, -8235625.643675084 4979504.9734030925, -8235402.425832146 4979381.447119106, -8235388.410708254 4979373.700134205)" +1630,Broadway,"LINESTRING (-8235638.668055507 4979512.308881933, -8235638.567867965 4979524.730697346, -8235635.706957052 4979620.430657104, -8235635.3173388345 4979630.956239877)" +1631,West 69th Street,"LINESTRING (-8235642.363862602 4979394.63317775, -8235663.53682975 4979406.084629968)" +1632,Broadway,"LINESTRING (-8235642.363862602 4979394.63317775, -8235641.8072651485 4979406.819640196, -8235638.957486182 4979502.342040283, -8235638.668055507 4979512.308881933)" +1633,West 75th Street,"LINESTRING (-8235552.1394153135 4980089.094693641, -8235574.637084402 4980101.237919004)" +1634,Broadway,"LINESTRING (-8235552.1394153135 4980089.094693641, -8235549.2785044 4980102.281707846, -8235527.660259288 4980189.475223181, -8235525.289154134 4980198.443071141)" +1635,West 81st Street,"LINESTRING (-8235296.995142415 4980699.949998908, -8235317.555852365 4980711.638216697)" +1636,Broadway,"LINESTRING (-8235296.995142415 4980699.949998908, -8235291.829918042 4980708.933017874, -8235247.8587191785 4980783.767326875, -8235242.960661584 4980792.353461089)" +1637,West 84th Street,"LINESTRING (-8235139.555986586 4980976.7954447195, -8235127.878572002 4980970.296911467, -8234982.951726939 4980889.491981437, -8234978.699322389 4980887.12488931, -8234967.901331782 4980881.096893321)" +1638,West 64th Street,"LINESTRING (-8235649.009636202 4978795.2367558535, -8235632.556615461 4978787.0492577655, -8235497.258906352 4978712.11265519, -8235390.536910529 4978653.257397912, -8235377.95780807 4978646.304739843)" +1639,Broadway,"LINESTRING (-8235649.009636202 4978795.2367558535, -8235649.566233655 4978801.777939691, -8235651.614512287 4978873.9811408855, -8235650.523581277 4978900.513599545)" +1640,West 77th Street,"LINESTRING (-8235496.435142119 4980306.028485948, -8235517.864144097 4980317.863247976)" +1641,Broadway,"LINESTRING (-8235496.435142119 4980306.028485948, -8235494.141960611 4980314.99644095, -8235486.093561427 4980336.695985818, -8235462.70533641 4980397.252084582, -8235459.521598974 4980405.499739618)" +1642,West 66th Street,"LINESTRING (-8235652.30469313 4979040.482699221, -8235674.056521631 4979052.286528288)" +1643,Broadway,"LINESTRING (-8235652.30469313 4979040.482699221, -8235652.382616771 4979050.140376488, -8235650.167358906 4979148.114156815, -8235650.512449327 4979157.713141196)" +1644,West 73rd Street,"LINESTRING (-8235597.201545187 4979872.018711495, -8235619.832797665 4979884.543890943)" +1645,Broadway,"LINESTRING (-8235597.201545187 4979872.018711495, -8235594.797044185 4979882.9855930945, -8235576.4961199 4979971.2650283, -8235574.125014746 4979982.173217074)" +1646,Broadway,"LINESTRING (-8235640.070681091 4978431.083468001, -8235640.282188123 4978443.533305796, -8235642.753480819 4978541.809678086, -8235642.920460055 4978552.78976494)" +1647,West 61st Street,"LINESTRING (-8235640.070681091 4978431.083468001, -8235628.204023372 4978424.424942613, -8235584.310748152 4978400.436650368, -8235582.796803078 4978399.554728983, -8235577.831953789 4978396.776677137, -8235570.996937054 4978392.955019804, -8235544.124411976 4978377.771296021, -8235533.771699333 4978372.141712271)" +1648,West 68th Street,"LINESTRING (-8235646.248912829 4979276.459091191, -8235633.246796304 4979269.888189423, -8235504.461277407 4979196.9764664965, -8235490.691056395 4979189.244327804)" +1649,Broadway,"LINESTRING (-8235646.248912829 4979276.459091191, -8235645.681183427 4979287.601704297, -8235643.042911495 4979384.563554993, -8235642.363862602 4979394.63317775)" +1650,West 78th Street,"LINESTRING (-8235459.521598974 4980405.499739618, -8235448.423045741 4980399.295620563, -8235300.412650783 4980316.70182349, -8235284.6720747845 4980307.92498722)" +1651,Broadway,"LINESTRING (-8235459.521598974 4980405.499739618, -8235456.393521281 4980412.527158854, -8235455.046555445 4980414.835329037, -8235413.1013713125 4980492.416627648, -8235405.086367975 4980506.809739085)" +1652,West 82nd Street,"LINESTRING (-8235242.960661584 4980792.353461089, -8235231.205323355 4980785.781539189, -8235085.35452652 4980704.419454121, -8235070.137152128 4980695.921610108)" +1653,Broadway,"LINESTRING (-8235242.960661584 4980792.353461089, -8235238.140527633 4980800.821984422, -8235221.676374944 4980830.182529313, -8235195.071016644 4980876.436225801, -8235190.818612097 4980884.096188422)" +1654,West 62nd Street,"LINESTRING (-8235795.6730653215 4978636.882646639, -8235810.378370055 4978645.11411602, -8235925.783286162 4978709.246319508, -8235936.837311598 4978715.375869142, -8236054.535409214 4978780.743271994, -8236096.458329445 4978804.056330595, -8236108.803660973 4978810.891506497)" +1655,Columbus Avenue,"LINESTRING (-8235795.6730653215 4978636.882646639, -8235800.67131046 4978627.798640268, -8235827.588363333 4978578.659897896, -8235840.245389436 4978555.81774287, -8235845.588724992 4978546.189952219)" +1656,West 60th Street,"LINESTRING (-8235896.8736144025 4978453.7195485225, -8235911.389676001 4978463.200260173, -8236153.654283816 4978601.590300305, -8236161.257405036 4978605.647223258, -8236196.2117251465 4978624.550154604, -8236209.024598534 4978629.636019515)" +1657,Columbus Avenue,"LINESTRING (-8235896.8736144025 4978453.7195485225, -8235903.764290881 4978440.902228954, -8235942.314230544 4978370.5983543685, -8235946.755878227 4978362.646390374)" +1658,Amsterdam Avenue,"LINESTRING (-8236209.024598534 4978629.636019515, -8236202.6571236625 4978641.189468146, -8236163.650774088 4978711.730477049, -8236159.209126406 4978719.7562211165)" +1659,West 60th Street,"LINESTRING (-8236209.024598534 4978629.636019515, -8236227.781932734 4978637.088433288, -8236356.500659938 4978708.540760086, -8236375.035355156 4978718.991864255, -8236395.317766379 4978729.972150302, -8236483.749969865 4978779.552631781, -8236514.251510342 4978796.38330012, -8236528.667384399 4978804.997085704)" +1660,Dyer Avenue,"LINESTRING (-8237326.282667883 4976216.778718359, -8237330.468280736 4976207.153232764, -8237345.463016145 4976171.722710236)" +1661,West 35th Street,"LINESTRING (-8237326.282667883 4976216.778718359, -8237333.785601562 4976221.055082177, -8237353.121797113 4976231.870911046, -8237393.597563965 4976253.399736482, -8237478.06679358 4976300.469408807, -8237493.017001192 4976308.801778423)" +1662,Riverside Boulevard,"LINESTRING (-8236613.158877911 4979215.615943872, -8236603.61879755 4979225.86179162, -8236585.384664959 4979245.456821624, -8236550.786567219 4979288.233805421, -8236545.198328783 4979295.14282038)" +1663,Riverside Boulevard,"LINESTRING (-8236613.158877911 4979215.615943872, -8236620.338985069 4979207.971989857, -8236689.023110887 4979134.810832651)" +1664,Freedom Place South,"LINESTRING (-8236557.510264465 4979062.150012834, -8236555.050103717 4979065.707337574, -8236551.654859249 4979070.102546376, -8236547.680753428 4979074.438958336, -8236542.816091678 4979078.481377999, -8236522.700659692 4979094.489376299, -8236517.880525741 4979098.605302967, -8236513.806232379 4979103.02992607, -8236508.529688514 4979110.409202284, -8236503.5537072765 4979118.008980626, -8236494.525696573 4979136.677706883, -8236490.317819821 4979145.379991474)" +1665,Freedom Place South,"LINESTRING (-8236557.510264465 4979062.150012834, -8236561.0056964755 4979054.432680562, -8236562.87586392 4979047.009347652, -8236564.267357554 4979040.835490917, -8236566.760914149 4979020.447091758, -8236567.840713209 4979012.553397098, -8236569.632957011 4979004.836104015, -8236571.592180049 4978998.3829817185, -8236574.8649730785 4978991.459477118, -8236585.918998514 4978971.409270677, -8236591.618556444 4978961.663474054)" +1666,Dyer Avenue,"LINESTRING (-8237738.977416099 4975863.448787263, -8237723.86022925 4975854.984543699, -8237682.8056010455 4975832.442653027, -8237672.575339841 4975826.7704514405, -8237666.463899797 4975823.434728209, -8237662.100175758 4975821.333370106, -8237656.712312403 4975818.453187707, -8237650.556344563 4975815.205636122, -8237644.634147652 4975812.472403499, -8237633.513330524 4975808.166828928, -8237628.860175808 4975806.609181256, -8237623.817402876 4975805.6393252835, -8237617.806150371 4975805.257260836, -8237612.952620572 4975805.6393252835, -8237607.5202294225 4975806.829603082)" +1667,10th Avenue,"LINESTRING (-8237738.977416099 4975863.448787263, -8237706.004582927 4975923.168936351, -8237701.37369211 4975931.57445908)" +1668,East 68th Street,"LINESTRING (-8232545.177330004 4977572.920735294, -8232549.24049142 4977571.465688326, -8232554.583826977 4977569.995944135, -8232559.459620673 4977568.864241257, -8232564.4801297095 4977568.540897601, -8232568.376311887 4977568.702569426, -8232571.459861782 4977568.864241257, -8232574.287376848 4977569.114097724, -8232577.248475304 4977570.010641575, -8232617.79103385 4977592.688819121, -8232657.142473846 4977613.706230931, -8232688.067028387 4977630.226242306, -8232702.082152279 4977637.707288676)" +1669,Amsterdam Avenue,"LINESTRING (-8235754.306742543 4979453.595804936, -8235748.7741638515 4979464.106507602, -8235706.762188025 4979539.607495887, -8235701.942054072 4979547.075304488)" +1670,2nd Avenue,"LINESTRING (-8233645.704079886 4977147.688808215, -8233674.43564046 4977097.205411948)" +1671,,"LINESTRING (-8233645.704079886 4977147.688808215, -8233645.459177005 4977129.964476924, -8233645.425781158 4977127.18678613, -8233644.735600316 4977122.660180602, -8233643.800516593 4977120.411575387, -8233642.464682703 4977117.94251928, -8233640.483195769 4977115.517554065, -8233637.778132141 4977113.460008295, -8233628.004280849 4977108.507203469)" +1672,,"LINESTRING (-8233535.943061964 4977101.188226453, -8233559.654113503 4977127.201482905, -8233564.819337875 4977131.992632607, -8233571.732278255 4977137.356959449, -8233580.559913874 4977142.603714854, -8233606.719994212 4977158.050061551, -8233610.0707108835 4977160.372159551, -8233613.443691454 4977163.149859781, -8233616.716484483 4977167.044520165, -8233619.18777718 4977171.497662053, -8233620.879833439 4977176.274136634, -8233623.918855538 4977188.105106801)" +1673,,"LINESTRING (-8233535.943061964 4977101.188226453, -8233577.4652320305 4977127.377844201, -8233626.56825942 4977154.713883745, -8233638.301333749 4977161.239272236)" +1674,Queensboro Bridge Exit,"LINESTRING (-8233512.554836949 4977128.186166855, -8233510.762593147 4977132.0661165165, -8233508.7254464645 4977136.827875027, -8233469.407402317 4977211.517242796, -8233468.817409014 4977212.66360118, -8233464.119726503 4977220.7322043665)" +1675,East 60th Street,"LINESTRING (-8233512.554836949 4977128.186166855, -8233463.396149813 4977102.011243676, -8233414.025955647 4977074.660654913, -8233373.160570575 4977052.027769936, -8233368.652131199 4977049.544034454, -8233356.67415399 4977042.901147388)" +1676,9th Avenue,"LINESTRING (-8236259.196293035 4977794.531328166, -8236263.693600464 4977786.638624211, -8236294.952113478 4977729.934804512, -8236305.6053887475 4977710.724953719, -8236309.067424912 4977704.478453375)" +1677,West 53rd Street,"LINESTRING (-8236259.196293035 4977794.531328166, -8236275.014792678 4977803.585164022, -8236564.111510267 4977961.514218891, -8236576.467973745 4977968.290013038)" +1678,Columbus Circle,"LINESTRING (-8235667.867157943 4978226.596785656, -8235671.796735967 4978221.672813242, -8235676.360835088 4978213.970843458, -8235679.099294563 4978207.297767676, -8235680.59097574 4978201.9916467955, -8235681.54832336 4978196.656132029, -8235681.982469374 4978191.291223428, -8235681.882281833 4978185.823429199, -8235680.936066161 4978178.694723579, -8235679.154954309 4978171.948180165, -8235676.750453308 4978165.921859924, -8235673.188229601 4978159.469291883, -8235669.058276494 4978153.501772616, -8235663.347586616 4978147.960507989, -8235659.18423766 4978144.594595467, -8235653.518075579 4978140.949416401)" +1679,Central Park South,"LINESTRING (-8235611.650815092 4978135.849107654, -8235597.446448066 4978138.142041515, -8235575.460848635 4978145.138432781, -8235569.705630962 4978146.990419544, -8235566.789060302 4978147.328480658, -8235563.449475577 4978146.9610229265, -8235557.8055773955 4978145.447097218, -8235553.096762934 4978142.727910855, -8235547.887010765 4978140.199803132, -8235503.314686651 4978122.7970328415)" +1680,Columbus Circle,"LINESTRING (-8235611.650815092 4978135.849107654, -8235601.465081685 4978139.758854177, -8235595.598544518 4978143.139463337, -8235590.911993958 4978146.622961826, -8235586.659589409 4978150.518014348, -8235582.451712657 4978155.353760963, -8235579.4572183555 4978159.5574818505, -8235576.618571338 4978164.4667246165, -8235574.481237116 4978169.346573166, -8235572.410694586 4978175.813846083, -8235571.675985949 4978179.106277576, -8235571.1305204425 4978182.530995442, -8235570.763166123 4978186.837616607, -8235570.718638327 4978191.173636423, -8235570.863353665 4978193.848741134, -8235571.197312137 4978197.052988399)" +1681,Columbus Circle,"LINESTRING (-8235653.518075579 4978140.949416401, -8235648.252663665 4978138.377214249, -8235642.408390397 4978136.245961552, -8235636.096575269 4978134.7467357945, -8235625.476695849 4978133.879536688)" +1682,Columbus Circle,"LINESTRING (-8235602.823179472 4978240.413318524, -8235607.977271895 4978241.750877531, -8235613.765885416 4978242.4270063285, -8235620.322603424 4978242.794467653, -8235625.766126524 4978242.912055279, -8235631.710587332 4978242.853261466, -8235636.263554507 4978242.294720257, -8235640.32671592 4978241.28052709, -8235645.881558511 4978239.50201469, -8235651.870547115 4978236.84159592, -8235659.3066891 4978232.7260324005, -8235663.726072884 4978230.08031391, -8235667.867157943 4978226.596785656)" +1683,Broadway,"LINESTRING (-8235602.823179472 4978240.413318524, -8235626.378383725 4978255.773210451, -8235630.363621494 4978258.6835084865, -8235633.380379694 4978261.667299795, -8235634.460178755 4978262.990163228, -8235635.417526376 4978264.636393528, -8235636.174498914 4978267.943553454, -8235636.9648672985 4978273.602474148, -8235637.309957719 4978279.261398117, -8235637.799763478 4978303.866731632, -8235638.111458053 4978313.47958486)" +1684,Columbus Circle,"LINESTRING (-8235625.476695849 4978133.879536688, -8235619.0424292805 4978134.364580248, -8235611.650815092 4978135.849107654)" +1685,Broadway,"LINESTRING (-8235625.476695849 4978133.879536688, -8235620.122228342 4978131.1015604045, -8235615.469073626 4978126.986041438, -8235612.608162713 4978124.1786705665, -8235609.992154679 4978120.415912966, -8235608.055195538 4978115.403804509, -8235606.585778261 4978111.6998433145, -8235605.26107632 4978106.981704302, -8235604.793534459 4978102.5428341655, -8235604.470707934 4978098.015776633, -8235609.5914045125 4978063.519079221, -8235610.6600716235 4978054.626682299)" +1686,Broadway,"LINESTRING (-8235635.3173388345 4979630.956239877, -8235633.903581301 4979646.803437574, -8235632.923969781 4979655.682583704, -8235631.955490212 4979661.136500312, -8235630.619656323 4979666.605120563, -8235628.960995911 4979672.588265044, -8235626.567626857 4979679.232940853)" +1687,West 71st Street,"LINESTRING (-8235635.3173388345 4979630.956239877, -8235647.595878668 4979637.615587911, -8235649.254539081 4979638.747530523)" +1688,West End Avenue,"LINESTRING (-8236528.667384399 4978804.997085704, -8236533.676761485 4978795.8688251125, -8236549.673372312 4978766.044020272, -8236558.445348186 4978749.7866736315, -8236573.740646222 4978721.94639784, -8236579.306620762 4978712.81821487)" +1689,West End Avenue,"LINESTRING (-8236528.667384399 4978804.997085704, -8236523.379708587 4978814.18415208, -8236508.273653687 4978841.363219845, -8236482.870545888 4978887.710393042, -8236477.939092444 4978896.559450165)" +1690,West 60th Street,"LINESTRING (-8236528.667384399 4978804.997085704, -8236545.009085648 4978814.360543839, -8236634.866178617 4978865.808276174, -8236645.986995746 4978872.173114469)" +1691,12th Avenue,"LINESTRING (-8237126.586633348 4978314.317402792, -8237150.49805997 4978272.044433317, -8237192.810598421 4978194.2896925295)" +1692,East 57th Street,"LINESTRING (-8233514.848018458 4976757.937302738, -8233499.441400934 4976749.369410754, -8233278.906357722 4976626.671555504, -8233264.434823919 4976618.912059155)" +1693,1st Avenue,"LINESTRING (-8233514.848018458 4976757.937302738, -8233506.933202663 4976772.1632531965, -8233474.238668217 4976831.007177423, -8233464.809907347 4976848.010844911, -8233459.911849751 4976856.975625339)" +1694,East 57th Street,"LINESTRING (-8233514.848018458 4976757.937302738, -8233529.653510733 4976766.181885139, -8233680.279913725 4976850.171209278, -8233691.534314247 4976856.461252469)" +1695,West 61st Street,"LINESTRING (-8236077.033078303 4978659.871982064, -8236081.463594035 4978676.570152206, -8236111.920606717 4978693.327147422, -8236145.973238949 4978712.4654350225, -8236159.209126406 4978719.7562211165)" +1696,West 34th Street,"LINESTRING (-8237700.037858221 4976295.223105657, -8237690.854000229 4976289.96210981, -8237562.124141077 4976219.188765091, -8237547.530155835 4976211.0034258645)" +1697,Hudson Boulevard East,"LINESTRING (-8237700.037858221 4976295.223105657, -8237691.544181072 4976308.184565615, -8237645.068293666 4976381.515598286, -8237639.457791331 4976390.377080993)" +1698,West 35th Street,"LINESTRING (-8237639.457791331 4976390.377080993, -8237647.584114159 4976394.903347233, -8237678.75357158 4976412.273648183, -8237684.352941967 4976415.3891369, -8237700.505400082 4976424.382911785)" +1699,Hudson Boulevard East,"LINESTRING (-8237639.457791331 4976390.377080993, -8237633.769365351 4976398.827092717, -8237588.640443784 4976468.7934705885, -8237585.423310501 4976471.953064695, -8237582.094857725 4976473.86351744, -8237577.976036565 4976474.980397682)" +1700,West 36th Street,"LINESTRING (-8237577.976036565 4976474.980397682, -8237576.027945477 4976473.892909024, -8237457.517215579 4976407.556329897, -8237442.923230335 4976399.503093972)" +1701,West 36th Street,"LINESTRING (-8237633.580122217 4976505.547695917, -8237577.976036565 4976474.980397682)" +1702,Hudson Boulevard West,"LINESTRING (-8237633.580122217 4976505.547695917, -8237639.480055228 4976497.112287714, -8237683.284274856 4976434.24374311, -8237687.224984829 4976428.6005835775, -8237689.907784558 4976426.117006587, -8237694.59433512 4976424.632738982, -8237700.505400082 4976424.382911785)" +1703,Lincoln Tunnel,"LINESTRING (-8237387.1410334995 4976610.843953008, -8237370.365186236 4976602.452541845, -8237352.999345671 4976595.060464078, -8237333.796733512 4976588.814677081, -8237317.020886249 4976584.611632081)" +1704,Lincoln Tunnel,"LINESTRING (-8237637.576491936 4976834.725349377, -8237611.616786683 4976822.953592434, -8237588.740631325 4976814.826532559, -8237548.966177266 4976806.699479446, -8237523.819104295 4976798.175633532, -8237337.815367128 4976695.978239441, -8237322.1304508755 4976686.1759283785, -8237306.734965299 4976673.91937936, -8237291.896077176 4976660.134454111, -8237281.420913092 4976648.054290406)" +1705,West 61st Street,"LINESTRING (-8236591.618556444 4978961.663474054, -8236581.510746677 4978955.857159421, -8236494.358717338 4978905.570209262, -8236477.939092444 4978896.559450165)" +1706,"['Riverside Boulevard', 'West 61st Street']","LINESTRING (-8236591.618556444 4978961.663474054, -8236601.759762054 4978967.484491681, -8236657.018757283 4978999.235557997, -8236659.111563711 4979000.440924586, -8236762.148884388 4979055.843849435, -8236752.953894449 4979065.780836032, -8236689.023110887 4979134.810832651)" +1707,Freedom Place South,"LINESTRING (-8236591.618556444 4978961.663474054, -8236585.918998514 4978971.409270677, -8236574.8649730785 4978991.459477118, -8236571.592180049 4978998.3829817185, -8236569.632957011 4979004.836104015, -8236567.840713209 4979012.553397098, -8236566.760914149 4979020.447091758, -8236564.267357554 4979040.835490917, -8236562.87586392 4979047.009347652, -8236561.0056964755 4979054.432680562, -8236557.510264465 4979062.150012834)" +1708,Freedom Place South,"LINESTRING (-8236591.618556444 4978961.663474054, -8236597.496225556 4978951.432602993, -8236639.986875192 4978879.4346209625, -8236645.986995746 4978872.173114469)" +1709,East 59th Street,"LINESTRING (-8233081.8263312215 4976768.312838941, -8233144.688447673 4976803.304636476, -8233158.681307665 4976810.976101488)" +1710,Vanderbilt Avenue,"LINESTRING (-8235178.996482175 4975991.970997631, -8235173.196736704 4976002.742487651, -8235172.0390139995 4976004.887970029, -8235134.457553907 4976074.719270115, -8235130.093829869 4976082.831019146)" +1711,East 43rd Street,"LINESTRING (-8235178.996482175 4975991.970997631, -8235190.161827101 4975998.15762278, -8235230.481746666 4976020.450078912, -8235280.219295153 4976048.1650953)" +1712,Columbus Avenue,"LINESTRING (-8235592.080848609 4979006.614755785, -8235596.867586713 4978997.545105105, -8235635.762616798 4978927.163726149, -8235643.833279881 4978912.684745971)" +1713,West 66th Street,"LINESTRING (-8235592.080848609 4979006.614755785, -8235604.927117848 4979013.6705676485, -8235638.389756779 4979032.61838765, -8235652.30469313 4979040.482699221)" +1714,East 61st Street,"LINESTRING (-8232985.713082871 4976953.09034551, -8233022.927188644 4976973.783057293, -8233042.909037241 4976985.070009466, -8233057.157932062 4976993.226604116)" +1715,2nd Avenue,"LINESTRING (-8233638.301333749 4977161.239272236, -8233645.704079886 4977147.688808215)" +1716,,"LINESTRING (-8233708.766571419 4976996.077739707, -8233691.022244588 4976989.140957656, -8233647.396136145 4976965.552996221, -8233645.0027670935 4976964.583025195, -8233643.143731598 4976964.2303084815, -8233641.1288488135 4976964.245005012, -8233639.459056453 4976964.862259268, -8233637.6334168045 4976966.273126289, -8233636.1862634225 4976968.051406885, -8233629.206531351 4976979.749855905, -8233607.3099875115 4977007.77622229)" +1717,East 58th Street,"LINESTRING (-8233708.766571419 4976996.077739707, -8233692.758828645 4976985.099402589, -8233646.906330386 4976959.204096703, -8233634.839297585 4976953.384275769)" +1718,,"LINESTRING (-8233964.033295758 4975882.09659974, -8233957.96638351 4975885.05027543, -8233955.3392435275 4975886.152393455, -8233953.068325915 4975886.843054145, -8233950.608165168 4975887.254511602, -8233946.322364773 4975886.754884692, -8233940.144133035 4975885.358868465, -8233933.91024155 4975883.272191947, -8233927.576162524 4975880.568330082, -8233922.110375525 4975877.776299592, -8233913.160288465 4975872.603697846, -8233802.263811737 4975810.503300901, -8233796.731233046 4975807.917017492, -8233790.4305498665 4975805.477682632, -8233783.896095757 4975804.008204094, -8233777.461829189 4975802.935484901, -8233771.161146011 4975802.465251869, -8233765.127629608 4975802.47994665, -8233758.214689231 4975803.155906645, -8233751.056845972 4975804.742943335, -8233744.399940425 4975806.932466602, -8233738.555667155 4975809.944898742, -8233732.488754909 4975813.721461325, -8233727.36805833 4975816.763285166, -8233722.770563362 4975820.907220616, -8233718.896645082 4975824.904209668, -8233715.17857409 4975829.5183828855, -8233699.727428767 4975850.943457778, -8233593.617690143 4975999.715300989, -8233591.357904481 4976002.889438485, -8233561.780315776 4976031.618368742)" +1719,"['General Douglas MacArthur Plaza', 'East 48th Street']","LINESTRING (-8233964.033295758 4975882.09659974, -8233955.561882508 4975900.773837666, -8233954.203784721 4975902.551924334, -8233952.745499392 4975903.786298741, -8233950.686088812 4975904.829639133, -8233948.04781688 4975905.167622664, -8233945.955010454 4975904.800249261, -8233943.672960892 4975903.889163282, -8233797.833296004 4975823.743319297, -8233791.543744775 4975822.641208314, -8233785.955506337 4975822.053415839, -8233780.2114206115 4975821.95055216, -8233774.311487599 4975822.082805461, -8233769.491353648 4975823.243695635, -8233764.6600877475 4975825.1099370895, -8233760.452210995 4975828.225238578, -8233756.099618906 4975832.795328882, -8233752.136645034 4975837.8062663665, -8233727.724280704 4975871.486886464, -8233725.2752519045 4975874.9254903365, -8233723.64998734 4975878.628603551, -8233722.870750904 4975882.640311117, -8233722.636979973 4975885.81441058, -8233723.349424714 4975889.737951618, -8233724.395827928 4975893.514545041, -8233726.4886343535 4975897.820157222, -8233728.681628323 4975902.066991575, -8233736.796819202 4975909.6054944685)" +1720,9th Avenue,"LINESTRING (-8237063.401690373 4976340.397248052, -8237072.507624721 4976324.27619799, -8237078.318502141 4976313.974611105)" +1721,,"LINESTRING (-8237063.401690373 4976340.397248052, -8237077.917751974 4976327.362267503, -8237085.08672718 4976317.560326279)" +1722,,"LINESTRING (-8237385.749539863 4977790.151391106, -8237409.126632932 4977803.232417013)" +1723,12th Avenue,"LINESTRING (-8237385.749539863 4977790.151391106, -8237380.673371084 4977798.984756117, -8237373.148173505 4977812.683101687)" +1724,3rd Avenue,"LINESTRING (-8233923.023195351 4977235.443827699, -8233918.726263006 4977243.32138936, -8233877.315412431 4977318.334906721, -8233871.682646195 4977328.519976123)" +1725,East 59th Street,"LINESTRING (-8233923.023195351 4977235.443827699, -8233907.54978613 4977227.125364631, -8233882.51403265 4977214.118594703, -8233731.386691949 4977129.964476924, -8233698.558574115 4977111.079134445, -8233688.484160198 4977105.288616515, -8233674.43564046 4977097.205411948)" +1726,Central Park South,"LINESTRING (-8234707.62523036 4977679.904024911, -8234720.927909508 4977687.26752839, -8234984.510199809 4977833.289447406, -8234997.812878959 4977840.667764359)" +1727,Grand Army Plaza,"LINESTRING (-8234707.62523036 4977679.904024911, -8234695.40235027 4977670.012540952, -8234653.011888177 4977644.747414166, -8234639.252799114 4977635.414472284)" +1728,Grand Army Plaza,"LINESTRING (-8234707.62523036 4977679.904024911, -8234715.996456066 4977665.265220112, -8234755.24770852 4977596.70123061, -8234760.435196792 4977587.632889042, -8234763.151392367 4977582.885608238)" +1729,"['Doris C. Freedman Place', 'Grand Army Plaza']","LINESTRING (-8234587.311124709 4977728.905966864, -8234599.923623016 4977737.077880319, -8234622.49921575 4977751.3787453165, -8234626.818411993 4977753.509914039, -8234632.228539245 4977755.641083228, -8234635.779631002 4977756.287782937, -8234639.586757587 4977756.625830528, -8234643.293696631 4977756.669923694, -8234647.056295419 4977756.287782937, -8234650.874553952 4977755.5528969085, -8234655.271673839 4977754.053729583, -8234658.466543226 4977752.422283047, -8234662.50744074 4977749.850183207, -8234665.490803095 4977747.498549661, -8234668.774728072 4977744.250356755, -8234671.4797917 4977740.811094855, -8234674.452022103 4977736.240111899, -8234699.387588041 4977693.896156027, -8234707.62523036 4977679.904024911)" +1730,5th Avenue,"LINESTRING (-8234587.311124709 4977728.905966864, -8234594.101613648 4977716.780388453, -8234601.393040294 4977703.537804259, -8234611.901600228 4977684.1516340235, -8234631.627413996 4977649.024403111, -8234639.252799114 4977635.414472284)" +1731,Central Park West,"LINESTRING (-8235580.013815808 4978220.364653823, -8235585.635450093 4978248.394579927, -8235586.058464157 4978251.3195742285, -8235586.28110314 4978254.53853882, -8235585.936012719 4978257.728107519, -8235584.900741454 4978262.91667081, -8235583.242081041 4978267.7965685455, -8235570.81882587 4978301.764839908, -8235566.956039539 4978311.936236227, -8235563.237968545 4978319.741173244, -8235538.413722098 4978364.101555206, -8235533.771699333 4978372.141712271)" +1732,Columbus Circle,"LINESTRING (-8235580.013815808 4978220.364653823, -8235584.23282451 4978225.920657955, -8235587.11599932 4978229.022026715, -8235592.448202929 4978233.681430919, -8235598.882469498 4978237.943979301, -8235602.823179472 4978240.413318524)" +1733,Columbus Circle,"LINESTRING (-8235571.197312137 4978197.052988399, -8235571.720513742 4978200.198443161, -8235572.544277975 4978203.78485076, -8235573.312382462 4978206.401165331, -8235574.258598135 4978209.135067821, -8235576.729890828 4978214.735160797, -8235580.013815808 4978220.364653823)" +1734,Central Park South,"LINESTRING (-8235503.314686651 4978122.7970328415, -8235543.757057657 4978154.001515468, -8235550.380567361 4978158.249330751, -8235553.408457508 4978160.703951497, -8235556.235972575 4978163.687712876, -8235558.4846262885 4978167.729755605, -8235560.688752206 4978173.256333098, -8235563.583058966 4978179.988179057, -8235571.197312137 4978197.052988399)" +1735,Central Park South,"LINESTRING (-8235503.314686651 4978122.7970328415, -8235371.545805399 4978049.173662735, -8235325.9048141735 4978023.672385238, -8235313.069676885 4978016.499703622)" +1736,West 37th Street,"LINESTRING (-8237078.318502141 4976313.974611105, -8237085.08672718 4976317.560326279)" +1737,9th Avenue,"LINESTRING (-8237078.318502141 4976313.974611105, -8237082.726753975 4976306.171276488, -8237112.348870476 4976253.678950229, -8237122.501208036 4976235.677027585, -8237128.312085455 4976224.978757841)" +1738,West 67th Street,"LINESTRING (-8235542.076133345 4979097.605720617, -8235555.21183326 4979104.926193728, -8235636.642040774 4979150.260330147, -8235650.512449327 4979157.713141196)" +1739,Columbus Avenue,"LINESTRING (-8235542.076133345 4979097.605720617, -8235546.139294758 4979090.167655164, -8235587.37203415 4979014.8024379425, -8235592.080848609 4979006.614755785)" +1740,West 31st Street,"LINESTRING (-8237388.0649852725 4975756.808671031, -8237399.998434686 4975763.421294245, -8237465.198260442 4975799.496906366, -8237567.734643413 4975857.453280647, -8237573.779291763 4975860.877184711)" +1741,West 59th Street,"LINESTRING (-8236726.894001653 4978793.414044733, -8236756.527250104 4978809.53917024, -8236815.081302261 4978841.172128246, -8236880.236600223 4978876.450640921, -8236888.207075763 4978880.757568072)" +1742,West 59th Street,"LINESTRING (-8236726.894001653 4978793.414044733, -8236614.260940869 4978732.441613925, -8236595.603794212 4978721.961097014, -8236579.306620762 4978712.81821487)" +1743,Freedom Place South,"LINESTRING (-8236726.894001653 4978793.414044733, -8236716.4744973155 4978803.5565544795, -8236712.177564971 4978807.731155753, -8236653.9240754405 4978864.161944542, -8236645.986995746 4978872.173114469)" +1744,West 60th Street,"LINESTRING (-8236645.986995746 4978872.173114469, -8236634.866178617 4978865.808276174, -8236545.009085648 4978814.360543839, -8236528.667384399 4978804.997085704)" +1745,Freedom Place South,"LINESTRING (-8236645.986995746 4978872.173114469, -8236639.986875192 4978879.4346209625, -8236597.496225556 4978951.432602993, -8236591.618556444 4978961.663474054)" +1746,Freedom Place South,"LINESTRING (-8236645.986995746 4978872.173114469, -8236653.9240754405 4978864.161944542, -8236712.177564971 4978807.731155753, -8236716.4744973155 4978803.5565544795, -8236726.894001653 4978793.414044733)" +1747,East 55th Street,"LINESTRING (-8234310.748981784 4976952.575967581, -8234323.539591276 4976959.733171505, -8234352.894540997 4976976.134504588, -8234468.355116848 4977040.652560533, -8234482.303449045 4977048.456481837)" +1748,Lexington Avenue,"LINESTRING (-8234310.748981784 4976952.575967581, -8234315.368740651 4976944.140173383, -8234357.091285801 4976868.350620868, -8234362.067267039 4976859.297651773)" +1749,,"LINESTRING (-8232895.53316338 4977141.677816637, -8232862.671649697 4977126.907547416, -8232856.504549907 4977123.306838406, -8232853.087041539 4977121.043536278, -8232851.26140189 4977118.868415247, -8232849.368970546 4977115.017864337, -8232848.801241144 4977112.401842068, -8232848.456150723 4977109.580066022, -8232848.734449451 4977106.831774511, -8232849.380102497 4977103.789548982, -8232850.626880793 4977100.335815833, -8232854.05552111 4977095.735739108, -8232879.402969162 4977071.192235371, -8232907.711515672 4977044.47368883, -8232928.65071189 4977021.282402393, -8232944.046197467 4977002.2503041485, -8232954.398910111 4976988.347343075, -8232963.916726573 4976973.25398173, -8232982.651796874 4976940.583621217, -8232989.308702423 4976909.324228758)" +1750,FDR Drive,"LINESTRING (-8232895.53316338 4977141.677816637, -8232866.100290013 4977122.219277578, -8232863.584469522 4977120.51445274, -8232860.7235586075 4977118.060093365, -8232859.209613535 4977115.8114892095, -8232858.363585403 4977113.753943378, -8232857.617744815 4977111.637610975, -8232857.4285016805 4977109.712336756, -8232857.67340456 4977106.964045207, -8232858.274529811 4977104.803624053, -8232859.966586071 4977102.378662101, -8232862.059392499 4977099.939004016, -8232888.174945038 4977076.291988258, -8232914.8804908795 4977050.734463806, -8232924.999432593 4977040.035301488)" +1751,"['Riverview Terrace', 'Sutton Square']","LINESTRING (-8233126.81053745 4976685.5146034, -8233129.8829553975 4976680.077044152, -8233130.194649971 4976679.592072799, -8233130.639927935 4976679.063013167, -8233131.062941999 4976678.710306762, -8233131.474824115 4976678.475169166, -8233132.2651925 4976678.137158881, -8233133.456311052 4976677.666883723, -8233135.126103413 4976677.387657858, -8233136.740236031 4976677.431746151, -8233138.565875678 4976677.946109597, -8233140.213404142 4976678.842571662, -8233195.550323016 4976709.954265175, -8233209.799217838 4976718.1400224455)" +1752,,"LINESTRING (-8233418.122512908 4976277.323974938, -8233444.160141804 4976260.380082559, -8233448.846692367 4976255.66283761, -8233453.577770726 4976251.680367792, -8233458.331112984 4976248.873535795, -8233463.429545661 4976246.551654439, -8233468.260811562 4976245.170282249, -8233472.468688314 4976244.949850535, -8233476.531849728 4976245.522973002, -8233482.142352062 4976247.27173151, -8233485.982874497 4976249.005794877, -8233493.697315208 4976253.326259182, -8233512.766343981 4976268.080512227)" +1753,FDR Drive,"LINESTRING (-8233418.122512908 4976277.323974938, -8233428.7423923295 4976263.995169014, -8233437.748139135 4976252.135926989, -8233446.753885939 4976239.2921049, -8233489.956980318 4976173.295111455, -8233569.305513355 4976057.246703138, -8233588.0294517055 4976029.796173215, -8233604.1596459225 4976005.108396329)" +1754,East 66th Street,"LINESTRING (-8233573.724897139 4977864.933941697, -8233558.507522747 4977856.247495758, -8233531.9244283475 4977841.358563244)" +1755,3rd Avenue,"LINESTRING (-8233573.724897139 4977864.933941697, -8233571.097757157 4977869.872432171, -8233566.422338542 4977878.588286037)" +1756,East 66th Street,"LINESTRING (-8233524.644133647 4977854.93938528, -8233551.282887795 4977869.78424482, -8233566.422338542 4977878.588286037)" +1757,East 66th Street,"LINESTRING (-8233524.644133647 4977854.93938528, -8233528.551447775 4977847.649244698, -8233531.9244283475 4977841.358563244)" +1758,East 66th Street,"LINESTRING (-8233531.9244283475 4977841.358563244, -8233528.551447775 4977847.649244698, -8233524.644133647 4977854.93938528)" +1759,East 66th Street,"LINESTRING (-8233531.9244283475 4977841.358563244, -8233528.484656081 4977837.625310279, -8233464.509344723 4977801.174726383, -8233434.998547712 4977784.551541549, -8233370.733805677 4977748.762552621, -8233367.550068241 4977747.30747946)" +1760,2nd Avenue,"LINESTRING (-8233324.591876743 4977725.554896415, -8233342.569974505 4977693.67569162, -8233351.764964447 4977677.331944167, -8233363.397851234 4977656.711229875, -8233368.897034079 4977646.95204741)" +1761,East 66th Street,"LINESTRING (-8233367.550068241 4977747.30747946, -8233340.855654349 4977733.697411693, -8233324.591876743 4977725.554896415)" +1762,East 66th Street,"LINESTRING (-8233367.550068241 4977747.30747946, -8233363.653886063 4977754.156613607, -8233358.822620162 4977762.651898257)" +1763,East 66th Street,"LINESTRING (-8233358.822620162 4977762.651898257, -8233366.592720619 4977767.002427513, -8233524.644133647 4977854.93938528)" +1764,East 66th Street,"LINESTRING (-8233358.822620162 4977762.651898257, -8233363.653886063 4977754.156613607, -8233367.550068241 4977747.30747946)" +1765,West 62nd Street,"LINESTRING (-8235480.906073155 4978463.597127373, -8235492.438772401 4978469.991101151, -8235563.137781003 4978508.8694915855, -8235586.247707293 4978521.584008239, -8235610.203661712 4978534.783604888, -8235628.883072267 4978545.131630771, -8235642.920460055 4978552.78976494)" +1766,Central Park West,"LINESTRING (-8235480.906073155 4978463.597127373, -8235476.442161574 4978472.313511054, -8235457.328605005 4978504.503933038, -8235433.495102026 4978546.204651128, -8235428.931002904 4978554.52423762)" +1767,East 59th Street,"LINESTRING (-8234639.252799114 4977635.414472284, -8234625.738612931 4977626.640045291, -8234556.030347796 4977587.485914368, -8234472.562993601 4977540.3806457715, -8234461.074822149 4977533.134832103)" +1768,5th Avenue,"LINESTRING (-8234639.252799114 4977635.414472284, -8234644.941225095 4977625.008620037, -8234684.348324835 4977554.828196983, -8234690.482028778 4977542.879203456)" +1769,West 43rd Street,"LINESTRING (-8236450.766004742 4976699.005641847, -8236467.564115903 4976708.234816136, -8236547.680753428 4976752.235171387, -8236607.381396338 4976785.360486088, -8236753.81105453 4976866.910375224, -8236767.180525373 4976874.199783933)" +1770,8th Avenue,"LINESTRING (-8236450.766004742 4976699.005641847, -8236445.478328928 4976708.558131317, -8236404.445964623 4976782.759248352, -8236400.3160115145 4976790.210253214)" +1771,East 49th Street,"LINESTRING (-8233930.7265041135 4976017.5110573955, -8233937.238694325 4976021.0084931, -8233940.823181928 4976022.933552783, -8233966.871942774 4976037.893189813, -8234133.238921764 4976130.179079947, -8234174.571848696 4976153.103735588, -8234188.965458856 4976161.039205842)" +1772,1st Avenue,"LINESTRING (-8233930.7265041135 4976017.5110573955, -8233926.195800838 4976025.637454048, -8233912.993309231 4976045.975517974, -8233902.763048027 4976058.422316419, -8233899.100636779 4976063.051295092, -8233887.144923468 4976078.187335906)" +1773,1st Avenue,"LINESTRING (-8233913.494246938 4976024.2561130915, -8233896.562552388 4976054.616268931, -8233887.144923468 4976078.187335906)" +1774,1st Avenue,"LINESTRING (-8233887.144923468 4976078.187335906, -8233876.513912098 4976097.335195888, -8233872.60659797 4976104.3301257)" +1775,West 65th Street,"LINESTRING (-8235650.35660204 4978916.344912537, -8235643.833279881 4978912.684745971)" +1776,Broadway,"LINESTRING (-8235650.35660204 4978916.344912537, -8235650.4345256835 4978927.07552925, -8235650.389997888 4978940.496166472, -8235651.748095676 4979028.517188428, -8235652.30469313 4979040.482699221)" +1777,2nd Avenue,"LINESTRING (-8233623.918855538 4977188.105106801, -8233638.301333749 4977161.239272236)" +1778,East 60th Street,"LINESTRING (-8233623.918855538 4977188.105106801, -8233638.52397273 4977194.821576987, -8233665.708192381 4977209.400889212, -8233676.272412058 4977215.250256483, -8233779.688219005 4977273.082757076, -8233856.632251042 4977318.687636221, -8233871.682646195 4977328.519976123)" +1779,East 60th Street,"LINESTRING (-8233623.918855538 4977188.105106801, -8233611.161641892 4977182.432118076, -8233592.382043797 4977172.144323091, -8233512.554836949 4977128.186166855)" +1780,1st Avenue,"LINESTRING (-8233356.67415399 4977042.901147388, -8233353.145326132 4977049.367674561, -8233333.753470837 4977085.198191326, -8233312.146357674 4977125.129237902, -8233307.938480922 4977132.874439557)" +1781,East 60th Street,"LINESTRING (-8233356.67415399 4977042.901147388, -8233341.746210276 4977034.641634815, -8233160.863169684 4976932.280105707, -8233128.869948032 4976914.350414873, -8233120.66570156 4976909.9855688885, -8233107.808300372 4976903.048847969)" +1782,East 60th Street,"LINESTRING (-8234220.246235768 4977521.553299305, -8234240.328271908 4977532.8114896305)" +1783,Park Avenue,"LINESTRING (-8234220.246235768 4977521.553299305, -8234216.294393845 4977528.99017031, -8234174.349209715 4977604.461503662, -8234169.673791101 4977612.897868102)" +1784,East 60th Street,"LINESTRING (-8234240.328271908 4977532.8114896305, -8234251.894367 4977539.293038509, -8234263.894608107 4977545.906868329, -8234396.086503425 4977621.393029902, -8234408.7880573245 4977628.433143634)" +1785,Park Avenue,"LINESTRING (-8234240.328271908 4977532.8114896305, -8234245.549156025 4977523.390470469, -8234286.570388382 4977449.007360566, -8234291.9359878395 4977439.1161104115)" +1786,East 60th Street,"LINESTRING (-8233871.682646195 4977328.519976123, -8233885.118908736 4977337.029587705, -8233927.932384893 4977360.971177156, -8233971.335854354 4977385.030402584, -8234030.212733036 4977417.863918847, -8234037.470763834 4977422.037927928, -8234048.825351896 4977428.24015598)" +1787,3rd Avenue,"LINESTRING (-8233871.682646195 4977328.519976123, -8233867.964575205 4977335.104269064, -8233855.964334096 4977356.415069056, -8233839.923195472 4977384.310241648, -8233829.559350881 4977402.373069761, -8233825.718828447 4977409.045595673, -8233820.2641734 4977418.584082259)" +1788,Amsterdam Avenue,"LINESTRING (-8235595.153266557 4979740.005473176, -8235587.216186862 4979754.485679994, -8235560.198946447 4979804.380079921, -8235544.847988666 4979833.120193236, -8235540.205965901 4979840.411815998)" +1789,West 72nd Street,"LINESTRING (-8235595.153266557 4979740.005473176, -8235583.743018751 4979733.404858106, -8235296.1045864895 4979573.550790051, -8235282.28983768 4979565.862454532)" +1790,West 72nd Street,"LINESTRING (-8235595.153266557 4979740.005473176, -8235611.806662379 4979749.178718453, -8235635.083567903 4979762.056558096, -8235644.3787453845 4979767.304723641)" +1791,Hudson Boulevard East,"LINESTRING (-8237761.141126717 4976200.540309225, -8237758.436063091 4976205.037096745, -8237755.1298742145 4976209.871880406, -8237708.787570196 4976282.570268476, -8237700.037858221 4976295.223105657)" +1792,East 56th Street,"LINESTRING (-8234074.384306981 4976940.333780825, -8234066.825713557 4976936.2040670235, -8233848.78422694 4976814.885317776, -8233834.724575253 4976807.066886763)" +1793,3rd Avenue,"LINESTRING (-8234074.384306981 4976940.333780825, -8234069.553041081 4976947.755512862, -8234027.140315088 4977024.074759696, -8234019.303422937 4977038.756693587)" +1794,East 57th Street,"LINESTRING (-8234019.303422937 4977038.756693587, -8234032.862136915 4977046.29607362)" +1795,East 57th Street,"LINESTRING (-8234019.303422937 4977038.756693587, -8234012.902552217 4977035.18541034, -8233899.612706437 4976972.151741067, -8233794.326732044 4976913.321663119, -8233780.434059593 4976905.503153324)" +1796,3rd Avenue,"LINESTRING (-8234019.303422937 4977038.756693587, -8234011.655773918 4977053.394559554, -8233993.566356665 4977086.065297339)" +1797,East 63rd Street,"LINESTRING (-8233364.555573939 4977406.047367605, -8233369.6428746665 4977408.825137694, -8233456.360757996 4977456.238414564, -8233460.201280428 4977458.340124351, -8233469.507589858 4977463.425382072)" +1798,West 43rd Street,"LINESTRING (-8237274.352125428 4977157.256433248, -8237098.51185777 4977060.537140668, -8237082.604302537 4977051.792623354)" +1799,West 43rd Street,"LINESTRING (-8237274.352125428 4977157.256433248, -8237344.038126664 4977195.688692733, -8237384.558421313 4977218.04266923, -8237398.3843020685 4977225.464612252)" +1800,West 35th Street,"LINESTRING (-8237314.983739567 4976210.518477795, -8237326.282667883 4976216.778718359)" +1801,Dyer Avenue,"LINESTRING (-8237314.983739567 4976210.518477795, -8237308.582868845 4976217.675138111, -8237298.441663235 4976229.98989647, -8237290.938729555 4976238.836546302, -8237284.137108668 4976246.169572751, -8237249.405427541 4976280.909676659, -8237241.223444967 4976287.963519951)" +1802,West 62nd Street,"LINESTRING (-8236108.803660973 4978810.891506497, -8236096.458329445 4978804.056330595, -8236054.535409214 4978780.743271994, -8235936.837311598 4978715.375869142, -8235925.783286162 4978709.246319508, -8235810.378370055 4978645.11411602, -8235795.6730653215 4978636.882646639)" +1803,Amsterdam Avenue,"LINESTRING (-8236108.803660973 4978810.891506497, -8236101.690345512 4978823.738710277, -8236056.683875384 4978905.129225751, -8236012.055891526 4978987.990376871, -8236007.937070366 4978994.649286485)" +1804,West 87th Street,"LINESTRING (-8234175.128446149 4980823.978140411, -8234189.466396564 4980832.284965308, -8234476.314460439 4980991.74796865, -8234491.921453049 4981000.437203989)" +1805,Central Park West,"LINESTRING (-8234175.128446149 4980823.978140411, -8234179.269531208 4980816.50935521, -8234221.570937708 4980739.73410311, -8234229.752920281 4980724.340899442)" +1806,Central Park West,"LINESTRING (-8234175.128446149 4980823.978140411, -8234170.66453457 4980832.343774714, -8234128.084829341 4980908.8845155565, -8234123.810160893 4980916.720933372)" +1807,86th Street Transverse,"LINESTRING (-8234229.752920281 4980724.340899442, -8234214.969691904 4980715.152035849, -8234205.908285353 4980710.035680348, -8234195.8672672855 4980704.595880026, -8234182.174969918 4980697.876995705, -8234172.33432693 4980693.701586332, -8234158.653161513 4980688.379412186, -8234145.695572784 4980683.909964316, -8234106.333000839 4980671.471972128, -8234092.117501865 4980666.605575243, -8234082.065351848 4980662.988858887, -8234071.790562846 4980658.651741446, -8234063.964802642 4980654.843900939, -8234055.4265976995 4980650.286255958, -8234046.387455047 4980644.728872372, -8234037.103409515 4980638.318772483, -8234027.507669408 4980631.614635817, -8234007.603744455 4980615.971668161, -8233971.736604521 4980587.964349765, -8233962.374635345 4980581.304353593, -8233953.624923371 4980575.291248367, -8233944.0514471615 4980569.601589864, -8233933.097609268 4980563.25034708, -8233921.197555702 4980557.237252972, -8233907.739029263 4980550.680191247, -8233893.055988428 4980544.196643511, -8233878.094648866 4980538.212964955, -8233805.97075078 4980510.852751733, -8233717.516283398 4980477.259042933, -8233706.662633044 4980472.6426736, -8233696.844253956 4980468.305640707, -8233688.896042315 4980464.350856459, -8233676.250148159 4980457.867366047, -8233663.682177648 4980450.707598189, -8233653.51870814 4980444.429941573, -8233643.911836083 4980438.049376692, -8233634.6389224995 4980431.1836583065, -8233626.056189761 4980423.847489178, -8233618.8872145545 4980416.423115211, -8233613.031809338 4980407.925521837, -8233607.899980812 4980399.486742657, -8233603.157770504 4980389.945344318, -8233599.751394086 4980382.300471021, -8233596.8014275795 4980374.508587088, -8233593.9405166665 4980365.511174134, -8233591.346772532 4980354.720170181, -8233589.532264832 4980345.796283552, -8233582.441213269 4980307.880882537, -8233580.303879044 4980297.722108745, -8233578.222204568 4980289.842083097, -8233575.316765856 4980279.99205998, -8233572.066236726 4980270.05383777, -8233567.568929298 4980259.204133356, -8233562.926906531 4980249.354141144, -8233555.68000768 4980236.166928322, -8233548.767067304 4980224.979128507, -8233542.778078699 4980216.49640316, -8233536.154568995 4980208.101893648, -8233530.020865053 4980201.295142546, -8233523.441883147 4980194.444292017, -8233492.873550975 4980169.040321711)" +1808,West 86th Street,"LINESTRING (-8234229.752920281 4980724.340899442, -8234242.565793673 4980732.280084549, -8234286.97113855 4980757.376773262, -8234356.11167428 4980795.8232024, -8234460.262189867 4980853.147623958, -8234530.961198471 4980892.755923074, -8234545.532919815 4980900.812864758)" +1809,Central Park West,"LINESTRING (-8234229.752920281 4980724.340899442, -8234236.9552913355 4980710.726682227, -8234267.72399859 4980657.196234668, -8234280.603663676 4980634.408025535, -8234285.9803950805 4980625.322160852)" +1810,Central Park West,"LINESTRING (-8234229.752920281 4980724.340899442, -8234221.570937708 4980739.73410311, -8234179.269531208 4980816.50935521, -8234175.128446149 4980823.978140411)" +1811,Central Park West,"LINESTRING (-8234123.810160893 4980916.720933372, -8234118.900971349 4980925.365994468, -8234077.746155604 4981001.495791566, -8234073.460355208 4981009.346986329)" +1812,Central Park West,"LINESTRING (-8234123.810160893 4980916.720933372, -8234128.084829341 4980908.8845155565, -8234170.66453457 4980832.343774714, -8234175.128446149 4980823.978140411)" +1813,11th Avenue,"LINESTRING (-8237402.948401192 4977216.940400946, -8237415.40505221 4977183.049386119, -8237435.175393775 4977145.131564402, -8237438.425922907 4977139.399813459, -8237446.630169378 4977124.717728309)" +1814,11th Avenue,"LINESTRING (-8237402.948401192 4977216.940400946, -8237423.943257156 4977189.486612327, -8237436.956505629 4977168.161479656, -8237446.886204208 4977152.068457221, -8237450.515219608 4977146.322005403, -8237458.340979812 4977131.6693034135)" +1815,West 57th Street,"LINESTRING (-8236926.077966531 4978656.050221785, -8236945.358502337 4978673.218756613, -8236979.17736364 4978692.195314384, -8236987.39274206 4978696.105283619, -8236997.7899825005 4978699.2215008205)" +1816,West 57th Street,"LINESTRING (-8236926.077966531 4978656.050221785, -8236891.2572298115 4978636.544568581, -8236799.786004227 4978586.141670714, -8236760.545883721 4978564.490112039, -8236700.878636656 4978531.329365735, -8236684.214108886 4978522.260156409)" +1817,West 67th Street,"LINESTRING (-8235225.461237632 4978922.401094766, -8235238.006944244 4978929.633239631, -8235333.0737893805 4978981.419669187, -8235465.12096936 4979054.814872111, -8235475.028404041 4979060.3272519, -8235526.881022853 4979089.153373952, -8235542.076133345 4979097.605720617)" +1818,Central Park West,"LINESTRING (-8235225.461237632 4978922.401094766, -8235220.429596648 4978931.441276684, -8235179.185725308 4979005.600483248, -8235174.866529066 4979013.552970743)" +1819,Central Park West,"LINESTRING (-8235225.461237632 4978922.401094766, -8235229.813829722 4978914.389883638, -8235269.3656448 4978843.244737342, -8235273.072583845 4978836.159649909, -8235275.5216126405 4978831.558755636)" +1820,Central Park West,"LINESTRING (-8235174.866529066 4979013.552970743, -8235169.8571519805 4979022.799031811, -8235127.989891494 4979098.370107111, -8235123.55937576 4979106.7195634805)" +1821,Central Park West,"LINESTRING (-8235174.866529066 4979013.552970743, -8235179.185725308 4979005.600483248, -8235220.429596648 4978931.441276684, -8235225.461237632 4978922.401094766)" +1822,West 66th Street,"LINESTRING (-8235275.5216126405 4978831.558755636, -8235289.581264327 4978838.467447532, -8235381.709274909 4978889.885908005, -8235521.036749585 4978966.602519089, -8235526.335557347 4978969.513028942, -8235576.395932358 4978997.64800223, -8235592.080848609 4979006.614755785)" +1823,Central Park West,"LINESTRING (-8235275.5216126405 4978831.558755636, -8235280.4085382875 4978822.548064823, -8235322.164479284 4978746.655741083, -8235327.051404929 4978738.115502947)" +1824,Central Park West,"LINESTRING (-8235275.5216126405 4978831.558755636, -8235273.072583845 4978836.159649909, -8235269.3656448 4978843.244737342, -8235229.813829722 4978914.389883638, -8235225.461237632 4978922.401094766)" +1825,Central Park West,"LINESTRING (-8235073.042590838 4979198.872752395, -8235068.467359765 4979207.016496025, -8235026.922925802 4979282.11859626, -8235022.1473196475 4979290.424109636)" +1826,Central Park West,"LINESTRING (-8235073.042590838 4979198.872752395, -8235077.818196992 4979190.405618206, -8235119.139991976 4979115.039627456, -8235123.55937576 4979106.7195634805)" +1827,Central Park West,"LINESTRING (-8235327.051404929 4978738.115502947, -8235322.164479284 4978746.655741083, -8235280.4085382875 4978822.548064823, -8235275.5216126405 4978831.558755636)" +1828,Central Park West,"LINESTRING (-8235327.051404929 4978738.115502947, -8235331.415128968 4978730.48662184, -8235362.5734544415 4978674.041906302, -8235373.171069965 4978654.697906968, -8235377.95780807 4978646.304739843)" +1829,65th Street Transverse,"LINESTRING (-8235327.051404929 4978738.115502947, -8235310.631780038 4978731.500865804, -8235305.043541599 4978729.4870771635, -8235298.9654974025 4978727.781971778, -8235291.60727906 4978726.444346211, -8235284.015289788 4978725.871078165, -8235276.311981025 4978725.841679804, -8235268.831311244 4978726.31205358, -8235261.7068638345 4978726.973516743, -8235254.560152525 4978728.384638303, -8235246.990427152 4978730.383727529, -8235222.043729263 4978738.747568509, -8235215.186448632 4978740.482074213, -8235207.739174698 4978741.716807275, -8235201.349435926 4978741.73150648, -8235194.748190121 4978740.805456666, -8235188.35845135 4978739.39433331, -8235181.078156652 4978737.174754281, -8235172.384104421 4978733.867435467, -8235155.942215632 4978726.767728199)" +1830,West 69th Street,"LINESTRING (-8235123.55937576 4979106.7195634805, -8235136.617152031 4979114.010643893, -8235424.945765134 4979273.107489738, -8235439.539750376 4979281.163095173)" +1831,Central Park West,"LINESTRING (-8235123.55937576 4979106.7195634805, -8235119.139991976 4979115.039627456, -8235077.818196992 4979190.405618206, -8235073.042590838 4979198.872752395)" +1832,Central Park West,"LINESTRING (-8235123.55937576 4979106.7195634805, -8235127.989891494 4979098.370107111, -8235169.8571519805 4979022.799031811, -8235174.866529066 4979013.552970743)" +1833,West 79th Street,"LINESTRING (-8235732.688497431 4980689.614391563, -8235724.873869178 4980685.07143248, -8235711.137044013 4980677.279306935)" +1834,West 79th Street,"LINESTRING (-8235732.688497431 4980689.614391563, -8235759.071216748 4980704.213623901, -8235793.435543557 4980723.444065974, -8235812.838530801 4980734.16196641, -8235875.934418184 4980769.3297004085)" +1835,,"LINESTRING (-8234019.7264370015 4977069.237575749, -8233993.566356665 4977086.065297339)" +1836,3rd Avenue,"LINESTRING (-8234019.7264370015 4977069.237575749, -8233990.761105498 4977117.384042389, -8233979.206142355 4977134.770324769, -8233972.961118919 4977144.044001144)" +1837,West 42nd Street,"LINESTRING (-8237446.630169378 4977124.717728309, -8237458.340979812 4977131.6693034135)" +1838,11th Avenue,"LINESTRING (-8237446.630169378 4977124.717728309, -8237455.6470481325 4977108.316145766, -8237494.864904739 4977034.465275193, -8237500.185976399 4977024.7067143535)" +1839,West 42nd Street,"LINESTRING (-8237446.630169378 4977124.717728309, -8237438.16988808 4977119.706130722, -8237346.13093309 4977068.017750768, -8237344.7505714055 4977067.238826464, -8237330.601864126 4977059.258530085, -8237153.993491981 4976959.821350641, -8237138.3308396265 4976951.003440932)" +1840,West 41st Street,"LINESTRING (-8237500.185976399 4977024.7067143535, -8237513.154697077 4977031.423072198)" +1841,11th Avenue,"LINESTRING (-8237500.185976399 4977024.7067143535, -8237505.072902045 4977016.1385884015, -8237545.904891268 4976944.169566381, -8237547.363176597 4976940.421959786, -8237547.797322612 4976936.39512136, -8237547.407704394 4976932.529945893)" +1842,West 40th Street,"LINESTRING (-8237547.407704394 4976932.529945893, -8237542.398327309 4976930.2079020515, -8237485.324824378 4976899.330650013, -8237397.293371059 4976851.28813254, -8237372.714027492 4976836.312553645)" +1843,Park Avenue,"LINESTRING (-8235150.910574647 4975858.687649356, -8235143.363113171 4975867.225370525, -8235141.314834542 4975869.0034510875, -8235138.55411117 4975870.3847700935, -8235135.782255849 4975870.899091053, -8235133.84529671 4975870.869701282, -8235131.396267912 4975870.208431486, -8235129.303461484 4975869.414907793, -8235094.070842649 4975850.105851085, -8235091.488230462 4975849.062516537, -8235088.98354192 4975848.709840094, -8235086.746020154 4975848.680450391, -8235084.2079357635 4975848.915568017, -8235080.779295447 4975849.650310636, -8235078.141023516 4975850.811204085, -8235075.257848705 4975852.42763823, -8235073.031458887 4975854.337969838, -8235070.560166194 4975857.497365242, -8235013.987600971 4975961.9931070125, -8234968.680568218 4976045.6669198675, -8234963.392892406 4976057.040970827, -8234957.303716259 4976071.69206115, -8234950.557755117 4976084.829567044, -8234948.754379366 4976090.737041894, -8234948.3647611495 4976095.483597658, -8234948.498344538 4976099.348441981, -8234949.967761816 4976118.261219321, -8234951.069824776 4976122.228939493, -8234952.739617136 4976125.946841708, -8234955.567132203 4976128.915286392, -8234959.162751757 4976130.97262482, -8234967.901331782 4976135.46938032, -8234970.47281202 4976137.012385135, -8234971.886569552 4976138.672952494, -8234972.921840818 4976140.862550594, -8234973.556361916 4976143.434226842, -8234972.788257428 4976145.623826008, -8234941.273709587 4976204.904838259, -8234940.082591034 4976208.681553507, -8234937.299603763 4976217.542879454)" +1844,West 55th Street,"LINESTRING (-8237061.431335387 4978476.57616358, -8237077.739640788 4978484.925088396)" +1845,12th Avenue,"LINESTRING (-8237061.431335387 4978476.57616358, -8237067.898997802 4978449.3393158605, -8237075.914001139 4978421.264716919, -8237082.504114994 4978402.861934591, -8237089.1053607995 4978385.252914954)" +1846,Columbus Avenue,"LINESTRING (-8235650.523581277 4978900.513599545, -8235670.43863818 4978866.058165822)" +1847,Broadway,"LINESTRING (-8235650.523581277 4978900.513599545, -8235650.501317378 4978905.570209262, -8235650.35660204 4978916.344912537)" +1848,Columbus Avenue,"LINESTRING (-8235643.833279881 4978912.684745971, -8235648.586622137 4978904.482449974, -8235650.523581277 4978900.513599545)" +1849,West 65th Street,"LINESTRING (-8235643.833279881 4978912.684745971, -8235628.716093029 4978904.203160446, -8235397.2160799755 4978775.436839571, -8235393.2419741545 4978773.187853847, -8235340.509931366 4978743.877590509, -8235327.051404929 4978738.115502947)" +1850,Amsterdam Avenue,"LINESTRING (-8235658.961598678 4979622.7533405945, -8235654.352971759 4979630.397619278, -8235649.254539081 4979638.747530523)" +1851,Broadway,"LINESTRING (-8235658.961598678 4979622.7533405945, -8235659.852154605 4979597.306756016, -8235661.933829083 4979539.739799533, -8235662.746461365 4979525.730323415)" +1852,West 71st Street,"LINESTRING (-8235649.254539081 4979638.747530523, -8235658.193494193 4979643.745720248)" +1853,Amsterdam Avenue,"LINESTRING (-8235649.254539081 4979638.747530523, -8235648.018892734 4979640.820308891, -8235640.627278544 4979653.4921975685, -8235626.567626857 4979679.232940853)" +1854,3rd Avenue,"LINESTRING (-8233993.566356665 4977086.065297339, -8233980.196885822 4977110.638231943, -8233975.365619921 4977132.756865293, -8233972.961118919 4977144.044001144)" +1855,West 37th Street,"LINESTRING (-8237574.035326591 4976590.916200261, -8237694.226980802 4976656.680877805, -8237707.396076561 4976664.1317865085)" +1856,Hudson Boulevard West,"LINESTRING (-8237574.035326591 4976590.916200261, -8237579.412057997 4976583.20082018, -8237627.902828187 4976513.689194365, -8237633.580122217 4976505.547695917)" +1857,West 37th Street,"LINESTRING (-8237085.08672718 4976317.560326279, -8237093.201918059 4976322.130645476, -8237141.158354693 4976348.391652846, -8237235.846713562 4976401.060836169, -8237263.008669315 4976416.241487758, -8237379.5379122775 4976480.770542023, -8237393.742279303 4976488.6327993525)" +1858,,"LINESTRING (-8237085.08672718 4976317.560326279, -8237090.263083503 4976310.462374979, -8237109.699466595 4976276.721459615, -8237112.872072083 4976271.519255679, -8237115.666191301 4976268.080512227, -8237118.538234164 4976265.817408221, -8237121.154242196 4976263.951082584, -8237124.627410311 4976262.378666774, -8237128.779627318 4976261.261810837, -8237133.4884417765 4976260.453559912, -8237137.763110224 4976260.365387088, -8237141.848535537 4976260.703382918, -8237145.566606528 4976261.526329339, -8237149.095434387 4976262.613794357, -8237152.245775975 4976263.965778061, -8237192.276264866 4976285.671020323, -8237196.406217975 4976288.051693025, -8237199.267128888 4976290.314802182, -8237201.604838194 4976292.489738746, -8237203.764436315 4976295.8697086945, -8237205.144798 4976299.132115579, -8237206.057617825 4976302.570869962, -8237206.2468609605 4976305.980234476, -8237206.013090028 4976309.551251169, -8237205.078006307 4976313.283920221, -8237203.797832163 4976317.001895141, -8237201.571442345 4976320.719871476, -8237198.332045165 4976324.849325112)" +1859,East 70th Street,"LINESTRING (-8232527.900545035 4977780.450866351, -8232538.409104965 4977786.271180048, -8232586.321013804 4977812.859475359, -8232600.7146239625 4977820.825689593)" +1860,West 65th Street,"LINESTRING (-8236455.7865137765 4979366.702862801, -8236475.523459495 4979377.301672911, -8236486.054283323 4979382.946536249)" +1861,Dyer Avenue,"LINESTRING (-8237345.463016145 4976171.722710236, -8237368.316907605 4976130.164384671, -8237376.36530679 4976116.189188316)" +1862,Dyer Avenue,"LINESTRING (-8237345.463016145 4976171.722710236, -8237321.907811893 4976202.347841214, -8237314.983739567 4976210.518477795)" +1863,Dyer Avenue,"LINESTRING (-8237645.446779935 4975782.803653406, -8237633.324087388 4975783.15632747, -8237625.297952101 4975785.625046268, -8237619.297831548 4975790.430232865, -8237607.5202294225 4975806.829603082)" From 56fa0c23036c2ed47c21af23a1d34c67a25e4d5f Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Fri, 9 Jun 2023 15:10:32 -0700 Subject: [PATCH 45/63] Update to CMake 3.26.4 (#1196) Updates minimum required CMake version to 3.26.4 Authors: - Vyas Ramasubramani (https://github.com/vyasr) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1196 --- conda/environments/all_cuda-118_arch-x86_64.yaml | 2 +- conda/recipes/cuspatial/conda_build_config.yaml | 3 +++ conda/recipes/cuspatial/meta.yaml | 2 +- conda/recipes/libcuspatial/conda_build_config.yaml | 2 +- cpp/CMakeLists.txt | 2 +- dependencies.yaml | 2 +- docs/source/developer_guide/build.md | 2 +- java/src/main/native/CMakeLists.txt | 2 +- python/cuspatial/CMakeLists.txt | 2 +- python/cuspatial/pyproject.toml | 2 +- 10 files changed, 12 insertions(+), 9 deletions(-) diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 0fbe91c42..530f2cb41 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -7,7 +7,7 @@ channels: - nvidia dependencies: - c-compiler -- cmake>=3.23.1,!=3.25.0 +- cmake>=3.26.4 - cudatoolkit=11.8 - cudf==23.8.* - cuml==23.8.* diff --git a/conda/recipes/cuspatial/conda_build_config.yaml b/conda/recipes/cuspatial/conda_build_config.yaml index ad733ac69..b4b06a9b6 100644 --- a/conda/recipes/cuspatial/conda_build_config.yaml +++ b/conda/recipes/cuspatial/conda_build_config.yaml @@ -9,3 +9,6 @@ cuda_compiler: sysroot_version: - "2.17" + +cmake_version: + - ">=3.26.4" diff --git a/conda/recipes/cuspatial/meta.yaml b/conda/recipes/cuspatial/meta.yaml index d39ace7f7..88b82e665 100644 --- a/conda/recipes/cuspatial/meta.yaml +++ b/conda/recipes/cuspatial/meta.yaml @@ -43,7 +43,7 @@ requirements: - ninja - sysroot_{{ target_platform }} {{ sysroot_version }} host: - - cmake >=3.23.1,!=3.25.0 + - cmake {{ cmake_version }} - cudf ={{ minor_version }} - cython >=0.29,<0.30 - libcuspatial ={{ version }} diff --git a/conda/recipes/libcuspatial/conda_build_config.yaml b/conda/recipes/libcuspatial/conda_build_config.yaml index 6056ed6b2..f3da4ec36 100644 --- a/conda/recipes/libcuspatial/conda_build_config.yaml +++ b/conda/recipes/libcuspatial/conda_build_config.yaml @@ -8,7 +8,7 @@ cuda_compiler: - nvcc cmake_version: - - ">=3.23.1,!=3.25.0" + - ">=3.26.4" gtest_version: - ">=1.13.0" diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index c3477d10d..ad47f587a 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -14,7 +14,7 @@ # limitations under the License. #============================================================================= -cmake_minimum_required(VERSION 3.23.1 FATAL_ERROR) +cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR) include(../fetch_rapids.cmake) include(rapids-cmake) diff --git a/dependencies.yaml b/dependencies.yaml index f17e1af12..4944bfbef 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -76,7 +76,7 @@ dependencies: - output_types: [conda, requirements, pyproject] packages: - ninja - - cmake>=3.23.1,!=3.25.0 + - cmake>=3.26.4 - output_types: conda packages: - c-compiler diff --git a/docs/source/developer_guide/build.md b/docs/source/developer_guide/build.md index 26f21cb68..ea6da6bc3 100644 --- a/docs/source/developer_guide/build.md +++ b/docs/source/developer_guide/build.md @@ -3,7 +3,7 @@ ## Pre-requisites - gcc >= 7.5 -- cmake >= 3.23 +- cmake >= 3.26.4 - miniconda ## Fetch cuSpatial repository diff --git a/java/src/main/native/CMakeLists.txt b/java/src/main/native/CMakeLists.txt index c7b649be1..071f0ca37 100755 --- a/java/src/main/native/CMakeLists.txt +++ b/java/src/main/native/CMakeLists.txt @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. #============================================================================= -cmake_minimum_required(VERSION 3.23.1 FATAL_ERROR) +cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR) include(../../../../fetch_rapids.cmake) diff --git a/python/cuspatial/CMakeLists.txt b/python/cuspatial/CMakeLists.txt index 14d57f1cd..bf9f575a8 100644 --- a/python/cuspatial/CMakeLists.txt +++ b/python/cuspatial/CMakeLists.txt @@ -12,7 +12,7 @@ # the License. # ============================================================================= -cmake_minimum_required(VERSION 3.23.1 FATAL_ERROR) +cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR) set(cuspatial_version 23.08.00) diff --git a/python/cuspatial/pyproject.toml b/python/cuspatial/pyproject.toml index 10b2555ae..8db1ffa61 100644 --- a/python/cuspatial/pyproject.toml +++ b/python/cuspatial/pyproject.toml @@ -15,7 +15,7 @@ [build-system] build-backend = "setuptools.build_meta" requires = [ - "cmake>=3.23.1,!=3.25.0", + "cmake>=3.26.4", "cudf==23.8.*", "cython>=0.29,<0.30", "ninja", From f43d18b32bb6bfe513243e9142fb38517beebd4d Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 12 Jun 2023 11:11:35 -0400 Subject: [PATCH 46/63] Remove Stale Demo Scripts (#1180) This PR removes scripts under `python/cuspatial/cuspatial/demo`. This decision is made mainly due to: 1. The scripts are outdated, most of them are using deprecated python APIs. 2. The scripts only demonstrates a single use of cuspatial API, not an end-to-end use case. These demos are sufficiently covered by `user_guide` at the moment. And is not worth converting into notebooks. Closes #209 Closes #312 Closes #341 Closes #885 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1180 --- python/cuspatial/demos/README.md | 6 -- .../cuspatial/demos/pip_test_gdal_locust.py | 43 ----------- .../demos/pip_test_shapely_locust.py | 39 ---------- .../demos/pip_verify_shapely_locust.py | 54 -------------- python/cuspatial/demos/stq_test_soa_locust.py | 16 ----- .../cuspatial/demos/traj_test_soa_locust.py | 71 ------------------- 6 files changed, 229 deletions(-) delete mode 100644 python/cuspatial/demos/README.md delete mode 100644 python/cuspatial/demos/pip_test_gdal_locust.py delete mode 100644 python/cuspatial/demos/pip_test_shapely_locust.py delete mode 100644 python/cuspatial/demos/pip_verify_shapely_locust.py delete mode 100644 python/cuspatial/demos/stq_test_soa_locust.py delete mode 100644 python/cuspatial/demos/traj_test_soa_locust.py diff --git a/python/cuspatial/demos/README.md b/python/cuspatial/demos/README.md deleted file mode 100644 index 6625c6532..000000000 --- a/python/cuspatial/demos/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Demo files - -`cuspatial` demos typically depend on third party libraries and datasets. You -can see the performance difference between GPU spatial code and our competitors -by running these demos. - diff --git a/python/cuspatial/demos/pip_test_gdal_locust.py b/python/cuspatial/demos/pip_test_gdal_locust.py deleted file mode 100644 index be740c27a..000000000 --- a/python/cuspatial/demos/pip_test_gdal_locust.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -pip demo directly using gdal/ogr for python; not for performance comparisons. -To run the demo, first install python-gdal by `conda install -c conda-forge -gdal` under cudf_dev environment -""" - -import numpy as np -from osgeo import ogr - -data_dir = "/home/jianting/cuspatial/data/" -shapefile = data_dir + "its_4326_roi.shp" -driver = ogr.GetDriverByName("ESRI Shapefile") -spatialReference = ogr.osr.SpatialReference() -spatialReference.SetWellKnownGeogCS("WGS84") -pt = ogr.Geometry(ogr.wkbPoint) -pt.AssignSpatialReference(spatialReference) -pnt_x = np.array( - [-90.666418409895840, -90.665136925928721, -90.671840534675397], - dtype=np.float64, -) -pnt_y = np.array( - [42.492199401857071, 42.492104092138952, 42.490649501411141], - dtype=np.float64, -) - -for i in range(3): - pt.SetPoint(0, pnt_x[i], pnt_y[i]) - res = "" - - """ - features can not be saved for later reuse - known issue: https://trac.osgeo.org/gdal/wiki/PythonGotchas - """ - - dataSource = driver.Open(shapefile, 0) - layer = dataSource.GetLayer() - for f in layer: - pip = pt.Within(f.geometry()) - if pip: - res += "1" - else: - res += "0" - print(res) diff --git a/python/cuspatial/demos/pip_test_shapely_locust.py b/python/cuspatial/demos/pip_test_shapely_locust.py deleted file mode 100644 index d46efa5e2..000000000 --- a/python/cuspatial/demos/pip_test_shapely_locust.py +++ /dev/null @@ -1,39 +0,0 @@ -""" -PIP demo directly using shapely, more efficient than using python gdal/ogr -directly polygons are created only once and stored for reuse - -To run the demo, first install python gdal and pyshp by `conda install -c -conda-forge gdal pyshp` under cudf_dev environment -""" - -import numpy as np -import shapefile -from shapely.geometry import Point, Polygon - -data_dir = "/home/jianting/cuspatial/data/" - -plyreader = shapefile.Reader(data_dir + "its_4326_roi.shp") -polygon = plyreader.shapes() -plys = [] -for shape in polygon: - plys.append(Polygon(shape.points)) - -pnt_x = np.array( - [-90.666418409895840, -90.665136925928721, -90.671840534675397], - dtype=np.float64, -) -pnt_y = np.array( - [42.492199401857071, 42.492104092138952, 42.490649501411141], - dtype=np.float64, -) - -for i in range(3): - pt = Point(pnt_x[i], pnt_y[i]) - res = "" - for j in range(len(plys)): - pip = plys[len(plys) - 1 - j].contains(pt) - if pip: - res += "1" - else: - res += "0" - print(res) diff --git a/python/cuspatial/demos/pip_verify_shapely_locust.py b/python/cuspatial/demos/pip_verify_shapely_locust.py deleted file mode 100644 index 86a108e8c..000000000 --- a/python/cuspatial/demos/pip_verify_shapely_locust.py +++ /dev/null @@ -1,54 +0,0 @@ -""" -verify the correctness of GPU-based implementation by comparing with shapely -python package GPU C++ kernel time 0.966ms, GPU C++ libcuspatial end-to-end -time 1.104ms, GPU python cuspaital end-to-end time 1.270ms shapely python -end-to-end time 127659.4, 100,519X speedup (127659.4/1.27) -""" - -import time - -import shapefile -from shapely.geometry import Point, Polygon - -import cuspatial - -data_dir = "/home/jianting/cuspatial/data/" -plyreader = shapefile.Reader(data_dir + "its_4326_roi.shp") -polygon = plyreader.shapes() -plys = [] -for shape in polygon: - plys.append(Polygon(shape.points)) - -pnt_lon, pnt_lat = cuspatial.read_points_lonlat(data_dir + "locust.location") -fpos, rpos, plyx, plyy = cuspatial.read_polygon(data_dir + "itsroi.ply") - -start = time.time() -bm = cuspatial.point_in_polygon(pnt_lon, pnt_lat, fpos, rpos, plyx, plyy) -end = time.time() -print("Python GPU Time in ms (end-to-end)={}".format((end - start) * 1000)) - -bma = bm.data.to_array() -pntx = pnt_lon.data.to_array() -pnty = pnt_lat.data.to_array() - -start = time.time() -mis_match = 0 -for i in range(pnt_lon.data.size): - pt = Point(pntx[i], pnty[i]) - res = 0 - for j in range(len(plys)): - pip = plys[len(plys) - 1 - j].contains(pt) - if pip: - res |= 0x01 << (len(plys) - 1 - j) - if res != bma[i]: - mis_match = mis_match + 1 - -end = time.time() -print(end - start) -print( - "python(shapely) CPU Time in ms (end-to-end)={}".format( - (end - start) * 1000 - ) -) - -print("CPU and GPU results mismatch={}".format(mis_match)) diff --git a/python/cuspatial/demos/stq_test_soa_locust.py b/python/cuspatial/demos/stq_test_soa_locust.py deleted file mode 100644 index 543f0b74a..000000000 --- a/python/cuspatial/demos/stq_test_soa_locust.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -GPU-based spatial window query demo using 1.3 million points read from file -and (x1,x2,y1,y2)=[-180,180,-90,90] as the query window num should be the same -as x.data.size, both are 1338671 -""" - -import cuspatial - -data_dir = "./data/" -data = cuspatial.read_points_lonlat(data_dir + "locust.location") - -points_inside = cuspatial.window_points( - -180, -90, 180, 90, data["lon"], data["lat"] -) -print(points_inside.shape[0]) -assert points_inside.shape[0] == data.shape[0] diff --git a/python/cuspatial/demos/traj_test_soa_locust.py b/python/cuspatial/demos/traj_test_soa_locust.py deleted file mode 100644 index b958501ff..000000000 --- a/python/cuspatial/demos/traj_test_soa_locust.py +++ /dev/null @@ -1,71 +0,0 @@ -""" -GPU-based coordinate transformation demo: (log/lat)==>(x/y), relative to a -camera origin - -Note: camera configuration is read from a CSV file using Panda -""" - -import numpy as np -import pandas as pd - -import cuspatial - - -def get_ts_struct(ts): - y = ts & 0x3F - ts = ts >> 6 - m = ts & 0xF - ts = ts >> 4 - d = ts & 0x1F - ts = ts >> 5 - hh = ts & 0x1F - ts = ts >> 5 - mm = ts & 0x3F - ts = ts >> 6 - ss = ts & 0x3F - ts = ts >> 6 - wd = ts & 0x8 - ts = ts >> 3 - yd = ts & 0x1FF - ts = ts >> 9 - ms = ts & 0x3FF - ts = ts >> 10 - pid = ts & 0x3FF - - return y, m, d, hh, mm, ss, wd, yd, ms, pid - - -data_dir = "./data/" -df = pd.read_csv(data_dir + "its_camera_2.csv") -this_cam = df.loc[df["cameraIdString"] == "HWY_20_AND_LOCUST"] -cam_lon = np.double(this_cam.iloc[0]["originLon"]) -cam_lat = np.double(this_cam.iloc[0]["originLat"]) - -lonlats = cuspatial.read_points_lonlat(data_dir + "locust.location") -ids = cuspatial.read_uint(data_dir + "locust.objectid") -ts = cuspatial.read_its_timestamps(data_dir + "locust.time") - -# examine binary representatons -ts_0 = ts.data.to_array()[0] -out1 = format(ts_0, "016x") -print(out1) -out2 = format(ts_0, "064b") -print(out2) - -y, m, d, hh, mm, ss, wd, yd, ms, pid = get_ts_struct(ts_0) - -xys = cuspatial.sinusoidal_projection( - cam_lon, cam_lat, lonlats["lon"], lonlats["lat"] -) -num_traj, trajectories = cuspatial.derive(xys["x"], xys["y"], ids, ts) -# = num_traj, tid, len, pos = -y, m, d, hh, mm, ss, wd, yd, ms, pid = get_ts_struct(ts_0) -distspeed = cuspatial.distance_and_speed( - xys["x"], xys["y"], ts, trajectories["length"], trajectories["position"] -) -print(distspeed) - -boxes = cuspatial.spatial_bounds( - xys["x"], xys["y"], trajectories["length"], trajectories["position"] -) -print(boxes.head()) From 9d91cd3063acc49a3d86e8bb49640d5958c6b615 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 20 Jun 2023 13:13:41 -0400 Subject: [PATCH 47/63] Updates Build Instructions to Adjust for Devcontainer Instructions and Remove Stale Infomation (#1179) closes #1174 Minor improvement: - updates build development environment to point to devcontainers, not rapids-compose. - Move point-linestring python test to correct location. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Ben Jarmak (https://github.com/jarmak-nv) - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1179 --- docs/source/developer_guide/build.md | 60 ++++++++++++------ .../development_environment.md | 36 +++++++---- .../test_point_linestring_distance.py | 0 test_fixtures/shapefiles/empty_poly.cpg | 1 - test_fixtures/shapefiles/empty_poly.dbf | Bin 66 -> 0 bytes test_fixtures/shapefiles/empty_poly.sbn | Bin 108 -> 0 bytes test_fixtures/shapefiles/empty_poly.sbx | Bin 108 -> 0 bytes test_fixtures/shapefiles/empty_poly.shp | Bin 100 -> 0 bytes test_fixtures/shapefiles/empty_poly.shx | Bin 100 -> 0 bytes test_fixtures/shapefiles/one_poly.cpg | 1 - test_fixtures/shapefiles/one_poly.dbf | Bin 86 -> 0 bytes test_fixtures/shapefiles/one_poly.sbn | Bin 132 -> 0 bytes test_fixtures/shapefiles/one_poly.sbx | Bin 116 -> 0 bytes test_fixtures/shapefiles/one_poly.shp | Bin 236 -> 0 bytes test_fixtures/shapefiles/one_poly.shx | Bin 108 -> 0 bytes test_fixtures/shapefiles/two_polys.dbf | Bin 90 -> 0 bytes test_fixtures/shapefiles/two_polys.sbn | Bin 164 -> 0 bytes test_fixtures/shapefiles/two_polys.sbx | Bin 124 -> 0 bytes test_fixtures/shapefiles/two_polys.shp | Bin 372 -> 0 bytes test_fixtures/shapefiles/two_polys.shx | Bin 116 -> 0 bytes 20 files changed, 63 insertions(+), 35 deletions(-) rename python/cuspatial/cuspatial/tests/{ => spatial/distance}/test_point_linestring_distance.py (100%) delete mode 100644 test_fixtures/shapefiles/empty_poly.cpg delete mode 100644 test_fixtures/shapefiles/empty_poly.dbf delete mode 100644 test_fixtures/shapefiles/empty_poly.sbn delete mode 100644 test_fixtures/shapefiles/empty_poly.sbx delete mode 100644 test_fixtures/shapefiles/empty_poly.shp delete mode 100644 test_fixtures/shapefiles/empty_poly.shx delete mode 100644 test_fixtures/shapefiles/one_poly.cpg delete mode 100644 test_fixtures/shapefiles/one_poly.dbf delete mode 100644 test_fixtures/shapefiles/one_poly.sbn delete mode 100644 test_fixtures/shapefiles/one_poly.sbx delete mode 100644 test_fixtures/shapefiles/one_poly.shp delete mode 100644 test_fixtures/shapefiles/one_poly.shx delete mode 100644 test_fixtures/shapefiles/two_polys.dbf delete mode 100644 test_fixtures/shapefiles/two_polys.sbn delete mode 100644 test_fixtures/shapefiles/two_polys.sbx delete mode 100644 test_fixtures/shapefiles/two_polys.shp delete mode 100644 test_fixtures/shapefiles/two_polys.shx diff --git a/docs/source/developer_guide/build.md b/docs/source/developer_guide/build.md index ea6da6bc3..c7d56d41d 100644 --- a/docs/source/developer_guide/build.md +++ b/docs/source/developer_guide/build.md @@ -18,30 +18,50 @@ git clone https://github.com/rapidsai/cuspatial.git $CUSPATIAL_HOME 2. clone the cuSpatial repo ```shell -conda env update --file conda/environments/all_cuda-118_arch-x86_64.yaml +conda env create -n cuspatial --file conda/environments/all_cuda-118_arch-x86_64.yaml ``` -## Build and install cuSpatial +## Build cuSpatial -1. Compile and install - ```shell - cd $CUSPATIAL_HOME && \ - chmod +x ./build.sh && \ - ./build.sh - ``` +### From the cuSpatial Dev Container: -2. Run C++/Python test code +Execute `build-cuspatial-cpp to build `libcuspatial`. The following options may be added. + - `-DBUILD_TESTS=ON`: build `libcuspatial` unit tests. + - `-DBUILD_BENCHMARKS=ON`: build `libcuspatial` benchmarks. + - `-DCMAKE_BUILD_TYPE=Debug`: Create a Debug build of `libcuspatial` (default is Release). +In addition, `build-cuspatial-python` to build cuspatial cython components. - Some tests using inline data can be run directly, e.g.: +### From Bare Metal: - ```shell - $CUSPATIAL_HOME/cpp/build/gtests/LEGACY_HAUSDORFF_TEST - $CUSPATIAL_HOME/cpp/build/gtests/POINT_IN_POLYGON_TEST - python python/cuspatial/cuspatial/tests/legacy/test_hausdorff_distance.py - python python/cuspatial/cuspatial/tests/test_pip.py - ``` +Compile libcuspatial (C++), cuspatial (cython) and C++ tests: +```shell +cd $CUSPATIAL_HOME && \ +chmod +x ./build.sh && \ +./build.sh libcuspatial cuspatial tests +``` +Additionally, the following options are also commonly used: +- `benchmarks`: build libcuspatial benchmarks +- `clean`: remove all existing build artifacts and configuration +Execute `./build.sh -h` for full list of available options. + +## Validate Installation with C++ and Python Tests + +```{note} +To manage difference between branches and build types, the build directories are located at +`$CUSPATIAL_HOME/cpp/build/[release|debug]` depending on build type, and `$CUSPATIAL_HOME/cpp/build/latest`. +is a symbolic link to the most recent build directory. On bare metal builds, remove the extra `latest` level in +the path below. +``` + +- C++ tests are located within the `$CUSPATIAL_HOME/cpp/build/latest/gtests` directory. +- Python tests are located within the `$CUSPATIAL_HOME/python/cuspatial/cuspatial/tests` directory. - Some other tests involve I/O from data files under `$CUSPATIAL_HOME/test_fixtures`. - For example, `$CUSPATIAL_HOME/cpp/build/gtests/SHAPEFILE_READER_TEST` requires three - pre-generated polygon shapefiles that contain 0, 1 and 2 polygons, respectively. They are available at - `$CUSPATIAL_HOME/test_fixtures/shapefiles`
    +Execute C++ tests: +```shell +ninja -C $CUSPATIAL_HOME/cpp/build/latest test +``` + +Execute Python tests: +```shell +pytest $CUSPATIAL_HOME/python/cuspatial/cuspatial/tests/ +``` diff --git a/docs/source/developer_guide/development_environment.md b/docs/source/developer_guide/development_environment.md index abac8ea8a..0a0e47992 100644 --- a/docs/source/developer_guide/development_environment.md +++ b/docs/source/developer_guide/development_environment.md @@ -1,15 +1,25 @@ # Creating a Development Environment -cuSpatial follows the RAPIDS release schedule, so developers are encouraged to develop -using the latest development branch of RAPIDS libraries that cuspatial depends on. Other -cuspatial dependencies can be found in `conda/environments/`. - -Maintaining a local development environment can be an arduous task, especially after each -RAPIDS release. Most cuspatial developers today use -[rapids-compose](https://github.com/trxcllnt/rapids-compose) to setup their development environment. -It contains helpful scripts to build a RAPIDS development container image with the required -dependencies and RAPIDS libraries automatically fetched and correctly versioned. It also provides -script commands for simple building and testing of all RAPIDS libraries, including cuSpatial. -`rapids-compose` is the recommended way to set up your environment to develop for cuspatial. - -For developers who would like to build from conda or from source, see the [build page](https://docs.rapids.ai/api/cuspatial/stable/developer_guide/build.html). +cuSpatial recommends using [Dev Containers](https://containers.dev/) to setup the development environment. +To setup Dev Containers for cuspatial, please refer to [documentation](https://github.com/rapidsai/cuspatial/tree/main/.devcontainer). + +## From Bare Metal + +RAPIDS keeps a single source of truth for library dependencies in `dependencies.yaml`. This file divides +the dependencies into several dimensions: building, testing, documentations, notebooks etc. As a developer, +you generally want to generate an environment recipe that includes everything that the library *may* use. + +To do so, install the rapids-dependency-file-generator via pip: +```shell +pip install rapids-dependency-file-generator +``` + +And run under the repo root: +```shell +rapids-dependency-file-generator --clean +``` + +The environment recipe is generated within the `conda/environments` directory. To continue the next step of building, +see the [build page](https://docs.rapids.ai/api/cuspatial/stable/developer_guide/build.html). + +For more information about how RAPIDS manages dependencies, see [README of rapids-dependency-file-generator repo](https://github.com/rapidsai/dependency-file-generator). diff --git a/python/cuspatial/cuspatial/tests/test_point_linestring_distance.py b/python/cuspatial/cuspatial/tests/spatial/distance/test_point_linestring_distance.py similarity index 100% rename from python/cuspatial/cuspatial/tests/test_point_linestring_distance.py rename to python/cuspatial/cuspatial/tests/spatial/distance/test_point_linestring_distance.py diff --git a/test_fixtures/shapefiles/empty_poly.cpg b/test_fixtures/shapefiles/empty_poly.cpg deleted file mode 100644 index 3ad133c04..000000000 --- a/test_fixtures/shapefiles/empty_poly.cpg +++ /dev/null @@ -1 +0,0 @@ -UTF-8 \ No newline at end of file diff --git a/test_fixtures/shapefiles/empty_poly.dbf b/test_fixtures/shapefiles/empty_poly.dbf deleted file mode 100644 index 857052728e1b88ef889c11929fd6749c3d9dc7f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66 jcmZQB=VoC50!IcB5QPEUJYC`qA);;|N|+l}39l3YYZwB} diff --git a/test_fixtures/shapefiles/empty_poly.sbn b/test_fixtures/shapefiles/empty_poly.sbn deleted file mode 100644 index 79a5619d86913d9d7eaf9d660a8be93fb8b9b547..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 jcmZQzQ0Myp|6c(ECNKjD)&BrXFyf*ywP6)u1c?Fw`F;tt diff --git a/test_fixtures/shapefiles/empty_poly.sbx b/test_fixtures/shapefiles/empty_poly.sbx deleted file mode 100644 index f700f0577969bd4799b832197e88c5914758eb9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 jcmZQzQ0Myp|6c(ECNKjD)&BrXFyf*ywP6)80*L|u`f~~9 diff --git a/test_fixtures/shapefiles/empty_poly.shp b/test_fixtures/shapefiles/empty_poly.shp deleted file mode 100644 index 25194a3bb47bef31d2f713f52cfc698e5f38740a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100 hcmZQzQ0HR64vbzfGcd4XmjjA^*bk9{(Kr<{0084X1hN1C diff --git a/test_fixtures/shapefiles/empty_poly.shx b/test_fixtures/shapefiles/empty_poly.shx deleted file mode 100644 index 25194a3bb47bef31d2f713f52cfc698e5f38740a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100 hcmZQzQ0HR64vbzfGcd4XmjjA^*bk9{(Kr<{0084X1hN1C diff --git a/test_fixtures/shapefiles/one_poly.cpg b/test_fixtures/shapefiles/one_poly.cpg deleted file mode 100644 index 3ad133c04..000000000 --- a/test_fixtures/shapefiles/one_poly.cpg +++ /dev/null @@ -1 +0,0 @@ -UTF-8 \ No newline at end of file diff --git a/test_fixtures/shapefiles/one_poly.dbf b/test_fixtures/shapefiles/one_poly.dbf deleted file mode 100644 index 89544e2b6fe51d79a60de28bd79645915f7badf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86 wcmZQB=VoPOU|?`$5CM{yz|GSo-Vh?}2BL(yQPuD&C@2`{86ZHawt;~Z0LknIjQ{`u diff --git a/test_fixtures/shapefiles/one_poly.sbn b/test_fixtures/shapefiles/one_poly.sbn deleted file mode 100644 index 652a33e277aab888fcfec4a4ad284f5e844d037c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmZQzQ0Myp|6c(ECU61@F&-Y=m%nO!+21dR{;SG5KIL_DFDas1*8A~ diff --git a/test_fixtures/shapefiles/two_polys.sbn b/test_fixtures/shapefiles/two_polys.sbn deleted file mode 100644 index 448266c9872379b266c57093010fb3c81b920b82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmZQzQ0Myp|6c(ECI|uwF`)}Ps6a$uG`c(vJ|j?^2Z%xDG5!Yvs5)j4A1cnmzyKBp OsR4-t`3(&~nh^l8-3!xd05$Zsu!R Date: Thu, 22 Jun 2023 12:50:25 -0700 Subject: [PATCH 48/63] Fix a small typo in pairwise_linestring_distance (#1199) This PR fixes a small typo in pairwise_linestring_distance Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1199 --- cpp/include/cuspatial/distance.cuh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/include/cuspatial/distance.cuh b/cpp/include/cuspatial/distance.cuh index 6f7da67d4..6c1ebb821 100644 --- a/cpp/include/cuspatial/distance.cuh +++ b/cpp/include/cuspatial/distance.cuh @@ -235,9 +235,9 @@ OutputIt pairwise_point_polygon_distance(MultiPointRange multipoints, * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator * "LegacyRandomAccessIterator" */ -template +template OutputIt pairwise_linestring_distance(MultiLinestringRange1 multilinestrings1, - MultiLinstringRange2 multilinestrings2, + MultiLinestringRange2 multilinestrings2, OutputIt distances_first, rmm::cuda_stream_view stream = rmm::cuda_stream_default); From d5499d2082e69b715abf4b44de2809d8d7412303 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 22 Jun 2023 15:22:09 -0700 Subject: [PATCH 49/63] Simplify point-in-polygon header only APIs (#1192) closes #707 This PR simplifies `point_in_polygon` and `pairwise_point_in_polygon` API using `multipoint_range` and `multipolygon_range`. While these range methods supports a pair of multi geometry semantics, in this PR I'm not really targeting to create an API that works with multipoint-in-multipolygon semantics (such as "any point in any polygon", or "all points in any polygon", that sort of semantics). Therefore, this PR introduces `contains_only_single_geometry` method in `multipoint_range` and `multipolygon_range` that provides compile-time check for API that only want to work single-type geometry ranges. There are caveats to this introduction, see *caveats* section below. This refactor results in a net decrease in LOC, and the compatibility layer for `is_point_in_polygon` is removed. The API dries up to a point where there's no raw kernel anymore. In addition, previous `pairwise_point_in_polygon` API stores the row wise result in an int32_t per pair. Since it's only storing booleans, this PR uses `uint8_t` instead. This saves memory and increases throughputs. ### Caveats `contains_only_single_geometry` method is an over-constrained method comparing to what it's really testing. A multipoint range can have a materialized column of integer sequences and still represent a single geometry column. The reason behind this refactor is that the original point-in-polygon test explicitly requires (by the number of arguments) that only single geometry columns accepted by the API. This means developers know at compile time that the geometry used in the API are constructed this way. `contains_only_single_geometry` is a `constexpr` method and verifies developers construction at compile time as well. This maintains the developer expectation while allowing `multi*_range` to be retrofit into the modern APIs. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1192 --- .../point_in_polygon/point_in_polygon.cu | 136 ++---- .../detail/algorithm/is_point_in_polygon.cuh | 24 - .../cuspatial/detail/point_in_polygon.cuh | 267 +++-------- .../detail/range/multipoint_range.cuh | 11 +- cpp/include/cuspatial/point_in_polygon.cuh | 145 ++---- .../cuspatial/range/multipoint_range.cuh | 9 +- .../cuspatial/range/multipolygon_range.cuh | 62 +++ .../cuspatial_test/vector_factories.cuh | 24 +- cpp/src/point_in_polygon/point_in_polygon.cu | 44 +- .../quadtree_point_in_polygon_test_large.cu | 25 +- .../pairwise_point_in_polygon_test.cpp | 2 +- .../pairwise_point_in_polygon_test.cu | 333 ++++++++------ .../point_in_polygon/point_in_polygon_test.cu | 420 +++++++----------- 13 files changed, 612 insertions(+), 890 deletions(-) diff --git a/cpp/benchmarks/point_in_polygon/point_in_polygon.cu b/cpp/benchmarks/point_in_polygon/point_in_polygon.cu index 13033f8c9..7f41dd371 100644 --- a/cpp/benchmarks/point_in_polygon/point_in_polygon.cu +++ b/cpp/benchmarks/point_in_polygon/point_in_polygon.cu @@ -17,6 +17,8 @@ #include #include +#include + #include #include @@ -30,94 +32,17 @@ using namespace cuspatial; -constexpr double PI = 3.141592653589793; auto constexpr radius = 10.0; -auto constexpr num_polygons = 31; -auto constexpr num_rings_per_polygon = 1; // only 1 ring for now - -/** - * @brief Generate a random point within a window of [minXY, maxXY] - */ -template -vec_2d random_point(vec_2d minXY, vec_2d maxXY) -{ - auto x = minXY.x + (maxXY.x - minXY.x) * rand() / static_cast(RAND_MAX); - auto y = minXY.y + (maxXY.y - minXY.y) * rand() / static_cast(RAND_MAX); - return vec_2d{x, y}; -} - -/** - * @brief Helper to generate 31 simple polygons used for benchmarks. - * - * The polygons are generated by setting a centroid and a radius. The vertices of the - * polygons are generated by rotating a circle around the centroid. The centroid of - * the polygon is randomly sampled from window [minXY, maxXY]. - * - * @tparam T The floating point type for the coordinates - * @param num_sides Number of sides of the polygon - * @param radius The radius of the circle from which the vertices are sampled - * @param minXY The minimum xy coordinates of the window from which the centroid is sampled - * @param maxXY The maximum xy coordinates of the window from which the centroid is sampled - * @return 32 polygons in structure of arrays: - * [polygon offset, poly ring offset, point coordinates] - * - */ -template -std::tuple, rmm::device_vector, rmm::device_vector>> -generate_polygon(int32_t num_sides, T radius, vec_2d minXY, vec_2d maxXY) -{ - std::vector polygon_offsets(num_polygons); - std::vector ring_offsets(num_polygons * num_rings_per_polygon); - std::vector> polygon_points(31 * (num_sides + 1)); - - std::iota(polygon_offsets.begin(), polygon_offsets.end(), 0); - std::iota(ring_offsets.begin(), ring_offsets.end(), 0); - std::transform( - ring_offsets.begin(), ring_offsets.end(), ring_offsets.begin(), [num_sides](int32_t i) { - return i * (num_sides + 1); - }); - - for (int32_t i = 0; i < num_polygons; i++) { - auto it = thrust::make_counting_iterator(0); - auto begin = i * num_sides + polygon_points.begin(); - auto center = random_point(minXY, maxXY); - std::transform(it, it + num_sides + 1, begin, [num_sides, radius, center](int32_t j) { - return center + - radius * - vec_2d{ - static_cast(std::cos(2 * PI * (j % num_sides) / static_cast(num_sides))), - static_cast(std::sin(2 * PI * (j % num_sides) / static_cast(num_sides)))}; - }); - } - - // Implicitly convert to device_vector - return std::make_tuple(polygon_offsets, ring_offsets, polygon_points); -} - -/** - * @brief Randomly generate `num_test_points` points within window `minXY` and `maxXY` - * - * @tparam T The floating point type for the coordinates - */ -template -rmm::device_vector> generate_points(int32_t num_test_points, - vec_2d minXY, - vec_2d maxXY) -{ - std::vector> points(num_test_points); - std::generate( - points.begin(), points.end(), [minXY, maxXY]() { return random_point(minXY, maxXY); }); - // Implicitly convert to device_vector - return points; -} +auto constexpr num_polygons = 31ul; +auto constexpr num_rings_per_polygon = 1ul; // only 1 ring for now template void point_in_polygon_benchmark(nvbench::state& state, nvbench::type_list) { // TODO: to be replaced by nvbench fixture once it's ready cuspatial::rmm_pool_raii rmm_pool; + rmm::cuda_stream_view stream(rmm::cuda_stream_default); - std::srand(0); // For reproducibility auto const minXY = vec_2d{-radius * 2, -radius * 2}; auto const maxXY = vec_2d{radius * 2, radius * 2}; @@ -128,14 +53,33 @@ void point_in_polygon_benchmark(nvbench::state& state, nvbench::type_list) auto const num_polygon_points = num_rings * (num_sides_per_ring + 1); // +1 for the overlapping start and end point of the ring - auto test_points = generate_points(num_test_points, minXY, maxXY); - auto [polygon_offsets, ring_offsets, polygon_points] = - generate_polygon(num_sides_per_ring, radius, minXY, maxXY); - rmm::device_vector result(num_test_points); + auto point_gen_param = test::multipoint_generator_parameter{ + static_cast(num_test_points), 1, minXY, maxXY}; + auto poly_gen_param = + test::multipolygon_generator_parameter{static_cast(num_polygons), + 1, + 0, + static_cast(num_sides_per_ring), + vec_2d{0, 0}, + radius}; + auto test_points = test::generate_multipoint_array(point_gen_param, stream); + auto test_polygons = test::generate_multipolygon_array(poly_gen_param, stream); + + auto [_, points] = test_points.release(); + auto [__, part_offset_array, ring_offset_array, poly_coords] = test_polygons.release(); + + auto points_range = make_multipoint_range( + num_test_points, thrust::make_counting_iterator(0), points.size(), points.begin()); + auto polys_range = make_multipolygon_range(num_polygons, + thrust::make_counting_iterator(0), + part_offset_array.size() - 1, + part_offset_array.begin(), + ring_offset_array.size() - 1, + ring_offset_array.begin(), + poly_coords.size(), + poly_coords.begin()); - auto polygon_offsets_begin = polygon_offsets.begin(); - auto ring_offsets_begin = ring_offsets.begin(); - auto polygon_points_begin = polygon_points.begin(); + rmm::device_vector result(num_test_points); state.add_element_count(num_polygon_points, "NumPolygonPoints"); state.add_global_memory_reads(num_test_points * 2, "TotalMemoryReads"); @@ -145,22 +89,8 @@ void point_in_polygon_benchmark(nvbench::state& state, nvbench::type_list) state.add_global_memory_writes(num_test_points, "TotalMemoryWrites"); state.exec(nvbench::exec_tag::sync, - [&test_points, - polygon_offsets_begin, - ring_offsets_begin, - &num_rings, - polygon_points_begin, - &num_polygon_points, - &result](nvbench::launch& launch) { - point_in_polygon(test_points.begin(), - test_points.end(), - polygon_offsets_begin, - polygon_offsets_begin + num_polygons, - ring_offsets_begin, - ring_offsets_begin + num_rings, - polygon_points_begin, - polygon_points_begin + num_polygon_points, - result.begin()); + [points_range, polys_range, &result, stream](nvbench::launch& launch) { + point_in_polygon(points_range, polys_range, result.begin(), stream); }); } diff --git a/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh b/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh index 51258e05f..54ad6b499 100644 --- a/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh +++ b/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh @@ -99,29 +99,5 @@ __device__ inline bool is_point_in_polygon(vec_2d const& test_point, PolygonR return point_is_within; } -/** - * @brief Compatibility layer with non-OOP style input - */ -template ::difference_type, - class Cart2dItDiffType = typename std::iterator_traits::difference_type> -__device__ inline bool is_point_in_polygon(Cart2d const& test_point, - OffsetType poly_begin, - OffsetType poly_end, - OffsetIterator ring_offsets_first, - OffsetItDiffType const& num_rings, - Cart2dIt poly_points_first, - Cart2dItDiffType const& num_poly_points) -{ - auto polygon = polygon_ref{thrust::next(ring_offsets_first, poly_begin), - thrust::next(ring_offsets_first, poly_end + 1), - poly_points_first, - thrust::next(poly_points_first, num_poly_points)}; - return is_point_in_polygon(test_point, polygon); -} - } // namespace detail } // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/point_in_polygon.cuh b/cpp/include/cuspatial/detail/point_in_polygon.cuh index ecf6dd0ba..72c21872a 100644 --- a/cpp/include/cuspatial/detail/point_in_polygon.cuh +++ b/cpp/include/cuspatial/detail/point_in_polygon.cuh @@ -24,240 +24,109 @@ #include +#include + +#include #include +#include #include #include namespace cuspatial { -namespace detail { - -// Get the begin and end offsets of a polygon -template > -__device__ auto poly_begin_end(OffsetIteratorA poly_offsets_first, - OffsetItADiffType const num_polys, - OffsetItADiffType const num_rings, - OffsetType const poly_idx) -{ - auto poly_idx_next = poly_idx + 1; - OffsetType poly_begin = poly_offsets_first[poly_idx]; - OffsetType poly_end = (poly_idx_next < num_polys) ? poly_offsets_first[poly_idx_next] : num_rings; - return std::make_pair(poly_begin, poly_end); -} - -template ::difference_type, - class Cart2dItBDiffType = typename std::iterator_traits::difference_type, - class OffsetItADiffType = typename std::iterator_traits::difference_type, - class OffsetItBDiffType = typename std::iterator_traits::difference_type> -__global__ void point_in_polygon_kernel(Cart2dItA test_points_first, - Cart2dItADiffType const num_test_points, - OffsetIteratorA poly_offsets_first, - OffsetItADiffType const num_polys, - OffsetIteratorB ring_offsets_first, - OffsetItBDiffType const num_rings, - Cart2dItB poly_points_first, - Cart2dItBDiffType const num_poly_points, - OutputIt result) -{ - using Cart2d = iterator_value_type; - using OffsetType = iterator_value_type; - - auto idx = blockIdx.x * blockDim.x + threadIdx.x; - - if (idx >= num_test_points) { return; } - - int32_t hit_mask = 0; - - Cart2d const test_point = test_points_first[idx]; - - // for each polygon - for (auto poly_idx = 0; poly_idx < num_polys; poly_idx++) { - auto [poly_begin, poly_end] = - poly_begin_end(poly_offsets_first, num_polys, num_rings, poly_idx); - - bool const point_is_within = is_point_in_polygon(test_point, - poly_begin, - poly_end, - ring_offsets_first, - num_rings, - poly_points_first, - num_poly_points); - - hit_mask |= point_is_within << poly_idx; - } - result[idx] = hit_mask; -} - -template ::difference_type, - class Cart2dItBDiffType = typename std::iterator_traits::difference_type, - class OffsetItADiffType = typename std::iterator_traits::difference_type, - class OffsetItBDiffType = typename std::iterator_traits::difference_type> -__global__ void pairwise_point_in_polygon_kernel(Cart2dItA test_points_first, - Cart2dItADiffType const num_test_points, - OffsetIteratorA poly_offsets_first, - OffsetItADiffType const num_polys, - OffsetIteratorB ring_offsets_first, - OffsetItBDiffType const num_rings, - Cart2dItB poly_points_first, - Cart2dItBDiffType const num_poly_points, - OutputIt result) -{ - using Cart2d = iterator_value_type; - using OffsetType = iterator_value_type; - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < num_test_points; - idx += gridDim.x * blockDim.x) { - Cart2d const test_point = test_points_first[idx]; - // for the matching polygon - auto [poly_begin, poly_end] = poly_begin_end(poly_offsets_first, num_polys, num_rings, idx); - - bool const point_is_within = is_point_in_polygon(test_point, - poly_begin, - poly_end, - ring_offsets_first, - num_rings, - poly_points_first, - num_poly_points); - result[idx] = point_is_within; +/** + * @brief Computes point-in-polygon result of a single point to up to 32 polygons + * Result is stored in an `int32_t` integer. + */ +template +struct pip_functor { + PointRange multipoints; + PolygonRange multipolygons; + + int32_t __device__ operator()(std::size_t i) + { + using T = typename PointRange::element_t; + vec_2d point = multipoints[i][0]; + int32_t hit_mask = 0; + for (auto poly_idx = 0; poly_idx < multipolygons.size(); ++poly_idx) + hit_mask |= (is_point_in_polygon(point, multipolygons[poly_idx][0]) << poly_idx); + return hit_mask; } -} +}; -} // namespace detail +template +pip_functor(PointRange, PolygonRange) -> pip_functor; -template -OutputIt point_in_polygon(Cart2dItA test_points_first, - Cart2dItA test_points_last, - OffsetIteratorA polygon_offsets_first, - OffsetIteratorA polygon_offsets_last, - OffsetIteratorB poly_ring_offsets_first, - OffsetIteratorB poly_ring_offsets_last, - Cart2dItB polygon_points_first, - Cart2dItB polygon_points_last, +template +OutputIt point_in_polygon(PointRange points, + PolygonRange polygons, OutputIt output, rmm::cuda_stream_view stream) { - using T = iterator_vec_base_type; + using T = typename PointRange::element_t; - static_assert(is_same_floating_point>(), - "Underlying type of Cart2dItA and Cart2dItB must be the same floating point type"); - static_assert( - is_same, iterator_value_type, iterator_value_type>(), - "Inputs must be cuspatial::vec_2d"); - - static_assert(cuspatial::is_integral, - iterator_value_type>(), - "OffsetIterators must point to integral type."); + static_assert(is_same_floating_point(), + "points and polygons must have the same coordinate type."); static_assert(std::is_same_v, int32_t>, "OutputIt must point to 32 bit integer type."); - auto const num_test_points = std::distance(test_points_first, test_points_last); - - if (num_test_points > 0) { - auto const num_polys = std::distance(polygon_offsets_first, polygon_offsets_last) - 1; - auto const num_rings = std::distance(poly_ring_offsets_first, poly_ring_offsets_last) - 1; - auto const num_poly_points = std::distance(polygon_points_first, polygon_points_last); + CUSPATIAL_EXPECTS(points.num_multipoints() == points.num_points(), + "Point in polygon API only support single point - single polygon tests. " + "Multipoint input is not accepted."); - CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( - num_poly_points, - std::distance(polygon_offsets_first, polygon_offsets_last), - std::distance(poly_ring_offsets_first, poly_ring_offsets_last)); + CUSPATIAL_EXPECTS(polygons.num_multipolygons() == polygons.num_polygons(), + "Point in polygon API only support single point - single polygon tests. " + "MultiPolygon input is not accepted."); - CUSPATIAL_EXPECTS(num_polys <= std::numeric_limits::digits, - "Number of polygons cannot exceed 31"); + CUSPATIAL_EXPECTS(polygons.size() <= std::numeric_limits::digits, + "Number of polygons cannot exceed 31"); - auto [threads_per_block, num_blocks] = grid_1d(num_test_points); + if (points.size() == 0) return output; - detail::point_in_polygon_kernel<<>>( - test_points_first, - num_test_points, - polygon_offsets_first, - num_polys, - poly_ring_offsets_first, - num_rings, - polygon_points_first, - num_poly_points, - output); - CUSPATIAL_CHECK_CUDA(stream.value()); - } + thrust::tabulate( + rmm::exec_policy(stream), output, output + points.size(), pip_functor{points, polygons}); - return output + num_test_points; + return output + points.size(); } -template -OutputIt pairwise_point_in_polygon(Cart2dItA test_points_first, - Cart2dItA test_points_last, - OffsetIteratorA polygon_offsets_first, - OffsetIteratorA polygon_offsets_last, - OffsetIteratorB poly_ring_offsets_first, - OffsetIteratorB poly_ring_offsets_last, - Cart2dItB polygon_points_first, - Cart2dItB polygon_points_last, +template +OutputIt pairwise_point_in_polygon(PointRange points, + PolygonRange polygons, OutputIt output, rmm::cuda_stream_view stream) { - using T = iterator_vec_base_type; + using T = typename PointRange::element_t; - static_assert(is_same_floating_point>(), - "Underlying type of Cart2dItA and Cart2dItB must be the same floating point type"); - static_assert( - is_same, iterator_value_type, iterator_value_type>(), - "Inputs must be cuspatial::vec_2d"); + static_assert(is_same_floating_point(), + "points and polygons must have the same coordinate type."); - static_assert(cuspatial::is_integral, - iterator_value_type>(), - "OffsetIterators must point to integral type."); - - static_assert(std::is_same_v, int32_t>, - "OutputIt must point to 32 bit integer type."); + static_assert(std::is_same_v, uint8_t>, + "OutputIt must be iterator to a uint8_t range."); - auto const num_test_points = std::distance(test_points_first, test_points_last); - auto const num_polys = std::distance(polygon_offsets_first, polygon_offsets_last) - 1; - auto const num_rings = std::distance(poly_ring_offsets_first, poly_ring_offsets_last) - 1; - auto const num_poly_points = std::distance(polygon_points_first, polygon_points_last); + CUSPATIAL_EXPECTS(points.num_multipoints() == points.num_points(), + "Point in polygon API only supports single point - single polygon tests. " + "Multipoint input is not accepted."); - CUSPATIAL_EXPECTS_VALID_POLYGON_SIZES( - num_poly_points, - std::distance(polygon_offsets_first, polygon_offsets_last), - std::distance(poly_ring_offsets_first, poly_ring_offsets_last)); + CUSPATIAL_EXPECTS(polygons.num_multipolygons() == polygons.num_polygons(), + "Point in polygon API only supports single point - single polygon tests. " + "MultiPolygon input is not accepted."); - CUSPATIAL_EXPECTS(num_test_points == num_polys, - "Must pass in an equal number of points and polygons"); + CUSPATIAL_EXPECTS(points.size() == polygons.size(), + "Must pass in an equal number of (multi)points and (multi)polygons"); - auto [threads_per_block, num_blocks] = grid_1d(num_test_points); - detail::pairwise_point_in_polygon_kernel<<>>( - test_points_first, - num_test_points, - polygon_offsets_first, - num_polys, - poly_ring_offsets_first, - num_rings, - polygon_points_first, - num_poly_points, - output); - CUSPATIAL_CHECK_CUDA(stream.value()); + if (points.size() == 0) return output; - return output + num_test_points; + return thrust::transform(rmm::exec_policy(stream), + points.begin(), + points.end(), + polygons.begin(), + output, + [] __device__(auto multipoint, auto multipolygon) { + return is_point_in_polygon(static_cast>(multipoint[0]), + multipolygon[0]); + }); } } // namespace cuspatial diff --git a/cpp/include/cuspatial/detail/range/multipoint_range.cuh b/cpp/include/cuspatial/detail/range/multipoint_range.cuh index 7e9c18cb3..04c3abc34 100644 --- a/cpp/include/cuspatial/detail/range/multipoint_range.cuh +++ b/cpp/include/cuspatial/detail/range/multipoint_range.cuh @@ -38,6 +38,7 @@ struct to_multipoint_functor { GeometryIterator _offset_iter; VecIterator _points_begin; + CUSPATIAL_HOST_DEVICE to_multipoint_functor(GeometryIterator offset_iter, VecIterator points_begin) : _offset_iter(offset_iter), _points_begin(points_begin) { @@ -66,6 +67,9 @@ CUSPATIAL_HOST_DEVICE multipoint_range::multipoin { static_assert(is_vec_2d>, "Coordinate range must be constructed with iterators to vec_2d."); + + static_assert(std::is_integral_v>, + "Offset range must be constructed with iterators to integers."); } template @@ -81,14 +85,14 @@ CUSPATIAL_HOST_DEVICE auto multipoint_range::num_ } template -auto multipoint_range::multipoint_begin() +CUSPATIAL_HOST_DEVICE auto multipoint_range::multipoint_begin() { return cuspatial::detail::make_counting_transform_iterator( 0, detail::to_multipoint_functor(_geometry_begin, _points_begin)); } template -auto multipoint_range::multipoint_end() +CUSPATIAL_HOST_DEVICE auto multipoint_range::multipoint_end() { return multipoint_begin() + size(); } @@ -122,8 +126,7 @@ template CUSPATIAL_HOST_DEVICE auto multipoint_range::operator[]( IndexType idx) { - return multipoint_ref{_points_begin + _geometry_begin[idx], - _points_begin + _geometry_begin[idx + 1]}; + return *(thrust::next(begin(), idx)); } template diff --git a/cpp/include/cuspatial/point_in_polygon.cuh b/cpp/include/cuspatial/point_in_polygon.cuh index 6ae058acd..814d40f2c 100644 --- a/cpp/include/cuspatial/point_in_polygon.cuh +++ b/cpp/include/cuspatial/point_in_polygon.cuh @@ -35,42 +35,27 @@ namespace cuspatial { * represents a hit or miss for each of the input polygons in least-significant-bit order. i.e. * `output[3] & 0b0010` indicates a hit or miss for the 3rd point against the 2nd polygon. * - * - * @tparam Cart2dItA iterator type for point array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam Cart2dItB iterator type for point array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OffsetIteratorA iterator type for offset array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OffsetIteratorB iterator type for offset array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OutputIt iterator type for output array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI], be device-accessible, mutable and - * iterate on `int32_t` type. - * - * @param test_points_first begin of range of test points - * @param test_points_last end of range of test points - * @param polygon_offsets_first begin of range of indices to the first ring in each polygon - * @param polygon_offsets_last end of range of indices to the first ring in each polygon - * @param ring_offsets_first begin of range of indices to the first point in each ring - * @param ring_offsets_last end of range of indices to the first point in each ring - * @param polygon_points_first begin of range of polygon points - * @param polygon_points_last end of range of polygon points + * Note that the input must be a single geometry column, that is a (multi*)geometry_range + * initialized with counting iterator as the geometry offsets iterator. + * + * @tparam PointRange an instance of template type `multipoint_range`, where + * `GeometryIterator` must be a counting iterator + * @tparam PolygonRange an instance of template type `multipolygon_range`, where + * `GeometryIterator` must be a counting iterator + * @tparam OutputIt iterator type for output array. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI], be device-accessible, mutable and iterate on `int32_t` + * type. + * + * @param points Range of points, one per computed point-in-polygon pair, + * @param polygons Range of polygons, one per comptued point-in-polygon pair * @param output begin iterator to the output buffer * @param stream The CUDA stream to use for kernel launches. * @return iterator to one past the last element in the output buffer * - * @note Limit 31 polygons per call. Polygons may contain multiple rings. * @note Direction of rings does not matter. - * @note This algorithm supports the ESRI shapefile format, but assumes all polygons are "clean" (as - * defined by the format), and does _not_ verify whether the input adheres to the shapefile format. - * @note The points of the rings can be either explicitly closed (the first and last vertex - * overlaps), or implicitly closed (not overlaps). Either input format is supported. + * @note The points of the rings must be explicitly closed. * @note Overlapping rings negate each other. This behavior is not limited to a single negation, * allowing for "islands" within the same polygon. - * @note `poly_ring_offsets` must contain only the rings that make up the polygons indexed by - * `poly_offsets`. If there are rings in `poly_ring_offsets` that are not part of the polygons in - * `poly_offsets`, results are likely to be incorrect and behavior is undefined. * * ``` * poly w/two rings poly w/four rings @@ -85,78 +70,44 @@ namespace cuspatial { * +-----------+ +------------------------+ * ``` * - * @pre All point iterators must have the same `vec_2d` value type, with the same underlying - * floating-point coordinate type (e.g. `cuspatial::vec_2d`). - * @pre All offset iterators must have the same integral value type. * @pre Output iterator must be mutable and iterate on int32_t type. * - * @throw cuspatial::logic_error if the number of polygons or rings exceeds 31. - * @throw cuspatial::logic_error polygon has less than 1 ring. - * @throw cuspatial::logic_error polygon has less than 4 vertices. - * * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator * "LegacyRandomAccessIterator" */ -template -OutputIt point_in_polygon(Cart2dItA test_points_first, - Cart2dItA test_points_last, - OffsetIteratorA polygon_offsets_first, - OffsetIteratorA polygon_offsets_last, - OffsetIteratorB poly_ring_offsets_first, - OffsetIteratorB poly_ring_offsets_last, - Cart2dItB polygon_points_first, - Cart2dItB polygon_points_last, +template +OutputIt point_in_polygon(PointRange points, + PolygonRange polygons, OutputIt output, rmm::cuda_stream_view stream = rmm::cuda_stream_default); /** - * @brief Given (point, polygon) pairs, tests whether the point of each pair is inside the polygon - * of the pair. - * - * Tests whether each point is inside a corresponding polygon. Points on the edges of the - * polygon are not considered to be inside. - * Polygons are a collection of one or more rings. Rings are a collection of three or more vertices. - * - * Each input point will map to one `int32_t` element in the output. - * - * - * @tparam Cart2dItA iterator type for point array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam Cart2dItB iterator type for point array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OffsetIteratorA iterator type for offset array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OffsetIteratorB iterator type for offset array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible. - * @tparam OutputIt iterator type for output array. Must meet - * the requirements of [LegacyRandomAccessIterator][LinkLRAI], be device-accessible, mutable and - * iterate on `int32_t` type. - * - * @param test_points_first begin of range of test points - * @param test_points_last end of range of test points - * @param polygon_offsets_first begin of range of indices to the first ring in each polygon - * @param polygon_offsets_last end of range of indices to the first ring in each polygon - * @param ring_offsets_first begin of range of indices to the first point in each ring - * @param ring_offsets_last end of range of indices to the first point in each ring - * @param polygon_points_first begin of range of polygon points - * @param polygon_points_last end of range of polygon points + * @brief Given (point, polygon) pairs, tests whether the point in the pair is in the polygon in the + * pair. + * + * Note that the input must be a single geometry column, that is a (multi*)geometry_range + * initialized with counting iterator as the geometry offsets iterator. + * + * Each input point will map to one `uint8_t` element in the output. + * + * @tparam PointRange an instance of template type `multipoint_range`, where + * `GeometryIterator` must be a counting iterator + * @tparam PolygonRange an instance of template type `multipolygon_range`, where + * `GeometryIterator` must be a counting iterator + * @tparam OutputIt iterator type for output array. Must meet the requirements of + * [LegacyRandomAccessIterator][LinkLRAI], be device-accessible, mutable and iterate on `int32_t` + * type. + * + * @param points Range of points, one per computed point-in-polygon pair, + * @param polygons Range of polygons, one per comptued point-in-polygon pair * @param output begin iterator to the output buffer * @param stream The CUDA stream to use for kernel launches. * @return iterator to one past the last element in the output buffer * * @note Direction of rings does not matter. - * @note This algorithm supports the ESRI shapefile format, but assumes all polygons are "clean" (as - * defined by the format), and does _not_ verify whether the input adheres to the shapefile format. * @note The points of the rings must be explicitly closed. * @note Overlapping rings negate each other. This behavior is not limited to a single negation, * allowing for "islands" within the same polygon. - * @note `poly_ring_offsets` must contain only the rings that make up the polygons indexed by - * `poly_offsets`. If there are rings in `poly_ring_offsets` that are not part of the polygons in - * `poly_offsets`, results are likely to be incorrect and behavior is undefined. * * ``` * poly w/two rings poly w/four rings @@ -171,31 +122,15 @@ OutputIt point_in_polygon(Cart2dItA test_points_first, * +-----------+ +------------------------+ * ``` * - * @pre All point iterators must have the same `vec_2d` value type, with the same underlying - * floating-point coordinate type (e.g. `cuspatial::vec_2d`). - * @pre All offset iterators must have the same integral value type. - * @pre Output iterator must be mutable and iterate on int32_t type. - * - * @throw cuspatial::logic_error polygon has less than 1 ring. - * @throw cuspatial::logic_error polygon has less than 4 vertices. + * @pre Output iterator must be mutable and iterate on uint8_t type. * * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator * "LegacyRandomAccessIterator" */ -template -OutputIt pairwise_point_in_polygon(Cart2dItA test_points_first, - Cart2dItA test_points_last, - OffsetIteratorA polygon_offsets_first, - OffsetIteratorA polygon_offsets_last, - OffsetIteratorB poly_ring_offsets_first, - OffsetIteratorB poly_ring_offsets_last, - Cart2dItB polygon_points_first, - Cart2dItB polygon_points_last, - OutputIt output, +template +OutputIt pairwise_point_in_polygon(PointRange points, + PolygonRange polygons, + OutputIt results, rmm::cuda_stream_view stream = rmm::cuda_stream_default); /** diff --git a/cpp/include/cuspatial/range/multipoint_range.cuh b/cpp/include/cuspatial/range/multipoint_range.cuh index b41edbd7e..92f7bff76 100644 --- a/cpp/include/cuspatial/range/multipoint_range.cuh +++ b/cpp/include/cuspatial/range/multipoint_range.cuh @@ -65,6 +65,7 @@ class multipoint_range { GeometryIterator geometry_end, VecIterator points_begin, VecIterator points_end); + /** * @brief Returns the number of multipoints in the array. */ @@ -83,22 +84,22 @@ class multipoint_range { /** * @brief Returns the iterator to the first multipoint in the multipoint array. */ - auto multipoint_begin(); + CUSPATIAL_HOST_DEVICE auto multipoint_begin(); /** * @brief Returns the iterator past the last multipoint in the multipoint array. */ - auto multipoint_end(); + CUSPATIAL_HOST_DEVICE auto multipoint_end(); /** * @brief Returns the iterator to the start of the multipoint array. */ - auto begin() { return multipoint_begin(); } + CUSPATIAL_HOST_DEVICE auto begin() { return multipoint_begin(); } /** * @brief Returns the iterator past the last multipoint in the multipoint array. */ - auto end() { return multipoint_end(); } + CUSPATIAL_HOST_DEVICE auto end() { return multipoint_end(); } /** * @brief Returns the iterator to the start of the underlying point array. diff --git a/cpp/include/cuspatial/range/multipolygon_range.cuh b/cpp/include/cuspatial/range/multipolygon_range.cuh index 99b2843b2..2af70e066 100644 --- a/cpp/include/cuspatial/range/multipolygon_range.cuh +++ b/cpp/include/cuspatial/range/multipolygon_range.cuh @@ -209,6 +209,68 @@ class multipolygon_range { CUSPATIAL_HOST_DEVICE bool is_valid_segment_id(IndexType1 segment_idx, IndexType2 ring_idx); }; +/** + * @brief Create a multipoylgon_range object of from size and start iterators + * + * @tparam GeometryIteratorDiffType Integer type of the size of the geometry offset array + * @tparam PartIteratorDiffType Integer type of the size of the part offset array + * @tparam RingIteratorDiffType Integer type of the size of the ring offset array + * @tparam VecIteratorDiffType Integer type of the size of the point array + * @tparam GeometryIterator iterator type for offset array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI]. + * @tparam PartIterator iterator type for offset array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI]. + * @tparam RingIterator iterator type for offset array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI]. + * @tparam VecIterator iterator type for the point array. Must meet + * the requirements of [LegacyRandomAccessIterator][LinkLRAI]. + * + * @note Iterators should be device-accessible if the view is intended to be + * used on device. + * + * @param num_multipolygons Number of multipolygons in the array + * @param geometry_begin Iterator to the start of the geometry offset array + * @param num_polygons Number of polygons in the array + * @param part_begin Iterator to the start of the part offset array + * @param num_rings Number of rings in the array + * @param ring_begin Iterator to the start of the ring offset array + * @param num_points Number of underlying points in the multipoint array + * @param point_begin Iterator to the start of the points array + * @return range to multipolygon array + * + * [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator + * "LegacyRandomAccessIterator" + */ +template +multipolygon_range +make_multipolygon_range(GeometryIteratorDiffType num_multipolygons, + GeometryIterator geometry_begin, + PartIteratorDiffType num_polygons, + PartIterator part_begin, + RingIteratorDiffType num_rings, + RingIterator ring_begin, + VecIteratorDiffType num_points, + VecIterator point_begin) +{ + return multipolygon_range{ + geometry_begin, + thrust::next(geometry_begin, num_multipolygons + 1), + part_begin, + thrust::next(part_begin, num_polygons + 1), + ring_begin, + thrust::next(ring_begin, num_rings + 1), + point_begin, + thrust::next(point_begin, num_points), + }; +} + /** * @brief Create a range object of multipolygon from cuspatial::geometry_column_view. * Specialization for polygons column. diff --git a/cpp/include/cuspatial_test/vector_factories.cuh b/cpp/include/cuspatial_test/vector_factories.cuh index f2572c17e..91d2c04d7 100644 --- a/cpp/include/cuspatial_test/vector_factories.cuh +++ b/cpp/include/cuspatial_test/vector_factories.cuh @@ -93,22 +93,22 @@ class multipolygon_array { multipolygon_array(thrust::device_vector geometry_offsets_array, thrust::device_vector part_offsets_array, thrust::device_vector ring_offsets_array, - thrust::device_vector coordinate_offsets_array) + thrust::device_vector coordinates_array) : _geometry_offsets_array(geometry_offsets_array), _part_offsets_array(part_offsets_array), _ring_offsets_array(ring_offsets_array), - _coordinate_offsets_array(coordinate_offsets_array) + _coordinates_array(coordinates_array) { } multipolygon_array(rmm::device_uvector&& geometry_offsets_array, rmm::device_uvector&& part_offsets_array, rmm::device_uvector&& ring_offsets_array, - rmm::device_uvector&& coordinate_offsets_array) + rmm::device_uvector&& coordinates_array) : _geometry_offsets_array(std::move(geometry_offsets_array)), _part_offsets_array(std::move(part_offsets_array)), _ring_offsets_array(std::move(ring_offsets_array)), - _coordinate_offsets_array(std::move(coordinate_offsets_array)) + _coordinates_array(std::move(coordinates_array)) { } @@ -124,8 +124,8 @@ class multipolygon_array { _part_offsets_array.end(), _ring_offsets_array.begin(), _ring_offsets_array.end(), - _coordinate_offsets_array.begin(), - _coordinate_offsets_array.end()); + _coordinates_array.begin(), + _coordinates_array.end()); } /** @@ -136,11 +136,19 @@ class multipolygon_array { auto geometry_offsets = cuspatial::test::to_host(_geometry_offsets_array); auto part_offsets = cuspatial::test::to_host(_part_offsets_array); auto ring_offsets = cuspatial::test::to_host(_ring_offsets_array); - auto coordinate_offsets = cuspatial::test::to_host(_coordinate_offsets_array); + auto coordinate_offsets = cuspatial::test::to_host(_coordinates_array); return std::tuple{geometry_offsets, part_offsets, ring_offsets, coordinate_offsets}; } + auto release() + { + return std::tuple{std::move(_geometry_offsets_array), + std::move(_part_offsets_array), + std::move(_ring_offsets_array), + std::move(_coordinates_array)}; + } + /** * @brief Output stream operator for `multipolygon_array` for human-readable formatting */ @@ -160,7 +168,7 @@ class multipolygon_array { GeometryArray _geometry_offsets_array; PartArray _part_offsets_array; RingArray _ring_offsets_array; - CoordinateArray _coordinate_offsets_array; + CoordinateArray _coordinates_array; }; template #include #include +#include +#include #include #include @@ -57,7 +59,7 @@ struct point_in_polygon_functor { rmm::mr::device_memory_resource* mr) { auto size = test_points_x.size(); - auto tid = cudf::type_to_id(); + auto tid = pairwise ? cudf::type_to_id() : cudf::type_to_id(); auto type = cudf::data_type{tid}; auto results = cudf::make_fixed_width_column(type, size, cudf::mask_state::UNALLOCATED, stream, mr); @@ -70,31 +72,27 @@ struct point_in_polygon_functor { auto ring_offsets_begin = poly_ring_offsets.begin(); auto polygon_points_begin = cuspatial::make_vec_2d_iterator(poly_points_x.begin(), poly_points_y.begin()); - auto results_begin = results->mutable_view().begin(); - if (pairwise) { - cuspatial::pairwise_point_in_polygon(points_begin, - points_begin + test_points_x.size(), - polygon_offsets_begin, - polygon_offsets_begin + poly_offsets.size(), - ring_offsets_begin, - ring_offsets_begin + poly_ring_offsets.size(), - polygon_points_begin, - polygon_points_begin + poly_points_x.size(), - results_begin, - stream); + auto multipoints_range = + make_multipoint_range(size, thrust::make_counting_iterator(0), size, points_begin); + + auto polygon_size = poly_offsets.size() - 1; + auto multipolygon_range = make_multipolygon_range(polygon_size, + thrust::make_counting_iterator(0), + polygon_size, + polygon_offsets_begin, + poly_ring_offsets.size() - 1, + ring_offsets_begin, + poly_points_x.size(), + polygon_points_begin); + if (pairwise) { + auto results_begin = results->mutable_view().begin(); + cuspatial::pairwise_point_in_polygon( + multipoints_range, multipolygon_range, results_begin, stream); } else { - cuspatial::point_in_polygon(points_begin, - points_begin + test_points_x.size(), - polygon_offsets_begin, - polygon_offsets_begin + poly_offsets.size(), - ring_offsets_begin, - ring_offsets_begin + poly_ring_offsets.size(), - polygon_points_begin, - polygon_points_begin + poly_points_x.size(), - results_begin, - stream); + auto results_begin = results->mutable_view().begin(); + cuspatial::point_in_polygon(multipoints_range, multipolygon_range, results_begin, stream); } return results; diff --git a/cpp/tests/join/quadtree_point_in_polygon_test_large.cu b/cpp/tests/join/quadtree_point_in_polygon_test_large.cu index 8da2a2aed..1be866afc 100644 --- a/cpp/tests/join/quadtree_point_in_polygon_test_large.cu +++ b/cpp/tests/join/quadtree_point_in_polygon_test_large.cu @@ -170,16 +170,21 @@ TYPED_TEST(PIPRefineTestLarge, TestLarge) { // verify rmm::device_uvector hits(points.size(), this->stream()); - auto hits_end = cuspatial::point_in_polygon(points.begin(), - points.end(), - multipolygons.part_offset_begin(), - multipolygons.part_offset_end(), - multipolygons.ring_offset_begin(), - multipolygons.ring_offset_end(), - multipolygons.point_begin(), - multipolygons.point_end(), - hits.begin(), - this->stream()); + + auto points_range = make_multipoint_range( + points.size(), thrust::make_counting_iterator(0), points.size(), points.begin()); + + auto polygons_range = make_multipolygon_range(multipolygons.size(), + thrust::make_counting_iterator(0), + multipolygons.size(), + multipolygons.part_offset_begin(), + multipolygons.num_rings(), + multipolygons.ring_offset_begin(), + multipolygons.num_points(), + multipolygons.point_begin()); + + auto hits_end = + cuspatial::point_in_polygon(points_range, polygons_range, hits.begin(), this->stream()); auto hits_host = cuspatial::test::to_host(hits); diff --git a/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cpp b/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cpp index 477d8ce90..21f939214 100644 --- a/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cpp +++ b/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cpp @@ -50,7 +50,7 @@ TYPED_TEST(PairwisePointInPolygonTest, Empty) auto poly_point_xs = wrapper({}); auto poly_point_ys = wrapper({}); - auto expected = wrapper({}); + auto expected = wrapper({}); auto actual = cuspatial::pairwise_point_in_polygon( test_point_xs, test_point_ys, poly_offsets, poly_ring_offsets, poly_point_xs, poly_point_ys); diff --git a/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cu b/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cu index c05c24f63..0dc955204 100644 --- a/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cu +++ b/cpp/tests/point_in_polygon/pairwise_point_in_polygon_test.cu @@ -14,11 +14,14 @@ * limitations under the License. */ +#include +#include +#include + #include #include #include #include -#include #include @@ -26,50 +29,87 @@ #include #include -#include +#include using namespace cuspatial; using namespace cuspatial::test; template -struct PairwisePointInPolygonTest : public ::testing::Test {}; +struct PairwisePointInPolygonTest : public BaseFixture { + void run_test(std::initializer_list> points, + std::initializer_list polygon_offsets, + std::initializer_list ring_offsets, + std::initializer_list> polygon_points, + std::initializer_list expected) + { + auto d_points = make_device_vector>(points); + auto d_polygon_offsets = make_device_vector(polygon_offsets); + auto d_ring_offsets = make_device_vector(ring_offsets); + auto d_polygon_points = make_device_vector>(polygon_points); + + auto mpoints = make_multipoint_range( + d_points.size(), thrust::make_counting_iterator(0), d_points.size(), d_points.begin()); + auto mpolys = make_multipolygon_range(polygon_offsets.size() - 1, + thrust::make_counting_iterator(0), + d_polygon_offsets.size() - 1, + d_polygon_offsets.begin(), + d_ring_offsets.size() - 1, + d_ring_offsets.begin(), + d_polygon_points.size(), + d_polygon_points.begin()); + + auto d_expected = make_device_vector(expected); + + auto got = rmm::device_uvector(points.size(), stream()); + + auto ret = pairwise_point_in_polygon(mpoints, mpolys, got.begin(), stream()); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(d_expected, got); + EXPECT_EQ(ret, got.end()); + } +}; // float and double are logically the same but would require separate tests due to precision. -using TestTypes = ::testing::Types; -TYPED_TEST_CASE(PairwisePointInPolygonTest, TestTypes); +TYPED_TEST_CASE(PairwisePointInPolygonTest, FloatingPointTypes); TYPED_TEST(PairwisePointInPolygonTest, OnePolygonOneRing) { - using T = TypeParam; - auto point_list = std::vector>{{-2.0, 0.0}, - {2.0, 0.0}, - {0.0, -2.0}, - {0.0, 2.0}, - {-0.5, 0.0}, - {0.5, 0.0}, - {0.0, -0.5}, - {0.0, 0.5}}; + using T = TypeParam; + auto point_list = std::vector>{{-2.0, 0.0}, + {2.0, 0.0}, + {0.0, -2.0}, + {0.0, 2.0}, + {-0.5, 0.0}, + {0.5, 0.0}, + {0.0, -0.5}, + {0.0, 0.5}}; + auto poly_offsets = make_device_vector({0, 1}); auto poly_ring_offsets = make_device_vector({0, 5}); auto poly_point = make_device_vector>( {{-1.0, -1.0}, {1.0, -1.0}, {1.0, 1.0}, {-1.0, 1.0}, {-1.0, -1.0}}); - auto got = rmm::device_vector(1); + auto polygon_range = make_multipolygon_range(poly_offsets.size() - 1, + thrust::make_counting_iterator(0), + poly_offsets.size() - 1, + poly_offsets.begin(), + poly_ring_offsets.size() - 1, + poly_ring_offsets.begin(), + poly_point.size(), + poly_point.begin()); + + auto got = rmm::device_vector(1); auto expected = cuspatial::test::make_host_vector({false, false, false, false, true, true, true, true}); for (size_t i = 0; i < point_list.size(); ++i) { - auto point = make_device_vector>({{point_list[i][0], point_list[i][1]}}); - auto ret = pairwise_point_in_polygon(point.begin(), - point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - EXPECT_EQ(got, std::vector({expected[i]})); + auto p = point_list[i]; + auto d_point = make_device_vector>({{p.x, p.y}}); + auto point_range = make_multipoint_range( + d_point.size(), thrust::make_counting_iterator(0), d_point.size(), d_point.begin()); + + auto ret = pairwise_point_in_polygon(point_range, polygon_range, got.begin(), this->stream()); + EXPECT_EQ(got, std::vector({expected[i]})); EXPECT_EQ(ret, got.end()); } } @@ -77,14 +117,14 @@ TYPED_TEST(PairwisePointInPolygonTest, OnePolygonOneRing) TYPED_TEST(PairwisePointInPolygonTest, TwoPolygonsOneRingEach) { using T = TypeParam; - auto point_list = std::vector>{{-2.0, 0.0}, - {2.0, 0.0}, - {0.0, -2.0}, - {0.0, 2.0}, - {-0.5, 0.0}, - {0.5, 0.0}, - {0.0, -0.5}, - {0.0, 0.5}}; + auto point_list = std::vector>{{-2.0, 0.0}, + {2.0, 0.0}, + {0.0, -2.0}, + {0.0, 2.0}, + {-0.5, 0.0}, + {0.5, 0.0}, + {0.0, -0.5}, + {0.0, 0.5}}; auto poly_offsets = make_device_vector({0, 1, 2}); auto poly_ring_offsets = make_device_vector({0, 5, 10}); @@ -99,23 +139,27 @@ TYPED_TEST(PairwisePointInPolygonTest, TwoPolygonsOneRingEach) {-1.0, 0.0}, {0.0, 1.0}}); - auto got = rmm::device_vector(2); - auto expected = std::vector({false, false, false, false, true, true, true, true}); + auto polygon_range = make_multipolygon_range(poly_offsets.size() - 1, + thrust::make_counting_iterator(0), + poly_offsets.size() - 1, + poly_offsets.begin(), + poly_ring_offsets.size() - 1, + poly_ring_offsets.begin(), + poly_point.size(), + poly_point.begin()); + + auto got = rmm::device_vector(2); + auto expected = std::vector({false, false, false, false, true, true, true, true}); for (size_t i = 0; i < point_list.size() / 2; i = i + 2) { auto points = make_device_vector>( - {{point_list[i][0], point_list[i][1]}, {point_list[i + 1][0], point_list[i + 1][1]}}); - auto ret = pairwise_point_in_polygon(points.begin(), - points.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, std::vector({expected[i], expected[i + 1]})); + {{point_list[i].x, point_list[i].y}, {point_list[i + 1].x, point_list[i + 1].y}}); + auto points_range = make_multipoint_range( + points.size(), thrust::make_counting_iterator(0), points.size(), points.begin()); + + auto ret = pairwise_point_in_polygon(points_range, polygon_range, got.begin(), this->stream()); + + EXPECT_EQ(got, std::vector({expected[i], expected[i + 1]})); EXPECT_EQ(ret, got.end()); } } @@ -125,7 +169,9 @@ TYPED_TEST(PairwisePointInPolygonTest, OnePolygonTwoRings) using T = TypeParam; auto point_list = std::vector>{{0.0, 0.0}, {-0.4, 0.0}, {-0.6, 0.0}, {0.0, 0.4}, {0.0, -0.6}}; - auto poly_offsets = make_device_vector({0, 1}); + + auto poly_offsets = make_device_vector({0, 2}); + auto num_polys = poly_offsets.size() - 1; auto poly_ring_offsets = make_device_vector({0, 5, 10}); auto poly_point = make_device_vector>({{-1.0, -1.0}, {1.0, -1.0}, @@ -138,90 +184,64 @@ TYPED_TEST(PairwisePointInPolygonTest, OnePolygonTwoRings) {0.5, -0.5}, {-0.5, -0.5}}); - auto got = rmm::device_vector(1); - auto expected = std::vector{0b0, 0b0, 0b1, 0b0, 0b1}; + auto polygon_range = make_multipolygon_range(num_polys, + thrust::make_counting_iterator(0), + num_polys, + poly_offsets.begin(), + poly_ring_offsets.size() - 1, + poly_ring_offsets.begin(), + poly_point.size(), + poly_point.begin()); + + auto expected = std::vector{0b0, 0b0, 0b1, 0b0, 0b1}; for (size_t i = 0; i < point_list.size(); ++i) { - auto point = make_device_vector>({{point_list[i][0], point_list[i][1]}}); - auto ret = pairwise_point_in_polygon(point.begin(), - point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, std::vector{expected[i]}); + auto got = rmm::device_vector(1); + + auto point = make_device_vector>({{point_list[i][0], point_list[i][1]}}); + auto points_range = make_multipoint_range( + point.size(), thrust::make_counting_iterator(0), point.size(), point.begin()); + + auto ret = pairwise_point_in_polygon(points_range, polygon_range, got.begin(), this->stream()); + + EXPECT_EQ(got, std::vector{expected[i]}); EXPECT_EQ(ret, got.end()); } } TYPED_TEST(PairwisePointInPolygonTest, EdgesOfSquare) { - auto test_point = - make_device_vector>({{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}}); - auto poly_offsets = make_device_vector({0, 1, 2, 3, 4}); - auto poly_ring_offsets = make_device_vector({0, 5, 10, 15, 20}); - // 0: rect on min x side // 1: rect on max x side // 2: rect on min y side // 3: rect on max y side - auto poly_point = make_device_vector>( + CUSPATIAL_RUN_TEST( + this->run_test, + {{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}}, + {0, 1, 2, 3, 4}, + {0, 5, 10, 15, 20}, {{-1.0, -1.0}, {0.0, -1.0}, {0.0, 1.0}, {-1.0, 1.0}, {-1.0, -1.0}, {0.0, -1.0}, {1.0, -1.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, -1.0}, - {-1.0, 1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {-1.0, 0.0}}); - - auto expected = std::vector{0b0, 0b0, 0b0, 0b0}; - auto got = rmm::device_vector(test_point.size()); - - auto ret = pairwise_point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + {-1.0, 1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {-1.0, 0.0}}, + {0b0, 0b0, 0b0, 0b0}); } TYPED_TEST(PairwisePointInPolygonTest, CornersOfSquare) { - auto test_point = - make_device_vector>({{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}}); - auto poly_offsets = make_device_vector({0, 1, 2, 3, 4}); - auto poly_ring_offsets = make_device_vector({0, 5, 10, 15, 20}); - // 0: min x min y corner // 1: min x max y corner // 2: max x min y corner // 3: max x max y corner - auto poly_point = make_device_vector>( + + CUSPATIAL_RUN_TEST( + this->run_test, + {{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}}, + {0, 1, 2, 3, 4}, + {0, 5, 10, 15, 20}, {{-1.0, -1.0}, {-1.0, 0.0}, {0.0, 0.0}, {0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {0.0, 1.0}, {-1.0, 0.0}, {-1.0, 0.0}, {0.0, -1.0}, {0.0, 0.0}, {1.0, 0.0}, {1.0, -1.0}, - {0.0, -1.0}, {0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}}); - - auto expected = std::vector{0b0, 0b0, 0b0, 0b0}; - auto got = rmm::device_vector(test_point.size()); - - auto ret = pairwise_point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + {0.0, -1.0}, {0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}}, + {0b0, 0b0, 0b0, 0b0}); } struct OffsetIteratorFunctor { @@ -271,6 +291,10 @@ TYPED_TEST(PairwisePointInPolygonTest, 32PolygonSupport) {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}}); + + auto points_range = make_multipoint_range( + test_point.size(), thrust::make_counting_iterator(0), test_point.size(), test_point.begin()); + auto offsets_iter = thrust::make_counting_iterator(0); auto poly_ring_offsets_iter = thrust::make_transform_iterator(offsets_iter, OffsetIteratorFunctor{}); @@ -280,21 +304,22 @@ TYPED_TEST(PairwisePointInPolygonTest, 32PolygonSupport) thrust::make_transform_iterator(offsets_iter, PolyPointIteratorFunctorB{}); auto poly_point_iter = make_vec_2d_iterator(poly_point_xs_iter, poly_point_ys_iter); - auto expected = std::vector({1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}); - auto got = rmm::device_vector(test_point.size()); - - auto ret = pairwise_point_in_polygon(test_point.begin(), - test_point.end(), - offsets_iter, - offsets_iter + num_polys + 1, - poly_ring_offsets_iter, - poly_ring_offsets_iter + num_polys + 1, - poly_point_iter, - poly_point_iter + num_poly_points, - got.begin()); - - EXPECT_EQ(got, expected); + auto polygons_range = make_multipolygon_range(num_polys, + thrust::make_counting_iterator(0), + num_polys, + offsets_iter, + num_polys, + poly_ring_offsets_iter, + num_poly_points, + poly_point_iter); + + auto expected = std::vector({1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}); + auto got = rmm::device_vector(test_point.size()); + + auto ret = pairwise_point_in_polygon(points_range, polygons_range, got.begin(), this->stream()); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(got, expected); EXPECT_EQ(ret, got.end()); } @@ -304,21 +329,27 @@ TEST_F(PairwisePointInPolygonErrorTest, InsufficientPoints) { using T = double; - auto test_point = make_device_vector>({{0.0, 0.0}, {0.0, 0.0}}); + auto test_point = make_device_vector>({{0.0, 0.0}, {0.0, 0.0}}); + auto points_range = make_multipoint_range( + test_point.size(), thrust::make_counting_iterator(0), test_point.size(), test_point.begin()); + auto poly_offsets = make_device_vector({0, 1}); + auto num_polys = poly_offsets.size() - 1; auto poly_ring_offsets = make_device_vector({0, 3}); auto poly_point = make_device_vector>({{0.0, 1.0}, {1.0, 0.0}, {0.0, -1.0}}); - auto got = rmm::device_vector(test_point.size()); - - EXPECT_THROW(pairwise_point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()), + + auto polygons_range = make_multipolygon_range(num_polys, + thrust::make_counting_iterator(0), + num_polys, + poly_offsets.begin(), + num_polys, + poly_ring_offsets.begin(), + poly_point.size(), + poly_point.begin()); + + auto got = rmm::device_vector(test_point.size()); + + EXPECT_THROW(pairwise_point_in_polygon(points_range, polygons_range, got.begin(), this->stream()), cuspatial::logic_error); } @@ -326,21 +357,27 @@ TEST_F(PairwisePointInPolygonErrorTest, InsufficientPolyOffsets) { using T = double; - auto test_point = make_device_vector>({{0.0, 0.0}, {0.0, 0.0}}); + auto test_point = make_device_vector>({{0.0, 0.0}, {0.0, 0.0}}); + auto points_range = make_multipoint_range( + test_point.size(), thrust::make_counting_iterator(0), test_point.size(), test_point.begin()); + auto poly_offsets = make_device_vector({0}); + auto num_polys = poly_offsets.size() - 1; auto poly_ring_offsets = make_device_vector({0, 4}); auto poly_point = make_device_vector>({{0.0, 1.0}, {1.0, 0.0}, {0.0, -1.0}, {0.0, 1.0}}); - auto got = rmm::device_vector(test_point.size()); - - EXPECT_THROW(pairwise_point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()), + + auto polygons_range = make_multipolygon_range(num_polys, + thrust::make_counting_iterator(0), + num_polys, + poly_offsets.begin(), + num_polys, + poly_ring_offsets.begin(), + poly_point.size(), + poly_point.begin()); + + auto got = rmm::device_vector(test_point.size()); + + EXPECT_THROW(pairwise_point_in_polygon(points_range, polygons_range, got.begin(), this->stream()), cuspatial::logic_error); } diff --git a/cpp/tests/point_in_polygon/point_in_polygon_test.cu b/cpp/tests/point_in_polygon/point_in_polygon_test.cu index 00e4229ed..c4705cad9 100644 --- a/cpp/tests/point_in_polygon/point_in_polygon_test.cu +++ b/cpp/tests/point_in_polygon/point_in_polygon_test.cu @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include @@ -32,55 +33,61 @@ #include using namespace cuspatial; +using namespace cuspatial::test; template -struct PointInPolygonTest : public ::testing::Test { +struct PointInPolygonTest : public BaseFixture { public: - rmm::device_vector> make_device_points(std::initializer_list> pts) + void run_test(std::initializer_list> points, + std::initializer_list polygon_offsets, + std::initializer_list ring_offsets, + std::initializer_list> polygon_points, + std::initializer_list expected) { - return rmm::device_vector>(pts.begin(), pts.end()); - } - - rmm::device_vector make_device_offsets(std::initializer_list pts) - { - return rmm::device_vector(pts.begin(), pts.end()); + auto d_points = make_device_vector>(points); + auto d_polygon_offsets = make_device_vector(polygon_offsets); + auto d_ring_offsets = make_device_vector(ring_offsets); + auto d_polygon_points = make_device_vector>(polygon_points); + + auto mpoints = make_multipoint_range( + d_points.size(), thrust::make_counting_iterator(0), d_points.size(), d_points.begin()); + auto mpolys = make_multipolygon_range(polygon_offsets.size() - 1, + thrust::make_counting_iterator(0), + d_polygon_offsets.size() - 1, + d_polygon_offsets.begin(), + d_ring_offsets.size() - 1, + d_ring_offsets.begin(), + d_polygon_points.size(), + d_polygon_points.begin()); + + auto d_expected = make_device_vector(expected); + + auto got = rmm::device_uvector(points.size(), stream()); + + auto ret = point_in_polygon(mpoints, mpolys, got.begin(), stream()); + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(d_expected, got); + EXPECT_EQ(ret, got.end()); } }; -// float and double are logically the same but would require separate tests due to precision. -using TestTypes = ::testing::Types; -TYPED_TEST_CASE(PointInPolygonTest, TestTypes); +TYPED_TEST_CASE(PointInPolygonTest, FloatingPointTypes); TYPED_TEST(PointInPolygonTest, OnePolygonOneRing) { - auto test_point = this->make_device_points({{-2.0, 0.0}, - {2.0, 0.0}, - {0.0, -2.0}, - {0.0, 2.0}, - {-0.5, 0.0}, - {0.5, 0.0}, - {0.0, -0.5}, - {0.0, 0.5}}); - auto poly_offsets = this->make_device_offsets({0, 1}); - auto poly_ring_offsets = this->make_device_offsets({0, 5}); - auto poly_point = - this->make_device_points({{-1.0, -1.0}, {1.0, -1.0}, {1.0, 1.0}, {-1.0, 1.0}, {-1.0, -1.0}}); - - auto got = rmm::device_vector(test_point.size()); - auto expected = std::vector{false, false, false, false, true, true, true, true}; - - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + CUSPATIAL_RUN_TEST(this->run_test, + {{-2.0, 0.0}, + {2.0, 0.0}, + {0.0, -2.0}, + {0.0, 2.0}, + {-0.5, 0.0}, + {0.5, 0.0}, + {0.0, -0.5}, + {0.0, 0.5}}, + {0, 1}, + {0, 5}, + {{-1.0, -1.0}, {1.0, -1.0}, {1.0, 1.0}, {-1.0, 1.0}, {-1.0, -1.0}}, + {false, false, false, false, true, true, true, true}); } // cuspatial expects closed rings, however algorithms may work OK with unclosed rings @@ -90,172 +97,106 @@ TYPED_TEST(PointInPolygonTest, OnePolygonOneRing) // uses a polygon ring with 4 vertices so it doesn't fail polygon validation. TYPED_TEST(PointInPolygonTest, OnePolygonOneRingUnclosed) { - auto test_point = this->make_device_points({{-2.0, 0.0}, - {2.0, 0.0}, - {0.0, -2.0}, - {0.0, 2.0}, - {-0.5, 0.0}, - {0.5, 0.0}, - {0.0, -0.5}, - {0.0, 0.5}}); - auto poly_offsets = this->make_device_offsets({0, 1}); - auto poly_ring_offsets = this->make_device_offsets({0, 4}); - auto poly_point = this->make_device_points({{-1.0, -1.0}, {1.0, -1.0}, {1.0, 0.0}, {1.0, 1.0}}); - - auto got = rmm::device_vector(test_point.size()); - auto expected = std::vector{false, false, false, false, false, true, true, false}; - - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + CUSPATIAL_RUN_TEST(this->run_test, + {{-2.0, 0.0}, + {2.0, 0.0}, + {0.0, -2.0}, + {0.0, 2.0}, + {-0.5, 0.0}, + {0.5, 0.0}, + {0.0, -0.5}, + {0.0, 0.5}}, + {0, 1}, + {0, 4}, + {{-1.0, -1.0}, {1.0, -1.0}, {1.0, 0.0}, {1.0, 1.0}}, + {false, false, false, false, false, true, true, false}); } TYPED_TEST(PointInPolygonTest, TwoPolygonsOneRingEach) { - auto test_point = this->make_device_points({{-2.0, 0.0}, - {2.0, 0.0}, - {0.0, -2.0}, - {0.0, 2.0}, - {-0.5, 0.0}, - {0.5, 0.0}, - {0.0, -0.5}, - {0.0, 0.5}}); - - auto poly_offsets = this->make_device_offsets({0, 1, 2}); - auto poly_ring_offsets = this->make_device_offsets({0, 5, 10}); - auto poly_point = this->make_device_points({{-1.0, -1.0}, - {-1.0, 1.0}, - {1.0, 1.0}, - {1.0, -1.0}, - {-1.0, -1.0}, - {0.0, 1.0}, - {1.0, 0.0}, - {0.0, -1.0}, - {-1.0, 0.0}, - {0.0, 1.0}}); - - auto got = rmm::device_vector(test_point.size()); - auto expected = std::vector({0b00, 0b00, 0b00, 0b00, 0b11, 0b11, 0b11, 0b11}); - - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + CUSPATIAL_RUN_TEST(this->run_test, + + {{-2.0, 0.0}, + {2.0, 0.0}, + {0.0, -2.0}, + {0.0, 2.0}, + {-0.5, 0.0}, + {0.5, 0.0}, + {0.0, -0.5}, + {0.0, 0.5}}, + + {0, 1, 2}, + {0, 5, 10}, + {{-1.0, -1.0}, + {-1.0, 1.0}, + {1.0, 1.0}, + {1.0, -1.0}, + {-1.0, -1.0}, + {0.0, 1.0}, + {1.0, 0.0}, + {0.0, -1.0}, + {-1.0, 0.0}, + {0.0, 1.0}}, + + {0b00, 0b00, 0b00, 0b00, 0b11, 0b11, 0b11, 0b11}); } TYPED_TEST(PointInPolygonTest, OnePolygonTwoRings) { - auto test_point = - this->make_device_points({{0.0, 0.0}, {-0.4, 0.0}, {-0.6, 0.0}, {0.0, 0.4}, {0.0, -0.6}}); - auto poly_offsets = this->make_device_offsets({0, 2}); - auto poly_ring_offsets = this->make_device_offsets({0, 5, 10}); - auto poly_point = this->make_device_points({{-1.0, -1.0}, - {1.0, -1.0}, - {1.0, 1.0}, - {-1.0, 1.0}, - {-1.0, -1.0}, - {-0.5, -0.5}, - {-0.5, 0.5}, - {0.5, 0.5}, - {0.5, -0.5}, - {-0.5, -0.5}}); - - auto got = rmm::device_vector(test_point.size()); - auto expected = std::vector{0b0, 0b0, 0b1, 0b0, 0b1}; - - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + CUSPATIAL_RUN_TEST(this->run_test, + {{0.0, 0.0}, {-0.4, 0.0}, {-0.6, 0.0}, {0.0, 0.4}, {0.0, -0.6}}, + {0, 2}, + {0, 5, 10}, + {{-1.0, -1.0}, + {1.0, -1.0}, + {1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, -1.0}, + {-0.5, -0.5}, + {-0.5, 0.5}, + {0.5, 0.5}, + {0.5, -0.5}, + {-0.5, -0.5}}, + + {0b0, 0b0, 0b1, 0b0, 0b1}); } TYPED_TEST(PointInPolygonTest, EdgesOfSquare) { - auto test_point = this->make_device_points({{0.0, 0.0}}); - auto poly_offsets = this->make_device_offsets({0, 1, 2, 3, 4}); - auto poly_ring_offsets = this->make_device_offsets({0, 5, 10, 15, 20}); - - // 0: rect on min x side - // 1: rect on max x side - // 2: rect on min y side - // 3: rect on max y side - auto poly_point = this->make_device_points( + CUSPATIAL_RUN_TEST( + this->run_test, + {{0.0, 0.0}}, + {0, 1, 2, 3, 4}, + {0, 5, 10, 15, 20}, + + // 0: rect on min x side + // 1: rect on max x side + // 2: rect on min y side + // 3: rect on max y side {{-1.0, -1.0}, {0.0, -1.0}, {0.0, 1.0}, {-1.0, 1.0}, {-1.0, -1.0}, {0.0, -1.0}, {1.0, -1.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, -1.0}, - {-1.0, 1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {-1.0, 0.0}}); - - auto expected = std::vector{0b0000}; - auto got = rmm::device_vector(test_point.size()); - - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); + {-1.0, 1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {-1.0, 0.0}}, - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + {0b0000}); } TYPED_TEST(PointInPolygonTest, CornersOfSquare) { - auto test_point = this->make_device_points({{0.0, 0.0}}); - auto poly_offsets = this->make_device_offsets({0, 1, 2, 3, 4}); - auto poly_ring_offsets = this->make_device_offsets({0, 5, 10, 15, 20}); - - // 0: min x min y corner - // 1: min x max y corner - // 2: max x min y corner - // 3: max x max y corner - auto poly_point = this->make_device_points( + CUSPATIAL_RUN_TEST( + this->run_test, + {{0.0, 0.0}}, + {0, 1, 2, 3, 4}, + {0, 5, 10, 15, 20}, + + // 0: min x min y corner + // 1: min x max y corner + // 2: max x min y corner + // 3: max x max y corner {{-1.0, -1.0}, {-1.0, 0.0}, {0.0, 0.0}, {0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {0.0, 1.0}, {-1.0, 0.0}, {-1.0, 0.0}, {0.0, -1.0}, {0.0, 0.0}, {1.0, 0.0}, {1.0, -1.0}, - {0.0, -1.0}, {0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}}); - - auto expected = std::vector{0b0000}; - auto got = rmm::device_vector(test_point.size()); + {0.0, -1.0}, {0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}}, - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(got, expected); - EXPECT_EQ(ret, got.end()); + {0b0000}); } struct OffsetIteratorFunctor { @@ -299,7 +240,7 @@ TYPED_TEST(PointInPolygonTest, 31PolygonSupport) auto constexpr num_polys = 31; auto constexpr num_poly_points = num_polys * 5; - auto test_point = this->make_device_points({{0.0, 0.0}, {2.0, 0.0}}); + auto test_point = make_device_vector>({{0.0, 0.0}, {2.0, 0.0}}); auto offsets_iter = thrust::make_counting_iterator(0); auto poly_ring_offsets_iter = thrust::make_transform_iterator(offsets_iter, OffsetIteratorFunctor{}); @@ -309,103 +250,60 @@ TYPED_TEST(PointInPolygonTest, 31PolygonSupport) thrust::make_transform_iterator(offsets_iter, PolyPointIteratorFunctorB{}); auto poly_point_iter = make_vec_2d_iterator(poly_point_xs_iter, poly_point_ys_iter); + auto points_range = make_multipoint_range( + test_point.size(), thrust::make_counting_iterator(0), test_point.size(), test_point.begin()); + + auto polygons_range = make_multipolygon_range(num_polys, + thrust::make_counting_iterator(0), + num_polys, + offsets_iter, + num_polys, + poly_ring_offsets_iter, + num_poly_points, + poly_point_iter); + auto expected = std::vector({0b1111111111111111111111111111111, 0b0000000000000000000000000000000}); auto got = rmm::device_vector(test_point.size()); - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - offsets_iter, - offsets_iter + num_polys + 1, - poly_ring_offsets_iter, - poly_ring_offsets_iter + num_polys + 1, - poly_point_iter, - poly_point_iter + num_poly_points, - got.begin()); + auto ret = point_in_polygon(points_range, polygons_range, got.begin()); EXPECT_EQ(got, expected); EXPECT_EQ(ret, got.end()); } -struct PointInPolygonErrorTest : public PointInPolygonTest {}; - TYPED_TEST(PointInPolygonTest, SelfClosingLoopLeftEdgeMissing) { - using T = TypeParam; - auto test_point = this->make_device_points({{-2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}}); - auto poly_offsets = this->make_device_offsets({0, 1}); - auto poly_ring_offsets = this->make_device_offsets({0, 4}); - // "left" edge missing - auto poly_point = this->make_device_points({{-1, 1}, {1, 1}, {1, -1}, {-1, -1}}); - auto expected = std::vector{0b0, 0b1, 0b0}; - auto got = rmm::device_vector(test_point.size()); - - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(expected, got); - EXPECT_EQ(got.end(), ret); + CUSPATIAL_RUN_TEST(this->run_test, + + {{-2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}}, + {0, 1}, + {0, 4}, + // "left" edge missing + {{-1, 1}, {1, 1}, {1, -1}, {-1, -1}}, + {0b0, 0b1, 0b0}); } TYPED_TEST(PointInPolygonTest, SelfClosingLoopRightEdgeMissing) { - using T = TypeParam; - auto test_point = this->make_device_points({{-2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}}); - auto poly_offsets = this->make_device_offsets({0, 1}); - auto poly_ring_offsets = this->make_device_offsets({0, 4}); - // "right" edge missing - auto poly_point = this->make_device_points({{1, -1}, {-1, -1}, {-1, 1}, {1, 1}}); - auto expected = std::vector{0b0, 0b1, 0b0}; - auto got = rmm::device_vector(test_point.size()); - - auto ret = point_in_polygon(test_point.begin(), - test_point.end(), - poly_offsets.begin(), - poly_offsets.end(), - poly_ring_offsets.begin(), - poly_ring_offsets.end(), - poly_point.begin(), - poly_point.end(), - got.begin()); - - EXPECT_EQ(expected, got); - EXPECT_EQ(got.end(), ret); + using T = TypeParam; + CUSPATIAL_RUN_TEST(this->run_test, + {{-2.0, 0.0}, {0.0, 0.0}, {2.0, 0.0}}, + {0, 1}, + {0, 4}, + // "right" edge missing + {{1, -1}, {-1, -1}, {-1, 1}, {1, 1}}, + {0b0, 0b1, 0b0}); } TYPED_TEST(PointInPolygonTest, ContainsButCollinearWithBoundary) { using T = TypeParam; - - auto point = cuspatial::test::make_multipoint_array({{{0.5, 0.5}}}); - auto polygon = cuspatial::test::make_multipolygon_array( - {0, 1}, + CUSPATIAL_RUN_TEST( + this->run_test, + {{0.5, 0.5}}, {0, 1}, {0, 9}, - {{0, 0}, {0, 1}, {1, 1}, {1, 0.5}, {1.5, 0.5}, {1.5, 1}, {2, 1}, {2, 0}, {0, 0}}); - - auto point_range = point.range(); - auto polygon_range = polygon.range(); - - auto res = rmm::device_uvector(1, rmm::cuda_stream_default); - - cuspatial::point_in_polygon(point_range.point_begin(), - point_range.point_end(), - polygon_range.part_offset_begin(), - polygon_range.part_offset_end(), - polygon_range.ring_offset_begin(), - polygon_range.ring_offset_end(), - polygon_range.point_begin(), - polygon_range.point_end(), - res.begin()); - - auto expect = cuspatial::test::make_device_vector({0b1}); - - CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(res, expect); + {{0, 0}, {0, 1}, {1, 1}, {1, 0.5}, {1.5, 0.5}, {1.5, 1}, {2, 1}, {2, 0}, {0, 0}}, + {0b1}); } From b047c6a154681764083c6c529c796c8a713d09ae Mon Sep 17 00:00:00 2001 From: Mark Harris <783069+harrism@users.noreply.github.com> Date: Sat, 24 Jun 2023 20:51:16 +1000 Subject: [PATCH 50/63] Add cmake infrastructure for internal projection library (#1132) Adds cmake files, directory structure and placeholder source files. Closes #1127 Will not merge until I have some content ready for the library (e.g. a first API) in a followup PR. Authors: - Mark Harris (https://github.com/harrism) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) - Robert Maynard (https://github.com/robertmaynard) - Paul Taylor (https://github.com/trxcllnt) URL: https://github.com/rapidsai/cuspatial/pull/1132 --- ci/release/update-version.sh | 1 + .../all_cuda-118_arch-x86_64.yaml | 2 + conda/recipes/libcuspatial/meta.yaml | 4 + cpp/CMakeLists.txt | 16 +- ...CUSPATIAL_GetCUDF.cmake => get_cudf.cmake} | 2 +- cpp/cuproj/CMakeLists.txt | 270 ++++++++++++++++++ cpp/cuproj/benchmarks/CMakeLists.txt | 80 ++++++ .../synchronization/synchronization.cpp | 61 ++++ .../synchronization/synchronization.hpp | 103 +++++++ cpp/cuproj/benchmarks/test.cu | 0 cpp/cuproj/cmake/modules/ConfigureCUDA.cmake | 50 ++++ cpp/cuproj/cmake/thirdparty/get_cudf.cmake | 77 +++++ cpp/cuproj/cmake/thirdparty/get_gtest.cmake | 39 +++ cpp/cuproj/cmake/thirdparty/get_proj.cmake | 32 +++ cpp/cuproj/include/cuproj/assert.cuh | 35 +++ cpp/cuproj/include/cuproj/error.hpp | 175 ++++++++++++ cpp/cuproj/src/test.cu | 0 cpp/cuproj/tests/CMakeLists.txt | 53 ++++ cpp/cuproj/tests/test.cu | 50 ++++ dependencies.yaml | 2 + 20 files changed, 1041 insertions(+), 11 deletions(-) rename cpp/cmake/thirdparty/{CUSPATIAL_GetCUDF.cmake => get_cudf.cmake} (98%) create mode 100644 cpp/cuproj/CMakeLists.txt create mode 100644 cpp/cuproj/benchmarks/CMakeLists.txt create mode 100644 cpp/cuproj/benchmarks/synchronization/synchronization.cpp create mode 100644 cpp/cuproj/benchmarks/synchronization/synchronization.hpp create mode 100644 cpp/cuproj/benchmarks/test.cu create mode 100644 cpp/cuproj/cmake/modules/ConfigureCUDA.cmake create mode 100644 cpp/cuproj/cmake/thirdparty/get_cudf.cmake create mode 100644 cpp/cuproj/cmake/thirdparty/get_gtest.cmake create mode 100644 cpp/cuproj/cmake/thirdparty/get_proj.cmake create mode 100644 cpp/cuproj/include/cuproj/assert.cuh create mode 100644 cpp/cuproj/include/cuproj/error.hpp create mode 100644 cpp/cuproj/src/test.cu create mode 100644 cpp/cuproj/tests/CMakeLists.txt create mode 100644 cpp/cuproj/tests/test.cu diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 3bd74f52f..86c1545e4 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -31,6 +31,7 @@ function sed_runner() { # python/cpp update sed_runner 's/'"CUSPATIAL VERSION .* LANGUAGES"'/'"CUSPATIAL VERSION ${NEXT_FULL_TAG} LANGUAGES"'/g' cpp/CMakeLists.txt +sed_runner 's/'"CUPROJ VERSION .* LANGUAGES"'/'"CUPROJ VERSION ${NEXT_FULL_TAG} LANGUAGES"'/g' cpp/cuproj/CMakeLists.txt sed_runner 's/'"cuspatial_version .*)"'/'"cuspatial_version ${NEXT_FULL_TAG})"'/g' python/cuspatial/CMakeLists.txt # RTD update diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 530f2cb41..0e1373e0d 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -29,6 +29,7 @@ dependencies: - numpydoc - nvcc_linux-64=11.8 - pre-commit +- proj - pydata-sphinx-theme - pydeck - pytest @@ -41,5 +42,6 @@ dependencies: - setuptools - shapely - sphinx<6 +- sqlite - sysroot_linux-64==2.17 name: all_cuda-118_arch-x86_64 diff --git a/conda/recipes/libcuspatial/meta.yaml b/conda/recipes/libcuspatial/meta.yaml index f43882c9d..7ec4df829 100644 --- a/conda/recipes/libcuspatial/meta.yaml +++ b/conda/recipes/libcuspatial/meta.yaml @@ -46,6 +46,8 @@ requirements: - gtest {{ gtest_version }} - libcudf ={{ minor_version }} - librmm ={{ minor_version }} + - sqlite + - proj outputs: - name: libcuspatial @@ -66,6 +68,8 @@ outputs: - cudatoolkit {{ cuda_spec }} - libcudf ={{ minor_version }} - librmm ={{ minor_version }} + - sqlite + - proj test: commands: - test -f $PREFIX/lib/libcuspatial.so diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index ad47f587a..4fe6b6615 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -84,12 +84,6 @@ rapids_cmake_support_conda_env(conda_env MODIFY_PREFIX_PATH) ################################################################################################### # - compiler options ------------------------------------------------------------------------------ -set(_ctk_static_suffix "") -if(CUDA_STATIC_RUNTIME) - set(_ctk_static_suffix "_static") - # Control legacy FindCUDA.cmake behavior too - set(CUDA_USE_STATIC_CUDA_RUNTIME ON) -endif() rapids_cuda_init_runtime(USE_STATIC ${CUDA_STATIC_RUNTIME}) @@ -110,7 +104,7 @@ include(cmake/Modules/ConfigureCUDA.cmake) # add third party dependencies using CPM rapids_cpm_init() # find or add cuDF -include(cmake/thirdparty/CUSPATIAL_GetCUDF.cmake) +include(cmake/thirdparty/get_cudf.cmake) # find or install GoogleTest if (CUSPATIAL_BUILD_TESTS) include(cmake/thirdparty/get_gtest.cmake) @@ -119,6 +113,9 @@ endif() ################################################################################################### # - library targets ------------------------------------------------------------------------------- +# cuProj +add_subdirectory(cuproj) + add_library(cuspatial src/bounding_boxes/linestring_bounding_boxes.cu src/bounding_boxes/polygon_bounding_boxes.cu @@ -222,9 +219,9 @@ endif() if(CUSPATIAL_BUILD_BENCHMARKS) # Find or install GoogleBench CPMFindPackage(NAME benchmark - VERSION 1.5.2 + VERSION 1.5.3 GIT_REPOSITORY https://github.com/google/benchmark.git - GIT_TAG v1.5.2 + GIT_TAG v1.5.3 GIT_SHALLOW TRUE OPTIONS "BENCHMARK_ENABLE_TESTING OFF" "BENCHMARK_ENABLE_INSTALL OFF") @@ -243,7 +240,6 @@ endif() rapids_cmake_install_lib_dir(lib_dir) include(CPack) -include(GNUInstallDirs) set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME cuspatial) diff --git a/cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake b/cpp/cmake/thirdparty/get_cudf.cmake similarity index 98% rename from cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake rename to cpp/cmake/thirdparty/get_cudf.cmake index 49db92353..3d7232fba 100644 --- a/cpp/cmake/thirdparty/CUSPATIAL_GetCUDF.cmake +++ b/cpp/cmake/thirdparty/get_cudf.cmake @@ -26,7 +26,7 @@ function(find_and_configure_cudf) set(global_targets cudf::cudf) set(cudf_components "") - if(BUILD_TESTS) + if(BUILD_TESTS OR BUILD_BENCHMARKS) list(APPEND global_targets cudf::cudftestutil) set(cudf_components COMPONENTS testing) endif() diff --git a/cpp/cuproj/CMakeLists.txt b/cpp/cuproj/CMakeLists.txt new file mode 100644 index 000000000..57be97a19 --- /dev/null +++ b/cpp/cuproj/CMakeLists.txt @@ -0,0 +1,270 @@ +#============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +#============================================================================= + +cmake_minimum_required(VERSION 3.23.1 FATAL_ERROR) + +include(../../fetch_rapids.cmake) +include(rapids-cmake) +include(rapids-cpm) +include(rapids-cuda) +include(rapids-export) +include(rapids-find) + +rapids_cuda_init_architectures(CUPROJ) + +project(CUPROJ VERSION 23.08.00 LANGUAGES C CXX CUDA) + +# Needed because GoogleBenchmark changes the state of FindThreads.cmake, +# causing subsequent runs to have different values for the `Threads::Threads` target. +# Setting this flag ensures `Threads::Threads` is the same value in first run and subsequent runs. +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# Must come after enable_language(CUDA) +# Use `-isystem ` instead of `-isystem=` +# because the former works with clangd intellisense +set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA "-isystem ") + +################################################################################################### +# - build options --------------------------------------------------------------------------------- + +option(BUILD_SHARED_LIBS "Build cuproj shared libraries" ON) +option(USE_NVTX "Build with NVTX support" ON) +option(BUILD_TESTS "Configure CMake to build tests" OFF) +option(BUILD_BENCHMARKS "Configure CMake to build (google) benchmarks" OFF) +option(PER_THREAD_DEFAULT_STREAM "Build with per-thread default stream" OFF) +option(DISABLE_DEPRECATION_WARNING "Disable warnings generated from deprecated declarations." OFF) +# Option to enable line info in CUDA device compilation to allow introspection when profiling / memchecking +option(CUDA_ENABLE_LINEINFO "Enable the -lineinfo option for nvcc (useful for cuda-memcheck / profiler" OFF) +# cudart can be statically linked or dynamically linked. The python ecosystem wants dynamic linking +option(CUDA_STATIC_RUNTIME "Statically link the CUDA toolkit runtime and libraries" OFF) + +message(STATUS "CUPROJ: Build with NVTX support: ${USE_NVTX}") +message(STATUS "CUPROJ: Configure CMake to build tests: ${BUILD_TESTS}") +message(STATUS "CUPROJ: Configure CMake to build (google) benchmarks: ${BUILD_BENCHMARKS}") +message(STATUS "CUPROJ: Build with per-thread default stream: ${PER_THREAD_DEFAULT_STREAM}") +message(STATUS "CUPROJ: Disable warnings generated from deprecated declarations: ${DISABLE_DEPRECATION_WARNING}") +message(STATUS "CUPROJ: Enable the -lineinfo option for nvcc (useful for cuda-memcheck / profiler: ${CUDA_ENABLE_LINEINFO}") +message(STATUS "CUPROJ: Statically link the CUDA toolkit runtime and libraries: ${CUDA_STATIC_RUNTIME}") + +# Set a default build type if none was specified +rapids_cmake_build_type("Release") +set(CUPROJ_BUILD_TESTS ${BUILD_TESTS}) +set(CUPROJ_BUILD_BENCHMARKS ${BUILD_BENCHMARKS}) + +set(CUPROJ_CXX_FLAGS "") +set(CUPROJ_CUDA_FLAGS "") +set(CUPROJ_CXX_DEFINITIONS "") +set(CUPROJ_CUDA_DEFINITIONS "") + +# Set RMM logging level +set(RMM_LOGGING_LEVEL "INFO" CACHE STRING "Choose the logging level.") +set_property(CACHE RMM_LOGGING_LEVEL PROPERTY STRINGS "TRACE" "DEBUG" "INFO" "WARN" "ERROR" "CRITICAL" "OFF") +message(STATUS "CUPROJ: RMM_LOGGING_LEVEL = '${RMM_LOGGING_LEVEL}'.") + +################################################################################################### +# - conda environment ----------------------------------------------------------------------------- + +rapids_cmake_support_conda_env(conda_env) + +################################################################################################### +# - compiler options ------------------------------------------------------------------------------ + +rapids_cuda_init_runtime(USE_STATIC ${CUDA_STATIC_RUNTIME}) + +# * find CUDAToolkit package +# * determine GPU architectures +# * enable the CMake CUDA language +# * set other CUDA compilation flags +include(cmake/modules/ConfigureCUDA.cmake) + +################################################################################################### +# - dependencies ---------------------------------------------------------------------------------- + +# add third party dependencies using CPM +rapids_cpm_init() +# find or add cuDF +include(cmake/thirdparty/get_cudf.cmake) +# find or install GoogleTest and Proj +if (CUPROJ_BUILD_TESTS) + include(cmake/thirdparty/get_gtest.cmake) + include(cmake/thirdparty/get_proj.cmake) +endif() + +################################################################################################### +# - library targets ------------------------------------------------------------------------------- + +add_library(cuproj + src/test.cu +) + +set_target_properties(cuproj + PROPERTIES BUILD_RPATH "\$ORIGIN" + INSTALL_RPATH "\$ORIGIN" + # set target compile options + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CUDA_STANDARD 17 + CUDA_STANDARD_REQUIRED ON + POSITION_INDEPENDENT_CODE ON + INTERFACE_POSITION_INDEPENDENT_CODE ON +) + +target_compile_options(cuproj + PRIVATE "$<$:${CUPROJ_CXX_FLAGS}>" + "$<$:${CUPROJ_CUDA_FLAGS}>" +) + +target_compile_definitions(cuproj + PUBLIC "$<$:${CUPROJ_CXX_DEFINITIONS}>" + "$<$:${CUPROJ_CUDA_DEFINITIONS}>" +) + +# Specify include paths for the current target and dependents +target_include_directories(cuproj + PUBLIC "$" + PRIVATE "$" + INTERFACE "$") + +# Add Conda library and include paths if specified +if(TARGET conda_env) + target_link_libraries(cuproj PRIVATE "$") +endif() + +# Per-thread default stream +if(PER_THREAD_DEFAULT_STREAM) + target_compile_definitions(cuproj PUBLIC CUDA_API_PER_THREAD_DEFAULT_STREAM) +endif() + +# Disable NVTX if necessary +if(NOT USE_NVTX) + target_compile_definitions(cuproj PUBLIC NVTX_DISABLE) +endif() + +# Define spdlog level +target_compile_definitions(cuproj PUBLIC "SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_${RMM_LOGGING_LEVEL}") + +# Specify the target module library dependencies +#target_link_libraries(cuproj PUBLIC cudf::cudf) + +add_library(cuproj::cuproj ALIAS cuproj) + +################################################################################################### +# - add tests ------------------------------------------------------------------------------------- + +if(CUPROJ_BUILD_TESTS) + # include CTest module -- automatically calls enable_testing() + include(CTest) + add_subdirectory(tests) +endif() + +################################################################################################### +# - add benchmarks -------------------------------------------------------------------------------- + +if(CUPROJ_BUILD_BENCHMARKS) + # Find or install GoogleBench + CPMFindPackage(NAME benchmark + VERSION 1.5.3 + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG v1.5.3 + GIT_SHALLOW TRUE + OPTIONS "BENCHMARK_ENABLE_TESTING OFF" + "BENCHMARK_ENABLE_INSTALL OFF") + + # Find or install NVBench Temporarily force downloading of fmt because current versions of nvbench + # do not support the latest version of fmt, which is automatically pulled into our conda + # environments by mamba. + set(CPM_DOWNLOAD_fmt TRUE) + include(${rapids-cmake-dir}/cpm/nvbench.cmake) + rapids_cpm_nvbench() + add_subdirectory(benchmarks) +endif() + +################################################################################################### +# - install targets ------------------------------------------------------------------------------- + +rapids_cmake_install_lib_dir(lib_dir) +include(CPack) + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME cuproj) + +install(TARGETS cuproj + DESTINATION ${lib_dir} + EXPORT cuproj-exports) + +install(DIRECTORY ${CUPROJ_SOURCE_DIR}/include/cuproj + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +set(doc_string + [=[ +Provide targets for the cuproj library. + +cuproj is a GPU-accelerated library for transformation of geospatial coordinates between coordinates +reference systems. + +Imported Targets +^^^^^^^^^^^^^^^^ + +If cuproj is found, this module defines the following IMPORTED GLOBAL +targets: + + cuproj::cuproj - The main cuproj library. + ]=] +) + +rapids_export( + INSTALL cuproj + EXPORT_SET cuproj-exports + GLOBAL_TARGETS cuproj + NAMESPACE cuproj:: + DOCUMENTATION doc_string +) + + +################################################################################################ +# - build export ------------------------------------------------------------------------------- + +rapids_export( + BUILD cuproj + EXPORT_SET cuproj-exports + GLOBAL_TARGETS cuproj + NAMESPACE cuproj:: + DOCUMENTATION doc_string +) + + +# ################################################################################################## +# * build documentation ---------------------------------------------------------------------------- + +find_package(Doxygen) + +if(DOXYGEN_FOUND) + +# doc targets for cuproj +add_custom_command( + OUTPUT CUPROJ_DOXYGEN + WORKING_DIRECTORY ${CUPROJ_SOURCE_DIR}/doxygen + COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile + VERBATIM + COMMENT "Custom command for building cuproj doxygen docs." +) + +add_custom_target( + docs_cuproj + DEPENDS CUPROJ_DOXYGEN + COMMENT "Custom command for building cuproj doxygen docs." +) + +endif() diff --git a/cpp/cuproj/benchmarks/CMakeLists.txt b/cpp/cuproj/benchmarks/CMakeLists.txt new file mode 100644 index 000000000..fd8412f60 --- /dev/null +++ b/cpp/cuproj/benchmarks/CMakeLists.txt @@ -0,0 +1,80 @@ +#============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +#============================================================================= + +################################################################################################### +# - compiler function ----------------------------------------------------------------------------- + +# Use an OBJECT library so we only compile common source files only once +add_library(cuproj_benchmark_common OBJECT + synchronization/synchronization.cpp) + +target_compile_features(cuproj_benchmark_common PUBLIC cxx_std_17 cuda_std_17) + +target_link_libraries(cuproj_benchmark_common + PUBLIC benchmark::benchmark + cudf::cudftestutil + cuproj) + +target_compile_options(cuproj_benchmark_common + PUBLIC "$<$:${CUPROJ_CXX_FLAGS}>" + "$<$:${CUPROJ_CUDA_FLAGS}>") + +target_include_directories(cuproj_benchmark_common + PUBLIC "$" + "$" + "$") + +function(ConfigureBench CMAKE_BENCH_NAME) + add_executable(${CMAKE_BENCH_NAME} ${ARGN}) + set_target_properties(${CMAKE_BENCH_NAME} + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "$" + INSTALL_RPATH "\$ORIGIN/../../../lib" + ) + target_link_libraries(${CMAKE_BENCH_NAME} PRIVATE benchmark::benchmark_main cuproj_benchmark_common) + install( + TARGETS ${CMAKE_BENCH_NAME} + COMPONENT benchmark + DESTINATION bin/benchmarks/libcuproj + EXCLUDE_FROM_ALL + ) +endfunction() + +# This function takes in a benchmark name and benchmark source for nvbench benchmarks and handles +# setting all of the associated properties and linking to build the benchmark +function(ConfigureNVBench CMAKE_BENCH_NAME) + add_executable(${CMAKE_BENCH_NAME} ${ARGN}) + set_target_properties( + ${CMAKE_BENCH_NAME} + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "$" + INSTALL_RPATH "\$ORIGIN/../../../lib" + ) + target_link_libraries( + ${CMAKE_BENCH_NAME} PRIVATE cuproj_benchmark_common nvbench::main + ) + install( + TARGETS ${CMAKE_BENCH_NAME} + COMPONENT benchmark + DESTINATION bin/benchmarks/libcuproj + EXCLUDE_FROM_ALL + ) +endfunction() + +################################################################################################### +### benchmark sources ############################################################################# +################################################################################################### + +ConfigureBench(TEST_BENCH + test.cu) diff --git a/cpp/cuproj/benchmarks/synchronization/synchronization.cpp b/cpp/cuproj/benchmarks/synchronization/synchronization.cpp new file mode 100644 index 000000000..cb132c9e2 --- /dev/null +++ b/cpp/cuproj/benchmarks/synchronization/synchronization.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019-2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include "synchronization.hpp" + +#include + +#include +#include + +cuda_event_timer::cuda_event_timer(benchmark::State& state, + bool flush_l2_cache, + rmm::cuda_stream_view stream) + : stream(stream), p_state(&state) +{ + // flush all of L2$ + if (flush_l2_cache) { + int current_device = 0; + CUPROJ_CUDA_TRY(cudaGetDevice(¤t_device)); + + int l2_cache_bytes = 0; + CUPROJ_CUDA_TRY( + cudaDeviceGetAttribute(&l2_cache_bytes, cudaDevAttrL2CacheSize, current_device)); + + if (l2_cache_bytes > 0) { + const int memset_value = 0; + rmm::device_buffer l2_cache_buffer(l2_cache_bytes, stream); + CUPROJ_CUDA_TRY( + cudaMemsetAsync(l2_cache_buffer.data(), memset_value, l2_cache_bytes, stream.value())); + } + } + + CUPROJ_CUDA_TRY(cudaEventCreate(&start)); + CUPROJ_CUDA_TRY(cudaEventCreate(&stop)); + CUPROJ_CUDA_TRY(cudaEventRecord(start, stream.value())); +} + +cuda_event_timer::~cuda_event_timer() +{ + CUPROJ_CUDA_TRY(cudaEventRecord(stop, stream.value())); + CUPROJ_CUDA_TRY(cudaEventSynchronize(stop)); + + float milliseconds = 0.0f; + CUPROJ_CUDA_TRY(cudaEventElapsedTime(&milliseconds, start, stop)); + p_state->SetIterationTime(milliseconds / (1000.0f)); + CUPROJ_CUDA_TRY(cudaEventDestroy(start)); + CUPROJ_CUDA_TRY(cudaEventDestroy(stop)); +} diff --git a/cpp/cuproj/benchmarks/synchronization/synchronization.hpp b/cpp/cuproj/benchmarks/synchronization/synchronization.hpp new file mode 100644 index 000000000..169450ead --- /dev/null +++ b/cpp/cuproj/benchmarks/synchronization/synchronization.hpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2023, NVIDIA CORPORATION. + * + * 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. + */ + +/** + * @file synchronization.hpp + * @brief This is the header file for `cuda_event_timer`. + **/ + +/** + * @brief This class serves as a wrapper for using `cudaEvent_t` as the user + * defined timer within the framework of google benchmark + * (https://github.com/google/benchmark). + * + * It is built on top of the idea of Resource acquisition is initialization + * (RAII). In the following we show a minimal example of how to use this class. + + #include + + static void sample_cuda_benchmark(benchmark::State& state) { + + for (auto _ : state){ + + rmm::cuda_stream_view stream{}; // default stream, could be another stream + + // Create (Construct) an object of this class. You HAVE to pass in the + // benchmark::State object you are using. It measures the time from its + // creation to its destruction that is spent on the specified CUDA stream. + // It also clears the L2 cache by cudaMemset'ing a device buffer that is of + // the size of the L2 cache (if flush_l2_cache is set to true and there is + // an L2 cache on the current device). + cuda_event_timer raii(state, true, stream); // flush_l2_cache = true + + // Now perform the operations that is to be benchmarked + sample_kernel<<<1, 256, 0, stream.value()>>>(); // Possibly launching a CUDA kernel + + } + } + + // Register the function as a benchmark. You will need to set the `UseManualTime()` + // flag in order to use the timer embedded in this class. + BENCHMARK(sample_cuda_benchmark)->UseManualTime(); + + + **/ + +#ifndef CUDF_BENCH_SYNCHRONIZATION_H +#define CUDF_BENCH_SYNCHRONIZATION_H + +// Google Benchmark library +#include + +#include + +#include + +#include + +class cuda_event_timer { + public: + /** + * @brief This c'tor clears the L2$ by cudaMemset'ing a buffer of L2$ size + * and starts the timer. + * + * @param[in,out] state This is the benchmark::State whose timer we are going + * to update. + * @param[in] flush_l2_cache_ whether or not to flush the L2 cache before + * every iteration. + * @param[in] stream_ The CUDA stream we are measuring time on. + **/ + cuda_event_timer(benchmark::State& state, + bool flush_l2_cache, + rmm::cuda_stream_view stream = rmm::cuda_stream_default); + + // The user must provide a benchmark::State object to set + // the timer so we disable the default c'tor. + cuda_event_timer() = delete; + + // The d'tor stops the timer and performs a synchronization. + // Time of the benchmark::State object provided to the c'tor + // will be set to the value given by `cudaEventElapsedTime`. + ~cuda_event_timer(); + + private: + cudaEvent_t start; + cudaEvent_t stop; + rmm::cuda_stream_view stream; + benchmark::State* p_state; +}; + +#endif diff --git a/cpp/cuproj/benchmarks/test.cu b/cpp/cuproj/benchmarks/test.cu new file mode 100644 index 000000000..e69de29bb diff --git a/cpp/cuproj/cmake/modules/ConfigureCUDA.cmake b/cpp/cuproj/cmake/modules/ConfigureCUDA.cmake new file mode 100644 index 000000000..792cd5cab --- /dev/null +++ b/cpp/cuproj/cmake/modules/ConfigureCUDA.cmake @@ -0,0 +1,50 @@ +#============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +#============================================================================= + +if(CMAKE_COMPILER_IS_GNUCXX) + list(APPEND CUPROJ_CXX_FLAGS -Wall -Werror -Wno-unknown-pragmas -Wno-error=deprecated-declarations) + if(CUPROJ_BUILD_TESTS OR CUPROJ_BUILD_BENCHMARKS) + # Suppress parentheses warning which causes gmock to fail + list(APPEND CUPROJ_CUDA_FLAGS -Xcompiler=-Wno-parentheses) + endif() +endif(CMAKE_COMPILER_IS_GNUCXX) + +list(APPEND CUPROJ_CUDA_FLAGS --expt-extended-lambda --expt-relaxed-constexpr) + +# set warnings as errors +if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2.0) + list(APPEND CUPROJ_CUDA_FLAGS -Werror=all-warnings) +endif() +list(APPEND CUPROJ_CUDA_FLAGS -Xcompiler=-Wall,-Werror,-Wno-error=deprecated-declarations) + +# Produce smallest binary size +list(APPEND CUPROJ_CUDA_FLAGS -Xfatbin=-compress-all) + +if(DISABLE_DEPRECATION_WARNING) + list(APPEND CUPROJ_CXX_FLAGS -Wno-deprecated-declarations) + list(APPEND CUPROJ_CUDA_FLAGS -Xcompiler=-Wno-deprecated-declarations) +endif() + +# Option to enable line info in CUDA device compilation to allow introspection when profiling / memchecking +if(CUDA_ENABLE_LINEINFO) + list(APPEND CUPROJ_CUDA_FLAGS -lineinfo) +endif() + +# Debug options +if(CMAKE_BUILD_TYPE MATCHES Debug) + message(STATUS "CUSPATIAL: Building with debugging flags") + list(APPEND CUPROJ_CUDA_FLAGS -G -Xcompiler=-rdynamic) +endif() diff --git a/cpp/cuproj/cmake/thirdparty/get_cudf.cmake b/cpp/cuproj/cmake/thirdparty/get_cudf.cmake new file mode 100644 index 000000000..8bd70fdc6 --- /dev/null +++ b/cpp/cuproj/cmake/thirdparty/get_cudf.cmake @@ -0,0 +1,77 @@ +#============================================================================= +# Copyright (c) 2021-2023, NVIDIA CORPORATION. +# +# 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. +#============================================================================= + +function(find_and_configure_cudf) + + if(TARGET cudf::cudf) + return() + endif() + + set(oneValueArgs VERSION GIT_REPO GIT_TAG USE_CUDF_STATIC EXCLUDE_FROM_ALL PER_THREAD_DEFAULT_STREAM) + cmake_parse_arguments(PKG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(global_targets cudf::cudf) + set(cudf_components "") + + if(BUILD_TESTS OR BUILD_BENCHMARKS) + list(APPEND global_targets cudf::cudftestutil) + set(cudf_components COMPONENTS testing) + endif() + + set(BUILD_SHARED ON) + if(${PKG_USE_CUDF_STATIC}) + set(BUILD_SHARED OFF) + endif() + + rapids_cpm_find(cudf ${PKG_VERSION} ${cudf_components} + GLOBAL_TARGETS ${global_targets} + BUILD_EXPORT_SET cuproj-exports + INSTALL_EXPORT_SET cuproj-exports + CPM_ARGS + GIT_REPOSITORY ${PKG_GIT_REPO} + GIT_TAG ${PKG_GIT_TAG} + GIT_SHALLOW TRUE + SOURCE_SUBDIR cpp + EXCLUDE_FROM_ALL ${PKG_EXCLUDE_FROM_ALL} + OPTIONS "BUILD_TESTS OFF" + "BUILD_BENCHMARKS OFF" + "BUILD_SHARED_LIBS ${BUILD_SHARED}" + "CUDF_BUILD_TESTUTIL ${BUILD_TESTS}" + "CUDF_BUILD_STREAMS_TEST_UTIL ${BUILD_TESTS}" + "CUDF_USE_PER_THREAD_DEFAULT_STREAM ${PKG_PER_THREAD_DEFAULT_STREAM}" + ) + + if(TARGET cudf) + set_property(TARGET cudf PROPERTY SYSTEM TRUE) + endif() +endfunction() + +set(CUPROJ_MIN_VERSION_cudf "${CUPROJ_VERSION_MAJOR}.${CUPROJ_VERSION_MINOR}") + +if(NOT DEFINED CUPROJ_CUDF_GIT_REPO) + set(CUPROJ_CUDF_GIT_REPO https://github.com/rapidsai/cudf.git) +endif() + +if(NOT DEFINED CUPROJ_CUDF_GIT_TAG) + set(CUPROJ_CUDF_GIT_TAG branch-${CUPROJ_MIN_VERSION_cudf}) +endif() + +find_and_configure_cudf(VERSION ${CUPROJ_MIN_VERSION_cudf}.00 + GIT_REPO ${CUPROJ_CUDF_GIT_REPO} + GIT_TAG ${CUPROJ_CUDF_GIT_TAG} + USE_CUDF_STATIC ${CUPROJ_USE_CUDF_STATIC} + EXCLUDE_FROM_ALL ${CUPROJ_EXCLUDE_CUDF_FROM_ALL} + PER_THREAD_DEFAULT_STREAM ${PER_THREAD_DEFAULT_STREAM}) diff --git a/cpp/cuproj/cmake/thirdparty/get_gtest.cmake b/cpp/cuproj/cmake/thirdparty/get_gtest.cmake new file mode 100644 index 000000000..0eaa54d25 --- /dev/null +++ b/cpp/cuproj/cmake/thirdparty/get_gtest.cmake @@ -0,0 +1,39 @@ +# ============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +# ============================================================================= + +# This function finds gtest and sets any additional necessary environment variables. +function(find_and_configure_gtest) + include(${rapids-cmake-dir}/cpm/gtest.cmake) + + # Find or install GoogleTest + rapids_cpm_gtest(BUILD_EXPORT_SET cuproj-testing-exports INSTALL_EXPORT_SET cuproj-testing-exports) + + if(GTest_ADDED) + rapids_export( + BUILD GTest + VERSION ${GTest_VERSION} + EXPORT_SET GTestTargets + GLOBAL_TARGETS gtest gmock gtest_main gmock_main + NAMESPACE GTest:: + ) + + include("${rapids-cmake-dir}/export/find_package_root.cmake") + rapids_export_find_package_root( + BUILD GTest [=[${CMAKE_CURRENT_LIST_DIR}]=] cuproj-testing-exports + ) + endif() + +endfunction() + +find_and_configure_gtest() diff --git a/cpp/cuproj/cmake/thirdparty/get_proj.cmake b/cpp/cuproj/cmake/thirdparty/get_proj.cmake new file mode 100644 index 000000000..cd0b914eb --- /dev/null +++ b/cpp/cuproj/cmake/thirdparty/get_proj.cmake @@ -0,0 +1,32 @@ +# ============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +# ============================================================================= + +# This function finds osgeo/proj and sets any additional necessary environment variables. +function(find_and_configure_proj VERSION) + include(${rapids-cmake-dir}/cpm/find.cmake) + + # Find or install Proj + rapids_cpm_find( + PROJ ${VERSION} + GLOBAL_TARGETS PROJ::proj + BUILD_EXPORT_SET cuproj-exports + INSTALL_EXPORT_SET cuproj-exports + CPM_ARGS + GIT_REPOSITORY https://github.com/osgeo/proj.git + GIT_TAG ${VERSION} + GIT_SHALLOW TRUE + ) +endfunction() + +find_and_configure_proj(9.2.0) diff --git a/cpp/cuproj/include/cuproj/assert.cuh b/cpp/cuproj/include/cuproj/assert.cuh new file mode 100644 index 000000000..cca3e5df8 --- /dev/null +++ b/cpp/cuproj/include/cuproj/assert.cuh @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +/** + * @brief `assert`-like macro for device code + * + * This is effectively the same as the standard `assert` macro, except it + * relies on the `__PRETTY_FUNCTION__` macro which is specific to GCC and Clang + * to produce better assert messages. + */ +#if !defined(NDEBUG) && defined(__CUDA_ARCH__) && (defined(__clang__) || defined(__GNUC__)) +#define __ASSERT_STR_HELPER(x) #x +#define cuproj_assert(e) \ + ((e) ? static_cast(0) \ + : __assert_fail(__ASSERT_STR_HELPER(e), __FILE__, __LINE__, __PRETTY_FUNCTION__)) +#else +#define cuproj_assert(e) (static_cast(0)) +#endif diff --git a/cpp/cuproj/include/cuproj/error.hpp b/cpp/cuproj/include/cuproj/error.hpp new file mode 100644 index 000000000..907804a34 --- /dev/null +++ b/cpp/cuproj/include/cuproj/error.hpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +#include + +#include +#include + +namespace cuproj { + +/** + * @addtogroup exception + * @{ + */ + +/**---------------------------------------------------------------------------* + * @brief Exception thrown when logical precondition is violated. + * + * This exception should not be thrown directly and is instead thrown by the + * CUPROJ_EXPECTS macro. + * + *---------------------------------------------------------------------------**/ +struct logic_error : public std::logic_error { + logic_error(char const* const message) : std::logic_error(message) {} + logic_error(std::string const& message) : std::logic_error(message) {} +}; + +/** + * @brief Exception thrown when a CUDA error is encountered. + */ +struct cuda_error : public std::runtime_error { + cuda_error(std::string const& message) : std::runtime_error(message) {} +}; + +/** + * @} // end of doxygen group + */ + +} // namespace cuproj + +#define CUPROJ_STRINGIFY_DETAIL(x) #x +#define CUPROJ_STRINGIFY(x) CUPROJ_STRINGIFY_DETAIL(x) + +/**---------------------------------------------------------------------------* + * @brief Macro for checking (pre-)conditions that throws an exception when + * a condition is violated. + * + * Example usage: + * + * @code + * CUPROJ_EXPECTS(lhs->dtype == rhs->dtype, "Column type mismatch"); + * @endcode + * + * @param[in] cond Expression that evaluates to true or false + * @param[in] reason String literal description of the reason that cond is + * expected to be true + * @throw cuproj::logic_error if the condition evaluates to false. + *---------------------------------------------------------------------------**/ +#define CUPROJ_EXPECTS(cond, reason) \ + (!!(cond)) ? static_cast(0) \ + : throw cuspatial::logic_error("cuProj failure at: " __FILE__ \ + ":" CUPROJ_STRINGIFY(__LINE__) ": " reason) + +/**---------------------------------------------------------------------------* + * @brief Macro for checking (pre-)conditions that throws an exception when + * a condition is violated. + * + * Example usage: + * + * @code + * CUPROJ_HOST_DEVICE_EXPECTS(lhs->dtype == rhs->dtype, "Column type + *mismatch"); + * @endcode + * + * @param[in] cond Expression that evaluates to true or false + * @param[in] reason String literal description of the reason that cond is + * expected to be true + * + * (if on host) + * @throw cuproj::logic_error if the condition evaluates to false. + * (if on device) + * program terminates and assertion error message is printed to stderr. + *---------------------------------------------------------------------------**/ +#ifndef __CUDA_ARCH__ +#define CUPROJ_HOST_DEVICE_EXPECTS(cond, reason) CUPROJ_EXPECTS(cond, reason) +#else +#define CUPROJ_HOST_DEVICE_EXPECTS(cond, reason) cuproj_assert(cond&& reason) +#endif + +/**---------------------------------------------------------------------------* + * @brief Indicates that an erroneous code path has been taken. + * + * In host code, throws a `cuproj::logic_error`. + * + * + * Example usage: + * ``` + * CUPROJ_FAIL("Non-arithmetic operation is not supported"); + * ``` + * + * @param[in] reason String literal description of the reason + *---------------------------------------------------------------------------**/ +#define CUPROJ_FAIL(reason) \ + throw cuproj::logic_error("cuProj failure at: " __FILE__ ":" CUPROJ_STRINGIFY( \ + __LINE__) ":" \ + " " reason) + +namespace cuproj { +namespace detail { + +inline void throw_cuda_error(cudaError_t error, const char* file, unsigned int line) +{ + throw cuproj::cuda_error(std::string{"CUDA error encountered at: " + std::string{file} + ":" + + std::to_string(line) + ": " + std::to_string(error) + " " + + cudaGetErrorName(error) + " " + cudaGetErrorString(error)}); +} + +} // namespace detail +} // namespace cuproj + +/** + * @brief Error checking macro for CUDA runtime API functions. + * + * Invokes a CUDA runtime API function call, if the call does not return + * cudaSuccess, invokes cudaGetLastError() to clear the error and throws an + * exception detailing the CUDA error that occurred + */ +#define CUPROJ_CUDA_TRY(call) \ + do { \ + cudaError_t const status = (call); \ + if (cudaSuccess != status) { \ + cudaGetLastError(); \ + cuproj::detail::throw_cuda_error(status, __FILE__, __LINE__); \ + } \ + } while (0); + +/** + * @brief Debug macro to check for CUDA errors + * + * In a non-release build, this macro will synchronize the specified stream + * before error checking. In both release and non-release builds, this macro + * checks for any pending CUDA errors from previous calls. If an error is + * reported, an exception is thrown detailing the CUDA error that occurred. + * + * The intent of this macro is to provide a mechanism for synchronous and + * deterministic execution for debugging asynchronous CUDA execution. It should + * be used after any asynchronous CUDA call, e.g., cudaMemcpyAsync, or an + * asynchronous kernel launch. + */ +#ifndef NDEBUG +#define CUPROJ_CHECK_CUDA(stream) \ + do { \ + CUPROJ_CUDA_TRY(cudaStreamSynchronize(stream)); \ + CUPROJ_CUDA_TRY(cudaPeekAtLastError()); \ + } while (0); +#else +#define CUPROJ_CHECK_CUDA(stream) CUPROJ_CUDA_TRY(cudaPeekAtLastError()); +#endif diff --git a/cpp/cuproj/src/test.cu b/cpp/cuproj/src/test.cu new file mode 100644 index 000000000..e69de29bb diff --git a/cpp/cuproj/tests/CMakeLists.txt b/cpp/cuproj/tests/CMakeLists.txt new file mode 100644 index 000000000..e69f76a87 --- /dev/null +++ b/cpp/cuproj/tests/CMakeLists.txt @@ -0,0 +1,53 @@ +#============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +#============================================================================= + +################################################################################################### +# - compiler function ----------------------------------------------------------------------------- + +function(ConfigureTest CMAKE_TEST_NAME) + add_executable(${CMAKE_TEST_NAME} ${ARGN}) + target_compile_options(${CMAKE_TEST_NAME} + PRIVATE "$<$:${CUPROJ_CXX_FLAGS}>" + "$<$:${CUPROJ_CUDA_FLAGS}>") + target_include_directories(${CMAKE_TEST_NAME} + PRIVATE "$" + "$") + set_target_properties( + ${CMAKE_TEST_NAME} + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "$" + INSTALL_RPATH "\$ORIGIN/../../../lib" + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CUDA_STANDARD 17 + CUDA_STANDARD_REQUIRED ON + ) + target_link_libraries(${CMAKE_TEST_NAME} GTest::gtest_main GTest::gmock_main cudf::cudftestutil PROJ::proj cuproj) + add_test(NAME ${CMAKE_TEST_NAME} COMMAND ${CMAKE_TEST_NAME}) + install( + TARGETS ${CMAKE_TEST_NAME} + COMPONENT testing + DESTINATION bin/gtests/libcuspatial # add to libcuspatial CI testing + EXCLUDE_FROM_ALL + ) +endfunction(ConfigureTest) + +################################################################################################### +### test sources ################################################################################## +################################################################################################### + +# index +ConfigureTest(TEST_TEST + test.cu) diff --git a/cpp/cuproj/tests/test.cu b/cpp/cuproj/tests/test.cu new file mode 100644 index 000000000..0d10a9c50 --- /dev/null +++ b/cpp/cuproj/tests/test.cu @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include + +#include + +#include + +template +struct ProjectionTest : public ::testing::Test {}; + +using TestTypes = ::testing::Types; +TYPED_TEST_CASE(ProjectionTest, TestTypes); + +TYPED_TEST(ProjectionTest, Empty) +{ + PJ_CONTEXT* C; + PJ* P; + + C = proj_context_create(); + + P = proj_create_crs_to_crs(C, "EPSG:4326", "EPSG:32756", NULL); + + PJ_COORD input_coords, + output_coords; // https://proj.org/development/reference/datatypes.html#c.PJ_COORD + + input_coords = proj_coord(-28.667003, 153.090959, 0, 0); + + output_coords = proj_trans(P, PJ_FWD, input_coords); + + std::cout << output_coords.xy.x << " " << output_coords.xy.y << std::endl; + + /* Clean up */ + proj_destroy(P); + proj_context_destroy(C); // may be omitted in the single threaded case +} diff --git a/dependencies.yaml b/dependencies.yaml index 4944bfbef..61224cf96 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -85,6 +85,8 @@ dependencies: - gtest>=1.13.0 - libcudf==23.8.* - librmm==23.8.* + - proj + - sqlite specific: - output_types: conda matrices: From 3da33321bef91c6640519f0e1a6c54b332e98077 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 26 Jun 2023 09:59:07 -0700 Subject: [PATCH 51/63] Add author credit to zipcode counting notebook, fix cudf string processing argument (#1201) This PR fixes the usage of a small cudf string processing method. `regex` should be set to false for `.str.split` without regex delimiter. In addition, adds credit to authors. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1201 --- notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb b/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb index bd74e59a4..987562d5e 100644 --- a/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb +++ b/notebooks/ZipCodes_Stops_PiP_cuSpatial.ipynb @@ -1,14 +1,18 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", "id": "458fe838-b143-4d31-9ddd-8efd0217f4a7", "metadata": {}, "source": [ - "# Stop Sign Counting By Zipcode in California" + "# Stop Sign Counting By Zipcode in California\n", + "\n", + "Author: Everett Spackman, Michael Wang, Thomson Comer, Ben Jarmak" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "6931011f-0d83-45ce-b254-4b5424b82624", "metadata": {}, @@ -59,6 +63,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "497810f3-acf0-4472-a187-322413c9db11", "metadata": {}, @@ -108,6 +113,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "044c84d9-2f82-4de5-a4c5-b7b9e5ef6b93", "metadata": {}, @@ -144,6 +150,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "50b8d8bc-378f-4faa-b60c-e8f0ff507b2a", "metadata": {}, @@ -170,6 +177,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "6fdaedfc-2d7f-4d73-a9b8-e3a8131bea2f", "metadata": {}, @@ -221,7 +229,7 @@ " # split polygons into rings\n", " wkts, num_rings = traverse(wkts, \"\\),\\s?\\(\", regex=True)\n", " # split coordinates into lists\n", - " wkts, num_coords = traverse(wkts, \",\", regex=True)\n", + " wkts, num_coords = traverse(wkts, \",\")\n", " # split into x-y coordinates\n", " wkts = wkts.str.split(\" \")\n", " wkts = wkts.explode().astype(cp.dtype(dtype))\n", @@ -400,6 +408,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "eda8fb4c-39ec-44e2-9163-cbbdd91eeb1d", "metadata": {}, @@ -468,6 +477,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "ab387f5a-cf7e-49d4-b3c8-c5b4b059cd4d", "metadata": {}, @@ -476,6 +486,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "6446d81b-006a-4a0b-995b-a001c9b7766f", "metadata": {}, @@ -604,6 +615,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "4b61f534-faa4-4465-b47b-fb717169f30e", "metadata": {}, @@ -668,6 +680,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "d1f2af42-affb-4e9e-ac24-b5583641a366", "metadata": {}, @@ -734,6 +747,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "e05fc526-c935-417f-9f53-0f13a0c6d02a", "metadata": {}, From 7cb3000e8ae2ce6021e917b6eb10c87e6aa038af Mon Sep 17 00:00:00 2001 From: Mark Harris <783069+harrism@users.noreply.github.com> Date: Tue, 27 Jun 2023 15:05:12 +1000 Subject: [PATCH 52/63] Use grid_stride_range in kernel loops (#1178) Adds a dependency on [Ranger](https://github.com/harrism/ranger) and uses `ranger::grid_stride_loop` with a range-based for loop in outer loops in every raw kernel in cuSpatial. In the few cases where we had raw kernels without grid-stride loops, this adds one. Also adds guidance to the C++ developer guide. Authors: - Mark Harris (https://github.com/harrism) - Michael Wang (https://github.com/isVoid) Approvers: - Michael Wang (https://github.com/isVoid) - Robert Maynard (https://github.com/robertmaynard) URL: https://github.com/rapidsai/cuspatial/pull/1178 --- cpp/CMakeLists.txt | 3 + cpp/benchmarks/CMakeLists.txt | 1 + cpp/cmake/thirdparty/get_ranger.cmake | 40 +++++++++ .../developer_guide/DEVELOPER_GUIDE.md | 47 +++++++++- .../cuspatial/detail/distance/hausdorff.cuh | 85 +++++++++---------- .../detail/find/find_and_combine_segment.cuh | 5 +- .../detail/find/find_duplicate_points.cuh | 5 +- .../linestring_intersection_count.cuh | 7 +- ...inestring_intersection_with_duplicates.cuh | 5 +- .../detail/kernel/pairwise_distance.cuh | 13 +-- .../pairwise_multipoint_equals_count.cuh | 5 +- .../point_linestring_nearest_points.cuh | 7 +- .../cuspatial_test/geometry_generator.cuh | 5 +- cpp/tests/CMakeLists.txt | 2 +- cpp/tests/operators/linestrings_test.cu | 8 +- 15 files changed, 168 insertions(+), 70 deletions(-) create mode 100644 cpp/cmake/thirdparty/get_ranger.cmake diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 4fe6b6615..e2f771dda 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -109,6 +109,8 @@ include(cmake/thirdparty/get_cudf.cmake) if (CUSPATIAL_BUILD_TESTS) include(cmake/thirdparty/get_gtest.cmake) endif() +# find or add ranger +include (cmake/thirdparty/get_ranger.cmake) ################################################################################################### # - library targets ------------------------------------------------------------------------------- @@ -201,6 +203,7 @@ target_compile_definitions(cuspatial PUBLIC "SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_${ # Specify the target module library dependencies target_link_libraries(cuspatial PUBLIC cudf::cudf) +target_link_libraries(cuspatial PRIVATE ranger::ranger) add_library(cuspatial::cuspatial ALIAS cuspatial) diff --git a/cpp/benchmarks/CMakeLists.txt b/cpp/benchmarks/CMakeLists.txt index e2587c710..99780a677 100644 --- a/cpp/benchmarks/CMakeLists.txt +++ b/cpp/benchmarks/CMakeLists.txt @@ -26,6 +26,7 @@ target_compile_features(cuspatial_benchmark_common PUBLIC cxx_std_17 cuda_std_17 target_link_libraries(cuspatial_benchmark_common PUBLIC benchmark::benchmark cudf::cudftestutil + ranger::ranger cuspatial) target_compile_options(cuspatial_benchmark_common diff --git a/cpp/cmake/thirdparty/get_ranger.cmake b/cpp/cmake/thirdparty/get_ranger.cmake new file mode 100644 index 000000000..563e4120a --- /dev/null +++ b/cpp/cmake/thirdparty/get_ranger.cmake @@ -0,0 +1,40 @@ +#============================================================================= +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# 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. +#============================================================================= + +function(find_and_configure_ranger) + + if(TARGET ranger::ranger) + return() + endif() + + set(global_targets ranger::ranger) + set(find_package_args "") + + rapids_cpm_find( + ranger 00.01.00 + GLOBAL_TARGETS "${global_targets}" + BUILD_EXPORT_SET cuspatial-exports + INSTALL_EXPORT_SET cuspatial-exports + CPM_ARGS + GIT_REPOSITORY https://github.com/harrism/ranger.git + GIT_TAG main + GIT_SHALLOW TRUE + OPTIONS "BUILD_TESTS OFF" + FIND_PACKAGE_ARGUMENTS "${find_package_args}" + ) +endfunction() + +find_and_configure_ranger() diff --git a/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md b/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md index 4cbbd9bee..74db9350f 100644 --- a/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md +++ b/cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md @@ -120,9 +120,10 @@ caught during code review, or not enforced. In general, we recommend following [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). We also recommend watching Sean Parent's [C++ Seasoning talk](https://www.youtube.com/watch?v=W2tWOdzgXHA), -and we try to follow his rules: "No raw loops. No raw pointers. No raw synchronization primitives." +and we try to follow his rules: "No raw loops. No raw pointers. No raw synchronization primitives." We also wherever possible add a fourth rule: "No raw kernels". * Prefer algorithms from STL and Thrust to raw loops. + * Prefer Thrust algorithms to raw kernels. * For device storage, prefer libcudf and RMM [owning data structures and views](#libcuspatial-data-structures) to raw pointers and raw memory allocation. When pointers are used, prefer smart pointers (e.g. `std::shared_ptr` and @@ -131,6 +132,50 @@ and we try to follow his rules: "No raw loops. No raw pointers. No raw synchroni Documentation is discussed in the [Documentation Guide](DOCUMENTATION.md). +### Loops and Grid-stride Loops + +Prefer algorithms over raw loops wherever possible, as mentioned above. However, avoiding raw loops is not always possible. C++ range-based for loops can make raw loops much +clearer, and cuSpatial uses [Ranger](https://github.com/harrism/ranger) for this purpose. +Ranger provides range helpers with iterators that can be passed to range-based for loops. Of special importance is `ranger::grid_stride_range()`, which can be used to iterate over +a range in parallel using all threads of a CUDA grid. + +When writing custom kernels, grid stride ranges help ensure kernels are adaptable to a +variety of grid shapes, most notably when there are fewer total threads than there are +data items. Instead of: + +```c++ +__global__ void foo(int n, int* data) { + auto const idx = threadIdx.x + blockIdx.x * blockDim.x; + if (idx < n) return; + + // process data +} +``` + +A grid-stride loop ensures all of data is processed even if there are fewer than n threads: + +```c++ +__global__ void foo(int n, int* data) { + for (auto const idx = threadIdx.x + blockIdx.x * blockDim.x; + idx < n; + idx += blockDim.x * gridDim.x) { + // process data + } +} +``` + +With ranger, the code is even clearer and less error prone: + +```c++ +#include + +__global__ void foo(int n, int* data) { + for (auto const idx = ranger::grid_stride_range(n)) { + // process data + } +} +``` + ### Includes The following guidelines apply to organizing `#include` lines. diff --git a/cpp/include/cuspatial/detail/distance/hausdorff.cuh b/cpp/include/cuspatial/detail/distance/hausdorff.cuh index 022c4490b..3b25014a4 100644 --- a/cpp/include/cuspatial/detail/distance/hausdorff.cuh +++ b/cpp/include/cuspatial/detail/distance/hausdorff.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,8 @@ #include #include +#include + #include #include #include @@ -87,49 +89,46 @@ __global__ void kernel_hausdorff( using Point = typename std::iterator_traits::value_type; // determine the LHS point this thread is responsible for. - auto const thread_idx = blockIdx.x * blockDim.x + threadIdx.x; - Index const lhs_p_idx = thread_idx; - - if (lhs_p_idx >= num_points) { return; } - - auto const lhs_space_iter = - thrust::upper_bound(thrust::seq, space_offsets, space_offsets + num_spaces, lhs_p_idx); - // determine the LHS space this point belongs to. - Index const lhs_space_idx = thrust::distance(space_offsets, thrust::prev(lhs_space_iter)); - - // get the coordinates of this LHS point. - Point const lhs_p = points[lhs_p_idx]; - - // loop over each RHS space, as determined by spa ce_offsets - for (uint32_t rhs_space_idx = 0; rhs_space_idx < num_spaces; rhs_space_idx++) { - // determine the begin/end offsets of points contained within this RHS space. - Index const rhs_p_idx_begin = space_offsets[rhs_space_idx]; - Index const rhs_p_idx_end = - (rhs_space_idx + 1 == num_spaces) ? num_points : space_offsets[rhs_space_idx + 1]; - - // each space must contain at least one point, this initial value is just an identity value to - // simplify calculations. If a space contains <= 0 points, then this initial value will be - // written to the output, which can serve as a signal that the input is ill-formed. - auto min_distance_squared = std::numeric_limits::max(); - - // loop over each point in the current RHS space - for (uint32_t rhs_p_idx = rhs_p_idx_begin; rhs_p_idx < rhs_p_idx_end; rhs_p_idx++) { - // get the x and y coordinate of this RHS point - Point const rhs_p = thrust::raw_reference_cast(points[rhs_p_idx]); - - // get distance between the LHS and RHS point - auto const distance_squared = magnitude_squared(rhs_p.x - lhs_p.x, rhs_p.y - lhs_p.y); - - // remember only smallest distance from this LHS point to any RHS point. - min_distance_squared = ::min(min_distance_squared, distance_squared); + for (auto lhs_p_idx : ranger::grid_stride_range(num_points)) { + auto const lhs_space_iter = + thrust::upper_bound(thrust::seq, space_offsets, space_offsets + num_spaces, lhs_p_idx); + // determine the LHS space this point belongs to. + Index const lhs_space_idx = thrust::distance(space_offsets, thrust::prev(lhs_space_iter)); + + // get the coordinates of this LHS point. + Point const lhs_p = points[lhs_p_idx]; + + // loop over each RHS space, as determined by spa ce_offsets + for (uint32_t rhs_space_idx = 0; rhs_space_idx < num_spaces; rhs_space_idx++) { + // determine the begin/end offsets of points contained within this RHS space. + Index const rhs_p_idx_begin = space_offsets[rhs_space_idx]; + Index const rhs_p_idx_end = + (rhs_space_idx + 1 == num_spaces) ? num_points : space_offsets[rhs_space_idx + 1]; + + // each space must contain at least one point, this initial value is just an identity value to + // simplify calculations. If a space contains <= 0 points, then this initial value will be + // written to the output, which can serve as a signal that the input is ill-formed. + auto min_distance_squared = std::numeric_limits::max(); + + // loop over each point in the current RHS space + for (uint32_t rhs_p_idx = rhs_p_idx_begin; rhs_p_idx < rhs_p_idx_end; rhs_p_idx++) { + // get the x and y coordinate of this RHS point + Point const rhs_p = thrust::raw_reference_cast(points[rhs_p_idx]); + + // get distance between the LHS and RHS point + auto const distance_squared = magnitude_squared(rhs_p.x - lhs_p.x, rhs_p.y - lhs_p.y); + + // remember only smallest distance from this LHS point to any RHS point. + min_distance_squared = ::min(min_distance_squared, distance_squared); + } + + // determine the output offset for this pair of spaces (LHS, RHS) + Index output_idx = rhs_space_idx * num_spaces + lhs_space_idx; + + // use atomicMax to find the maximum of the minimum distance calculated for each space pair. + atomicMax(&thrust::raw_reference_cast(*(results + output_idx)), + static_cast(std::sqrt(min_distance_squared))); } - - // determine the output offset for this pair of spaces (LHS, RHS) - Index output_idx = rhs_space_idx * num_spaces + lhs_space_idx; - - // use atomicMax to find the maximum of the minimum distance calculated for each space pair. - atomicMax(&thrust::raw_reference_cast(*(results + output_idx)), - static_cast(std::sqrt(min_distance_squared))); } } diff --git a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh index b05e71b03..0142f680e 100644 --- a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh +++ b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh @@ -23,6 +23,8 @@ #include #include +#include + #include namespace cuspatial { @@ -37,8 +39,7 @@ void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, SegmentRange segments, OutputIt merged_flag) { - for (auto pair_idx = threadIdx.x + blockIdx.x * blockDim.x; pair_idx < offsets.size() - 1; - pair_idx += gridDim.x * blockDim.x) { + for (auto pair_idx : ranger::grid_stride_range(offsets.size() - 1)) { // Zero-initialize flags for all segments in current space. for (auto i = offsets[pair_idx]; i < offsets[pair_idx + 1]; i++) { merged_flag[i] = 0; diff --git a/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh b/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh index f391e97ea..430a0bc5e 100644 --- a/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh +++ b/cpp/include/cuspatial/detail/find/find_duplicate_points.cuh @@ -22,6 +22,8 @@ #include #include +#include + #include namespace cuspatial { @@ -35,8 +37,7 @@ template void __global__ find_duplicate_points_kernel_simple(MultiPointRange multipoints, OutputIt duplicate_flags) { - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multipoints.size(); - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(multipoints.size())) { auto multipoint = multipoints[idx]; auto global_offset = multipoints.offsets_begin()[idx]; diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection_count.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_count.cuh index 0985253ad..a0297b05b 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection_count.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_count.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ #include +#include + #include namespace cuspatial { @@ -38,8 +40,7 @@ __global__ void count_intersection_and_overlaps_simple(MultiLinestringRange1 mul OutputIt2 segment_count_it) { using T = typename MultiLinestringRange1::element_t; - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings1.num_points(); - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(multilinestrings1.num_points())) { auto const part_idx = multilinestrings1.part_idx_from_point_idx(idx); if (!multilinestrings1.is_valid_segment_id(idx, part_idx)) continue; auto const geometry_idx = multilinestrings1.geometry_idx_from_part_idx(part_idx); diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh index 8e35dfdca..941efd426 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh @@ -30,6 +30,8 @@ #include #include +#include + #include #include #include @@ -395,8 +397,7 @@ void __global__ pairwise_linestring_intersection_simple(MultiLinestringRange1 mu using types_t = uint8_t; using count_t = iterator_value_type; - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings1.num_points(); - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(multilinestrings1.num_points())) { if (auto const part_idx_opt = multilinestrings1.part_idx_from_segment_idx(idx); part_idx_opt.has_value()) { auto const part_idx = part_idx_opt.value(); diff --git a/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh b/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh index cc791c9ce..48c139e1e 100644 --- a/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh +++ b/cpp/include/cuspatial/detail/kernel/pairwise_distance.cuh @@ -19,11 +19,14 @@ #include #include -#include #include +#include + #include +#include + namespace cuspatial { namespace detail { @@ -52,8 +55,7 @@ __global__ void linestring_distance(MultiLinestringRange1 multilinestrings1, { using T = typename MultiLinestringRange1::element_t; - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings1.num_points(); - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(multilinestrings1.num_points())) { auto const part_idx = multilinestrings1.part_idx_from_point_idx(idx); if (!multilinestrings1.is_valid_segment_id(idx, part_idx)) continue; auto const geometry_idx = multilinestrings1.geometry_idx_from_part_idx(part_idx); @@ -89,15 +91,14 @@ __global__ void linestring_distance(MultiLinestringRange1 multilinestrings1, * set to nullopt, no distance computation will be bypassed. */ template -void __global__ point_linestring_distance(MultiPointRange multipoints, +__global__ void point_linestring_distance(MultiPointRange multipoints, MultiLinestringRange multilinestrings, thrust::optional intersects, OutputIterator distances) { using T = typename MultiPointRange::element_t; - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multilinestrings.num_points(); - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(multilinestrings.num_points())) { // Search from the part offsets array to determine the part idx of current linestring point auto part_idx = multilinestrings.part_idx_from_point_idx(idx); // Pointer to the last point in the linestring, skip iteration. diff --git a/cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh b/cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh index f6d4f46c1..fc768ec1c 100644 --- a/cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh +++ b/cpp/include/cuspatial/detail/pairwise_multipoint_equals_count.cuh @@ -25,6 +25,8 @@ #include #include +#include + #include #include #include @@ -47,8 +49,7 @@ void __global__ pairwise_multipoint_equals_count_kernel(MultiPointRangeA lhs, { using T = typename MultiPointRangeA::point_t::value_type; - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < lhs.num_points(); - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(lhs.num_points())) { auto geometry_id = lhs.geometry_idx_from_point_idx(idx); vec_2d lhs_point = lhs.point_begin()[idx]; auto rhs_multipoint = rhs[geometry_id]; diff --git a/cpp/include/cuspatial/detail/point_linestring_nearest_points.cuh b/cpp/include/cuspatial/detail/point_linestring_nearest_points.cuh index 12464f645..c1c7bfc77 100644 --- a/cpp/include/cuspatial/detail/point_linestring_nearest_points.cuh +++ b/cpp/include/cuspatial/detail/point_linestring_nearest_points.cuh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,8 @@ #include #include +#include + #include #include @@ -72,8 +74,7 @@ pairwise_point_linestring_nearest_points_kernel(OffsetIteratorA points_geometry_ thrust::distance(points_geometry_offsets_first, points_geometry_offsets_last) - 1; auto num_linestring_points = thrust::distance(linestring_points_first, linestring_points_last); - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < num_pairs; - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(num_pairs)) { IndexType nearest_point_idx; IndexType nearest_part_idx; IndexType nearest_segment_idx; diff --git a/cpp/include/cuspatial_test/geometry_generator.cuh b/cpp/include/cuspatial_test/geometry_generator.cuh index 73b1d270e..2fd3be28c 100644 --- a/cpp/include/cuspatial_test/geometry_generator.cuh +++ b/cpp/include/cuspatial_test/geometry_generator.cuh @@ -28,6 +28,8 @@ #include #include +#include + #include #include @@ -193,8 +195,7 @@ template void __global__ generate_multipolygon_array_coordinates(MultipolygonRange multipolygons, multipolygon_generator_parameter params) { - for (auto idx = threadIdx.x + blockIdx.x * blockDim.x; idx < multipolygons.num_points(); - idx += gridDim.x * blockDim.x) { + for (auto idx : ranger::grid_stride_range(multipolygons.num_points())) { auto ring_idx = multipolygons.ring_idx_from_point_idx(idx); auto part_idx = multipolygons.part_idx_from_ring_idx(ring_idx); auto geometry_idx = multipolygons.geometry_idx_from_part_idx(part_idx); diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 8f344e534..b67b214ce 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -34,7 +34,7 @@ function(ConfigureTest CMAKE_TEST_NAME) CUDA_STANDARD 17 CUDA_STANDARD_REQUIRED ON ) - target_link_libraries(${CMAKE_TEST_NAME} GTest::gtest_main GTest::gmock_main cudf::cudftestutil cuspatial) + target_link_libraries(${CMAKE_TEST_NAME} GTest::gtest_main GTest::gmock_main ranger::ranger cudf::cudftestutil cuspatial) add_test(NAME ${CMAKE_TEST_NAME} COMMAND ${CMAKE_TEST_NAME}) install( TARGETS ${CMAKE_TEST_NAME} diff --git a/cpp/tests/operators/linestrings_test.cu b/cpp/tests/operators/linestrings_test.cu index e67810f33..7216f276a 100644 --- a/cpp/tests/operators/linestrings_test.cu +++ b/cpp/tests/operators/linestrings_test.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,8 +69,10 @@ segment __device__ order_end_points(segment const& seg) } template -void __global__ -compute_intersection(segment ab, segment cd, Point point_out, Segment segment_out) +__global__ void compute_intersection(segment ab, + segment cd, + Point point_out, + Segment segment_out) { auto [p, s] = detail::segment_intersection(ab, cd); point_out[0] = p; From feff9eb5152b52ebf592676edc805f5079f048e8 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 5 Jul 2023 23:11:16 -0700 Subject: [PATCH 53/63] cuSpatial: Build CUDA 12 packages (#1044) This PR builds `libcuspatial` and `cuspatial` conda packages using CUDA 12. Closes #925. Based on https://github.com/rapidsai/cudf/pull/12922. Authors: - Michael Wang (https://github.com/isVoid) - Bradley Dice (https://github.com/bdice) Approvers: - Bradley Dice (https://github.com/bdice) - Vyas Ramasubramani (https://github.com/vyasr) - Ray Douglass (https://github.com/raydouglass) - https://github.com/jakirkham - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1044 --- .github/workflows/build.yaml | 12 ++--- .github/workflows/pr.yaml | 20 ++++---- .github/workflows/test.yaml | 6 +-- ci/build_cpp.sh | 3 +- .../all_cuda-118_arch-x86_64.yaml | 3 +- .../all_cuda-120_arch-x86_64.yaml | 49 +++++++++++++++++++ .../recipes/cuspatial/conda_build_config.yaml | 3 ++ conda/recipes/cuspatial/meta.yaml | 19 +++++-- conda/recipes/libcuspatial/build.sh | 5 +- .../libcuspatial/conda_build_config.yaml | 3 ++ conda/recipes/libcuspatial/meta.yaml | 40 +++++++++++---- dependencies.yaml | 36 ++++++++++++-- 12 files changed, 158 insertions(+), 41 deletions(-) create mode 100644 conda/environments/all_cuda-120_arch-x86_64.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a872e289f..cf372ce5b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ concurrency: jobs: cpp-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@cuda-120 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -37,7 +37,7 @@ jobs: python-build: needs: [cpp-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@cuda-120 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -46,7 +46,7 @@ jobs: upload-conda: needs: [cpp-build, python-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@cuda-120 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -56,7 +56,7 @@ jobs: if: github.ref_type == 'branch' needs: python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@cuda-120 with: arch: "amd64" branch: ${{ inputs.branch }} @@ -68,7 +68,7 @@ jobs: sha: ${{ inputs.sha }} wheel-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@cuda-120 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -80,7 +80,7 @@ jobs: wheel-publish: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@cuda-120 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 53cc04bd2..718f6ae27 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -22,40 +22,40 @@ jobs: - wheel-build - wheel-tests secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@cuda-120 checks: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@cuda-120 with: enable_check_generated_files: false conda-cpp-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@cuda-120 with: build_type: pull-request conda-cpp-tests: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@cuda-120 with: build_type: pull-request conda-python-build: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@cuda-120 with: build_type: pull-request conda-python-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@cuda-120 with: build_type: pull-request conda-notebook-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@cuda-120 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -65,7 +65,7 @@ jobs: docs-build: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@cuda-120 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -75,7 +75,7 @@ jobs: wheel-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@cuda-120 with: build_type: pull-request package-dir: python/cuspatial @@ -84,7 +84,7 @@ jobs: wheel-tests: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@cuda-120 with: build_type: pull-request package-name: cuspatial diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 00a4c0446..54100318f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,7 +16,7 @@ on: jobs: conda-cpp-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@cuda-120 with: build_type: nightly branch: ${{ inputs.branch }} @@ -24,7 +24,7 @@ jobs: sha: ${{ inputs.sha }} conda-python-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@cuda-120 with: build_type: nightly branch: ${{ inputs.branch }} @@ -32,7 +32,7 @@ jobs: sha: ${{ inputs.sha }} wheel-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@cuda-120 with: build_type: nightly branch: ${{ inputs.branch }} diff --git a/ci/build_cpp.sh b/ci/build_cpp.sh index ea05049d7..529a8f450 100755 --- a/ci/build_cpp.sh +++ b/ci/build_cpp.sh @@ -11,6 +11,7 @@ rapids-print-env rapids-logger "Begin cpp build" -rapids-mamba-retry mambabuild conda/recipes/libcuspatial +rapids-mamba-retry mambabuild \ + conda/recipes/libcuspatial rapids-upload-conda-to-s3 cpp diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 0e1373e0d..a6a12dc2e 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -8,7 +8,8 @@ channels: dependencies: - c-compiler - cmake>=3.26.4 -- cudatoolkit=11.8 +- cuda-version=11.8 +- cudatoolkit - cudf==23.8.* - cuml==23.8.* - cxx-compiler diff --git a/conda/environments/all_cuda-120_arch-x86_64.yaml b/conda/environments/all_cuda-120_arch-x86_64.yaml new file mode 100644 index 000000000..b385a9e14 --- /dev/null +++ b/conda/environments/all_cuda-120_arch-x86_64.yaml @@ -0,0 +1,49 @@ +# This file is generated by `rapids-dependency-file-generator`. +# To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. +channels: +- rapidsai +- rapidsai-nightly +- conda-forge +- nvidia +dependencies: +- c-compiler +- cmake>=3.26.4 +- cuda-cudart-dev +- cuda-nvcc +- cuda-nvrtc-dev +- cuda-version=12.0 +- cudf==23.8.* +- cuml==23.8.* +- cxx-compiler +- cython>=0.29,<0.30 +- doxygen +- gcc_linux-64=11.* +- geopandas>=0.11.0 +- gmock>=1.13.0 +- gtest>=1.13.0 +- ipython +- ipywidgets +- libcudf==23.8.* +- librmm==23.8.* +- myst-parser +- nbsphinx +- ninja +- notebook +- numpydoc +- pre-commit +- proj +- pydata-sphinx-theme +- pydeck +- pytest +- pytest-cov +- pytest-xdist +- python>=3.9,<3.11 +- rmm==23.8.* +- scikit-build>=0.13.1 +- scikit-image +- setuptools +- shapely +- sphinx<6 +- sqlite +- sysroot_linux-64==2.17 +name: all_cuda-120_arch-x86_64 diff --git a/conda/recipes/cuspatial/conda_build_config.yaml b/conda/recipes/cuspatial/conda_build_config.yaml index b4b06a9b6..e28b98da7 100644 --- a/conda/recipes/cuspatial/conda_build_config.yaml +++ b/conda/recipes/cuspatial/conda_build_config.yaml @@ -5,6 +5,9 @@ cxx_compiler_version: - 11 cuda_compiler: + - cuda-nvcc + +cuda11_compiler: - nvcc sysroot_version: diff --git a/conda/recipes/cuspatial/meta.yaml b/conda/recipes/cuspatial/meta.yaml index 88b82e665..ab4066938 100644 --- a/conda/recipes/cuspatial/meta.yaml +++ b/conda/recipes/cuspatial/meta.yaml @@ -2,8 +2,9 @@ {% set version = environ.get('GIT_DESCRIBE_TAG', '0.0.0.dev').lstrip('v') %} {% set minor_version = version.split('.')[0] + '.' + version.split('.')[1] %} -{% set py_version = environ['CONDA_PY'] %} {% set cuda_version = '.'.join(environ['RAPIDS_CUDA_VERSION'].split('.')[:2]) %} +{% set cuda_major = cuda_version.split('.')[0] %} +{% set py_version = environ['CONDA_PY'] %} {% set date_string = environ['RAPIDS_DATE_STRING'] %} package: @@ -33,16 +34,24 @@ build: - SCCACHE_S3_USE_SSL - SCCACHE_S3_NO_CREDENTIALS ignore_run_exports_from: - - {{ compiler('cuda') }} + {% if cuda_major == "11" %} + - {{ compiler('cuda11') }} + {% endif %} requirements: build: - {{ compiler('c') }} - {{ compiler('cxx') }} - - {{ compiler('cuda') }} {{ cuda_version }} + {% if cuda_major == "11" %} + - {{ compiler('cuda11') }} ={{ cuda_version }} + {% else %} + - {{ compiler('cuda') }} + {% endif %} + - cuda-version ={{ cuda_version }} - ninja - sysroot_{{ target_platform }} {{ sysroot_version }} host: + - cuda-version ={{ cuda_version }} - cmake {{ cmake_version }} - cudf ={{ minor_version }} - cython >=0.29,<0.30 @@ -52,6 +61,10 @@ requirements: - scikit-build >=0.13.1 - setuptools run: + {% if cuda_major == "11" %} + - cudatoolkit + {% endif %} + - {{ pin_compatible('cuda-version', max_pin='x', min_pin='x') }} - cudf ={{ minor_version }} - geopandas >=0.11.0 - python diff --git a/conda/recipes/libcuspatial/build.sh b/conda/recipes/libcuspatial/build.sh index 4d3547d16..e942f6094 100644 --- a/conda/recipes/libcuspatial/build.sh +++ b/conda/recipes/libcuspatial/build.sh @@ -1,4 +1,5 @@ -# Copyright (c) 2018-2022, NVIDIA CORPORATION. +# Copyright (c) 2018-2023, NVIDIA CORPORATION. # build cuspatial with verbose output -./build.sh -v libcuspatial tests benchmarks --allgpuarch -n +./build.sh -v libcuspatial tests benchmarks --allgpuarch -n \ + --cmake-args=\"-DNVBench_ENABLE_CUPTI=OFF\" diff --git a/conda/recipes/libcuspatial/conda_build_config.yaml b/conda/recipes/libcuspatial/conda_build_config.yaml index f3da4ec36..37d54ccc2 100644 --- a/conda/recipes/libcuspatial/conda_build_config.yaml +++ b/conda/recipes/libcuspatial/conda_build_config.yaml @@ -5,6 +5,9 @@ cxx_compiler_version: - 11 cuda_compiler: + - cuda-nvcc + +cuda11_compiler: - nvcc cmake_version: diff --git a/conda/recipes/libcuspatial/meta.yaml b/conda/recipes/libcuspatial/meta.yaml index 7ec4df829..9833b5d92 100644 --- a/conda/recipes/libcuspatial/meta.yaml +++ b/conda/recipes/libcuspatial/meta.yaml @@ -4,7 +4,6 @@ {% set minor_version = version.split('.')[0] + '.' + version.split('.')[1] %} {% set cuda_version = '.'.join(environ['RAPIDS_CUDA_VERSION'].split('.')[:2]) %} {% set cuda_major = cuda_version.split('.')[0] %} -{% set cuda_spec = ">=" + cuda_major ~ ",<" + (cuda_major | int + 1) ~ ".0a0" %} # i.e. >=11,<12.0a0 {% set date_string = environ['RAPIDS_DATE_STRING'] %} package: @@ -34,13 +33,18 @@ build: requirements: build: - {{ compiler('c') }} - - {{ compiler('cuda') }} {{ cuda_version }} - {{ compiler('cxx') }} + {% if cuda_major == "11" %} + - {{ compiler('cuda11') }} ={{ cuda_version }} + {% else %} + - {{ compiler('cuda') }} + {% endif %} + - cuda-version ={{ cuda_version }} - cmake {{ cmake_version }} - ninja - sysroot_{{ target_platform }} {{ sysroot_version }} host: - - cudatoolkit ={{ cuda_version }} + - cuda-version ={{ cuda_version }} - doxygen - gmock {{ gtest_version }} - gtest {{ gtest_version }} @@ -58,14 +62,21 @@ outputs: string: cuda{{ cuda_major }}_{{ date_string }}_{{ GIT_DESCRIBE_HASH }}_{{ GIT_DESCRIBE_NUMBER }} run_exports: - {{ pin_subpackage("libcuspatial", max_pin="x.x") }} - ignore_run_exports_from: - - {{ compiler('cuda') }} requirements: build: - cmake {{ cmake_version }} - - ninja + host: + - cuda-version ={{ cuda_version }} + {% if cuda_major == "11" %} + - cudatoolkit + {% else %} + - cuda-cudart-dev + {% endif %} run: - - cudatoolkit {{ cuda_spec }} + - {{ pin_compatible('cuda-version', max_pin='x', min_pin='x') }} + {% if cuda_major == "11" %} + - cudatoolkit + {% endif %} - libcudf ={{ minor_version }} - librmm ={{ minor_version }} - sqlite @@ -79,19 +90,28 @@ outputs: license_family: Apache license_file: LICENSE summary: libcuspatial library + - name: libcuspatial-tests version: {{ version }} script: install_libcuspatial_tests.sh build: number: {{ GIT_DESCRIBE_NUMBER }} string: cuda{{ cuda_major }}_{{ date_string }}_{{ GIT_DESCRIBE_HASH }}_{{ GIT_DESCRIBE_NUMBER }} - ignore_run_exports_from: - - {{ compiler('cuda') }} requirements: build: - cmake {{ cmake_version }} + host: + - cuda-version ={{ cuda_version }} + {% if cuda_major == "11" %} + - cudatoolkit + {% else %} + - cuda-cudart-dev + {% endif %} run: - {{ pin_subpackage('libcuspatial', exact=True) }} - - cudatoolkit {{ cuda_spec }} + {% if cuda_major == "11" %} + - cudatoolkit + {% endif %} + - {{ pin_compatible('cuda-version', max_pin='x', min_pin='x') }} - gmock {{ gtest_version }} - gtest {{ gtest_version }} diff --git a/dependencies.yaml b/dependencies.yaml index 61224cf96..66f19f6a1 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -3,7 +3,7 @@ files: all: output: conda matrix: - cuda: ["11.8"] + cuda: ["11.8", "12.0"] arch: [x86_64] includes: - build_cpp @@ -112,6 +112,11 @@ dependencies: cuda: "11.8" packages: - nvcc_linux-aarch64=11.8 + - matrix: + cuda: "12.0" + packages: + - cuda-version=12.0 + - cuda-nvcc build_python: common: - output_types: [conda, requirements, pyproject] @@ -143,6 +148,10 @@ dependencies: - *sysroot_aarch64 - output_types: [requirements, pyproject] matrices: + - matrix: {cuda: "12.0"} + packages: + - cudf-cu12==23.8.* + - rmm-cu12==23.8.* - matrix: {cuda: "11.8"} packages: &build_python_packages_cu11 - &cudf_cu11 cudf-cu11==23.8.* @@ -161,22 +170,32 @@ dependencies: specific: - output_types: conda matrices: + - matrix: + cuda: "12.0" + packages: + - cuda-version=12.0 + - cuda-cudart-dev + - cuda-nvrtc-dev - matrix: cuda: "11.8" packages: - - cudatoolkit=11.8 + - cuda-version=11.8 + - cudatoolkit - matrix: cuda: "11.5" packages: - - cudatoolkit=11.5 + - cuda-version=11.5 + - cudatoolkit - matrix: cuda: "11.4" packages: - - cudatoolkit=11.4 + - cuda-version=11.4 + - cudatoolkit - matrix: cuda: "11.2" packages: - - cudatoolkit=11.2 + - cuda-version=11.2 + - cudatoolkit develop: common: - output_types: [conda, requirements] @@ -212,6 +231,9 @@ dependencies: - output_types: [requirements, pyproject] matrices: - {matrix: null, packages: [*cuml_conda]} + - matrix: {cuda: "12.0"} + packages: + - cuml-cu12==23.8.* - matrix: {cuda: "11.8"} packages: ¬ebooks_packages_cu11 - &cuml_cu11 cuml-cu11==23.8.* @@ -250,6 +272,10 @@ dependencies: specific: - output_types: [requirements, pyproject] matrices: + - matrix: {cuda: "12.0"} + packages: + - cudf-cu12==23.8.* + - rmm-cu12==23.8.* - matrix: {cuda: "11.8"} packages: &run_python_packages_cu11 - cudf-cu11==23.8.* From 0ae38c7f7e7f6f57483ee13119c3655a0d7b129c Mon Sep 17 00:00:00 2001 From: jakirkham Date: Fri, 7 Jul 2023 13:13:41 -0700 Subject: [PATCH 54/63] Add CUDA major to `cuspatial`'s `build/string` (#1211) Authors: - https://github.com/jakirkham Approvers: - H. Thomson Comer (https://github.com/thomcom) - Ray Douglass (https://github.com/raydouglass) - Ajay Thorve (https://github.com/AjayThorve) URL: https://github.com/rapidsai/cuspatial/pull/1211 --- conda/recipes/cuspatial/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda/recipes/cuspatial/meta.yaml b/conda/recipes/cuspatial/meta.yaml index ab4066938..96f02de87 100644 --- a/conda/recipes/cuspatial/meta.yaml +++ b/conda/recipes/cuspatial/meta.yaml @@ -16,7 +16,7 @@ source: build: number: {{ GIT_DESCRIBE_NUMBER }} - string: py{{ py_version }}_{{ date_string }}_{{ GIT_DESCRIBE_HASH }}_{{ GIT_DESCRIBE_NUMBER }} + string: cuda{{ cuda_major }}_py{{ py_version }}_{{ date_string }}_{{ GIT_DESCRIBE_HASH }}_{{ GIT_DESCRIBE_NUMBER }} script_env: - AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY From 29fb208172d3d67af737f74583dc8c67aa8eeb88 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 17 Jul 2023 14:57:41 +0800 Subject: [PATCH 55/63] Add streams to allocate_like call (#1218) rapidsai/cudf#13629 added stream argument to all copying APIs. This fix makes sure cuspatial usage is compliant. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) URL: https://github.com/rapidsai/cuspatial/pull/1218 --- cpp/src/distance/haversine.cu | 2 +- cpp/src/trajectory/derive_trajectories.cu | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/src/distance/haversine.cu b/cpp/src/distance/haversine.cu index 45c736c2f..3c4e631da 100644 --- a/cpp/src/distance/haversine.cu +++ b/cpp/src/distance/haversine.cu @@ -54,7 +54,7 @@ struct haversine_functor { if (a_lon.is_empty()) { return cudf::empty_like(a_lon); } auto mask_policy = cudf::mask_allocation_policy::NEVER; - auto result = cudf::allocate_like(a_lon, a_lon.size(), mask_policy, mr); + auto result = cudf::allocate_like(a_lon, a_lon.size(), mask_policy, stream, mr); auto lonlat_a = cuspatial::make_vec_2d_iterator(a_lon.begin(), a_lat.begin()); auto lonlat_b = cuspatial::make_vec_2d_iterator(b_lon.begin(), b_lat.begin()); diff --git a/cpp/src/trajectory/derive_trajectories.cu b/cpp/src/trajectory/derive_trajectories.cu index 0a5db39ed..8356369ef 100644 --- a/cpp/src/trajectory/derive_trajectories.cu +++ b/cpp/src/trajectory/derive_trajectories.cu @@ -47,10 +47,10 @@ struct derive_trajectories_dispatch { { auto cols = std::vector>{}; cols.reserve(4); - cols.push_back(cudf::allocate_like(object_id, cudf::mask_allocation_policy::NEVER, mr)); - cols.push_back(cudf::allocate_like(x, cudf::mask_allocation_policy::NEVER, mr)); - cols.push_back(cudf::allocate_like(y, cudf::mask_allocation_policy::NEVER, mr)); - cols.push_back(cudf::allocate_like(timestamp, cudf::mask_allocation_policy::NEVER, mr)); + cols.push_back(cudf::allocate_like(object_id, cudf::mask_allocation_policy::NEVER, stream, mr)); + cols.push_back(cudf::allocate_like(x, cudf::mask_allocation_policy::NEVER, stream, mr)); + cols.push_back(cudf::allocate_like(y, cudf::mask_allocation_policy::NEVER, stream, mr)); + cols.push_back(cudf::allocate_like(timestamp, cudf::mask_allocation_policy::NEVER, stream, mr)); auto points_begin = thrust::make_zip_iterator(x.begin(), y.begin()); auto points_out_begin = thrust::make_zip_iterator(cols[1]->mutable_view().begin(), From 1e0e357dbe8097b0afb0a17292f938e377df63ff Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 18 Jul 2023 23:20:24 +0800 Subject: [PATCH 56/63] Update GeoDataFrame to Use the Structured GatherMap Class (#1219) As title, addresses upstream cudf change rapidsai/cudf#13534. Fixes #1222 Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Lawrence Mitchell (https://github.com/wence-) - Mark Harris (https://github.com/harrism) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1219 --- .../cuspatial/cuspatial/core/geodataframe.py | 22 +++++++++---------- python/cuspatial/cuspatial/core/geoseries.py | 9 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/python/cuspatial/cuspatial/core/geodataframe.py b/python/cuspatial/cuspatial/core/geodataframe.py index 1791bc0c5..3e58a5d60 100644 --- a/python/cuspatial/cuspatial/core/geodataframe.py +++ b/python/cuspatial/cuspatial/core/geodataframe.py @@ -6,6 +6,7 @@ from geopandas.geoseries import is_geometry_type as gp_is_geometry_type import cudf +from cudf.core.copy_types import BooleanMask, GatherMap from cuspatial.core._column.geocolumn import GeoColumn, GeoMeta from cuspatial.core.geoseries import GeoSeries @@ -181,31 +182,30 @@ def _slice(self: T, arg: slice) -> T: ) return self.__class__(result) - def _apply_boolean_mask(self, mask) -> T: + def _apply_boolean_mask(self, mask: BooleanMask, keep_index=True) -> T: geo_columns, data_columns = self._split_out_geometry_columns() - data = data_columns._apply_boolean_mask(mask) + data = data_columns._apply_boolean_mask(mask, keep_index) geo = GeoDataFrame( - {name: geo_columns[name][mask] for name in geo_columns} + {name: geo_columns[name][mask.column] for name in geo_columns} ) res = self.__class__._from_data(self._recombine_columns(geo, data)) - res.index = data.index + if keep_index: + res.index = data.index return res - def _gather( - self, gather_map, keep_index=True, nullify=False, check_bounds=True - ): + def _gather(self, gather_map: GatherMap, keep_index=True): geo_data, cudf_data = self._split_out_geometry_columns() # gather cudf columns df = cudf.DataFrame._from_data(data=cudf_data, index=self.index) - cudf_gathered = cudf.DataFrame._gather( - df, gather_map, keep_index, nullify, check_bounds - ) + + cudf_gathered = df._gather(gather_map, keep_index=keep_index) # gather GeoColumns gathered = { - geo: geo_data[geo].iloc[gather_map] for geo in geo_data.keys() + geo: geo_data[geo].iloc[gather_map.column] + for geo in geo_data.keys() } geo_gathered = GeoDataFrame(gathered) diff --git a/python/cuspatial/cuspatial/core/geoseries.py b/python/cuspatial/cuspatial/core/geoseries.py index 2a66ccec3..87b80ad5e 100644 --- a/python/cuspatial/cuspatial/core/geoseries.py +++ b/python/cuspatial/cuspatial/core/geoseries.py @@ -22,6 +22,7 @@ import cudf from cudf._typing import ColumnLike from cudf.core.column.column import as_column +from cudf.core.copy_types import GatherMap import cuspatial.io.pygeoarrow as pygeoarrow from cuspatial.core._column.geocolumn import ColumnType, GeoColumn @@ -922,10 +923,10 @@ def align(self, other): aligned_right, ) - def _gather( - self, gather_map, keep_index=True, nullify=False, check_bounds=True - ): - return self.iloc[gather_map] + def _gather(self, gather_map: GatherMap, keep_index=True): + # TODO: This could use the information to avoid reprocessing + # in iloc + return self.iloc[gather_map.column] # def reset_index(self, drop=False, inplace=False, name=None): def reset_index( From 174ca0e0502cfa6cc41f22fb0c5de57696a5d30b Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Tue, 18 Jul 2023 14:34:58 -0500 Subject: [PATCH 57/63] Revert CUDA 12.0 CI workflows to branch-23.08. (#1223) This PR reverts changes to the branch of `shared-action-workflows` used for CUDA 12 testing. Now that https://github.com/rapidsai/shared-action-workflows/pull/101 is merged, we can revert this. Authors: - Bradley Dice (https://github.com/bdice) Approvers: - Ray Douglass (https://github.com/raydouglass) URL: https://github.com/rapidsai/cuspatial/pull/1223 --- .github/workflows/build.yaml | 12 ++++++------ .github/workflows/pr.yaml | 20 ++++++++++---------- .github/workflows/test.yaml | 6 +++--- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index cf372ce5b..a872e289f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ concurrency: jobs: cpp-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -37,7 +37,7 @@ jobs: python-build: needs: [cpp-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -46,7 +46,7 @@ jobs: upload-conda: needs: [cpp-build, python-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -56,7 +56,7 @@ jobs: if: github.ref_type == 'branch' needs: python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 with: arch: "amd64" branch: ${{ inputs.branch }} @@ -68,7 +68,7 @@ jobs: sha: ${{ inputs.sha }} wheel-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -80,7 +80,7 @@ jobs: wheel-publish: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 718f6ae27..53cc04bd2 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -22,40 +22,40 @@ jobs: - wheel-build - wheel-tests secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.08 checks: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@branch-23.08 with: enable_check_generated_files: false conda-cpp-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 with: build_type: pull-request conda-cpp-tests: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 with: build_type: pull-request conda-python-build: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 with: build_type: pull-request conda-python-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 with: build_type: pull-request conda-notebook-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -65,7 +65,7 @@ jobs: docs-build: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -75,7 +75,7 @@ jobs: wheel-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 with: build_type: pull-request package-dir: python/cuspatial @@ -84,7 +84,7 @@ jobs: wheel-tests: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 with: build_type: pull-request package-name: cuspatial diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 54100318f..00a4c0446 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,7 +16,7 @@ on: jobs: conda-cpp-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 with: build_type: nightly branch: ${{ inputs.branch }} @@ -24,7 +24,7 @@ jobs: sha: ${{ inputs.sha }} conda-python-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 with: build_type: nightly branch: ${{ inputs.branch }} @@ -32,7 +32,7 @@ jobs: sha: ${{ inputs.sha }} wheel-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@cuda-120 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 with: build_type: nightly branch: ${{ inputs.branch }} From b0657dda3899175ee100e1ecde5b4e9c1aa8c77d Mon Sep 17 00:00:00 2001 From: Mark Harris <783069+harrism@users.noreply.github.com> Date: Thu, 20 Jul 2023 12:12:57 +1000 Subject: [PATCH 58/63] WGS84 <--> UTM projection header-only API (#1191) Implements WGS to UTM projection (either direction) in CUDA C++. This is based on the code from PROJ, and that library is used for comparison in the tests. To reviewers, I would start by looking over the test: wgs_to_utm_test.cu. This uses `projection_factories.hpp`, so review that next, then look at `projection.cuh` and `projection_parameters.cuh`. The projection pipeline is applied using a `thrust::transform()` where the operator is a `pipeline` made up of a sequence of `operation`s (operation.cuh). A pipeline can be applied forward or inverse. The operations for UTM projection are all in include/cuproj/operation. Note that the dispatch of operations is a little clunky (switch statement in a device function). This is due to limitations of creating arrays of objects on the host for virtual dispatch on the device. This bears more experimentation in the future to come up with a better approach, but this works fine for now. ~TODO:~ - [x] Design a way to build pipelines of device operations dynamically and run on GPU - [x] Documentation - [x] More testing Benchmark and Python API are left to follow-up PRs. Authors: - Mark Harris (https://github.com/harrism) Approvers: - Michael Wang (https://github.com/isVoid) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1191 --- cpp/cuproj/README.md | 7 + cpp/cuproj/include/cuproj/constants.hpp | 38 ++ cpp/cuproj/include/cuproj/detail/pipeline.cuh | 120 ++++ .../include/cuproj/detail/wrap_to_pi.cuh | 49 ++ cpp/cuproj/include/cuproj/ellipsoid.hpp | 71 +++ cpp/cuproj/include/cuproj/error.hpp | 24 +- .../include/cuproj/operation/axis_swap.cuh | 43 ++ .../operation/clamp_angular_coordinates.cuh | 125 +++++ .../cuproj/operation/degrees_to_radians.cuh | 74 +++ .../offset_scale_cartesian_coordinates.cuh | 96 ++++ .../include/cuproj/operation/operation.cuh | 86 +++ .../cuproj/operation/transverse_mercator.cuh | 522 ++++++++++++++++++ cpp/cuproj/include/cuproj/projection.cuh | 118 ++++ .../include/cuproj/projection_factories.hpp | 141 +++++ .../include/cuproj/projection_parameters.hpp | 72 +++ .../cuproj_test/coordinate_generator.cuh | 63 +++ cpp/cuproj/tests/CMakeLists.txt | 7 +- cpp/cuproj/tests/wgs_to_utm_test.cu | 260 +++++++++ .../cuspatial_test/vector_equality.hpp | 14 +- 19 files changed, 1911 insertions(+), 19 deletions(-) create mode 100644 cpp/cuproj/README.md create mode 100644 cpp/cuproj/include/cuproj/constants.hpp create mode 100644 cpp/cuproj/include/cuproj/detail/pipeline.cuh create mode 100644 cpp/cuproj/include/cuproj/detail/wrap_to_pi.cuh create mode 100644 cpp/cuproj/include/cuproj/ellipsoid.hpp create mode 100644 cpp/cuproj/include/cuproj/operation/axis_swap.cuh create mode 100644 cpp/cuproj/include/cuproj/operation/clamp_angular_coordinates.cuh create mode 100644 cpp/cuproj/include/cuproj/operation/degrees_to_radians.cuh create mode 100644 cpp/cuproj/include/cuproj/operation/offset_scale_cartesian_coordinates.cuh create mode 100644 cpp/cuproj/include/cuproj/operation/operation.cuh create mode 100644 cpp/cuproj/include/cuproj/operation/transverse_mercator.cuh create mode 100644 cpp/cuproj/include/cuproj/projection.cuh create mode 100644 cpp/cuproj/include/cuproj/projection_factories.hpp create mode 100644 cpp/cuproj/include/cuproj/projection_parameters.hpp create mode 100644 cpp/cuproj/include/cuproj_test/coordinate_generator.cuh create mode 100644 cpp/cuproj/tests/wgs_to_utm_test.cu diff --git a/cpp/cuproj/README.md b/cpp/cuproj/README.md new file mode 100644 index 000000000..8b14b45a0 --- /dev/null +++ b/cpp/cuproj/README.md @@ -0,0 +1,7 @@ +#
     cuProj: GPU-Accelerated Coordinate Projection
    + +## Overview + +cuProj is a GPU-accelerated generic coordinate transformation library that transforms geospatial +coordinates from one coordinate reference system (CRS) to another. cuProj is inspired by +[PROJ](https://proj.org/en/9.2/), and aims to be compatible with it. diff --git a/cpp/cuproj/include/cuproj/constants.hpp b/cpp/cuproj/include/cuproj/constants.hpp new file mode 100644 index 000000000..7a681df96 --- /dev/null +++ b/cpp/cuproj/include/cuproj/constants.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +namespace cuproj { + +// TODO, use C++20 numerical constants when we can + +template +static constexpr T M_TWOPI = T{2.0} * M_PI; // 6.283185307179586476925286766559005l; + +// Epsilon in radians used for hysteresis in wrapping angles to e.g. [-pi,pi] +template +static constexpr T EPSILON_RADIANS = T{1e-12}; + +template +constexpr T DEG_TO_RAD = T{0.017453292519943295769236907684886}; + +template +constexpr T RAD_TO_DEG = T{57.295779513082320876798154814105}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/detail/pipeline.cuh b/cpp/cuproj/include/cuproj/detail/pipeline.cuh new file mode 100644 index 000000000..cc019bfba --- /dev/null +++ b/cpp/cuproj/include/cuproj/detail/pipeline.cuh @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace cuproj { + +namespace detail { + +/** + * @internal + * @brief A pipeline of projection operations applied in order to a coordinate + * + * @tparam Coordinate the coordinate type + * @tparam dir The direction of the pipeline, FORWARD or INVERSE + * @tparam T the coordinate value type + */ +template +class pipeline { + public: + using iterator_type = std::conditional_t>; + + /** + * @brief Construct a new pipeline object with the given operations and parameters + * + * @param params The projection parameters + * @param ops The operations to apply + * @param num_stages The number of operations to apply + */ + pipeline(projection_parameters const& params, + operation_type const* ops, + std::size_t num_stages) + : params_(params), d_ops(ops), num_stages(num_stages) + { + if constexpr (dir == direction::FORWARD) { + first_ = d_ops; + } else { + first_ = std::reverse_iterator(d_ops + num_stages); + } + } + + /** + * @brief Apply the pipeline to the given coordinate + * + * @param c The coordinate to transform + * @return The transformed coordinate + */ + __device__ Coordinate operator()(Coordinate const& c) const + { + Coordinate c_out{c}; + thrust::for_each_n(thrust::seq, first_, num_stages, [&](auto const& op) { + switch (op) { + case operation_type::AXIS_SWAP: { + auto op = axis_swap{}; + c_out = op(c_out, dir); + break; + } + case operation_type::DEGREES_TO_RADIANS: { + auto op = degrees_to_radians{}; + c_out = op(c_out, dir); + break; + } + case operation_type::CLAMP_ANGULAR_COORDINATES: { + auto op = clamp_angular_coordinates{params_}; + c_out = op(c_out, dir); + break; + } + case operation_type::OFFSET_SCALE_CARTESIAN_COORDINATES: { + auto op = offset_scale_cartesian_coordinates{params_}; + c_out = op(c_out, dir); + break; + } + case operation_type::TRANSVERSE_MERCATOR: { + auto op = transverse_mercator{params_}; + c_out = op(c_out, dir); + break; + } + } + }); + return c_out; + } + + private: + projection_parameters params_; + operation_type const* d_ops; + iterator_type first_; + std::size_t num_stages; +}; + +} // namespace detail + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/detail/wrap_to_pi.cuh b/cpp/cuproj/include/cuproj/detail/wrap_to_pi.cuh new file mode 100644 index 000000000..8ef8c2805 --- /dev/null +++ b/cpp/cuproj/include/cuproj/detail/wrap_to_pi.cuh @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +namespace cuproj { + +namespace detail { + +/** + * @brief Wrap/normalize an angle in radians to the -pi:pi range. + * + * @tparam T data type + * @param longitude The angle to normalize + * @return The normalized angle + */ +template +__host__ __device__ T wrap_to_pi(T angle) +{ + // Let angle slightly overshoot, to avoid spurious sign switching of longitudes at the date line + if (fabs(angle) < M_PI + EPSILON_RADIANS) return angle; + + // adjust to 0..2pi range + angle += M_PI; + + // remove integral # of 'revolutions' + angle -= M_TWOPI * floor(angle / M_TWOPI); + + // adjust back to -pi..pi range + return angle - M_PI; +} + +} // namespace detail +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/ellipsoid.hpp b/cpp/cuproj/include/cuproj/ellipsoid.hpp new file mode 100644 index 000000000..dbe2dfbe9 --- /dev/null +++ b/cpp/cuproj/include/cuproj/ellipsoid.hpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include + +namespace cuproj { + +/** + * @brief Ellipsoid parameters + * + * @tparam T Floating point type + */ +template +struct ellipsoid { + ellipsoid() = default; + + /** + * @brief Construct an ellipsoid from semi-major axis and inverse flattening + * + * @param a Semi-major axis + * @param inverse_flattening Inverse flattening (a / (a - b), where b is the semi-minor axis) + */ + constexpr ellipsoid(T a, T inverse_flattening) : a(a) + { + assert(inverse_flattening != 0.0); + b = a * (1. - 1. / inverse_flattening); + f = 1.0 / inverse_flattening; + es = 2 * f - f * f; + e = sqrt(es); + alpha = asin(e); + n = pow(tan(alpha / 2), 2); + } + + T a{}; // semi-major axis + T b{}; // semi-minor axis + T e{}; // first eccentricity + T es{}; // first eccentricity squared + T alpha{}; // angular eccentricity + T f{}; // flattening + T n{}; // third flattening +}; + +/** + * @brief Create the WGS84 ellipsoid + * + * @tparam T Floating point type + * @return The WGS84 ellipsoid + */ +template +constexpr ellipsoid make_ellipsoid_wgs84() +{ + return ellipsoid{T{6378137.0}, T{298.257223563}}; +} + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/error.hpp b/cpp/cuproj/include/cuproj/error.hpp index 907804a34..2e738a0c7 100644 --- a/cpp/cuproj/include/cuproj/error.hpp +++ b/cpp/cuproj/include/cuproj/error.hpp @@ -30,13 +30,13 @@ namespace cuproj { * @{ */ -/**---------------------------------------------------------------------------* +/** * @brief Exception thrown when logical precondition is violated. * * This exception should not be thrown directly and is instead thrown by the * CUPROJ_EXPECTS macro. * - *---------------------------------------------------------------------------**/ + */ struct logic_error : public std::logic_error { logic_error(char const* const message) : std::logic_error(message) {} logic_error(std::string const& message) : std::logic_error(message) {} @@ -58,7 +58,7 @@ struct cuda_error : public std::runtime_error { #define CUPROJ_STRINGIFY_DETAIL(x) #x #define CUPROJ_STRINGIFY(x) CUPROJ_STRINGIFY_DETAIL(x) -/**---------------------------------------------------------------------------* +/** * @brief Macro for checking (pre-)conditions that throws an exception when * a condition is violated. * @@ -72,13 +72,13 @@ struct cuda_error : public std::runtime_error { * @param[in] reason String literal description of the reason that cond is * expected to be true * @throw cuproj::logic_error if the condition evaluates to false. - *---------------------------------------------------------------------------**/ -#define CUPROJ_EXPECTS(cond, reason) \ - (!!(cond)) ? static_cast(0) \ - : throw cuspatial::logic_error("cuProj failure at: " __FILE__ \ - ":" CUPROJ_STRINGIFY(__LINE__) ": " reason) + */ +#define CUPROJ_EXPECTS(cond, reason) \ + (!!(cond)) ? static_cast(0) \ + : throw cuproj::logic_error("cuProj failure at: " __FILE__ \ + ":" CUPROJ_STRINGIFY(__LINE__) ": " reason) -/**---------------------------------------------------------------------------* +/** * @brief Macro for checking (pre-)conditions that throws an exception when * a condition is violated. * @@ -97,14 +97,14 @@ struct cuda_error : public std::runtime_error { * @throw cuproj::logic_error if the condition evaluates to false. * (if on device) * program terminates and assertion error message is printed to stderr. - *---------------------------------------------------------------------------**/ + */ #ifndef __CUDA_ARCH__ #define CUPROJ_HOST_DEVICE_EXPECTS(cond, reason) CUPROJ_EXPECTS(cond, reason) #else #define CUPROJ_HOST_DEVICE_EXPECTS(cond, reason) cuproj_assert(cond&& reason) #endif -/**---------------------------------------------------------------------------* +/** * @brief Indicates that an erroneous code path has been taken. * * In host code, throws a `cuproj::logic_error`. @@ -116,7 +116,7 @@ struct cuda_error : public std::runtime_error { * ``` * * @param[in] reason String literal description of the reason - *---------------------------------------------------------------------------**/ + */ #define CUPROJ_FAIL(reason) \ throw cuproj::logic_error("cuProj failure at: " __FILE__ ":" CUPROJ_STRINGIFY( \ __LINE__) ":" \ diff --git a/cpp/cuproj/include/cuproj/operation/axis_swap.cuh b/cpp/cuproj/include/cuproj/operation/axis_swap.cuh new file mode 100644 index 000000000..d165a88c4 --- /dev/null +++ b/cpp/cuproj/include/cuproj/operation/axis_swap.cuh @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +namespace cuproj { + +/** + * @brief Axis swap operation: swap x and y coordinates + * + * @tparam Coordinate the coordinate type + */ +template +struct axis_swap : operation { + /** + * @brief Swap x and y coordinates + * + * @param coord the coordinate to swap + * @param dir (unused) the direction of the operation + * @return the swapped coordinate + */ + __host__ __device__ Coordinate operator()(Coordinate const& coord, direction) const + { + return Coordinate{coord.y, coord.x}; + } +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/operation/clamp_angular_coordinates.cuh b/cpp/cuproj/include/cuproj/operation/clamp_angular_coordinates.cuh new file mode 100644 index 000000000..44d7a8a2d --- /dev/null +++ b/cpp/cuproj/include/cuproj/operation/clamp_angular_coordinates.cuh @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include + +#include + +#include + +namespace cuproj { + +/** + * @brief Clamp angular coordinates to the valid range and offset by the central meridian (lam0) and + * an optional prime meridian offset. + * + * @tparam Coordinate the coordinate type + * @tparam T the coordinate value type + */ +template +class clamp_angular_coordinates : operation { + public: + /** + * @brief Construct a new clamp angular coordinates object + * + * @param params the projection parameters + */ + __host__ __device__ clamp_angular_coordinates(projection_parameters const& params) + : lam0_(params.lam0_), prime_meridian_offset_(params.prime_meridian_offset_) + { + } + + // projection_parameters setup(projection_parameters const& params) { return params; } + + /** + * @brief Clamp angular coordinate to the valid range + * + * @param coord The coordinate to clamp + * @param dir The direction of the operation + * @return The clamped coordinate + */ + __host__ __device__ Coordinate operator()(Coordinate const& coord, direction dir) const + { + if (dir == direction::FORWARD) + return forward(coord); + else + return inverse(coord); + } + + private: + /** + * @brief Forward clamping operation + * + * Offsets the longitude by the prime meridian offset and central meridian (lam0) and clamps the + * latitude to the range -pi/2..pi/2 radians (-90..90 degrees) and the longitude to the range + * -pi..pi radians (-180..180 degrees). + * + * @param coord The coordinate to clamp + * @return The clamped coordinate + */ + __host__ __device__ Coordinate forward(Coordinate const& coord) const + { + // check for latitude or longitude over-range + T t = (coord.y < 0 ? -coord.y : coord.y) - M_PI_2; + CUPROJ_HOST_DEVICE_EXPECTS(t <= EPSILON_RADIANS, "Invalid latitude"); + CUPROJ_HOST_DEVICE_EXPECTS(coord.x <= 10 || coord.x >= -10, "Invalid longitude"); + + Coordinate xy = coord; + + /* Clamp latitude to -pi/2..pi/2 degree range */ + auto half_pi = static_cast(M_PI_2); + xy.y = std::clamp(xy.y, -half_pi, half_pi); + + // Distance from central meridian, taking system zero meridian into account + xy.x = (xy.x - prime_meridian_offset_) - lam0_; + + // Ensure longitude is in the -pi:pi range + xy.x = detail::wrap_to_pi(xy.x); + + return xy; + } + + /** + * @brief Inverse clamping operation + * + * Reverse-offsets the longitude by the prime meridian offset and central meridian + * and clamps the longitude to the range -pi..pi radians (-180..180 degrees) + * + * @param coord The coordinate to clamp + * @return The clamped coordinate + */ + __host__ __device__ Coordinate inverse(Coordinate const& coord) const + { + Coordinate xy = coord; + + // Distance from central meridian, taking system zero meridian into account + xy.x += prime_meridian_offset_ + lam0_; + + // Ensure longitude is in the -pi:pi range + xy.x = detail::wrap_to_pi(xy.x); + + return xy; + } + + T lam0_{}; // central meridian + T prime_meridian_offset_{}; +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/operation/degrees_to_radians.cuh b/cpp/cuproj/include/cuproj/operation/degrees_to_radians.cuh new file mode 100644 index 000000000..802e6f127 --- /dev/null +++ b/cpp/cuproj/include/cuproj/operation/degrees_to_radians.cuh @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include + +namespace cuproj { + +/** + * @brief Converts degrees to radians and vice versa + * + * @tparam Coordinate The coordinate type + */ +template +class degrees_to_radians : operation { + public: + /** + * @brief Converts degrees to radians and vice versa + * + * @param coord The coordinate to convert + * @param dir The direction of the conversion: FORWARD converts degrees to radians, INVERSE + * converts radians to degrees + * @return The converted coordinate + */ + __host__ __device__ Coordinate operator()(Coordinate const& coord, direction dir) const + { + if (dir == direction::FORWARD) + return forward(coord); + else + return inverse(coord); + } + + private: + /** + * @brief Converts degrees to radians + * + * @param coord The coordinate to convert (lat, lon) in degrees + * @return The converted coordinate (lat, lon) in radians + */ + __host__ __device__ Coordinate forward(Coordinate const& coord) const + { + using T = typename Coordinate::value_type; + return Coordinate{coord.x * DEG_TO_RAD, coord.y * DEG_TO_RAD}; + } + + /** + * @brief Converts radians to degrees + * + * @param coord The coordinate to convert (lat, lon) in radians + * @return The converted coordinate (lat, lon) in degrees + */ + __host__ __device__ Coordinate inverse(Coordinate const& coord) const + { + using T = typename Coordinate::value_type; + return Coordinate{coord.x * RAD_TO_DEG, coord.y * RAD_TO_DEG}; + } +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/operation/offset_scale_cartesian_coordinates.cuh b/cpp/cuproj/include/cuproj/operation/offset_scale_cartesian_coordinates.cuh new file mode 100644 index 000000000..a32c383f3 --- /dev/null +++ b/cpp/cuproj/include/cuproj/operation/offset_scale_cartesian_coordinates.cuh @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include + +#include + +#include + +namespace cuproj { + +/** + * @brief Given Cartesian coordinates (x, y) in meters, offset and scale them + * to the projection's origin and scale (ellipsoidal semi-major axis). + * + * @tparam Coordinate coordinate type + * @tparam T coordinate value type + */ +template +class offset_scale_cartesian_coordinates : operation { + public: + /** + * @brief Constructor + * + * @param params projection parameters, including the ellipsoid semi-major axis + * and the projection origin + */ + __host__ __device__ offset_scale_cartesian_coordinates(projection_parameters const& params) + : a_(params.ellipsoid_.a), ra_(T{1.0} / a_), x0_(params.x0), y0_(params.y0) + { + } + + /** + * @brief Offset and scale a single coordinate + * + * @param coord the coordinate to offset and scale + * @param dir the direction of the operation, either forward or inverse + * @return the offset and scaled coordinate + */ + __host__ __device__ Coordinate operator()(Coordinate const& coord, direction dir) const + { + if (dir == direction::FORWARD) + return forward(coord); + else + return inverse(coord); + } + + private: + /** + * @brief Scale a coordinate by the ellipsoid semi-major axis and offset it by + * the projection origin + * + * @param coord the coordinate to offset and scale + * @return the offset and scaled coordinate + */ + __host__ __device__ Coordinate forward(Coordinate const& coord) const + { + return coord * a_ + Coordinate{x0_, y0_}; + }; + + /** + * @brief Offset a coordinate by the projection origin and scale it by the + * inverse of the ellipsoid semi-major axis + * + * @param coord the coordinate to offset and scale + * @return the offset and scaled coordinate + */ + __host__ __device__ Coordinate inverse(Coordinate const& coord) const + { + return (coord - Coordinate{x0_, y0_}) * ra_; + }; + + T a_; // ellipsoid semi-major axis + T ra_; // inverse of ellipsoid semi-major axis + T x0_; // projection origin x + T y0_; // projection origin y +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/operation/operation.cuh b/cpp/cuproj/include/cuproj/operation/operation.cuh new file mode 100644 index 000000000..40eb294bf --- /dev/null +++ b/cpp/cuproj/include/cuproj/operation/operation.cuh @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +namespace cuproj { + +/** + * @brief Enumerates the different types of transform operations + * + * This enum is used to identify the type of transform operation in the transform pipeline. Each + * operation_type has a corresponding class that implements the operation. + */ +enum operation_type { + AXIS_SWAP, + DEGREES_TO_RADIANS, + CLAMP_ANGULAR_COORDINATES, + OFFSET_SCALE_CARTESIAN_COORDINATES, + TRANSVERSE_MERCATOR +}; + +/// Enumerates the direction of a transform operation +enum class direction { FORWARD, INVERSE }; + +/// Returns the inverse of a direction +direction reverse(direction dir) +{ + return dir == direction::FORWARD ? direction::INVERSE : direction::FORWARD; +} + +/** + * @brief Base class for all transform operations + * + * This class is used to define the interface for all transform operations. A transform operation + * is a function object that takes a coordinate and returns a coordinate. Operations are composed + * together to form a transform pipeline by cuproj::projection. + * + * @tparam Coordinate + * @tparam Coordinate::value_type + */ +template +class operation { + public: + /** + * @brief Applies the transform operation to a coordinate + * + * @param c Coordinate to transform + * @param dir Direction of transform + * @return Coordinate + */ + __host__ __device__ Coordinate operator()(Coordinate const& c, direction dir) const { return c; } + + /** + * @brief Modifies the projection parameters for the transform operation + * + * Some (but not all) operations require additional parameters to be set in the projection_params + * object. This function is called by cuproj::projection::setup() to allow the operation to + * modify the parameters as needed. + * + * The final project_parameters are passed to every operation in the transform pipeline. + * + * @param params Projection parameters + * @return The modified parameters + */ + __host__ projection_parameters setup(projection_parameters const& params) + { + return params; + }; +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/operation/transverse_mercator.cuh b/cpp/cuproj/include/cuproj/operation/transverse_mercator.cuh new file mode 100644 index 000000000..8e46a9690 --- /dev/null +++ b/cpp/cuproj/include/cuproj/operation/transverse_mercator.cuh @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +// Code in this file is originally from the [OSGeo/PROJ project](https://github.com/OSGeo/PROJ) +// and has been modified to run on the GPU using CUDA. +// +// PROJ License from https://github.com/OSGeo/PROJ/blob/9.2/COPYING: +// Note however that the file it is taken from did not have a copyright notice. +/* + Copyright information can be found in source files. + + -------------- + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +// The following text is taken from the PROJ file +// [tmerc.cpp](https://github.com/OSGeo/PROJ/blob/9.2/src/projections/tmerc.cpp) +// see the file LICENSE_PROJ in the cuspatial repository root directory for the original PROJ +// license text. +/*****************************************************************************/ +// +// Exact Transverse Mercator functions +// +// +// The code in this file is largly based upon procedures: +// +// Written by: Knud Poder and Karsten Engsager +// +// Based on math from: R.Koenig and K.H. Weise, "Mathematische +// Grundlagen der hoeheren Geodaesie und Kartographie, +// Springer-Verlag, Berlin/Goettingen" Heidelberg, 1951. +// +// Modified and used here by permission of Reference Networks +// Division, Kort og Matrikelstyrelsen (KMS), Copenhagen, Denmark +// +/*****************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +#include + +#include + +namespace cuproj { + +namespace detail { + +/** + * @brief Evaluate Gaussian<-->Geographic trigonometric series + * + * @tparam T data type + * @param p1 pointer to the first element of the array + * @param len_p1 length of the array + * @param B The argument to the trigonometric series + * @param cos_2B precomputed cos(2*B) + * @param sin_2B precomputed sin(2*B) + * @return The value of the trigonometric series at B + */ +template +inline static __host__ __device__ T gatg(T const* p1, int len_p1, T B, T cos_2B, T sin_2B) +{ + T h = 0, h1, h2 = 0; + + T const two_cos_2B = 2 * cos_2B; + T const* p = p1 + len_p1; + h1 = *--p; + while (p - p1) { + h = -h2 + two_cos_2B * h1 + *--p; + h2 = h1; + h1 = h; + } + return (B + h * sin_2B); +} + +/** + * @brief Clenshaw summation for complex numbers + * + * @see https://en.wikipedia.org/wiki/Clenshaw_algorithm + * + * @tparam T data type + * @param a coefficients + * @param size size of coefficients + * @param sin_arg_r precomputed sin(arg_r) + * @param cos_arg_r precomputed cos(arg_r) + * @param sinh_arg_i precomputed sinh(arg_i) + * @param cosh_arg_i precomputed cosh(arg_i) + * @param R real part of the summation + * @param I imaginary part of the summation + * @return The real part of the summation at arg_r + */ +template +inline static __host__ __device__ T clenshaw_complex( + T const* a, int size, T sin_arg_r, T cos_arg_r, T sinh_arg_i, T cosh_arg_i, T* R, T* I) +{ + T r, i, hr, hr1, hr2, hi, hi1, hi2; + + // arguments + T const* p = a + size; + r = 2 * cos_arg_r * cosh_arg_i; + i = -2 * sin_arg_r * sinh_arg_i; + + // summation loop + hi1 = hr1 = hi = 0; + hr = *--p; + for (; a - p;) { + hr2 = hr1; + hi2 = hi1; + hr1 = hr; + hi1 = hi; + hr = -hr2 + r * hr1 - i * hi1 + *--p; + hi = -hi2 + i * hr1 + r * hi1; + } + + r = sin_arg_r * cosh_arg_i; + i = cos_arg_r * sinh_arg_i; + *R = r * hr - i * hi; + *I = r * hi + i * hr; + return *R; +} + +/** + * @brief Clenshaw summation for real numbers + * + * @see https://en.wikipedia.org/wiki/Clenshaw_algorithm + * + * @tparam T data type + * @param a pointer to array of coefficients + * @param size number of coefficients + * @param arg_r argument value + * @return the summation at arg_r + */ +template +static __host__ __device__ T clenshaw_real(T const* a, int size, T arg_r) +{ + T r, hr, hr1, hr2, cos_arg_r; + + T const* p = a + size; + cos_arg_r = cos(arg_r); + r = 2 * cos_arg_r; + + // summation loop + hr1 = 0; + hr = *--p; + for (; a - p;) { + hr2 = hr1; + hr1 = hr; + hr = -hr2 + r * hr1 + *--p; + } + return sin(arg_r) * hr; +} +} // namespace detail + +template +class transverse_mercator : operation { + public: + static constexpr int ETMERC_ORDER = 6; ///< 6th order series expansion + + /** + * @brief construct a transverse mercator projection + * + * @param params projection parameters + */ + __host__ __device__ transverse_mercator(projection_parameters const& params) : params_(params) + { + } + + /** + * @brief Perform UTM projection for a single coordinate + * + * @param coord the coordinate to project + * @param dir direction of projection + * @return projected coordinate + */ + __host__ __device__ Coordinate operator()(Coordinate const& coord, direction dir) const + { + if (dir == direction::FORWARD) + return forward(coord); + else + return inverse(coord); + } + + static constexpr T utm_central_meridian = T{500000}; // false easting center of UTM zone + // false northing center of UTM zone + static constexpr T utm_central_parallel(hemisphere h) + { + return (h == hemisphere::NORTH) ? T{0} : T{10000000}; + } + + /** + * @brief Set up the projection parameters for transverse mercator projection + * + * @param input_params projection parameters + * @return projection parameters modified for transverse mercator projection + */ + projection_parameters setup(projection_parameters const& input_params) + { + params_ = input_params; + + // so we don't have to qualify the class name everywhere. + auto& params = params_; + auto& tmerc_params = params_.tmerc_params_; + auto& ellipsoid = params_.ellipsoid_; + + assert(ellipsoid.es > 0); + + params.x0 = utm_central_meridian; + params.y0 = utm_central_parallel(params.utm_hemisphere_); + + if (params.utm_zone_ > 0 && params.utm_zone_ <= 60) { + --params.utm_zone_; + } else { + params.utm_zone_ = lround((floor((detail::wrap_to_pi(params.lam0_) + M_PI) * 30. / M_PI))); + params.utm_zone_ = std::clamp(params.utm_zone_, 0, 59); + } + + params.lam0_ = (params.utm_zone_ + .5) * M_PI / 30. - M_PI; + params.k0 = T{0.9996}; + params.phi0 = T{0}; + + // third flattening + T const n = ellipsoid.n; + T np = n; + + // COEFFICIENTS OF TRIG SERIES GEO <-> GAUSS + // cgb := Gaussian -> Geodetic, KW p190 - 191 (61) - (62) + // cbg := Geodetic -> Gaussian, KW p186 - 187 (51) - (52) + // ETMERC_ORDER = 6th degree : Engsager and Poder: ICC2007 + + tmerc_params.cgb[0] = + n * + (2 + n * (-2 / 3.0 + n * (-2 + n * (116 / 45.0 + n * (26 / 45.0 + n * (-2854 / 675.0)))))); + tmerc_params.cbg[0] = + n * (-2 + n * (2 / 3.0 + + n * (4 / 3.0 + n * (-82 / 45.0 + n * (32 / 45.0 + n * (4642 / 4725.0)))))); + np *= n; + tmerc_params.cgb[1] = + np * (7 / 3.0 + n * (-8 / 5.0 + n * (-227 / 45.0 + n * (2704 / 315.0 + n * (2323 / 945.0))))); + tmerc_params.cbg[1] = + np * (5 / 3.0 + n * (-16 / 15.0 + n * (-13 / 9.0 + n * (904 / 315.0 + n * (-1522 / 945.0))))); + np *= n; + // n^5 coeff corrected from 1262/105 -> -1262/105 + tmerc_params.cgb[2] = + np * (56 / 15.0 + n * (-136 / 35.0 + n * (-1262 / 105.0 + n * (73814 / 2835.0)))); + tmerc_params.cbg[2] = + np * (-26 / 15.0 + n * (34 / 21.0 + n * (8 / 5.0 + n * (-12686 / 2835.0)))); + np *= n; + // n^5 coeff corrected from 322/35 -> 332/35 + tmerc_params.cgb[3] = np * (4279 / 630.0 + n * (-332 / 35.0 + n * (-399572 / 14175.0))); + tmerc_params.cbg[3] = np * (1237 / 630.0 + n * (-12 / 5.0 + n * (-24832 / 14175.0))); + np *= n; + tmerc_params.cgb[4] = np * (4174 / 315.0 + n * (-144838 / 6237.0)); + tmerc_params.cbg[4] = np * (-734 / 315.0 + n * (109598 / 31185.0)); + np *= n; + tmerc_params.cgb[5] = np * (601676 / 22275.0); + tmerc_params.cbg[5] = np * (444337 / 155925.0); + + // Constants of the projections + // Transverse Mercator (UTM, ITM, etc) + np = n * n; + // Norm. meridian quadrant, K&W p.50 (96), p.19 (38b), p.5 (2) + tmerc_params.Qn = params.k0 / (1 + n) * (1 + np * (1 / 4.0 + np * (1 / 64.0 + np / 256.0))); + // coef of trig series + // utg := ell. N, E -> sph. N, E, KW p194 (65) + // gtu := sph. N, E -> ell. N, E, KW p196 (69) + tmerc_params.utg[0] = + n * (-0.5 + + n * (2 / 3.0 + + n * (-37 / 96.0 + n * (1 / 360.0 + n * (81 / 512.0 + n * (-96199 / 604800.0)))))); + tmerc_params.gtu[0] = + n * (0.5 + n * (-2 / 3.0 + n * (5 / 16.0 + n * (41 / 180.0 + + n * (-127 / 288.0 + n * (7891 / 37800.0)))))); + tmerc_params.utg[1] = + np * (-1 / 48.0 + + n * (-1 / 15.0 + n * (437 / 1440.0 + n * (-46 / 105.0 + n * (1118711 / 3870720.0))))); + tmerc_params.gtu[1] = + np * (13 / 48.0 + + n * (-3 / 5.0 + n * (557 / 1440.0 + n * (281 / 630.0 + n * (-1983433 / 1935360.0))))); + np *= n; + tmerc_params.utg[2] = + np * (-17 / 480.0 + n * (37 / 840.0 + n * (209 / 4480.0 + n * (-5569 / 90720.0)))); + tmerc_params.gtu[2] = + np * (61 / 240.0 + n * (-103 / 140.0 + n * (15061 / 26880.0 + n * (167603 / 181440.0)))); + np *= n; + tmerc_params.utg[3] = np * (-4397 / 161280.0 + n * (11 / 504.0 + n * (830251 / 7257600.0))); + tmerc_params.gtu[3] = np * (49561 / 161280.0 + n * (-179 / 168.0 + n * (6601661 / 7257600.0))); + np *= n; + tmerc_params.utg[4] = np * (-4583 / 161280.0 + n * (108847 / 3991680.0)); + tmerc_params.gtu[4] = np * (34729 / 80640.0 + n * (-3418889 / 1995840.0)); + np *= n; + tmerc_params.utg[5] = np * (-20648693 / 638668800.0); + tmerc_params.gtu[5] = np * (212378941 / 319334400.0); + + // Gaussian latitude value of the origin latitude + T const Z = detail::gatg( + tmerc_params.cbg, ETMERC_ORDER, params.phi0, cos(2 * params.phi0), sin(2 * params.phi0)); + + // Origin northing minus true northing at the origin latitude + // i.e. true northing = N - P->Zb + tmerc_params.Zb = + -tmerc_params.Qn * (Z + detail::clenshaw_real(tmerc_params.gtu, ETMERC_ORDER, 2 * Z)); + + return params; + } + + private: + /** + * @brief Forward projection, from geographic to transverse mercator. + * + * @param coord Geographic coordinate (lat, lon) in radians. + * @return Transverse mercator coordinate (x, y) in meters. + */ + __host__ __device__ Coordinate forward(Coordinate const& coord) const + { + // so we don't have to qualify the class name everywhere. + auto& tmerc_params = this->params_.tmerc_params_; + auto& ellipsoid = this->params_.ellipsoid_; + + // ell. LAT, LNG -> Gaussian LAT, LNG + T Cn = + detail::gatg(tmerc_params.cbg, ETMERC_ORDER, coord.y, cos(2 * coord.y), sin(2 * coord.y)); + + // Gaussian LAT, LNG -> compl. sph. LAT + T const sin_Cn = sin(Cn); + T const cos_Cn = cos(Cn); + T const sin_Ce = sin(coord.x); + T const cos_Ce = cos(coord.x); + + T const cos_Cn_cos_Ce = cos_Cn * cos_Ce; + Cn = atan2(sin_Cn, cos_Cn_cos_Ce); + + T const inv_denom_tan_Ce = 1. / hypot(sin_Cn, cos_Cn_cos_Ce); + T const tan_Ce = sin_Ce * cos_Cn * inv_denom_tan_Ce; + + // Variant of the above: found not to be measurably faster + // T const sin_Ce_cos_Cn = sin_Ce*cos_Cn; + // T const denom = sqrt(1 - sin_Ce_cos_Cn * sin_Ce_cos_Cn); + // T const tan_Ce = sin_Ce_cos_Cn / denom; + + // compl. sph. N, E -> ell. norm. N, E + T Ce = asinh(tan_Ce); /* Replaces: Ce = log(tan(FORTPI + Ce*0.5)); */ + + // Non-optimized version: + // T const sin_arg_r = sin(2*Cn); + // T const cos_arg_r = cos(2*Cn); + // + // Given: + // sin(2 * Cn) = 2 sin(Cn) cos(Cn) + // sin(atan(y)) = y / sqrt(1 + y^2) + // cos(atan(y)) = 1 / sqrt(1 + y^2) + // ==> sin(2 * Cn) = 2 tan_Cn / (1 + tan_Cn^2) + // + // cos(2 * Cn) = 2cos^2(Cn) - 1 + // = 2 / (1 + tan_Cn^2) - 1 + // + T const two_inv_denom_tan_Ce = 2 * inv_denom_tan_Ce; + T const two_inv_denom_tan_Ce_square = two_inv_denom_tan_Ce * inv_denom_tan_Ce; + T const tmp_r = cos_Cn_cos_Ce * two_inv_denom_tan_Ce_square; + T const sin_arg_r = sin_Cn * tmp_r; + T const cos_arg_r = cos_Cn_cos_Ce * tmp_r - 1; + + // Non-optimized version: + // T const sinh_arg_i = sinh(2*Ce); + // T const cosh_arg_i = cosh(2*Ce); + // + // Given + // sinh(2 * Ce) = 2 sinh(Ce) cosh(Ce) + // sinh(asinh(y)) = y + // cosh(asinh(y)) = sqrt(1 + y^2) + // ==> sinh(2 * Ce) = 2 tan_Ce sqrt(1 + tan_Ce^2) + // + // cosh(2 * Ce) = 2cosh^2(Ce) - 1 + // = 2 * (1 + tan_Ce^2) - 1 + // + // and 1+tan_Ce^2 = 1 + sin_Ce^2 * cos_Cn^2 / (sin_Cn^2 + cos_Cn^2 * + // cos_Ce^2) = (sin_Cn^2 + cos_Cn^2 * cos_Ce^2 + sin_Ce^2 * cos_Cn^2) / + // (sin_Cn^2 + cos_Cn^2 * cos_Ce^2) = 1. / (sin_Cn^2 + cos_Cn^2 * cos_Ce^2) + // = inv_denom_tan_Ce^2 + + T const sinh_arg_i = tan_Ce * two_inv_denom_tan_Ce; + T const cosh_arg_i = two_inv_denom_tan_Ce_square - 1; + + T dCn, dCe; + Cn += detail::clenshaw_complex( + tmerc_params.gtu, ETMERC_ORDER, sin_arg_r, cos_arg_r, sinh_arg_i, cosh_arg_i, &dCn, &dCe); + + Ce += dCe; + + CUPROJ_HOST_DEVICE_EXPECTS(fabs(Ce) <= 2.623395162778, // value comes from PROJ + "Coordinate transform outside projection domain"); + Coordinate xy{0.0, 0.0}; + xy.y = tmerc_params.Qn * Cn + tmerc_params.Zb; // Northing + xy.x = tmerc_params.Qn * Ce; // Easting + + return xy; + } + + /** + * @brief inverse transform, from projected to geographic coordinate + * @param coord projected coordinate (x, y) in meters + * @return geographic coordinate (lon, lat) in radians + */ + __host__ __device__ Coordinate inverse(Coordinate const& coord) const + { + // so we don't have to qualify the class name everywhere. + auto& tmerc_params = this->params_.tmerc_params_; + auto& ellipsoid = this->params_.ellipsoid_; + + // normalize N, E + T Cn = (coord.y - tmerc_params.Zb) / tmerc_params.Qn; + T Ce = coord.x / tmerc_params.Qn; + + CUPROJ_HOST_DEVICE_EXPECTS(fabs(Ce) <= 2.623395162778, // value comes from PROJ + "Coordinate transform outside projection domain"); + + // norm. N, E -> compl. sph. LAT, LNG + T const sin_arg_r = sin(2 * Cn); + T const cos_arg_r = cos(2 * Cn); + + // T const sinh_arg_i = sinh(2*Ce); + // T const cosh_arg_i = cosh(2*Ce); + T const exp_2_Ce = exp(2 * Ce); + T const half_inv_exp_2_Ce = T{0.5} / exp_2_Ce; + T const sinh_arg_i = T{0.5} * exp_2_Ce - half_inv_exp_2_Ce; + T const cosh_arg_i = T{0.5} * exp_2_Ce + half_inv_exp_2_Ce; + + T dCn_ignored, dCe; + Cn += detail::clenshaw_complex(tmerc_params.utg, + ETMERC_ORDER, + sin_arg_r, + cos_arg_r, + sinh_arg_i, + cosh_arg_i, + &dCn_ignored, + &dCe); + Ce += dCe; + + // compl. sph. LAT -> Gaussian LAT, LNG + T const sin_Cn = sin(Cn); + T const cos_Cn = cos(Cn); + +#if 0 + // Non-optimized version: + T sin_Ce, cos_Ce; + Ce = atan (sinh (Ce)); // Replaces: Ce = 2*(atan(exp(Ce)) - FORTPI); + sin_Ce = sin (Ce); + cos_Ce = cos (Ce); + Ce = atan2 (sin_Ce, cos_Ce*cos_Cn); + Cn = atan2 (sin_Cn*cos_Ce, hypot (sin_Ce, cos_Ce*cos_Cn)); +#else + // One can divide both member of Ce = atan2(...) by cos_Ce, which + // gives: Ce = atan2 (tan_Ce, cos_Cn) = atan2(sinh(Ce), cos_Cn) + // + // and the same for Cn = atan2(...) + // Cn = atan2 (sin_Cn, hypot (sin_Ce, cos_Ce*cos_Cn)/cos_Ce) + // = atan2 (sin_Cn, hypot (sin_Ce/cos_Ce, cos_Cn)) + // = atan2 (sin_Cn, hypot (tan_Ce, cos_Cn)) + // = atan2 (sin_Cn, hypot (sinhCe, cos_Cn)) + T const sinhCe = sinh(Ce); + Ce = atan2(sinhCe, cos_Cn); + T const modulus_Ce = hypot(sinhCe, cos_Cn); + Cn = atan2(sin_Cn, modulus_Ce); +#endif + + // Gaussian LAT, LNG -> ell. LAT, LNG + + // Optimization of the computation of cos(2*Cn) and sin(2*Cn) + T const tmp = 2 * modulus_Ce / (sinhCe * sinhCe + 1); + T const sin_2_Cn = sin_Cn * tmp; + T const cos_2_Cn = tmp * modulus_Ce - 1.; + // T const cos_2_Cn = cos(2 * Cn); + // T const sin_2_Cn = sin(2 * Cn); + + return Coordinate{Ce, detail::gatg(tmerc_params.cgb, ETMERC_ORDER, Cn, cos_2_Cn, sin_2_Cn)}; + } + + /** + * @brief Get the origin longitude + * + * @return the origin longitude in radians + */ + T lam0() const { return this->params_.lam0_; } + + private: + projection_parameters params_{}; +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/projection.cuh b/cpp/cuproj/include/cuproj/projection.cuh new file mode 100644 index 000000000..c774de77b --- /dev/null +++ b/cpp/cuproj/include/cuproj/projection.cuh @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +namespace cuproj { + +/** + * @brief A projection transforms coordinates between coordinate reference systems + * + * Projections are constructed from a list of operations to be applied to coordinates. + * The operations are applied in order, either forward or inverse. + * + * @tparam Coordinate the coordinate type + * @tparam T the coordinate value type + */ +template +class projection { + public: + /** + * @brief Construct a new projection object + * + * @param operations the list of operations to apply to coordinates + * @param params the projection parameters + * @param dir the default order to execute the operations, FORWARD or INVERSE + */ + __host__ projection(std::vector const& operations, + projection_parameters const& params, + direction dir = direction::FORWARD) + : params_(params), constructed_direction_(dir) + { + setup(operations); + } + + /** + * @brief Transform a range of coordinates + * + * @tparam CoordIter the coordinate iterator type + * @param first the start of the coordinate range + * @param last the end of the coordinate range + * @param result the output coordinate range + * @param dir the direction of the transform, FORWARD or INVERSE. If INVERSE, the operations will + * run in the reverse order of the direction specified in the constructor. + * @param stream the CUDA stream on which to run the transform + */ + template + void transform(CoordIter first, + CoordIter last, + CoordIter result, + direction dir, + rmm::cuda_stream_view stream = rmm::cuda_stream_default) const + { + static_assert(std::is_same_v, + "Coordinate type must match iterator value type"); + dir = (constructed_direction_ == direction::FORWARD) ? dir : reverse(dir); + + if (dir == direction::FORWARD) { + auto pipe = detail::pipeline{ + params_, operations_.data().get(), operations_.size()}; + thrust::transform(rmm::exec_policy(stream), first, last, result, pipe); + } else { + auto pipe = detail::pipeline{ + params_, operations_.data().get(), operations_.size()}; + thrust::transform(rmm::exec_policy(stream), first, last, result, pipe); + } + } + + private: + void setup(std::vector const& operations) + { + std::for_each(operations.begin(), operations.end(), [&](auto const& op) { + switch (op) { + case operation_type::TRANSVERSE_MERCATOR: { + auto op = transverse_mercator{params_}; + params_ = op.setup(params_); + break; + } + // TODO: some ops don't have setup. Should we make them all have setup? + default: break; + } + }); + + operations_.resize(operations.size()); + thrust::copy(operations.begin(), operations.end(), operations_.begin()); + } + + thrust::device_vector operations_; + projection_parameters params_; + direction constructed_direction_{direction::FORWARD}; +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/projection_factories.hpp b/cpp/cuproj/include/cuproj/projection_factories.hpp new file mode 100644 index 000000000..7f16556ab --- /dev/null +++ b/cpp/cuproj/include/cuproj/projection_factories.hpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include +#include +#include + +namespace cuproj { + +namespace detail { + +/** + * @internal + * @brief Check if the given EPSG code string is valid + * + * @param epsg_str the EPSG code string + * @return true if the EPSG code is valid, false otherwise + */ +inline bool is_epsg(std::string const& epsg_str) { return epsg_str.find("EPSG:") == 0; } + +/** + * @internal + * @brief Convert an EPSG code string to its integer value (the part after 'EPSG:') + * + * @param epsg_str the EPSG code string + * @return the integer value of the EPSG code + */ +inline int epsg_stoi(std::string const& epsg_str) +{ + try { + CUPROJ_EXPECTS(is_epsg(epsg_str), "EPSG code must start with 'EPSG:'"); + return std::stoi(epsg_str.substr(epsg_str.find_first_not_of("EPSG:"))); + } catch (std::invalid_argument const&) { + CUPROJ_FAIL("Invalid EPSG code"); + } +} + +/** + * @internal + * @brief Check if the given EPSG code string is for WGS84 + * + * @param epsg_str the EPSG code string + * @return true if the EPSG code is for WGS84, false otherwise + */ +inline bool is_wgs_84(std::string const& epsg_str) { return epsg_str == "EPSG:4326"; } + +/** + * @internal + * @brief Convert an EPSG code string to a UTM zone and hemisphere + * + * @param epsg_str the EPSG code string + * @return a pair of UTM zone and hemisphere + */ +inline auto epsg_to_utm_zone(std::string const& epsg_str) +{ + int epsg = epsg_stoi(epsg_str); + + if (epsg >= 32601 && epsg <= 32660) { + return std::make_pair(epsg - 32600, hemisphere::NORTH); + } else if (epsg >= 32701 && epsg <= 32760) { + return std::make_pair(epsg - 32700, hemisphere::SOUTH); + } else { + CUPROJ_FAIL("Unsupported UTM EPSG code. Must be in range [32601, 32760] or [32701, 32760]]"); + } +} + +} // namespace detail + +/** + * @brief Create a WGS84<-->UTM projection for the given UTM zone and hemisphere + * + * @tparam Coordinate the coordinate type + * @tparam Coordinate::value_type the coordinate value type + * @param zone the UTM zone + * @param hemisphere the UTM hemisphere + * @param dir if FORWARD, create a projection from UTM to WGS84, otherwise create a projection + * from WGS84 to UTM + * @return a projection object implementing the requested transformation + */ +template +projection make_utm_projection(int zone, + hemisphere hemisphere, + direction dir = direction::FORWARD) +{ + projection_parameters tmerc_proj_params{ + make_ellipsoid_wgs84(), zone, hemisphere, T{0}, T{0}}; + + std::vector h_utm_pipeline{ + operation_type::AXIS_SWAP, + operation_type::DEGREES_TO_RADIANS, + operation_type::CLAMP_ANGULAR_COORDINATES, + operation_type::TRANSVERSE_MERCATOR, + operation_type::OFFSET_SCALE_CARTESIAN_COORDINATES}; + + return projection{h_utm_pipeline, tmerc_proj_params, dir}; +} + +/** + * @brief Create a projection object from EPSG codes + * + * @throw cuproj::logic_error if the EPSG codes describe a transformation that is not supported + * + * @note Currently only WGS84 to UTM and UTM to WGS84 are supported, so one of the EPSG codes must + * be "EPSG:4326" (WGS84) and the other must be a UTM EPSG code. + * + * @tparam Coordinate the coordinate type + * @param src_epsg the source EPSG code + * @param dst_epsg the destination EPSG code + * @return a projection object implementing the transformation between the two EPSG codes + */ +template +cuproj::projection make_projection(std::string const& src_epsg, + std::string const& dst_epsg) +{ + if (detail::is_wgs_84(src_epsg)) { + auto [dst_zone, dst_hemisphere] = detail::epsg_to_utm_zone(dst_epsg); + return make_utm_projection(dst_zone, dst_hemisphere); + } else { + CUPROJ_EXPECTS(detail::is_wgs_84(dst_epsg), + "Source or Destination EPSG must be WGS84 (EPSG:4326)"); + auto [src_zone, src_hemisphere] = detail::epsg_to_utm_zone(src_epsg); + return make_utm_projection(src_zone, src_hemisphere, direction::INVERSE); + } +} + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj/projection_parameters.hpp b/cpp/cuproj/include/cuproj/projection_parameters.hpp new file mode 100644 index 000000000..46072f7e1 --- /dev/null +++ b/cpp/cuproj/include/cuproj/projection_parameters.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +namespace cuproj { + +/** + * @brief Hemisphere identifier for projections + */ +enum class hemisphere { NORTH, SOUTH }; + +/** + * @brief Projection parameters + * + * Storage for parameters for projections. This is a POD type that is passed to + * the projection operators. + + * + * @tparam T Coordinate value type + */ +template +struct projection_parameters { + projection_parameters( + ellipsoid const& e, int utm_zone, hemisphere utm_hemisphere, T lam0, T prime_meridian_offset) + : ellipsoid_(e), + utm_zone_(utm_zone), + utm_hemisphere_{utm_hemisphere}, + lam0_(lam0), + prime_meridian_offset_(prime_meridian_offset) + { + } + + ellipsoid ellipsoid_{}; ///< Ellipsoid parameters + int utm_zone_{-1}; ///< UTM zone + hemisphere utm_hemisphere_{hemisphere::NORTH}; ///< UTM hemisphere + T lam0_{}; ///< Central meridian + T prime_meridian_offset_{}; ///< Offset from Greenwich + + T k0{}; // scaling + T phi0{}; // central parallel + T x0{}; // false easting + T y0{}; // false northing + + struct tmerc_params { + T Qn{}; // Meridian quadrant, scaled to the projection + T Zb{}; // Radius vector in polar coord. systems + T cgb[6]{}; // Constants for Gauss -> Geo lat + T cbg[6]{}; // Constants for Geo lat -> Gauss + T utg[6]{}; // Constants for transverse Mercator -> geo + T gtu[6]{}; // Constants for geo -> transverse Mercator + }; + + tmerc_params tmerc_params_{}; +}; + +} // namespace cuproj diff --git a/cpp/cuproj/include/cuproj_test/coordinate_generator.cuh b/cpp/cuproj/include/cuproj_test/coordinate_generator.cuh new file mode 100644 index 000000000..a6569bd28 --- /dev/null +++ b/cpp/cuproj/include/cuproj_test/coordinate_generator.cuh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace cuproj_test { + +// Generate a grid of coordinates +template +struct grid_generator { + Coord min_corner{}; + Coord max_corner{}; + Coord spacing{}; + int num_points_x{}; + + grid_generator(Coord const& min_corner, + Coord const& max_corner, + int num_points_x, + int num_points_y) + : min_corner(min_corner), max_corner(max_corner), num_points_x(num_points_x) + { + spacing = Coord{(max_corner.x - min_corner.x) / num_points_x, + (max_corner.y - min_corner.y) / num_points_y}; + } + + __device__ Coord operator()(int i) const + { + return min_corner + Coord{(i % num_points_x) * spacing.x, (i / num_points_x) * spacing.y}; + } +}; + +template +auto make_grid_array(Coord const& min_corner, + Coord const& max_corner, + int num_points_x, + int num_points_y) +{ + auto gen = grid_generator(min_corner, max_corner, num_points_x, num_points_y); + Vector grid(num_points_x * num_points_y); + thrust::tabulate(rmm::exec_policy(), grid.begin(), grid.end(), gen); + return grid; +} + +} // namespace cuproj_test diff --git a/cpp/cuproj/tests/CMakeLists.txt b/cpp/cuproj/tests/CMakeLists.txt index e69f76a87..cbeac0fae 100644 --- a/cpp/cuproj/tests/CMakeLists.txt +++ b/cpp/cuproj/tests/CMakeLists.txt @@ -24,7 +24,8 @@ function(ConfigureTest CMAKE_TEST_NAME) "$<$:${CUPROJ_CUDA_FLAGS}>") target_include_directories(${CMAKE_TEST_NAME} PRIVATE "$" - "$") + "$" + ../../../cpp/include) set_target_properties( ${CMAKE_TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "$" @@ -49,5 +50,5 @@ endfunction(ConfigureTest) ################################################################################################### # index -ConfigureTest(TEST_TEST - test.cu) +ConfigureTest(WGS_TO_UTM_TEST + wgs_to_utm_test.cu) diff --git a/cpp/cuproj/tests/wgs_to_utm_test.cu b/cpp/cuproj/tests/wgs_to_utm_test.cu new file mode 100644 index 000000000..4df935fe6 --- /dev/null +++ b/cpp/cuproj/tests/wgs_to_utm_test.cu @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * 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. + */ + +#include + +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +template +struct ProjectionTest : public ::testing::Test {}; + +using TestTypes = ::testing::Types; +TYPED_TEST_CASE(ProjectionTest, TestTypes); + +template +using coordinate = typename cuspatial::vec_2d; + +template +void convert_coordinates(InVector const& in, OutVector& out) +{ + using in_coord_type = typename InVector::value_type; + using out_coord_type = typename OutVector::value_type; + + static_assert( + (std::is_same_v != std::is_same_v), + "Invalid coordinate vector conversion"); + + if constexpr (std::is_same_v) { + using T = typename out_coord_type::value_type; + auto proj_coord_to_coordinate = [](auto const& c) { + return out_coord_type{static_cast(c.xy.x), static_cast(c.xy.y)}; + }; + thrust::transform(in.begin(), in.end(), out.begin(), proj_coord_to_coordinate); + } else if constexpr (std::is_same_v) { + auto coordinate_to_proj_coord = [](auto const& c) { return PJ_COORD{c.x, c.y, 0, 0}; }; + thrust::transform(in.begin(), in.end(), out.begin(), coordinate_to_proj_coord); + } +} + +// run a test using the cuproj library +template +void run_cuproj_test(thrust::host_vector> const& input, + thrust::host_vector> const& expected, + cuproj::projection> const& proj, + cuproj::direction dir, + T tolerance = T{0}) // 0 for 1-ulp comparison +{ + thrust::device_vector> d_in = input; + thrust::device_vector> d_out(d_in.size()); + + proj.transform(d_in.begin(), d_in.end(), d_out.begin(), dir); + +#ifndef NDEBUG + std::cout << "expected " << std::setprecision(20) << expected[0].x << " " << expected[0].y + << std::endl; + coordinate c_out = d_out[0]; + std::cout << "Device: " << std::setprecision(20) << c_out.x << " " << c_out.y << std::endl; +#endif + + CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(expected, d_out, tolerance); +} + +// run a test using the proj library for comparison +void run_proj_test(thrust::host_vector& coords, + char const* epsg_src, + char const* epsg_dst) +{ + PJ_CONTEXT* C = proj_context_create(); + PJ* P = proj_create_crs_to_crs(C, epsg_src, epsg_dst, nullptr); + proj_trans_array(P, PJ_FWD, coords.size(), coords.data()); + + proj_destroy(P); + proj_context_destroy(C); +} + +// Run a test using the cuproj library in both directions, comparing to the proj library +template +void run_forward_and_inverse(DeviceVector const& input, + T tolerance = T{0}, + std::string const& utm_epsg = "EPSG:32756") +{ + // note there are two notions of direction here. The direction of the construction of the + // projection is determined by the order of the epsg strings. The direction of the transform is + // determined by the direction argument to the transform method. This test runs both directions + // for a single projection, with the order of construction determined by the inverted template + // parameter. This is needed because a user may construct either a UTM->WGS84 or WGS84->UTM + // projection, and we want to test both directions for each. + thrust::host_vector> h_input(input.begin(), input.end()); + thrust::host_vector pj_input{input.size()}; + convert_coordinates(h_input, pj_input); + thrust::host_vector pj_expected(pj_input); + + char const* epsg_src = "EPSG:4326"; + char const* epsg_dst = utm_epsg.c_str(); + + if constexpr (inverted) {} + + auto run = [&]() { + run_proj_test(pj_expected, epsg_src, epsg_dst); + + thrust::host_vector> h_expected{pj_expected.size()}; + convert_coordinates(pj_expected, h_expected); + + auto proj = cuproj::make_projection>(epsg_src, epsg_dst); + + run_cuproj_test(h_input, h_expected, proj, cuproj::direction::FORWARD, tolerance); + run_cuproj_test(h_expected, h_input, proj, cuproj::direction::INVERSE, tolerance); + }; + + // forward construction + run(); + // invert construction + pj_input = pj_expected; + convert_coordinates(pj_input, h_input); + std::swap(epsg_src, epsg_dst); + run(); +} + +// Just test construction of the projection from supported EPSG codes +TYPED_TEST(ProjectionTest, make_projection_valid_epsg) +{ + using T = TypeParam; + cuproj::make_projection>("EPSG:4326", "EPSG:32756"); + cuproj::make_projection>("EPSG:32756", "EPSG:4326"); + cuproj::make_projection>("EPSG:4326", "EPSG:32601"); + cuproj::make_projection>("EPSG:32601", "EPSG:4326"); +} + +// Test that construction of the projection from unsupported EPSG codes throws +// expected exceptions +TYPED_TEST(ProjectionTest, invalid_epsg) +{ + using T = TypeParam; + EXPECT_THROW(cuproj::make_projection>("EPSG:4326", "EPSG:756"), + cuproj::logic_error); + EXPECT_THROW(cuproj::make_projection>("EPSG:4326", "UTM:32756"), + cuproj::logic_error); +} + +// Test on a single coordinate +TYPED_TEST(ProjectionTest, one) +{ + using T = TypeParam; + + coordinate sydney{-33.865143, 151.209900}; // Sydney, NSW, Australia + std::vector> input{sydney}; + // We can expect nanometer accuracy with double precision. The precision ratio of + // double to single precision is 2^53 / 2^24 == 2^29 ~= 10^9, then we should + // expect meter (10^9 nanometer) accuracy with single precision. + T tolerance = std::is_same_v ? T{1.0} : T{1e-9}; + run_forward_and_inverse(input, tolerance, "EPSG:32756"); +} + +// Test on a grid of coordinates +template +void test_grid(coordinate const& min_corner, + coordinate max_corner, + int num_points_xy, + std::string const& utm_epsg) +{ + auto input = cuproj_test::make_grid_array, rmm::device_vector>>( + min_corner, max_corner, num_points_xy, num_points_xy); + + thrust::host_vector> h_input(input); + + // We can expect nanometer accuracy with double precision. The precision ratio of + // double to single precision is 2^53 / 2^24 == 2^29 ~= 10^9, then we should + // expect meter (10^9 nanometer) accuracy with single precision. + // For large arrays seem to need to relax the tolerance a bit to match PROJ results. + // 1um for double and 10m for float seems like reasonable accuracy while not allowing excessive + // variance from PROJ results. + T tolerance = std::is_same_v ? T{1e-6} : T{10}; + run_forward_and_inverse(h_input, tolerance); +} + +TYPED_TEST(ProjectionTest, many) +{ + int num_points_xy = 100; + + // Test with grids of coordinates covering various locations on the globe + // Sydney Harbour + { + coordinate min_corner{-33.9, 151.2}; + coordinate max_corner{-33.7, 151.3}; + std::string epsg = "EPSG:32756"; + test_grid(min_corner, max_corner, num_points_xy, epsg); + } + + // London, UK + { + coordinate min_corner{51.0, -1.0}; + coordinate max_corner{52.0, 1.0}; + std::string epsg = "EPSG:32630"; + test_grid(min_corner, max_corner, num_points_xy, epsg); + } + + // Svalbard + { + coordinate min_corner{77.0, 15.0}; + coordinate max_corner{79.0, 20.0}; + std::string epsg = "EPSG:32633"; + test_grid(min_corner, max_corner, num_points_xy, epsg); + } + + // Ushuaia, Argentina + { + coordinate min_corner{-55.0, -70.0}; + coordinate max_corner{-53.0, -65.0}; + std::string epsg = "EPSG:32719"; + test_grid(min_corner, max_corner, num_points_xy, epsg); + } + + // McMurdo Station, Antarctica + { + coordinate min_corner{-78.0, 165.0}; + coordinate max_corner{-77.0, 170.0}; + std::string epsg = "EPSG:32706"; + test_grid(min_corner, max_corner, num_points_xy, epsg); + } + + // Singapore + { + coordinate min_corner{1.0, 103.0}; + coordinate max_corner{2.0, 104.0}; + std::string epsg = "EPSG:32648"; + test_grid(min_corner, max_corner, num_points_xy, epsg); + } +} diff --git a/cpp/include/cuspatial_test/vector_equality.hpp b/cpp/include/cuspatial_test/vector_equality.hpp index 4abde035d..a352b6a8f 100644 --- a/cpp/include/cuspatial_test/vector_equality.hpp +++ b/cpp/include/cuspatial_test/vector_equality.hpp @@ -75,7 +75,9 @@ MATCHER(vec_2d_matcher, ::testing::Matches(floating_eq_by_ulp(rhs.y))(lhs.y)) return true; - *result_listener << lhs << " != " << rhs; + *result_listener << std::fixed + << std::setprecision(std::numeric_limits::max_digits10) << lhs + << " != " << rhs; return false; } @@ -91,7 +93,9 @@ MATCHER_P(vec_2d_near_matcher, ::testing::Matches(floating_eq_by_abs_error(rhs.y, abs_error))(lhs.y)) return true; - *result_listener << lhs << " != " << rhs; + *result_listener << std::fixed + << std::setprecision(std::numeric_limits::max_digits10) << lhs + << " != " << rhs; return false; } @@ -103,7 +107,8 @@ MATCHER(float_matcher, std::string(negation ? "are not" : "are") + " approximate if (::testing::Matches(floating_eq_by_ulp(rhs))(lhs)) return true; - *result_listener << std::setprecision(std::numeric_limits::max_digits10) << lhs + *result_listener << std::fixed + << std::setprecision(std::numeric_limits::max_digits10) << lhs << " != " << rhs; return false; @@ -118,7 +123,8 @@ MATCHER_P(float_near_matcher, if (::testing::Matches(floating_eq_by_abs_error(rhs, abs_error))(lhs)) return true; - *result_listener << std::setprecision(std::numeric_limits::max_digits10) << lhs + *result_listener << std::fixed + << std::setprecision(std::numeric_limits::max_digits10) << lhs << " != " << rhs; return false; From 7f3231c17fc1b54124babb7cb884b0d6eef2a92f Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Thu, 20 Jul 2023 10:11:47 -0500 Subject: [PATCH 59/63] Use rapids-cmake to supply Google Benchmark library. (#1224) This PR updates cuspatial to use rapids-cmake to supply its Google Benchmark (gbench, also called `benchmark`) dependency. Currently I am unable to build cuspatial in a rapids-compose environment with cudf because cuspatial and cudf expect different versions of `benchmark` (rapids-cmake and cudf use 1.8.0, while cuspatial is pinned at 1.5.3). Authors: - Bradley Dice (https://github.com/bdice) Approvers: - Mark Harris (https://github.com/harrism) - Robert Maynard (https://github.com/robertmaynard) URL: https://github.com/rapidsai/cuspatial/pull/1224 --- cpp/CMakeLists.txt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index e2f771dda..f71a2f120 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -221,13 +221,8 @@ endif() if(CUSPATIAL_BUILD_BENCHMARKS) # Find or install GoogleBench - CPMFindPackage(NAME benchmark - VERSION 1.5.3 - GIT_REPOSITORY https://github.com/google/benchmark.git - GIT_TAG v1.5.3 - GIT_SHALLOW TRUE - OPTIONS "BENCHMARK_ENABLE_TESTING OFF" - "BENCHMARK_ENABLE_INSTALL OFF") + include(${rapids-cmake-dir}/cpm/gbench.cmake) + rapids_cpm_gbench() # Find or install NVBench Temporarily force downloading of fmt because current versions of nvbench # do not support the latest version of fmt, which is automatically pulled into our conda From 8d88bed89118786640ab4785b37872a2907188a2 Mon Sep 17 00:00:00 2001 From: Ray Douglass Date: Fri, 21 Jul 2023 10:04:42 -0400 Subject: [PATCH 60/63] v23.10 Updates [skip ci] --- .github/workflows/build.yaml | 12 ++++---- .github/workflows/pr.yaml | 20 ++++++------- .github/workflows/test.yaml | 6 ++-- ci/build_docs.sh | 2 +- .../all_cuda-118_arch-x86_64.yaml | 10 +++---- .../all_cuda-120_arch-x86_64.yaml | 10 +++---- cpp/CMakeLists.txt | 2 +- cpp/cuproj/CMakeLists.txt | 2 +- cpp/doxygen/Doxyfile | 4 +-- dependencies.yaml | 30 +++++++++---------- docs/source/conf.py | 4 +-- fetch_rapids.cmake | 2 +- python/cuspatial/CMakeLists.txt | 2 +- python/cuspatial/cuspatial/__init__.py | 2 +- python/cuspatial/pyproject.toml | 10 +++---- 15 files changed, 59 insertions(+), 59 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a872e289f..b36dd86ea 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ concurrency: jobs: cpp-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -37,7 +37,7 @@ jobs: python-build: needs: [cpp-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -46,7 +46,7 @@ jobs: upload-conda: needs: [cpp-build, python-build] secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-upload-packages.yaml@branch-23.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -56,7 +56,7 @@ jobs: if: github.ref_type == 'branch' needs: python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.10 with: arch: "amd64" branch: ${{ inputs.branch }} @@ -68,7 +68,7 @@ jobs: sha: ${{ inputs.sha }} wheel-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -80,7 +80,7 @@ jobs: wheel-publish: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 53cc04bd2..6c63e1046 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -22,40 +22,40 @@ jobs: - wheel-build - wheel-tests secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.10 checks: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@branch-23.10 with: enable_check_generated_files: false conda-cpp-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-build.yaml@branch-23.10 with: build_type: pull-request conda-cpp-tests: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.10 with: build_type: pull-request conda-python-build: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-build.yaml@branch-23.10 with: build_type: pull-request conda-python-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.10 with: build_type: pull-request conda-notebook-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.10 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -65,7 +65,7 @@ jobs: docs-build: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/custom-job.yaml@branch-23.10 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -75,7 +75,7 @@ jobs: wheel-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.10 with: build_type: pull-request package-dir: python/cuspatial @@ -84,7 +84,7 @@ jobs: wheel-tests: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.10 with: build_type: pull-request package-name: cuspatial diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 00a4c0446..d2ec061ab 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,7 +16,7 @@ on: jobs: conda-cpp-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-cpp-tests.yaml@branch-23.10 with: build_type: nightly branch: ${{ inputs.branch }} @@ -24,7 +24,7 @@ jobs: sha: ${{ inputs.sha }} conda-python-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/conda-python-tests.yaml@branch-23.10 with: build_type: nightly branch: ${{ inputs.branch }} @@ -32,7 +32,7 @@ jobs: sha: ${{ inputs.sha }} wheel-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.10 with: build_type: nightly branch: ${{ inputs.branch }} diff --git a/ci/build_docs.sh b/ci/build_docs.sh index c4f318f26..bea85b9dc 100755 --- a/ci/build_docs.sh +++ b/ci/build_docs.sh @@ -26,7 +26,7 @@ rapids-mamba-retry install \ libcuspatial \ cuspatial -export RAPIDS_VERSION_NUMBER="23.08" +export RAPIDS_VERSION_NUMBER="23.10" export RAPIDS_DOCS_DIR="$(mktemp -d)" rapids-logger "Build CPP docs" diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index a6a12dc2e..1b743a7b1 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -10,8 +10,8 @@ dependencies: - cmake>=3.26.4 - cuda-version=11.8 - cudatoolkit -- cudf==23.8.* -- cuml==23.8.* +- cudf==23.10.* +- cuml==23.10.* - cxx-compiler - cython>=0.29,<0.30 - doxygen @@ -21,8 +21,8 @@ dependencies: - gtest>=1.13.0 - ipython - ipywidgets -- libcudf==23.8.* -- librmm==23.8.* +- libcudf==23.10.* +- librmm==23.10.* - myst-parser - nbsphinx - ninja @@ -37,7 +37,7 @@ dependencies: - pytest-cov - pytest-xdist - python>=3.9,<3.11 -- rmm==23.8.* +- rmm==23.10.* - scikit-build>=0.13.1 - scikit-image - setuptools diff --git a/conda/environments/all_cuda-120_arch-x86_64.yaml b/conda/environments/all_cuda-120_arch-x86_64.yaml index b385a9e14..30b8ecd2f 100644 --- a/conda/environments/all_cuda-120_arch-x86_64.yaml +++ b/conda/environments/all_cuda-120_arch-x86_64.yaml @@ -12,8 +12,8 @@ dependencies: - cuda-nvcc - cuda-nvrtc-dev - cuda-version=12.0 -- cudf==23.8.* -- cuml==23.8.* +- cudf==23.10.* +- cuml==23.10.* - cxx-compiler - cython>=0.29,<0.30 - doxygen @@ -23,8 +23,8 @@ dependencies: - gtest>=1.13.0 - ipython - ipywidgets -- libcudf==23.8.* -- librmm==23.8.* +- libcudf==23.10.* +- librmm==23.10.* - myst-parser - nbsphinx - ninja @@ -38,7 +38,7 @@ dependencies: - pytest-cov - pytest-xdist - python>=3.9,<3.11 -- rmm==23.8.* +- rmm==23.10.* - scikit-build>=0.13.1 - scikit-image - setuptools diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index f71a2f120..e35232147 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -25,7 +25,7 @@ include(rapids-find) rapids_cuda_init_architectures(CUSPATIAL) -project(CUSPATIAL VERSION 23.08.00 LANGUAGES C CXX CUDA) +project(CUSPATIAL VERSION 23.10.00 LANGUAGES C CXX CUDA) # Needed because GoogleBenchmark changes the state of FindThreads.cmake, # causing subsequent runs to have different values for the `Threads::Threads` target. diff --git a/cpp/cuproj/CMakeLists.txt b/cpp/cuproj/CMakeLists.txt index 57be97a19..18646bbf0 100644 --- a/cpp/cuproj/CMakeLists.txt +++ b/cpp/cuproj/CMakeLists.txt @@ -25,7 +25,7 @@ include(rapids-find) rapids_cuda_init_architectures(CUPROJ) -project(CUPROJ VERSION 23.08.00 LANGUAGES C CXX CUDA) +project(CUPROJ VERSION 23.10.00 LANGUAGES C CXX CUDA) # Needed because GoogleBenchmark changes the state of FindThreads.cmake, # causing subsequent runs to have different values for the `Threads::Threads` target. diff --git a/cpp/doxygen/Doxyfile b/cpp/doxygen/Doxyfile index 2c3b7bb66..0a37670cf 100644 --- a/cpp/doxygen/Doxyfile +++ b/cpp/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "libcuspatial" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 23.08.00 +PROJECT_NUMBER = 23.10.00 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -2171,7 +2171,7 @@ SKIP_FUNCTION_MACROS = YES # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = rmm.tag=https://docs.rapids.ai/api/librmm/23.08 "libcudf.tag=https://docs.rapids.ai/api/libcudf/23.08" +TAGFILES = rmm.tag=https://docs.rapids.ai/api/librmm/23.10 "libcudf.tag=https://docs.rapids.ai/api/libcudf/23.10" # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to diff --git a/dependencies.yaml b/dependencies.yaml index 66f19f6a1..f355a5de9 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -83,8 +83,8 @@ dependencies: - cxx-compiler - gmock>=1.13.0 - gtest>=1.13.0 - - libcudf==23.8.* - - librmm==23.8.* + - libcudf==23.10.* + - librmm==23.10.* - proj - sqlite specific: @@ -126,8 +126,8 @@ dependencies: - setuptools - output_types: conda packages: &build_python_packages_conda - - &cudf_conda cudf==23.8.* - - &rmm_conda rmm==23.8.* + - &cudf_conda cudf==23.10.* + - &rmm_conda rmm==23.10.* - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -150,12 +150,12 @@ dependencies: matrices: - matrix: {cuda: "12.0"} packages: - - cudf-cu12==23.8.* - - rmm-cu12==23.8.* + - cudf-cu12==23.10.* + - rmm-cu12==23.10.* - matrix: {cuda: "11.8"} packages: &build_python_packages_cu11 - - &cudf_cu11 cudf-cu11==23.8.* - - &rmm_cu11 rmm-cu11==23.8.* + - &cudf_cu11 cudf-cu11==23.10.* + - &rmm_cu11 rmm-cu11==23.10.* - {matrix: {cuda: "11.5"}, packages: *build_python_packages_cu11} - {matrix: {cuda: "11.4"}, packages: *build_python_packages_cu11} - {matrix: {cuda: "11.2"}, packages: *build_python_packages_cu11} @@ -226,17 +226,17 @@ dependencies: - scikit-image - output_types: conda packages: - - &cuml_conda cuml==23.8.* + - &cuml_conda cuml==23.10.* specific: - output_types: [requirements, pyproject] matrices: - {matrix: null, packages: [*cuml_conda]} - matrix: {cuda: "12.0"} packages: - - cuml-cu12==23.8.* + - cuml-cu12==23.10.* - matrix: {cuda: "11.8"} packages: ¬ebooks_packages_cu11 - - &cuml_cu11 cuml-cu11==23.8.* + - &cuml_cu11 cuml-cu11==23.10.* - {matrix: {cuda: "11.5"}, packages: *notebooks_packages_cu11} - {matrix: {cuda: "11.4"}, packages: *notebooks_packages_cu11} - {matrix: {cuda: "11.2"}, packages: *notebooks_packages_cu11} @@ -274,12 +274,12 @@ dependencies: matrices: - matrix: {cuda: "12.0"} packages: - - cudf-cu12==23.8.* - - rmm-cu12==23.8.* + - cudf-cu12==23.10.* + - rmm-cu12==23.10.* - matrix: {cuda: "11.8"} packages: &run_python_packages_cu11 - - cudf-cu11==23.8.* - - rmm-cu11==23.8.* + - cudf-cu11==23.10.* + - rmm-cu11==23.10.* - {matrix: {cuda: "11.5"}, packages: *run_python_packages_cu11} - {matrix: {cuda: "11.4"}, packages: *run_python_packages_cu11} - {matrix: {cuda: "11.2"}, packages: *run_python_packages_cu11} diff --git a/docs/source/conf.py b/docs/source/conf.py index 6851fe052..89d88301a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -50,9 +50,9 @@ # built documents. # # The short X.Y version. -version = '23.08' +version = '23.10' # The full version, including alpha/beta/rc tags. -release = '23.08.00' +release = '23.10.00' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/fetch_rapids.cmake b/fetch_rapids.cmake index 99da99888..0d7bf678a 100644 --- a/fetch_rapids.cmake +++ b/fetch_rapids.cmake @@ -11,7 +11,7 @@ # or implied. See the License for the specific language governing permissions and limitations under # the License. # ============================================================================= -file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-23.08/RAPIDS.cmake +file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-23.10/RAPIDS.cmake ${CMAKE_BINARY_DIR}/RAPIDS.cmake ) include(${CMAKE_BINARY_DIR}/RAPIDS.cmake) diff --git a/python/cuspatial/CMakeLists.txt b/python/cuspatial/CMakeLists.txt index bf9f575a8..7ef7f58af 100644 --- a/python/cuspatial/CMakeLists.txt +++ b/python/cuspatial/CMakeLists.txt @@ -14,7 +14,7 @@ cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR) -set(cuspatial_version 23.08.00) +set(cuspatial_version 23.10.00) include(../../fetch_rapids.cmake) include(rapids-cuda) diff --git a/python/cuspatial/cuspatial/__init__.py b/python/cuspatial/cuspatial/__init__.py index d8f07d5d0..cd11e4950 100644 --- a/python/cuspatial/cuspatial/__init__.py +++ b/python/cuspatial/cuspatial/__init__.py @@ -29,4 +29,4 @@ ) from .io.geopandas import from_geopandas -__version__ = "23.08.00" +__version__ = "23.10.00" diff --git a/python/cuspatial/pyproject.toml b/python/cuspatial/pyproject.toml index 8db1ffa61..80ea51489 100644 --- a/python/cuspatial/pyproject.toml +++ b/python/cuspatial/pyproject.toml @@ -16,10 +16,10 @@ build-backend = "setuptools.build_meta" requires = [ "cmake>=3.26.4", - "cudf==23.8.*", + "cudf==23.10.*", "cython>=0.29,<0.30", "ninja", - "rmm==23.8.*", + "rmm==23.10.*", "scikit-build>=0.13.1", "setuptools", "wheel", @@ -27,7 +27,7 @@ requires = [ [project] name = "cuspatial" -version = "23.8.0" +version = "23.10.0" description = "cuSpatial: GPU-Accelerated Spatial and Trajectory Data Management and Analytics Library" readme = { file = "README.md", content-type = "text/markdown" } authors = [ @@ -36,9 +36,9 @@ authors = [ license = { text = "Apache 2.0" } requires-python = ">=3.9" dependencies = [ - "cudf==23.8.*", + "cudf==23.10.*", "geopandas>=0.11.0", - "rmm==23.8.*", + "rmm==23.10.*", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. classifiers = [ "Intended Audience :: Developers", From 7cacad25c02be1d4ff38daee619b5a1d874c59b5 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 21 Jul 2023 10:47:43 -0500 Subject: [PATCH 61/63] Use Google Benchmark from rapids-cmake in cuproj. (#1225) Follow-up to #1224 for cuproj. Authors: - Bradley Dice (https://github.com/bdice) Approvers: - Robert Maynard (https://github.com/robertmaynard) URL: https://github.com/rapidsai/cuspatial/pull/1225 --- cpp/cuproj/CMakeLists.txt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cpp/cuproj/CMakeLists.txt b/cpp/cuproj/CMakeLists.txt index 57be97a19..585ffe0aa 100644 --- a/cpp/cuproj/CMakeLists.txt +++ b/cpp/cuproj/CMakeLists.txt @@ -175,13 +175,8 @@ endif() if(CUPROJ_BUILD_BENCHMARKS) # Find or install GoogleBench - CPMFindPackage(NAME benchmark - VERSION 1.5.3 - GIT_REPOSITORY https://github.com/google/benchmark.git - GIT_TAG v1.5.3 - GIT_SHALLOW TRUE - OPTIONS "BENCHMARK_ENABLE_TESTING OFF" - "BENCHMARK_ENABLE_INSTALL OFF") + include(${rapids-cmake-dir}/cpm/gbench.cmake) + rapids_cpm_gbench() # Find or install NVBench Temporarily force downloading of fmt because current versions of nvbench # do not support the latest version of fmt, which is automatically pulled into our conda From 8ee773c4075716ccff862751cf92c70b7a5847fa Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 26 Jul 2023 00:15:01 +0800 Subject: [PATCH 62/63] Sort the mergeable segments before computing merged segments (#1207) This PR is part-1 fix to \#1200. In `find_and_combine_segments` the N^2 algorithm depends on the fact that the API needs to be presorted with certain criteria. This Pr adds such sorting. Authors: - Michael Wang (https://github.com/isVoid) Approvers: - Mark Harris (https://github.com/harrism) - H. Thomson Comer (https://github.com/thomcom) URL: https://github.com/rapidsai/cuspatial/pull/1207 --- .../detail/algorithm/is_point_in_polygon.cuh | 4 +- .../detail/find/find_and_combine_segment.cuh | 64 ++++++++++++++++++- .../cuspatial/detail/utility/linestring.cuh | 12 ++-- cpp/include/cuspatial/geometry/segment.cuh | 14 ++++ .../find/find_and_combine_segments_test.cu | 64 ++++++++++++++++++- .../linestring_intersection_large_test.cu | 2 + .../tests/binpreds/test_contains_properly.py | 2 +- 7 files changed, 151 insertions(+), 11 deletions(-) diff --git a/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh b/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh index 54ad6b499..9e8d6583c 100644 --- a/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh +++ b/cpp/include/cuspatial/detail/algorithm/is_point_in_polygon.cuh @@ -68,8 +68,8 @@ __device__ inline bool is_point_in_polygon(vec_2d const& test_point, PolygonR T run_to_point = test_point.x - a.x; // point-on-edge test - bool is_colinear = float_equal(run * rise_to_point, run_to_point * rise); - if (is_colinear) { + bool is_collinear = float_equal(run * rise_to_point, run_to_point * rise); + if (is_collinear) { T minx = a.x; T maxx = b.x; if (minx > maxx) thrust::swap(minx, maxx); diff --git a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh index 0142f680e..5694088ad 100644 --- a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh +++ b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh @@ -19,12 +19,14 @@ #include #include #include +#include #include #include #include +#include #include namespace cuspatial { @@ -32,7 +34,18 @@ namespace detail { /** * @internal - * @brief Kernel to merge segments, naive n^2 algorithm. + * @pre All segments in range @p segments , it is presorted using `segment_comparator`. + * + * @brief Kernel to merge segments. Each thread works on one segment space, within each space, + * `segment_comparator` guarantees that segments with same slope are grouped together. We call + * each of such group is a "mergeable group". Within each mergeable group, the first segment is + * the "leading segment". The algorithm behave as follows: + * + * 1. For each mergeable group, loop over the rest of the segments in the group and see if it is + * mergeable with the leading segment. If it is, overwrite the leading segment with the merged + * result. Then mark the segment as merged by setting the flag to 1. This makes sure the inner loop + * for each merged segment is not run again. + * 2. Repeat 1 until all mergeable group is processed. */ template void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, @@ -45,6 +58,9 @@ void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, merged_flag[i] = 0; } + // For each of the segment, loop over the rest of the segment in the space and see + // if it is mergeable with the current segment. + // Note that if the current segment is already merged. Skip checking. for (auto i = offsets[pair_idx]; i < offsets[pair_idx + 1] && merged_flag[i] != 1; i++) { for (auto j = i + 1; j < offsets[pair_idx + 1]; j++) { auto res = maybe_merge_segments(segments[i], segments[j]); @@ -58,10 +74,44 @@ void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, } } +/** + * @brief Comparator for sorting the segment range. + * + * This comparator makes sure that the segment range is sorted such that: + * 1. Segments with the same space id are grouped together. + * 2. Segments within the same space are grouped by their slope. + * 3. Within each slope group, segments are sorted by their lower left point. + */ +template +struct segment_comparator { + bool __device__ operator()(thrust::tuple> const& lhs, + thrust::tuple> const& rhs) const + { + auto lhs_index = thrust::get<0>(lhs); + auto rhs_index = thrust::get<0>(rhs); + auto lhs_segment = thrust::get<1>(lhs); + auto rhs_segment = thrust::get<1>(rhs); + + // Compare space id + if (lhs_index == rhs_index) { + // Compare slope + if (lhs_segment.collinear(rhs_segment)) { + // Sort by the lower left point of the segment. + return lhs_segment.lower_left() < rhs_segment.lower_left(); + } + return lhs_segment.slope() < rhs_segment.slope(); + } + return lhs_index < rhs_index; + } +}; + /** * @internal * @brief For each pair of mergeable segment, overwrites the first segment with merged result, * sets the flag for the second segment as 1. + * + * @note This function will alter the input segment range by rearranging the order of the segments + * within each space so that merging kernel can take place. */ template void find_and_combine_segment(OffsetRange offsets, @@ -69,9 +119,21 @@ void find_and_combine_segment(OffsetRange offsets, OutputIt merged_flag, rmm::cuda_stream_view stream) { + using index_t = typename OffsetRange::value_type; + using T = typename SegmentRange::value_type::value_type; auto num_spaces = offsets.size() - 1; if (num_spaces == 0) return; + // Construct a key iterator using the offsets of the segment and the segment itself. + auto space_id_iter = make_geometry_id_iterator(offsets.begin(), offsets.end()); + auto space_id_segment_iter = thrust::make_zip_iterator(space_id_iter, segments.begin()); + + thrust::sort_by_key(rmm::exec_policy(stream), + space_id_segment_iter, + space_id_segment_iter + segments.size(), + segments.begin(), + segment_comparator{}); + auto [threads_per_block, num_blocks] = grid_1d(num_spaces); simple_find_and_combine_segments_kernel<<>>( offsets, segments, merged_flag); diff --git a/cpp/include/cuspatial/detail/utility/linestring.cuh b/cpp/include/cuspatial/detail/utility/linestring.cuh index 94180a5df..239a100f8 100644 --- a/cpp/include/cuspatial/detail/utility/linestring.cuh +++ b/cpp/include/cuspatial/detail/utility/linestring.cuh @@ -93,10 +93,10 @@ __forceinline__ T __device__ point_to_segment_distance_squared(vec_2d const& * @brief Computes shortest distance between two segments (ab and cd) that don't intersect. */ template -__forceinline__ T __device__ segment_distance_no_intersect_or_colinear(vec_2d const& a, - vec_2d const& b, - vec_2d const& c, - vec_2d const& d) +__forceinline__ T __device__ segment_distance_no_intersect_or_collinear(vec_2d const& a, + vec_2d const& b, + vec_2d const& c, + vec_2d const& d) { auto dist_sqr = min( min(point_to_segment_distance_squared(a, c, d), point_to_segment_distance_squared(b, c, d)), @@ -123,7 +123,7 @@ __forceinline__ T __device__ squared_segment_distance(vec_2d const& a, if (float_equal(denom, T{0})) { // Segments parallel or collinear - return segment_distance_no_intersect_or_colinear(a, b, c, d); + return segment_distance_no_intersect_or_collinear(a, b, c, d); } auto ac = c - a; @@ -132,7 +132,7 @@ __forceinline__ T __device__ squared_segment_distance(vec_2d const& a, auto r = r_numer * denom_reciprocal; auto s = det(ac, ab) * denom_reciprocal; if (r >= 0 and r <= 1 and s >= 0 and s <= 1) { return 0.0; } - return segment_distance_no_intersect_or_colinear(a, b, c, d); + return segment_distance_no_intersect_or_collinear(a, b, c, d); } /** diff --git a/cpp/include/cuspatial/geometry/segment.cuh b/cpp/include/cuspatial/geometry/segment.cuh index 9cfaf3b8e..bc2ce86e8 100644 --- a/cpp/include/cuspatial/geometry/segment.cuh +++ b/cpp/include/cuspatial/geometry/segment.cuh @@ -55,6 +55,20 @@ class alignas(sizeof(Vertex)) segment { /// Return the length squared of segment. T CUSPATIAL_HOST_DEVICE length2() const { return dot(v2 - v1, v2 - v1); } + /// Return slope of segment. + T CUSPATIAL_HOST_DEVICE slope() { return (v2.y - v1.y) / (v2.x - v1.x); } + + /// Return the lower left vertex of segment. + Vertex CUSPATIAL_HOST_DEVICE lower_left() { return v1 < v2 ? v1 : v2; } + + /// Returns true if two segments are on the same line + /// Test if the determinant of the matrix, of which the column vector is constructed from the + /// segments is 0. + bool CUSPATIAL_HOST_DEVICE collinear(segment const& other) + { + return (v1.x - v2.x) * (other.v1.y - other.v2.y) == (v1.y - v2.y) * (other.v1.x - other.v2.x); + } + private: friend std::ostream& operator<<(std::ostream& os, segment const& seg) { diff --git a/cpp/tests/find/find_and_combine_segments_test.cu b/cpp/tests/find/find_and_combine_segments_test.cu index ea01d7e53..f7a584f51 100644 --- a/cpp/tests/find/find_and_combine_segments_test.cu +++ b/cpp/tests/find/find_and_combine_segments_test.cu @@ -279,5 +279,67 @@ TYPED_TEST(FindAndCombineSegmentsTest, nooverlap3) CUSPATIAL_RUN_TEST(this->run_single_test, segments, {0, 0}, - {S{P{0.0, 0.0}, P{1.0, 1.0}}, S{P{0.0, 1.0}, P{1.0, 0.0}}}); + {S{P{0.0, 1.0}, P{1.0, 0.0}}, S{P{0.0, 0.0}, P{1.0, 1.0}}}); +} + +TYPED_TEST(FindAndCombineSegmentsTest, twospaces) +{ + using T = TypeParam; + using index_t = std::size_t; + using P = vec_2d; + using S = segment; + + auto segments = make_segment_array({0, 2, 4}, + {S{P{0.0, 0.0}, P{1.0, 1.0}}, + S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{1.0, 1.0}, P{0.0, 0.0}}, + S{P{2.0, 2.0}, P{1.0, 1.0}}}); + + CUSPATIAL_RUN_TEST(this->run_single_test, + segments, + {0, 1, 0, 1}, + {S{P{0.0, 0.0}, P{2.0, 2.0}}, + S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{0.0, 0.0}, P{2.0, 2.0}}, + S{P{2.0, 2.0}, P{1.0, 1.0}}}); +} + +TYPED_TEST(FindAndCombineSegmentsTest, twospaces_non_contiguous_segments_with_empty) +{ + using T = TypeParam; + using index_t = std::size_t; + using P = vec_2d; + using S = segment; + + auto segments = make_segment_array({0, 4, 4}, + {S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{3.0, 3.0}, P{4.0, 4.0}}, + S{P{0.0, 0.0}, P{1.0, 1.0}}, + S{P{2.0, 2.0}, P{3.0, 3.0}}}); + + CUSPATIAL_RUN_TEST(this->run_single_test, + segments, + {0, 1, 1, 1}, + {S{P{0.0, 0.0}, P{4.0, 4.0}}, + S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{2.0, 2.0}, P{3.0, 3.0}}, + S{P{3.0, 3.0}, P{4.0, 4.0}}}); +} + +TYPED_TEST(FindAndCombineSegmentsTest, onespace_non_contiguous_segments_overlaps) +{ + using T = TypeParam; + using index_t = std::size_t; + using P = vec_2d; + using S = segment; + + auto segments = make_segment_array( + {0, 3}, + {S{P{1.0, 1.0}, P{2.0, 2.0}}, S{P{4.0, 4.0}, P{5.0, 5.0}}, S{P{-1.0, -1.0}, P{4.0, 4.0}}}); + + CUSPATIAL_RUN_TEST( + this->run_single_test, + segments, + {0, 1, 1}, + {S{P{-1.0, -1.0}, P{5.0, 5.0}}, S{P{1.0, 1.0}, P{2.0, 2.0}}, S{P{4.0, 4.0}, P{5.0, 5.0}}}); } diff --git a/cpp/tests/intersection/linestring_intersection_large_test.cu b/cpp/tests/intersection/linestring_intersection_large_test.cu index aed4c00f3..9c5833aa2 100644 --- a/cpp/tests/intersection/linestring_intersection_large_test.cu +++ b/cpp/tests/intersection/linestring_intersection_large_test.cu @@ -27,6 +27,8 @@ #include #include +#include + #include template diff --git a/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py b/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py index e3a67df6c..a50094737 100644 --- a/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py +++ b/python/cuspatial/cuspatial/tests/binpreds/test_contains_properly.py @@ -131,7 +131,7 @@ def test_float_precision_limits(point, polygon, expects): Unique success cases identified by @mharris. These go in a pair with test_float_precision_limits_failures because these are inconsistent results, where 0.6 fails above (as True, within the - polygon) and 0.66 below succeeds, though they are colinear. + polygon) and 0.66 below succeeds, though they are collinear. """ gpdpoint = gpd.GeoSeries(point) gpdpolygon = gpd.GeoSeries(polygon) From e8d2145f42ff252c0d466b4e83a52f74c7ad6948 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Tue, 25 Jul 2023 12:24:59 -0700 Subject: [PATCH 63/63] Switch to new wheel building pipeline (#1227) Moves the wheel build and test logic out of the workflow into the repo. This matches conda tests more closely and allows each repo to manage its own wheels more easily. Authors: - Vyas Ramasubramani (https://github.com/vyasr) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/cuspatial/pull/1227 --- .github/workflows/build.yaml | 8 +++----- .github/workflows/pr.yaml | 14 ++++---------- .github/workflows/test.yaml | 7 ++----- ci/build_wheel.sh | 26 ++++++++++++++++++++++++++ ci/test_wheel.sh | 22 ++++++++++++++++++++++ 5 files changed, 57 insertions(+), 20 deletions(-) create mode 100755 ci/build_wheel.sh create mode 100755 ci/test_wheel.sh diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a872e289f..ebe3619b1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -68,19 +68,17 @@ jobs: sha: ${{ inputs.sha }} wheel-build: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-build.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} sha: ${{ inputs.sha }} date: ${{ inputs.date }} - package-name: cuspatial - package-dir: python/cuspatial - skbuild-configure-options: "-DCUSPATIAL_BUILD_WHEELS=ON" + script: ci/build_wheel.sh wheel-publish: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-publish.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-publish.yaml@branch-23.08 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 53cc04bd2..c5300ccd5 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -75,20 +75,14 @@ jobs: wheel-build: needs: checks secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-build.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-build.yaml@branch-23.08 with: build_type: pull-request - package-dir: python/cuspatial - package-name: cuspatial - skbuild-configure-options: "-DCUSPATIAL_BUILD_WHEELS=ON" + script: ci/build_wheel.sh wheel-tests: needs: wheel-build secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-test.yaml@branch-23.08 with: build_type: pull-request - package-name: cuspatial - test-smoketest: "python ./ci/wheel_smoke_test.py" - test-unittest: "python -m pytest -n 8 ./python/cuspatial/cuspatial/tests" - test-before-amd64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" - test-before-arm64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" + script: ci/test_wheel.sh diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 00a4c0446..5c058f38c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -32,13 +32,10 @@ jobs: sha: ${{ inputs.sha }} wheel-tests: secrets: inherit - uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux-test.yml@branch-23.08 + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-test.yaml@branch-23.08 with: build_type: nightly branch: ${{ inputs.branch }} date: ${{ inputs.date }} sha: ${{ inputs.sha }} - package-name: cuspatial - test-unittest: "python -m pytest -n 8 ./python/cuspatial/cuspatial/tests" - test-before-amd64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" - test-before-arm64: "apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev && python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9'" + script: ci/test_wheel.sh diff --git a/ci/build_wheel.sh b/ci/build_wheel.sh new file mode 100755 index 000000000..34924f48b --- /dev/null +++ b/ci/build_wheel.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright (c) 2023, NVIDIA CORPORATION. + +set -euo pipefail + +source rapids-configure-sccache +source rapids-date-string + +# Use gha-tools rapids-pip-wheel-version to generate wheel version then +# update the necessary files +version_override="$(rapids-pip-wheel-version ${RAPIDS_DATE_STRING})" + +RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" + +ci/release/apply_wheel_modifications.sh ${version_override} "-${RAPIDS_PY_CUDA_SUFFIX}" +echo "The package name and/or version was modified in the package source. The git diff is:" +git diff + +cd python/cuspatial + +SKBUILD_CONFIGURE_OPTIONS="-DCUSPATIAL_BUILD_WHEELS=ON" python -m pip wheel . -w dist -vvv --no-deps --disable-pip-version-check + +mkdir -p final_dist +python -m auditwheel repair -w final_dist dist/* + +RAPIDS_PY_WHEEL_NAME="cuspatial_${RAPIDS_PY_CUDA_SUFFIX}" rapids-upload-wheels-to-s3 final_dist diff --git a/ci/test_wheel.sh b/ci/test_wheel.sh new file mode 100755 index 000000000..8efc79545 --- /dev/null +++ b/ci/test_wheel.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright (c) 2023, NVIDIA CORPORATION. + +set -eou pipefail + +mkdir -p ./dist +RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" +RAPIDS_PY_WHEEL_NAME="cuspatial_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./dist + +# Install additional dependencies +apt update +DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgdal-dev +python -m pip install --no-binary fiona 'fiona>=1.8.19,<1.9' + +# echo to expand wildcard before adding `[extra]` requires for pip +python -m pip install $(echo ./dist/cuspatial*.whl)[test] + +if [[ "$(arch)" == "aarch64" && ${RAPIDS_BUILD_TYPE} == "pull-request" ]]; then + python ./ci/wheel_smoke_test.py +else + python -m pytest -n 8 ./python/cuspatial/cuspatial/tests +fi