From b4d8a6b0a36d6a458209dca96d34d6a5c2fbe8ea Mon Sep 17 00:00:00 2001 From: Pierre Yver Date: Thu, 13 Jul 2023 11:16:54 +0200 Subject: [PATCH] samples updates for 405 (#575) --- CMakeLists.txt | 1 - .../body tracking/cpp/src/TrackingViewer.cpp | 3 - body tracking/body tracking/cpp/src/main.cpp | 2 +- .../body tracking/csharp/GLViewer.cs | 109 +- .../body tracking/csharp/MainWindow.cs | 2 +- .../body tracking/csharp/TrackingViewer.cs | 138 +- .../python/cv_viewer/tracking_viewer.py | 2 - .../body tracking/python/ogl_viewer/viewer.py | 2 - .../JSON export/python/ogl_viewer/viewer.py | 2 - .../multi-camera/cpp/src/GLViewer.cpp | 6 - .../multi-camera/python/ogl_viewer/viewer.py | 4 +- .../cpp/src/GLViewer.cpp | 2 - .../advanced point cloud mapping/README.md | 9 - .../cpp/CMakeLists.txt | 57 - .../cpp/README.md | 24 - .../cpp/include/GLViewer.hpp | 266 -- .../cpp/include/ZEDModel.hpp | 2791 ----------------- .../cpp/src/GLViewer.cpp | 768 ----- .../cpp/src/main.cpp | 215 -- .../fused_point_cloud.jpg | Bin 232946 -> 0 bytes spatial mapping/spatial mapping/README.md | 19 +- .../spatial mapping/cpp/CMakeLists.txt | 23 +- .../spatial mapping/cpp/include/GLViewer.hpp | 344 +- .../spatial mapping/cpp/src/GLViewer.cpp | 1246 +++++--- .../spatial mapping/cpp/src/main.cpp | 268 +- .../spatial mapping/csharp/MainWindow.cs | 33 +- tutorials/tutorial 1 - hello ZED/c/main.c | 2 + tutorials/tutorial 2 - image capture/c/main.c | 1 + tutorials/tutorial 3 - depth sensing/c/main.c | 1 + .../tutorial 4 - positional tracking/c/main.c | 1 + .../tutorial 5 - spatial mapping/c/main.c | 1 + .../tutorial 6 - object detection/c/main.c | 1 + tutorials/tutorial 7 - sensor data/c/main.c | 1 + tutorials/tutorial 8 - body tracking/c/main.c | 1 + .../csharp/Program.cs | 2 +- 35 files changed, 1237 insertions(+), 5110 deletions(-) delete mode 100644 spatial mapping/advanced point cloud mapping/README.md delete mode 100644 spatial mapping/advanced point cloud mapping/cpp/CMakeLists.txt delete mode 100644 spatial mapping/advanced point cloud mapping/cpp/README.md delete mode 100644 spatial mapping/advanced point cloud mapping/cpp/include/GLViewer.hpp delete mode 100644 spatial mapping/advanced point cloud mapping/cpp/include/ZEDModel.hpp delete mode 100644 spatial mapping/advanced point cloud mapping/cpp/src/GLViewer.cpp delete mode 100644 spatial mapping/advanced point cloud mapping/cpp/src/main.cpp delete mode 100644 spatial mapping/advanced point cloud mapping/fused_point_cloud.jpg diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cf38c4e..b5914641 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,6 @@ add_subdirectory("plane detection/plane detection/${TYPE}") add_subdirectory("plane detection/floor plane/${TYPE}") add_subdirectory("positional tracking/positional tracking/${TYPE}") add_subdirectory("spatial mapping/spatial mapping/${TYPE}") -add_subdirectory("spatial mapping/advanced point cloud mapping/${TYPE}") add_subdirectory("recording/export/sensors/${TYPE}") add_subdirectory("recording/export/svo/${TYPE}") add_subdirectory("recording/playback/${TYPE}") diff --git a/body tracking/body tracking/cpp/src/TrackingViewer.cpp b/body tracking/body tracking/cpp/src/TrackingViewer.cpp index 24723b8d..d45b0bb5 100644 --- a/body tracking/body tracking/cpp/src/TrackingViewer.cpp +++ b/body tracking/body tracking/cpp/src/TrackingViewer.cpp @@ -44,7 +44,6 @@ void createSKPrimitive(sl::BodyData& body, const std::vector>&ma } - void render_2D(cv::Mat &left_display, sl::float2 img_scale, std::vector &bodies, bool isTrackingON, bool fastRender) { cv::Mat overlay = left_display.clone(); cv::Rect roi_render(0, 0, left_display.size().width, left_display.size().height); @@ -69,8 +68,6 @@ void render_2D(cv::Mat &left_display, sl::float2 img_scale, std::vector 0) { - if (body_format_ == BODY_FORMAT.POSE_38) + if (body_format_ == BODY_FORMAT.BODY_38) { - foreach (var limb in SKELETON_BONES_POSE_38) + foreach (var limb in SKELETON_BONES_BODY_38) { Vector3 kp_1 = keypoints[getIdx(limb.Item1)]; Vector3 kp_2 = keypoints[getIdx(limb.Item2)]; @@ -138,35 +138,7 @@ public void update(Mat pointCloud_, Bodies bodies, sl.Pose pose) } } } - else if (body_format_ == BODY_FORMAT.POSE_70) - { - foreach (var limb in BODY_BONES_POSE_70) - { - Vector3 kp_1 = keypoints[getIdx(limb.Item1)]; - Vector3 kp_2 = keypoints[getIdx(limb.Item2)]; - - float norm_1 = kp_1.Length(); - float norm_2 = kp_2.Length(); - - if (!float.IsNaN(norm_1) && norm_1 > 0 && !float.IsNaN(norm_2) && norm_2 > 0) - { - skeleton.addCylinder(new float3(kp_1.X, kp_1.Y, kp_1.Z), new float3(kp_2.X, kp_2.Y, kp_2.Z), clr_id); - } - } - - for (int i = 0; i < keypoints.Length; i++) - { - Vector3 kp = keypoints[i]; - float norm = kp.Length(); - - if (!float.IsNaN(norm) && norm > 0) - { - skeleton.addSphere(sphere, new float3(kp.X, kp.Y, kp.Z), clr_id); - } - } - } } - } } } @@ -380,12 +352,7 @@ int getIdx(BODY_38_PARTS part) return (int)(part); } - int getIdx(BODY_70_PARTS part) - { - return (int)(part); - } - - private static readonly Tuple[] SKELETON_BONES_POSE_38 = + public static readonly Tuple[] SKELETON_BONES_BODY_38 = { Tuple.Create(BODY_38_PARTS.PELVIS, BODY_38_PARTS.SPINE_1), Tuple.Create(BODY_38_PARTS.SPINE_1, BODY_38_PARTS.SPINE_2), @@ -426,76 +393,6 @@ int getIdx(BODY_70_PARTS part) Tuple.Create(BODY_38_PARTS.RIGHT_ANKLE, BODY_38_PARTS.RIGHT_SMALL_TOE) }; - private static readonly Tuple[] BODY_BONES_POSE_70 = - { - Tuple.Create(BODY_70_PARTS.PELVIS, BODY_70_PARTS.SPINE_1), - Tuple.Create(BODY_70_PARTS.SPINE_1, BODY_70_PARTS.SPINE_2), - Tuple.Create(BODY_70_PARTS.SPINE_2, BODY_70_PARTS.SPINE_3), - Tuple.Create(BODY_70_PARTS.SPINE_3, BODY_70_PARTS.NECK), - Tuple.Create(BODY_70_PARTS.PELVIS, BODY_70_PARTS.LEFT_HIP), - Tuple.Create(BODY_70_PARTS.PELVIS, BODY_70_PARTS.RIGHT_HIP), - Tuple.Create(BODY_70_PARTS.NECK, BODY_70_PARTS.NOSE), - Tuple.Create(BODY_70_PARTS.NECK, BODY_70_PARTS.LEFT_CLAVICLE), - Tuple.Create(BODY_70_PARTS.LEFT_CLAVICLE, BODY_70_PARTS.LEFT_SHOULDER), - Tuple.Create(BODY_70_PARTS.NECK, BODY_70_PARTS.RIGHT_CLAVICLE), - Tuple.Create(BODY_70_PARTS.RIGHT_CLAVICLE, BODY_70_PARTS.RIGHT_SHOULDER), - Tuple.Create(BODY_70_PARTS.NOSE, BODY_70_PARTS.LEFT_EYE), - Tuple.Create(BODY_70_PARTS.LEFT_EYE, BODY_70_PARTS.LEFT_EAR), - Tuple.Create(BODY_70_PARTS.NOSE, BODY_70_PARTS.RIGHT_EYE), - Tuple.Create(BODY_70_PARTS.RIGHT_EYE, BODY_70_PARTS.RIGHT_EAR), - Tuple.Create(BODY_70_PARTS.LEFT_SHOULDER, BODY_70_PARTS.LEFT_ELBOW), - Tuple.Create(BODY_70_PARTS.LEFT_ELBOW, BODY_70_PARTS.LEFT_WRIST), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_THUMB_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_THUMB_1, BODY_70_PARTS.LEFT_HAND_THUMB_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_THUMB_2, BODY_70_PARTS.LEFT_HAND_THUMB_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_THUMB_3, BODY_70_PARTS.LEFT_HAND_THUMB_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_INDEX_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_INDEX_1, BODY_70_PARTS.LEFT_HAND_INDEX_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_INDEX_2, BODY_70_PARTS.LEFT_HAND_INDEX_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_INDEX_3, BODY_70_PARTS.LEFT_HAND_INDEX_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_MIDDLE_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_MIDDLE_1, BODY_70_PARTS.LEFT_HAND_MIDDLE_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_MIDDLE_2, BODY_70_PARTS.LEFT_HAND_MIDDLE_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_MIDDLE_3, BODY_70_PARTS.LEFT_HAND_MIDDLE_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_RING_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_RING_1, BODY_70_PARTS.LEFT_HAND_RING_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_RING_2, BODY_70_PARTS.LEFT_HAND_RING_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_RING_3, BODY_70_PARTS.LEFT_HAND_RING_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_PINKY_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_PINKY_1, BODY_70_PARTS.LEFT_HAND_PINKY_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_PINKY_2, BODY_70_PARTS.LEFT_HAND_PINKY_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_PINKY_3, BODY_70_PARTS.LEFT_HAND_PINKY_4), - Tuple.Create(BODY_70_PARTS.RIGHT_SHOULDER, BODY_70_PARTS.RIGHT_ELBOW), - Tuple.Create(BODY_70_PARTS.RIGHT_ELBOW, BODY_70_PARTS.RIGHT_WRIST), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_THUMB_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_THUMB_1, BODY_70_PARTS.RIGHT_HAND_THUMB_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_THUMB_2, BODY_70_PARTS.RIGHT_HAND_THUMB_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_THUMB_3, BODY_70_PARTS.RIGHT_HAND_THUMB_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_INDEX_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_INDEX_1, BODY_70_PARTS.RIGHT_HAND_INDEX_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_INDEX_2, BODY_70_PARTS.RIGHT_HAND_INDEX_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_INDEX_3, BODY_70_PARTS.RIGHT_HAND_INDEX_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_MIDDLE_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_MIDDLE_1, BODY_70_PARTS.RIGHT_HAND_MIDDLE_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_MIDDLE_2, BODY_70_PARTS.RIGHT_HAND_MIDDLE_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_MIDDLE_3, BODY_70_PARTS.RIGHT_HAND_MIDDLE_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_RING_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_RING_1, BODY_70_PARTS.RIGHT_HAND_RING_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_RING_2, BODY_70_PARTS.RIGHT_HAND_RING_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_RING_3, BODY_70_PARTS.RIGHT_HAND_RING_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_PINKY_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_PINKY_1, BODY_70_PARTS.RIGHT_HAND_PINKY_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_PINKY_2, BODY_70_PARTS.RIGHT_HAND_PINKY_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_PINKY_3, BODY_70_PARTS.RIGHT_HAND_PINKY_4), - Tuple.Create(BODY_70_PARTS.LEFT_HIP, BODY_70_PARTS.LEFT_KNEE), - Tuple.Create(BODY_70_PARTS.LEFT_ANKLE, BODY_70_PARTS.LEFT_HEEL), - Tuple.Create(BODY_70_PARTS.LEFT_ANKLE, BODY_70_PARTS.LEFT_BIG_TOE), - Tuple.Create(BODY_70_PARTS.LEFT_ANKLE, BODY_70_PARTS.LEFT_SMALL_TOE), - Tuple.Create(BODY_70_PARTS.RIGHT_HIP, BODY_70_PARTS.RIGHT_KNEE), - Tuple.Create(BODY_70_PARTS.RIGHT_ANKLE, BODY_70_PARTS.RIGHT_HEEL), - Tuple.Create(BODY_70_PARTS.RIGHT_ANKLE, BODY_70_PARTS.RIGHT_BIG_TOE), - Tuple.Create(BODY_70_PARTS.RIGHT_ANKLE, BODY_70_PARTS.RIGHT_SMALL_TOE) - }; public void exit() { diff --git a/body tracking/body tracking/csharp/MainWindow.cs b/body tracking/body tracking/csharp/MainWindow.cs index 4c4f12db..26bd3ba4 100644 --- a/body tracking/body tracking/csharp/MainWindow.cs +++ b/body tracking/body tracking/csharp/MainWindow.cs @@ -96,7 +96,7 @@ public MainWindow(string[] args) bt_params.enableBodyFitting = true; // smooth skeletons moves bt_params.imageSync = true; // the body tracking is synchronized to the image bt_params.detectionModel = sl.BODY_TRACKING_MODEL.HUMAN_BODY_ACCURATE; - bt_params.bodyFormat = sl.BODY_FORMAT.POSE_38; + bt_params.bodyFormat = sl.BODY_FORMAT.BODY_38; zedCamera.EnableBodyTracking(ref bt_params); diff --git a/body tracking/body tracking/csharp/TrackingViewer.cs b/body tracking/body tracking/csharp/TrackingViewer.cs index 249a3151..9fe77212 100644 --- a/body tracking/body tracking/csharp/TrackingViewer.cs +++ b/body tracking/body tracking/csharp/TrackingViewer.cs @@ -11,118 +11,6 @@ public class TrackingViewer { - private static readonly Tuple[] SKELETON_BONES_POSE_38 = - { - Tuple.Create(BODY_38_PARTS.PELVIS, BODY_38_PARTS.SPINE_1), - Tuple.Create(BODY_38_PARTS.SPINE_1, BODY_38_PARTS.SPINE_2), - Tuple.Create(BODY_38_PARTS.SPINE_2, BODY_38_PARTS.SPINE_3), - Tuple.Create(BODY_38_PARTS.SPINE_3, BODY_38_PARTS.NECK), - Tuple.Create(BODY_38_PARTS.PELVIS, BODY_38_PARTS.LEFT_HIP), - Tuple.Create(BODY_38_PARTS.PELVIS, BODY_38_PARTS.RIGHT_HIP), - Tuple.Create(BODY_38_PARTS.NECK, BODY_38_PARTS.NOSE), - Tuple.Create(BODY_38_PARTS.NECK, BODY_38_PARTS.LEFT_CLAVICLE), - Tuple.Create(BODY_38_PARTS.LEFT_CLAVICLE, BODY_38_PARTS.LEFT_SHOULDER), - Tuple.Create(BODY_38_PARTS.NECK, BODY_38_PARTS.RIGHT_CLAVICLE), - Tuple.Create(BODY_38_PARTS.RIGHT_CLAVICLE, BODY_38_PARTS.RIGHT_SHOULDER), - Tuple.Create(BODY_38_PARTS.NOSE, BODY_38_PARTS.LEFT_EYE), - Tuple.Create(BODY_38_PARTS.LEFT_EYE, BODY_38_PARTS.LEFT_EAR), - Tuple.Create(BODY_38_PARTS.NOSE, BODY_38_PARTS.RIGHT_EYE), - Tuple.Create(BODY_38_PARTS.RIGHT_EYE, BODY_38_PARTS.RIGHT_EAR), - Tuple.Create(BODY_38_PARTS.LEFT_SHOULDER, BODY_38_PARTS.LEFT_ELBOW), - Tuple.Create(BODY_38_PARTS.LEFT_ELBOW, BODY_38_PARTS.LEFT_WRIST), - Tuple.Create(BODY_38_PARTS.LEFT_WRIST, BODY_38_PARTS.LEFT_HAND_THUMB_4), - Tuple.Create(BODY_38_PARTS.LEFT_WRIST, BODY_38_PARTS.LEFT_HAND_INDEX_1), - Tuple.Create(BODY_38_PARTS.LEFT_WRIST, BODY_38_PARTS.LEFT_HAND_MIDDLE_4), - Tuple.Create(BODY_38_PARTS.LEFT_WRIST, BODY_38_PARTS.LEFT_HAND_PINKY_1), - Tuple.Create(BODY_38_PARTS.RIGHT_SHOULDER, BODY_38_PARTS.RIGHT_ELBOW), - Tuple.Create(BODY_38_PARTS.RIGHT_ELBOW, BODY_38_PARTS.RIGHT_WRIST), - Tuple.Create(BODY_38_PARTS.RIGHT_WRIST, BODY_38_PARTS.RIGHT_HAND_THUMB_4), - Tuple.Create(BODY_38_PARTS.RIGHT_WRIST, BODY_38_PARTS.RIGHT_HAND_INDEX_1), - Tuple.Create(BODY_38_PARTS.RIGHT_WRIST, BODY_38_PARTS.RIGHT_HAND_MIDDLE_4), - Tuple.Create(BODY_38_PARTS.RIGHT_WRIST, BODY_38_PARTS.RIGHT_HAND_PINKY_1), - Tuple.Create(BODY_38_PARTS.LEFT_HIP, BODY_38_PARTS.LEFT_KNEE), - Tuple.Create(BODY_38_PARTS.LEFT_KNEE, BODY_38_PARTS.LEFT_ANKLE), - Tuple.Create(BODY_38_PARTS.LEFT_ANKLE, BODY_38_PARTS.LEFT_HEEL), - Tuple.Create(BODY_38_PARTS.LEFT_ANKLE, BODY_38_PARTS.LEFT_BIG_TOE), - Tuple.Create(BODY_38_PARTS.LEFT_ANKLE, BODY_38_PARTS.LEFT_SMALL_TOE), - Tuple.Create(BODY_38_PARTS.RIGHT_HIP, BODY_38_PARTS.RIGHT_KNEE), - Tuple.Create(BODY_38_PARTS.RIGHT_KNEE, BODY_38_PARTS.RIGHT_ANKLE), - Tuple.Create(BODY_38_PARTS.RIGHT_ANKLE, BODY_38_PARTS.RIGHT_HEEL), - Tuple.Create(BODY_38_PARTS.RIGHT_ANKLE, BODY_38_PARTS.RIGHT_BIG_TOE), - Tuple.Create(BODY_38_PARTS.RIGHT_ANKLE, BODY_38_PARTS.RIGHT_SMALL_TOE) - }; - - private static readonly Tuple[] BODY_BONES_POSE_70 = - { - Tuple.Create(BODY_70_PARTS.PELVIS, BODY_70_PARTS.SPINE_1), - Tuple.Create(BODY_70_PARTS.SPINE_1, BODY_70_PARTS.SPINE_2), - Tuple.Create(BODY_70_PARTS.SPINE_2, BODY_70_PARTS.SPINE_3), - Tuple.Create(BODY_70_PARTS.SPINE_3, BODY_70_PARTS.NECK), - Tuple.Create(BODY_70_PARTS.PELVIS, BODY_70_PARTS.LEFT_HIP), - Tuple.Create(BODY_70_PARTS.PELVIS, BODY_70_PARTS.RIGHT_HIP), - Tuple.Create(BODY_70_PARTS.NECK, BODY_70_PARTS.NOSE), - Tuple.Create(BODY_70_PARTS.NECK, BODY_70_PARTS.LEFT_CLAVICLE), - Tuple.Create(BODY_70_PARTS.LEFT_CLAVICLE, BODY_70_PARTS.LEFT_SHOULDER), - Tuple.Create(BODY_70_PARTS.NECK, BODY_70_PARTS.RIGHT_CLAVICLE), - Tuple.Create(BODY_70_PARTS.RIGHT_CLAVICLE, BODY_70_PARTS.RIGHT_SHOULDER), - Tuple.Create(BODY_70_PARTS.NOSE, BODY_70_PARTS.LEFT_EYE), - Tuple.Create(BODY_70_PARTS.LEFT_EYE, BODY_70_PARTS.LEFT_EAR), - Tuple.Create(BODY_70_PARTS.NOSE, BODY_70_PARTS.RIGHT_EYE), - Tuple.Create(BODY_70_PARTS.RIGHT_EYE, BODY_70_PARTS.RIGHT_EAR), - Tuple.Create(BODY_70_PARTS.LEFT_SHOULDER, BODY_70_PARTS.LEFT_ELBOW), - Tuple.Create(BODY_70_PARTS.LEFT_ELBOW, BODY_70_PARTS.LEFT_WRIST), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_THUMB_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_THUMB_1, BODY_70_PARTS.LEFT_HAND_THUMB_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_THUMB_2, BODY_70_PARTS.LEFT_HAND_THUMB_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_THUMB_3, BODY_70_PARTS.LEFT_HAND_THUMB_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_INDEX_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_INDEX_1, BODY_70_PARTS.LEFT_HAND_INDEX_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_INDEX_2, BODY_70_PARTS.LEFT_HAND_INDEX_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_INDEX_3, BODY_70_PARTS.LEFT_HAND_INDEX_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_MIDDLE_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_MIDDLE_1, BODY_70_PARTS.LEFT_HAND_MIDDLE_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_MIDDLE_2, BODY_70_PARTS.LEFT_HAND_MIDDLE_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_MIDDLE_3, BODY_70_PARTS.LEFT_HAND_MIDDLE_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_RING_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_RING_1, BODY_70_PARTS.LEFT_HAND_RING_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_RING_2, BODY_70_PARTS.LEFT_HAND_RING_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_RING_3, BODY_70_PARTS.LEFT_HAND_RING_4), - Tuple.Create(BODY_70_PARTS.LEFT_WRIST, BODY_70_PARTS.LEFT_HAND_PINKY_1), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_PINKY_1, BODY_70_PARTS.LEFT_HAND_PINKY_2), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_PINKY_2, BODY_70_PARTS.LEFT_HAND_PINKY_3), - Tuple.Create(BODY_70_PARTS.LEFT_HAND_PINKY_3, BODY_70_PARTS.LEFT_HAND_PINKY_4), - Tuple.Create(BODY_70_PARTS.RIGHT_SHOULDER, BODY_70_PARTS.RIGHT_ELBOW), - Tuple.Create(BODY_70_PARTS.RIGHT_ELBOW, BODY_70_PARTS.RIGHT_WRIST), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_THUMB_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_THUMB_1, BODY_70_PARTS.RIGHT_HAND_THUMB_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_THUMB_2, BODY_70_PARTS.RIGHT_HAND_THUMB_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_THUMB_3, BODY_70_PARTS.RIGHT_HAND_THUMB_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_INDEX_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_INDEX_1, BODY_70_PARTS.RIGHT_HAND_INDEX_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_INDEX_2, BODY_70_PARTS.RIGHT_HAND_INDEX_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_INDEX_3, BODY_70_PARTS.RIGHT_HAND_INDEX_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_MIDDLE_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_MIDDLE_1, BODY_70_PARTS.RIGHT_HAND_MIDDLE_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_MIDDLE_2, BODY_70_PARTS.RIGHT_HAND_MIDDLE_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_MIDDLE_3, BODY_70_PARTS.RIGHT_HAND_MIDDLE_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_RING_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_RING_1, BODY_70_PARTS.RIGHT_HAND_RING_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_RING_2, BODY_70_PARTS.RIGHT_HAND_RING_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_RING_3, BODY_70_PARTS.RIGHT_HAND_RING_4), - Tuple.Create(BODY_70_PARTS.RIGHT_WRIST, BODY_70_PARTS.RIGHT_HAND_PINKY_1), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_PINKY_1, BODY_70_PARTS.RIGHT_HAND_PINKY_2), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_PINKY_2, BODY_70_PARTS.RIGHT_HAND_PINKY_3), - Tuple.Create(BODY_70_PARTS.RIGHT_HAND_PINKY_3, BODY_70_PARTS.RIGHT_HAND_PINKY_4), - Tuple.Create(BODY_70_PARTS.LEFT_HIP, BODY_70_PARTS.LEFT_KNEE), - Tuple.Create(BODY_70_PARTS.LEFT_ANKLE, BODY_70_PARTS.LEFT_HEEL), - Tuple.Create(BODY_70_PARTS.LEFT_ANKLE, BODY_70_PARTS.LEFT_BIG_TOE), - Tuple.Create(BODY_70_PARTS.LEFT_ANKLE, BODY_70_PARTS.LEFT_SMALL_TOE), - Tuple.Create(BODY_70_PARTS.RIGHT_HIP, BODY_70_PARTS.RIGHT_KNEE), - Tuple.Create(BODY_70_PARTS.RIGHT_ANKLE, BODY_70_PARTS.RIGHT_HEEL), - Tuple.Create(BODY_70_PARTS.RIGHT_ANKLE, BODY_70_PARTS.RIGHT_BIG_TOE), - Tuple.Create(BODY_70_PARTS.RIGHT_ANKLE, BODY_70_PARTS.RIGHT_SMALL_TOE) - }; - static float[,] id_colors = new float[8, 3]{ { 232.0f, 176.0f ,59.0f }, { 165.0f, 218.0f ,25.0f }, @@ -182,9 +70,9 @@ public static void render_2D(ref OpenCvSharp.Mat left_display, sl.float2 img_sca { // Draw Skeleton bones OpenCvSharp.Scalar base_color = generateColorID(bod.id); - if (body_format == BODY_FORMAT.POSE_38) + if (body_format == BODY_FORMAT.BODY_38) { - foreach (var part in SKELETON_BONES_POSE_38) + foreach (var part in GLViewer.SKELETON_BONES_BODY_38) { var kp_a = cvt(bod.keypoints2D[(int)part.Item1], img_scale); var kp_b = cvt(bod.keypoints2D[(int)part.Item2], img_scale); @@ -205,28 +93,6 @@ public static void render_2D(ref OpenCvSharp.Mat left_display, sl.float2 img_sca } } } - else if (body_format == BODY_FORMAT.POSE_70){ - - foreach (var part in BODY_BONES_POSE_70) - { - var kp_a = cvt(bod.keypoints2D[(int)part.Item1], img_scale); - var kp_b = cvt(bod.keypoints2D[(int)part.Item2], img_scale); - if (roi_render.Contains(kp_a) && roi_render.Contains(kp_b)) - { - Cv2.Line(left_display, kp_a, kp_b, base_color, 1, LineTypes.AntiAlias); - } - } - - // Draw Skeleton joints - foreach (var kp in bod.keypoints2D) - { - Point cv_kp = cvt(kp, img_scale); - if (roi_render.Contains(cv_kp)) - { - Cv2.Circle(left_display, cv_kp, 3, base_color, -1); - } - } - } } } diff --git a/body tracking/body tracking/python/cv_viewer/tracking_viewer.py b/body tracking/body tracking/python/cv_viewer/tracking_viewer.py index 321f6937..54ea6f16 100644 --- a/body tracking/body tracking/python/cv_viewer/tracking_viewer.py +++ b/body tracking/body tracking/python/cv_viewer/tracking_viewer.py @@ -52,7 +52,5 @@ def render_2D(left_display, img_scale, objects, is_tracking_on, body_format): render_sk(left_display, img_scale, obj, color, sl.BODY_34_BONES) elif body_format == sl.BODY_FORMAT.BODY_38: render_sk(left_display, img_scale, obj, color, sl.BODY_38_BONES) - elif body_format == sl.BODY_FORMAT.BODY_70: - render_sk(left_display, img_scale, obj, color, sl.BODY_70_BONES) cv2.addWeighted(left_display, 0.9, overlay, 0.1, 0.0, left_display) \ No newline at end of file diff --git a/body tracking/body tracking/python/ogl_viewer/viewer.py b/body tracking/body tracking/python/ogl_viewer/viewer.py index 9da72f77..a944c0fc 100644 --- a/body tracking/body tracking/python/ogl_viewer/viewer.py +++ b/body tracking/body tracking/python/ogl_viewer/viewer.py @@ -298,8 +298,6 @@ def set(self, obj): self.createSk(obj, sl.BODY_34_PARTS, sl.BODY_34_BONES) elif self.body_format == sl.BODY_FORMAT.BODY_38: self.createSk(obj, sl.BODY_38_PARTS, sl.BODY_38_BONES) - elif self.body_format == sl.BODY_FORMAT.BODY_70: - self.createSk(obj, sl.BODY_70_PARTS, sl.BODY_70_BONES) def push_to_GPU(self): self.joints.push_to_GPU() diff --git a/body tracking/export/JSON export/python/ogl_viewer/viewer.py b/body tracking/export/JSON export/python/ogl_viewer/viewer.py index bd876e41..bc9b086f 100644 --- a/body tracking/export/JSON export/python/ogl_viewer/viewer.py +++ b/body tracking/export/JSON export/python/ogl_viewer/viewer.py @@ -325,8 +325,6 @@ def set(self, obj): self.createSk(obj, sl.BODY_34_PARTS, sl.BODY_34_BONES) elif kpt_size == 38*3: self.createSk(obj, sl.BODY_38_PARTS, sl.BODY_38_BONES) - elif kpt_size == 70*3: - self.createSk(obj, sl.BODY_70_PARTS, sl.BODY_70_BONES) def push_to_GPU(self): self.joints.push_to_GPU() diff --git a/body tracking/multi-camera/cpp/src/GLViewer.cpp b/body tracking/multi-camera/cpp/src/GLViewer.cpp index 0f58cc33..5ef22d1f 100644 --- a/body tracking/multi-camera/cpp/src/GLViewer.cpp +++ b/body tracking/multi-camera/cpp/src/GLViewer.cpp @@ -317,9 +317,6 @@ void GLViewer::addSKeleton(sl::BodyData &obj, Simple3DObject &simpleObj, sl::flo case sl::BODY_FORMAT::BODY_38: createSKPrimitive(obj, sl::BODY_38_BONES, simpleObj, clr_id, raw); break; - case sl::BODY_FORMAT::BODY_70: - createSKPrimitive(obj, sl::BODY_70_BONES, simpleObj, clr_id, raw); - break; } } @@ -334,9 +331,6 @@ void GLViewer::addSKeleton(sl::BodyData& obj, Simple3DObject& simpleObj, sl::flo case 38: addSKeleton(obj, simpleObj, clr_id, raw, sl::BODY_FORMAT::BODY_38); break; - case 70: - addSKeleton(obj, simpleObj, clr_id, raw, sl::BODY_FORMAT::BODY_70); - break; } } diff --git a/body tracking/multi-camera/python/ogl_viewer/viewer.py b/body tracking/multi-camera/python/ogl_viewer/viewer.py index bd876e41..ed66c70a 100644 --- a/body tracking/multi-camera/python/ogl_viewer/viewer.py +++ b/body tracking/multi-camera/python/ogl_viewer/viewer.py @@ -325,9 +325,7 @@ def set(self, obj): self.createSk(obj, sl.BODY_34_PARTS, sl.BODY_34_BONES) elif kpt_size == 38*3: self.createSk(obj, sl.BODY_38_PARTS, sl.BODY_38_BONES) - elif kpt_size == 70*3: - self.createSk(obj, sl.BODY_70_PARTS, sl.BODY_70_BONES) - + def push_to_GPU(self): self.joints.push_to_GPU() diff --git a/object detection/concurrent detections/cpp/src/GLViewer.cpp b/object detection/concurrent detections/cpp/src/GLViewer.cpp index 04ad0bac..8a28a5c6 100644 --- a/object detection/concurrent detections/cpp/src/GLViewer.cpp +++ b/object detection/concurrent detections/cpp/src/GLViewer.cpp @@ -241,8 +241,6 @@ void GLViewer::updateData(sl::Mat &matXYZRGBA, sl::Objects &objs, sl::Bodies & b createSKPrimitive(body, sl::BODY_34_BONES, skeletons, clr_id); if (bodies.body_format == sl::BODY_FORMAT::BODY_38) createSKPrimitive(body, sl::BODY_38_BONES, skeletons, clr_id); - if (bodies.body_format == sl::BODY_FORMAT::BODY_70) - createSKPrimitive(body, sl::BODY_70_BONES, skeletons, clr_id); } } diff --git a/spatial mapping/advanced point cloud mapping/README.md b/spatial mapping/advanced point cloud mapping/README.md deleted file mode 100644 index 4e9d1040..00000000 --- a/spatial mapping/advanced point cloud mapping/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# ZED SDK - Point Cloud Fusion - -## This sample shows how to map your environment as a Point cloud. - -### Features - - real time 3D display of the current fused point cloud - - press 'f' to un/follow the camera movement - -![](fused_point_cloud.jpg) \ No newline at end of file diff --git a/spatial mapping/advanced point cloud mapping/cpp/CMakeLists.txt b/spatial mapping/advanced point cloud mapping/cpp/CMakeLists.txt deleted file mode 100644 index 6a08415d..00000000 --- a/spatial mapping/advanced point cloud mapping/cpp/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.5) -PROJECT(ZED_Point_Cloud_Mapping) - -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -SET(CMAKE_BUILD_TYPE "Release") - -option(LINK_SHARED_ZED "Link with the ZED SDK shared executable" ON) - -if (NOT LINK_SHARED_ZED AND MSVC) - message(FATAL_ERROR "LINK_SHARED_ZED OFF : ZED SDK static libraries not available on Windows") -endif() - -find_package(ZED 3 REQUIRED) -find_package(CUDA ${ZED_CUDA_VERSION} REQUIRED) -find_package(OpenCV REQUIRED) -find_package(GLUT REQUIRED) -find_package(GLEW REQUIRED) -SET(OpenGL_GL_PREFERENCE GLVND) -find_package(OpenGL REQUIRED) - -include_directories(${ZED_INCLUDE_DIRS}) -include_directories(${OpenCV_INCLUDE_DIRS}) -include_directories(${GLEW_INCLUDE_DIRS}) -include_directories(${GLUT_INCLUDE_DIR}) -include_directories(${CUDA_INCLUDE_DIRS}) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - -link_directories(${ZED_LIBRARY_DIR}) -link_directories(${OpenCV_LIBRARY_DIRS}) -link_directories(${GLEW_LIBRARY_DIRS}) -link_directories(${GLUT_LIBRARY_DIRS}) -link_directories(${OpenGL_LIBRARY_DIRS}) -link_directories(${CUDA_LIBRARY_DIRS}) - -FILE(GLOB_RECURSE SRC_FILES src/*.cpp) -FILE(GLOB_RECURSE HDR_FILES include/*.hpp) - -ADD_EXECUTABLE(${PROJECT_NAME} ${HDR_FILES} ${SRC_FILES}) - -if (LINK_SHARED_ZED) - SET(ZED_LIBS ${ZED_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_CUDART_LIBRARY}) -else() - SET(ZED_LIBS ${ZED_STATIC_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_LIBRARY}) -endif() - -TARGET_LINK_LIBRARIES(${PROJECT_NAME} - ${ZED_LIBS} - ${OpenCV_LIBRARIES} - ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES} - ${GLEW_LIBRARIES}) - -if(INSTALL_SAMPLES) - LIST(APPEND SAMPLE_LIST ${PROJECT_NAME}) - SET(SAMPLE_LIST "${SAMPLE_LIST}" PARENT_SCOPE) -endif() \ No newline at end of file diff --git a/spatial mapping/advanced point cloud mapping/cpp/README.md b/spatial mapping/advanced point cloud mapping/cpp/README.md deleted file mode 100644 index b044ba9d..00000000 --- a/spatial mapping/advanced point cloud mapping/cpp/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# ZED SDK - Point Cloud Fusion - -This sample shows how to map your environment as a Point cloud. - -## Getting Started - - Get the latest [ZED SDK](https://www.stereolabs.com/developers/release/) - - Check the [Documentation](https://www.stereolabs.com/docs/) - -## Build the program - - Build for [Windows](https://www.stereolabs.com/docs/app-development/cpp/windows/) - - Build for [Linux/Jetson](https://www.stereolabs.com/docs/app-development/cpp/linux/) - -## Run the program -- Navigate to the build directory and launch the executable -- Or open a terminal in the build directory and run the sample : - - ./ZED_Point_Cloud_Mapping - -### Features - - real time 3D display of the current fused point cloud - - press 'f' to un/follow the camera movement - -## Support -If you need assistance go to our Community site at https://community.stereolabs.com/ \ No newline at end of file diff --git a/spatial mapping/advanced point cloud mapping/cpp/include/GLViewer.hpp b/spatial mapping/advanced point cloud mapping/cpp/include/GLViewer.hpp deleted file mode 100644 index 252448b7..00000000 --- a/spatial mapping/advanced point cloud mapping/cpp/include/GLViewer.hpp +++ /dev/null @@ -1,266 +0,0 @@ -#ifndef __VIEWER_INCLUDE__ -#define __VIEWER_INCLUDE__ - -#include -#include - -#include "ZEDModel.hpp" -#include - -#include -#include - -#include - -#ifndef M_PI -#define M_PI 3.141592653f -#endif - -const float MOUSE_R_SENSITIVITY = 0.025f; -const float MOUSE_UZ_SENSITIVITY = 0.75f; -const float MOUSE_DZ_SENSITIVITY = 1.25f; -const float MOUSE_T_SENSITIVITY = 80.f; -const float KEY_T_SENSITIVITY = 0.1f; - -///////////////// - -class CameraGL { -public: - - CameraGL() {} - enum DIRECTION { - UP, DOWN, LEFT, RIGHT, FORWARD, BACK - }; - CameraGL(sl::Translation position, sl::Translation direction, sl::Translation vertical = sl::Translation(0, 1, 0)); // vertical = Eigen::Vector3f(0, 1, 0) - ~CameraGL(); - - void update(); - void setProjection(float horizontalFOV, float verticalFOV, float znear, float zfar); - const sl::Transform& getViewProjectionMatrix() const; - - float getHorizontalFOV() const; - float getVerticalFOV() const; - - // Set an offset between the eye of the camera and its position - // Note: Useful to use the camera as a trackball camera with z>0 and x = 0, y = 0 - // Note: coordinates are in local space - void setOffsetFromPosition(const sl::Translation& offset); - const sl::Translation& getOffsetFromPosition() const; - - void setDirection(const sl::Translation& direction, const sl::Translation &vertical); - void translate(const sl::Translation& t); - void setPosition(const sl::Translation& p); - void rotate(const sl::Orientation& rot); - void rotate(const sl::Rotation& m); - void setRotation(const sl::Orientation& rot); - void setRotation(const sl::Rotation& m); - - const sl::Translation& getPosition() const; - const sl::Translation& getForward() const; - const sl::Translation& getRight() const; - const sl::Translation& getUp() const; - const sl::Translation& getVertical() const; - float getZNear() const; - float getZFar() const; - - static const sl::Translation ORIGINAL_FORWARD; - static const sl::Translation ORIGINAL_UP; - static const sl::Translation ORIGINAL_RIGHT; - - sl::Transform projection_; -private: - void updateVectors(); - void updateView(); - void updateVPMatrix(); - - sl::Translation offset_; - sl::Translation position_; - sl::Translation forward_; - sl::Translation up_; - sl::Translation right_; - sl::Translation vertical_; - - sl::Orientation rotation_; - - sl::Transform view_; - sl::Transform vpMatrix_; - float horizontalFieldOfView_; - float verticalFieldOfView_; - float znear_; - float zfar_; -}; - -class Shader { -public: - Shader() {} - Shader(GLchar* vs, GLchar* fs); - ~Shader(); - GLuint getProgramId(); - - static const GLint ATTRIB_VERTICES_POS = 0; - static const GLint ATTRIB_COLOR_POS = 1; -private: - bool compile(GLuint &shaderId, GLenum type, GLchar* src); - GLuint verterxId_; - GLuint fragmentId_; - GLuint programId_; -}; - -struct ShaderData { - Shader it; - GLuint MVP_Mat; -}; - -class Simple3DObject { -public: - - Simple3DObject(); - Simple3DObject(sl::Translation position, bool isStatic); - ~Simple3DObject(); - - void addPoint(float x, float y, float z, float r, float g, float b); - void addLine(sl::float3 p1, sl::float3 p2, sl::float3 clr); - void addPoint(sl::float3 position, sl::float3 color); - void pushToGPU(); - void clear(); - - void setDrawingType(GLenum type); - - void draw(); - - void translate(const sl::Translation& t); - void setPosition(const sl::Translation& p); - - void setRT(const sl::Transform& mRT); - - void rotate(const sl::Orientation& rot); - void rotate(const sl::Rotation& m); - void setRotation(const sl::Orientation& rot); - void setRotation(const sl::Rotation& m); - - const sl::Translation& getPosition() const; - - sl::Transform getModelMatrix() const; -private: - std::vector vertices_; - std::vector colors_; - std::vector indices_; - - bool isStatic_; - - GLenum drawingType_; - - GLuint vaoID_; - /* - Vertex buffer IDs: - - [0]: Vertices coordinates; - - [1]: RGB color values; - - [2]: Indices; - */ - GLuint vboID_[3]; - - sl::Translation position_; - sl::Orientation rotation_; -}; - -class SubMapObj { - GLuint vaoID_; - GLuint vboID_[2]; - int current_fc; - - std::vector index; -public: - SubMapObj(); - ~SubMapObj(); - void update(sl::PointCloudChunk &chunks); - void draw(); -}; - -// This class manages input events, window and Opengl rendering pipeline -class GLViewer { -public: - GLViewer(); - ~GLViewer(); - bool isAvailable(); - - GLenum init(int argc, char **argv, sl::CameraParameters param, sl::FusedPointCloud* ptr, sl::MODEL zed_model); - void updatePose(sl::Pose pose_, sl::POSITIONAL_TRACKING_STATE tracking_state); - - void updateChunks() { - new_chunks = true; - chunks_pushed = false; - } - - bool chunksUpdated() { - return chunks_pushed; - } - - void exit(); -private: - // Rendering loop method called each frame by glutDisplayFunc - void render(); - // Everything that needs to be updated before rendering must be done in this method - void update(); - // Once everything is updated, every renderable objects must be drawn in this method - void draw(); - // Clear and refresh inputs' data - void clearInputs(); - - void printText(); - - // Glut functions callbacks - static void drawCallback(); - static void mouseButtonCallback(int button, int state, int x, int y); - static void mouseMotionCallback(int x, int y); - static void reshapeCallback(int width, int height); - static void keyPressedCallback(unsigned char c, int x, int y); - static void keyReleasedCallback(unsigned char c, int x, int y); - static void idle(); - - bool available; - - enum MOUSE_BUTTON { - LEFT = 0, - MIDDLE = 1, - RIGHT = 2, - WHEEL_UP = 3, - WHEEL_DOWN = 4 - }; - - enum KEY_STATE { - UP = 'u', - DOWN = 'd', - FREE = 'f' - }; - - Simple3DObject zedModel; - Simple3DObject zedPath; - std::vector vecPath; - - std::mutex mtx; - bool updateZEDposition = false;; - - bool mouseButton_[3]; - int mouseWheelPosition_; - int mouseCurrentPosition_[2]; - int mouseMotion_[2]; - int previousMouseMotion_[2]; - KEY_STATE keyStates_[256]; - sl::float3 bckgrnd_clr; - sl::Pose pose; - - sl::POSITIONAL_TRACKING_STATE tracking_state; - - bool followCamera = true; - bool new_chunks = false; - bool chunks_pushed = false; - - CameraGL camera_; - ShaderData mainShader; - ShaderData pcf_shader; - - sl::FusedPointCloud* p_fpc; - std::list sub_maps; // Opengl mesh container -}; - -#endif /* __VIEWER_INCLUDE__ */ diff --git a/spatial mapping/advanced point cloud mapping/cpp/include/ZEDModel.hpp b/spatial mapping/advanced point cloud mapping/cpp/include/ZEDModel.hpp deleted file mode 100644 index 03688c5b..00000000 --- a/spatial mapping/advanced point cloud mapping/cpp/include/ZEDModel.hpp +++ /dev/null @@ -1,2791 +0,0 @@ -#pragma once - -#ifndef __ZED3D_HDR__ -#define __ZED3D_HDR__ - -#include - -namespace ZED_model { - const float vertices[] = { - -0.068456, -0.016299, 0.016299 - , -0.068456, 0.016299, 0.016299 - , -0.068456, 0.016299, -0.016299 - , -0.068456, -0.016299, -0.016299 - , -0.076606, 0.014115, 0.016299 - , -0.082572, 0.008150, 0.016299 - , -0.084755, -0.000000, 0.016299 - , -0.082572, -0.008150, 0.016299 - , -0.076606, -0.014115, 0.016299 - , -0.076606, -0.014115, -0.016299 - , -0.082572, -0.008150, -0.016299 - , -0.084755, -0.000000, -0.016299 - , -0.082572, 0.008150, -0.016299 - , -0.076606, 0.014115, -0.016299 - , -0.053494, -0.009779, -0.016299 - , -0.048604, -0.008469, -0.016299 - , -0.045024, -0.004890, -0.016299 - , -0.043714, 0.000000, -0.016299 - , -0.045024, 0.004890, -0.016299 - , -0.048604, 0.008469, -0.016299 - , -0.053494, 0.009779, -0.016299 - , -0.058383, 0.008469, -0.016299 - , -0.061963, 0.004890, -0.016299 - , -0.063273, 0.000000, -0.016299 - , -0.061963, -0.004890, -0.016299 - , -0.058383, -0.008469, -0.016299 - , 0.000000, -0.016299, -0.016299 - , 0.068456, -0.016299, 0.016299 - , 0.000000, 0.016299, -0.016299 - , 0.068456, 0.016299, 0.016299 - , 0.068456, 0.016299, -0.016299 - , 0.068456, -0.016299, -0.016299 - , 0.076606, 0.014115, 0.016299 - , 0.082572, 0.008150, 0.016299 - , 0.084755, -0.000000, 0.016299 - , 0.082572, -0.008150, 0.016299 - , 0.076606, -0.014115, 0.016299 - , 0.076606, -0.014115, -0.016299 - , 0.082572, -0.008150, -0.016299 - , 0.084755, -0.000000, -0.016299 - , 0.082572, 0.008150, -0.016299 - , 0.076606, 0.014115, -0.016299 - , 0.053494, -0.009779, -0.016299 - , 0.048604, -0.008469, -0.016299 - , 0.045024, -0.004890, -0.016299 - , 0.043714, 0.000000, -0.016299 - , 0.045024, 0.004890, -0.016299 - , 0.048604, 0.008469, -0.016299 - , 0.053494, 0.009779, -0.016299 - , 0.058383, 0.008469, -0.016299 - , 0.061963, 0.004890, -0.016299 - , 0.063273, 0.000000, -0.016299 - , 0.061963, -0.004890, -0.016299 - , 0.058383, -0.008469, -0.016299 - , 0.053494, 0.000000, -0.016299 - , -0.053494, 0.000000, -0.016299 - }; - - const int nb_aluTriangle = 54; - const sl::float3 alluColor(0.79f, 0.82f, 0.93f); - const int alluminiumTriangles[] = { - 1, 10, 4 - , 6, 14, 13 - , 7, 13, 12 - , 8, 12, 11 - , 9, 11, 10 - , 5, 3, 14 - , 44, 45, 55 - , 47, 48, 55 - , 43, 44, 55 - , 46, 47, 55 - , 52, 53, 55 - , 48, 49, 55 - , 54, 43, 55 - , 50, 51, 55 - , 53, 54, 55 - , 49, 50, 55 - , 45, 46, 55 - , 51, 52, 55 - , 27, 32, 28 - , 38, 28, 32 - , 42, 34, 41 - , 41, 35, 40 - , 40, 36, 39 - , 39, 37, 38 - , 31, 33, 42 - , 27, 1, 4 - , 20, 19, 56 - , 22, 21, 56 - , 23, 22, 56 - , 24, 23, 56 - , 19, 18, 56 - , 21, 20, 56 - , 17, 16, 56 - , 26, 25, 56 - , 15, 26, 56 - , 18, 17, 56 - , 16, 15, 56 - , 25, 24, 56 - , 2, 29, 3 - , 31, 29, 30 - , 1, 9, 10 - , 6, 5, 14 - , 7, 6, 13 - , 8, 7, 12 - , 9, 8, 11 - , 5, 2, 3 - , 38, 37, 28 - , 42, 33, 34 - , 41, 34, 35 - , 40, 35, 36 - , 39, 36, 37 - , 31, 30, 33 - , 27, 28, 1 - , 2, 30, 29}; - - const int nb_darkTriangle = 54; - const sl::float3 darkColor(0.07f, 0.07f, 0.07f); - const int darkTriangles[] = { - 23, 3, 22 - , 13, 10, 11 - , 4, 14, 3 - , 11, 12, 13 - , 9, 6, 8 - , 1, 5, 9 - , 8, 6, 7 - , 1, 30, 2 - , 21, 22, 3 - , 23, 24, 3 - , 24, 25, 4 - , 3, 24, 4 - , 25, 26, 4 - , 26, 15, 4 - , 16, 17, 27 - , 17, 18, 27 - , 18, 19, 29 - , 27, 18, 29 - , 19, 20, 29 - , 20, 21, 29 - , 3, 29, 21 - , 16, 27, 15 - , 27, 4, 15 - , 51, 50, 31 - , 38, 41, 39 - , 32, 42, 38 - , 39, 41, 40 - , 34, 37, 36 - , 28, 33, 30 - , 36, 35, 34 - , 49, 31, 50 - , 51, 31, 52 - , 52, 32, 53 - , 31, 32, 52 - , 53, 32, 54 - , 54, 32, 43 - , 44, 27, 45 - , 45, 27, 46 - , 46, 29, 47 - , 27, 29, 46 - , 47, 29, 48 - , 48, 29, 49 - , 31, 49, 29 - , 44, 43, 27 - , 27, 43, 32 - , 13, 14, 10 - , 4, 10, 14 - , 9, 5, 6 - , 1, 2, 5 - , 1, 28, 30 - , 38, 42, 41 - , 32, 31, 42 - , 34, 33, 37 - , 28, 37, 33 - }; -}; - -namespace ZED_M_model { - const float vertices[] = {0.030800, 0.013300, 0.000001 - ,0.058785, 0.013300, -0.002250 - ,0.058785, 0.013300, 0.002251 - ,0.059839, 0.013300, -0.001999 - ,0.060770, 0.013300, -0.001351 - ,0.059839, 0.013300, 0.002000 - ,0.060770, 0.013300, 0.001352 - ,0.002815, 0.013300, -0.002250 - ,0.002815, 0.013300, 0.002251 - ,0.001761, 0.013300, -0.001999 - ,0.000830, 0.013300, -0.001351 - ,0.001761, 0.013300, 0.002000 - ,0.000830, 0.013300, 0.001352 - ,0.061449, 0.013300, -0.000563 - ,0.061449, 0.013300, 0.000564 - ,0.000152, 0.013300, 0.000564 - ,0.000152, 0.013300, -0.000563 - ,0.030800, -0.013333, 0.000001 - ,0.058785, -0.013333, -0.002250 - ,0.058785, -0.013333, 0.002251 - ,0.059839, -0.013333, -0.001999 - ,0.060770, -0.013333, -0.001351 - ,0.059839, -0.013333, 0.002000 - ,0.060770, -0.013333, 0.001352 - ,0.002815, -0.013333, -0.002250 - ,0.002815, -0.013333, 0.002251 - ,0.001761, -0.013333, -0.001999 - ,0.000830, -0.013333, -0.001351 - ,0.001761, -0.013333, 0.002000 - ,0.000830, -0.013333, 0.001352 - ,0.061449, -0.013333, 0.000564 - ,0.061449, -0.013333, -0.000563 - ,0.000152, -0.013333, -0.000563 - ,0.000152, -0.013333, 0.000564 - ,-0.031684, 0.009412, 0.000501 - ,-0.031809, 0.008300, 0.000501 - ,-0.028977, 0.012805, 0.000501 - ,-0.029926, 0.012209, 0.000501 - ,-0.026809, 0.013300, 0.000501 - ,-0.027920, 0.013175, 0.000501 - ,-0.030718, 0.011417, 0.000501 - ,-0.031314, 0.010469, 0.000501 - ,-0.031809, -0.008310, 0.000501 - ,-0.031684, -0.009431, 0.000501 - ,-0.028977, -0.012824, 0.000501 - ,-0.029926, -0.012228, 0.000501 - ,-0.026847, -0.013300, 0.000500 - ,-0.027920, -0.013194, 0.000501 - ,-0.030718, -0.011437, 0.000501 - ,-0.031314, -0.010488, 0.000501 - ,-0.031684, 0.009412, -0.000500 - ,-0.031809, 0.008300, -0.000500 - ,-0.028977, 0.012805, -0.000500 - ,-0.029926, 0.012209, -0.000500 - ,-0.026809, 0.013300, -0.000500 - ,-0.027920, 0.013175, -0.000500 - ,-0.030718, 0.011417, -0.000500 - ,-0.031314, 0.010469, -0.000500 - ,-0.031809, -0.008310, -0.000500 - ,-0.031684, -0.009431, -0.000500 - ,-0.029926, -0.012228, -0.000500 - ,-0.028977, -0.012824, -0.000500 - ,-0.027920, -0.013194, -0.000500 - ,-0.026847, -0.013300, -0.000500 - ,-0.031314, -0.010488, -0.000500 - ,-0.030718, -0.011437, -0.000500 - ,-0.031809, 0.006354, -0.000500 - ,-0.031809, 0.006354, 0.000501 - ,-0.031809, -0.006364, -0.000500 - ,-0.031809, -0.006364, 0.000501 - ,-0.031809, 0.005707, -0.000700 - ,-0.031809, 0.005707, 0.000701 - ,-0.031809, -0.005716, -0.000700 - ,-0.031809, -0.005716, 0.000701 - ,-0.031809, 0.005128, -0.001423 - ,-0.031809, 0.005128, 0.001424 - ,-0.031809, -0.005138, -0.001423 - ,-0.031809, -0.005138, 0.001424 - ,-0.031809, 0.004146, -0.002297 - ,-0.031809, 0.004146, 0.002299 - ,-0.031809, -0.004156, -0.002297 - ,-0.031809, -0.004156, 0.002299 - ,-0.031809, 0.003313, -0.002495 - ,-0.031809, 0.003313, 0.002497 - ,-0.031809, -0.003322, -0.002495 - ,-0.031809, -0.003322, 0.002497 - ,-0.031809, -0.000005, 0.000001 - ,-0.026800, 0.013300, -0.000500 - ,-0.026800, 0.013300, 0.000501 - ,0.088376, 0.013300, -0.000500 - ,0.088376, 0.013300, 0.000501 - ,0.093228, 0.009412, 0.000501 - ,0.093353, 0.008300, 0.000501 - ,0.090522, 0.012805, 0.000501 - ,0.091470, 0.012209, 0.000501 - ,0.089464, 0.013175, 0.000501 - ,0.092262, 0.011417, 0.000501 - ,0.092858, 0.010469, 0.000501 - ,0.093353, -0.008310, 0.000501 - ,0.093228, -0.009431, 0.000501 - ,0.090522, -0.012824, 0.000501 - ,0.091470, -0.012228, 0.000501 - ,0.088376, -0.013321, 0.000501 - ,0.089464, -0.013194, 0.000501 - ,0.092262, -0.011437, 0.000501 - ,0.092858, -0.010488, 0.000501 - ,0.093228, 0.009412, -0.000500 - ,0.093353, 0.008300, -0.000500 - ,0.090522, 0.012805, -0.000500 - ,0.091470, 0.012209, -0.000500 - ,0.089464, 0.013175, -0.000500 - ,0.092262, 0.011417, -0.000500 - ,0.092858, 0.010469, -0.000500 - ,0.093353, -0.008310, -0.000500 - ,0.093228, -0.009431, -0.000500 - ,0.091470, -0.012228, -0.000500 - ,0.090522, -0.012824, -0.000500 - ,0.089464, -0.013194, -0.000500 - ,0.088376, -0.013321, -0.000500 - ,0.092858, -0.010488, -0.000500 - ,0.092262, -0.011437, -0.000500 - ,-0.001600, 0.000000, -0.018000 - ,0.017592, 0.000000, -0.018000 - ,0.007996, -0.009596, -0.018000 - ,0.007996, -0.009763, -0.008431 - ,0.007996, 0.009763, -0.008431 - ,0.007996, 0.009596, -0.018000 - ,-0.001767, 0.000000, -0.008431 - ,0.002258, -0.007899, -0.008431 - ,0.002356, -0.007764, -0.018000 - ,0.005033, -0.009127, -0.018000 - ,0.004982, -0.009286, -0.008431 - ,0.000097, -0.005738, -0.008431 - ,0.000232, -0.005640, -0.018000 - ,-0.001131, -0.002963, -0.018000 - ,-0.001290, -0.003014, -0.008431 - ,0.000097, 0.005738, -0.008431 - ,0.000232, 0.005640, -0.018000 - ,-0.001131, 0.002963, -0.018000 - ,-0.001290, 0.003014, -0.008431 - ,0.002258, 0.007899, -0.008431 - ,0.002356, 0.007764, -0.018000 - ,0.005033, 0.009127, -0.018000 - ,0.004982, 0.009286, -0.008431 - ,0.017759, 0.000000, -0.008431 - ,0.013734, 0.007899, -0.008431 - ,0.013636, 0.007764, -0.018000 - ,0.010959, 0.009127, -0.018000 - ,0.011010, 0.009286, -0.008431 - ,0.015895, 0.005738, -0.008431 - ,0.015760, 0.005640, -0.018000 - ,0.017123, 0.002963, -0.018000 - ,0.017282, 0.003014, -0.008431 - ,0.015895, -0.005738, -0.008431 - ,0.015760, -0.005640, -0.018000 - ,0.017123, -0.002963, -0.018000 - ,0.017282, -0.003014, -0.008431 - ,0.013734, -0.007899, -0.008431 - ,0.013636, -0.007764, -0.018000 - ,0.010959, -0.009127, -0.018000 - ,0.011010, -0.009286, -0.008431 - ,0.004827, 0.009763, -0.007940 - ,0.007996, 0.010264, -0.007940 - ,-0.001767, -0.003169, -0.007940 - ,-0.002269, 0.000000, -0.007940 - ,0.004827, -0.009763, -0.007940 - ,0.001963, -0.008304, -0.007940 - ,0.007996, -0.010264, -0.007940 - ,-0.000308, -0.006033, -0.007940 - ,-0.001767, 0.003169, -0.007940 - ,-0.000308, 0.006033, -0.007940 - ,0.001963, 0.008304, -0.007940 - ,0.011165, -0.009763, -0.007940 - ,0.017759, 0.003169, -0.007940 - ,0.018260, -0.000000, -0.007940 - ,0.011165, 0.009763, -0.007940 - ,0.014029, 0.008304, -0.007940 - ,0.016300, 0.006033, -0.007940 - ,0.017759, -0.003169, -0.007940 - ,0.016300, -0.006033, -0.007940 - ,0.014029, -0.008304, -0.007940 - ,0.002356, -0.007764, -0.019500 - ,0.005033, -0.009127, -0.019500 - ,0.007996, -0.009596, -0.019500 - ,0.000232, -0.005640, -0.019500 - ,-0.001600, 0.000000, -0.019500 - ,-0.001131, -0.002963, -0.019500 - ,0.000232, 0.005640, -0.019500 - ,-0.001131, 0.002963, -0.019500 - ,0.002356, 0.007764, -0.019500 - ,0.007996, 0.009596, -0.019500 - ,0.005033, 0.009127, -0.019500 - ,0.013636, 0.007764, -0.019500 - ,0.010959, 0.009127, -0.019500 - ,0.015760, 0.005640, -0.019500 - ,0.017592, 0.000000, -0.019500 - ,0.017123, 0.002963, -0.019500 - ,0.015760, -0.005640, -0.019500 - ,0.017123, -0.002963, -0.019500 - ,0.013636, -0.007764, -0.019500 - ,0.010959, -0.009127, -0.019500 - ,0.002356, -0.007764, -0.022997 - ,0.005033, -0.009127, -0.022997 - ,0.007996, -0.009596, -0.022997 - ,0.000232, -0.005640, -0.022997 - ,-0.001600, 0.000000, -0.022997 - ,-0.001131, -0.002963, -0.022997 - ,0.000232, 0.005640, -0.022997 - ,-0.001131, 0.002963, -0.022997 - ,0.002356, 0.007764, -0.022997 - ,0.007996, 0.009596, -0.022997 - ,0.005033, 0.009127, -0.022997 - ,0.013636, 0.007764, -0.022997 - ,0.010959, 0.009127, -0.022997 - ,0.015760, 0.005640, -0.022997 - ,0.017592, 0.000000, -0.022997 - ,0.017123, 0.002963, -0.022997 - ,0.015760, -0.005640, -0.022997 - ,0.017123, -0.002963, -0.022997 - ,0.013636, -0.007764, -0.022997 - ,0.010959, -0.009127, -0.022997 - ,0.002745, -0.007227, -0.022997 - ,0.005238, -0.008497, -0.022997 - ,0.007996, -0.008933, -0.022997 - ,0.000769, -0.005250, -0.022997 - ,-0.000937, 0.000000, -0.022997 - ,-0.000501, -0.002758, -0.022997 - ,0.000769, 0.005250, -0.022997 - ,-0.000501, 0.002758, -0.022997 - ,0.002745, 0.007227, -0.022997 - ,0.007996, 0.008933, -0.022997 - ,0.005238, 0.008497, -0.022997 - ,0.013246, 0.007227, -0.022997 - ,0.010754, 0.008497, -0.022997 - ,0.015223, 0.005250, -0.022997 - ,0.016929, 0.000000, -0.022997 - ,0.016493, 0.002758, -0.022997 - ,0.015223, -0.005250, -0.022997 - ,0.016493, -0.002758, -0.022997 - ,0.013246, -0.007227, -0.022997 - ,0.010754, -0.008497, -0.022997 - ,0.004095, -0.005369, -0.022203 - ,0.005947, -0.006313, -0.022203 - ,0.007996, -0.006637, -0.022203 - ,0.002626, -0.003901, -0.022203 - ,0.001359, 0.000000, -0.022203 - ,0.001683, -0.002049, -0.022203 - ,0.002626, 0.003901, -0.022203 - ,0.001683, 0.002049, -0.022203 - ,0.004095, 0.005369, -0.022203 - ,0.007996, 0.006637, -0.022203 - ,0.005947, 0.006313, -0.022203 - ,0.011897, 0.005369, -0.022203 - ,0.010045, 0.006313, -0.022203 - ,0.013365, 0.003901, -0.022203 - ,0.014633, 0.000000, -0.022203 - ,0.014308, 0.002049, -0.022203 - ,0.013365, -0.003901, -0.022203 - ,0.014308, -0.002049, -0.022203 - ,0.011897, -0.005369, -0.022203 - ,0.010045, -0.006313, -0.022203 - ,0.004446, -0.004886, -0.021500 - ,0.006131, -0.005744, -0.021500 - ,0.007996, -0.006039, -0.021500 - ,0.003110, -0.003549, -0.021500 - ,0.001957, 0.000000, -0.021500 - ,0.002252, -0.001865, -0.021500 - ,0.003110, 0.003549, -0.021500 - ,0.002252, 0.001865, -0.021500 - ,0.004446, 0.004886, -0.021500 - ,0.007996, 0.006039, -0.021500 - ,0.006131, 0.005744, -0.021500 - ,0.011545, 0.004886, -0.021500 - ,0.009861, 0.005744, -0.021500 - ,0.012882, 0.003549, -0.021500 - ,0.014035, 0.000000, -0.021500 - ,0.013740, 0.001865, -0.021500 - ,0.012882, -0.003549, -0.021500 - ,0.013740, -0.001865, -0.021500 - ,0.011545, -0.004886, -0.021500 - ,0.009861, -0.005744, -0.021500 - ,0.004446, -0.004886, -0.020078 - ,0.006131, -0.005744, -0.020078 - ,0.007996, -0.006039, -0.020078 - ,0.003110, -0.003549, -0.020078 - ,0.001957, 0.000000, -0.020078 - ,0.002252, -0.001865, -0.020078 - ,0.003110, 0.003549, -0.020078 - ,0.002252, 0.001865, -0.020078 - ,0.004446, 0.004886, -0.020078 - ,0.007996, 0.006039, -0.020078 - ,0.006131, 0.005744, -0.020078 - ,0.011545, 0.004886, -0.020078 - ,0.009861, 0.005744, -0.020078 - ,0.012882, 0.003549, -0.020078 - ,0.014035, 0.000000, -0.020078 - ,0.013740, 0.001865, -0.020078 - ,0.012882, -0.003549, -0.020078 - ,0.013740, -0.001865, -0.020078 - ,0.011545, -0.004886, -0.020078 - ,0.009861, -0.005744, -0.020078 - ,-0.026847, -0.013300, -0.006500 - ,-0.031847, -0.008300, -0.006500 - ,-0.029965, -0.012209, -0.006500 - ,-0.027959, -0.013175, -0.006500 - ,-0.029016, -0.012805, -0.006500 - ,-0.031352, -0.010469, -0.006500 - ,-0.030756, -0.011417, -0.006500 - ,-0.031722, -0.009412, -0.006500 - ,0.088353, -0.013310, -0.006500 - ,-0.031847, 0.008300, -0.006500 - ,-0.026847, 0.013300, -0.006500 - ,-0.030756, 0.011417, -0.006500 - ,-0.031722, 0.009412, -0.006500 - ,-0.031352, 0.010469, -0.006500 - ,-0.029016, 0.012805, -0.006500 - ,-0.029965, 0.012209, -0.006500 - ,-0.027959, 0.013175, -0.006500 - ,0.088353, 0.013300, -0.006500 - ,0.093353, 0.008300, -0.006500 - ,0.091470, 0.012209, -0.006500 - ,0.089464, 0.013175, -0.006500 - ,0.090522, 0.012805, -0.006500 - ,0.092858, 0.010469, -0.006500 - ,0.092262, 0.011417, -0.006500 - ,0.093228, 0.009412, -0.006500 - ,0.093353, -0.008310, -0.006500 - ,0.091470, -0.012228, -0.006500 - ,0.089464, -0.013194, -0.006500 - ,0.090522, -0.012824, -0.006500 - ,0.092858, -0.010488, -0.006500 - ,0.092262, -0.011437, -0.006500 - ,0.093228, -0.009431, -0.006500 - ,-0.031722, -0.009412, -0.002250 - ,-0.031809, -0.004156, -0.002297 - ,-0.029016, -0.012805, -0.002250 - ,-0.029965, -0.012209, -0.002250 - ,-0.026847, -0.013300, -0.002250 - ,-0.027959, -0.013175, -0.002250 - ,-0.030756, -0.011417, -0.002250 - ,-0.031352, -0.010469, -0.002250 - ,0.088353, -0.013310, -0.002250 - ,-0.031809, 0.004146, -0.002297 - ,-0.027959, 0.013175, -0.002250 - ,-0.026847, 0.013300, -0.002250 - ,-0.031352, 0.010469, -0.002250 - ,-0.030756, 0.011417, -0.002250 - ,-0.031722, 0.009412, -0.002250 - ,-0.029965, 0.012209, -0.002250 - ,-0.029016, 0.012805, -0.002250 - ,0.088353, 0.013300, -0.002250 - ,0.093228, 0.009412, -0.002250 - ,0.093353, 0.008300, -0.002250 - ,0.090522, 0.012805, -0.002250 - ,0.091470, 0.012209, -0.002250 - ,0.089464, 0.013175, -0.002250 - ,0.092262, 0.011417, -0.002250 - ,0.092858, 0.010469, -0.002250 - ,0.093353, -0.008310, -0.002250 - ,0.093228, -0.009431, -0.002250 - ,0.090522, -0.012824, -0.002250 - ,0.091470, -0.012228, -0.002250 - ,0.089464, -0.013194, -0.002250 - ,0.092262, -0.011437, -0.002250 - ,0.092858, -0.010488, -0.002250 - ,0.002815, -0.013333, -0.002250 - ,0.001761, 0.013300, -0.001999 - ,0.058785, -0.013333, -0.002250 - ,0.059839, 0.013300, -0.001999 - ,-0.031722, -0.009412, -0.000500 - ,-0.031847, -0.006340, -0.000500 - ,-0.029016, -0.012805, -0.000500 - ,-0.029965, -0.012209, -0.000500 - ,-0.026847, -0.013300, -0.000500 - ,-0.027959, -0.013175, -0.000500 - ,-0.030756, -0.011417, -0.000500 - ,-0.031352, -0.010469, -0.000500 - ,0.000152, -0.013333, -0.000563 - ,-0.031847, 0.006354, -0.000500 - ,-0.027959, 0.013175, -0.000500 - ,-0.026847, 0.013300, -0.000500 - ,-0.031352, 0.010469, -0.000500 - ,-0.030756, 0.011417, -0.000500 - ,-0.031722, 0.009412, -0.000500 - ,-0.029965, 0.012209, -0.000500 - ,-0.029016, 0.012805, -0.000500 - ,0.088353, 0.013300, -0.000500 - ,0.061448, 0.013300, -0.000563 - ,0.093228, 0.009412, -0.000500 - ,0.093353, 0.008300, -0.000500 - ,0.090522, 0.012805, -0.000500 - ,0.091470, 0.012209, -0.000500 - ,0.089464, 0.013175, -0.000500 - ,0.092262, 0.011417, -0.000500 - ,0.092858, 0.010469, -0.000500 - ,0.093353, -0.008310, -0.000500 - ,0.093228, -0.009431, -0.000500 - ,0.090522, -0.012824, -0.000500 - ,0.091470, -0.012228, -0.000500 - ,0.088353, -0.013310, -0.000500 - ,0.089464, -0.013194, -0.000500 - ,0.092262, -0.011437, -0.000500 - ,0.092858, -0.010488, -0.000500 - ,0.000151, 0.013300, -0.000563 - ,0.061448, -0.013333, -0.000563 - ,0.058800, 0.013300, -0.002250 - ,0.002815, 0.013300, -0.002250 - ,0.000830, 0.013300, -0.001351 - ,0.060770, 0.013300, -0.001351 - ,0.060770, -0.013333, -0.001351 - ,0.059839, -0.013333, -0.001999 - ,0.000830, -0.013333, -0.001351 - ,0.001761, -0.013333, -0.001999 - ,-0.026844, -0.011518, -0.007940 - ,-0.026847, -0.011634, -0.007898 - ,-0.027589, -0.011551, -0.007898 - ,-0.027563, -0.011437, -0.007940 - ,-0.028294, -0.011304, -0.007898 - ,-0.028243, -0.011199, -0.007940 - ,-0.028926, -0.010907, -0.007898 - ,-0.028854, -0.010816, -0.007940 - ,-0.029454, -0.010379, -0.007898 - ,-0.029363, -0.010306, -0.007940 - ,-0.029852, -0.009746, -0.007898 - ,-0.029747, -0.009696, -0.007940 - ,-0.030098, -0.009041, -0.007898 - ,-0.029985, -0.009016, -0.007940 - ,-0.030181, -0.008300, -0.007898 - ,-0.030066, -0.008297, -0.007940 - ,-0.030181, 0.008300, -0.007898 - ,-0.030065, 0.008296, -0.007940 - ,-0.030098, 0.009041, -0.007898 - ,-0.029985, 0.009015, -0.007940 - ,-0.029852, 0.009746, -0.007898 - ,-0.029747, 0.009696, -0.007940 - ,-0.029454, 0.010379, -0.007898 - ,-0.029363, 0.010306, -0.007940 - ,-0.028926, 0.010907, -0.007898 - ,-0.028854, 0.010816, -0.007940 - ,-0.028294, 0.011304, -0.007898 - ,-0.028243, 0.011199, -0.007940 - ,-0.027589, 0.011551, -0.007898 - ,-0.027563, 0.011437, -0.007940 - ,-0.026847, 0.011634, -0.007898 - ,-0.026844, 0.011518, -0.007940 - ,0.088349, 0.011518, -0.007940 - ,0.088353, 0.011634, -0.007898 - ,0.089094, 0.011551, -0.007898 - ,0.089068, 0.011437, -0.007940 - ,0.089799, 0.011304, -0.007898 - ,0.089749, 0.011199, -0.007940 - ,0.090432, 0.010907, -0.007898 - ,0.090359, 0.010816, -0.007940 - ,0.090960, 0.010379, -0.007898 - ,0.090869, 0.010306, -0.007940 - ,0.091357, 0.009746, -0.007898 - ,0.091252, 0.009696, -0.007940 - ,0.091604, 0.009041, -0.007898 - ,0.091490, 0.009016, -0.007940 - ,0.091637, 0.008187, -0.007940 - ,0.091724, 0.008300, -0.007867 - ,0.088353, -0.011644, -0.007898 - ,0.088349, -0.011528, -0.007940 - ,0.089094, -0.011570, -0.007898 - ,0.089069, -0.011456, -0.007940 - ,0.089799, -0.011323, -0.007898 - ,0.089749, -0.011219, -0.007940 - ,0.090432, -0.010926, -0.007898 - ,0.090359, -0.010835, -0.007940 - ,0.090960, -0.010398, -0.007898 - ,0.090869, -0.010325, -0.007940 - ,0.091357, -0.009766, -0.007898 - ,0.091252, -0.009715, -0.007940 - ,0.091604, -0.009061, -0.007898 - ,0.091490, -0.009035, -0.007940 - ,0.091724, -0.008310, -0.007867 - ,0.091637, -0.008196, -0.007940 - ,-0.031809, -0.003322, -0.002495 - ,-0.031809, 0.003313, -0.002495 - ,-0.031809, 0.005707, -0.000700 - ,-0.031809, 0.005128, -0.001423 - ,-0.031809, -0.005716, -0.000700 - ,-0.031809, -0.005138, -0.001423 - ,0.061397, 0.000000, -0.018000 - ,0.080589, 0.000000, -0.018000 - ,0.070993, -0.009596, -0.018000 - ,0.070993, -0.009763, -0.008431 - ,0.070993, 0.009763, -0.008431 - ,0.070993, 0.009596, -0.018000 - ,0.061230, 0.000000, -0.008431 - ,0.065255, -0.007899, -0.008431 - ,0.065353, -0.007764, -0.018000 - ,0.068030, -0.009127, -0.018000 - ,0.067979, -0.009286, -0.008431 - ,0.063094, -0.005738, -0.008431 - ,0.063229, -0.005640, -0.018000 - ,0.061866, -0.002963, -0.018000 - ,0.061707, -0.003014, -0.008431 - ,0.063094, 0.005738, -0.008431 - ,0.063229, 0.005640, -0.018000 - ,0.061866, 0.002963, -0.018000 - ,0.061707, 0.003014, -0.008431 - ,0.065255, 0.007899, -0.008431 - ,0.065353, 0.007764, -0.018000 - ,0.068030, 0.009127, -0.018000 - ,0.067979, 0.009286, -0.008431 - ,0.080756, 0.000000, -0.008431 - ,0.076731, 0.007899, -0.008431 - ,0.076633, 0.007764, -0.018000 - ,0.073956, 0.009127, -0.018000 - ,0.074007, 0.009286, -0.008431 - ,0.078892, 0.005738, -0.008431 - ,0.078757, 0.005640, -0.018000 - ,0.080120, 0.002963, -0.018000 - ,0.080279, 0.003014, -0.008431 - ,0.078892, -0.005738, -0.008431 - ,0.078757, -0.005640, -0.018000 - ,0.080120, -0.002963, -0.018000 - ,0.080279, -0.003014, -0.008431 - ,0.076731, -0.007899, -0.008431 - ,0.076633, -0.007764, -0.018000 - ,0.073956, -0.009127, -0.018000 - ,0.074007, -0.009286, -0.008431 - ,0.067824, 0.009763, -0.007940 - ,0.070993, 0.010264, -0.007940 - ,0.061230, -0.003169, -0.007940 - ,0.060728, 0.000000, -0.007940 - ,0.067824, -0.009763, -0.007940 - ,0.064960, -0.008304, -0.007940 - ,0.070993, -0.010264, -0.007940 - ,0.062688, -0.006033, -0.007940 - ,0.061230, 0.003169, -0.007940 - ,0.062688, 0.006033, -0.007940 - ,0.064960, 0.008304, -0.007940 - ,0.074162, -0.009763, -0.007940 - ,0.080756, 0.003169, -0.007940 - ,0.081257, -0.000000, -0.007940 - ,0.074162, 0.009763, -0.007940 - ,0.077026, 0.008304, -0.007940 - ,0.079297, 0.006033, -0.007940 - ,0.080756, -0.003169, -0.007940 - ,0.079297, -0.006033, -0.007940 - ,0.077026, -0.008304, -0.007940 - ,0.065353, -0.007764, -0.019500 - ,0.068030, -0.009127, -0.019500 - ,0.070993, -0.009596, -0.019500 - ,0.063229, -0.005640, -0.019500 - ,0.061397, 0.000000, -0.019500 - ,0.061866, -0.002963, -0.019500 - ,0.063229, 0.005640, -0.019500 - ,0.061866, 0.002963, -0.019500 - ,0.065353, 0.007764, -0.019500 - ,0.070993, 0.009596, -0.019500 - ,0.068030, 0.009127, -0.019500 - ,0.076633, 0.007764, -0.019500 - ,0.073956, 0.009127, -0.019500 - ,0.078757, 0.005640, -0.019500 - ,0.080589, 0.000000, -0.019500 - ,0.080120, 0.002963, -0.019500 - ,0.078757, -0.005640, -0.019500 - ,0.080120, -0.002963, -0.019500 - ,0.076633, -0.007764, -0.019500 - ,0.073956, -0.009127, -0.019500 - ,0.065353, -0.007764, -0.022997 - ,0.068030, -0.009127, -0.022997 - ,0.070993, -0.009596, -0.022997 - ,0.063229, -0.005640, -0.022997 - ,0.061397, 0.000000, -0.022997 - ,0.061866, -0.002963, -0.022997 - ,0.063229, 0.005640, -0.022997 - ,0.061866, 0.002963, -0.022997 - ,0.065353, 0.007764, -0.022997 - ,0.070993, 0.009596, -0.022997 - ,0.068030, 0.009127, -0.022997 - ,0.076633, 0.007764, -0.022997 - ,0.073956, 0.009127, -0.022997 - ,0.078757, 0.005640, -0.022997 - ,0.080589, 0.000000, -0.022997 - ,0.080120, 0.002963, -0.022997 - ,0.078757, -0.005640, -0.022997 - ,0.080120, -0.002963, -0.022997 - ,0.076633, -0.007764, -0.022997 - ,0.073956, -0.009127, -0.022997 - ,0.065742, -0.007227, -0.022997 - ,0.068235, -0.008497, -0.022997 - ,0.070993, -0.008933, -0.022997 - ,0.063766, -0.005250, -0.022997 - ,0.062060, 0.000000, -0.022997 - ,0.062496, -0.002758, -0.022997 - ,0.063766, 0.005250, -0.022997 - ,0.062496, 0.002758, -0.022997 - ,0.065742, 0.007227, -0.022997 - ,0.070993, 0.008933, -0.022997 - ,0.068235, 0.008497, -0.022997 - ,0.076243, 0.007227, -0.022997 - ,0.073751, 0.008497, -0.022997 - ,0.078220, 0.005250, -0.022997 - ,0.079926, 0.000000, -0.022997 - ,0.079490, 0.002758, -0.022997 - ,0.078220, -0.005250, -0.022997 - ,0.079490, -0.002758, -0.022997 - ,0.076243, -0.007227, -0.022997 - ,0.073751, -0.008497, -0.022997 - ,0.067092, -0.005369, -0.022203 - ,0.068944, -0.006313, -0.022203 - ,0.070993, -0.006637, -0.022203 - ,0.065623, -0.003901, -0.022203 - ,0.064356, 0.000000, -0.022203 - ,0.064680, -0.002049, -0.022203 - ,0.065623, 0.003901, -0.022203 - ,0.064680, 0.002049, -0.022203 - ,0.067092, 0.005369, -0.022203 - ,0.070993, 0.006637, -0.022203 - ,0.068944, 0.006313, -0.022203 - ,0.074894, 0.005369, -0.022203 - ,0.073042, 0.006313, -0.022203 - ,0.076362, 0.003901, -0.022203 - ,0.077630, 0.000000, -0.022203 - ,0.077305, 0.002049, -0.022203 - ,0.076362, -0.003901, -0.022203 - ,0.077305, -0.002049, -0.022203 - ,0.074894, -0.005369, -0.022203 - ,0.073042, -0.006313, -0.022203 - ,0.067443, -0.004886, -0.021500 - ,0.069128, -0.005744, -0.021500 - ,0.070993, -0.006039, -0.021500 - ,0.066107, -0.003549, -0.021500 - ,0.064954, 0.000000, -0.021500 - ,0.065249, -0.001865, -0.021500 - ,0.066107, 0.003549, -0.021500 - ,0.065249, 0.001865, -0.021500 - ,0.067443, 0.004886, -0.021500 - ,0.070993, 0.006039, -0.021500 - ,0.069128, 0.005744, -0.021500 - ,0.074542, 0.004886, -0.021500 - ,0.072858, 0.005744, -0.021500 - ,0.075879, 0.003549, -0.021500 - ,0.077032, 0.000000, -0.021500 - ,0.076737, 0.001865, -0.021500 - ,0.075879, -0.003549, -0.021500 - ,0.076737, -0.001865, -0.021500 - ,0.074542, -0.004886, -0.021500 - ,0.072858, -0.005744, -0.021500 - ,0.067443, -0.004886, -0.020078 - ,0.069128, -0.005744, -0.020078 - ,0.070993, -0.006039, -0.020078 - ,0.066107, -0.003549, -0.020078 - ,0.064954, 0.000000, -0.020078 - ,0.065249, -0.001865, -0.020078 - ,0.066107, 0.003549, -0.020078 - ,0.065249, 0.001865, -0.020078 - ,0.067443, 0.004886, -0.020078 - ,0.070993, 0.006039, -0.020078 - ,0.069128, 0.005744, -0.020078 - ,0.074542, 0.004886, -0.020078 - ,0.072858, 0.005744, -0.020078 - ,0.075879, 0.003549, -0.020078 - ,0.077032, 0.000000, -0.020078 - ,0.076737, 0.001865, -0.020078 - ,0.075879, -0.003549, -0.020078 - ,0.076737, -0.001865, -0.020078 - ,0.074542, -0.004886, -0.020078 - ,0.072858, -0.005744, -0.020078 - ,-0.026847, -0.013300, 0.006300 - ,0.088353, -0.013310, 0.006300 - ,0.002815, -0.013333, 0.002250 - ,-0.026847, 0.013300, 0.006300 - ,0.002815, 0.013300, 0.002250 - ,0.058800, 0.013300, 0.002250 - ,0.088353, 0.013300, 0.006300 - ,-0.026847, -0.013300, 0.002250 - ,-0.026847, -0.013300, 0.000500 - ,-0.027959, -0.013175, 0.006300 - ,-0.029016, -0.012805, 0.006300 - ,-0.026847, 0.013300, 0.000500 - ,0.000151, 0.013300, 0.000563 - ,0.000830, 0.013300, 0.001351 - ,-0.029965, -0.012209, 0.006300 - ,0.001761, 0.013300, 0.001999 - ,-0.030756, -0.011417, 0.006300 - ,-0.031352, -0.010469, 0.006300 - ,-0.031722, -0.009412, 0.006300 - ,-0.031847, -0.008300, 0.006300 - ,-0.026847, 0.013300, 0.002250 - ,-0.031847, 0.008300, 0.006300 - ,-0.027959, 0.013175, 0.006300 - ,-0.031722, 0.009412, 0.006300 - ,-0.031352, 0.010469, 0.006300 - ,-0.029016, 0.012805, 0.006300 - ,-0.030756, 0.011417, 0.006300 - ,-0.029965, 0.012209, 0.006300 - ,-0.027959, -0.013175, 0.000500 - ,-0.027959, -0.013175, 0.002250 - ,-0.029016, -0.012805, 0.000500 - ,-0.029016, -0.012805, 0.002250 - ,-0.029965, -0.012209, 0.000500 - ,-0.029965, -0.012209, 0.002250 - ,-0.030756, -0.011417, 0.000500 - ,-0.030756, -0.011417, 0.002250 - ,-0.031352, -0.010469, 0.000500 - ,-0.031352, -0.010469, 0.002250 - ,-0.031722, -0.009412, 0.000500 - ,-0.031722, -0.009412, 0.002250 - ,-0.031847, -0.006364, 0.000500 - ,-0.031809, -0.004156, 0.002299 - ,-0.031847, 0.006354, 0.000500 - ,-0.031809, 0.004146, 0.002299 - ,-0.031722, 0.009412, 0.000500 - ,-0.031722, 0.009412, 0.002250 - ,-0.027959, 0.013175, 0.002250 - ,-0.027959, 0.013175, 0.000500 - ,-0.031352, 0.010469, 0.000500 - ,-0.031352, 0.010469, 0.002250 - ,-0.029016, 0.012805, 0.002250 - ,-0.029016, 0.012805, 0.000500 - ,-0.030756, 0.011417, 0.000500 - ,-0.030756, 0.011417, 0.002250 - ,-0.029965, 0.012209, 0.002250 - ,-0.029965, 0.012209, 0.000500 - ,0.059839, 0.013300, 0.001999 - ,0.060770, 0.013300, 0.001351 - ,0.088353, 0.013300, 0.002250 - ,0.058785, -0.013333, 0.002250 - ,0.089464, 0.013175, 0.006300 - ,0.090522, 0.012805, 0.006300 - ,0.091470, 0.012209, 0.006300 - ,0.092262, 0.011417, 0.006300 - ,0.092858, 0.010469, 0.006300 - ,0.093228, 0.009412, 0.006300 - ,0.093353, 0.008300, 0.006300 - ,0.088353, -0.013310, 0.002250 - ,0.059839, -0.013333, 0.001999 - ,0.060770, -0.013333, 0.001351 - ,0.061448, 0.013300, 0.000563 - ,0.088353, 0.013300, 0.000500 - ,0.088353, -0.013310, 0.000500 - ,0.061448, -0.013333, 0.000563 - ,0.093353, -0.008310, 0.006300 - ,0.089464, -0.013194, 0.006300 - ,0.093228, -0.009431, 0.006300 - ,0.092858, -0.010488, 0.006300 - ,0.090522, -0.012824, 0.006300 - ,0.092262, -0.011437, 0.006300 - ,0.091470, -0.012228, 0.006300 - ,0.089464, 0.013175, 0.002250 - ,0.090522, 0.012805, 0.002250 - ,0.091470, 0.012209, 0.002250 - ,0.089464, 0.013175, 0.000500 - ,0.090522, 0.012805, 0.000500 - ,0.092262, 0.011417, 0.002250 - ,0.091470, 0.012209, 0.000500 - ,0.092858, 0.010469, 0.002250 - ,0.092262, 0.011417, 0.000500 - ,0.093228, 0.009412, 0.002250 - ,0.093353, 0.008300, 0.002250 - ,0.092858, 0.010469, 0.000500 - ,0.093228, 0.009412, 0.000500 - ,0.093353, 0.008300, 0.000500 - ,0.093353, -0.008310, 0.002250 - ,0.093353, -0.008310, 0.000500 - ,0.093228, -0.009431, 0.002250 - ,0.089464, -0.013194, 0.002250 - ,0.092858, -0.010488, 0.002250 - ,0.090522, -0.012824, 0.002250 - ,0.092262, -0.011437, 0.002250 - ,0.091470, -0.012228, 0.002250 - ,0.093228, -0.009431, 0.000500 - ,0.089464, -0.013194, 0.000500 - ,0.092858, -0.010488, 0.000500 - ,0.090522, -0.012824, 0.000500 - ,0.092262, -0.011437, 0.000500 - ,0.091470, -0.012228, 0.000500 - ,0.000152, -0.013333, 0.000564 - ,0.000830, -0.013333, 0.001352 - ,0.001761, -0.013333, 0.002000 - ,-0.026591, -0.013201, 0.006500 - ,0.088097, -0.013211, 0.006500 - ,-0.026591, 0.013201, 0.006500 - ,0.088097, 0.013201, 0.006500 - ,0.088477, 0.011982, 0.006500 - ,-0.026591, 0.011982, 0.006500 - ,-0.027698, -0.013077, 0.006500 - ,-0.028751, -0.012710, 0.006500 - ,-0.029695, -0.012119, 0.006500 - ,-0.030483, -0.011333, 0.006500 - ,-0.031076, -0.010391, 0.006500 - ,-0.031445, -0.009342, 0.006500 - ,-0.031569, -0.008238, 0.006500 - ,-0.027698, 0.013077, 0.006500 - ,-0.031445, 0.009342, 0.006500 - ,-0.031569, 0.008238, 0.006500 - ,-0.028751, 0.012710, 0.006500 - ,-0.031076, 0.010391, 0.006500 - ,-0.029695, 0.012118, 0.006500 - ,-0.030483, 0.011332, 0.006500 - ,-0.027703, -0.011897, 0.006500 - ,-0.026192, -0.011982, 0.006500 - ,-0.028399, -0.011645, 0.006500 - ,-0.029024, -0.011241, 0.006500 - ,-0.029545, -0.010703, 0.006500 - ,-0.029937, -0.010058, 0.006500 - ,-0.030180, -0.009340, 0.006500 - ,-0.030263, -0.008585, 0.006500 - ,-0.030263, 0.008585, 0.006500 - ,-0.030180, 0.009340, 0.006500 - ,-0.027703, 0.011897, 0.006500 - ,-0.029937, 0.010059, 0.006500 - ,-0.028399, 0.011646, 0.006500 - ,-0.029545, 0.010703, 0.006500 - ,-0.029024, 0.011241, 0.006500 - ,0.088477, -0.011992, 0.006500 - ,0.089204, 0.013077, 0.006500 - ,0.090256, 0.012710, 0.006500 - ,0.091200, 0.012118, 0.006500 - ,0.091989, 0.011332, 0.006500 - ,0.092582, 0.010391, 0.006500 - ,0.092950, 0.009342, 0.006500 - ,0.093075, 0.008238, 0.006500 - ,0.089204, -0.013096, 0.006500 - ,0.092950, -0.009361, 0.006500 - ,0.093075, -0.008248, 0.006500 - ,0.090256, -0.012729, 0.006500 - ,0.092582, -0.010410, 0.006500 - ,0.091200, -0.012138, 0.006500 - ,0.091989, -0.011352, 0.006500 - ,0.089209, 0.011897, 0.006500 - ,0.089905, 0.011646, 0.006500 - ,0.090529, 0.011241, 0.006500 - ,0.091050, 0.010703, 0.006500 - ,0.091443, 0.010059, 0.006500 - ,0.091686, 0.009340, 0.006500 - ,0.091768, 0.008585, 0.006500 - ,0.091768, -0.008595, 0.006500 - ,0.091686, -0.009360, 0.006500 - ,0.089209, -0.011916, 0.006500 - ,0.091443, -0.010078, 0.006500 - ,0.089905, -0.011665, 0.006500 - ,0.091050, -0.010723, 0.006500 - ,0.090529, -0.011260, 0.006500 - ,-0.031809, -0.003322, 0.002497 - ,-0.031809, 0.003313, 0.002497 - ,-0.031809, 0.005707, 0.000701 - ,-0.031809, 0.005128, 0.001424 - ,-0.031809, -0.005138, 0.001424 - ,-0.031809, -0.005716, 0.000701 - ,0.070993, -0.000000, -0.021500 - ,0.076551, 0.004038, -0.021500 - ,0.075030, 0.005558, -0.021500 - ,0.073114, 0.006534, -0.021500 - ,0.077863, 0.000000, -0.021500 - ,0.077527, 0.002121, -0.021500 - ,0.065435, -0.004038, -0.021500 - ,0.066955, -0.005558, -0.021500 - ,0.068872, -0.006534, -0.021500 - ,0.076551, -0.004038, -0.021500 - ,0.077527, -0.002121, -0.021500 - ,0.065435, 0.004038, -0.021500 - ,0.064459, 0.002121, -0.021500 - ,0.064123, 0.000000, -0.021500 - ,0.068872, 0.006534, -0.021500 - ,0.066955, 0.005558, -0.021500 - ,0.070993, 0.006870, -0.021500 - ,0.073114, -0.006534, -0.021500 - ,0.075030, -0.005558, -0.021500 - ,0.070993, -0.006870, -0.021500 - ,0.064459, -0.002121, -0.021500 - ,0.065353, -0.007764, -0.018000 - ,0.068030, -0.009127, -0.018000 - ,0.068030, -0.009127, -0.019500 - ,0.065353, -0.007764, -0.019500 - ,0.070993, -0.009596, -0.018000 - ,0.070993, -0.009596, -0.019500 - ,0.063229, -0.005640, -0.018000 - ,0.063229, -0.005640, -0.019500 - ,0.061397, 0.000000, -0.018000 - ,0.061866, -0.002963, -0.018000 - ,0.061866, -0.002963, -0.019500 - ,0.061397, 0.000000, -0.019500 - ,0.063229, 0.005640, -0.018000 - ,0.061866, 0.002963, -0.018000 - ,0.061866, 0.002963, -0.019500 - ,0.063229, 0.005640, -0.019500 - ,0.065353, 0.007764, -0.018000 - ,0.065353, 0.007764, -0.019500 - ,0.070993, 0.009596, -0.018000 - ,0.068030, 0.009127, -0.018000 - ,0.068030, 0.009127, -0.019500 - ,0.070993, 0.009596, -0.019500 - ,0.076633, 0.007764, -0.018000 - ,0.073956, 0.009127, -0.018000 - ,0.073956, 0.009127, -0.019500 - ,0.076633, 0.007764, -0.019500 - ,0.078757, 0.005640, -0.018000 - ,0.078757, 0.005640, -0.019500 - ,0.080589, 0.000000, -0.018000 - ,0.080120, 0.002963, -0.018000 - ,0.080120, 0.002963, -0.019500 - ,0.080589, 0.000000, -0.019500 - ,0.078757, -0.005640, -0.018000 - ,0.080120, -0.002963, -0.018000 - ,0.080120, -0.002963, -0.019500 - ,0.078757, -0.005640, -0.019500 - ,0.076633, -0.007764, -0.018000 - ,0.076633, -0.007764, -0.019500 - ,0.073956, -0.009127, -0.018000 - ,0.073956, -0.009127, -0.019500 - ,0.002356, -0.007764, -0.018000 - ,0.005033, -0.009127, -0.018000 - ,0.005033, -0.009127, -0.019500 - ,0.002356, -0.007764, -0.019500 - ,0.007996, -0.009596, -0.018000 - ,0.007996, -0.009596, -0.019500 - ,0.000232, -0.005640, -0.018000 - ,0.000232, -0.005640, -0.019500 - ,-0.001600, 0.000000, -0.018000 - ,-0.001131, -0.002963, -0.018000 - ,-0.001131, -0.002963, -0.019500 - ,-0.001600, 0.000000, -0.019500 - ,0.000232, 0.005640, -0.018000 - ,-0.001131, 0.002963, -0.018000 - ,-0.001131, 0.002963, -0.019500 - ,0.000232, 0.005640, -0.019500 - ,0.002356, 0.007764, -0.018000 - ,0.002356, 0.007764, -0.019500 - ,0.007996, 0.009596, -0.018000 - ,0.005033, 0.009127, -0.018000 - ,0.005033, 0.009127, -0.019500 - ,0.007996, 0.009596, -0.019500 - ,0.013636, 0.007764, -0.018000 - ,0.010959, 0.009127, -0.018000 - ,0.010959, 0.009127, -0.019500 - ,0.013636, 0.007764, -0.019500 - ,0.015760, 0.005640, -0.018000 - ,0.015760, 0.005640, -0.019500 - ,0.017592, 0.000000, -0.018000 - ,0.017123, 0.002963, -0.018000 - ,0.017123, 0.002963, -0.019500 - ,0.017592, 0.000000, -0.019500 - ,0.015760, -0.005640, -0.018000 - ,0.017123, -0.002963, -0.018000 - ,0.017123, -0.002963, -0.019500 - ,0.015760, -0.005640, -0.019500 - ,0.013636, -0.007764, -0.018000 - ,0.013636, -0.007764, -0.019500 - ,0.010959, -0.009127, -0.018000 - ,0.010959, -0.009127, -0.019500 - ,0.007996, -0.000000, -0.021500 - ,0.013554, 0.004038, -0.021500 - ,0.012033, 0.005558, -0.021500 - ,0.010117, 0.006534, -0.021500 - ,0.014866, 0.000000, -0.021500 - ,0.014530, 0.002121, -0.021500 - ,0.002438, -0.004038, -0.021500 - ,0.003958, -0.005558, -0.021500 - ,0.005875, -0.006534, -0.021500 - ,0.013554, -0.004038, -0.021500 - ,0.014530, -0.002121, -0.021500 - ,0.002438, 0.004038, -0.021500 - ,0.001462, 0.002121, -0.021500 - ,0.001126, 0.000000, -0.021500 - ,0.005875, 0.006534, -0.021500 - ,0.003958, 0.005558, -0.021500 - ,0.007996, 0.006870, -0.021500 - ,0.010117, -0.006534, -0.021500 - ,0.012033, -0.005558, -0.021500 - ,0.007996, -0.006870, -0.021500 - ,0.001462, -0.002121, -0.021500 - ,0.090529, -0.008928, 0.006500 - ,0.089905, -0.009249, 0.006500 - ,0.089209, -0.009448, 0.006500 - ,0.088477, -0.009506, 0.006500 - ,-0.026234, -0.009497, 0.006500 - ,-0.027703, -0.009430, 0.006500 - ,-0.028399, -0.009231, 0.006500 - ,-0.029024, -0.008910, 0.006500 - ,0.090529, -0.009792, 0.006500 - ,0.089905, -0.010144, 0.006500 - ,0.089209, -0.010362, 0.006500 - ,0.088477, -0.010427, 0.006500 - ,-0.026219, -0.010417, 0.006500 - ,-0.027703, -0.010344, 0.006500 - ,-0.028399, -0.010125, 0.006500 - ,-0.029024, -0.009773, 0.006500 - ,0.090529, 0.008867, 0.006500 - ,0.089905, 0.009187, 0.006500 - ,0.089209, 0.009385, 0.006500 - ,0.088477, 0.009453, 0.006500 - ,-0.026549, 0.009454, 0.006500 - ,-0.027703, 0.009387, 0.006500 - ,-0.028399, 0.009189, 0.006500 - ,-0.029024, 0.008869, 0.006500 - ,0.090529, 0.009705, 0.006500 - ,0.089905, 0.010055, 0.006500 - ,0.089209, 0.010272, 0.006500 - ,0.088477, 0.010346, 0.006500 - ,-0.026564, 0.010347, 0.006500 - ,-0.027703, 0.010273, 0.006500 - ,-0.028399, 0.010056, 0.006500 - ,-0.029024, 0.009707, 0.006500 - ,0.090529, -0.010555, 0.006500 - ,0.089905, -0.010935, 0.006500 - ,0.089209, -0.011170, 0.006500 - ,0.088477, -0.011240, 0.006500 - ,-0.026205, -0.011231, 0.006500 - ,-0.027703, -0.011151, 0.006500 - ,-0.028399, -0.010915, 0.006500 - ,-0.029024, -0.010536, 0.006500 - ,0.090529, 0.010411, 0.006500 - ,0.089905, 0.010786, 0.006500 - ,0.089209, 0.011019, 0.006500 - ,0.088477, 0.011098, 0.006500 - ,-0.026577, 0.011099, 0.006500 - ,-0.027703, 0.011020, 0.006500 - ,-0.028399, 0.010787, 0.006500 - ,-0.029024, 0.010412, 0.006500}; - - const int nb_aluTriangle = 125; - const sl::float3 alluColor(0.79f, 0.82f, 0.93f); - const int alluminiumTriangles[] = { - 2, 1, 8 - ,1, 2, 4 - ,1, 4, 5 - ,1, 5, 14 - ,1, 14, 15 - ,1, 6, 3 - ,1, 7, 6 - ,1, 15, 7 - ,1, 10, 8 - ,1, 11, 10 - ,1, 17, 11 - ,1, 16, 17 - ,1, 9, 12 - ,1, 12, 13 - ,1, 13, 16 - ,3, 9, 1 - ,3, 9, 1 - ,18, 21, 19 - ,18, 22, 21 - ,18, 32, 22 - ,18, 31, 32 - ,18, 31, 32 - ,18, 20, 23 - ,18, 23, 24 - ,18, 24, 31 - ,19, 25, 18 - ,20, 18, 26 - ,18, 25, 27 - ,18, 27, 28 - ,18, 28, 33 - ,18, 33, 34 - ,18, 33, 34 - ,18, 29, 26 - ,18, 30, 29 - ,18, 34, 30 - ,51, 35, 52 - ,52, 35, 36 - ,53, 37, 54 - ,54, 37, 38 - ,55, 39, 56 - ,56, 39, 40 - ,56, 40, 53 - ,53, 40, 37 - ,57, 41, 58 - ,58, 41, 42 - ,54, 38, 57 - ,57, 38, 41 - ,58, 42, 51 - ,51, 42, 35 - ,59, 43, 60 - ,60, 43, 44 - ,61, 46, 62 - ,62, 46, 45 - ,48, 47, 63 - ,63, 47, 64 - ,62, 45, 63 - ,63, 45, 48 - ,65, 50, 66 - ,66, 50, 49 - ,66, 49, 61 - ,61, 49, 46 - ,60, 44, 65 - ,65, 44, 50 - ,52, 36, 67 - ,67, 36, 68 - ,43, 59, 70 - ,70, 59, 69 - ,67, 68, 71 - ,71, 68, 72 - ,70, 69, 74 - ,74, 69, 73 - ,71, 72, 87 - ,74, 73, 87 - ,71, 87, 75 - ,87, 72, 76 - ,74, 87, 78 - ,87, 73, 77 - ,75, 87, 79 - ,87, 76, 80 - ,87, 77, 81 - ,78, 87, 82 - ,79, 87, 83 - ,87, 80, 84 - ,87, 81, 85 - ,82, 87, 86 - ,83, 87, 85 - ,87, 84, 86 - ,88, 17, 89 - ,89, 17, 16 - ,90, 91, 14 - ,14, 91, 15 - ,107, 108, 92 - ,92, 108, 93 - ,109, 110, 94 - ,94, 110, 95 - ,90, 111, 91 - ,91, 111, 96 - ,111, 109, 96 - ,96, 109, 94 - ,112, 113, 97 - ,97, 113, 98 - ,110, 112, 95 - ,95, 112, 97 - ,113, 107, 98 - ,98, 107, 92 - ,108, 114, 93 - ,93, 114, 99 - ,114, 115, 99 - ,99, 115, 100 - ,116, 117, 102 - ,102, 117, 101 - ,118, 119, 104 - ,104, 119, 103 - ,117, 118, 101 - ,101, 118, 104 - ,120, 121, 106 - ,106, 121, 105 - ,121, 116, 105 - ,105, 116, 102 - ,115, 120, 100 - ,100, 120, 106 - ,64, 47, 33 - ,33, 47, 34 - ,119, 32, 103 - ,103, 32, 31}; - - const int nb_darkTriangle = 1268; - const sl::float3 darkColor(0.07f, 0.07f, 0.07f); - const int darkTriangles[] = {126, 144, 127 - ,127, 144, 143 - ,128, 136, 122 - ,122, 136, 135 - ,129, 132, 130 - ,130, 132, 131 - ,132, 125, 131 - ,131, 125, 124 - ,133, 129, 134 - ,134, 129, 130 - ,136, 133, 135 - ,135, 133, 134 - ,137, 140, 138 - ,138, 140, 139 - ,140, 128, 139 - ,139, 128, 122 - ,141, 137, 142 - ,142, 137, 138 - ,144, 141, 143 - ,143, 141, 142 - ,124, 125, 160 - ,160, 125, 161 - ,145, 153, 123 - ,123, 153, 152 - ,146, 149, 147 - ,147, 149, 148 - ,149, 126, 148 - ,148, 126, 127 - ,150, 146, 151 - ,151, 146, 147 - ,153, 150, 152 - ,152, 150, 151 - ,154, 157, 155 - ,155, 157, 156 - ,157, 145, 156 - ,156, 145, 123 - ,158, 154, 159 - ,159, 154, 155 - ,161, 158, 160 - ,160, 158, 159 - ,126, 163, 144 - ,144, 163, 162 - ,128, 165, 136 - ,136, 165, 164 - ,129, 167, 132 - ,132, 167, 166 - ,132, 166, 125 - ,125, 166, 168 - ,133, 169, 129 - ,129, 169, 167 - ,136, 164, 133 - ,133, 164, 169 - ,137, 171, 140 - ,140, 171, 170 - ,140, 170, 128 - ,128, 170, 165 - ,141, 172, 137 - ,137, 172, 171 - ,144, 162, 141 - ,141, 162, 172 - ,125, 168, 161 - ,161, 168, 173 - ,145, 175, 153 - ,153, 175, 174 - ,146, 177, 149 - ,149, 177, 176 - ,149, 176, 126 - ,126, 176, 163 - ,150, 178, 146 - ,146, 178, 177 - ,153, 174, 150 - ,150, 174, 178 - ,154, 180, 157 - ,157, 180, 179 - ,157, 179, 145 - ,145, 179, 175 - ,158, 181, 154 - ,154, 181, 180 - ,161, 173, 158 - ,158, 173, 181 - ,182, 183, 202 - ,202, 183, 203 - ,183, 184, 203 - ,203, 184, 204 - ,185, 182, 205 - ,205, 182, 202 - ,186, 187, 206 - ,206, 187, 207 - ,187, 185, 207 - ,207, 185, 205 - ,188, 189, 208 - ,208, 189, 209 - ,189, 186, 209 - ,209, 186, 206 - ,190, 188, 210 - ,210, 188, 208 - ,191, 192, 211 - ,211, 192, 212 - ,192, 190, 212 - ,212, 190, 210 - ,193, 194, 213 - ,213, 194, 214 - ,194, 191, 214 - ,214, 191, 211 - ,195, 193, 215 - ,215, 193, 213 - ,196, 197, 216 - ,216, 197, 217 - ,197, 195, 217 - ,217, 195, 215 - ,198, 199, 218 - ,218, 199, 219 - ,199, 196, 219 - ,219, 196, 216 - ,200, 198, 220 - ,220, 198, 218 - ,184, 201, 204 - ,204, 201, 221 - ,201, 200, 221 - ,221, 200, 220 - ,202, 203, 222 - ,222, 203, 223 - ,203, 204, 223 - ,223, 204, 224 - ,205, 202, 225 - ,225, 202, 222 - ,206, 207, 226 - ,226, 207, 227 - ,207, 205, 227 - ,227, 205, 225 - ,208, 209, 228 - ,228, 209, 229 - ,209, 206, 229 - ,229, 206, 226 - ,210, 208, 230 - ,230, 208, 228 - ,211, 212, 231 - ,231, 212, 232 - ,212, 210, 232 - ,232, 210, 230 - ,213, 214, 233 - ,233, 214, 234 - ,214, 211, 234 - ,234, 211, 231 - ,215, 213, 235 - ,235, 213, 233 - ,216, 217, 236 - ,236, 217, 237 - ,217, 215, 237 - ,237, 215, 235 - ,218, 219, 238 - ,238, 219, 239 - ,219, 216, 239 - ,239, 216, 236 - ,220, 218, 240 - ,240, 218, 238 - ,204, 221, 224 - ,224, 221, 241 - ,221, 220, 241 - ,241, 220, 240 - ,223, 243, 222 - ,222, 243, 242 - ,224, 244, 223 - ,223, 244, 243 - ,222, 242, 225 - ,225, 242, 245 - ,227, 247, 226 - ,226, 247, 246 - ,225, 245, 227 - ,227, 245, 247 - ,229, 249, 228 - ,228, 249, 248 - ,226, 246, 229 - ,229, 246, 249 - ,228, 248, 230 - ,230, 248, 250 - ,232, 252, 231 - ,231, 252, 251 - ,230, 250, 232 - ,232, 250, 252 - ,234, 254, 233 - ,233, 254, 253 - ,231, 251, 234 - ,234, 251, 254 - ,233, 253, 235 - ,235, 253, 255 - ,237, 257, 236 - ,236, 257, 256 - ,235, 255, 237 - ,237, 255, 257 - ,239, 259, 238 - ,238, 259, 258 - ,236, 256, 239 - ,239, 256, 259 - ,238, 258, 240 - ,240, 258, 260 - ,241, 261, 224 - ,224, 261, 244 - ,240, 260, 241 - ,241, 260, 261 - ,263, 262, 243 - ,243, 262, 242 - ,264, 263, 244 - ,244, 263, 243 - ,242, 262, 245 - ,245, 262, 265 - ,267, 266, 247 - ,247, 266, 246 - ,265, 267, 245 - ,245, 267, 247 - ,269, 268, 249 - ,249, 268, 248 - ,266, 269, 246 - ,246, 269, 249 - ,268, 270, 248 - ,248, 270, 250 - ,272, 271, 252 - ,252, 271, 251 - ,270, 272, 250 - ,250, 272, 252 - ,274, 273, 254 - ,254, 273, 253 - ,271, 274, 251 - ,251, 274, 254 - ,273, 275, 253 - ,253, 275, 255 - ,277, 276, 257 - ,257, 276, 256 - ,275, 277, 255 - ,255, 277, 257 - ,279, 278, 259 - ,259, 278, 258 - ,276, 279, 256 - ,256, 279, 259 - ,278, 280, 258 - ,258, 280, 260 - ,281, 264, 261 - ,261, 264, 244 - ,280, 281, 260 - ,260, 281, 261 - ,262, 263, 282 - ,282, 263, 283 - ,263, 264, 283 - ,283, 264, 284 - ,265, 262, 285 - ,285, 262, 282 - ,266, 267, 286 - ,286, 267, 287 - ,267, 265, 287 - ,287, 265, 285 - ,268, 269, 288 - ,288, 269, 289 - ,269, 266, 289 - ,289, 266, 286 - ,270, 268, 290 - ,290, 268, 288 - ,271, 272, 291 - ,291, 272, 292 - ,272, 270, 292 - ,292, 270, 290 - ,273, 274, 293 - ,293, 274, 294 - ,274, 271, 294 - ,294, 271, 291 - ,275, 273, 295 - ,295, 273, 293 - ,276, 277, 296 - ,296, 277, 297 - ,277, 275, 297 - ,297, 275, 295 - ,278, 279, 298 - ,298, 279, 299 - ,279, 276, 299 - ,299, 276, 296 - ,280, 278, 300 - ,300, 278, 298 - ,264, 281, 284 - ,284, 281, 301 - ,281, 280, 301 - ,301, 280, 300 - ,320, 461, 327 - ,461, 460, 327 - ,460, 477, 327 - ,477, 476, 327 - ,309, 303, 334 - ,334, 303, 335 - ,306, 304, 336 - ,336, 304, 337 - ,302, 305, 338 - ,338, 305, 339 - ,305, 306, 339 - ,339, 306, 336 - ,308, 307, 340 - ,340, 307, 341 - ,304, 308, 337 - ,337, 308, 340 - ,307, 309, 341 - ,341, 309, 334 - ,366, 302, 338 - ,303, 478, 335 - ,318, 312, 344 - ,344, 312, 345 - ,315, 313, 346 - ,346, 313, 347 - ,314, 348, 311 - ,311, 348, 343 - ,314, 315, 348 - ,348, 315, 346 - ,317, 316, 349 - ,349, 316, 350 - ,313, 317, 347 - ,347, 317, 349 - ,316, 318, 350 - ,350, 318, 344 - ,312, 367, 345 - ,326, 320, 352 - ,352, 320, 353 - ,323, 321, 354 - ,354, 321, 355 - ,319, 322, 351 - ,351, 322, 356 - ,322, 323, 356 - ,356, 323, 354 - ,325, 324, 357 - ,357, 324, 358 - ,321, 325, 355 - ,355, 325, 357 - ,324, 326, 358 - ,358, 326, 352 - ,320, 327, 353 - ,353, 327, 359 - ,327, 333, 359 - ,359, 333, 360 - ,328, 330, 362 - ,362, 330, 361 - ,329, 310, 363 - ,363, 310, 342 - ,330, 329, 361 - ,361, 329, 363 - ,331, 332, 365 - ,365, 332, 364 - ,332, 328, 364 - ,364, 328, 362 - ,333, 331, 360 - ,360, 331, 365 - ,368, 310, 366 - ,366, 310, 302 - ,367, 312, 407 - ,310, 368, 342 - ,369, 319, 351 - ,370, 482, 371 - ,336, 337, 372 - ,372, 337, 373 - ,338, 339, 374 - ,374, 339, 375 - ,339, 336, 375 - ,375, 336, 372 - ,340, 341, 376 - ,376, 341, 377 - ,337, 340, 373 - ,373, 340, 376 - ,341, 334, 377 - ,377, 334, 370 - ,366, 338, 413 - ,413, 338, 412 - ,412, 338, 378 - ,338, 374, 378 - ,344, 345, 380 - ,380, 345, 381 - ,346, 347, 382 - ,382, 347, 383 - ,481, 348, 480 - ,480, 348, 384 - ,348, 346, 384 - ,384, 346, 382 - ,349, 350, 385 - ,385, 350, 386 - ,347, 349, 383 - ,383, 349, 385 - ,350, 344, 386 - ,386, 344, 380 - ,409, 351, 388 - ,388, 351, 387 - ,352, 353, 389 - ,389, 353, 390 - ,354, 355, 391 - ,391, 355, 392 - ,351, 356, 387 - ,387, 356, 393 - ,356, 354, 393 - ,393, 354, 391 - ,357, 358, 394 - ,394, 358, 395 - ,355, 357, 392 - ,392, 357, 394 - ,358, 352, 395 - ,395, 352, 389 - ,353, 359, 390 - ,390, 359, 396 - ,359, 360, 396 - ,396, 360, 397 - ,362, 361, 399 - ,399, 361, 398 - ,363, 342, 401 - ,401, 342, 400 - ,361, 363, 398 - ,398, 363, 401 - ,365, 364, 403 - ,403, 364, 402 - ,364, 362, 402 - ,402, 362, 399 - ,360, 365, 397 - ,397, 365, 403 - ,367, 408, 345 - ,345, 408, 381 - ,342, 368, 411 - ,406, 319, 369 - ,312, 319, 407 - ,407, 319, 406 - ,369, 351, 409 - ,381, 408, 404 - ,400, 410, 405 - ,411, 410, 342 - ,342, 410, 400 - ,414, 415, 463 - ,463, 415, 462 - ,414, 417, 415 - ,415, 417, 416 - ,416, 417, 418 - ,418, 417, 419 - ,418, 419, 420 - ,420, 419, 421 - ,420, 421, 422 - ,422, 421, 423 - ,422, 423, 424 - ,424, 423, 425 - ,424, 425, 426 - ,426, 425, 427 - ,426, 427, 428 - ,428, 427, 429 - ,428, 429, 430 - ,430, 429, 431 - ,431, 433, 430 - ,430, 433, 432 - ,432, 433, 434 - ,434, 433, 435 - ,434, 435, 436 - ,436, 435, 437 - ,436, 437, 438 - ,438, 437, 439 - ,438, 439, 440 - ,440, 439, 441 - ,440, 441, 442 - ,442, 441, 443 - ,442, 443, 444 - ,444, 443, 445 - ,444, 445, 447 - ,447, 445, 446 - ,446, 449, 447 - ,447, 449, 448 - ,448, 449, 450 - ,450, 449, 451 - ,450, 451, 452 - ,452, 451, 453 - ,452, 453, 454 - ,454, 453, 455 - ,454, 455, 456 - ,456, 455, 457 - ,456, 457, 458 - ,458, 457, 459 - ,458, 459, 461 - ,461, 459, 460 - ,463, 462, 465 - ,465, 462, 464 - ,464, 466, 465 - ,465, 466, 467 - ,467, 466, 469 - ,469, 466, 468 - ,469, 468, 471 - ,471, 468, 470 - ,471, 470, 473 - ,473, 470, 472 - ,473, 472, 475 - ,475, 472, 474 - ,474, 476, 475 - ,475, 476, 477 - ,303, 309, 428 - ,428, 309, 426 - ,304, 306, 420 - ,420, 306, 418 - ,305, 302, 416 - ,416, 302, 415 - ,306, 305, 418 - ,418, 305, 416 - ,307, 308, 424 - ,424, 308, 422 - ,308, 304, 422 - ,422, 304, 420 - ,309, 307, 426 - ,426, 307, 424 - ,428, 430, 303 - ,303, 430, 311 - ,312, 318, 444 - ,444, 318, 442 - ,313, 315, 436 - ,436, 315, 434 - ,314, 311, 432 - ,432, 311, 430 - ,315, 314, 434 - ,434, 314, 432 - ,316, 317, 440 - ,440, 317, 438 - ,317, 313, 438 - ,438, 313, 436 - ,318, 316, 442 - ,442, 316, 440 - ,320, 326, 461 - ,461, 326, 458 - ,321, 323, 452 - ,452, 323, 450 - ,322, 319, 448 - ,448, 319, 447 - ,323, 322, 450 - ,450, 322, 448 - ,324, 325, 456 - ,456, 325, 454 - ,325, 321, 454 - ,454, 321, 452 - ,326, 324, 458 - ,458, 324, 456 - ,462, 310, 464 - ,464, 310, 329 - ,466, 464, 330 - ,330, 464, 329 - ,468, 466, 328 - ,328, 466, 330 - ,470, 468, 332 - ,332, 468, 328 - ,472, 470, 331 - ,331, 470, 332 - ,474, 472, 333 - ,333, 472, 331 - ,327, 476, 333 - ,333, 476, 474 - ,427, 425, 433 - ,433, 425, 435 - ,425, 423, 435 - ,435, 423, 437 - ,423, 421, 437 - ,437, 421, 439 - ,421, 419, 439 - ,439, 419, 441 - ,419, 417, 441 - ,441, 417, 443 - ,417, 414, 443 - ,443, 414, 445 - ,463, 465, 446 - ,446, 465, 449 - ,465, 467, 449 - ,449, 467, 451 - ,467, 469, 451 - ,451, 469, 453 - ,469, 471, 453 - ,453, 471, 455 - ,471, 473, 455 - ,455, 473, 457 - ,473, 475, 457 - ,457, 475, 459 - ,475, 477, 459 - ,459, 477, 460 - ,431, 429, 433 - ,433, 429, 427 - ,415, 302, 462 - ,462, 302, 310 - ,463, 446, 414 - ,414, 446, 445 - ,312, 444, 319 - ,319, 444, 447 - ,311, 479, 303 - ,303, 479, 478 - ,479, 311, 343 - ,480, 384, 379 - ,343, 348, 481 - ,483, 482, 334 - ,334, 482, 370 - ,334, 335, 483 - ,488, 506, 489 - ,489, 506, 505 - ,490, 498, 484 - ,484, 498, 497 - ,491, 494, 492 - ,492, 494, 493 - ,494, 487, 493 - ,493, 487, 486 - ,495, 491, 496 - ,496, 491, 492 - ,498, 495, 497 - ,497, 495, 496 - ,499, 502, 500 - ,500, 502, 501 - ,502, 490, 501 - ,501, 490, 484 - ,503, 499, 504 - ,504, 499, 500 - ,506, 503, 505 - ,505, 503, 504 - ,486, 487, 522 - ,522, 487, 523 - ,507, 515, 485 - ,485, 515, 514 - ,508, 511, 509 - ,509, 511, 510 - ,511, 488, 510 - ,510, 488, 489 - ,512, 508, 513 - ,513, 508, 509 - ,515, 512, 514 - ,514, 512, 513 - ,516, 519, 517 - ,517, 519, 518 - ,519, 507, 518 - ,518, 507, 485 - ,520, 516, 521 - ,521, 516, 517 - ,523, 520, 522 - ,522, 520, 521 - ,488, 525, 506 - ,506, 525, 524 - ,490, 527, 498 - ,498, 527, 526 - ,491, 529, 494 - ,494, 529, 528 - ,494, 528, 487 - ,487, 528, 530 - ,495, 531, 491 - ,491, 531, 529 - ,498, 526, 495 - ,495, 526, 531 - ,499, 533, 502 - ,502, 533, 532 - ,502, 532, 490 - ,490, 532, 527 - ,503, 534, 499 - ,499, 534, 533 - ,506, 524, 503 - ,503, 524, 534 - ,487, 530, 523 - ,523, 530, 535 - ,507, 537, 515 - ,515, 537, 536 - ,508, 539, 511 - ,511, 539, 538 - ,511, 538, 488 - ,488, 538, 525 - ,512, 540, 508 - ,508, 540, 539 - ,515, 536, 512 - ,512, 536, 540 - ,516, 542, 519 - ,519, 542, 541 - ,519, 541, 507 - ,507, 541, 537 - ,520, 543, 516 - ,516, 543, 542 - ,523, 535, 520 - ,520, 535, 543 - ,544, 545, 564 - ,564, 545, 565 - ,545, 546, 565 - ,565, 546, 566 - ,547, 544, 567 - ,567, 544, 564 - ,548, 549, 568 - ,568, 549, 569 - ,549, 547, 569 - ,569, 547, 567 - ,550, 551, 570 - ,570, 551, 571 - ,551, 548, 571 - ,571, 548, 568 - ,552, 550, 572 - ,572, 550, 570 - ,553, 554, 573 - ,573, 554, 574 - ,554, 552, 574 - ,574, 552, 572 - ,555, 556, 575 - ,575, 556, 576 - ,556, 553, 576 - ,576, 553, 573 - ,557, 555, 577 - ,577, 555, 575 - ,558, 559, 578 - ,578, 559, 579 - ,559, 557, 579 - ,579, 557, 577 - ,560, 561, 580 - ,580, 561, 581 - ,561, 558, 581 - ,581, 558, 578 - ,562, 560, 582 - ,582, 560, 580 - ,546, 563, 566 - ,566, 563, 583 - ,563, 562, 583 - ,583, 562, 582 - ,564, 565, 584 - ,584, 565, 585 - ,565, 566, 585 - ,585, 566, 586 - ,567, 564, 587 - ,587, 564, 584 - ,568, 569, 588 - ,588, 569, 589 - ,569, 567, 589 - ,589, 567, 587 - ,570, 571, 590 - ,590, 571, 591 - ,571, 568, 591 - ,591, 568, 588 - ,572, 570, 592 - ,592, 570, 590 - ,573, 574, 593 - ,593, 574, 594 - ,574, 572, 594 - ,594, 572, 592 - ,575, 576, 595 - ,595, 576, 596 - ,576, 573, 596 - ,596, 573, 593 - ,577, 575, 597 - ,597, 575, 595 - ,578, 579, 598 - ,598, 579, 599 - ,579, 577, 599 - ,599, 577, 597 - ,580, 581, 600 - ,600, 581, 601 - ,581, 578, 601 - ,601, 578, 598 - ,582, 580, 602 - ,602, 580, 600 - ,566, 583, 586 - ,586, 583, 603 - ,583, 582, 603 - ,603, 582, 602 - ,585, 605, 584 - ,584, 605, 604 - ,586, 606, 585 - ,585, 606, 605 - ,584, 604, 587 - ,587, 604, 607 - ,589, 609, 588 - ,588, 609, 608 - ,587, 607, 589 - ,589, 607, 609 - ,591, 611, 590 - ,590, 611, 610 - ,588, 608, 591 - ,591, 608, 611 - ,590, 610, 592 - ,592, 610, 612 - ,594, 614, 593 - ,593, 614, 613 - ,592, 612, 594 - ,594, 612, 614 - ,596, 616, 595 - ,595, 616, 615 - ,593, 613, 596 - ,596, 613, 616 - ,595, 615, 597 - ,597, 615, 617 - ,599, 619, 598 - ,598, 619, 618 - ,597, 617, 599 - ,599, 617, 619 - ,601, 621, 600 - ,600, 621, 620 - ,598, 618, 601 - ,601, 618, 621 - ,600, 620, 602 - ,602, 620, 622 - ,603, 623, 586 - ,586, 623, 606 - ,602, 622, 603 - ,603, 622, 623 - ,625, 624, 605 - ,605, 624, 604 - ,626, 625, 606 - ,606, 625, 605 - ,604, 624, 607 - ,607, 624, 627 - ,629, 628, 609 - ,609, 628, 608 - ,627, 629, 607 - ,607, 629, 609 - ,631, 630, 611 - ,611, 630, 610 - ,628, 631, 608 - ,608, 631, 611 - ,630, 632, 610 - ,610, 632, 612 - ,634, 633, 614 - ,614, 633, 613 - ,632, 634, 612 - ,612, 634, 614 - ,636, 635, 616 - ,616, 635, 615 - ,633, 636, 613 - ,613, 636, 616 - ,635, 637, 615 - ,615, 637, 617 - ,639, 638, 619 - ,619, 638, 618 - ,637, 639, 617 - ,617, 639, 619 - ,641, 640, 621 - ,621, 640, 620 - ,638, 641, 618 - ,618, 641, 621 - ,640, 642, 620 - ,620, 642, 622 - ,643, 626, 623 - ,623, 626, 606 - ,642, 643, 622 - ,622, 643, 623 - ,624, 625, 644 - ,644, 625, 645 - ,625, 626, 645 - ,645, 626, 646 - ,627, 624, 647 - ,647, 624, 644 - ,628, 629, 648 - ,648, 629, 649 - ,629, 627, 649 - ,649, 627, 647 - ,630, 631, 650 - ,650, 631, 651 - ,631, 628, 651 - ,651, 628, 648 - ,632, 630, 652 - ,652, 630, 650 - ,633, 634, 653 - ,653, 634, 654 - ,634, 632, 654 - ,654, 632, 652 - ,635, 636, 655 - ,655, 636, 656 - ,636, 633, 656 - ,656, 633, 653 - ,637, 635, 657 - ,657, 635, 655 - ,638, 639, 658 - ,658, 639, 659 - ,639, 637, 659 - ,659, 637, 657 - ,640, 641, 660 - ,660, 641, 661 - ,641, 638, 661 - ,661, 638, 658 - ,642, 640, 662 - ,662, 640, 660 - ,626, 643, 646 - ,646, 643, 663 - ,643, 642, 663 - ,663, 642, 662 - ,664, 665, 666 - ,666, 665, 723 - ,665, 664, 777 - ,777, 664, 776 - ,667, 668, 670 - ,670, 668, 669 - ,778, 779, 781 - ,781, 779, 780 - ,671, 666, 775 - ,667, 670, 778 - ,778, 670, 779 - ,666, 671, 664 - ,776, 664, 782 - ,782, 664, 673 - ,782, 673, 783 - ,783, 673, 674 - ,675, 676, 677 - ,783, 674, 784 - ,784, 674, 678 - ,679, 668, 667 - ,784, 678, 785 - ,785, 678, 680 - ,785, 680, 786 - ,786, 680, 681 - ,786, 681, 787 - ,787, 681, 682 - ,682, 683, 787 - ,787, 683, 788 - ,667, 684, 679 - ,778, 789, 667 - ,667, 789, 686 - ,791, 685, 790 - ,790, 685, 687 - ,789, 792, 686 - ,686, 792, 689 - ,687, 688, 790 - ,790, 688, 793 - ,792, 794, 689 - ,689, 794, 691 - ,688, 690, 793 - ,793, 690, 795 - ,794, 795, 691 - ,691, 795, 690 - ,671, 672, 693 - ,693, 672, 692 - ,693, 692, 695 - ,695, 692, 694 - ,695, 694, 697 - ,697, 694, 696 - ,664, 671, 673 - ,673, 671, 693 - ,673, 693, 674 - ,674, 693, 695 - ,697, 696, 699 - ,699, 696, 698 - ,782, 796, 776 - ,776, 796, 797 - ,674, 695, 678 - ,678, 695, 697 - ,699, 698, 701 - ,701, 698, 700 - ,798, 796, 783 - ,783, 796, 782 - ,678, 697, 680 - ,680, 697, 699 - ,701, 700, 703 - ,703, 700, 702 - ,799, 798, 784 - ,784, 798, 783 - ,703, 844, 705 - ,680, 699, 681 - ,681, 699, 701 - ,785, 800, 784 - ,784, 800, 799 - ,681, 701, 682 - ,682, 701, 703 - ,786, 801, 785 - ,785, 801, 800 - ,682, 703, 683 - ,683, 703, 705 - ,787, 802, 786 - ,786, 802, 801 - ,675, 677, 684 - ,684, 677, 679 - ,788, 803, 787 - ,787, 803, 802 - ,685, 841, 707 - ,803, 788, 804 - ,804, 788, 791 - ,683, 685, 788 - ,788, 685, 791 - ,708, 842, 706 - ,710, 711, 684 - ,684, 711, 675 - ,709, 708, 713 - ,713, 708, 712 - ,714, 715, 710 - ,710, 715, 711 - ,713, 712, 717 - ,717, 712, 716 - ,718, 719, 714 - ,714, 719, 715 - ,717, 716, 718 - ,718, 716, 719 - ,707, 709, 685 - ,685, 709, 687 - ,686, 710, 667 - ,667, 710, 684 - ,687, 709, 688 - ,688, 709, 713 - ,689, 714, 686 - ,686, 714, 710 - ,805, 804, 790 - ,790, 804, 791 - ,688, 713, 690 - ,690, 713, 717 - ,691, 718, 689 - ,689, 718, 714 - ,778, 781, 789 - ,789, 781, 806 - ,690, 717, 691 - ,691, 717, 718 - ,807, 805, 793 - ,793, 805, 790 - ,789, 806, 792 - ,792, 806, 808 - ,809, 807, 795 - ,795, 807, 793 - ,792, 808, 794 - ,794, 808, 810 - ,810, 809, 794 - ,794, 809, 795 - ,811, 777, 797 - ,797, 777, 776 - ,669, 720, 670 - ,720, 721, 722 - ,720, 722, 670 - ,779, 670, 812 - ,812, 670, 724 - ,812, 724, 813 - ,813, 724, 725 - ,813, 725, 814 - ,814, 725, 726 - ,814, 726, 815 - ,815, 726, 727 - ,815, 727, 816 - ,816, 727, 728 - ,816, 728, 817 - ,817, 728, 729 - ,729, 730, 817 - ,817, 730, 818 - ,731, 732, 723 - ,732, 731, 733 - ,733, 731, 736 - ,721, 734, 722 - ,722, 734, 735 - ,736, 737, 733 - ,665, 731, 723 - ,777, 819, 665 - ,665, 819, 739 - ,821, 738, 820 - ,820, 738, 740 - ,819, 822, 739 - ,739, 822, 742 - ,740, 741, 820 - ,820, 741, 823 - ,822, 824, 742 - ,742, 824, 744 - ,825, 823, 743 - ,743, 823, 741 - ,824, 825, 744 - ,744, 825, 743 - ,826, 780, 812 - ,812, 780, 779 - ,827, 826, 813 - ,813, 826, 812 - ,670, 722, 724 - ,724, 722, 745 - ,828, 827, 814 - ,814, 827, 813 - ,724, 745, 725 - ,725, 745, 746 - ,815, 829, 814 - ,814, 829, 828 - ,725, 746, 726 - ,726, 746, 747 - ,722, 735, 745 - ,745, 735, 748 - ,816, 830, 815 - ,815, 830, 829 - ,745, 748, 746 - ,746, 748, 749 - ,726, 747, 727 - ,727, 747, 750 - ,817, 831, 816 - ,816, 831, 830 - ,818, 832, 817 - ,817, 832, 831 - ,746, 749, 747 - ,747, 749, 751 - ,727, 750, 728 - ,728, 750, 752 - ,747, 751, 750 - ,750, 751, 753 - ,728, 752, 729 - ,729, 752, 754 - ,729, 754, 730 - ,730, 754, 755 - ,750, 753, 752 - ,752, 753, 756 - ,752, 756, 754 - ,754, 756, 757 - ,754, 757, 755 - ,755, 757, 758 - ,818, 821, 832 - ,832, 821, 833 - ,730, 738, 818 - ,818, 738, 821 - ,730, 755, 738 - ,738, 755, 759 - ,755, 758, 759 - ,759, 758, 760 - ,821, 820, 833 - ,833, 820, 834 - ,835, 819, 811 - ,811, 819, 777 - ,820, 823, 834 - ,834, 823, 836 - ,837, 822, 835 - ,835, 822, 819 - ,823, 825, 836 - ,836, 825, 838 - ,839, 824, 837 - ,837, 824, 822 - ,825, 824, 838 - ,838, 824, 839 - ,738, 759, 740 - ,740, 759, 761 - ,739, 762, 665 - ,665, 762, 731 - ,740, 761, 741 - ,741, 761, 763 - ,742, 764, 739 - ,739, 764, 762 - ,741, 763, 743 - ,743, 763, 765 - ,744, 766, 742 - ,742, 766, 764 - ,743, 765, 744 - ,744, 765, 766 - ,759, 760, 761 - ,761, 760, 767 - ,762, 768, 731 - ,731, 768, 736 - ,761, 767, 763 - ,763, 767, 769 - ,764, 770, 762 - ,762, 770, 768 - ,763, 769, 765 - ,765, 769, 771 - ,766, 772, 764 - ,764, 772, 770 - ,765, 771, 766 - ,766, 771, 772 - ,775, 774, 671 - ,671, 774, 672 - ,672, 774, 773 - ,683, 705, 840 - ,840, 841, 683 - ,683, 841, 685 - ,843, 842, 709 - ,709, 842, 708 - ,707, 843, 709 - ,702, 845, 703 - ,703, 845, 844 - ,845, 702, 704 - ,808, 1014, 810 - ,810, 1014, 1015 - ,806, 1013, 808 - ,808, 1013, 1014 - ,781, 1012, 806 - ,806, 1012, 1013 - ,781, 780, 1012 - ,1012, 780, 1011 - ,780, 826, 1011 - ,1011, 826, 1010 - ,826, 827, 1010 - ,1010, 827, 1009 - ,827, 828, 1009 - ,1009, 828, 1008 - ,968, 976, 969 - ,969, 976, 977 - ,969, 977, 970 - ,970, 977, 978 - ,970, 978, 971 - ,971, 978, 979 - ,972, 971, 980 - ,980, 971, 979 - ,973, 972, 981 - ,981, 972, 980 - ,974, 973, 982 - ,982, 973, 981 - ,975, 974, 983 - ,983, 974, 982 - ,976, 1000, 977 - ,977, 1000, 1001 - ,977, 1001, 978 - ,978, 1001, 1002 - ,978, 1002, 979 - ,979, 1002, 1003 - ,980, 979, 1004 - ,1004, 979, 1003 - ,981, 980, 1005 - ,1005, 980, 1004 - ,982, 981, 1006 - ,1006, 981, 1005 - ,983, 982, 1007 - ,1007, 982, 1006 - ,985, 984, 969 - ,969, 984, 968 - ,986, 985, 970 - ,970, 985, 969 - ,987, 986, 971 - ,971, 986, 970 - ,988, 987, 972 - ,972, 987, 971 - ,989, 988, 973 - ,973, 988, 972 - ,990, 989, 974 - ,974, 989, 973 - ,991, 990, 975 - ,975, 990, 974 - ,993, 992, 985 - ,985, 992, 984 - ,994, 993, 986 - ,986, 993, 985 - ,995, 994, 987 - ,987, 994, 986 - ,996, 995, 988 - ,988, 995, 987 - ,996, 988, 997 - ,997, 988, 989 - ,997, 989, 998 - ,998, 989, 990 - ,998, 990, 999 - ,999, 990, 991 - ,1000, 839, 1001 - ,1001, 839, 837 - ,1001, 837, 1002 - ,1002, 837, 835 - ,1002, 835, 1003 - ,1003, 835, 811 - ,1004, 1003, 797 - ,797, 1003, 811 - ,1005, 1004, 796 - ,796, 1004, 797 - ,1006, 1005, 798 - ,798, 1005, 796 - ,1007, 1006, 799 - ,799, 1006, 798 - ,1009, 1008, 993 - ,993, 1008, 992 - ,1010, 1009, 994 - ,994, 1009, 993 - ,1011, 1010, 995 - ,995, 1010, 994 - ,1012, 1011, 996 - ,996, 1011, 995 - ,1012, 996, 1013 - ,1013, 996, 997 - ,1013, 997, 1014 - ,1014, 997, 998 - ,1014, 998, 1015 - ,1015, 998, 999 - ,831, 992, 830 - ,830, 992, 1008 - ,832, 984, 831 - ,831, 984, 992 - ,832, 833, 984 - ,984, 833, 968 - ,833, 834, 968 - ,968, 834, 976 - ,834, 836, 976 - ,976, 836, 1000 - ,802, 983, 801 - ,801, 983, 1007 - ,803, 975, 802 - ,802, 975, 983 - ,804, 991, 803 - ,803, 991, 975 - ,804, 805, 991 - ,991, 805, 999 - ,805, 807, 999 - ,999, 807, 1015 - ,801, 1007, 800 - ,800, 1007, 799 - ,807, 809, 1015 - ,1015, 809, 810 - ,830, 1008, 829 - ,829, 1008, 828 - ,839, 1000, 838 - ,838, 1000, 836}; - - const int nb_greyTriangle = 40; - const static sl::float3 greyColor(0.22f, 0.22f, 0.22f); - const int greyTriangles[] = {849, 846, 848 - ,846, 847, 848 - ,847, 846, 851 - ,846, 850, 851 - ,852, 853, 846 - ,846, 853, 854 - ,850, 846, 856 - ,846, 855, 856 - ,859, 846, 858 - ,846, 857, 858 - ,860, 861, 846 - ,846, 861, 857 - ,860, 846, 862 - ,862, 846, 849 - ,863, 864, 846 - ,846, 864, 855 - ,854, 865, 846 - ,846, 865, 863 - ,859, 866, 846 - ,846, 866, 852 - ,950, 947, 949 - ,947, 948, 949 - ,948, 947, 952 - ,947, 951, 952 - ,953, 954, 947 - ,947, 954, 955 - ,951, 947, 957 - ,947, 956, 957 - ,960, 947, 959 - ,947, 958, 959 - ,961, 962, 947 - ,947, 962, 958 - ,961, 947, 963 - ,963, 947, 950 - ,964, 965, 947 - ,947, 965, 956 - ,955, 966, 947 - ,947, 966, 964 - ,960, 967, 947 - ,947, 967, 953}; - - const int nb_yellowTriangle = 80; - const static sl::float3 yellowColor(1.00f, 1.00f, 0.00f); - const int yellowTriangles[] = {867, 868, 870 - ,870, 868, 869 - ,868, 871, 869 - ,869, 871, 872 - ,873, 867, 874 - ,874, 867, 870 - ,875, 876, 878 - ,878, 876, 877 - ,876, 873, 877 - ,877, 873, 874 - ,879, 880, 882 - ,882, 880, 881 - ,880, 875, 881 - ,881, 875, 878 - ,883, 879, 884 - ,884, 879, 882 - ,885, 886, 888 - ,888, 886, 887 - ,886, 883, 887 - ,887, 883, 884 - ,889, 890, 892 - ,892, 890, 891 - ,890, 885, 891 - ,891, 885, 888 - ,893, 889, 894 - ,894, 889, 892 - ,895, 896, 898 - ,898, 896, 897 - ,896, 893, 897 - ,897, 893, 894 - ,899, 900, 902 - ,902, 900, 901 - ,900, 895, 901 - ,901, 895, 898 - ,903, 899, 904 - ,904, 899, 902 - ,871, 905, 872 - ,872, 905, 906 - ,905, 903, 906 - ,906, 903, 904 - ,907, 908, 910 - ,910, 908, 909 - ,908, 911, 909 - ,909, 911, 912 - ,913, 907, 914 - ,914, 907, 910 - ,915, 916, 918 - ,918, 916, 917 - ,916, 913, 917 - ,917, 913, 914 - ,919, 920, 922 - ,922, 920, 921 - ,920, 915, 921 - ,921, 915, 918 - ,923, 919, 924 - ,924, 919, 922 - ,925, 926, 928 - ,928, 926, 927 - ,926, 923, 927 - ,927, 923, 924 - ,929, 930, 932 - ,932, 930, 931 - ,930, 925, 931 - ,931, 925, 928 - ,933, 929, 934 - ,934, 929, 932 - ,935, 936, 938 - ,938, 936, 937 - ,936, 933, 937 - ,937, 933, 934 - ,939, 940, 942 - ,942, 940, 941 - ,940, 935, 941 - ,941, 935, 938 - ,943, 939, 944 - ,944, 939, 942 - ,911, 945, 912 - ,912, 945, 946 - ,945, 943, 946 - ,946, 943, 944}; -} - -struct ModelPart { - int nb_triangles; - sl::float3 color; - int * triangles; -}; - -struct Model3D { - std::vector part; - float * vertices; -}; - -struct Model3D_ZED:Model3D { - Model3D_ZED() { - part.emplace_back(); - part.back().color = ZED_model::alluColor; - part.back().nb_triangles = ZED_model::nb_aluTriangle; - part.back().triangles = (int*) ZED_model::alluminiumTriangles; - part.emplace_back(); - part.back().color = ZED_model::darkColor; - part.back().nb_triangles = ZED_model::nb_darkTriangle; - part.back().triangles = (int*) ZED_model::darkTriangles; - vertices = (float*) ZED_model::vertices; - } -}; - -struct Model3D_ZED2:Model3D { - Model3D_ZED2() { - part.emplace_back(); - part.back().color = ZED_model::darkColor; - part.back().nb_triangles = ZED_model::nb_aluTriangle; - part.back().triangles = (int*) ZED_model::alluminiumTriangles; - part.emplace_back(); - part.back().color = ZED_M_model::greyColor; - part.back().nb_triangles = ZED_model::nb_darkTriangle; - part.back().triangles = (int*) ZED_model::darkTriangles; - vertices = (float*) ZED_model::vertices; - } -}; - -struct Model3D_ZED_M:Model3D { - Model3D_ZED_M() { - part.emplace_back(); - part.back().color = ZED_M_model::alluColor; - part.back().nb_triangles = ZED_M_model::nb_aluTriangle; - part.back().triangles = (int*) ZED_M_model::alluminiumTriangles; - part.emplace_back(); - part.back().color = ZED_M_model::darkColor; - part.back().nb_triangles = ZED_M_model::nb_darkTriangle; - part.back().triangles = (int*) ZED_M_model::darkTriangles; - part.emplace_back(); - part.back().color = ZED_M_model::greyColor; - part.back().nb_triangles = ZED_M_model::nb_greyTriangle; - part.back().triangles = (int*) ZED_M_model::greyTriangles; - part.emplace_back(); - part.back().color = ZED_M_model::yellowColor; - part.back().nb_triangles = ZED_M_model::nb_yellowTriangle; - part.back().triangles = (int*) ZED_M_model::yellowTriangles; - vertices = (float*) ZED_M_model::vertices; - } -}; - -#endif /* __ZED3D_HDR__ */ diff --git a/spatial mapping/advanced point cloud mapping/cpp/src/GLViewer.cpp b/spatial mapping/advanced point cloud mapping/cpp/src/GLViewer.cpp deleted file mode 100644 index cd03ad8e..00000000 --- a/spatial mapping/advanced point cloud mapping/cpp/src/GLViewer.cpp +++ /dev/null @@ -1,768 +0,0 @@ -#include "GLViewer.hpp" - -GLchar* VERTEX_SHADER = - "#version 330 core\n" - "layout(location = 0) in vec3 in_Vertex;\n" - "layout(location = 1) in vec3 in_Color;\n" - "uniform mat4 u_mvpMatrix;\n" - "out vec3 b_color;\n" - "void main() {\n" - " b_color = in_Color;\n" - " gl_Position = u_mvpMatrix * vec4(in_Vertex, 1);\n" - "}"; - -GLchar* FPC_VERTEX_SHADER = - "#version 330 core\n" - "layout(location = 0) in vec4 in_VertexRGBA;\n" - "uniform mat4 u_mvpMatrix;\n" - "uniform float pointsize;\n" - "out vec3 b_color;\n" - "void main() {\n" - " uint vertexColor = floatBitsToUint(in_VertexRGBA.w); \n" - " b_color = vec3(((vertexColor & uint(0x00FF0000)) >> 16) / 255.f, ((vertexColor & uint(0x0000FF00)) >> 8) / 255.f, (vertexColor & uint(0x000000FF)) / 255.f);\n" - " gl_Position = u_mvpMatrix * vec4(in_VertexRGBA.xyz, 1);\n" - " gl_PointSize = pointsize;\n" - "}"; - -GLchar* FRAGMENT_SHADER = - "#version 330 core\n" - "in vec3 b_color;\n" - "layout(location = 0) out vec4 out_Color;\n" - "void main() {\n" - " out_Color = vec4(b_color, 1);\n" - "}"; - -GLViewer* currentInstance_ = nullptr; - -GLViewer::GLViewer() : available(false){ - currentInstance_ = this; - mouseButton_[0] = mouseButton_[1] = mouseButton_[2] = false; - clearInputs(); - previousMouseMotion_[0] = previousMouseMotion_[1] = 0; -} - -GLViewer::~GLViewer() {} - -void GLViewer::exit() { - if (currentInstance_) - available = false; -} - -bool GLViewer::isAvailable() { - if(available) - glutMainLoopEvent(); - return available; -} - -void CloseFunc(void) { if(currentInstance_) currentInstance_->exit();} - -void fillZED(int nb_tri, float *vertices, int *triangles, sl::float3 color, Simple3DObject *zed_camera) { - for (int p = 0; p < nb_tri * 3; p = p + 3) { - int index = triangles[p] - 1; - zed_camera->addPoint(sl::float3(vertices[index * 3], vertices[index * 3 + 1], vertices[index * 3 + 2]) * 1000, sl::float3(color.r, color.g, color.b)); - index = triangles[p + 1] - 1; - zed_camera->addPoint(sl::float3(vertices[index * 3], vertices[index * 3 + 1], vertices[index * 3 + 2]) * 1000, sl::float3(color.r, color.g, color.b)); - index = triangles[p + 2] - 1; - zed_camera->addPoint(sl::float3(vertices[index * 3], vertices[index * 3 + 1], vertices[index * 3 + 2]) * 1000, sl::float3(color.r, color.g, color.b)); - } -} - -GLenum GLViewer::init(int argc, char **argv, -sl::CameraParameters param, sl::FusedPointCloud* ptr, sl::MODEL zed_model) { - - glutInit(&argc, argv); - int wnd_w = glutGet(GLUT_SCREEN_WIDTH); - int wnd_h = glutGet(GLUT_SCREEN_HEIGHT) *0.9; - glutInitWindowSize(1280, 720); - glutInitWindowPosition(wnd_w*0.05, wnd_h*0.05); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); - glutCreateWindow("ZED PointCloud Fusion"); - - GLenum err = glewInit(); - if (GLEW_OK != err) - return err; - - glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); - glEnable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - - p_fpc = ptr; - - // Compile and create the shader - mainShader.it = Shader(VERTEX_SHADER, FRAGMENT_SHADER); - mainShader.MVP_Mat = glGetUniformLocation(mainShader.it.getProgramId(), "u_mvpMatrix"); - - pcf_shader.it = Shader(FPC_VERTEX_SHADER, FRAGMENT_SHADER); - pcf_shader.MVP_Mat = glGetUniformLocation(pcf_shader.it.getProgramId(), "u_mvpMatrix"); - - // Create the camera - camera_ = CameraGL(sl::Translation(0, 0, 1000), sl::Translation(0, 0, -100)); - camera_.setOffsetFromPosition(sl::Translation(0, 0, 1500)); - - // change background color - bckgrnd_clr = sl::float3(37, 42, 44); - bckgrnd_clr /= 255.f; - - zedPath.setDrawingType(GL_LINE_STRIP); - zedModel.setDrawingType(GL_TRIANGLES); - Model3D *model = nullptr; - switch (zed_model) - { - case sl::MODEL::ZED: model = new Model3D_ZED(); break; - case sl::MODEL::ZED2i: - case sl::MODEL::ZED2: model = new Model3D_ZED2(); break; - case sl::MODEL::ZED_M: model = new Model3D_ZED_M(); break; - } - if(model) { - for (auto it : model->part) - fillZED(it.nb_triangles, model->vertices, it.triangles, it.color, &zedModel); - delete model; - } - zedModel.pushToGPU(); - updateZEDposition = false; - - // Map glut function on this class methods - glutDisplayFunc(GLViewer::drawCallback); - glutMouseFunc(GLViewer::mouseButtonCallback); - glutMotionFunc(GLViewer::mouseMotionCallback); - glutReshapeFunc(GLViewer::reshapeCallback); - glutKeyboardFunc(GLViewer::keyPressedCallback); - glutKeyboardUpFunc(GLViewer::keyReleasedCallback); - glutCloseFunc(CloseFunc); - - available = true; - - // ready to start - chunks_pushed = true; - - return err; -} - -void GLViewer::render() { - if (available) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glClearColor(bckgrnd_clr.r, bckgrnd_clr.g, bckgrnd_clr.b, 1.f); - update(); - draw(); - printText(); - glutSwapBuffers(); - glutPostRedisplay(); - } -} - -void GLViewer::update() { - if (keyStates_['q'] == KEY_STATE::UP || keyStates_['Q'] == KEY_STATE::UP || keyStates_[27] == KEY_STATE::UP) { - currentInstance_->exit(); - return; - } - - if (keyStates_['f'] == KEY_STATE::UP || keyStates_['F'] == KEY_STATE::UP) { - followCamera = !followCamera; - if(followCamera) - camera_.setOffsetFromPosition(sl::Translation(0, 0, 1500)); - } - - // Rotate camera with mouse - if(!followCamera){ - if (mouseButton_[MOUSE_BUTTON::LEFT]) { - camera_.rotate(sl::Rotation((float) mouseMotion_[1] * MOUSE_R_SENSITIVITY, camera_.getRight())); - camera_.rotate(sl::Rotation((float) mouseMotion_[0] * MOUSE_R_SENSITIVITY, camera_.getVertical() * -1.f)); - } - - // Translate camera with mouse - if (mouseButton_[MOUSE_BUTTON::RIGHT]) { - camera_.translate(camera_.getUp() * (float) mouseMotion_[1] * MOUSE_T_SENSITIVITY); - camera_.translate(camera_.getRight() * (float) mouseMotion_[0] * MOUSE_T_SENSITIVITY); - } - } - - // Zoom in with mouse wheel - if (mouseWheelPosition_ != 0) { - sl::Translation cur_offset = camera_.getOffsetFromPosition(); - bool zoom_ = mouseWheelPosition_ > 0; - sl::Translation new_offset = cur_offset * (zoom_? MOUSE_UZ_SENSITIVITY : MOUSE_DZ_SENSITIVITY); - if (zoom_) { - if(followCamera) { - if((new_offset.tz<500.f)) - new_offset.tz = 500.f; - } else { - if((new_offset.tz<50.f) ) - new_offset.tz = 50.f; - } - } else { - if(followCamera) { - if(new_offset.tz>5000.f) - new_offset.tz = 5000.f; - } - } - camera_.setOffsetFromPosition(new_offset); - } - - // Update point cloud buffers - camera_.update(); - clearInputs(); - mtx.lock(); - if (updateZEDposition) { - sl::float3 clr(0.1f, 0.5f, 0.9f); - for(auto it: vecPath) - zedPath.addPoint(it, clr); - zedPath.pushToGPU(); - vecPath.clear(); - updateZEDposition = false; - } - - if (new_chunks) { - const int nb_c = p_fpc->chunks.size(); - if (nb_c > sub_maps.size()) { - const float step = 500.f; - size_t new_size = ((nb_c / step) + 1) * step; - sub_maps.resize(new_size); - } - int c = 0; - for (auto& it : sub_maps) { - if ((c < nb_c) && p_fpc->chunks[c].has_been_updated) - it.update(p_fpc->chunks[c]); - c++; - } - - new_chunks = false; - chunks_pushed = true; - } - - mtx.unlock(); -} - -void GLViewer::draw() { - const sl::Transform vpMatrix = camera_.getViewProjectionMatrix(); - - glUseProgram(mainShader.it.getProgramId()); - glUniformMatrix4fv(mainShader.MVP_Mat, 1, GL_TRUE, vpMatrix.m); - - glLineWidth(1.f); - zedPath.draw(); - - glUniformMatrix4fv(mainShader.MVP_Mat, 1, GL_FALSE, (sl::Transform::transpose(zedModel.getModelMatrix()) * sl::Transform::transpose(vpMatrix)).m); - - zedModel.draw(); - glUseProgram(0); - - if(sub_maps.size()){ - glPointSize(2.f); - glUseProgram(pcf_shader.it.getProgramId()); - glUniformMatrix4fv(pcf_shader.MVP_Mat, 1, GL_TRUE, vpMatrix.m); - - for (auto &it: sub_maps) - it.draw(); - glUseProgram(0); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } -} - -void GLViewer::clearInputs() { - mouseMotion_[0] = mouseMotion_[1] = 0; - mouseWheelPosition_ = 0; - for (unsigned int i = 0; i < 256; ++i) - if (keyStates_[i] != KEY_STATE::DOWN) - keyStates_[i] = KEY_STATE::FREE; -} - -void GLViewer::drawCallback() { - currentInstance_->render(); -} - -void printGL(float x, float y, const char *string) { - glRasterPos2f(x, y); - int len = (int) strlen(string); - for(int i = 0; i < len; i++) { - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]); - } -} - -void GLViewer::printText() { - if(available) { - glColor3f(0.85f, 0.86f, 0.83f); - printGL(-0.99f, 0.90f, "Press 'F' to un/follow the camera"); - - std::string positional_tracking_state_str(); - // Show mapping state - if ((tracking_state == sl::POSITIONAL_TRACKING_STATE::OK)) - glColor3f(0.25f, 0.99f, 0.25f); - else - glColor3f(0.99f, 0.25f, 0.25f); - std::string state_str("POSITIONAL TRACKING STATE : "); - state_str += sl::toString(tracking_state).c_str(); - printGL(-0.99f, 0.95f, state_str.c_str()); - } -} - -void GLViewer::mouseButtonCallback(int button, int state, int x, int y) { - if (button < 5) { - if (button < 3) { - currentInstance_->mouseButton_[button] = state == GLUT_DOWN; - } else { - currentInstance_->mouseWheelPosition_ += button == MOUSE_BUTTON::WHEEL_UP ? 1 : -1; - } - currentInstance_->mouseCurrentPosition_[0] = x; - currentInstance_->mouseCurrentPosition_[1] = y; - currentInstance_->previousMouseMotion_[0] = x; - currentInstance_->previousMouseMotion_[1] = y; - } -} - -void GLViewer::mouseMotionCallback(int x, int y) { - currentInstance_->mouseMotion_[0] = x - currentInstance_->previousMouseMotion_[0]; - currentInstance_->mouseMotion_[1] = y - currentInstance_->previousMouseMotion_[1]; - currentInstance_->previousMouseMotion_[0] = x; - currentInstance_->previousMouseMotion_[1] = y; - glutPostRedisplay(); -} - -void GLViewer::reshapeCallback(int width, int height) { - glViewport(0, 0, width, height); - float hfov = (180.0f / M_PI) * (2.0f * atan(width / (2.0f * 500))); - float vfov = (180.0f / M_PI) * (2.0f * atan(height / (2.0f * 500))); - currentInstance_->camera_.setProjection(hfov, vfov, currentInstance_->camera_.getZNear(), currentInstance_->camera_.getZFar()); -} - -void GLViewer::keyPressedCallback(unsigned char c, int x, int y) { - currentInstance_->keyStates_[c] = KEY_STATE::DOWN; - glutPostRedisplay(); -} - -void GLViewer::keyReleasedCallback(unsigned char c, int x, int y) { - currentInstance_->keyStates_[c] = KEY_STATE::UP; -} - -void GLViewer::idle() { - glutPostRedisplay(); -} - -void GLViewer::updatePose(sl::Pose pose_, sl::POSITIONAL_TRACKING_STATE state) { - mtx.lock(); - pose = pose_; - tracking_state = state; - vecPath.push_back(pose.getTranslation()); - zedModel.setRT(pose.pose_data); - updateZEDposition = true; - mtx.unlock(); - if(followCamera) { - camera_.setPosition(pose.getTranslation()); - sl::Rotation rot = pose.getRotationMatrix(); - camera_.setRotation(rot); - } -} - -Simple3DObject::Simple3DObject() : isStatic_(false) { - vaoID_ = 0; - drawingType_ = GL_TRIANGLES; - position_ = sl::float3(0, 0, 0); - rotation_.setIdentity(); -} - -Simple3DObject::Simple3DObject(sl::Translation position, bool isStatic) : isStatic_(isStatic) { - vaoID_ = 0; - drawingType_ = GL_TRIANGLES; - position_ = position; - rotation_.setIdentity(); -} - -Simple3DObject::~Simple3DObject() { - if (vaoID_ != 0) { - glDeleteBuffers(3, vboID_); - glDeleteVertexArrays(1, &vaoID_); - } -} - -void Simple3DObject::addPoint(sl::float3 position, sl::float3 color) { - addPoint(position.x, position.y, position.z, color.r, color.g, color.b); -} - -void Simple3DObject::addPoint(float x, float y, float z, float r, float g, float b) { - vertices_.push_back(x); - vertices_.push_back(y); - vertices_.push_back(z); - colors_.push_back(r); - colors_.push_back(g); - colors_.push_back(b); - indices_.push_back((int)indices_.size()); -} - -void Simple3DObject::addLine(sl::float3 p1, sl::float3 p2, sl::float3 clr) { - vertices_.push_back(p1.x); - vertices_.push_back(p1.y); - vertices_.push_back(p1.z); - - vertices_.push_back(p2.x); - vertices_.push_back(p2.y); - vertices_.push_back(p2.z); - - colors_.push_back(clr.r); - colors_.push_back(clr.g); - colors_.push_back(clr.b); - - colors_.push_back(clr.r); - colors_.push_back(clr.g); - colors_.push_back(clr.b); - - indices_.push_back((int)indices_.size()); - indices_.push_back((int)indices_.size()); -} - -void Simple3DObject::pushToGPU() { - if (!isStatic_ || vaoID_ == 0) { - if (vaoID_ == 0) { - glGenVertexArrays(1, &vaoID_); - glGenBuffers(3, vboID_); - } - glBindVertexArray(vaoID_); - if (vertices_.size()) { - glBindBuffer(GL_ARRAY_BUFFER, vboID_[0]); - glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(float), &vertices_[0], isStatic_ ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); - glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); - } - - if (colors_.size()) { - glBindBuffer(GL_ARRAY_BUFFER, vboID_[1]); - glBufferData(GL_ARRAY_BUFFER, colors_.size() * sizeof(float), &colors_[0], isStatic_ ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); - glVertexAttribPointer(Shader::ATTRIB_COLOR_POS, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(Shader::ATTRIB_COLOR_POS); - } - - if (indices_.size()) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[2]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_.size() * sizeof(unsigned int), &indices_[0], isStatic_ ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); - } - - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } -} - -void Simple3DObject::clear() { - vertices_.clear(); - colors_.clear(); - indices_.clear(); -} - -void Simple3DObject::setDrawingType(GLenum type) { - drawingType_ = type; -} - -void Simple3DObject::draw() { - if (indices_.size() && vaoID_) { - glBindVertexArray(vaoID_); - glDrawElements(drawingType_, (GLsizei)indices_.size(), GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - } -} - -void Simple3DObject::translate(const sl::Translation& t) { - position_ = position_ + t; -} - -void Simple3DObject::setPosition(const sl::Translation& p) { - position_ = p; -} - -void Simple3DObject::setRT(const sl::Transform& mRT) { - position_ = mRT.getTranslation(); - rotation_ = mRT.getOrientation(); -} - -void Simple3DObject::rotate(const sl::Orientation& rot) { - rotation_ = rot * rotation_; -} - -void Simple3DObject::rotate(const sl::Rotation& m) { - this->rotate(sl::Orientation(m)); -} - -void Simple3DObject::setRotation(const sl::Orientation& rot) { - rotation_ = rot; -} - -void Simple3DObject::setRotation(const sl::Rotation& m) { - this->setRotation(sl::Orientation(m)); -} - -const sl::Translation& Simple3DObject::getPosition() const { - return position_; -} - -sl::Transform Simple3DObject::getModelMatrix() const { - sl::Transform tmp = sl::Transform::identity(); - tmp.setOrientation(rotation_); - tmp.setTranslation(position_); - return tmp; -} - -Shader::Shader(GLchar* vs, GLchar* fs) { - if (!compile(verterxId_, GL_VERTEX_SHADER, vs)) { - std::cout << "ERROR: while compiling vertex shader" << std::endl; - } - if (!compile(fragmentId_, GL_FRAGMENT_SHADER, fs)) { - std::cout << "ERROR: while compiling fragment shader" << std::endl; - } - - programId_ = glCreateProgram(); - - glAttachShader(programId_, verterxId_); - glAttachShader(programId_, fragmentId_); - - glBindAttribLocation(programId_, ATTRIB_VERTICES_POS, "in_vertex"); - glBindAttribLocation(programId_, ATTRIB_COLOR_POS, "in_texCoord"); - - glLinkProgram(programId_); - - GLint errorlk(0); - glGetProgramiv(programId_, GL_LINK_STATUS, &errorlk); - if (errorlk != GL_TRUE) { - std::cout << "ERROR: while linking Shader :" << std::endl; - GLint errorSize(0); - glGetProgramiv(programId_, GL_INFO_LOG_LENGTH, &errorSize); - - char *error = new char[errorSize + 1]; - glGetShaderInfoLog(programId_, errorSize, &errorSize, error); - error[errorSize] = '\0'; - std::cout << error << std::endl; - - delete[] error; - glDeleteProgram(programId_); - } -} - -Shader::~Shader() { - if (verterxId_ != 0) - glDeleteShader(verterxId_); - if (fragmentId_ != 0) - glDeleteShader(fragmentId_); - if (programId_ != 0) - glDeleteShader(programId_); -} - -GLuint Shader::getProgramId() { - return programId_; -} - -bool Shader::compile(GLuint &shaderId, GLenum type, GLchar* src) { - shaderId = glCreateShader(type); - if (shaderId == 0) { - std::cout << "ERROR: shader type (" << type << ") does not exist" << std::endl; - return false; - } - glShaderSource(shaderId, 1, (const char**)&src, 0); - glCompileShader(shaderId); - - GLint errorCp(0); - glGetShaderiv(shaderId, GL_COMPILE_STATUS, &errorCp); - if (errorCp != GL_TRUE) { - std::cout << "ERROR: while compiling Shader :" << std::endl; - GLint errorSize(0); - glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &errorSize); - - char *error = new char[errorSize + 1]; - glGetShaderInfoLog(shaderId, errorSize, &errorSize, error); - error[errorSize] = '\0'; - std::cout << error << std::endl; - - delete[] error; - glDeleteShader(shaderId); - return false; - } - return true; -} - -const sl::Translation CameraGL::ORIGINAL_FORWARD = sl::Translation(0, 0, 1); -const sl::Translation CameraGL::ORIGINAL_UP = sl::Translation(0, 1, 0); -const sl::Translation CameraGL::ORIGINAL_RIGHT = sl::Translation(1, 0, 0); - -CameraGL::CameraGL(sl::Translation position, sl::Translation direction, sl::Translation vertical) { - this->position_ = position; - setDirection(direction, vertical); - - offset_ = sl::Translation(0, 0, 0); - view_.setIdentity(); - updateView(); - setProjection(80, 80, 100.f, 900000.f); - updateVPMatrix(); -} - -CameraGL::~CameraGL() {} - -void CameraGL::update() { - if (sl::Translation::dot(vertical_, up_) < 0) - vertical_ = vertical_ * -1.f; - updateView(); - updateVPMatrix(); -} - -void CameraGL::setProjection(float horizontalFOV, float verticalFOV, float znear, float zfar) { - horizontalFieldOfView_ = horizontalFOV; - verticalFieldOfView_ = verticalFOV; - znear_ = znear; - zfar_ = zfar; - - float fov_y = verticalFOV * M_PI / 180.f; - float fov_x = horizontalFOV * M_PI / 180.f; - - projection_.setIdentity(); - projection_(0, 0) = 1.0f / tanf(fov_x * 0.5f); - projection_(1, 1) = 1.0f / tanf(fov_y * 0.5f); - projection_(2, 2) = -(zfar + znear) / (zfar - znear); - projection_(3, 2) = -1; - projection_(2, 3) = -(2.f * zfar * znear) / (zfar - znear); - projection_(3, 3) = 0; -} - -const sl::Transform& CameraGL::getViewProjectionMatrix() const { - return vpMatrix_; -} - -float CameraGL::getHorizontalFOV() const { - return horizontalFieldOfView_; -} - -float CameraGL::getVerticalFOV() const { - return verticalFieldOfView_; -} - -void CameraGL::setOffsetFromPosition(const sl::Translation& o) { - offset_ = o; -} - -const sl::Translation& CameraGL::getOffsetFromPosition() const { - return offset_; -} - -void CameraGL::setDirection(const sl::Translation& direction, const sl::Translation& vertical) { - sl::Translation dirNormalized = direction; - dirNormalized.normalize(); - this->rotation_ = sl::Orientation(ORIGINAL_FORWARD, dirNormalized * -1.f); - updateVectors(); - this->vertical_ = vertical; - if (sl::Translation::dot(vertical_, up_) < 0) - rotate(sl::Rotation(M_PI, ORIGINAL_FORWARD)); -} - -void CameraGL::translate(const sl::Translation& t) { - position_ = position_ + t; -} - -void CameraGL::setPosition(const sl::Translation& p) { - position_ = p; -} - -void CameraGL::rotate(const sl::Orientation& rot) { - rotation_ = rot * rotation_; - updateVectors(); -} - -void CameraGL::rotate(const sl::Rotation& m) { - this->rotate(sl::Orientation(m)); -} - -void CameraGL::setRotation(const sl::Orientation& rot) { - rotation_ = rot; - updateVectors(); -} - -void CameraGL::setRotation(const sl::Rotation& m) { - this->setRotation(sl::Orientation(m)); -} - -const sl::Translation& CameraGL::getPosition() const { - return position_; -} - -const sl::Translation& CameraGL::getForward() const { - return forward_; -} - -const sl::Translation& CameraGL::getRight() const { - return right_; -} - -const sl::Translation& CameraGL::getUp() const { - return up_; -} - -const sl::Translation& CameraGL::getVertical() const { - return vertical_; -} - -float CameraGL::getZNear() const { - return znear_; -} - -float CameraGL::getZFar() const { - return zfar_; -} - -void CameraGL::updateVectors() { - forward_ = ORIGINAL_FORWARD * rotation_; - up_ = ORIGINAL_UP * rotation_; - right_ = sl::Translation(ORIGINAL_RIGHT * -1.f) * rotation_; -} - -void CameraGL::updateView() { - sl::Transform transformation(rotation_, (offset_ * rotation_) + position_); - view_ = sl::Transform::inverse(transformation); -} - -void CameraGL::updateVPMatrix() { - vpMatrix_ = projection_ * view_; -} - -SubMapObj::SubMapObj() { - current_fc = 0; - vaoID_ = 0; -} - -SubMapObj::~SubMapObj() { - current_fc = 0; - if(vaoID_) { - glDeleteBuffers(2, vboID_); - glDeleteVertexArrays(1, &vaoID_); - } -} - -void SubMapObj::update(sl::PointCloudChunk &chunk) { - if (vaoID_ == 0) { - glGenVertexArrays(1, &vaoID_); - glGenBuffers(2, vboID_); - } - - glShadeModel(GL_SMOOTH); - - const auto nb_v = chunk.vertices.size(); - index.resize(nb_v); - for (int c = 0; c < nb_v; c++) index[c] = c; - - glBindVertexArray(vaoID_); - - glBindBuffer(GL_ARRAY_BUFFER, vboID_[Shader::ATTRIB_VERTICES_POS]); - glBufferData(GL_ARRAY_BUFFER, chunk.vertices.size() * sizeof(sl::float4), &chunk.vertices[0], GL_DYNAMIC_DRAW); - glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 4, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.size() * sizeof(sl::uint1), &index[0], GL_DYNAMIC_DRAW); - current_fc = (int)index.size(); - - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void SubMapObj::draw() { - if(current_fc && vaoID_) { - glBindVertexArray(vaoID_); - glDrawElements(GL_POINTS, (GLsizei) current_fc, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - } -} diff --git a/spatial mapping/advanced point cloud mapping/cpp/src/main.cpp b/spatial mapping/advanced point cloud mapping/cpp/src/main.cpp deleted file mode 100644 index d5dc90bc..00000000 --- a/spatial mapping/advanced point cloud mapping/cpp/src/main.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2023, STEREOLABS. -// -// All rights reserved. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////// - -/********************************************************************************** - ** This sample demonstrates how to capture a live 3D reconstruction of a scene ** - ** as a fused point cloud and display the result in an OpenGL window. ** - **********************************************************************************/ - -// ZED includes -#include - -// Sample includes -#include "GLViewer.hpp" - -#include - -// Using std and sl namespaces -using namespace std; -using namespace sl; - -void parse_args(int argc, char **argv,InitParameters& param); - -void print(std::string msg_prefix, sl::ERROR_CODE err_code = sl::ERROR_CODE::SUCCESS, std::string msg_suffix = ""); - -int main(int argc, char **argv) { - - Camera zed; - // Set configuration parameters for the ZED - InitParameters init_parameters; - init_parameters.depth_mode = DEPTH_MODE::ULTRA; - init_parameters.coordinate_system = COORDINATE_SYSTEM::RIGHT_HANDED_Y_UP; // OpenGL's coordinate system is right_handed - parse_args(argc, argv, init_parameters); - - // Open the camera - auto returned_state = zed.open(init_parameters); - - if (returned_state != ERROR_CODE::SUCCESS) {// Quit if an error occurred - print("Open Camera", returned_state, "\nExit program."); - zed.close(); - return EXIT_FAILURE; - } - - auto camera_infos = zed.getCameraInformation(); - - // Point cloud viewer - GLViewer viewer; - - // Initialize point cloud viewer - FusedPointCloud map; - GLenum errgl = viewer.init(argc, argv, camera_infos.camera_configuration.calibration_parameters.left_cam, &map, camera_infos.camera_model); - if (errgl!=GLEW_OK) - print("Error OpenGL: "+std::string((char*)glewGetErrorString(errgl))); - - // Setup and start positional tracking - Pose pose; - POSITIONAL_TRACKING_STATE tracking_state = POSITIONAL_TRACKING_STATE::OFF; - PositionalTrackingParameters positional_tracking_parameters; - positional_tracking_parameters.enable_area_memory = false; - returned_state = zed.enablePositionalTracking(positional_tracking_parameters); - if (returned_state != ERROR_CODE::SUCCESS) { - print("Enabling positional tracking failed: ", returned_state); - zed.close(); - return EXIT_FAILURE; - } - - // Set spatial mapping parameters - SpatialMappingParameters spatial_mapping_parameters; - // Request a Point Cloud - spatial_mapping_parameters.map_type = SpatialMappingParameters::SPATIAL_MAP_TYPE::FUSED_POINT_CLOUD; - // Set mapping range, it will set the resolution accordingly (a higher range, a lower resolution) - spatial_mapping_parameters.set(SpatialMappingParameters::MAPPING_RANGE::LONG); - // Request partial updates only (only the lastest updated chunks need to be re-draw) - spatial_mapping_parameters.use_chunk_only = true; - // Start the spatial mapping - zed.enableSpatialMapping(spatial_mapping_parameters); - - // Timestamp of the last fused point cloud requested - chrono::high_resolution_clock::time_point ts_last; - - // Setup runtime parameters - RuntimeParameters runtime_parameters; - // Use low depth confidence avoid introducing noise in the constructed model - runtime_parameters.confidence_threshold = 50; - - auto resolution = camera_infos.camera_configuration.resolution; - - // Define display resolution and check that it fit at least the image resolution - float image_aspect_ratio = resolution.width / (1.f * resolution.height); - int requested_low_res_w = min(1280, (int)resolution.width); - sl::Resolution display_resolution(requested_low_res_w, requested_low_res_w / image_aspect_ratio); - - // Create a Mat to contain the left image and its opencv ref - Mat image_zed(display_resolution, MAT_TYPE::U8_C4); - cv::Mat image_zed_ocv(image_zed.getHeight(), image_zed.getWidth(), CV_8UC4, image_zed.getPtr(MEM::CPU)); - - // Start the main loop - while (viewer.isAvailable()) { - // Grab a new image - if (zed.grab(runtime_parameters) == ERROR_CODE::SUCCESS) { - // Retrieve the left image - zed.retrieveImage(image_zed, VIEW::LEFT, MEM::CPU, display_resolution); - // Retrieve the camera pose data - tracking_state = zed.getPosition(pose); - viewer.updatePose(pose, tracking_state); - - if (tracking_state == POSITIONAL_TRACKING_STATE::OK) { - auto duration = chrono::duration_cast(chrono::high_resolution_clock::now() - ts_last).count(); - - // Ask for a fused point cloud update if 500ms have elapsed since last request - if((duration > 500) && viewer.chunksUpdated()) { - // Ask for a point cloud refresh - zed.requestSpatialMapAsync(); - ts_last = chrono::high_resolution_clock::now(); - } - - // If the point cloud is ready to be retrieved - if(zed.getSpatialMapRequestStatusAsync() == ERROR_CODE::SUCCESS) { - zed.retrieveSpatialMapAsync(map); - viewer.updateChunks(); - } - } - cv::imshow("ZED View", image_zed_ocv); - cv::waitKey(15); - } - } - - // Save generated point cloud - //map.save("MyFusedPointCloud"); - - // Free allocated memory before closing the camera - image_zed.free(); - // Close the ZED - zed.close(); - - return 0; -} - -void parse_args(int argc, char **argv,InitParameters& param) -{ - if (argc > 1 && string(argv[1]).find(".svo")!=string::npos) { - // SVO input mode - param.input.setFromSVOFile(argv[1]); - param.svo_real_time_mode=true; - - cout<<"[Sample] Using SVO File input: "< 1 && string(argv[1]).find(".svo")==string::npos) { - string arg = string(argv[1]); - unsigned int a,b,c,d,port; - if (sscanf(arg.c_str(),"%u.%u.%u.%u:%d", &a, &b, &c, &d,&port) == 5) { - // Stream input mode - IP + port - string ip_adress = to_string(a)+"."+to_string(b)+"."+to_string(c)+"."+to_string(d); - param.input.setFromStream(String(ip_adress.c_str()),port); - cout<<"[Sample] Using Stream input, IP : "<OYAwYnWZ|^hCId^~ikKeiD+;PXf`&(p=k+GO7YrfBX=ku0XuBNY+0C!(0sVD)6 zh=>4h34egAS-^9^H6o(FKL7n9zCrxgb@Tdl;u|D4Nl5-Gq-5k|q@=eM2OUqsi4uiv;yXwofmLWSzPgys_yUn4a3#`Wuj+Wv(91FloupuR7x zaPywlI}%P88j+82-$}WimABGrkD$3lEnEZ1Zqd;*Ff#G*@;!L?NK9NpQc7Cp`3prQ z<(De2bl&Ld=^GdtSz1}!*xK1UxVd|HdO^K?f<6U@gnkYSk5BlLn3ViACG|&kPHtX) zL19rvWmRBe&?d#ZWw$zeM{t$^JFL0{?GG_CEyspK>7qw~2`eokvUs00AysFA`u@ zi@^b07m1fl4oso#nxQ8rCzmv%`+`nRKv~OLfR;jGpx zz!?vSq6Pi6;tH_xCZG#;XnO^?1>4ma1^o$U!XdD&7vHN|0vB1F#oCw3$aWGO?wKz1 zx%fM~@bn2c*TuwFJlebVgd~99freFYbgQr@vTL+$3|pP?!$0>5aN8CQyA0E8cgFKR zZoy5kqq|@vSAfkgc!?`On?>IhAWA<3uZJ^5%?e#__szjcK8xOPw^6ZFnSf_Q4Uvko z9H)ti?~OUUZZ@Y)y`4ISg}CyCip%l8!q8y(vHW{F8VOoeh_40heafqj`()VSp1r>Qoc?B4Gh=W`KK6NHv0hqEc8HSdw02kC*A&WRQLl~wAcLnGM zA+oy5g4xNMMQ~$!nB-p&<<nP91U6`e5mzp!u<%Dkik`;1*sQ*K{riZNw{#;8o%C&{;LK^?Kp=`Meaj{8kpa zBs6%D|7K&Nm7AB)z@2M+oL_X}wWASNfK~4+z@H3#|HOrm^ir%p@)UjrU}c(@+w~{@ zmyk@#->Y5@gDs`QXaXLX*cshP#?YfY6PFFdSp{s8PE?p`q6J^?!sb-hYzNyvr ziYE3~Y9CJF+yzW{0Z<#jt*PjB!S80iKQ(3=9xVOp71jLg zfvbz^72ulQ@tFIN{S_cY6bHHjyvRo(F7MHq;~ipfmY^U)KfMZIhM|P5uK-=e{qHVH zfRJ+yXoCiNs`a;f7MVsfQzb^PvJ`sMR-Y538NLtx3Mp9`%~Y31t;N9w4Rhk{Uf8p| zP!>wRrRjEVx9CTMn_oV-gMZV4uF3j_<3e2qFRSk9tCcq_dKZ{G$Rs9kKXFb{qOQ)Z z4Vj@+iL7L3?|)^JZesrUj~CdSfAP@wAX{HugyVE&h(h-V0S-P|_LdaTkSV3|za)X^ zFLQ)uJNsw!<`rP(Y(LxC3yzD#y`qqPGc3-^uM_mk)`E|0LDSEqE&iP*wEi{%pd^v7rSI~O zMq8F**>2v)N6mDqszQ3oo!t!svD=0sb;+;o+;c8*4ut*Si^EBv3DBQs&+{W6-C7a z9)s>dH_lz1si97b9TnU4B!R~X?`~$@M~chVT1Kx`rSZKzw`xwjOPbps+8bLkGhd28 z44KO5W@c(umiJyBv|qCPG5?zy7yMmQ>dNk30a}&hDWT>oVwu+(FzOq4ZoRYWkWi1+ zO{T=ItarXJ8tUnG7k}0Uqo+=K>r`Y(x`w9V_idGQv1gA@z3XA^pq~7rXU#RI_{^bo z@3Mb|3d|A}Ie=4tBWcjznY`@Pj}QMZ*PIUM$|5DY0>uA2m8A(?N)p)Pwi`O)GR(X^ z2G8r*f}8hIq#;@-jLL2hY0G9JUW#D*Z2q!+BmdO=7f>3N+y$dQ#(-`$GiQ~B{2QL? z1Uy^*6_W7L{io)C^tk@cO8=nrk1qYMKKVZy^1lWx|8+*k8@J1jE5OatOo?O^Uppfc z-6Eqixj_Q6B_n(N(o)u7lT0|^aL0KXwp5*VKLSP4wi)T5bqlK3>RBkwVIfEaT+aWy z6Vdc29B}k^ccZZ4vU8EdHZ1P)9$w7-y>4Qoki~Q2>6k}NB82+77m)#!oFC+A{KNt8 z0qD+T_S0MciRV39@QqUZ@2~v-O3ieTCG69qC-Ss-Nq{>$I&ubvss9uHfOy~vfQk;F zf{pOwTnJI?03m8+CPb|pDEbTPmQZ$_+JEJWm@7cIIr??h2Xo>^FMpIX6aGC;fe_E% zvkx$z6^nB2GV;uV*{>^AbgwHs?&EZd8tGaRDb0DW@Qs3?7g?Xo|Gc_nfuThI3f&0d zPKY#4kr3aNp}H^cNtolEO8m$#N&@Ht#@UfsXt+ENj(C|5%bs{aNM?|Be};&|cCP@E zu*41jOy$FqQ*Fq6)PnJfth&z)fOiXCc&JV2j0biHgiiS@o#GB_XTft4;#__73L(z@ z%Q-ZQQ~cK|8W8-&*ID642fq%c=~qId`~>_jl9!!H@Sv&cCeEXtXjp}rvHjFN1)*fl zD(9LPddTfwmq60rrLaqe*=3;%)|l=q0GjX3KP`+8WoyXyG3<=FAdFI&yrVN?@;W>Y+YHCqq- z;2j{KcK1EnBw=o9oboUB*%$(Hfnm@?eo(N@NoxQd&Z7jL-x2j(rv{O%9jb?TKZdhG za;?93$w8jBws<$J4cX9hKXaUT_CE(-0Du7icu-O{Yq8O}b8d|{rbE()tktlIO#%yfrt+fZ z<>w_vdmm3fmeVwPKzt&ErO8yynvPgnO<=rTw&YKhUTfMJ^@(wCFPLG$%`e1CIbLrz-!%h8Tysu}=Zv*$efzh=&7YQI|!VsZ^Sv!aL z+|0)yP`n9+b^$b_f6g124;Z&FriSXY=~|82ISI~&R9}j3o_@T}1|Ei?)EPO!PP5LyQ#qK6yMEB+%LB3wVoYhv z3i}7V`bx|PnUj!4p5@Pt_m(qsUM6V%oSM~?3B>}3*oLYeUo&XzR!e$qrB(Y-8c?|0 z@*iIqgY(wh-MRuOo-E~G(lgm!0oV%*Z%Eau*bRPt^FBV^tl;n?A!~re75bj@cA}$K zmYv&-DJT_W1iC{O6>-)D$SZ*DoPBCW?wQ6z)Jk-{p$%bQVHy*XAbq?`5v}X#=`+>c44GD7!vq%!PXpydqGw%m+u4J}f zvgw@5z()LW53c~hT`7c=A%Q(Yzg!Mx{V@-?1w*;y!7yithm!p#4KRt4#R2pw&l2XvS17Xiif(%W(V83lZjuYw z$xHwFQ&x8D^(k=}Gt{fg>&0f$a@ce_BRbnC`|Qb?yX=+8}r(F;1g$ssRb(q{Qw zn2`!!22z1n~!OdF^}_LxHv^^KiDi!^;bm~Vd@;nfXw#>2u*}(am2vRgwl?D~GMRGig))-7K{+ zC0&o!wP{$yyb?N4F>gjpG}Ni4a4#(8i<-No!;xo>(Y|UIAEGnP0eBFO!Ovuj{TiX~ zBr`m!eo|Zkuu9);eG{B`+PoL7W;#M`Q?k;W#zq51TPl^qE+6{6L4%_GC{|eMTNfUo zA*K1b-u2y~R#O6kyW*6U%%ARddpYz-`O12#sMeQGQ80&~ve1WFGh>$#2d$cTL9wAr zkn(@h3ln-x#z)7H=F}d;y?K7|>L!En-IA0w7zt?UYwAJkyz$ZxL+BNteRyk;tP%9? zy9521S8!?70X4Kn*1$%=*~6bMcU3M3_(QWo(_TvH&hO3L3SQ?B*wU8;UYsR*M+LnY zboqGNUgBi&j{8A~nQ-Pw8^|e5?`OsN>*x*5D}b8f&-z(^&xSnX-_3S0U;Jv03oLJj>kfAA-@v;Dje4r`am(jk2DEsRj?M-=f-7IIO)FW~+H7)N%ua zt{ns6F4+GgnCgQN!z+N%gG()QkCVDvy^r{gSd0vu@?wfsky`9F(4hUt~{&-wgr6LOB`7fJF=eqxv7mve+e6(e! zqdhJ*AG1C)Yf@Zn*jQpo@&03u!KY&OWd0nCt53|X=69%ScP1%DvR(S|C8I;;T}0Jz zevsPOm#zAZP*i|>ahkQ=_~(fniLq;JlX{OEmgAv(|K|e$yvId(%j*8+BiJ;m7`Ej& zt}BEL?Wp&PyaL$Ad`|6(fms*ZGa+ zix6KWNge9mI2Fg*5NeCM*fk|f=M22JuSD)jhRyOah~guC$)8-670Igmyke`TDnD z_m^X%<&AJW4@z~9k;^^lm-9U1lLI*O>~T!^hNHP{FLh%ay(8L7=1cR5&wn`Dk z;pF|6r~%JF+w|N3YsX~YeJWM%caxIVgX9mAp5{b;ZIMxVrt`H6waz#poLzM>H4M~?$H z_9`4}IsCIVekR*+-M}q|2hg^l`F77y7nHg|yY+cdD=_Nm1%)Q_o>YDaBdgcLNAG); z6gXA_!2`}7zD=)?qs$R$VW=^b1h%~AzI9FH??alW8nj+LTuUx>)5pB^S(E`Iu)BUd z*n{0NR%oBviVj zI0`WmnLKGqEQxN}_0t9FPi_sU)JaSA%s?J=4JcOI^$u?9uZ8O=Nq)TK#08;};5-Ct za6E6@elpqyS*;rrvZ_j4;W7AbH%*;Wly1wYwPmgY4O-Fv%zcsFV&^#t^k0DscDKLZ z);oi&XSwmrPew39V>Du{OCT#ajHU#G5^&R^v7 z&o#(r*XyP~GE#;ZD_iZjQ4YxlwSY z0Yx!*z?;QRk_q`Zurb`Tdg!|cg+zN7h!M!QtZuG-IgiE$qdxXSWZ3rcXJr81!VBEP^tW;g5Yq5SBj`Ap*# zpz2iCEkyXLAzWMcvaN~I`<7^&Gu4KMDCT(^{* zrGPGm1xVv&yHabCVI|P+PMKHM56u1UG zG-StQiz)Mau8CxFy|HZa$H5+Ls~&C2zQlhSAYS>`id*@%x+Cu2?aFe)p6|cg6}P|aN&%8!SG>H|rQ+~CxDfUku90b$!YMl2K=* zV>0O_LzwJs)4wFc%@-PMC!dAn7s%xXuXPS)=Lx3ybIlpFO4C2#m!JK(ZlPyu>rLDs zDk?0Wj8R<{3ingBTp@io<)?$n0HaoWJPM%}zT=IfVul>!95qK`VY)5Dsmx(Nq90g3 zv;4??ZL9t3>;_y%zhQD;4?LR|Q5VkupHx{D5$UD@v)GYIBR_|S%iMTP0?-@!93TiS z>ujbeANDZ6hYQsi{xc-B>*KMIEjF2yX~Zzr7xwiB9qJ{{b42Sz8)jaS6= zEG>RAqcNw!ifqZKU3aWw|S*f5>J6F_}M`z|(sd zKp%!!=g`n^(z#W%-cAJag`#uNeNuAg3q$1LFz0yVbr;63BgK-?Y#7$M4gf zXm#J$t&4mafBpR(Mz3z>B}^U7@wJMOXWt*xLll+NbK+HwUL7`P_1F~~!}lZKwL4G; z<&4u zMp?NM1NucHQ892O_WK5Y+VEGxYYjf!aBo7IpKFV|%4N1RX^6ZXOc9~G+4V@$S&TIXtZBaS$UW&iIQgDe%eEo7qAJ>BEp+s%-dS3VQs?8 zu)8?7y;=FOi{ydwNo^FHHfd6*_=qLJn+vfTClDB z`Zm`rUH?(?ElZ5zNN06pmutFWH0NLMp>m zzHe)~+(16-+vlw@Bn>y@x>MdD_}=hE#SLyN zGIn<8h;Q-yw%%myoXMQ#oh&j$b+ih(K$VSh?2l{jiXwGG23w=>2W56AZQ&2T zUHdOwD4PQa0Y?uf8gcP)5A^4imU8RjDYqHj72u~_{$h}liy{9ASdS_Gh&>J8^%|Yuv5SoWzfi2GKYkUm{a1W zcbEnX-ERJf&22ia+}4kBY*J~zK$wb-NKYG5odt=_DDu%{4CGFt% zvtr@46@e~?cu#$4-?=jf7>*A}j?r9}2+rMUmcdMfwzHanD7VL;{J(U-G7;vg;^-Lb zl-kc18JrdG#P&GITsXU#h8T^Lmi)BN8Rwz0Z7{0ACioCt_L7{N7J7bmGu7lQDa+Eu zrZ+@&CwG=7Qr{JnV9E7#*?T3CeRqfXrPPHiwtiBc8@kiYR2I=li@E@7U^YH8ccylS z9$UABbU3KpcdWc7^cO1 zY>ABDYqQNQfAU##MJIvA2G}EC8@mqeXIoCJQT4M8q6v${%FE`vYlQ7&K}#o}JZ6q( z;Yu4FvC2T@bIvzoWt@b4T3G&z0oJ*i*?95^>)>y7u!nSS%Q#P3$~7XEgudXFsYcT!{MhvI>oPWdu9d7BR1VKKJpXA z1(o3MOmH*}?>Uz3^Nm$g+}Sk=T8jXmlSeS8JiUGAIC^bHTIzk>Z6fV`EbZ=)BSxbd zMHvcW#y|11MOUJ}_}t03(Ybe-xHLpN4}J~q#niW7pVHbsxi;TX9x3L^|APC7jX9W% z{AjVVrM-*V+#YdQphc(4WPTEO{0WoW?l4K$Io~`&CyEUYy}?Z+Xr0Ww z6vd4`V1$N1u62PbI5AN7#cWV7pT z_Yz(d=-z*BYCPX9ro_m_X|PchJmqaSILgYXLUS-I7=6C7xLaw7hCRcGrNY9Tjx#h- zCt()o&~W&^SZ-w?g_2?u($U&*4P5Mx^q3Y=WvyKKEw8n({3weAW_<;~8H3P8pk;3? zCC+d`HmlVfvqsqCU~>waG2a61&<_k@v(8!)*pwGeFHOv&3E4EkT#W4V35fF_3T9=0 zFD*@KT$=XSyE+kQmX4+z^*T((n=9O8ejbtR5c@nWsrMZx)!aqK6#ya!TY7v+=g+5z zHmmm&FM+k`WV8AVs)kkhrrh|MvK+jJltr&gcSGhUbU zF1`aBXR)IX_Oyz&;x+}G@5J^kEs}%TZUyIrKcy)Bevyj}P1s;egjG99JZX!Hvo@xv z#Zd0)6yov?a52Td>uKKOmCDt5u?)l!>YSspJF>L`B~$&J4ByXbtEiMZ6FFXgc%Q3o z{<>bS?3Z~tNvPNXQn~Gtt#NW6ujz~;tcsKoYF}jCI$?4d`z9%=uhX?<3Dl?L>8zup zFS7QijwL3dTANnv={%Q$x|!mri5pV26EziC?=3S z@B7$?T-?<>Es&zv{L?4p-hL+`AP0!~(=joK$c`c!i}L*HWSBf9*V3%0u$2C^aj_n$M=6`JUM<#U7cDbQ%h@ny4-qLx6m3Qhn*w|7;F$ZbX zNn2ep8-V@^-PKlQ7txDXu4$-OwiW$7Fyv>28!N?oV$_?<%7!*fXAO*}OWBn44#!Rs zSa-VzYSRZiWNlB9>2-RQwkX5{ehi<1mJfD&(B|!#BpAV5=Q3!h@|f6XAhF0|bI91X zh(sake5c_nd`})ZEIY*QiO{gA4SP51!lE|IWgM9myogp6qQ#w?PKkN5cS!nVW~~sC zeSq0Hs9U=mSVp}x+h&-XV8UdV!OYZCPZGZ>ihfZI5f=JFr^$y)JJ)fz0?+^fesV59 zaK0LdOiIe<9xgV?^8PD!_5Ood_WY*_G9+MdM#Xhqy(e9|uMdRaB>_m8mI(1hs%;s9 z--M@H=8tmjsE>&#(b1}^i>IXA_S$1M8F0QeSUwo}w&r4Bd#*FW`Ua`@iv;_dp;Ty9 z6bvs&`B`}L!2cr6o+9|N%-{Xz>EUx*OIx|Uo^ZKd?&RNyggzyAJ=gFdrudynDDx61 zxS0=cSv~A0z6_&-hN?FI^dHJZ?gz+s zRWN#Uf)BvgO4rOh;U4#W0cXY_bWfwPie7l(M!bs)_Qb`DM#nqK-Rc6V*zjA6G~dO} z$BD2K`}#s{EiR}G2iC^e;<=F3nN6q+VwKAAKPt=hEwz{%8Jz=>`oba36{_^fq;*Py zob2|~M~zyFE(uG{(~nlVFGZ_^lqRd4Y3=Ue)bS>jILr2gZKLYFMxSiELvmBO1-j%5 zan`B+crL8MhD`2L)AYb=7fcn zA+9xhfvlsGbhaWXxyhO6?mhM5O(vVDJX5=7w#h%NLhag6jg41Ls$YWi%OQHErY{a| zkMx%&$8&`QzN`%thxA%e3qgHYZ98J7^VmNzX?B2H?m;sT6k)_eKc3s?&uwbwWf#_z z=glu7pFifoBIlHTDj}#E5+fv;xl@*-Wy7JbN}Ra_e{7!!+$N+dkNpUHBNypMFE?C`tN0q3*whtibmM8X6aoJf zMS%Y-I#fMV^V20g*XxF-?h(&u9vhg?zG=<>Vu=X_*yAx6UZ;%@voAmXCv|xH&&B%6j))e+ z;7budPW-}V1W`?IhcWheJRp7KJsa=MTKvpkNb_lGj$SeUY?z=0_+5YQ)H(-os13l? z2cyF?Fuz(O(iYbVenelZGLhuo8~Bar7sti!D8hwykFyfJP)u7;S4$BPC=0f=fvy-N zT<2pKV&LOTFx2-;-21H?49dm%6UcX3-$UtB#Y6eF$7VVTsOu-iGln^2(?- z&Uoglj@60Ee8bbe&)3%_33#^3LZw$G$T4cXJNW}izW00}{)TXDd@nsudcm31v6wqC zVbbvvr>Xv{dPzFEKELk*-&FRQR9%=LrwLB13av}&XUEcW7~NGP#UgVCRMPs~-bd@& zyEg^eDf(Sb6o6-X8bQVR5pbUIKND3lb5sIpz|M}xA`G$L_NO)Way~#ezQc{3ZyFfS znaL_{bo)N3wX^An%lXPt5h%q+n7C6B5Tgom#Xyt0u$nSYYx)lrohtbE8{eqUhKK}< z%#d(#$$>4pI$LUvJwoOkrxjV=n|ux%)Tz-JrTO@)TOqYhqWH$Afp?DKC$Y$s#gHsG89myRoJ?t<4ke1Cz60127-KZyi5L)_nWS>n+9GLeFJ(t5zSTTN=O)|&I zG7?`qNXE@Vg!uV$v}%!ZJN~O*t>Ce~h)7kw`>sgG2Te#vy3dGUu6M!K6zpx#?}k9j z+b}03gVk2XchRrn(%Fs720Z9Fg&*f)Br+|-;6~fBM4SiqDa8%~tG zh(G72#|A>Q-{O0gQ?IxG|PNh!w|5S?cBn^De@J^0ppS!HgX+jTdQKIg>{LoL}?&a+GTZCxW z4rL;_N)kzul-3wmbVx1&GpFw5Z*#vsX+`bhYP|B(xPBeL(&{na*ks)~&e7fZw&C1# zUy-Rj9Q(zvl>+O=x!V&N+`CUw%Q(cx8AV~<9v~kgYusI5o+)M7oKh1z%COi=-sQRU zkb(R5Az0ofBg}|3IkdWE??Orw>%CXuQls0oPt=>aGepw-=-9QH0b_tsOi5bN4xH`R zu^U#>rA+PEb+=HpDg*cw{(*-~E{(BkR^9Z?cE9cNJ4fF0W0GZ7{{{GEpK3*^y_Rl% zBLp;*w3e-^JNvVMCj=^ucZt+ZZHRpEBmC_@jQoGKO8%YbG~HBCZ~)`$cJf@KkKGr- zuO1=VvQBvx2p0FJZrNp+5&w6cs2boyi{gi3IYW{14~(}#=q!hFg;gYFjcLxM!+sL| zT&rhr8#Qy8lT^ujA+wbG6(bTpL0(4@-kqt}QGQm|cQ-mre7t zU>M5!T!-jx@srFXR(u-)8E&_w2dyo$7{ACN6p^Tnh;ebq<5e zW16)Qs-Je_$=`3$kX+-ebhbKv zP%^9R0j5mNJ$Nq0tibv7rpk4f(KME1uStZ%$VJH00~Ts0>Q&3N1orcXe~PFm@mzEV z%anT$+1BmHE?za}_aS=sAQ8h(tZte1Q%pHVf$i6My)9Y{X`SHjd+v~EuYCV=LTmPG z05#>_kg{I=a6`r4MW!f>jQpn%y3A$TmS$_uVps@HI2&Y)CKp17oKcRuvo5e+aocjf z=}eml_&E7i#YMixIZK13j;LBik6RU0(%YLaf9>pOE!xL#(Z8P0IXNLkXma=QOuzgQ z)!qM+D^bl#$T2k_ORj(Tdm!_K>PF&%Y97&Uj3N=GR@|>W+{7$}RBLVoI81&jws((n zqyKs)DK}Q?yXQ6WDO96zRRzD73z(@TDc{buuMS|@J+Lz%vLJh*LH?zI3aRLFtK=CO zWfrlB->Fl|?Er1Lhc%bn<Wp0r`k7|x+fYSl2_ ziEm8MC~Z=@1@*N-G8>B~pASS`lory0^*?2<*Hl&{wK3*I8`s9>R?dl39Rw5o=8J!M zK3#MLn58!gsVvwk2D{m=J)>yC#Q3RoDi;txGH^*qXG;u28CMqI5}s^HBt78GTz9VO zYev%poZbv>_PNB3F|=+aMsz;el&8*=<6WTf^{uI?_|%{wDF0UVw%czDpEI}Lg&W4< z>+_jmg1I>crBxiYO_hnZi)7ZC!Yau5y4F=o#vxj*?3&7&#_y z+i^cds=NF30ZZ4&7*=Y5lQ%PX26K`F7h20+v`B2ibu;Jth-06v-hM~~Wl0UwIBZmG z82*z2YJ4%Mgt<*4|_M z^#~yQjOegXnmaOMg*eD?$|wW@v3_?M;X&Kt1oRZMm!~X8=f$|uB$&(_>@AF# zQayGF?qe;E^pFO6(mHJDCM`=miFq^%HW%UF4Vm6+i+Owq0;w#geVy00g#simvxOXd|qdz68l3Kk3p$ywMl{Fm@5BFP0`&-@y3>i z%vL5=uF^Z>E(WQkL7elg1?GJ$H9u(^8qy^!izs=h8KPZ3qylmh40hGStd)}0lW)Tw(x)GA?Gxv6yq_`|HNALfhVAr z^}S4Hc7DN+?Wt=MG=0W7P1VtM(VJ_pH(eqFMIQe7MX=w1e=B(T0x2Lcyf|Q4NYH7 z(N(m4YN}WL+9&eiIn3AD(j?P%^q5%?ej|x6*bR{T3r}dN2VMk+c%q)J#EjiceiL}+ z+Xt!`xJ|diyA$76H?OQ{Hg}XT?h^AVX&hMg+p};r# zsT=qJMQi$5AxErpkXQ0a9lJ2YRsv3kdlcdh(K|8_QD?(}M(JIIe=200`>Ya0%i2ae z*n3FxR#jyVQdW1mZ>l;UVqdh&+se6gvwD9c6NHrVj0@yMZ}bKVEV#=XID@#>PU}l4 zfgT0!>;7WO&b~0#f&Setf!=b_4@4XfcA{INL_4rr=Jr`FEwy77QSD;GgZH@#S}kX@ zhG@-j!RTJotrpwyeaCkon^et3v9Bm}UyltSS|+o~gE6YaaO>W}bMaKaK36f<@)xua zmU4@&U&w8Z=eMKni%}W$uZErB&GQ>QEWNt$Rn2OptppbPo{Nn;HvxRyy5=;~4o2O< zPwG8(%e;!hk`}f)N;vuB#%}TqG5qHLJwKrNZW%(aB3(NcJ|vMhJa6Lt?z?JEm${pS zu4})3Em1AYq`wFG^|QRh0+o$f@>4#{7jT?s@exlp*p$y3OEm}%kPt8-w zIq;I@F;hCdh^qTuu4(@#6XY&Eu|u#G^JnB80|{yDuOhQ29%#Yv$02!R+xn7ONcvkN zU+7=W=$QcY?SJ)_x3*$wr)K(``GR7w(S_iG*;g?vQz-`7iH6}TkKW7dEgiE}CoG$i zs7+2lAbVEhPC%&$rfIUsS9*%Czh{I>>Hcor8#2-$QyQVIrvXx;{AFKNh8m9xiSQ!d zN@7ZQ<-P@<_s@Ue4;oQM73Zrv7uX*)e{ynyINKN->OBk?O!e85%?UG9BAsLSIG#Rr zFUPKL<-$!H+=K+CMJ?U%;^f2Z&nXP`=gY~T04!NGvQQp}HY4zmk~7G-aLJVFduq~< zfte31t1neta#r)w8K32pfA#-jr z!W&_9fsggCm)?VX5-vHV(-E}}`XJ5C#(-tfCG3bq8#<(#uALj_71}#MI6}xYp%<%dqiCb5Y*!u9F zG77uc`RxaB{-2cwH%CR3TH7hI3z=sl&yI`&bo-I%vpTzRIdO=L*eig832Pq$=Q1Wf z2y0`{hnfjhDR{sa&Ft0bRuQ#FPQa3=pI;c*%rTb4AH0jF7FfoCnnl1-vuznM;mX;s zkbPqRq9@O}i@H%g)YKNT9#8{n*c9Y1} zULQBAs{bTenHCWxF{b$N=fJv{7uA|eM)w+t_X^%2B;y^6Kt9sH^bm`2qC`6Hj=YwA zMn*OFgnI>iqm?`T%}*Ss={x*|&9-;WSK8D;#@SuIz-&?_w@3-McGrhH!!KOGo;6dI z;!V-{zD3hF#=bt0o!2lljrROxQMVX*l>T-y81I!DTzCE^EN{BHs7F*;*f_#l;r1eE zej31$RptQCCzmray}6@Nd9IsSp~@m@2IiZg5$tz#GMDu{8e=T1nw6|;Bz{vLsCp{E zBwg|@Sz>_E?dTNJvvNyir68~ISI^Y3smzH{^6wDePvNX*>9JDLBp+A0wiw**zma|| zr$KrBjgNZgvi;(_hBQ?$tB%H-v8jQ>9~4o69ApGOtf2OZTyish;-GI7onp%xk|m!- z(XZWQm7*s(79PkYuXX+_?iXvhAu=np>Y^aCoQ9QEtZGm14C2~s4vQkxR;D`*Hebt&QP2rz5klJ2)X=ag|yOvWdOw;w@_Khuj{F@~; z+eC2rKH-=>GCY<1L8GR$))X5}Z~3=}E)^8{w_4{=dC+V@CVpa-GN z{GI=)li&fUaxbU)a5cg;=z0|XnK_|hGwVsrTT3IWbXbJfJwrrn@%uK3+Sw20E=z&Z zLw-ztY;0j{2ZKqz)BDq+&t2PIuC(&q%6Tt+L6ZAIqtK(o_@@EH@q3bP24j0u+a8;- zAPLI`7Z)b`HM>p1mSjQ`HlJn0RE=&@GRoqx!kF}q>ni5paMC#xZ|k)Tqc$;Cw8qLB zQ?%Hf>*;wez-Kbd+`ly<57c>lfZ<;>Rsq!l|G`zm*S%C(X~cTeX1qixG6G^LYCba<-`mIiQ8|g! zGRe`SwM$8OID>3=Hze26w@_VX-uy?GK#JrGRSqTf1{GqV-+YB_~?s*qQnkJ%^6lgOf}AUg@-&u6D@XHkuUki{Q*0Z34Zl`XBXyc z;~CYm+x+Pm!7^7W>>RR{MytyvM7rFyLU^$M53!SmOF|Gb#detrwPz$C&5^V{>WzGm z^Eqm`dH2f$jpZVF3w$(K)2^<>^jOA$U*f0}OPBEZ#iCuU+oPN(l*04Nri1D48E(IS zx%0YjIkDQSF4Gt)hJ%c(M+Gq#aJx!`YNg+1FZD0l4{_9b^C!wxz`6g)<1X&586%NG zLAMjPDTdZ!go~;@SS*jxKmp-Xgm32~4matYq8xO%gO#k#m26z7>koGV$sRYdWq=bZaS^_9 zA0W>}^O`cwjOT#DVcO;`O;0rYK4kN#vMG^>mtiztj|v5Vp!xcN5Phv?#CRDSM0(F} z%kt(bN{8ddgI$?>!%HjD9W|KiuluNRp38#*bp7J<+g&O3kPnrC6?b3#oc{iSn{DZ~ zzF^akuX2(2K{J;f9aGgEt7w({&p|FMzL6^9{8UG`vrye61++Gr^!^Rn)isr-Azsmn z@#}n4b8R}l44*GKgip!`EL8Gm=O}oM8;Zq^H#7G7j0%!`!^%UTA09mmOy4*lN*GY^ zE@?-_+_E2Q&vhVkdB^yq&%>!VHrYR(o(Lxp_;lky@WHyjiVQ1xhmXe{kU7@#azw#|L~TDJKHrJ_(1DP0WZOm{gEKNi1-Xo0PBhkfaYkR!xn7vs@3Gc4Jr-Bavw@?FmJ8i+p-Z zTYw;9WIeOX*Hlvz@p56EOelm&_x0_M`mFURw=PYZG5z6}$tKNHK*jG}SYg6}Fv>i| zCcyCj#@$;5#nnY!yJ!eOfnJbDo&v+R>&r1S#4{wM*g?-)d zH&g4}xo7Py32I+okm`N2>m?G#@pISr_wu-8>UBq?y}ChO-TrqM`(6_zcJE1@w8*Ubw5bovi2hU$DfPc9H@Xe-3MK1#j3?D~GFW#L)&4EEt0m~3eIFC@dKq`yti#sv$MZ{LwdIsNZENET%KO=2TOqt@HQvR&pSWT4)ii7A`1j!0V!7 zq#(R=E;{2mXJDCb)jyWM4l)KcEvqTeoTd}f%Q9dJ-zvJ=KQB1JiPS+3s$ zic`y8P2t@fhqAm?BjUO_g0nhOEei`)JNp=~eenF!vS5V2r~fS*SaP17^ViV$)Mo;7 zW*KAB=v_$WyQ?Q9hn6!Zje*ClC4WI=RM033VI|9m<;&ejdHD`<2ygDWDCG;ofc2KP zvd*^VOr^0!287RojK*u9BO2umBw4aJ-Gga<;YOKRYbqK}a_q(RdWRa%-`SqY#`&BW zU9ELDAS0wYwYi$CTxyjh`o>W-tZzZ*DFr3e){)B{xW0O zShqUHQa-o|;38r*OiR^edG265p*?j*?cM)m)LSMBdcgG@_<{cE``~CBhRDWTM3hET zD5COO-d&!5KK#)uV?ryIhi2%=nB`CA*;zR7rXn>3vs`bOx(;Z*tah0UrV8=aa8|@X zBW3(?sNlqS^UOvCL;V^%a{o#D2jOzbo$MO&Hre&DmJ@&2ECmQgI z4>=;xLBm<-8eFB(l#}8Q9i@8yYc~f0eQQzREKDItSYeB9qcdrL#!kGS(IwZ($v+aD z_e@+FbH0n^Ft!6cm;5pv$aN+~jlRAqQGz(959CM;6yfGjPKJR+dI;ISQwB4+IP3f1 zuHB^C;WXa$MpVJ5WD1mAv>mNHqDFfoC^%sF-QwFFNT3U$pVcsbT;Hd#RMqgF3(vPb zD)aG zzCanZ+~Z@0NcRI2p~yFd%Pk5Fa)uZEoss-tMSYFU>jl`XM?~IOSqqbp_EmiN3Sd@o z!wt9v<9{uqQ(kfMP#jj4YWIaIvt}MjZ%&ZSFQU_bRDF2zA~)UDCR*o0OFPpy>JW)% zf-f931yc#eyFl*eo%$USYmVk7VP}ysN4s_GoxhF3RkC&H<;In9z?6%kj@{86f`p4p z**vXH)w||yGUAcDZ=|gm_ZeM}Nd_lZ2Nxzs#xez~1}C=LBdsWJgdg-AnJFo=S*H9< zyo(p4&GPMD3vp57-=@e@7faC3VADR)pmOA%vK>>`Xl=0?WPVc7n%jUp&ZY{3F~TuB ze}ZAkgoI1BG+}nqkHWOuw8-fpA93x;O@5#r>;Cm}8B}dnVCUG5HhjB>A=cU;r2F7W zU3gB4Hp9;kt06c%KQhRKnkZK`c00U?V*S*UE#_e`X96!nLfUHEYXH?L*GgMBSYJDy zKz2%m{rHZzM)43i{-C>JjD4Q%vKpzg$YE&>hLd#mAFyLP!(VE^r{4`Mv?u$*&&0j4AQIRt53 z3S6nMv!Aels&jVj5Jzx;V^<~(F0{k37az(`0#vO6hk7kWFK<~8{pMcvOTI6@h;+_W zU=yhdu{(uBl2tYxKp)8>IV>C{d_V zsH8PuXe2Qf^SV+M?^&7rE9ouJzd$1#0bumF!e<;j6R$nIEay!I0G}7%y!wB{unr^q ziwrX;ssye5<;K|0#LMxsfJuIT3NYwo=a@@;W~SLWYPM&>V&lj{UhzHM+2>ZA*5kS? zF3Y^0s9lsBsG1dj4ctYRog)5wR zJOBmrR~U7gnZOu~WR2NeBt3v3AO;|0CED5kIh`cK-L|4sc|XD`oDhsXcI)7sAb28U zNKBa-ib#L0+;3TbTExq}iTT!&z5)1J)5~MloRudpGNG<{##mg~Nv|}4w`6z(C*{`yz@ZTA%j>Dg};3@|#2cO@X3WNC^kN9JOhtvbRUSIl^R+aAEbB zyiTj6PgRFbkrkq||8W)NhxZeIiXUW*+@NZ|lyKnX?=W%$t@H{e7PiYUX%vin4w2$R z;mb+Qj8&O>4_s|OFUlIbyEW7px$}Vk8RDD-D&Qpy39pDOwf#_Tcl{z#RgRXG^gzabIhvgX?Ee+?}dl@P2>D$DP2z=tK3D*ad z#6yW_2PE$(-O!?Vdx;ZE*S*qXD#yNktGr}NOX6cIW7qp4yXKJ{o-*1E7AN_k-=r)G zh~434nrSkwWCU(v`L+36$}R92xXP_>tjvj6e=vXk1A zNtlUJlDl(bU|nG5RI*eqAMf3af@$*Y=h%1;=J-i=^3Z+Yr`iTM6h!q=lXP;0zHk1v zZD3CvS6Ewv7ZidKAXRpwj5~Z%O+UlA>-+Omd@)_1M{0^wi|3n_3+~&&HAK4M+2emm zJW4|c?V6V4W5pyqM)H&5?E1Ih=n#chO(VE#KQV+)=S>4naasvThLZ3>i3n|>%rs3s z+%KzJRy5lo1a@%~^K#)ZbNjpKlF)`qa=|r z7GVrqXj`c>mtT|bq7HK3j^3)*=3r)^GC!U8gbVnIX6X(%)OK>Gsa^3K11P7xeSfAf zVXDFtx#8AH;=n3os6>+lq3`%(hRj@0s)iMS6zfe~VzK3oTfATbAF^hToJh$rqEi0sRck8_E7bbd_~wybYOyyDukhrcd+i zpMG>P?{3fURKAi>VVVj>_9;TLY!W({?2b+ZeDpu{lMoDbG$LKSeuW-2U+?EP_ve30 zdcnOdTBrYwmKuY)-JP8Cs;A`q7s*xxh1e43)3^NSym51wA0>X5?Hu08eb%Eh1AhE~ z?Pw&WR+xAt)Y)NWF*9{1eBkFYUuV}Mq$4EirRUbk^w)5d{~NjB_!e>8P(?zll3(ZQ z5zK_>0CMn{on^}9ropkBZpWyzYX2UWaAhtNUBCxR45@yC9|K@1J{% ztpx!p9fzpn3@1M2dXh13cdk_aA*&In5E#iXH(N#Vc~BtLX^YJSZNghJJ$2aK$+E7H zyf89c(0k@rA1xbADp#`kn^Re3cO4TP{>HhzMkm}aDfkThx-lMxBY(=@A;vdjofS5! zWiiLBSDxu+EvFDxQMz6NY(`tceV6=rY?SB`apOVER990`Jcq85`uxXSI7(=wp1igV zN0RnNmA+7nZ9E0StSS2P(+SsD+z)HK^OalzS=ts)XuRtnX^!8y$DF%EUkk7agk)7$ zkt~qw6$XC%2%yq4F_0E0&hjRgaSKuMxA56Ssrhvf>8yX=vYIR=--SwSEt{xwL35j( zP}X03xYWlIj+g`?gx;P+ktw`2^$7jz8haz&iuIZ9S=TD}(1|m=X|9R9qgRPx_??(E zwzoA)5Mqh9%jT&XlR}zY(3mB(kGyL3`j$LqJPo^e53_G~D{SLacZivXqh`*pcm>pX zoGF+DNcrMB6w8*=W_t57k7;@c4&}t;Y2LIlA4`bF85@7|fumi&%*#ixwr)(%`-+%5v=64P3t1;ufxVQcI3CRhZU|pjCH@ z6VLd%OLEy2eT}a+XS~;^&BxJOAfcb)a)nKcMRQE>_9k97{uL}Eg;V$witcjiu?{^@68NX=&p_sXV6n?%Nr z6EB)W%st0wtG8INAeZ*+@Rk^hej#$9@Du(ar!>C`ONXF(Z(Vw+&*H`wrYuPDNa(@J zg{~U+TK7NtNI6`Kt5R~v$8KB5BIYROlW?~8Rwx`-OURI}Z}RVmvv-Z0HnmjqR+UR4 z(v2iHH}Ek)Kbk3$ER#^}kP=}bvSQjwIrwWbxrT>A7e)-mgV-L2@y72tQn7X|iH9Bu zgPdK{j}Y!Hl0^5GGGzi;yOXWF!r|M5!-UzEbhSne3D>CEm{nBVw*Le!u;)F_>^y2^ zqv!?Vaq9__19^fRqoUs{W~(fRmt-4smy8k`c_pglsBxkAr_nWE6%EtHi9Ed9N0a1B z8Gz{WJCxLQ)V57;OPv?3E_shjry#eeiSDOK>TU`j_(O0zHz=a~1vuRvssx(z-Qk*6 z?|)s|_%_Is(&8!BXeKljvu4+AG@Yk3f!~w}be>t*A;XhW&}?jXEFI07807&I!UE(~ z15U*?fmMfPu4PAR@GO^62j_!+$?@(K<$T@(UXLN1^-S#f&oq67bB$PRVp12Y8PnJY zNC_Uy>%E?oH#DmfwW_2gCI*L(QLDu{0#%vsiF*vXpEfR;5Y?A0BRCVW7_x`iDskaV ziH7yF#E28OfyRV=P@72It+%DDhHFdg9Gxs)Y>r|P6NXtX)jKgN`ZXp{4fn_#7r$5z zYky`a4BY+bMjUuDZ*ZGI)~adFsKC$+N4HubBc}PNl6id=dDTIq6gl-uwrp;VK}a=R z@lStnrnVi>Qw(LcbFrk5Cu68~<~pF3m^D^t#DYOTB@TY0k9Z!k)@6+BtLTnLo~hf| zxQd?2k!2{F^;0Um*BMx8j#aH&O0@Z~^yOF2H(7vK9H48%eJe*W%E_wsl&yo$u8P0eJ-ol$m zF&*y=V#^BqVG(=av39<4sB`;H^medrsSmM0NmF94roq9U1W$Ew3~f4)M-CV*>#SxY ztWgpxN*+2ulK#1jeCLO5vr_mI2kayJBzp#gOv@}gH0Ag{8llfVoCj)?!~IU{3OtXA zjUodkG@D|_x`=AJAw<^|S{nY1O>g)*e0SnS01XG4vD-5n!X=+gHD(Ory-MU~ie{!x z2ephuksT*jV4b30kg=)Mp4*yfQ^Y@PHCS!kX~Jv~?K1mGGbbE2iQaGf*vuCF8r2k* zFoY+n6kb9&lWF>z;CH&@o@s9M(J{r8oJyR3<BTds&6n`j^gvZjN2$GncE4WC4hL5&H$p`#itXMN}}KL;2%qzx{#+%jBBN_!Qnrp zBaho1g_d10JWwWT)0xeribFw+I~$eG%-T_kf^~+O_GQnoKiyZVMPbcm0u*;j&1uME zQl+0b!|e58W5z&+Zu%O?I+o`t>Q}clU3hoq8!BgB41^Yyk5I45)ca zh%~3_$XjH2jNbwF4f!V0Sp8N-pa;0lw33r6^Do_#>P|uK6}ZBYFwtVoUL8EdVc)Ki zLd%YNLWQw?*LsP%v|zfSR&t>iJ_S_q0XJoPbSO-<^Elz=`a$SYn+gevqs; zWp+zP#nEKr(dPxW-CZ8wrvY1==Qh}&({JE!X|M;6@IC)OFLBqVs$Z5#qk&K2ecv{yS`Ub6Pm ziVo}SZiAzh#Su;8WXQF-1g#?y z5!(5B3s0Xma(o#jq$uktjof*N^r)^hPr4LppAUci=_@NWJCX#8h5Pez+IJ!CQ>MQJp+mw!m}|W|J&FOZ8c% zZPqeJ_bPR{NSP9q4Q06sdqs?D>u>JqlAL~bjmk8C3Zb)q_Kpllh( z*CsHjHk62jSmYR4mG^2qM_)|NXQn_K~y^Io&p=yI$ zwiri$!9k4#C%`L=U*<9kne`80_}3ckL6L46gMuwW&M3CSG1vVi?+}}&kX?^HzVO&j zq-k&Zk9!iP)5mmF3`@h<+NcI2#N`tl0?lXKk!^N{#${Uh6Ovf3sjBwZ7;j2T{QpB;sW{n)Z!18+WMbo7Jaavl$(QJYSG^a^%vd{Xa67 z-EsTQK2VYUmM$`4DtH~o_k9El#ZZDpR$upyA1A)t*hox=ZZvfVOHyHXnMCY&ejk~O zFlNuXgx}*KUkQTtg_(;z3EuFHL(;3t3sZH)3|v`lMvcazSwtwBcea=6=w`QGfm{U- zg~&0d1%FVf_-?MNI&oK3y^3fD>8#`Bb03OSkaq9~w&z1WA{#aeweglw*!NFy{vNaA zwyWI5A(^=T8O(zU#SYlmxfqndu|4pC?cI)C-6hJr+MaacU{Y^Lv$^>O`~%5r;d7I= zRqnSAUX8-Iil2(+O!b{N{AU@M;~aw^+Rq4;?&6jd1+%o=)pu!V-YOlf2?>M7ZzWi% zrVW0W|90H!%Ae>H3;t9RTj2>1|o zip`o(FG>Qr+8Um}yHJOe-wLlJ8I2kgQNht@mk~W*NbFOcaoT1eQMXUMlI=0e$M$y@ z(NcQY;BA`TBL@SQ@|_mJoB2t%=XX&VsjZ5sJfnOA)iFT5wY+*w30^Vl9JOW8a^W38 zU!8a2$OK<0z!R95c*7jKSXMC|1-5suYJA6%UuyQhOb*0YTgS+s==q2hxIjPsf6k5n zA%%8c%D4aD=_4Id8^w^ibLRdhOt*;$V}{vAb-}ton=0dBN4T?DuD%uPWPa#X@C3&= z8>;$!D1p(D;2a5})bKC?(^}HJABC!m$PN_LWz`|6!51%eBFS-}`mry|g)|+cZc$^T zKn9C1^_tp}`uQ+STfExaLOkp>Xgu|do-aNx2&y_O`M~b{>BpF-hF&cYHNFIRQ$;c$ zYS`xV`q2%xWN3ycvE4>|E1)CRNQHiYUm zQ?g*3`Ph^QWR%-7?akm=gXx!LVJR{sTeJ+eir=F+7cN&_yj9iEwdYKF*4}|6IOPFW z;o83&;bDy4jH$p6X#RUZJX9K$g<=wcYbWfV?2Qh-r5s;GlV_%QyDkGRD3MdxUC5&M z9WjcO%w94!-`CpV1s1#%{CVR4$alJY)%nNuI9qipKk5mjm&T-@KYcRVEw26xv)Su* zPreAJCo>_WJ(|1-@V6b6t^SAu{3Zvy+wrrRw~%fJXOHZ`zdsZEkvsP@a85w}tU7N_ zxjL)Fc>I=x7nJ&>*_J80h@R}yva^kbi*7$YN5Xq(0ABVl-fU?U!rW_XSAss(1$DV* zi)QL@Ci=hs0TZs?PUm3jeYCuis}~}T@}=O$q=lrIWW`Zt4^*w(x5?kT6Onu5l^cn7 zV@KZ6?Ip}KxajLrNz+KN(ByGuY$E;AF-I;s+`5Pe+K zMc7qsj+1xZ(#hS-!ey^94R*f)Q!t091;?Uaxq1e+-&37yQq!mg*T~eblAlZe3J6PJ zsWhB#+p8U6mDw+;H4CytqCBLU1+galV1}so?s}~>i=bpsXH*=MhZSW%f!R)Uc|SW) z3PFncBgJTeLDC73W=pC+%k`?Cn+k0o13I>_hB@5)4JHLxfbhl{fPNmUd3StXw>E7| z;l772p7U@3o}Q}1H_l%NP54IsspC&lfe3*viXi5<6IW)kka6j4z~VLQ?gW;Jt#^_yZ@ z9p~lA8EFYUKhyi`?hc#!Jq#)Q(sPUK=Ui)u8f`5uM!o%!6Bk#0417fXyQ<(mV7D>h zU4-t4KCHPgerZSY(2(G*HnNJGgn#+$W8%DYME=1VZhiLcPN2QXlD9HMyinPhf|jnA zCb4wzbr0AoyDt+6#50Q0g|{2gsAVr>mxjxyBGuPlj$XOwT`$H;m$_xR7&%D&{?~Wu z$e9<&o)D*>6BdntL!uwT-9SI#57yf)Zn2*N)gVmwBG`x_6BA*3os>b zETk%VpCST=og;aHX3mi)F=I`66XKNHja)#^66)K>>^jpXl>33~&tIy*MAmaQ1addWPK!UPmI_oCe0}NtHF4Xd#N}mli`7lP231srfudps@L?P-At` zcp%@3Q^n#V8!JmUT4?58%Q~f>WSr_`KInbjAbERHI%1(7LmOT5UPYTHbzGP>bnJ6X zBk>ep;rSnG+)xrIR+hQK4&JB(%0w`kh6T&u+r{o7v{*Z*>!`GA(18=f)HQ;Mtqc{2 zfqfZ-dxHy!71m~zAL<(a;_=AfWux?@46{cd#cDS%4amo58|DH{xzu6X7>P4(JZqn~ zf}NX4o$Ym|6f z6Vhj<>^LtxEeC#ocjhi(qJD+hQ2#R4o|aXN;a1wRLa#n-&I8M4!}0sTr!UYh;-}2m zZNAZdNZaK>1sKA>N%(s$K8p~OeI1uHAHjP0tT98(q4wr`3lEa)Ux4gMysAZPcCvG# z@3(h;%LIo@r%CC7XIyJX5(XPw$zl%!f=LieR59HUZZFC!)me4{Wsp>JV?A5mFm?

4$Sw)qmb`id9``x*GG-h>3!*yQN!F-H^RE@*J7MvTW)d@@BAAPv{ zX6q5WC%6xAroce0wr`6320Jz(HE6uK0u5Gtnai<=q|bkt7*3<|rezC4bvt^y*ZTf? z9Z~b({%`#9iXUIYG@uVQ&(_fnE;es@@vu2-g9 zuB!yBTR8ZT^*W%bSiGMYfl^93FO0uO6)3V?@}Ca0SMZ1dZ;?R;_85+H@nsS2qvXCmlqFI*>c|Zv)E(TH-PGvMa`<_%E9JNP|%U4!bK}=N=p_IjI}62OOq^EOO3{s!?4ZM*K>Xz{%9S5U=EjktgiF0$i~bMllFRf zPA-JT)S98}0nHyTAg7eIBdImdgkk#jYkGG2VDBA@1U}eWoxGr-YqP#Z4UKa%)ON`&2^q5V7K8L52iIa~H@go?A||)4K*MX|>J5jz>9I7gKzF zVFYihgRFzYcN2gISV+SANSTqTy7MP~d}S+=MHNb({ApSZaY$djS0HHx;$fWe0EqYD z#%vuOb&(6JQEfRAv~^87Zah$28pwkzCX(fT;t-M+DYX&zK-XjO6(3&3@3E z%|T6lAFe33RT6(*DxwC^qWtZh#>%H+xv)%bx}fouR9b9m5o*|vpzWDc{!w2g8Lyh{ z$Xjp8X_^e|uU*bDSEgLR=U!LHR1_N~NPjiAW3SBi$S<5{Pdv%WJuSmlgD1X_GMq}t z+o#MwS7LK|vKqwjZb28C>MgrNS1 zaa`xKGrDFn3^OYlZZ%|DT*Y&~Bj26$8rKqKvyYFTV9HR%(2fKjn;Pk9K*eJ~Flzsv z5(Ca63Zu4X^Hq2qU?5?@K`Rs0q(sPD>f<;5`@CHUDsg$DQ`C?KKR1cc z&TDScU>?^%aQa*oiVq+C%vTX;Un!yyu-zY4^|bs-VFkmkgm+p}>QPjWW}kJEaRi0y$LGg$QX z@qK`MkjhAM4)OE`Dll-CGg8$M84po><^&qMsSe3g# zr#Tm&7oq1@(GJ$p40+rA2G;X8I=6^p%uXYYHIc3n7CVAZDUXj~rlI*9V)4EMaPs2xSsV}4A}p1ak^$XSZvfp zU92_@)Q~RP2Y?a9brmLqlpeSD;p2=c(hXVhfTGIYD-2yZi5Or z&K^^34AVGok@etAAJ_Dji)8*~RdTOH&Gs3t-KoM9UtI$E6X?Jd9?Lsr>;nZ&E)>Yn}pIu`wIKND{Y0w zQX+b>f`rZZd#K}bNWqa4)8b+Ub`@ruh^Yy|jMuP9GJ;RbsRV+Q^+6@reHPbMSg$Pk zKu7=III>P~yZLOBRELJqOTo(kcd-n1#e1w%C;R$uF9te+m4jO;J{WDWv*WP*_((8n6OwlH?Olg}~)j5$E z#9iY2+~gD4Sh9F{ew_XtzQ+(KlzQ7$e`*%i<7oKY?zUmwvU!23GPgfn#pT32b@LG> z!vcpV4b>Cg5f^H+3>}TA;EGUQfOMAnzu&cX-hOj7viHcvN{U9aGyJd+ecvsPKZDp8 zE|9htrP8=Fm}am3R`qXqPeuH`X4`gGKA5f+Lv8~62IC02SMlVry%FU^fby-HD%X3z__T^-Z`T6>bMZ60)PjGr4e6BHv zNZP%`unRu_fdl4=Y2jj?-49})BBiZBh2fPd^x~;FJ2_a9PYV7|AQa|uP|HFIGM~>bJq+zf?a+0i`CO} z^L}Y1#e0m;n^+ zsu&YL#2bcG-?dQ5S!h=kfo1=_ar$MnCSGTB=+}4gMN+#t;91&`|&07O$Ze+wmGY2$hV4zMXh$rLPr_Y=v~Guuti#1$%ka$*NqjgOB-AephgE zZesh;yp67FJEV6mWeD{~DNy6G%Rl~F7jr=zH7slePq$)#1m2hhb)n&MWA4lgY}Mc` zG37y=Udp@!Ap)aBaF_|#$oif0hTpF1%c%-7mA%tXMW^{ z+F^CS>{Bj)=5Mc@EnVq6BrSr2VQvq>+fHvPjT*P^KON0lM&9aGlYiuuvh32q`LWi_ zkr+H6>e_EOox+7LZ6jHDCpb?!x29xw*%G0j(8R~?y_y-@@>FOYZ$G^403cbL-Rzv+ zi`5Q)A?M;~t-vdp_V}m{a)H6D%k;`TEBm=35CW)W%T$tNg_&|3)zkt@Y9}r&z*-Tc z(BQw3KYBIne3)ZQ;kEFV#*oL+J6un1A|8 zOUv*p>Z_P#(No$x2@DlB^+Y>eZrev9lS9%}kBiD!M;pd* z$u^)qiA&8Blzw8r=XJ(M5hMH=Z`1X;oZhBvrbVTULM}_OR%PG&w}aR3BRCvSp}tR^ zPvXZwRx+8`7C8?JDH_8a_X*;0uMt3_gNVVt-t-Ckzv&2$yNDeffbLTPV-jynLEZ4O z{h7 zunJbxaT~?^rlnru?qzR6rmulaC*V|%cR9a)JIk2-rENVIZ1QVOo?f_jnbbhVKCp_t zNt6F$8X7a`T5FuvjfNs~Jf@+F)$NL&>9E=Hfiqh6a!Z6c#anQnXK-Tl(gL^)OR|aqD*BHds+VU%PYItOQfIB>^+j+1%)9yJ9G1T5qnA>sYUB~ zMSb->j@WM%ybZ9xky-OXq*bGticf+Q8MTt*9N%oY4j13I4G{L08&?(HB`zodujFf& zi(p?X|LOT3sHPXyVsY=2jjIA~o$UiS+q^X73mrrXyscYW!{U>1T6TceR%Ad*_{`7_ zc?t86;DPBnyWpcVR8ET#Bmft}SiDCnJqr})Qq>^jRk54jUjeY1}1B?y*_EWmZP~m}` z%I-YRLbEp6b7COv1WuJr_B7TY5|gZ;t}Z~A_(eA}F~1}QY}(puxb?lACu4)ruO>_~ z{O>9weKysQdGU)J!OUU6lQQS4c!hcIvaao+mj~U_c~?30r%sO4@D$A|c#w=X+OzuU z%e~&klIm}eZA_mcgQba(8KZ*u_EWp-xeTKW(fgKfNp)%P+zHaiSdvlqb{2 zqk6rEnzku+mgBiB93|z~e@GRn3}=?v_k(lA8KItOalDR~0#&o(Vor9HJmb6XKGl%# z&c75hkO2V9GxKt0Tca~Q00#eN)~RAe{J&2*)egAA3@uG9f}?eXrelq8%WOcsk16&w z;&1x$q}vexi=faiiIczet$3Zs;Q@!n(o}rM23j>}Ri;VFl>x)3i3zME<%+qCf+NB35y0vC7rJvmj5JT_Q#knjX`%V5B) zuEu!>V)U3aAvb$oIa#@{=Zn~v=ugz|MgBvwgsc-ypx)~&_mOM&@vRvxIrzq<#QdxF zg74dPzxvYm#XZEgB=k(YTuz^qebWTnSh6gV+uMTL^B9_6M=Tj6kgJbK;U(H)r3>rx z{JtCptDLZI)WwBCBKGo6Vwni+ZPYzx@$GnY-NuWz_%D%{0;(J%l5 zPIe0=^^eH0X+JyfV!K1f3Mcv=iXl6Cbi|#F$MjjYYj#LU>#XUF-(tja5|5(|itGds zfl8%t2wJU*aZ~^oD-;~TYgZ2k%qJ`J@jCgVj#a_Ch$_ zwVS0{Pf;Xebt752QyrmSXd|j-|D@b$mbI$YiwW+VzLC5bK2Y`XXxM5I=ny4igw^Rr zIXV)st8&gRUkQ3o1Uj>>RFm?S=0`$5{VxKA|NjDi<2>t6;`v!#R6>;``aB=2dOF(2 zev@@2%!C;_Q;0v#=N$Sxe^#5HmkGa9Yo1-mkDL9#s#D*JiKmigrO(v`Q4=Kin z;&`3F4^(<|#|r{29eJke2m}JrfMEt3L&`qsG5?)v9j)beC<=Gik7RB$&Ho z&qaU5_tJ+ih$;NgaS^RkR$LuT9oyI7conXCt;l z+0sw8z4?MVtjzXNv~fH)hRBnp-dh$8(kb%o4H`Dyd)fV|T7jHMxMMd#$dyh zoZQJ}QBSP?Jjt)1?mMe>(uwS7p0HoHy}VZq0ed4Xmsux>YTFMTvBFJ0d@?13Ino91 zAF~U4?Iv_5E9{)1{tEl%*KyD#{6iIe0@=y z00Et)bzTOti@x+;S)O+)&Yi={O1)^5JHv5w5phLdX+;AUuPCn+^|dWr{CY#Mh~M#Q z*Uh_IN^fEgB-i91SS-jPv1@yaZ)S2Fz-TYC!b^~DbJqd+QPM7-!dBTtPX~d-e)b~p zZseDyG|SaHC2m=pA>rLR*mi7j{a74gS7dv51^ zt>xx(IW;ji1JeGiH(O6b@TTmA6->@zCps-UZEI^k$`sa?Aq)|!M;CQ39;Ye+tSn#M z7El)F_K;OVlLEVaQEk}JM@g0O6>40snaO84lp{9D)WXAIiI>4t^zF~|(%;@9GdSWh z(#9`yw}(RcLQckYY&0F0V%u!;#aDre2+b8e74v8ow1FZ+M|Wo_hFBS!!{78XHJ-&W zC5KZS&-E*VJ`7$}A&yJpu*O@3gH`J?O)s^2Mf zdIp9HyN9E7yXl|Xy?>2wsDL`F-^dq@$5+QD^Rs1Wg5ArG{(ZAUmG&k2S>fbNmI>)X zv&7zxN7`npvD2wLX!U#b&ba{b{#Y!G#gr>Bb_1cj4l%74?c~NK&UaHr#>`NTy>PP( z&t|E%p7*V9g@OMewadD+WM3XxpJ!z?EpA8lYNoSP{WkXm;NG0d8}m(wN9NeK68>?| zCuVbX^5)m=Uo6%m7Z@2#2wQ&EV<MhVQ#^M)ULhR1uW}}u=kKrS$y?p@;w|`zW{#KLlv5Bmy@p6CmEgnj! zxi!>%1Nirsh|j3H$D=jm{fPXLstRj%mZyUi(Q7K5w5Lrm2rus+xIDnd8iR)C;n9L2 zx0GGnS|GW}g1(>Vk13QGw+_evcyJD|7(!P?LLL-0p5h8T-ecq+GyuWlss)k@c_#!? zO0b6AhM1C}mW;!U0meiqy@1=2!@1V=AKx^N)!Wjoe zD=WGOyB3>igmQ_EOy$Qmv zAWqI*S{eq@$_SQud+0lnY<;q5XW1#B-Dv$jm?%Es)p5_kNA%gp$Mm&XtNX}Tl{=V?*wPw6xJ5+=(RufnHs zEIRz!()}>Rv8^9C3v?jB)Iv(XF!<*tcT8%mL zcsJAKOoiTj3&a~*!rYnpO+EwN^X7zAkdVh#Jq;!-Prw>Q*hi+g{#15Z)|d}*e-Qc` zuGi>*P^UBi>D!Bf$17-CNlAu6M^-v{O%d_fLgOw9gOu7}$$h1!X~!x})s#I7iuuNl zj!vks{FM@WJ!as~Ym5TCQH}fH%0>yn5!8ME$k&28o<;q{1VEob&_?6usNq5qb=+r+ zK)s@wOS4Cu5uUpWj&lc|0~x^@(i$!SUvJK)f(tV3_*IdPN&#CJZ<Cg2LI$0OuH9L=F`H>*O_o>(|sAaqDnkB|2 z_i-nhdawWU_W=Qt+q$1~BqGSXxKki!a|Op-OVi*y^u3Z|FC|b5EL#an#IY}7Rq<{6 zZ^n`DSIFI6*ketZ`*i|w+gN#2v02u&M=2l8Ben&bydJPb{JWl8hRmK(Ph*vt>l}tg zfA%E?oV2H@k-CJ9;_X{=Ad&6nLOYAv6;aNX!&<+5jj^kS>5=tzE>g*IyYhSOT67b_hh-x zUQ!$FMbu+Vb?YO^7jQv{i#BY7J*+WFIZb^UpA&Pr8EG(9%;#OQNaGNkdoNK()+1_z zEn=I)>!L>ry9$Yw7juX<2=aU>QlYc~I#%j?V$LZ0Ov~CvYW}4hd1oK>Kcu?5vPQP) zl1iN`<()57W+D7^MX9wCa)ur^heljset{N+c3fa!JmbjFmQnA777~8L?nhrw^#kui z!yB!XRa|dDI1lZlBN$wi^45`J#|Y6BrujGVRJvd9Z=zbrA=8thG|_kQgi>tzq3z$2 zYGQkB8Q!$BmB0V=$p}tq94)?GkVeDUe?N2XYg1yd+itU|@Q>nXD(e%XhGPeFSCwQh zBFeERGa7?hA7~S#JJ(XW#USFMDl5Z!q_OM6yH*(iv9^F}Q1R;ig$qxhZ9h9?#=h#p zikRx=sQ(N$o8AD1ha@{H)Tuup%+dh`*&@@eLL)c>|cjg$+#QZCuNx(D>ekL&QLmfyxv=my~muTF??g|>gLI9w_^ zDb}AGF;C658nWgf$V^PU`bHVp)jT15CdqZs8WV?5xIpox$Z8UNTt!?4GYvV?J%LDd zT%>y7s9awwqIbPtJNYFE`$28!KayFUF*8^S8(RtJgQu8qVzE|Cu&3qDh8zFXv<4%G zn{X9r&mA>GGszqd{PN~MByTXuSG?s-O1|Odb4*mbVRY|@+V?VBT&VVmULjYyoryvu zu~3!CA@+RWhTP8AjnJmu@r}0(0N`G0mQueb&%LjP=B7i2)d!y6<7mFW@W}8(S%e?b zAi?9R24k(~r=d14F@i<@WriitCIviKfvS4HW(t7P&xK7{SrsG!9r61q|^lx+on zTgfapxX0B`(~f4>|A)J`h>EL?!gLFF2<{TxgG+F?puydtkiy*|NRYyUTX1(MoZ#** zgO!GQy}pxxo!76oxp1z^NHu3xYJTS@<+%cj`OZvE ztn7?`i&Qpj&rK;&S*M&&(W8(?b8B?px^{QY0G6A`SQ=P9lyRKnvq56=&A-t?3Ae_~ zd4D#yJ#Qz6Of*L!op`H7s9VQ>fKs7|_0NDqu24yN_0TC8HGv}KAce*>#jcruSuZ<< z;-jv~60OuY6IIi<@TS|{n(pRYoY8+jj%RsMI5p)y9!@|rbWzPDg9z!act2viB&|hR zz~|Nx+7F&qJn_o$T%WK|>65xKuDuKTRV4VTqD*V&CoQ62FMKNT6wra)`dc>%c>Fub zLp0sI`MgsG1Hn?(CKJPY3Tp*2h(F0yg7!v2&^pJaPJ?IJy)c2d8$Y-1Y`de>+jbqDN%Xu0Y!;$g|l8Z)vo~SOGaxXg^+S zZvXR=Tnu&|OFo^{#gO7FG&z>oU0I@;^v~J3ptL@yG>G-tXyFQp&ygh3Q+~y9Md34N zXq&^W8uZv0t!|b`f_JId$EVG)59AjNWqey%5n!O=<9CZ)>YB+fJJYIl2KJQ9Ug2+#0nkCAH0 z(t<3Vr=uMYr``J>^0U!kOetXuI&*?yCe^Pgez8?K{%O8+tOZBXep0d^;jv3>-$UMF zQTU8ny8zSN;UcrjZ~08tO+MEg!2ZT=opdq9Z-2ZbSft}AUcAym!#bQ$O4l}M;K)4M zr0~zLm$%ASlfqYjn#bh{JT+)!wT*r2AZQ4?*(|4o(_QLeQL+NbvD&3d5MSo}L_oCd z#2bu}H0;c*B4xRMSCJO9^6WTRWUe$mKFR#Xc1dwV!(80(8s8jfg?&K-cL^Jq^7W3O zOPP(^m_(-QS2tyopS|CzMT>ho7jMTTgFEg1Ipf&yim97cGfOhOeoA*sdBdhHkSsM+ zDB|t4ig;oBbwa|57+@Oc-d>ViW~@|cU}U&%d;d_^U9jerSu^x4Tw|W=9HvOk8}!&S zC504R&=qEG0JY=SAM6xt)7ii%1Y23~>2ebq=5mLM3-5xp$%>whyS&(2aAS1crQb(x zClV17KSz3{TVcmvQt;i8HcqkNjO&5dhGjYRH;jx|)4JMznkO_N7x9SO1jlvIwGExU zkdL~*5%xdtiWa*#RT&%M1+T7&{}}iS8xkyz%GqL#cp>^7OpnTn&GROCGP|y5WK_K2+S0>Gd+`bIo+Q^;hAVx4PsrO@2M(gJhhP8U zhnYEU3DnN;@$x9GGWVu!zGc^JLG{c_qqPEWZl#!Qc$YgAv_c}5?w!t_f*R%wE;o-W ze@Z?jWn)x_%GJ>7~eeYXr@t?+GO-`7sq35_#@@+DDjDr3DKJC~a_kPzQ9Hb6?I#lyeUH zVxj^UzAdv>j3rWTTY*l&a;-H%YS%T@csL3~^ZwjUKGx4w==H4ep08M}jb=&^DQ7f* zj>w7nZtb}$UN3uI!K(5H#sQ~rgOKI^M{FLa$uAbvoGLt)3kG~&{4wKsVL=b8dzpsD zPWvpOj`X4q5AZ5p_u_3TO~PNi*L-;-8x=cn4ncA$(fgLzedIm<0A$O$IWC7fCg)Ze zHx!Da#C70`hrU~}<^4WC$p7rLX3@1swQz>cpJ`Nc*3YcaDUZibn<8xa={N2&-XzVC z-@j_=n?rkyuMW0Z+fqGcKI$Wx%jES&Oc-HyntNjo4 z9QW<*TR|#tva8$xIMW2t>)zc`LTBU0lnEwB9uiH&-A%NzSR7Wh8XE5!n6+!6?1L%J zDWOFn`|*GC?$we)LX30wQ%b;EkM+5i#3E1Z#1tqpF_PJc=~q}gHX)7HW$LT?3{!r- z$)M7S77iaZInH?Oz7qfdyU7tQS5D2g0aH`7U(5c!BM#l`IjbLcnm(Q(*#l4dC%sVc zO_AxKro%yltKG)M!Lo${H}6?vO?Am}eOXhI2DC2wjHwNl49AO%PnAj=VQY=DkApAY zk9O%fun4jikztQ2LEhkG{?gfrII6V<1t|1ROH%%PPEE1F@BWF9Qj>u&5P{b(91aIs zr$4la*c7CAq(MxL^6vsi>d(zfG{0y!dN`G?NA0&ZD^XK*H>Zq&B1H0NgW2)gh>x-{ z?SDBDo-FzP3#3Uhi1Bu^`DslsBM_>kxh6M#(}>Q|DuvvdF$8UP7#fl?YAkskGbf14lTx#0KRl>Uo34-a6si!}rA!OHQOykbOV$_yr zR7Lj0LnR5MZ|CE%#Nk@XkwfeFtl)e13ugQraEvql+JSa>uXcxraX-AqKbg06>n+~2b+ot`40$ds*)HEv+(>4<^b^@$6IAHH3ev5;uFxCK_n>0mykPf#$~a@2%F;uY zeDBhnC3IfNY;ljAV|M=Xc9|AwjNjuEagPzuYcmeIa`j;JldDqdpYXCs zR0{RO{RjyL^a^xZya1MNd~#g*bK{TWyzfb1 z6UI0DpLbSo?8B_bjN=&~gT||;s5NmeZqT9L+N z*N7X34KX9($dN?2wVNvS^1mbW(RKAIklNpK2ExVpTMBb0MdzgOI==WFO&GOsA;>)waZ`2zaKM?rF^-0vh z{iy{Jey{Cr(p_!R(6W#X^uAY+opUxN8NGZp9a`IIr$gl_f#;VA&aTh`07?F{W_2P`g|KFO1TVhB-`-$EL?>!%$ zQaZ-M?aSAsFCV=_ivQI+#Gmr0jvwDzvliqP18*{CzTv7u2$z$jcBvyeP-JpWBmN;L zfT4H)?r`j%j~r~%;y)2LH3>!ty|UugITu&dr~`<|nS(P@Rk5dTMs#_%`a^!K)NKDB z0Lw&r<}G9993rmZkpPi``OMCxqUZdTsifA?i#sJYKyL8eeMxPYq8_n~is`6$Cv(?5 z(SL-{c@3HMBLeG8h$O5vPQ2aRwn!UZW8Mz#!MNJMOIG(t;JF=Uv5DVk0g(4lL{b?n zZw+FfVh3cYG&FV3J8aPKam%#Jx7^+QWS!kM(;?%WHc4&n{A}-IRl%E0z}3)izU=v+ zA6}YD-JZb2S+a>Emi5b60+Y){%f?l2(s0ZExjTn!`ViQzQtU1|&%9oQou9Dh(~ExG zR68*Yf2GjFv$)u_!R!v1Z)&~U(5APg%{6emo~lqmcVWSv!O98?R;7#6TkNzb%%eWi z=yvoqs1{gPLdW)DYE?dDvK~tzCfae8yr4-y1?CDa-es+?8&OOv&z`Tr(De0>-dI=> zx3R#Nsb*(2lMQiT)AiZAG;M&*M}kW^E90E9Q$?lk z3fhq|q9%6uT^|k9H)|z*Fn2{nnpz>1Bg22`*(00E=OK9|;AZM5shcG`8Aw+DqQGTIs`*5UmhYC8nFH^1(jI;F?e{KE=vQ>ZgRw+0p#+F^j+# zNT7=9VzD~8v|6|(wuanbloYouvRyR$usb!Qco@7I@NgRJ$~VIcSRnR@eiIUvBNQ;^+KG(HIEpifo%7{B6#2C?7Pb9rZ5D~$=Zuar~U^}U96^S3Tl9ojiT35 z4^$ya2xW)UM37ziP%QXhr5;(;+Am{S-=}?2DEXT>mSmz=Ni$8H>`+!g#0c06H`c+_ zb;lV82hKdG&AGv`6j+r@ZefzHd;yB*asO06+7G~HK zKG0*zL>delt~EzQ6wFhDgb?txE@*i9Sy}1g7u$}=tbh${$;kYRA?HJkgiMuXuZnp( z?KwwK>S(6?`VeeS@dh*0Yy?{5+j!@$MgujIlS#7scjfMcVLADIgOVHn$C;=WK5xun zW`3Ap-+v5J(u-zS)x~d%EfHUMh(xC$N>3TN^6BMk1cIVhw;Tdgl)oTCQiWUI=6&Pe zZgCFZfz_5tYiP&#Yz0=BRn8OY!ppK3D+0%ZT45?fj*xsH%io7{{QE|XPHL8tMBxs3 zGDd8v&fwoH_)vx3DW6gNtlbSajhTYclqk4~bk~qD|4GhgSPbn1`M)Ms>emK{nI2%Y`6ZjI!Ob;MP?Mx=eRYkoo){NI*ytPLPK0l&>=xr$dX1<+9r zx<*n5*@Yz^8sw-?*wgaXboiG|uFv-+X*IV;p!uxRO7n}{fe*RPs0SV#sLYSD( zmi=!~nBFzlb5q%xWWm;J@;6A;y%*%`dER<>YNiR!SUxS03ORYAms{KbSYcZ?6~!Zu zH&XS>2u(pEongV>X#BaX zU#WSEI4=XlbTNQ#URY~v=jZZoYn3?@Fvvs>`(-1%NRhmHcYLANX=l$`5w-TtOFMGO zc2fp!h&`)Brp{f6*Hb<`{t6%n1w#~HHNtC}b_j(50hqDSja0UN|5H999z`CLFzTPG z)4mru+ZqoH>Zx(h!}+Fk#f$@uHuRM>MC7LjuGio)b7oNgO!BvmAfyUaPKf;mize_ zsBHuvRFEe(w+&XZw|Bg+-yH2WH_(t`ToDjP$G$g1$7Zk1w@lXoyHy+>j^`cMfBude637 z*d2k~Viz8Q@bVWgng#Dj1)XH(xYpJc1nqT2PbwXTqyR*h8Yr~Egn~q%7Q*(Xdf<&g z6=!HqFUzpwCo4_2c5~E-9hJS&o(lwi-K&)MFmDGZ$5fWpJ|$ETmjb(Pnaqmfev+yf zbo(~+jyz4R`&w)8*k#{9Hjb{N$_$O#hx3;>T&a)BFQwjKOiX9sQwiD`O=}!@W5<}^d?RA4n1(z;r88B}UXMF@r3ivV$#wDlc2prLLWn`NcPxe!!xUXDC z7Lgw&4IXM*O`l?-xTkatelb%1N}$HTeqNT7u`577V$bu?tK8eK5Si%MN z>EycNoBwHs{O|;Jp!~0F@|uBI9JK2!^-0XCa}sL8BvnQpRGkT=kQOR3va8Z{>b45L z+_FBE>F?BjG5O^6R;gmi2S9;g1_4U2_g(d`g|&UwtZKG>(+avaQCA`7qAD|FVyYvm z7YqDK;5KKKM7zKy!^_w7O{s&YSlm*YY=9I3x!-OTL$G;WYg4li4$F9Y%l_v?Oo?qA zSxo%KXKn7J$BfCZiO{6w!B55n5qzzkvN2;mdypG5$3I+GoHH1mV3z8cW`bosus|JVh=LJCj2kaFr;_ct(=&GK#&Q>?`Y#+YALj7I2dt$yRZAOhQ2(loH%^%syNx3OpNrVzo7<_y z@`b=ecfE6@w|a2|yE6+yA+Q}WET(wSq#6ae{H&d;gM2ckF1uYJq2_XPx3OH?th%cj zt=*z8Ev3}dianfju?LJTqp^0I))Mi>9`gOFx#pQPwDH?voVUFwcb7FeBA)Y)JC7;l9Q7pylxx&Jj3{ z+t`cH-JmYX9&H@B?2ehlGIaLGJrvVt56sehO;F+QR3dS|_(P?h`K{Po%Z5gb@60kR zIc3|e=hE0FzxXiHao@PpnwThQ8?@TfJ8hW6Y2X`CUA6}NQ8^d|O|j|csmykHeL8IC z6lhPOBc=m>IenJB9y+#;a;mbNKf2i;^1X6PRGX(9&a+r_ytr2+AjBNx!gqo{9Q(S0zI}U)|prV&gbNgp10KkR1Px%~&8CRoEacNiP+v5_PO}jiCfB&@#16pzHu_yJL!N|TvrF^wQc_I&dqr74?r99{}elYy!xlttmh@J5F^dktoGxqO4obzTq0OVYUB=NRO>T7 z%;Cz9ca9~m0*{lsj{580lI$l{2MD!q(hpqE4^=J(HIq=rVqxOTs*0A_n^`*6{aQ=w z>T(A`RBc+EBCX6)KgqILqkRDGaP%#K%yx1ETjZVJ&0x2Bfra+mooOHRY9+3*tyWO+ z5Z2_BD~BKMpdAHkL+GtqN8IHl$fo0~w6D>?Nu4ScW0ktIIFWGj@Px$Bj*wZ_ zO5=8^-s)e4C~~W55qczf1&T=iu<)(CW!?!N;KYQHNo4QpXjD+I$L2zH@1oNaQ= zlcCm}U4-z%e~(o%oa*8XNq^^^W^G+G$BXwe>Vh{;ku<~+50(?Pr~l22Gx@=}6&j4O za=M;>?HPYR{>GyEXR*eZbiBk!;d49mbEc+tG{+Ad8fYYF+nIaX_n_d4zI4~S^nG;x zecB-zDwEc#8N|wA87e(>J~sZUC&snEBT*g@9q&5099h#8glwl%>*SPwyi7MIWFM7k zKN{lzD>4OxjG9V0z@b7KruO*t=pEZglF7ZHy?78>zdGzD5~3te?{DK!bUA{MMr0V4 z>kL!4^Wsft7Lu zZj}W6DhJxRg0CbZBinNg8!yeri)PyxnuE&m)mFCr+%xzW?T4md={=f4R!HOA5rTwT zNM=DJP;F%B9og@Tky6~<07*0)WL{lUCJm^O?}3&Xm<_BrXGy4`mKi1+-v4CY{FqFv z{0f1DaPE=Q*3kym&QedLNE5~0fY8xw0M^u^F#j&{S*Mnxk3jq49nob1l3)giy4NH{ z7wHyh>^s9p-CS3YxzvgJFh|CA+J1xe zm_C{&901ptB%=N6*kxB?rhB5h)9+TeK+oi#)ees9=V@vxk_F$si*eP_Ma%oS54o8P z{s+KxG*C`D)yUzgJZc3`p%nFoZqpjzg^R;8zeos9O?Lm%i{#?e8FI62kI3^wEVn9y zt}{aX$|;-`MGvhqh!8!rX)77T!<2jW3@|v_>*+AE$!=?-E{X_&~-o!QVoegkNx=v!psB(cc1T#!^&15wfAb8f zI(U*x=P!rfwh{*k;U8<)+y!W#pWSt|64;~~#Kce&XMPJ-pt&>`Fp@%Wz*JRJAkkOt z9d2*q|5B#E0&G#4)m3mN&|^;-z8Lu)jK)OkZYsAyF2hEutn4~P#8bx02HNGd_XJzL zuyt~RZt)cA!P|x-vX;i0&dxBr*Cu1TK!Hm<7H^&-cR_iwnP ziy0yVw|)=1@*1Ei3($6d`>y)IdNkwakRs}9+pH3wX7#<|EHAO2J82g>z5;4=<&2>T zk+#)ZGU%q`XAg3*uV)7J4%CY-Y0+QWk=RtLMzVU zVX@dXFNQb}Asmj?Me$1ZWk%+8yB5yb=&#PXZi*UG-KS=#Y6r$XT|I> zltIrwq|;>g(-LJ0m~924Y(K7m*XxE|kerg9*kv7KAWX*8?kc0?5iNO#tiX8IK+BrR z%DdLLTqj`@z~67oSeJmKGB|h- zz(tLU6Na6R^SB4AYiAtN`ikhc21(s8{&|}0+X#$ME}1wf`T9n=G=*+QnKL3K?r{g2 zxP)J*TBJh3ZV?#Et~>JZGc5QYH@ybuMwh1De_EBiv|3Ux%V;zdE3%ax!HD zo!YH+l>4G_e4fhLi1Eik`cnp-JPm^6b!?(0iSA@WLH|pC=o~kWD_X#84 zI~w4wjGQ-t+Ci=9#B6PGgx$n-Al@UKTL>4M99w?~R-kucv3^Zo;`?kah}5k>G;*37 z$v~D`NtSDxa4v)*OB+n&HUdaaKqeQYN)EPjB-DH#TG(rQ5vkrv%iAycS z3@ykU=nIc_SL%!MCzG*p;TAET+4fHx3nL1fMd`Q8hl3h3Y2|Iz-oGFH6zhH1&TW=* zVeSonagJl=z$*QS6ZCN96PpM$>nNvMCP(Kd*~|}VxBr>m!QDc8qn8mcv5=$!7^ROn z=QHAb?FhF8!F{@tk4=*6p-PaG$`!f_Xn5mNZE(stGw%#{A@%7tm9|I{l>MH~Vv#!x zX2P)bYRBrAi|jw8IA&vaa_n3mFVC=SjD{+b?t5%^W0NA(H|5INZ=%gPHjSeJ&$MZL zwH1hK^9T3Ko47Gv;Wl4e^m75I<=$-yq7b zPxCH#2ldYXWj5!6LPpkH+#Eqai7E7~Rz0B=2>=G7eQ+c%*FV7uVB75Yu6@wi-`d}- zHXSl(T)l^?EbNPp{3tv1gKS33M2m|+jdvieb@39>}KTidDa*=t! zv-=#@{xxQ4se`=2e9P72-xI3p$t)*W=@qMh~TQ- z7*XSFtIt0Cop^qyte#Gz$1GVcOwUn?m(2n%G2jU=_iJm`8{pCf;q z|6OBlUDfTS4c`kJFYdwR1c?d}ZU|9x>d%)BZTvnEi}Sa|1f7=dMzsB*#`d3Kaov z{_s;g363pR@d{kh*GKfpg=z=23YV=y5{T+yB=)jzd_77I5YNc2d};XBP6#u7_PjP) zuzg}VVme&bDmdC0gxtarA{h|doe)nN`ppELn8uUvO!xW8aOba{-K%)6CWo@D$U?Wy z8n{_8(eg>#-q{f`xpTvo+D*`*>k~`wnvC@$9M|F~9#(K(lz!P{l%P)Qw#s70^hK|a zRY3Dw84!mz{VF=}0V2N-_wJ^1Hex%YlzankT73g66nnc=ZX6JO;et>BEi8LlU}9E% z@#&?a=zQnRD?U#11!jtU6(G7eG_oi8DtK45Rs4cC)UmDZXVtDF8X@la<8N z$PudoQrUWw1y9-%^^*5~ceHo)Md3#J0>^4k>sUooQ$hpR%yr^l+b$y-L< zd+Itq?9Z!cf+& z%zr$6kyLKsmN`hjsrWO5De&xppR-#_h(WPEh~L|UbXf#!%}&6C{-bgmr8G{NJKZE1 zY=vYgMT?$MnZ1h0@lJZz_IhEsrhQr&cdyvAEGsjtA2knn6MJ(vMuFyfxXDRg z3kR)6R|`3X9sGhe{A|p|8PEG=1MV6$nR%7NY?v?j+9>{_^abjW9P4`}_$E-}CN)pa z^ZU4@t8Fwcv0yw2OKKK!g+)_VZJ>&|l_(7Pw$a;hV~kr+)#aFBWv` z0vGGMcv-*U4@14dFLHC)y0o~gY!5b5+bDlI#7~n)t5qX2CpTO2*HwM_e|lNV^jJjF z{N4)|sho@8!qJg4v>zNgJiw=$kYo}y8k8SPB@!q*E#cBI99iU9oKcs-m-;`x#>i6b zARw%tFpJohUF94@k-Mk*|waympb>NExwnR+%Kwv6n(^TgjI) zwZ&rld&fX!Qpf`ZX`4dli=*}IIA?6Xup1*~UlCXNbIw-qu@Xhv&iGGf-Z%}ICbIF8 za^fSJgY*~Ez3kldDiTKBg%4MqBG(h|e}JOa$VHMzW(EI`IKy1>SE5e3V&h68f8~JKSF6aa3)L4rVDcy6 zI8=82f-~1!kems=n=+N@k4sh05rx9--mfp?Q#BjLBG;1v>Os>ZTZ{hzQvP5E z053;b{QpcH^5U0ulSg=;3&-iGrrPIH(0?IZeGa(y(0on*$7{Z~vssOvQ03g~YqQaK zrlW3jWDAwM$f$Eh={*hm3uHy4R=f&Jn%{Xy?Xat@>F}C&_FlvG%ue#XEZKy-H*@^0 zw$FpHhbU8J$t)IdWXn@b$=poAxg`$6Q|4EA`O=*S2Z_#|P%;L;TYl@{9+{FO9(g_e znyz^DxV>CqoiH$)*UR&6TPcI5BUq;{g9rG(^uU}4;@8<+b!Ym|aNA=KCt-?8$b7$= zs<$GHW5TQ zM^KLh1>hF)B;HD@{;hV}?0%Tn(Wu5(&7QQ@+0U@rCAd6Kuh zUA1#hN9RiFqt>7qiW>z)-CilvV;|=uzr#)sYhTAk!eI)W**`n9aTk|XE$z!k(F}2g zA2P0)5_6;94p3wSP=$#RRa*W~(P3ZEsL}_}h#JItHAewNPOFujG3iGUm zocV2nn^oUth0Szfm96O02|rgQ5mqW6rvS81DsIrvO?hrRY%tF@$-WIlOy$V_yvE?s zj1x=DR}MJJMx0hGV5gv%bC0S4v3?X@ZB34+$y#uYpx{-Rt_rYPW5NZ6<>%W?rU=5j!tITui8u1d=04L5#|CWYMd^I(cpoGz zaM;I8H$ru-i}Dc(LO$bCJ~Vl3k@zE{%G$DifK$miLdK9b%uuu4grwGewK1`l`Do3e zRH=$}c3arin3FJ6B;dVogHGwzvOyjteBZkiNG4HeGU--&;%gXj?=@EtA)n3GC?C!T zify@sy-p+BPd)62Cs{Sj;a6*WpJ|VnBBghtUdL8C{Jhnv6e=se9%}(V_voebzBqTG z->>q5F)&lS0yJND5^fmo5K2S1awgj2sfwJK`Wh5^W9Q3b@8j97JGZ9$I?aZz!x@$+ zsAY;Bz0FCRgzf5GtxD>x^{Tr2$W8^l-aL*F5^5DBXe|7xA-PRn;R`D$Naefegnj%q zKFT9Y1nc`!(~fWzFLH_l@v0#rg)Y**Z4bsc`7l{@j>o`tQ0SM@g+DvwBwDkmRNB!> zx@iZ}DO{NHBYoMH06}<-885$#uaIPltcp!3Pe&C91k!>G+EW@_6mE^?afwhH)9WEu zf^Z>d{J9FOtpeV2D3B^HJ3KTVf11Yl-5`+?RRHk}Ym0Fi6>v(oELGCF^e0Lh)YyVM5I81yKG*TlA!n68k(~xrk8XVs{oHKxEXjre z9nV-iBFhnsTkO`$kM8k^#tIGE6k`6pbZ3C%`_jq%=IJ>K#(>j)kgf7z_GBn#5B@L! zyG{K4s(8lUO>%lL(s;>!uGj(=|PVi=a4>z7Wr2_CHny--&{{QG4J=j%SzjN zsG)79*6VSQ9ozeyX<{aqI1bS&GNu2Au9z?0H)gx%M4CcG0A1)xJGEE)&Yv>~Wt0A?Z59d2(hsNQ4Cmt^4@{_v z0oU9;-5w>CI&A7Q_4Wk2B@R*y&&3VvgxW1Xak&zd8Lw~sO@tauv{Y9fd#*$u7xPtG z!7A!-a++G{Y-(D^2% z`Z-o_ac^w|t66d=rq+hl+801nb0D5Wd7e`tp{CZ{85A$hp)0)*i&2Nzww}Hag3Mcq zB3t`Pl{NB|PF0r@XqHD#t{I2xy7(quB^U*8{(V|eTz83gLv~yqLO5+!^tU~$$<@Gi zc4*SMGVX#1r}MQeFz68laIj3kX)8*%XcnX4gtS`mWX{nz$~IRO%vvZSA=s-u0*JM6 z5#V?{`41pJW7-_9k07&QBUC{ASsSy_$EofU`RG1b&4lG$!G8dw$N>tn2&Rl0UPf&_ z_Ag(G&Hr+B&_qRy!+~Q<5msW+6AV4A_s(bT4Bo!WbjC=Th}!;Wp;bVD%1XpHhDYtg zb_Qe4w&W_C+T{|Y9yE=dHB~->*sJ~L$is$RwK)b0_OfdyWEI980jAb(uS+fp_T58$ zbHLv(iY6wK*FP7sKNDPC$P8h@PWO3G6Y?VF(2LH5M#ki1+|7`kZXiQv26oD*X4YH3T=%cHi< z#mH5MaS3aUfKMflA0Hvc#~55*`yArmnmi(zmFR5wl+mzRdN>pS_*by4_&Lnq4=?{_ zI+f7(0^}B-mD4Z$Z`eUoGa5A;zpZm`yjj8WG?nQS!?gp}z?-t+d?!EeV))%axZ~0o zZ32p(+Js4pdTXeH@)>7#_+D9|{Os~TT5@>qSWiV~pP=wuhnC(t2p^2Ec_%3B!Gn6B zWDnFLD{h=jxhBw!!Sw zIyp0E>V#qRdZTd;<+h)t8mN^GhypJ~=+VrRum!9C*GCj_7cZT!X z{aIa0q6Jquvj*LhuK%9vUQSPo|K&-$alO-S2dBq-xb;48#!#Wb`yqvy_%jkRE!s!z znx9f4_Dz;=nH8aH73Tyd_T5k>aN3N_b|qREheH$A`GZU-NHwRwc0xijxv%V6?cqdm zsN?to(9wpc+)ci${OkDY!T4l6mh{lD z-V+3dpHWM~5(rHf|>4GHy6(HBbzSf zmbVGAFC$d{$Yn8AeY=W)UQ1u|o9mNSbG4L{zZJ+L3jcB@szb*;0Jwi_AbA9b25zM{ zV)~aztaBV4-5}SrFiXH7=U@aP#+VPVliJD!3@^q|qJ5d&ZO_9OJ4ea`h3}-)>xVY9 z+ZK7o8JBv`+0UJXp*|a#(zhGrmb)9peWqqV*YNziM9qB!4q|Lv+*kn`Q0_*5vO_mwjBZ}i|i9fUCWsosUr>CN&xj-T(S1h_2tMt7L`I@Est zA|S2Sz+w|P#gF;pIap5M*r>=CBYdbB*HE0^b{VwA5w|XjDEAG3L^MQD1^i$g^PGEW zN$Z>xU!67^g-mUwUDOC2)!$bg=<_XNEXL>;kc-}`DaqS>Ih3j6;(I+%rP|JZc)q`{ zDeQk|^y?7(oH;aioJ?WhldIW7mW1?BAK#z5L0R%Bd8rUK((FC9hABLR6`YMoZ0NTi zsI>}A{M+7900lm97&7)v!oTQSi9}fjri*Y0)-qtnI{Oa2N1`u~&Wwe!ajV-Nrot1%xbWIwf@uyc?R?un$T4|1kGbK z%%?@q4wnB{Rqgho^DRzv(#{e{36K_^4eu3ZcUcH*y>~xiPQjz0yS41o$X@u)WS5Db z+dl4Ct}n+sRts-MOB0eLG5S}qQr$Ln2~uCvi|#pwA85`OPUe=oa=Hv|CR?jMXwIAr zD(<{RxHV@EDU_zNVPI>za>atkSe(3nV2yr&cQ+Z;fW7g*j;5%oiQ+o}0GKHip%)!b zQkbahe}N|(8)EGf=fx4_{3RRzzM=&X7q$T{J5w?(Zb4{GAwAoe{qw|SweFVDF=1JJNPC-@~eLn{qij_SBEgqAOg%Kn-o8 zsw5)j*Zp^%dTjsu*!d^d{{TI&-zsI=UK&-e{sRQtoRE-r{mW`eKQ!m(Q?dz0l(?r@ zOfLKDb{u7L*`MuXGEeh*SIrW$9>=#q+d5wpn$4oXoW7XXN@me)7;*DHAk-ZngwBj6 z^rUX*%W9`m?!1c?Oe*|XAKrMkkyw4xs zW46U?h=yY(6SX-PT)Bqap1Mv^rrqCjWnT9Wq6BC7{{~9n^Ts9H;Xc`F@^SH#S(haD zFVBjKj&oDq6MEfL8B=Gb(H13hd;BgQ+bsUdEMfoI%Y^Mg7R9CMfOAV5!e4 zo)hBih3Rs>RH0>t@52+xoDkia6TR@gD6Sx&s#wA;~{H8 z-bQC^ezzs6%gA~5^>>9GgN3%69}??9X$d{B>t1`=o*yqy@^t08|2N-g?SbD|@~B)( z9a6-PP2BB3>WNC2O}@e5{d)4^&*PK7<>YJyD^5mqeNe)syMN=#0YDNYyBij6WEHj< zWir^GumTqnyDDUN;m=NAtsT=pv9nF+B274t#y-cARDMj!BCAi*sS(E9gju0j`3z{! zi>$-w_n9O^GeJP21s%O||IZ5!RaChQEqRka4SzdVRr!_)uC3f5Wwz{?gnii!Ae?>) zS_NHgua6=@&9V`N8n`$DFJ;L{RJr;YZ*Pz5gdGtmK#rKy(fgNl!WtGh^E*1|Ze69uWyR=OYnWmdLL9 zyl?HcAhXm>%b~yflCf>X#7Maj&HcOO+Bzi{K*dgGfAolG#+op-|Cc%f*vXoDFZ0%j zlU?k;N%-%w)w+-Kx^w$Bki}*pPq(&AmQu;#5*4i9_!%-z=*qSRNsb1M*5CW*@&@rP z_w7$8gct9;XPv$rbz!qm2bAJEpaTRpvMG>gauHPBb_2wWGgR`6dO>4F#O~Ao+&=Fi zBwVO$;QbHM&Z@1g2I{tN zuJNoCd=nrT-3XP2QUlDH321AV;^KNoapRO%^e2n;XdZ6H5oSn7X>8PDp9A=DtGq0@ zk=9F(n}{M3ZYO&4vf3QAK7DL?nIO14GtHx+@hQgw>(x>n9=q)1VEKcN3Aw8{_U9)eUcw!PEmT@u3^9h>ix&3 zlz$``oxSVxkYTz7df(}zH`u;*5B`)}^l-lW#^7D1?@v?1I-S&lAsAZG1|GGc($&HL z9nH@{$pl01#yS6bT;t_$O^Pdi;S00f3QWnKm23$`AE?6yJnzOz|N5TdUpabC)tZu^ zuu*E&bDEkB~=q z{ipD6wd|1#XtIgG9}!hKUPS5W@wKGdiaT#ChJ7Y$n&sO0{%xbUS{h`vn6l{cdvT;K z(I#}?w9}RA>$}+!uCsAX*GTJ@y*Vm z%I9yF;QEfiSp=G(id#`Mo(ZMCi&s56a+M-nijX1M)>Srj>zobCy=hHz_q;PJ)iSB9 zh2#KFIJK?}rS!O~O z^elI4G8PIJUvGkM?uMEqh99H|F8Io8>UcT~cFeEJgx~XA;o54GpmT~%?KeSd=xR7) z6`#!vQm@!Pm1Ve@`5CuYmLrT|p@{q#1XNndu*YcvBqU8<) zgnpY5|B+d61RC-)I6Cy&@2fLO?~qEJJ57q~#TCpoSl`T( zyc7#H4`dT{{H?xl23zYl&R$l#Rxq2Gq46(&$mRkhKgS}hX^>zYS#?1FUQH#4J|x!{xW(UVI9FEG5--o!Q!pQ5 zB?+o^{q+C)uRx@z!vLjwo2w~#x+~)D4qQJj@$y0mV6BJu@S)Go242p#yw_BO_ zq3-#Ar!LJ2QV;($=pFE%#V4==5X5h|%zb1Cp)CZ0_H&!BQuAI)hD-lq711NrPbMNr zC-?EA)PDBFRv}(DCmqr?VQ}t{x+=DJsvwXHM`HD(^*jyk4k_WTlLx5~mm6rqfbIn8y(_OWlxoww9{@hYt0fr4ZB^G}^=5*D3F)=m=w ztnr{8y2xj>uh(iD^~D)l&5}l_3OB$8ws21l|Cqh1SR4NjI8%}8oiU24 z{`1_O_<%1l7}U#mKBNFKy>`CHI;>!qE6jM&k-4Z!Hsep+k!&&hCBu?Ym!FVKN5>74 zy%zE)?3^lxn3{T5YcuFc+nYI?nL5M$WKd;SRW}~J2~uj$oV&v>v1}Xc5TVD1N^Zm% zA2rQ9HP^ZuYq0Og*ZxV00un%$@9c?6tXzqNyAqt=Qc(11Z-wG3n)XfSurxmfbWgBp z)eO_wLq(J!T3uAl-hwIy4G~(lw0=Uh1L1KJnxq+CbvUmXB)GfGQ|=S$$#EO~M6x$e zXBlAXCVyH^cC#k~R07g<4#FB~g4HyJVLiK2&9!5wZAeL)m()XwG6yLy1c)P>j}}#&A2riq%ivS6Dx9uv#i*9a|0h1({;J*pVmZhPXe2L_-VrCs;v((;5 zrQm%Q>o|5TlZOb7`~x{SPc4joB)I!U>^3dG5a(KId95dho^4Chlup|mEf2(fA1Dm- z`iM5=j+%=}cvTR)U?9;LeQ?l!=I~bZMtYFW7#jhu1sHN@niy#|ISj+k*Xp#^mmMoT zW;uHsZxA}I0=-s#FI@!Lu8p=xn)`uvWtPp!b5<%VCzs#m7x&&D zc(5ccL`-Ot-d&B|scqTY!^hsByLh;v-@7=C_|Mg?x8&Ng%gYR}TnQCj46Y%;v%V?3DD z$5PK*tM}Jt&Vqf-Vvp6fL!70GIK%ky2-}WgX-u>Y!HSiT$EGn=KCYt5)^h` zVOy-ZC{wt4Tho_B_faca$`Rr}$u5iv8_mHRlr?jO^Hr6!_;@8n{KoBJXmw)c!4%$? zi2$A&ic&fu(?xw`Us5-VQ;w6RdgkykR zIA3vB^ITCpk~vmAQsTgD(R!XPMj|5L)8`XOBWuErzf7!+XtweST3;!&+$V0t$*-{| zvm#~Si51+a|EFHZLKk|Z4*fG~L(x#*rj||Eh{5BcMiaO{OtkxLY)qms5KJ0Ir@z`K zARYY5!u^$39iPmjH_BS!7Te{MW=Z4+HO>D3_)I*p7`l5$L<;pJ^>X=IO%bT>^{s8K znT#clt>}|}$g!dexkke(izu-5fWDPgiiSsFVhV5R{={rKf7llbF->~G=&63b6NO#L zGja|Xq#^i1tev{9SJ?+%)3a4dKXJm!2>tgT03Pi^3WoR)(9E}yE>!<W=A4VY%}@<9tAK zYI+AdSHUrJ#`ySAsxu}B>TeeapiB~#OXhoW%yCOsqoS@HYnwu*a6y0rb&IMizdJAc zwmXe|hlYmlwmkMNEGb8<M?(zvXd- zg2Z~h_HfuEgWAon?)d)fwbkm7zO%+f5SEPtMW!idO@cUiIU4 z2dfcDk=nw4!!^*_0bOi>9#ppz0rRjbmZG_P>+uXvIk}IXF8&nA238!Q@9IOY=YkO? zCc)Es#ZB3dZsFHdoRVL38F~rd@p=jLk>ExAZevPP^kxrds6V@bAAl5bE@i)6ez_f? zBkm3>D9{tWnBVZLUOB&)ZoP@@2u74rX02>6ug3GJJFPcd=Oj8RUK_WsRodTI5*FGZ*Seg(dM~hmP@}0_+P8N!g^Exf}DC zrrK#JZH|WH#5iMJV!w~V zNB?*yo6~wFW*cW7;7Ezb78lcVprA(cUvqSuwsAd}AWAO%V~RQ_@y4&1LU_kd+7{zu zZ4F#REVm}?3gR6o%>E@}>5U(qrn_F_3_Ihu@&6Ch0 zJV%0Ft;=Wc+?>FYwmUV=`0$SB-&$0S0tB3UspqoO%8dJv=DpSk7IJ9JDSvRcn-?9k zX{UMZZ2K56y8H!R#&kwQh6^D(7E=PLJCsVcPK;*BJf9)OnmVhx@|ggnORO%R@4_7T zBzuM+c#8C>;H(|Zi%LozYq~@r@SsRD1d1=+HIJB6jw*;>in)r;us?COd{(_ zQ&2Uub^g?}btBwm<<*5M(BQDPt|yW6^*G5N4Lr2f9XE;)>A94KOK{3toHFkG9{}Ot z_q;~O9oyHx+gERYyKc_6x+MgS0U!K=zpLJ0RI#7Rra-wuV?=Uj5{fj99?G!#`~&z- zAd!Km(C$z!@!Sm>A16pfT$s{aKK=Bg8uEk1{yeR`@a0LDbg3Mg{Lo7l%BcYNW1x3p z)9g3oL39oHBKO1jO!HGU)_V))Dm|Ma4T_46z3U_Eui?dsMyu`J8#=vn=62hpcEF{* z=-Hd8sgXhaSFcf#o?!}5bE&WbqIJpaJI>K_P?)FZIAe2CN9qcThyfeDG2&cw=K0Wf zgr)eEmB|uaCN@c$n=Y3EE3FKYOgOoRr}zE`I{|}w_iVd_jY{gi5FB70AYe%L2 zD~yE@r}W7W$v<$k=O1^D-th0PZ_s7Sa>PPw>Zeb&eSgt&QN31-rr}?aeAd+XmBOlV|d!Up=7YB6dGg2>0T&>8_nSxA<`*x!C&h19{^_<1c4AY z*cj0^U!8tk3&6?FJ)Fx#-U!*j2x$awfb_JcavLDJ;s+GAInF@-UXe`K3QuoV@%f_7 zf{B_nC{p5Ep61XP-?(`(tWJ2yoh%#Sn7)}wjZA;7Z2aK<<^04Qo#dbM@y#={h-oLU zhP;#k2c#fco{`WsjK_~n3Q^?bPPlVY z zm6~!0F3^HMTud}l0be(M5dLzBgtUCgMrX{N6>i`w}F1q0E=K%1js=X$zTzS(?#=!Dj&ueLKZ3f_Rk^O>-va-lAya zJLdNc&wAjZ(I?-ybse`tyWHQE)ldosPK3X#ao?ONGX0Z>Ak8GZ)%+E27QQx;G!Xgy z{;&HeBz2OFI`G*tw*LX#Tra0Aj=Qn$+%vgufP`@ypaVM*Ab_e0$C1!+c@%KiMV~Gm zcGoGz6~D9dmsm$ruVY~KWmb1OXcvNsM9sH8tc*c4evR4Ds@soTH*Y;{O;1{WHW44@wDtpzT4pR8TO;BzpJ=Of9hJcspsQ1@Qikv zr%c7hpK){x#tYaBI8&I@ZV+FwK1fCX)2>ZXa5Z9LS!8wC|1@-^Fs0$}B*RCI@KD|? ziggB3s@syOxUNpwa=^jtR-8;J*{&es zXhY|eJKLQ|s+mcs4%uC%GSb$fFJZdMArswo0RCrlO`CvAyC*NyC9QH#8ssq*Q8|BEWsRs<%3A?Lfvm$Yo0E2uFw%*Nb#rT~r>BuPi^>WxmqQ zk|iSDse+>5xX}LmOf2A1S}-mUmZv$>vEXPt1<#`zX>x@qT;E$YMvmTjQMs=zbF$j8 zq%3##Jr^6P=)85BoV|kl1N3Nvq-C?JdxiUxIovs`jkbw}edRxw*9!Mu{@q6f>-i2w zheAu%k~Pa@57l!+8h2t@i5By4DKj-X!;fLg2<{X{4nvFwoSG%FSIXAYU{Bt|(;Fe7 zzO2Fvhz{)0_vhZ$U)zr{&$`z8so(7%&1m+>(nyB^pup4c=>;z40$qXHXsK_+2TZ$m z{Dz1d(nm-t`Z<=xOl@kgo)x6pns9`m;-ueYAd0{iLlPVDNVr&!K!1?p721F$b5jxX zh0hGlyN;Nvt&~lP{a7w(!3PdVbEUheb~w2B*?Ty%OlzI9?>>UjHJX!?vvQz(AD8e1 z052^3RAS5ZLZ3UaxUH}>5c_`CG<0ZnN7wwcyU`(j6}|ex@tMW8(k8##6D;uQ;)@er zzJsZ21o8(*4MD&48q{nIxLt$b>fANG9Fz^ka$RY6ZvVN(QN_#Ip75s;Sfrtu_Yzc@$X4Qn+dYj!_{6-Mg9PhTH7ZeIOf-h_@Z(~81uwXp>a z6Rs(q(BtaU)aCeMjd7ro8>m&r=kMG%5wR9*SlgYmzYqXPXtGi~-BpSlp zHe|0^ZNvEa3xf`WLoh)v(q9d_ddHOZrNcL$B9hASXS0P&UYN$Se!0q#7d%4xiO<*( z9WqxkWN$61e&xJ>K0Q`ekh4A-(Ap1hT<+nch|G3B4zTL{7v-#z_8*|R5`pc9aJ?+k z!NlL6)MKqvKa_a^E`Fckg{?~;-FN;2oPPr|-xq`nW(mwx9>nc4x29Oe*!LqoeWuIl zaNFCmR6*Y*bG2Q3{SUDH`jV~?5$V3UX120&LSO8iX3U`oZsK+g3(t(rKRj}E_5|FRSWHio5hvNUz=cp;>&M~cZ_6!zoSdwzV6TfBcM7d0+T)$r zio0o&;eT@Pg->rcDs%H3YxrpaPYRz-kZvlhLtk@+2BU8H1tB>T8sHMGRUJ#bh@z?$qsXHD7(mhG zdMQn^ap`=#BaoVK&?M1MVZ%#AM<8_c=XuW*-%IX|qnohsN3r;>z(6_itcF?UYFlbE z^C0Q5A*{f=6VB;QeK}$WU(`N^Zkr+;mqlI(x*Hk6%yN|*yss!f@a56OV`0dlt0*FI@S3N&_z_;pvzXzQf*Hr` zd)?FuJp8hWIbaJiT1|INyV!cIp^=~*Bj3>yb7%2jS7~$6xBXORkZs{TQ1{c9!^wZ2+A;c%-;$VmCXj{9UM>jOXt? zv&e;R;TaVPl6T3N9CZ)^YPn%H;(0C^U~pWxa3Y_e9qqurGhPJJb%kDCv@$BxWJ48d z>sVFkf9eOU@OZG!VKlf}-$(%GuN~b`DSnLT_iAR>ufvlHZ3whKa=GJE89~wK)O%!- zI4Sj%({uR`5aOG*5K>ORnNfUy0K3n+l2ZP^h!mBf28zWa`kxDfR%G#_#^Q?u_|B{t z=u7$9D+gw+CN@PxV5x*jfvn)H@=^LVvzDlMLl-~v#}$G*7`5Xm#ASqVLiTUrPv;+^8&TI=Ep;f^g$_H;YnFbH}LN! z%i9hk?3iTKiDABZ^2jv#I4qtja42+`cRch{=_DP;bN(3rqCx`|8oJ>Jmx+Z*NW-fp zgvlP)vNIz-!O#^4JGoQ-2N(&NFa4MDj>LM)Yaln%SQ_)-y$7|tSs4(BK+=tBQR4W9 zkdwL}2k0T>pENNzzCCu8|2V<%g9G&KL^U!pW&-kSaVo8{x9kbeV6Ddbh*=`db0yWAhxCF)J8c=im6C@17-P}7hwGik)24Kkq}_jj zzShq6%&HubtTMXs+VhJ!Cs@u)YTslUDIoX7sZ1c}H@6J%kLsz%UzZ*{2MQv9g;QykE55wfD zkMe3U=cQEfnae8_ZhA~`Cp>?9g^G;4cAUj$n#{*tv`uuGOCvWqOXN1L)5X_e$Dkp* zB#e17^2<>1B2Y9TFW1zt(a6@`_e9G_pFQ>i9q znEsZx1=>;mL9)U`=R1;iMC5&^uXDrL)d*!eYtVTqz1Q>D(HU?2IZXDF2Di3F-nwFs zhz^Md4tF)aU_>5t+zJ7C6Rei>CFI*iuiAwg^>4^K@R!nWwKW72TsWOJKOa3yl{$b; zjiC#V$$ZW{?WxI{`y%G4tHHw*Wtrcm$r{}9`#5zUlV=ZhcE*3jRvyWjGlIDX6!EYT zs4qW`n}!i=$ZO7AUR(-MSLzWu%VTvd&>S z3^`Y~uV^ZwiYqYYM#ikAqcIWr5Y-z(RkTlIu_4?PQ{IcPLGdD#E-!Lr}lV=)4b`Xop|p1M!$V4Qotlm9*s zCL5P)^Q>+-;khlS9XP8mupfepv_*3C8tjb`Nkj3E{}?#PX4Mv4Sn3@!o^y@@#zx}k zsJu;`$?`CQjBa7bO5%2C zp)5+;%-42E;SqUvz=hyQRizD8TwjA>;FnTRbGFn>%N@W&9f9a=A*rV?0jn!R?q}5 zE)oN`nwwmy#EBY=kkWJG`w2{uh?~B|wWR0crO-ysn%yj}$1Nh!+mka=HOa7FtmXYc zi+tN+pJJ@MIt+5ER8XBWZtbX_Z&cGVCdQMhSEL`+NZ4Pi8+z*VkA`KE+4y+1 zoN~S-ty{m zh-|RH)x>NEj`H{I!3~Y8e1-}P7)^wy2K6J-d0W&jcr1zX=~bepZ1M65}&Q#_nbGrYwt zd>bS?7Dk-!L^3PTtn_p5eiGF%z3dKU5b`S1%Vz}sXY z4MJdchJ$}j=eg1`k>p|{cTomf<6vWQxf>b3HYcTFtL`CyEfQulL@yRb6rdLpwcA>k zy?hb>DR&nw72R8CPXgxPs2}1KsZq1UzB2h&0+Rn7i+OEZ&tjtzco6Ca=*)>BlA`*?9g?aMlX%|(leNznBAB?%s7STUn~p1bu`*qb{g#3*2D^JiqQ ztCJzxLo!OETx=#EczLv+SD#T-Wx?x5ZiKa0F%-&gGchOqo z`sW(IQHptM-ix#-i}RN}K?pF(D4p*heI>kfvlY(NYy=s2#_0!F9_JP^(2ed?vSk*% zUcIY=ihvlu@`ao&=A!5|7M4(~6}r_?cX8byUt09EcI|A5H{jA$5L!)(!wHGfs}s49 z`ekx`)~NISYOn34b0`ln&r`VlEgNV{3!VWv^nK|$4OT}Y0ex%M1ycb5(7FhK5Ex*RA0SLu1 z5ku)Id2zj3M|*lsDQ2882;4gQ9ce9g(|2~@STC_@0kwMp$VO~zpPsxYIc~QhVaf|X z$sll4$xIchTPBB*Ccd!PFNVcK+X~iw5G1HJS%xX=pFHj2{Y^hf(FD)gzbTj9>xa@m zo$(f01;ZH>pNSakJNBAf&G`s=5sYHQK6(UI_l8vqv09eYCE!G2oyRRrBGJOz6N)9P zMDEUIH?pL?@SWgmpg4#6jK%+f`!*0CuL@orA&KQs^ew6IZj>+%3_VBiZdKYOpJrh(a4$5m5c`*mp>xVg-wl4IBz zjk&_sXT}IMUJ4838i9z_a;1?s#eNGJw0fl8I*1{X=UNQh3zFNC zMn$Tf88Os`3q{DyS2`*2riJ~UAu!QWO`?be61yW&xE5PtL3K{TT+s3OC2GsCd%!lk zdAlc&OZ~1Kc;+f5eHkXhmhf%f60yk!R=qmssf&)?CP{tKPs~(Jnp#xh>o}4G%P^;> zup-+0{j`e8{qnsh*7={dY*tGU?%)(tX8rJOl_p~q|CT+FU>bMRz)~F=G{Ku-*=Lr_ z96ARVz?qHn<`FA!JqXr*r3+E$Ok0G0qUrgi>$T}h;yeVIuJ)R*x4=G9{(e;VSu6&-kQv?epXAlK4$iguq==&4wou&oGq4JEI&Xtx@A31kG4$z zI6WRn7uWO^kdj(;M&6|;sf=jP89A?3sh^p{iLf{m_1`jD4zYUt`{Wgb`!naJx4BBWhxprGx41mF2t!pJX zGN0GbH;O4oj0YS$`Kt^xt`HJ7*Cvkfarp( z21}I_y1R^JQLJ&Bmfh$(W;YR9lf?wdJH-BQQm#U9HSw+=0Vy=zTY%Hh27?f+9L#>9 zs3QG*LZ#TiHohS(WU}uLK{T15gCR)zzDm94%@9jBquK=r$tKM=G>!dR2C`OC&Y-nxB{bp_#q!n`|xhFvQilnPS zTl&g6|L2-{zKu|iXLNV4*1G=7l-P%vZ*)F8YSF~-D4Dys$=CsjjpbvD<#sbi_pgLm zL=67{NV5->?5^k}vLXJ0L*PZ)f#0}35PFf8Aw-@lH~wAOx$UmNf@Nv^6`OSmzPQ8R zLUqx;p}Po8!flc0?18z~DFWvHuPa=gjxY^{46B`&_O=8*(?7T`2(^~Tu{by?0rqYb zOLC_9q*fB4Lvgrf;W9;C&^9~$oRob#>!Zt8XA(MD*&tSRy2^x!y-AvGHkydk0b6yjd${hrlp zp*FLSBCF=n5A1c#oK(8&z}l6xXoNzU^`Q@Nkx2xA@X;N1rT9p*)fBUTGq&#r{u$+= z3S;t{lc_|~K@}asA1gjPAYiSoH(bT@TyWS)qAEawV!!c^LPe6o%Dt#x%rYK4${z?AP~3uy%zz^tsKKi@!51qw z(d^Nn0Rwcy`B&bLgGG66H8g!Y#GX>OF5}$@1<`rS>}FI_hTUww?cr?8>ET{CSsB(k z29v%z$WiX45LxwCMYfJd#cHTQ1-YR+YETo9m_E{ft;xRiyd4QzX5|A|bV>`CFV@{R zvQB2NPRHhcnUdWDaBya)5uPwEed#kWUBr7|8o24VGdoLRTNhgTl~8X>t=BWMIzsHI zaOOXDE`%S^Az5vqPY}H5?Kr!4GIhH~+c=kzVgC!UInC`;H}7)?h+!k?u0?35(VZ3_ ze^V;QAUX7b?QtwgTd8>s29HvQ{%JEnbGummJ}a4-{!>FqrcW+wHtr!<12t{yHJ@O0 zL^RtO{LcA9_*wTvA6C017p9kep*4@6;aB^cR-va1#~05byCC6ctkVgqdeN!gz4YY1 z+PF}b(IATZ<|{X~#*Dinxm%5KT1S4KgQoL+q9VYXKB_yhg^!Bq+-%JwVUC2vaMx|| zRHAjB`9DAn_>%b?)U29tEA0#+m)m5_#5fKauFA@+pNVs!Ic}o0{l< zbH{Du0574O9n!rTof9Ip%$f5({hvyOBgQU(f~LO(*?c?AG>;h0zNK6q>ZL}$NDr+u zi_#iF9fJ{*@nVHCSS6@@w9y+ldm2L5sz!95WhV*bzQ}UyC)BfdkY2SbUvFeC5ka&@ z_t%)PhvvZXm{MLt1TR_Agmg%No#qDCfcmv45e>hID90fUPTzbzv6$d*BZYp3s--sA zpD94;+l^VgFT|Q{4Y%i2UE`enhpSzWX3zm!sf%Jlq!y}9QMt#c?HJruZI}j9|8#?V zK`05od2wz;c`FxMR#xDLzO#HY^qEg6^J+Jnis5e6@V1@aFKV*mRla*Yd~ODzzAbj|ec0mPC+xvN5yeWHJp_QVb8aj7>OR zGyF-#3}MxQF+vbMuP&^=bXSGR<*ea$dOizwQF`|nT(Vw^am?Ag#_)e)753nOs8YO@ zdM#JN#lLr9%04{}<=|-*Jz49pzSKkPikhKt_NXJTiXi15tA6l+E?iwxD;}R&owK>6 z@%N7}7FpAjOVvmP8!=_D^H|S&C1mKn8u^%v`05~fDc%50|6sdo-6mejXBrvi2InA5 z%%`U*N6k*H+U$Y3zRns)ROIB~EDN>Q%e{+^QwPnFKU~`;HjkY%lmK2^`fh(F{HSlA zyF0wbft+A#CBOX4D13rSA%}jzNJaOfN3c-<@Ks`lJkN!&C#_NKp5_bZXMS&dIK<8lVF_OYQ5=7hDL1D*o1aO+N14%1GWwlS?x;hu_$MshnvvKMVAdu# z9`w?5N_f+U4?X`)Lr<}lQe0Ws-8WK*_Xk)Zl<|vZ&KUElS&1#f$vV zg8!|Uq!uE|PR=^nj61stG~F@R)cL7HpQGH2r7&n}Y5Y6F@8ZXkv2i@bC=I@{Dqhb) zgSVMZmh2|490XFVH)=aeuNrW$y^AgX(rBve?m`h6jCP!E@TuJE`(lpbT=vweviJAn z*gw20%I*e6j&XHK>n*i#&E$#k_P{E_ek^)gyjA^97avdN%f(SbeuZZPMOa2R<%v`z z!@BFFckgpaWuV^4!#P;U-6X9L?|N&iu0fekCAQ3{N6_+6LWdFPRLQG6OBVv`Zm!r4 zcuV&EYQPpXTXs&F=2gvPVmc2Zwc_(a`kL=suF3jPve@vrDcjKzu--Le6N_gKe%I36 zojM!IrKB-Dv}JzPygCmFa7N>{v+EFbcHR-p$n)-M8AHdG0Q%*TysW~Ox8+0c?$-%I-b*%SyT$cNOH4P><_SuFWek(t#P9&WiVsH2|L*j*I- zx2SrY&hAFzz3pwNsPw9j9LG{g-$MH$rSwO+mgOY&x-8hVBm2fI5-N$X`a4Kmx=Xy- zJ{6R>YtY*b_bOfTSoN=8gfg8K-FiuiF$$(>O20ulYN}1z%ciEWPrNA@x=tP|8T!G^ zCEb4gA0YD8J-;wHtk7DYdImJVS3A#=b?$To%2pq!E2~K~+hg?JO!|B&Rek;JX+Ubh z3uCU$d4K<@4NXguiCq4OI{5T5T>c{XS$=qR@U*a!^>9Bax$Z!A zw)076F2%{9wkZ9;AjhfGS79XX9Yark`?E>YyptW_3CtC1HgjIl@S;9%n5DfT*K;zu zkc_DoJjFKbaCr*xnf67k5@CAm|6YG}9yQ>ho(3w_($qQ8z|zZ?a0P#1-rqySenH#~Z3OQod#1SCUoCu+#9K#e4IBlJZP>d%8>zi)w zvxp9jfGv^eZ{*)q1espnasgis=6jP(~_iB#rJql$}A z%>LH)z7fYxBht}a|M{19UD@Z=^tPr}`|hpqBM>6V0w%Jw*lc$;2h-x5&Cax2INcPI zs&)EY%HQ8DzkFp4&Oz}Zd;MN>C6%^SjedfsU7_L8lv8QdCb6Wnyiv9qdTx}pV$PP- znC%)gf=Xkr$&|r3aoGju#dTdB;zRcMGN6w+)1ad#r2@W29~N6Q*F3W=it-tMiC34= zCr%F2hjMm_iki`4m1|6C8=QZzd&hU<1kEr3iSgkIkxRIXA67+)&o&g38^5f*u!^Q@GX3)v_Z?_%(isC|1N zri=hnzOyVZ!2qD7fptOpNyEmNby7LwW}VIAm0a_-T}tVLbVRqIZ;*C#1h;x^wD$)c zd9i67BJRxQfA8vLQTrG1>lbmZY&RWif{KrH8h!r(BFG7xh;vZ; zcNLM{KtuY(3BQ7gfj$e?<{Y2M2$Bx8vhi-B=IX`{c#H#h`EE|fy;S}Kd{kQC?vD7i zO3Ww^Kj3Q-O{yRlN5c6S3*S-TP{$wRkrrkus5+gfwpP~Ve+79+zcLTy>c%;$u}Vqz z$r9-%t2e8cApeCA>mc=`3R8-VY?jgec#BAYsFxdXtO%#(IFv3YU15{nxUey5+YJ+V zwEY7&b{V*|`}T6a^230@lNYq4SAD9-+PtFj?bR1g46NQF%M^U2V-8&jnr0akAxAwR zZ;nMt1a|!FNSVIG^4fXK>lf>x%WHVetHHxiFWjONmsn}n;!*F?4)Fn<^^TD(^V~AT5r}hv~kT~pvj+gf7xXvdmnx0YPvcM<7P$_ z#c+F(xVpQxTq3ISFOzfym%ZgNr>;WJOw*<98pU8B=OI!6zWoicVuT3COcxE0zxDQu zj<@opNgbG1Y3)|x2+o0;lYXO1$GLYe;PXMZ#@$f`*bAlPL_5UqZW@{S{_MO`(^3G? zzR)4=*v(Iyd3Ig1| z1~;O7&ZmSzpdFM+b=sS|b!8OmcG?m2yq#Za3qSflppYq|vsp)XJz6~5l#^CC9zTc6 z9Bk}=!iv0Ls`k(N?Uf&i{`)@wicjfd%mdCN#NENU+?oh6CilqYdfK{LUvh`gsU6Jt zD^q(C48i%wii2hoRQTK7La8vBZ-Ry?K$H|VWL~i^Rj)S(7?*uWy`&y}UG1Fz{HW4e zImIs`eyrS&+Xdn>gAymLDS=EP!kc{{O((N}G z3>hLST-D)h3c(4hKpDB$`932Q8+Q=qt_-rb7eKuu*fP;5w9KZ>QLKs9WC34*Ilg}z zQySshu073ula#;4c%Zr-%I|u=?BAf8W#Zaq;(ZRf3}MNS?sE=?$}HZP%GW+caB$$M zZ3p9A5N!?qh&0?K!E}2-Q?c0KYyIIsEH=%=hmUt_MhAb% z;wC7LzU3s$!8q~YsE2NncKjUtHOi~SEU{>0L|UD31mU3va7gOLH@edi^APrEgunyd zLHQ6)MUOj=f?OrX`GwtHYDX){A@VkJr}8A5VUc^hq>8Jxs0mq}E5I04Ffts$wuLU! z$mO|-_~7tw)urTRFqBjsC6#Db9`OR*z>1GDfkDKKoUQM5osT%!^Qu0XOtx&PO@Ln2 zDLq|8zy9hVzk~+-G3e}+qh1Q+pUS5UkL5pt;OG6hT!iV0r+Uk}Aw;b<{qGnjaT5`L zFx(TVW2IleAaKaNx&Ul<&O#F`na+>Z#g7tKL`tvcnX4N9T^0kRte4a9V zFzwX>pf{mnY=ijEul$*z94FUHDn zxn2?EyI(f_bd8F=O^MdzbaSKoE?lbO%vxvvc{G*iyV}Jv>xv69nxRdwXxIEL{6i zKDl)C>5(+pwY6SD`uhe)pmr-c^x3(fmVJEG6xF5v(30?@hUMM`ze*;ELXA|TKgQg! z`C-3`Yt+obxP<|?nbrK)WG&2l<4*dyw*uOp?-qXh-BM(nT_W{kItRQo9}pR|~pc;NBPJ$KLO_N1Wv)q#JBKl=tHiCP0Z%qFdIeBHbc zFvyQZ(P+?_9M&ctu^BBe(7e=)M`UcRv4p8hb>8CF5v@g=7EMK*VO6$=<>wAqVg^^P zo)Fc+MgsWbeb!0?dq36hmU>jZ@I3_LjGPqa`9s{TrsT-`DjTjt(Hwsl>t z)#du3E+rW}sn`!*3x=*+7zqT!+~^TIjO18WL_sH7)~reVekir?7~*=S+881Lfa4f*x0i19e4 z`_=+;x2)yza@O%z3culEf+HE-5#7Fa%PyQ`!PQgZN)6@3s`Q&h(VCFS5u6uYoN*kYY?5qY|Jcml3tefc;j3K`@0x>L}a!`$VKjKj&(AYJsJa zDtQsbnJ2>A9JQWcU)L@{uvf4duAv;21rnfOt+in(04@y_>p;9_k)Ky#E+2^PBlLv` z`gi_4B)xGt1Rx(>bTF4$%{B%NWN<0(i?+S_)*^ak($- zMu9@cjAz!%zx+!H>^)x(-Nk9rpdGEJ`!(a_`$=mWEZk8$%@uBIaF)09E3)Yzn)9X% zE@@P+g@HZ(qm|w(SBmp*<&8hSpdPf^Tc6p7*);Lsm+}@HH2{_$`!IwjCYLr*!y{@Z zzhjbGj{ymhy@dxbU4k%oRyiHX3R?a+yplOeJIg3R6X7?LjWqFtRM7QQ_U&hubSrwT z^$w}5w>;O;LF0@52RY_tdn`Ee*6$oJsw3esFi^hXYGE*HvS9|LJ*^;49C+|Yp^j?r z2TePKq2160@a>GTqO&9LXAR!p+_+iFAVSzK{0EGWf3vE`%iu2Tr@ce5dN?Q4#8#gC zHcXj{oeRnq_Acc=F+Xo3^DcVjZ=ZKA-J8$#M|CxGZH628K9)bhuwAFaz`@yo)!RF0 z<7VEc8I2MjjN@OBydjr0?%H}o!x4>>FodBCr(bNnJx)AQ#d>De(G>-XFtO;LXr>DY z&v&5aM~LM^h+0>0zw(|3KpSCvb)gNr$Q+GIDeB7lDzS&_bfM|_oUL$VSFPuhuffvY zv`BZIHJIgwn7jLTR1hfYsscEDF>**M2Ra_KvD_evkiGg-U}=_~G*SLgD1*9bvD$LM z!AnPTyU9Oe9@WJSSb6*!s&foF2#4>w<~bVcGS}x~Ti={1uvLWG>Mz8BJ;Xq~kw@ zJ_E}ZW0J(L^!6Txug?f!lpK4gtd8I=DXo9&ysbCKPX;;&0)8rF=pZ<>wx91N7xB#8 z`YzqSasDsP&hoFxH*Wu+DAFZJgM=X6ozhG|x;qC9q(>_%ARW@BG!mn`yQPth8Y#Vz zqxSvn{`~>>gZsf=*YjQH>%2a39PdNY&haK!rKQhru7;eB(gk8 zsel?HNlLfmfkg{npR+Mrwk|rND2u(xa$h5S27(B6}F!3m(M``c6CdYnV99QEj~M$_9z z=k2waNZ-I8oQ&>S>XMnX;%ylZcYS%?0^XWRvNlIZExB5pz!EU@xU^`D<}{7;mWA#v)@Ux{Lkv6 zSZrWkakwAUEeH21p(we1r5QpoqMg;%wzkhTJPhe8JC;3c;7RWE!vN5;dJ@s7>%x@1 z?*FiswR+0xn9Ov{^8@$?V&#dat^TI<2hb=7D}AC=H@1jt8p*S9&6wT%no z+6al|)%{%m^}}yxtIE|%pt&7!u@PDVSh2uK*ghdUHeHkRB52Y+y7s!RIU-=B}BD1KjpiliI%CDkZCl@TOX!~IDq_Pv@%=i`y>ZxQ2vvA7u{ z8CY>38bUHG_R)c-7sOmGks*G?t}F&=D!E3AiDy(S^DAr$1ddK)PCxPJ&Z~Xw5UC~6cuF{SW2!0mMF5cP<-zz2yezOiZC|tX10aRTUBW){lZ&?-s zt2x{L2$tC{@1@_5SwO9L+EX@t1^_C9YxLeYX+>fQ@1|K%CTDWOl3OYT5Bdr4R%}^l z)LW(Pq)E=Sy}n)TCvdM1*w$W^bEWTk{%OvS3gr^{t*-~$3yRFKhsQFJZ5+^sKfI^i zJ7E57?`JbZJu^9Mbu^fXzcNbilYB4&$Izl0V<+rjGPOp-Xcgpf`Nw_PZSy}YeAoQf^QRAjp}+e| z4w_$amrsFq9t-``3b`0X6-*I7pNM0L6XQu#)k#Qc_>7n41#N(QZ+#E#%}FTFBoCJV z$L({IU+uM-$1%W&gKD6|#)=zg7^fOnhis8aZQa=yRzNjFyAq>S%PN|4*q|KOq2D@51si=W|9<_Q8+rSe zRq%CyxI1qkhJ-Zz(c9Q_e+lLn>UUBxMK4l9brn8$dvnVmnve!x^E=_)OQ*{ra$GxE zTOQTZ`|v_RvnTU?=FtU+kuGa>=6bTiT)qAy&W8WKe`xJYO0RnZI)B5~5MIek43byQ-Wdtb&`) zZs$I;IqEI&r*&5dOlQ^voZB>2v26^<`!vP^YUtZc|N*1 z*qPFl`fI%EY^pSUd3@Q@?_lmRDOj3Y_CKu3upYmAs>YnrE8p+Ws%A~Pl2pDM{-j#1 z7g4Sxl(_FOa3pkQb5xMBg;0QNuwDDdR;!r%oBb^PvuUxSN$Jc}R-i z*N%G9&5oo`Q4H`YUon-GUun7V_7W+{f8V}ah$Z4VoArI?B73F_r319zl%-Hyx~i57 zjGy!-^9njVHP{@%r%0z$kHc=kzOfO*jv^FG&k1NwU*x?%n!67aI|I5VURa@3^Y-#e z*Vrq^TS%*hgEJo*VM4+xNy$Z=%Ko59hn!zLS&#b@lxLr+RGJI?@w@i^!g>CAboZM^ z?nfs9#*)4S$6<-*+NQPjJb&O_VqZApgNRCJ{^|x&xhe8YFC8Af`;j-ioJA|D^y#nR z^r?!w3cO2Ak1C_txFMSNYtefj@E?Yhy7(^+&r{%8X%=i>N8&1&pYf8HQU6I7^*_1` zHxms#bI#d`t17!d_rQBN7|On|AaTDoMW12@6IZd7FxbW@gy~=-HceVE&3kGiVq6@oeI7tu+(F=Pd|5DCI<`>P&{`1vjIf@dxzmH2DE|CVw@$B8Ev*IR8x$UFX}ku}626{o2wz11hjp}D+)ar1 zgqfhplcIvvmiPi((z%N*)+S=5xqU9U)t(SdR(HzLe6gSC4WT4TEJwXkL!?&*6j`rK z1>i>6WnZ5ks(0R-mW=STCb#W!27FRm`>1f=+VK;d5PYo2_R7D|ylow&BBa3ku7Y%O zy0|UFCf{1Yr6)Di($u1~rTmaKbAi3N_S-K)j_=rUYt0%Tbh6^-2$MEX zS+fs|o*8*?xys8myWRlC?l?jL#c3L%lSLQjr`_QkK21F+%3>6q%1o2n1cwwTMf>8h zbcHYl_ub)q1@`o!5w^bvPK`oe)uS~$>{|_R9h9C;#gV&u%S~W5!Mg7;H!ZG4qGv$z zu1jEbKekhTD{a=#oVxSf-E^|=`{h*2pX93+Bh0a5&sxU+WG3;y*2ZE)83}{W-uHCP z+hpIL(E3)Cul^oS5e$uO;ZNOje6l5zyM3B#>>#k{)Kx6Vb=2VoxLR31+bx?Y6)BMq z6HQyrF$=t1duSAaTqZto6&JU5@~l@YZpq?&h4a|?%+5Z#<6`tFv(GSzWKF{Q-O{zR zId0+rZJhsjdhMaGdC9nHP)Um8k5NMtI|Ws>X8{h&KUPuB)<}lI>@UEeya{W`yi$NT zj9Y$Ey?;A*Khf;a-A^2q>JybzW}9^Y^E&7ZVie<);lBgU>d z+%M{sVyr4dEZm1fbQ}e5`Kz>U1(sw2n0%{(e$^b%Zuq9i+wQNJQ}dYPG0++^2oDiQ zBt-fBS~t%z?&w6yc0vD@9*}05@s78#p0?t8$r7(iKJ`zGESulShXI-vYeaf*O?5op z1Ou^CjTibMXV0&^i~Rfb_Y-eyJ}+iu>0gJ;?gs^m?v~`=v>ycrwM*?`9PZ3^a+1+ z_^($jjXD<=f$7rTY=srHY}c)60~9K{t~{Na*L4JQ-Uap424eubIL-dGv>T2Mesp&Vn`NLQ2tDw}6FTRt; zpKo%qvTb8^|3euSkbv?;@oKIL2v^>98zg6^OIE|B6x3Lpg=VT5KlZne#r)(0C1(bvtOHrYkT1k+HJrAaUgt4IIUp4zV9I%H^r*5 z^e5Wm_=NZJra&d_)RSDgI^wa6@ZVE+rhqaT2jWcXm5jltfeliTdrKjWYWFh_KF_m7 zaUlS!S|b&k@7jYbHq`6JEkGHiy7AJNJ)F?;PbKR6RoY?`10T7m{rtAU1)D~~LNeu~ zW*w&xBYwnloH=iZi%9WK4dh0azw1YHsJ@ZQG_jtMf5-%6t!3=-;8MtZ04;=A$|!Zs zpyiQLjp(R3g=9eq2*!4ZsN<$~H%F^#)Srz!<#_E@hYaug4~sH{Z}HUV`cSf($40}W zX^IPvuhG&~pKN@{-`?=zmCg947o10tc*%#DN!gTWqeK`b>c*hE!8&>drd5>Q1@kPj z;7oTR#p^QLh3WZlfb~ zG5Pbo<^v&09ua?Us>qb<@ zU6|dq40Lf16;Oo;Bbl~v?g|D;u-yVKs@l`z!yWkH_7rq<+^x3f1{Se?@lNN4w9u=>f zMtxI9vsi`Qd7vG1%O!?8kxN8wq?JZwg)YSwjAx2;OL1} zD=PinyxpuiIsogn6 zez`i&r0SM|$8Dtlt7{!p8ZdM-Pi(uNk#~u&xULCFZysk%1~awx0C@7IWfi50P3!%I zWUpI%dQ?;!kQh8 zb@icUl=-i_N>nt6+ER0ietk6dP*++Y#5XD+?G!Hot7$B_%Pj(3cuNAY^NRDTO&5zJ z-hi?`yrR3oV>QW;Sj!$jsoe`asG{H%tKfivBr^-}GJL%tJh)mO6Hqe;>J;^eV@cZ= z=Szm9(;M%eck+&Q@)!Z2338$7(D{;B2sc>^7x+ks~J=96iGzm7Pmt#J;^tXupE?UuQu6BVlMdl{aNR2g37 zCZLpHy6@t@(v6*{C3bGVaNWPaH`%w_zy5#}k9aMX&$-Yk4bQWN^GBanJs5(3{w@3< z%BGW&N_E6YTmE8chl!%KK=a6Ju`lr}J$7qyE;0<5UX>V?(QllQFD1vhP#CdNVA|F# zrMuqSw|i{wbuE4`F+KKN?#O|`{!5b%u=>9G1Y&t*bbloU&yaKLIl5EJcMYdLm9a(A z4O-zf&Aid#Fla_YvkzGc;UpOZfe}2T2nI-uwPU%1Yag&qp#1#GnLui)8jQ0z^ z!L7WfB9Sn^>)0VaJu)_hXgsnE=5p+{FZPrN`E-x@GOxDIupd|!(d=&7r#Z#oFBSy@ z*0A}1Gk<%h*&-z&yN~BZ!1Qw+PqKF5;i1m?-8wa0>%n}AMKnW5usngECy_arX$Z}w zUM-R{rL4Igy1R-AROQ8Q<;uYBDBsG#tgzp)JdM`{wjNtSt6WkvV7)cr#G$ z*`we6?7kHGT&anrwzek+}0>5UxryPl5Y)ljRJ zWwpwVt}EE|bBLD5cS)&`|V;_A5&C_y|W|bVR*6d`nvM(>(d-#Z>8%ng^{FnB1Xkzi$uCGwR4&pQ+uE*XQs&l@{K1 z(KsqQL+jcfMQ1~6r%Q>!9kO9_dJomh^1sIpm)FV)_93^7hUFnGGZ=aH1x*JY8I~hO8b?94(s_je z`FBvfYLLmMO^B=l04Qpm4zB9Bkne-7j{$7-5= zhxH#;d&(F-z-5M<)pOf1K@}%~+hu+~GN~c-0d2N&+_RZ|PcQ)AxO-sSKZKcS2;^2L!X8-X^iGWLf_1H%FoQaj;JDd^=dv1x^Ld|DbR{_X#(KGJJdf` zI=pej^DD!Rs4BiG;58wm*2JpM@?QDL+k>v^#Vbz`uOH}Sb-O}k0&vj15qk^rSo;Hc zpu2ZR6~Lp0xUFgX9E(?1!|g}@!@?t1<4?nlsoo;_KK>hYk@nt|jppsQ-t&!ddCd^o z$0`|CB>%8fR6pQHECAtqXW5(w2iZyH@eQrou@dUi82m^PqWqPv-{shZLqm%>Nb;p9 z9YZ7?n2KLoxfa9RGCGBKPKdU;z`wXYi)0en?d+{F8M}xtuE6#$P^d#>LseK!tnF{A zSh!z&KxWt>@-cSAiVMQzFTEpE*4BfzYrnN0Pg~Z^jyxPI*Ve43_K%&3*!jD{E#+$< z*Q)E!kW9l6JU27>Xi*Tymh-pEO7$ikVvKs!(I>EQDr9!m;x{ZLc}?9$LwRQOgKQ%n zn@bJ;(Sto|88Om-R~D5zB%b{z;!;-4YT=ky^pWxW3=sPvub6BN>iSBcSl^uI2Ewx& z5M7F%HeI*F)<-fO?;~4=3MkP041OV|0f9(d_{~?(O+>EVJFBDN-$_-Kj^6$SjVvPa zhaY(UwC$VXM4wrI0FP|*50DUmz0q6hRp{3tY)JW7%+>jLy(EM(?-immH!x0WHcT_$^JPy~L5sFYwY6QIqHK-vr76kdiDT}p)!u2q=(WQC7OY46-EvYzx zOT|UHCEsIG%q_WLkf8<*?j!#Uq3&@<#uT+rAz_c7LfjB%L*7b-E?!6IU{`2O29R<= z?@+_m-i!VTd>jAQ4%mZtyz2d&c($=!K}xrIf$6N@2C4aY{L?je!9KRk^`nbZ8u^f? zt!a`_{}k+@u$&Mb)czJxz+F|91HEf&?RN%A2zy7{ za-(Ev>cj%?q*mqyGoPBrs~wKrG3`9C@Ng0gODQdNEE_v?gMYeXq>qt5}VVK1qx5uulb4m)-+uRXyVta;&w-h-ah(N} zt@(@)({SjsK6GUM0{yf3xzS&(-LIn)%&()Ko^iD>34Q+bd>OCX zaq{GmU;d~P2Nsl@UxI+COHnQk<=%bI=Ik8(Lit0hmlgXJ8~wJ7Jw&@RF}hRQ3m&gv zzDoVK9*?rfy|Us|`U>~F=FiZbdpprVuCNTXQ`{Mh?U(8j2adm;kYL|-weTP#WoXcI z)7LJZc0QcRv+pkk8lNUJjqiv($7Kdx?Zf)E_q)`<`RR0&qSb1@dUdU0i&2gx*}=gT ze7sXbnN7_ph98g|94=OgNqDl<&u&J?k;|XF~W+F^o87l3V}eK`1H7 z#wfiU$}|3Bcl;9F18F@hODKD5`p@gquuDfR1Mt_hFh$a*UVT-lTQE0N*pRzjNYD8D z3e8*YpM^18kr+Y>*8k;4SzQ8#>CT?KC!2cNeBAetlLJ1r$FX@rrD7vtNbis3Tb0di zCVDuRA^KLLhr?c~5x8j4#FBksEY90>!g9#D-8~y|j6-wmK}%zvk4Mr){9FwmZ##D< ziv@B0{kMgX*-^DS!0vUq8FgAK^#rQ~eTvXW37q77$vf^6`_%eMZJ}G!N91nLG^W;^ zM))uN*k!^jA}=dpyPl&RHQ=y|0plL$t`;yG7lY5JpDc|!{Ks8{ie7cOBS@(?0Pl73 ze^?DQg#xD;yWiQ!Jq`8N09;II!Swmh?3PTjKg8;lg_&|!o^@EJUFleLo737JYHAFJ zzqHJ2KHCS;&TtmS>`6WOU!Wr-YBMK(Z)V-cMY{){fF|E-i^YW#QHp&^cYasD79JMA z^TyDF1zUTz7iTZ#l9B`T9~MRYf-wvsGqFt)F?BOoKxwvaZAHe{5z2XP?%FDxdO>L8 zjW<#uI#rr+P4wzm<7LvSnQ(02Ys(^>(?9ftmuJfehz@G3SOS%}Wgbz&0y6vebd>G( z4@S+l+hBz%OJJ8vkS@68Kcm5 zvYIEfTU&BeLRjWr6T};WdO>K}-@`>Op}F;D#qw@|=mFJ&faE{rvJH2}miBO+rb7x~ zy@NGZTZ~}hIz!G6=hII?=rnzemKYcy`}8ea!u8@0{&D&7I4W950NPTEUe^YzXWOA+0@911 z?~T`2?xYvPXSw+#71UK{FM#@Pw1oqB8JbI=^ZAYRHa8eFqzMw72VsODj6Ubr72g>Jm}#F_94 zkgdzIYd0|p24f@)u6jcL`55}x(PiI=^K~AYyH6v=~4o{`xlB zVkb+DNx%xsUEo~E{ckR`%plPivGZ|)$J@iDxFzjLIhFu?`k0HVkAAyOcgP^Gm^ zp2LCdjH+sq=ASC!lZvL6nT%nF;jf1f&i(a(HQTk;7?Y3;wa6O{1Q zZYG^bbMNjHU>=Oho7)CtW&xTNy;rmmpeXN~?$C2_f7+Bh%bJ<~@eA=liihb*# zmUt&$aI|llSXC;RPpB!Q*;uTv1-j9h`R1aT8pg8q{N4R3k(K0@TesUbl)!o(i`g-4l8kkMk;Zeatv@XHMRellZDscc4rU`wszk3?)35;WwV-b~d(%x!@`00eQlDlBiXZaz`$`R-Ow6PHse!n}q) z_hiVa7-nqd+l-ltZZfMq&I7moo9MMpOn<@!sdW2n28$vt(h#vZqD;Cpsf ze*zoOr3E7~*Zu<=Q58TkT}DPI)r+^hkD0u}(+{71^3#(xoE^fCc=pNFZczD1U%(6d zruin5)7>^V6uEU9^XsRoiqbDHYPZ=H&Qc9Z78@&b=p@bdER%(xDxBe5*Hc)B?+`}` zLbzBrY>QIbRv1HlOW7r6zsGwmat*p)!bq!@CqffOG`qiOA*xCVWN8;YGqrpe`p3M= zq|Xgbc&G%_Ef~MxOTGryT3M_e`hU@N`v-xCti0`%cbV_#9;2shBgW#P&WlaMx~%$! zOu!KDzuSg-yQE_!QVxE&U78N$YbY#Oe}XkUY14KPGd1&|QsxT%`jKF$uIVF3aB#VS z%FCSwjUB1vUCw`5l5~kd1BX}i3>q98PB-Z86FSYCG}VwAon^??qyI+JLWpg-Tu-o% zt!PdDj8JFI%?n3!U$%@OhIziB!r=qK2klYU#6NP^N4W2^=1z56~wzjGNoz05Mgc;_1b z5FLsWRJe$z=y=$CE^J9AI--<@x>>*-oNxlW&ZUS+c;6GY1qOOtnp<9?Au#yd$u5uZ z?rw8OnDufgl)}|Ya!JIJE1VOJX2q`&t^x-Lc#Agk)odc$H0(;vVrwCogEAL;3~a!)0TmcCoILgNe?4fpsbh2@#bg5 zp;|uwVYzh(nvKi+Xls2-(~uy<@;OUk&@l{bYKPP8{d_y7V$=FN!hEBBy)nqKLq1#i z#W4LdD2sZpw9sIi?Lr)5BVdaGe|x$u(Q)XcE`a!4HaF#pNB2kWmox)a48%Hn$wag9 za7+SNI{tXs;cpd$W)HRcm}Ak7(L*h-ySoOJ?6k8edNy`k?-zGaGQ8ZZze}Y6u z-~W{$m@jb#9%m2T+=&=7Nmc*JoIS=jAr&HF`)c8chcSL4iJM-c8G~b`Rhnpns{*LR z1)sgE9+k6}*!_$fx4ADt`Mn4=JfRk)V@tVkBQ_Tq$cC@^EAE%FM~9*$fo3|sALm%V z)Db%92)cAD>u-op{(}x+84el!*94*9Z9fuYf<004!fAN_-ld*K8Au)7ES97o!xi}~ z=&I6+6Y0Aw<={WaYCTFlAo0DBYFynYZGZt8Cro&84V0x)}BJ%TQ3mxaH67>XsGX%LnNIsdYRkubXEw z3`m=oVn=;>6+r{f7BM+}I^b3NOdy&Jq9Mqco(``NUs@(7 z_B58@_{#S0INGve@Zr4bLUpORYR1ho4~N%!YRRj@E%XA^w~8ZX1!f36fM2j5Tcl3Y zbc({#BpX?AialRXU_Hr1gCz5^%*XLO&keEE+qI49drO+%77dTPa}QTiIsai%A51y( z9mQ%X9akByZKHF0A4H%YZA#mpew z6g5FcBST@aR{{sP#TusI{c0AZZ1$7>n?e3kXe#+W4)Lx)$+SJW2QhWLME>4~ypdhW zLkkk&zh4TLjhB)HiM6>*SROxgHaBf}Kr5fg(1Tp$kIrTJjgVe*RYs??`X4&Jf7Pe% zuXIQeL*`@KJULelJk;`LBu8bUsnWUKa@a{>qirSzYHaSv44{PkfXy}N!=-kMMOTkOFdb=TBR-s}qW zBtqKHUwBQ>8@&`*IJnm|gog%nH3GEqdf+E>!y^CsWo9av4xtQ$W>#qxD31yKSfdUx zac_d)zxjcTZWV-%Vx(=!#T-rs3?0VIb}77mSIhT&zZ~76jz0lqPmZQ71=md9X;APB zc@V#Vou6INRE5)-0#E$v(kt;VHi;8cdpL#$(w|t)e@P+`;Y3kK+ z+T03ULRI8;HyCZ~zkYOfZroyI22Q`*Fae+N70bDQBh}ioRJ*okRQ@*b0L!E1+Z!eP zh_zMNhJ1u1yIx-$RC~IK_BFJ&H*K*0O8Z)cRNYmyWwsEeNbnk&u*mPSWj`&1dar2& zRA}pIY1?L|uchv|;5)nLyubw?LCcU<`56==o-(h}+ru&_0;v!KZL3~;a_YAV(%$A@ z78rq#M%fiFcb#_+x>^D}0hb*?VvPOxx)`{0=*>Y`hWk zJq7c<`&(>PEgxMIv9eNAML+mWTWWC6-{Wx@OqlRTD_84Euz9W5i=|WgqcD*%0S7SE}SQ+Hz)^r+sBR72lT{^y= zzg#;ws{0p4foj3XXz>`zQ%ps`EsfjnBQ^NglNzz`_)Z-qKT3Yc#9`tt*Ns7oEXP-6 zh$sFI2l90~HJdoZjn5ah>H^&`nB+?0pK7e<0XXu(Wq83rv7a+jpwh!gNvB9^OLk6C z)8~Nk0NZWjxF=5@Dib=5)t8|8`Pa}-omzbJCPT?tXXK)DpFf;)a!3MYO0lowURnhi zSxuxjS}wtWp`s_@J(j!y+$8h-3_R#gdMQFCpxAv}<}xeT}MybNcM{qQkyZVaEJ$T=)Oe5of5 z)>H|G3}qOhrOYd~g`NSh=S=k2!+=`M)A?X>tbVlNVuUeC%h zKjEKptAwQ~(W`R4;E){gJXFhKp_9Grpq;2EuUh6Vte$*Nm%PJODy>iN9Vhn}Ms<0y zV?i2u0nuhO@xrl(NJlwOjlSXHWps5lttg#H=Y?A;8e9Jdw^ zkY%%m*`y?JBpvY3{2$hr%H#CxAJAn@WMqLK2b8_Od**nN!#Qq>A$1q}?i1{>fHb^TJ>fCg@{bTJ|80${q1Hk^9RfRMDuifP}BHBN4wlKmB6W zrMA;y^nkqiR{-5@O%6?)(TB`cxqmk5!$6tWH5)6aVZ1l@uaW%GSJXpLwcVD#?sfxG z#NH)8!kf}`ACyFe3fo+D6IY;TZv0(-9`|Ojj;!$%uQbtlx666N={=~U&8?4iVabX$ zf7ZkIOUPjL)Kq&WyjG_JhxF94<7V{Zi{o*{-rsZJnzMmd*AN!BF95_vrx8`Z9+O_X z6Ohr^MrhQ;W1lOKwVk$rta_^vnfKT@H{uMBzIxf(tu?82d0J@HOXHR1sE6GPYbEXv z|1R$B+D?^Ko@26ud{c-q5f7yDcJlpU`P5239N*ZCjdQLO6fd%aAuQYiL$9F+FnD}> zM--R0&TY>)ItNoRk5?~di?6eHEW)m`N0cUVmqe3G&y{?rbO@<$|L zfdI|U)>6Zkxi#^FOyXdQ0>bnNB=hk=AErjVP%vpRYQnL8Zfe@lrk*Uh3-~zuS9Bzb zC?P}iQWuyseis*$5V=Q&Zsf*}5K@P(dX4ptmESa&ft^5}6DGd`AMzv(4MQMl%Mvul zbPKz$5Yor*HHb-0Zlz}*ZfqPNKBEHF>OABh5 z27Fu@r&ypL2(NU_=UbGodrGPbnerM@>3& zXP;qf8ks1z@>^zNtK$|3%bZTAc)5AP ztXi-BxgqOFQUVbrh~*}q*Y^08XcSgQHk3oHERUct7*zf=w>y=NRi>0v-G7x-{6pZ_ zFrL1K=|~zMa=zw~w>vSwWyJ(40en+^*dx!6a$}Vr=pnD+%P@&pIzQ)Ts;@~bQs!8p z*Jj~*f!!7gdl6>+l;%Xwh4y_nmO1BM3YaHE(v$sU3Q84;cUmfq1?{E5A2wCu(_!|y z(W!ahZJU*o#i&mVkEOWRz?B+pt=0q+*Y@SS579{?MicIJc%28C&C8}Q-#XAyL#7s| z?m3Ul_+vdq3SOb~raHM1g%|3WMOM+E8M=(JCU@C8+KiLBGF3>uh4lM7jUT3HyDEF9 zR=Ddla<~2-@Oy4U+zAcpkY)fp`Ts{Kt%rYT^>$ke73c>F_5k#(oOx`RceR_K$CE~A z&tBYT=HfD+$ixY514aLJW6Xja{qls(MR1TR5+uhx;^kawwm!P#e|^72c!S(?aM?H6 zdM=4iSfM8#(R8WIgwSCV3nN9!M~9GYkzix2%Vhk1c>yC{uK6r6oDb~9Z_~Bp#>Jfy zRQ|(Kb1gKTExXi=UYFqvr>a)rnd zch>9lL$vZma?R-zcvLF?>B*)N+qb-<<^J8YZ4TXu^?#QQD;-w{Al^bNmn8`+Qy**V zBQ*A20bLl0nG)ju1IiTshvX1yRlOzqL8rLtBDr`>vRS!RaCN#+BSqToyjI1I!Bo|& z(Px98$8I7v9BSWx6U6heC-Q;46bhRN2UWh~SiIuah#6xs7m4SDeWVgk5b&qKd=IW} z2AL>Uz$C*3h*Z}g$E6le_?XR%FE@Zl@Pyy;Y_C54$CTH{^cw*CXp^U)ktoJBNg#~- zlw?3GpA?0M@IL#1aC3$BJg^uq_c+gQZOBz`R|m??(;u(~lE}=9Tpv#(A>+-kJ}PAW za#gL!b&Ao3V|@^>$bI#Eo!7t+pFyB-$O|UY2Os|Lo#tEe#ID)P0}wLak?0x`iE9%m z0glG>fdlY`%YC!jRj=>%$BADzv&);p2TCq+ga4=S-R`s@+)P7`P8V;8kDe# zH8E-#&N0G70}KNFiI$NKm0fDHEi*sVME>E9j*n2n(bcXQjiCY#n-sn{YDQf5Y!*O; zdyT9lQnaMu#~UP~MDNB4NXSQ?u;d^)Thq^J*f7~|q4Y@Z(!aUtsa(@To#TgmVQ-;_ z8rw{?V2=$n*`qLgFE(IvO5A8Z5z1rxIb|*oVmn`=@>R`scBJW7fN(J%*2mgv%7YdT z3HF-n|B+0tLbD?_R0EA8!yP)9@WUp1s5@B^HzWRcVs*bmRC3^};#L@B#0uVW)|<9pyF+2Len;B}~R zZC;b~#C3b7ntODT<`frCgm^01K9~ssmY3+c!B_Hp^-X{F>UI|G`@5OoD69gOu5ka1gb8QgAN=u7u0Scs>wd z0&_{I59M%bXKfct7Vr<}{yqiypUb6wWW8XS1rh%%rcq9Cj<+;T!#@lGJT{;i4%e}e zrBQHLB8{mFM)1h)mZxn^rs7EOuRSl7E^{k^z|n3-yPv?%a<;k_f6~(2r3Vr=+fBT5 zBI6dY?HNOR-4MD-#Oq5WY>8Nk$u>ZXMHwgPNYQnu`e~%hM%1h9y_5H2eb}uR@-R>T ztyUzfGtgcYWIbeQj;0{6^n^FJAf@5T&97>QTs(Oi0iqEmxtZz8DV*O*vnbeG&S(I) z&Wu(h!et&v_JU(bKbX~5E6Yra#-shgv2z7V{rzA#L{HvOG-6es7Vb}&OvfX3aJ zQv3v$1Vd7bHcR}`3yt8;~Au}ahZrZ zgK@X{`?<{_QMBm1pQ~m%K)yo13GSRx$O&^?QLzGB6we6PW(PA4=~D;F{k`lt)m-F1 ze>w8UG(VCUrf0_Rkw_WEVk;EWAmf|vMfSxFo$M)5j0be_b>}w^+rR-O*$x${-eOjZ z!JnfwCIQ*jy&(Cms6;smRHV6dHNWxv&=}-`q}0J!sqMB4eGrx{#g`BpG(232SHneejhZy%Kdo-T!#t}SaOga^qYnblL<|`MIEQLW0u9Dey#kS z@nna-%W_%Xl}Kz}VM%1RQU~NyVr7QPQK@Z71EqyLCLo53(+BaqrwMgyv^pW@HAW3S z|9T)tc4;l5Vb34P7Uc+a>_fNYpPT-(CJ3QHN^K7jIm>;KMYj|w1$yEb2`h>&;9!Ww zLoa=J_~zpRKZ{rCam>jR^f>kqA7BD8I}NWb$(iUw)KEO`JR#yfo)v(yabH;5blDTF zoJ4lV7@&uB_z#@V`dA(q$i-5R%UiT8*m#R4-7KNR?N#D~^s8u4Hl4rxN*$2J_KhXp zYN~}L;7F0#Vc{Sk>ns`|2%7Bwi^vb&K2z6+7HwHvK)^u?B2xENs1c z;5?YVG)5t^1uls?0f?4y&1sgdBVNoZ+m!0`oyE4-L}3&fMq0uHXsMY84n7E+pGE}Y z$d?w%u+YCWCsCY4<+9V3uMu0Ut{m`-O-|!^hbn3t$%|$@Fth%0NklSONtoeJ3e*7C z0{fnAKXyyZ1)KG>P^#kjJ{+W)$PH4>i|bpPvcmU|Z^p?vqHe?dRKX-}~7nPv2c?0^G z2!GuN3?xeH27^yLvOv4tZ8p@}a8KrRd-~%5+!Y!_0;|5F2S4PhJdJ2*fa+{GoE?#O zN!87c$gkj`plnJpf9*P>n(}lvFs4BgJR1j)_B0ayMyp!iw5)S<&ayO{SNZS(mA3_h z5xHq1DTlw8p`vu$lxLaVX_)J@dI}kKTuk!J)_#8%y|48-nkeJ74#O4+qbtE?jwf+< zM#&$zV>U0zvD-_t@)^+vF9JI0*3nG1ISW8bu*Pox%&?qMGQijDJ);2Xa~ZH(vI8ks z2Zx0Q^cMjVbrz~vBl!tjb$I-*?YILXcn7tYUEY7C`P=*Qb!iPjXt}ZquEFQ!xB(6iVHMN@{k@r52;(mys(Jx zdF{Cto(TD&i2#y>5L|cpBukXsfn*la%WdwBB&a>PgZV-3jKbwX*`>Mbqv;e3WAzsg7X!GQM2 zRCwdP%#!)@B3tHcH;w8!&ZsmJ34YN!y|dQaY$mcEmprv=*O{x0m{%=Q9C2udqZWbE zf>O*1y{3h)#Fs_hj;~|;Z|uG%C8^M-mvP*Zu)lg=!~J|4gAY4TP@$3PJ+-X)AP z?d_+Lxh`BaR2rtn`!j?I7)Dc=pgi_4e|1fg7Tf_*{Hod`dAxo=bTUJ8!@2F#n2(18 zh0t+e*xU)L3{U6M=X)zu(ZKA;<{863Xo#Hjyl+lcX)ws_6ncoB*LHb8U8=Y#QC`6+ z-_MThvlYF~aI}_c+|^o_3Zt3_wOBjG&&6WYELmH3@(Ce6TOF1@!)RiJQ_k-LF^&(l zNQ~3gZvD-?9IZ|nwUOF$Q_#@l+%KTG5}80zBQrg=RUTqs$c#NPrc;rz$RWe}iAM-K zH`F>Ow#Adsd=M-a4x3H}3z(4;CPxbb|sS-CatDfS}|kCC3~SsgXmv zQ$R`S27$5BNSAa;Gg5jZ#(;s}-M>G7=iK)n?|-(PvvaOYpjiRq{j#`$xvvp;r8S@`Q_0ZL0Ak|bB{%BcEr zb67tAtmEqsmO)61uT0|Cw@-a9_xsrEkDAaa1~cbTXJga`&Yn-UEdcXFLSWaTxC=Pn zaDzUq@taXGk%p7TAyS#|a=!e#H-R=YM>0U`6D24TErHy|x;Y43RETk%SakJ1 z)A+#IitHbI##)GP5*%Ekc;nJB?+&m~K;Y`$rPAI%pXHQ&v)9x$L_eN zVd<|uD^U?3cLLT`)%9Ce8j_6_T`owh(@%EL9NccM6Q>Pm+yk&^_9%**#8?FPVF|yH z{iaTn%au3)aQnmk`Y?Tq6O@HkdYcGhl;(HW*gu)@QOcc}`MqaoH1F(gkr1DkT_A-X zdHk_j=O}rm8%)AwCqq8&o{|#lNjGPD{aTo{FBhxL$fV7YtSVo}!urd-jY4Z9NMl@4 z%#)I2>HF)l@|WpMSzRyK)ZDg{W@Q7dO4l~;Os8^^P1ZY3+anOk@)b8KK*2OEHW>^y zM#F@0cxT%nJ!Rbg#~XB_+XZbqLBMg#TrhzdBV#rf-oLtSIg@Lcp9QP&5)$P>-ra|q z_kxr4<&!H5I6lkA_fvNJ669x-EjsCr3}Z>GJ&%l*>hDwhND9C7A-?N`DR#b<1+%R$ z1eEh2e}@%yp5{B=wG|S<{px>BWnfM9kH{R^*ioP24|GKgl`$~eH52)FS+e+q)((5D zeKMdao2q))Z0KbJJIDDPI5516{$y}2r%oWSrDk2+_Xyv#?Wx!B&u=7VAojM__t`mF z$7|OB7qUbbeZ*lux;MM!QioI5i1*q~FYlxP*cYC-hzw&vx@K00Ms3T&E!q0L$Bwo*RB z%Tvw-JRoS?-gNyRg025c%=JItQH1=;2dfC$ypD0gzZT#ESBjZ+sck^6&0^y(mo&sQ zWUn#}rd=g6{~UpxG8We9mRV|LHC6W>Zkixth4k})#n!qY^0wYha{g9e0{jan&$m^1 zhZxSCuuTun`)!n72{Z#eA#W^NOSi`yVGCpLI=RWwd&nIITC7OdR;$3!S;eb*yfNY{q^X&orfSHPq+nW;UvYj_+wwGNyuBeyWu94FQ8=X~i_>KJgh8s}_`!F< zk%PHRg~VB0PA z5lWj@^zy~R#}en~3#Ollf+;^x-VN~kva658a35BODSb=%Fofz!)~pS5ywrD(CGaFJ z4&ON!?sm2`5bBsH8TA&pO-zsY^C-cP%C}v(lh_~i7APb;f0oe3#ZTFieI>zZ&l@BD z#fmh)QX;c0<0o~tX$%VwIFj9G>z#`Z@&Z9FEJTqL5pk|6N=F zd*9rGM!Kh6tChJGpsi#6h)m(l(Nkpp&Ye!i2P{-BMSUGUp5*!3Zk%N7=MR)6tmN2Q zZS8VIMBn`_m{-BiPAg_X{8$yodcpeU@QTvap=tP-JiWYO>zH^#6Vka0vpQSF9!W=^ z`FM9?QT6jsx=Cw8^5#8I6d-(~j4UVE0ls9r=BHwB;|6fV+q&0)nE!aMQv+-cNLsa^=kUY9@o zNcCz%QPkABrnV#iYcrFAk1kVoB0F-EFfGLiS@CFKdM=Wz772Hdt+1Be6isZY>%l)F z?+$9cAR`Tv9Y*33+AxeN!I_0MjrQcNa;&|UIEgw0Z(N#(CO_HI2(tZpbmzLrfbmxs zW0>^Y`8J`BqQ#?+BOgBO44la{HxblEzLX2?gTkrUMel~pE%J7$zO79bC*q_LS7194 zy&UR~uqXL**|?UG{{+O+pB!=8M{E%!M^L;LZGt;$5M0w^4Q@?jG+}Qjp#I1hqzq$N zV+#y#Fw2l+=RPj_M^vNy+_}8Vde^R7NqJU*{Zk$AVzO(HS?x3s% z*RQG7nq~X+a{cqS6FlFsW+p4bU&%|GeyzFBm2H<#W1BrLYFpHqwK)3@Ta$9KJWEI5 zL9!>SPgsj#(F%vZRna~&ESRY_@V*k&1U$}qo;&4DLxe&2)b)oIpSjtV`R~Yyayy3b{M6rjnK(oWl-&ErGDD8$~u+QNy^Zs^t#l zlUoD_+OdP>BF73{cdg)jGI}ce_OotCI?H9Hm{%EF+ulx;#ISC*1*%$Y?xpsQ;?V1g zPven6>k9XNxy{wE$2pn3dY)IVLP)_u%6QXf63Eb-~ z?D#Ns_O~!zemFet(V)VfmQj%gYxkp{zi4Bzb4E~|%_C_WJ~b`9C>A$ymWod-Zi_iC zh$7TX)3gvLau8bh(klO2;k~(rlE&p1L4r%EI?Hh}BU}G^c@cFs1pw%t9Ssa3xp}>B z6qR+)aEB$FUEHZer)yf$a=wx(l9^(5yl1w>f7!qK;Z-LoV)tRFfCcG;AEX&A%EghyQJyRyJM`-S|KvbCLg_7RZ~@xMhXAG@2qiL-`A+Jr$M&!G|F-_9(Y0L z!sh%TO{?mNfw|-{rLgSKU7NNbeO{eZreqgLfM;6=`PtugVQ(9_fuL-Q_VJAeKJ5xL zeUxsg=dyjC-<&)FZ=~IBgeN(E2^!8n{^doyJz&+*BY&!?hdDEGn@9eU*dKsj+)SUm zR6}wh2Lv}{7Pqp92W8&)&Pf+qEAR>wKc$76ocPfFCf>C72}%~9rYPuWc#O-?E+G_O znTl(k-Y4e&s{5=>>s1(d=t1$r2UU6sTr@>AaO*&e{jHf(3wa?Y+i*5%pvUR;Iez&7 zG4tmTqM!$%jNVYMoBFymOuocqsbjM9HW?`WqA`o02l4pKMGEZ(53vADfGPbHprM(D zk0w*{ZnE_J@6({d#T?u|6_@Nz#pFAknQ8VB@_@8PAgmmzn)L=QAfo$bHan)wFUqno2vm|R}^ z1$bzs(aFv(`Vo(U?!+=V#Wq+;-A-Pq%IgTZz6UZb1?i8Mze`EnfN*%(8vHCJxN@T> zyTpVnX6?54)VBeZAC0|rWR^O$Wi9=CZe=E8KE2h~ZsR_Qh7=ze1hgy-(Hyhcue97O z+$v8=TFkxdxE*T;nVagvvo75%=K1x?bWW)3xDmk>Ct-I0K^xDIMa`26+NH`#6@xc5 zAO{6+s+%v9WDFPYvkm7hWCLxbA)KW1#L>M8eVLBR3v7;s0@e4XkyB~}SETCzR^z_b zTKog@v@=d>EetmG2Q=J#V{-GmgK;phu-S*aiw+_?PeIH`laShY?^RWvM#H;HpUmiq zzq4(uhx>H|p-5kJ=uX2jVzGu$Evj9@QNJE!w^kF6=4FDtzVtWcFw{J@$EbNCXdu zX*R1Ke0YECU@>Oc4-`a@2UY$#QRzQYTA_H!$jX=P_he{&DXZ{&##^r{5Hh9Lvf9od zk(KFpbL&JXKS5^>I9jz2C9Djtbx=;NpkZ!ULul+XjWyekmiLK>R3GgmQ}X1y)Z~Fo z(kBXyw4LPi%lNifD(>HjU}SMOcCOK2@cq;r3U;p+iS^PL*@-_V%d5(7HNoC;WEuF} zHH?c@3s)!0stfAbc(9*w1-WHiuIR)RpgO|Og`=<;ka&OXeC>4z^G)^2IwyKc|1sCV z+-VE1dB$?2sP^VTVqa`0x3-?}gWKhHvNXyFFE$P|eKx8lWaYv1M+Irrby$eSlqZC0 z`3QJUcAjkqs~h1YVWRO8fs0-`F^4(g?Fd!ZbX@v+Zdbw+XGDfzZbYjlhSIcoM!{`e z-fys^6?511K(LZij0!vZ=4IEtP_4B>+yC;m%%$S^+-}>HYmziuTsrCqH?}s_?uFxC z;SlTlxQI&Cbt@C$dw9{>_}jfMEzdub+vc8&-hw*;@id5dvlVlF?)XE8cy43oHvZ04 zx#KB_)CDh8G`fB#cI$XP2e`deE-n=4rl_`AlB*8Qxa zpPi)y=kA8SMvYwbf)oK-xJhJ=Fy=V&93%z5U78XCw>Ccg&wJj91v?(|=IILz8C2)t z?Z(8c@>($gui$TbEw@Vr9qT?UvcZL@&iOwDmf(a=7`MjH%rhRUiNE4hOO(~(m_L#G ziCoE}{jGahtIjrYMtc-+Sr|B{y|x-3NT>AQbUQVU^Oprr5SN)?1OKk%U3f!dYcwDT z)48SNX`;m;4B8${iyQkk#wmN&5dlMn$6XuaYHW}xYBLfLGW?4sCH@AC9-_d@)S+(*u6mv+t>iEsX8 z>OCQPL9dFd^GJzlg6FHg=`mmCHVwY6XF6e@hpZ#A{Rr>kI(<*V6F}xF3tnz&Qjw>} z+g(qfe$eyLxGGC+wZc00P}K7kuh%hOwM-$&xH)WMT0e?13{So0cl_9yiM#l_FrJIF zp4nvf_{iYOAnR#B%C9FzGWgylYQA}f8dY4!`Z8H3j0jJT-mskTH^{^JLLN{u{AsJS z@M)gKzw+FE=vr-W`r)IobYDei<3k#`>{1O(Wqz*k*&wiOSPJ%_ozMT-O@v zITD1igSc@mxbLO7kUaqwC%HaLn&gMtLRR#i!JWQRGM5pjL~Lvqq5ZHvxOcbInCP*} zexI^Erqs+qun%`^xgPx9bXgMdqAmyN&RyHm%U7)bi27k+>l^D2y2gTG|Ka~f=t_kY^P%i9`^q(PqT=UY5s~cM29bJQ;`{ ziTCTddR|s|J41)HSnakU*<)iv-%E=@F;^+=P3k#aiw$jS#R^mDR7lKm$*S`|k>Q~I z;4R6%@SxLL97B(%xw=MG#kIFpYs^|$#g|cjfnQAisGBGZo^S}3_uK`m;`&CPz0zU(7@kx?Q@g=-vE7wNH?^>j8zp*cg1%(eF^j{B7VAU!=OvY7 zW(tiA>QK)3nIv%dnal^W`@>%{Z%GNuqKE&BG_b496GBK&YX&=ob`3!oFn`4n2dlrA zuT59wzTM*b#X;;P_-jB>bU|FHHd{IxqG@G!OKP4OZDJY*KOiNA&(U#?BlE!H{mOOZO;J^mnnNLk&<#`Tc%C zVD)l8hz>lvAgxZt&bPfwEucH_$9C}*Be%X$o4VKH**F2JrQ~~)PRQo2;>4y9c5x7} z8YpKIDe)q0UwuM|k$f!D$$8r`nwqODDF5Edry=5STcU0L+739yeG#@ zw~FG%6Qk*p`6^pWTyLzT-sil1tZngPnl|oF?V9U3J1JCLeH`}QCQ9k44LcN~o7=lO z53@x(q}79!3Z&;7h*@$$;byJpzmz-zbz{r8PkxX#tWgHXcGR+l*R1c8n^4|oXIA$l zF#W8X+!TAm;8=1R>cNt`e$MOS;J2UqM|ni~SgL()!sI`ntZLSbX%ccfFX+7*6d)TB z2k+O}ztAx`mQ`DrS^doj^*RA&q^1=jrP8AWG_)2Zms^1ET+NB({enr3TBWa_nC-H| zBf4!Kj+EN0?6OHtrkKH}Kjv!*J*{if9{eg0zxqOJxDLTmO~{-k!sgO?jD;Ov(~p$- zD@`lBLM_GsNX_NkK3wJ~0Kx|MSc z7B;tl3?B>gtf+b(z+*TW5$XyT<~;a(FM8X&_!3ghqpdo~W&5$~KI5~@A{~ld8>fz( ziYvUzA;J2{4701jsp8F1EtC{iyI0t34E3Aucph8fery&3{OMV3#;%!0Epw=c16S$w zb*O{68o~bC7LHsSTM(jr#QZ<(9%0kEj;5b8!k%%qyR+Cyz-7Mk%ArC}+^zO|O?3x> z{lv8p>t0OPj{0n6AcOy_>4QLOs9pCd&Ue4ZSHM^J3l|cOp{oZg@GFJ+kuJ#(GPS-} z8ef+g8h(CMJ4S%ukp7i8g9_yr#iV`7!seal*R&MxeNn^2P0_cJ}QE zbtT4!&2d}n)5Ax_`3Sn06=_o&&-Rl%sSL!H@ce}ly1fa#v944=pckm1kJ3>$8dKJj z5@ex3Nml*00b?)IFYO;7`%o88k!9iETqWGzo;~CV zu&CSVHi&~!66pEwe>T=x56T1WYPt;r-GQ%nK5_o}^4>J-aB0Wu z*JlwzF5-fp>5PIPdcPZnj_wHZNWf{HOU^3LS3+TiM$K9D^xjgFW{Y`|8V)KSKyY(b zS*z|xM5mBHHvLmjB#N?EIBbPus#U$hUoKN4rFWqm=RdDrwi`a`r(Tdy@XJQ1dnt#o(%i=ts^2q z2BK6(-sZYAQi`bvh~g9;a%0hL%+#!OUe}V_nM==u-bxQSH+bx?h|46I(`c}((6~r9 z?RsG!>;~~`$b%}Ro^&bo-VDEZlu5S|RWZDtyP#?{)qx_trijP`nrQYI?$e9x$^A}Q z>{#$vG=5^m47FcYn5tad;@PD50FJYHxQctww~)|Tf_Xo2u1tb!!MZYi26<=P7Wq9d z@<>k)+BIC9H(-okkhhh2U0&Dtk!8J&xo<@QqujIlN4IB10eubSo7^x&A`|+rBJf<^ zrnh_@K7?f;;rA=1s!FkMmQ^kC>YD>ylGd+kDn_`{5Hk>TOBp|6b)%>`LauG~?26q` z^;&aZN$w^~K^?a7KV)W8k{?=ES#q@SIxfK<{}}=ABKc{&+X-$2Vq%EVc+aBU>3gz* zYi*EkdYlsD9{Ur2ahOvLA%*Dk$5zt<%hDvUjX_h+dmyJOGlQ#r+6r@w1Ch9^mnQ)c z#Kwr}Sl_rEP7frD=nH$Wn+f(SIl91j({=O9pNQOi*&Lc8yn|?qvFL;u-+Ku`M14Sa}j|Y&<|Gz;c}aEObbPQ zaZ=gdl4r%tx}ZO6DfSgRYSl$%L6y=DRsc`s5Uhp0wHO@Te@O1*ZMV)&HXo_J)e*zA zKuLBv%-Yp))r$x#>T%h=??e@lm5}z*uE>0J)?{|};97dYx==-DfnbkE_mA69w~Ho( zv9mFwipF{r$+YLHpRnmxBs|zNr81kZ_d%>WBpl`#WaO0qtJgJRLv3X3=y1~h?>FSD z=+_m)Q#Tx%X9(I0AG-cuIXqJ}M}ny2qbq>V`-C^}xWku^Fbjd(PHDVM_u~rVRz!tI zl^-Z5q6`vNcoFDkT>PnyO~e>|WGi>s!k>T=!#Q|UHP~jo9q`>PChrjan zce?%5U{5@hBYmYh%7F{m-2B19y>u^&)R803wwa@<`Kq6j>8lWt_=QzA+oT-ECpyCS zBzNYg8ropwejd#?Pjqc!u5O#NGzk)j1+NR;X(c9T%G4xO#HaKP#oA{)y{e*umBBruhOGE zgln^f0YAk?Iop~MKoi<;rpmoRQp3*1!}wYegvw9QaSEyj2tSo zZ;Y0X!D|+dwrnQbpH@Bxa>XkvZk%|z)1*y^RdAMl7^=)j5Zk|Tk>PJ)>F=^(fkt$) zDPcT!qFb5smi@KRx5=lwb5fyy^ft2Pc%Nz~<=p$OK5-&AR3i9&!kE+Ow;zNZ|6vxs z8dg?4j~n~tE0|VWv#Ru^bbr=;VYz46?UR1GBK(WOxBhwiFURH+12N7)14eHs1zhP}l0MO=jSH_PW`aodxRN zoquYT(!=DL+cTmMB7crOS=5=eSlgc!t2al~ymu`7Y2)L@o5XqfEMaKg?NsTAj6d6o z;vZ4(DjA*;quPzYW)#Pj+Tc<>tE7af%yy;Auw%qy-mZ21pK0q^_L7_Vb;{oki$8uC ztzP+$h$?WHNk1F)-TxIT^4Rl_ao8CzsO;r%0P%}BQf-NtC$Zt$_h*fIKIwZQi7`C= zX-w_)=$5zWi>UK~20HWt`$G_YFmH|j`vB~;_xL$bFk6~K*)f*>Mda8gd+(349Z}#y zB-$9RB#6eLn|D`ea{Mx3B*0G+9TYXsTa#rPUK9lzd&9Hsa4{nGe$T%PIX(8< zL&~eRj8QVR=^BYcZuM60$A!K3jdNCDFS17;3;iZi_6gRORR-a%HP24Y51Q0SXgecW8Pd$!QBiZb;|S`m`hGALI$pk6UFn&ID}?`OAFU`V_61bnFr7IZ(ue> z7t?)aApU_9G5}V$jw4>0ot%-c%Z0i9in34LVPL1diKl zh8rd!L;hsBuT*!09FP7Se|4K1P&8zsN_ou0$$Yq=viYQu{hO2W>vtKsp=^EI+QMs@ z?%(M>c>fWxLt5{jXcPPBtNtVMn5BkfU`%1k`+*4ktK+iX7xTL}FstAD@{AsU3u)?` z@`ab>*0TP?=E2o8%GE1GV=6MG$7jQeJZ9#$X`AXSKOUMDSn>=pupj04Vp(OYxHI*m zXPm;wdc{MT3yj0;`93B8_xUA{EHSI-WPL#$Z>a;K6RG; z7Rbgk|F#u->^VblsvHK4JZNf+(T{Apr!-!#Fstr0;QJrJz>9Z^bvv{iSs#3C9aAPm& zuv!Jts3@FCyWWNDUyXZg4V(c8o6X#&`+t51eTlL$N8ILQn zPlv56kvvekta-)rh&uV&sQzTj6c71FlzhJ1vnnO1e)Dbh*b6U6FlGjv|ILp+9Uae) zenIrVJjBxq${DK&uFuf@JsQYTsXf<{Y2E8$Ss=DR5wcFZn4M*8AG8|^_qr998j z?U_$iPfB zQ6{TFcx7;a-vpZwf!Iij#SBTtBUz3KC&P~FUW}~lY zMF_ofT~3p|oZcaosuscAxteClqp8ZF(b?L3)TKTSt!ZrG=iW1e3&_fP+J?l~N z;?RS)Mxo`JM2IDZHsL+*b~5Ylm}Jr~@Sltf10$H6kOBZSPI8%Iuz{UKT|os(yBW** z2ohQ!h`!Gtj|s9T`pnO;O;hxC{v4m{w0-6M_xCIxg=IFZO3}|-#+M(N@C#JApJve> zQ#4%h*OWeL$E+}pef}E)3m2pAaLF?kUlSh5+D0h&pjIgfG*mZTiU>#*P>P;j*)@96 zD4j#LM|9|=l6EX&{PXJ^^HB?x)}&wcxzxnA@;Iz5Tc~|eMtCfX9THNomI#9b z%5+?BArZ)=(9lo?kNT8foh!MT?cG|*xy&Lb$2wB#uX-R31j+}@6v?R$cFCdip0Sd6 z>r-v!6U^YcUYB(Dcq_tz^fMt_##hMKM9`zlExA?iYsw$~sgDwNb|`Xj6{Ityfxisg zstN>2D7Ul-#MY46ACi`T=lZ!sK}5U#&crO5qFh@ZaCO_E$_LLnbOJH2@U~4h>~l{G zeu#M84!r9QL|1%U4IUAzMbUG;i1i?@@-^sz{kNM#ing?PmwqMLFq=f4m2s5*?CW$I z&>vy@yE$mofDl;kn;C)S9!rj%f})%v90z zX_?&JI2b+&_vCQpVJN~C=a@zw3LLo}7=tg0QWgeGoXsx%nAU2!9@!p^>XVehJL0fc z(($W3vkN@wRfEOD)Rs3tv-ZS}C}BUVN4=3pZahkBj`UU+Y+0{BYBQz| zu91s%!6U7kj}q@cP&~EFeVZ$n*`Dd!hFzRpxMa8{apzUuyUm@Fv!c5LTcvYV!|p#Kqz&%?iMCNm24CvmrLIlx5j9Q{a&_r0Fl zz=%!|0%h~{d|14Hs$(~EWETAgwB=>EIL277w#(ENYHTs3KndJ)^Fj>{*8Z*ixtuIx zm9HpSck|w&f@8#(dSLX`1%N{ItNk%Zo&X4$9j@{Cxa{I3CF1gAxcDAYS|`a22Gr84 zjBfPq*BsO9FL`AymsYaPm07|RJD1cqIVL8WM#tX8kahNJ%uTyuMGG-(C!l2Bkd*PX zL&*XuA8^f*Vm>nw{v%^2!2c-Y??s^Ah2N^Xg-G)@Ec-^DP&OSc(VZ4lkS`e9ifD=k zX54Sp3RdciWD(L|Q}xA|$GFx#Aw`j|kBt)eH^38@$~)|9kDf$>h$jNeQTa{~1z#^H(}ct8*$#ZM?6zH7jusdHv^RNH9KXSf# zY3)tf3}x}PO$G&5$Eb%xD0k_+(Uv#Kr-s=-qH=+eT_TL}ulm?o{k&?VSwo8s&L#~Y zJRM6_7yQog3L0#g@tJLHu$sM|Xp_nHQST^@3>k-Zh}5UzEwe2mx8#w7k@;U=Na1s-AGMP%{;j zToYG)G(F>iRb&nQJGPx$*r$E6_a`%r^pRR=3)SaDI=)#vY33EPB?;HRGc6G|eV@P|T+0@enoJK~8tXBWh6 zF3@5uFXXo0qspOhx3;4H;qPH@zIaY53R6Cv9WL^w{kKp*!{`-l&nhje0yBV*7hR58 zIVT~Ay8PxO)^;nAZhuZPBPNYeXJOuA8Eb%|IX8Po zpU@A0u#<}c*`DZroLl^>GFN|o-iBmoftNY!Q!_ipq(c7hcG zq^F;K|NcwI;`GxQ00!p)sfFiBOs^B#C0N3wF>%fzr*g{R|6=#S*j0d& z;_-l%rOw7Zv-bwS<*Ma!d|8#GTjR%GPlJ(`B!AR_(~gxx|;%>MDBI^u>psC!mI@KrGTv*4(_b&lC&Uy75uGy3Ckkdy?CA;Y~5Q zB=9Em+O^ixh3oOAe~#9mUD=Xq{ zCvi}}A|JKa#R6dWBI@o{;y)rCc)W?c;JdJ!q2NH9uk7gzENt_Yi#F6&+NCR+&<>aM zH|o^p_~njP7lMpJ3%$Ucn_p!npT_&}$>vGMe2eXv&1wMl_!V^gZigH+2k zzQ@qJ_KC}TJE5Ltg4GVK?b8Bzr}-jWREvs3<#dBqKjMDa+InFWfJPnEWgOqza>M}1hQ`sC! zpt{Dh60Dl<;8T)hRpOc_?W;cI^{sSDAaKISC#hoWU7>X`jeAo6h`Qy{(hJO7q~!w6 z+jGl(az8Yu-PeLBAQpMjHo*avFTsUtXiz<-_Rh42G8LY8l6l=A^4Jlb5bo*q zTZe7F<%&B#IHunMFL_kT+5Z2Dvb6V00&X(xPkqG4>e*Yuq~-0u{K5lQ?f((!pW+8$ zGnawZ$0^nB2{yitnGnUwd#*xClUsGn!z5q&8Q6C+h%V&E!r9SN)+`uE&niwUkQA?U z{eaN-p~)iX&*!D3l^x-69pjbQ_G9UM{68XvmVVmowOl&rB9;;JPA(U#pXyMB+v!Yj z%U@m^sJAjRvnf-X2D6cv^a?9J2sgIagPnOIYtc2LK3-6y(#F z>f5u8Ubc#@Yd8MV>%Z)|&JWgonK?RDl4}yDFz>0^n)KZmAphNf;o*OqIdU_(boe(D z_H+K+0Vvkzum^i`j+r0ptNQxzRz%%Gn;^FT zZptJm@7{K1q{V>qq1I#T0W&=-^ud1opcYp3Gu<|%G}06)S{wY2NPuqk1=qt5BpusE z@3!!2H~Era?|!y>xUy&f4sVx&a3WEp7SfK5QO-dVdgsQ@<;yK#J#ld*jmEk>(y z=UpDIgCKy=nQFa<+L`iKt^{TTge*Xd_xjcNtMXR{A5AqIh-hs!h4~L0{wXuVBFtyL zRJ?6Czx`I_S-XONaZ`=wL2KTU)U4;;g}N>Pgrk%sr?;j&zuPzEY#jRfXD(O&N|p*1 z-E1+Bv~zfW+ag~lY%z^8zyI`j41ocqj=@L`Q^ zpH8%N%5}axruBFt_A})--qQiS`WEw#C`z#Psn2?wa`(k!i+)r^&67$&?uKqX7a^|c zdv#4B0vcyE^D~75AzR8KRfIJ3F+&?_MyF0~?=JPeIwZL5`qAt?$7IXU2kY$73XZ{_=!hsJ}jIwQNP#8J5i>1YLuZd65;4q%Md zd==y?r?FcdkonfEApMXuuO#w?5fj_`MBNWIDG0HjyOi);_h4hz? z3c_n`uX~I2-n%KrrYyP?JAW^Pz0mwb_iUijtd^6A=`yoBhXs9-^98~$~ zT=QU+5^gdD{t+$a*cUn7TxBQv@J3vAu4YlF%gtG#HwpbMA^4y~jJyGrh06m&$YV>F zWDU08YLCsTn%K9;0?uGM9lR1W)}~ISis48&?YTL)jzd#W;H(KdNyl1YhIGHxeXwxvti?(K zunO?U!o@kA?mk#xUb1TO*}zXLjUn>_W;CgL+Q#;xpiXyB?gL3K3}u2RvwR0>D+$Vm zTo2^t4GDBDQ3jo4Nv8sTzDTW8_SKh*ot2zzTLUSFzcFvZ$l&6XYE%Ca8Qw%obZ~6& z+;}gTaGztOu^^;bkg@H91j%7hT8b$%#ZQAs`y*SjO7Tge*VmXf$WPL`b}D-MJt$7L75I$u$SwM+QFgHZi#_9p!O zUA$&<{M?d9_Jw3=22Yj5v_GAT7i`|HWK`nw$ULX$M|e{eC1@p&cC&!@WR)Yb6H(eJEqKwDx zv#ha7m)V4e4Xv$Da{!lIB8!E!qW>8_(jg^BowQP4`z+u^CKXgsHIX(CC2n8`O5BaJ zgh?yk5_kWiQ(E{_odNK}P>p1vu7qI{iykwtxitOq7u4$Gc1aiZCrTn#(9toqasPWT z>^GizIJ&B7s`7x1Ce8@pVedUxe1F0;(W*&P~VIOWM0*KG}& z;>w7vs|!!vb{Oyi>Spb5JvNZdo6YcBqM^6jI}Tw-8|v}*DwE?oqSggf``XFsye1?8 ziyCb)y;6Iz1-fl-NKPr%?HUyxbT@HnA(bjn25f<&tB9**oN1ReMHBiWVT)j6h(HbV z=J`GJ^s%j5WgQtrctur{Xp`xQ3U%tQYo>*qM)cC9{7tN1P~}G37XLS7OC1uM2$)hX zX?r_W6L*pORqe#lIeeb@h`6a=^}vTVS8=s9<#_e#ltK-m{B{#3&3^d&D!iq@Uk~#K zw+liIKpKck=DSNe%MUFjBORV-#Iwn(c?*2-FSyI;ojzpKxlzOO22&GSDN)6)o&j2B z?^|_sE4P9&TTK2saWpSXp_fU67A5@#Qx)Ee2{PYblZV6xiUe@mHP061>~c##8Iitv z6>e2T+pV1@^ER%K;EZ&)(ei(an|r^eya4GXM+tKFSl{WuJUV=2Xt7rY14+0oD$TEs zsHVyKs0<{(|6}iF?x$~jT+;%xIi0iVsZff5p*mu{*ApW+L>{vNe0J629QYRw)ntVd%Lx*%EC^ ztZa@50zHfUO`2^~>0)z~njs&2^OBd0zmNIwN%B1(n=V)^_3ka9dgX6Wjk9~(F&=hQ z04^UXUeI)7J@3|UPHk&zdZP<5d@5HoCOom7@e^s*#Io}KRmZxKp37LJe*pTTr=1#; zlkUCN=0Ztq19iCtGr=hLlC@@6c!P#n_Z^+Y%W|~nfN{SKhvhHhxg4OI?=Z&NKA|=lWCsx~jFz&5Cf` zKc@S`(>Df(y7%5PqQk>bx+V29{vsD{RZ(VDIbPFGH9iRbH>O~y&Ei}-=6ZBw6>S1Z z)Bii8GXRNEuyNlwCfz4+N75D-pz+7*dEj z#Tb#mx`OMg=CPiH`EB9vqhwkWglE znricA7$fQ>(Ia+d(1q_Jp1@C3&@K3bSIF!c%@L|?pWe&J#dT!x>TU-j@$-t)KBdX)cKze*x?#au(oGN)090{gp0G6;fME(sDrKFw3eG&D1n@a$ zzoX@OhXs38p!LY`&yuC$V7NJJ$%*@5KrxGQ^kW=9HXIis9NHkSeWuI^8VRU!uAgsg zY?uQ_EGTt*0-uctyb(nrA8m!2C!2mMM1UeN(h(l3Bx({-%5`IrHLjzn#Wt1;mU?y= zee9pHyNC;fifxh}>p^WogJsh)$LYI+H4rq_A5@Hgjy@_73PF{%GruY&V9fq9jec!j zf>EY*y)PO3RGD0e?5T7g=;5b%XUo7V@P5j`s0luO3f9ExV!VSCOkJDX_AFM-dTG)! zMizzVk2goByauTHaIM%zJ8M@e&+rZu(pxI;1(2Su=s6bRWrvQy?WYb?aUyG4g zONGkNz2Z#ze~g{yJKJyE{>`FRtF>3{P3=ulBUG)LFVP@Au$(kVnaJ9mnm8ihP2+i|o_B zqjggB?7O)@KDSM(g@#xP)SZ49ew+@;k**RiPfabp$hpYdcf%Tk060eJZnrz*J#mx2 z${z_T8!8^z>M-cbT^2c@x>YS&6wz|!kHec%Vfmm$B-?%CjxBx}GPu56q{aNSp*XG( zNf6o4;bTbk*A6nQjbBS^hBsrHBxTd=2{ibkaKvwrlLs0M1l{pCb@ESv#k6>e7gy9< zK64@mn|wU%9RHXCSKh6E1UZN}H&_YzuW_G8Ydm9W;88tbb6I3G7jizKE#M5^Wb$;vmh?UcW3$zq-@uAYg2Dj5Idi0a{c!Z_XYvQj#{paYjZ~b;I_Idq60K3 zrB%d&i> z`9Q?g;_QCY*cq$X%6yWOLDh;y=Ej7r^G#KPta zop}NHl{`4B|0R5vV;Xebkv5+H1ip4sWU{S)GK58THD%#zqj@&hX;fY+J}_lO4ld?S z9u9t8#rH|xqwdQ#?WJ?qbI!&F2%})1&NP*m@G#10&p~BAaD;Xhca;b0L8{WfDvMOf zjH*=de5?umMBUGkNG;W_vQ8oRp!gOhV{od|9#Mm0{6h? zm}?wtXJ#A~{aoyP(uFPMg-1*3AA(m8$DPOF`;2@)ku<>2#vJDaapv0Ou{0!Oa^(+_F?XC4-rMe3%wnIid$OZ#?}t$F9Kvkz%*hN*fgU zZ~~LTKGjarK?9(VJ&qvfYl#*8B{P$z+(7DAH9cIi!8SwZg;%N5{x_bF?F~!0F0DdV zLPzI|HaJDIn^Aj@g!@^?Q*u$Y+SOet1?Ma3T)4k{2CSyUjF9~Lrm${kaNfQ_NA%ya z_Q6Q(F)zi?A}ve=zIHXzt~q|fSFS&fLqszDJs!VI`F;uF!_nXgx%vZWuGmP@EgxpjUgWYwo#&Pg+g)Ou3B^iYk?7xM;&pmW*;gbt^wZhibuSD z@$zUig8RKcL+H|0x#_{UR|&C$FEp3Kv{;ssaFSrQNTI=6i#AZ&!%^-4SCcuw>~BFW z;?>q$sm%`AZ>D9QTQ{!Wi|d_TXD|V14Uw`C2l2fOle=7fFxMYi7vN3|+lGNY;{%M_ESItXXPv)Hh*oMZvYF6<#ww zNPbK`_PxaP78VrCdT2u{PoT36Rb6%=?@}sK3ftR2Av!u!2v=uu=FrA8y21)>vV4zS zevrq$ndsYVs6Ii!{!67%^m4 zT48B%C?_fZJn8o+9t zZmBdP*MB0Fi>6o~Flr`iWtnw2mtTIqfLeRUW_K#vlz;Ky(lt5n^lx0TFPoyzs-{D$ zza)QNg5m{y9FDzgF64iResUxs*T7JbI zZ&{R8egwlfE!3GZ%FqTDSeyyrOKh{@ZFA-NL-Q+S)Y=$_PF$RAtaH2u%H{Y6 z$ngVmf&y?2X%vk0!GI3$`NG;|GXP@YL5!~BS7FsylXhz6-F>}GcM}uA8CI)tb7Rwd z17T655*t-*WWI#8M~tR1w~n+WUvx)pL+!lv!vSPepZ#IwNh%xHNzxyxSb8QL(H&EjN35yGE?>kUindBCM{Nb0W zQo@$5C^OW$?d3F7627VWp7+$}0XTA-bm;#Sb}*yO*qL{|VC(&K8rrtQ;@-iKcv%L6 zgi2&N;1B-WZ_1`@Ujo?1MskhW#1LTFLe1tIf^ zBv@R-I`a+tC;3LnXQjLs^bYh9WN&aN-d zvT81LTNrO{L_5Y(L%4P^iDFdv4=d1KQSh8uoI1e=J8_a`GEe*iJgJn_b-$zj(yBzo zf&1t-x)QB!aMmwzTC$8$RH1OQzikYNLHFW4Ms;1$9A4Ub;$eR0N)pmtCl1IGrZ|Cj zMFY!YZaZ<@v-NZ!L%fTks0W&Ygzs$~wH-7H2|*OMCd68*iHv(-QfrdRBq8 z;@ojz+{XPRu}37Mb22#{l|-~ksMp3wbTw{s6{Gy;@I76@TIYl0y;oQ2c+ZxOive8ol(1&zylYRH=?MjsyfluI^Pt1Fe$qfv_= zHLT!qq_fRFXZdLcD>0`zZ_bN7e&abCu}t|kbIU&bwfTY0&~j>xolKMK^i6(U3Xdkz z_%|K{+*|8)hPDt4M}NhoVRkIIxAMjh_SiKUL_#@rk|QheJh16lAGbO9EbQg=b~5~T zYhwV0j+_8a;^f|z?jd;6svTe^df@+|HjDOh85eJMtC{n&T>Ebk20M>m@w&VflV39V z^~_l@b_xvT;I;6|#|sHH6z-{Q(1QGtrf*c`gxg~!hK*Wy>!p1xWt4MnwRm%VuzdO2 z2`qC}zotz5{i!8fHBp6(h=5Ho)zk9TIpUI@{)r^@vu=`vRXNgUq3mCL@Vi&(323?U zh6?SYYf1-L&C4elaQJ*raS{aBNc?ySqzSsjR45T_!4?uXmg_U#LCG^G;y2p?jt?P5 z>kZ>wG*r3z^_g(;Mhhnte&;x=7y>IKU4-F^S>m-6%y+NkAFAst4di2#K!LRIbH4T| z-_yb2(fvy(=XL*e$FRAob6^u>QV43+?$}nh3$7WVP9#a^-^OwoChd{#DRZr88=~`D zzA$TXpt5?{6JDZ$%+b&41M#6h4NW!CVhj zJvJlT<;(kFxiH%qyG-BwoVnr*shHH!Fb!r28Pq{06tu~gQ9s`X(EyxflRXT#(_o79=8P?~zhPC5e5-7j*b5ruxIexG~3c83=m=^#;FOMp-W!Els*377{qB&w0%zmwp$<=jm5?0F4{H)LAFzgBeCW4d}*r=;S#*U z0Q@k-z90l*kTK~`s=dw*h}g;1B`5@&YGE>@so9N*ZoJX))q{;tYjosSGOB;SewE^4 zkrC&bwH|QMinZ8u6}ANLRz~ae^B&lvfVbdlKW7KWOxe$wF+%pp)37ZNpn)jskz-(y zBe3PoBRfGA`|Ir|Rp@;6$MLSX-AJH?^^ClR`6~1JZ_?%=VjFB!>Wv>_+|KEVHWMqy zx{V7H-;sr&vE$~i+|-PgZYhK8KB=wN5DH67)J;8Nd}CJdN*45UD;khFog;1vz!E*> zHdKdDs!4X$VA$ei(+mDI(!*7yFKZYpqE=tmHpkJ}p7u6Z?{O>=KAQE4I4zb*Zl9NkD>lE0 zjWVmaPq5GpTzLl1&dKnK;BKHe&D9mMY6lkUIjQ6?dm~b&eQ{ll{AmDu=p@`(SUEN1#Xr zj7`ZA4Rw^L3w9pWld@Ip=E3(rq^ZL-U#* z(6LJ|lP80p?xY;#h?-$K#qZE=fl4w1oW=OZBOIuFT8(U<99nBTHkOQGMDip}87#%y zpX?6`@oC32(ss76eO}m)Uv=76IWqRU*S|vFK96xSL@QW)xwtY4GnT!za0Im-SBgtp zC26kZZa4n#=NmT3eoHFXr@qB@FrdyC^GE@KH#QxbH^H`kQpR`;IDl~=GPT>Yao*(> zfa_UdbF9JZf!8CRDNHI@t0eop9y1l4Ekbc}uWC8!snTRP3OoK-D3~tWNaNGkjPZ@g zQK*n4eg)+MORh-Cv{ajO_E3(hQvz(8zhb0#-_La8_~g8I)12}4KX0fVR5!Y(Gl#} zqVzmN<-&=lRZ8(nu=;k>-|CwobxY%vJ9K~PJK;%U;HUef%#aVc8*)2WRR-jQ9@<)d z!A7$?J_b>Ni;s!1s#a%>d3FWp-1n_>m;YfQz!I=S9+%@l)Hg&8Ul`Ia`hs&8--k@i zUB*JhLXt9|G6z0Q-w65pZT9GN*_-w>d>HAvy82NvEFVPYNSxI&$zN_HLH@SWey9ARzdc?MLU5q3 z?Tka33r%S;xv*o&Bo7$G8zzb^HYX9)njD84T!(vvre2+1mbeI5&u+%i6o*Y4DT$5tOI%J6 z-o#@eCmReC=u!;jnGQi!4SqAGBfG0I>L_n6Cz6i}{)#2HhNGeQFZJI1?|OM<*D#k4 zR&Y$TZ8rZ-hL@A~6~!hmJYY1Bc#@H?*3%%ZT41TGWoei8iu22BBF3N=F$e|>S3g!( z-XA>tPI>c!>2KT*sY&?h(SQm;_^}tJWi-DrSEn@>!EK!};z!7`9Ot(9n?av@u5tEp zoFBZu3fS#u?dw#rLC4=&UJ7P*IW$M9Lu^~@`Pl#~o9>+Z=vgTuug|e>;&E}g z&Wczy0x`2~?L9wBov~f;#L2G{#9|RI7{@eFQoO$LVssX!!4YSw;Y~vSg^P`VV9vY5 zWfS7cH<~rF^2*@`*VXa}k!uDm4T{!Cz0!(bt9K(bvr6A2CLtmBICw{zO~0l35FdNe zz$j_hQL_lO6&dq#WLp`3p-InSAsjpUmuz+_(Nw_tHYZ`qico8`&}x*Kdp}Hc)eSve zVy*-7z&)*x8}SJ$EX2IRc47WrN11lxh3lw?`m^C&yK}f~s}!6siiUGU%2qT*%tO#&;5Y*&5w$?8`0JEFEFzz!kGT z6lmDijkSNBqkCT@v0MMOJfPgn-1xvt)>4aD?T8tY7{~UpOVN3w>0Pph-6hf`&t|iH zNo*|ZCsdqVXtE*V-w^5E;OOZ-2rSJe-E%PhVP31Sb+n1uUV}!9=luFqDQOImt2b`b zQ>wN3@WD~<<(!K{E`pUZ795_MFR{8$69ip3Wmu?;20vuGqO`A*A95do=8b!4-a7Ep zxZG518|{0C60J@8Ai=fv2VT%Xhwvw3(94xQ4CQin+a=`bWIH?!GKne-do^Imsdsm- zK8h_DMlR=7{Npb01t;eZNW8a1)7@xDVnGC9Vd%3*3`lbaYld{ZC18IMp52}A_0mkC z-DQUU#un4D7e=|pJS;*?_V*3O3UoC8?_P!DvJn-F5Bt-zpD$;oJrLRjGzMf&928U%bJ!$VSk zHnd#J#@)8G+Wg4sSj$*cq&a6^Q>ra>5DgDs863P{2vl+m*~*q#2mtxIzG_r-2nf*F zFlGp|8p93zj+^$yWWz3=lJfEQo!9}y6s*7X*68OS{48%mqmdi`XKqKpR_}PuCh-cR zBr{s3jR7xIba<1N)LEe&NBrO7>kJr~1lh^&`rZL;q26m4q?}`|CT9x<6O~_UN{^%y zXE?UME5^#f=3*q{bLh^L!?fLW^1%LqIOZFFgt(tAziXUc8#ZM15z%1#h}^hw99~jN ztd*eC`9Y0GzFiO_gvs?7lAALr#Ed%t}izSe83hfEuM zUyc{}T5e6gjWl&)VjeMyJ?nfYqV9nDsW0ERLsC{`Z{77;wW_#xj8*^ z-e{5VU)_@B+4W<=Igxr@tJzCBPP`*$@OJ21=;8sK0!fv6#%74tD@BXGpB1OihV#!< za(0>8wKqpB|7m#(V}GGBjkk=aYQgyJSDqBq=oCY{51rFkNbc`sm{y<#$+-R?gO&!q zLK@E9dRNvQQ2&|jrFI*0AnmNUb`C$G)1xzgNRSD?pkhmox$fjd$8U7eJkBWybV7QC zhyqP#8o1Se2yt~n4j22oSHzwV$OW55(d0aT&MPq*I91luGbz2HLu=)GyFNgj*4o*y zX#rF|+g?SFbuSuSlQKtt41+y)^Pbpbt4-Qd6nwtRl|ffx$1ZM<{?_-%cm^*lTDKS% zIPFF^JUkL1-|5I#WU^)yw6!z8RY!G&HTOG>pYPEm?5Y(1k#{=gTlXOdxo9E`h% zW`UMxYk!+=y-V!Y7)Dh&4fz~)aQI@@n+G6DmH zXPI^h4B8ZW3aqdcJlm=81lYA)Sm`z|SURX?vZ2yXp25_65nSQDi?4GyC2q$X%QuB6 zwErAl8!+;1c9uZKd5_H8%ip%LVIGUD{Ki6b4@Ji=HVwCeYC}U%(LOrz0UoHFWJO<| zZ=G5asf4zJZd=r1FI;klHH^AL>t?$@4HlC&Q)^Df_IZottCx7U`Td7@y)z(a!HTSS zR!(T^$m9=F==US^P*o2jisa;(Nxm|ZtO~bzMtv3+QZ%R8^2Dho75%`+^QT> zPv$w9tw&zb-?`Fb2u%B0V{Lq?En4bb)0bC*PyRHXjq{mnOkQW4>m~woIMH>#wLrf? zolHpT$kRX{kAPyQCc0I3GnLIySGUsdb&W__*mqu}>EQEiEPVR}oYBGdiM=(1m=)=v z%zFRj89dyT4u<9%G_qt$6_>pOea?YzEeB7sj+5xgg%hT@B(!`S02%ZsyhIB1uJPV! zx1hb#EcvD`KVRiO`=>1)dG?sUnZ-%6SXY%fXz>QaUrP;1{P{fDjPO>g7mn$v@ad($ zv#{w-qq=now{t5}-#jHm`@H}l!N=F`4bZ_*VjNd6?63Kxy9ow?XtEQloT23g!<=-* z=l>F%n90NuqWv)ZiEQy-w-rr`#!#@URFo;W_-mtSIxj(-qwZiEnM~mqOGb2YL7>*W zoOmJn#Za*9*$xaCSJ<{valUZ)Xv@B~sLryJqX=9$Ff{CZNw4r=bp zB=q7av%tubGPkdjsde77`JP5Kw{QJ<#8-AEC#p5^ouu(PW**N7#ujWXkNMxljeAi+ zOhXyyuD)Q}Ii|7h5ztn&!#p^@Q^r7vj<|@F?;-!ase^6J$O~GwbUx=^e4`0JtDkV5 zGpqhKSMmYdR*T~A6qkc2SWw9i%eurrsqrVMlshR-kzHK7lx;Vhjy6n(ot*e@p&vr8 zTBqfNJo3>$PsN4EK{FDurOHgbKo9;-8;!*mGJk7tim`hP1)4>TC(}BqXFY8b8;V<7 zr}+!%7}KIHc`EFxlaG}@Z`~30LmM(W?Ki)G%=IBo9SvqW!D$sX5gKN_XtS_Ig zS$aGCyy~@sSxO<#cfvHQ*4E?Z=kHbO+mK8@{Dh)CCC=91>Cuc4`Cu^LQfeqD%2pG)D{3*D{KHGDfLiG?8}8Y_T1W?^>cs5V17)X}Jew+!_+BYl34LK> zj;;D#LD(ewrwE#HAslC>KGCh55 z4AtXW4wyWfJ$1Z!epRXsOQE-bMJ=jBr8wZCOqkT$evC9mR+{#drXK4ZWMKF3#j)evKvbh9M>=mfG8rN80W9I zIJVODppL&2gpBEOZ+9oP6NS3rp*XZIEclqexAwTxbkm$>)eBSjwIbB6M4MvczGT)g zY_RIWAEk3w5by7YB#Yj>984=}co+)k&@;qbtGw|!2<}O9&njJ_LacNb!leeT=ezDR z>T@#zsOliV7?zB6?_DyTni!DAAv8tDeu2o3PARNw3 zv|=}0Y4O$N9KKmt4RjIs1_06DDvo?|*t7yn_R}rQsN=Mi0r}ba=i9MgD4&+V#*?J@ zg_ERRBRfT0fBI{*1R43oCG)pgcbc#!Y3wB6oiB*fr}LHuo{_)j+u>0BeDkp)Cu#cM zEl|~G=GtibhHk=q#?fm%i1}*a_VZ{bCo=XbJSRDyrc$6jTZR$p%GgKPz&J6mNBUKB zWJ2aE(U5_u*4lTZUB z(`##%uh(z{@#{akizX+cqyF8CR(6Qc*M~_cE%=)MVVBiWi!9okBVyJlrx*4)zs~feB6y9Zxotw} z*M^-EyKqnU&_XQ<=~jp6-&mDHiLRrJ6DF-#6}KC2PV!Z~30V(g@mv~AL3gudy1-vn zT>N%z=V{=ivy$P%vNU%vib(E3*wjBe8SVYRRny!O;4rydWyJMuq8l5vpF_m!_vrP3 zMSo=EZW4@mWIn1vyhU+x%Zweh9|cUs~IniWjCpWis1 z09J#u4}+WzC(YVgW_w4#C@!xWSw@&SRy5gPTPikb7j?~fq}ITu6|v|))U}Lf+M;lD zMg32XjOToW3L)t`5b!pG+f2*RL2kc}LOHRYe`MBp00`)V!#%GgdV;sTcXZ;BIhus3 zMU5WH%jKla7G9k|4;^&YgQq{Y`Y9gmUdNp6wj29@ojGOE$n+xt@v&U6q{NnymrT;g zPs;PD4A5~@hHs@r9SXmcZ2Y%M5)@ej0}{SRv;n%0GOK8kO*CA0LsjRLg+W+#J{BL! znT0c2Mae1x<^f(b;!7D0Kmpm~BeCgpfj9?maIfgMZbs~5e8&+kAdGXSA=6^r@LHh$ zURxSiI_~3Aer2_INLQI4$Fh}y5MsI0H*3*vL;01d8P(`JRsUf* zVWN`h3L}Lp%@Rq&wQ@Ot?JxZ9A3_tbjtQJfC3zEd;IkHpL&)N}*-GUixJfLh6|}Or zh-@1E3y2H%J_kMzvT0^<{Pc-ryh+MVe(=3QMtR*D%n{CPV6Xq?I$9`A*no|-YAu1R zy!l03I%~PvPwVeXU?H25Ro;Ow3&%R6OF}eP`*VywzuZ_c5qWB)edVf*4w?@zyW zg5Ww_MNW^gaKbWuY5y$ibFS|SH`JM zRz94KSqxP=N?cPLCk?X*tJ2W>ymIMcd!~f9gZ!}DsqJ#I1;lThLfQ^);*arKFzluh z+?mqE7ms1icAW##^_#1ZKz#|@XTg}6F`OYfb-K4Azp2*#E#WfUF3j_aQ_>`e5y8_k7L;%Oa9uuc;nr+_KI+*kca#Ajzui3Z6J8&p8*+7J2ne2! zfmru%Jj-X#X>jk;jN0xMb*dWyxsXolqf7F1+4Zei|CB@xe!So z=~^8uQotKCN(x67SWE<*^HrE3*ot1ms88Q=iZh$lEGHH0et^putEOGbf>3ZI%KG~{JI^fZ4uWr77Q&URHES(pm9I|g*rKepbU zG|Y{)wnMZ&Uc4K(A%#yDb&R>ZA;|lOb>rhz{z$cu251RG>@;b=wrX^~|2syt!?)+T zYWU%i-Lp7Qb!vMmP=$4MY0V_71b)acMqdZ9exjUImX|t+J%LrhEmp(0L*ys4%$hCN z!?`Z{RH>(XKZ(!ej`va?k+~93#bApRppVOvzq{KX!+3ygR2?sDWvi>##Ed-&d|lkxJ1YF4-# z`%CfeKeeEa12}Oa!bP{hO_jZ^hW|W$!EVFZl5pafNqUs%GaHbxHNUFh{)TN{&;aA4=ig#c65iW=fP z3IHz1Rdok74Bxaq>RhgX*Oe=-?HS+vhOm?Zy!IH?_`*tXh+A&`P1{=s$5F7ndRGSsZK6{K9q-I2 zI;DUSa$416XS`nT7z=RNWiV>6s{7_zoM~yisJbv_c;ErJtMNHFKkw|470|O}blKNi zfN={}Ali@YYXdTvwF zNrkoXo?(~b6S8gE3gHibO0Cj1>+ZUqtgAL=<@26t(t}<5E`ou6f3kn2N!*gocT^x8 zK9#KSH!(XI8n*cYWv!h(BIK~tJDiSW3ghZF5E2s$i0#?>ksT2w4_4v~(F;4Q;YTjq zVyOyQ>FrjENrj>68f)w7q=VGRgdDb8h8LH`%s(N_HIGZM_SupvTXdu zecx;qBEvx?{sFZK9r574UWrHEw(qMq-c8Xj;r3ZJR4Wi+s?lS4=B4vD^1`NbP@3j( zM@Daplhcc}HdCKN9&OITS&OvbE`@#hVyBD5FLIN0W~(gf8uRVd8d%xCuey&uTw>Zc zP4d34RsAB29$O`r9F<~7{wEL8vObtdgMF`=6d2X)a)^l+;nIIeln|f7w65u0C+bM- z5KyEfk?rXDU6m^Fd?jC<^;OQ!CrO)HMD)-vQ*?=ZD6Y%J#K3zj*F7@PStRdy|AEIjPz%l?NI4yUg^ z+wVa*Yz;+v3K*ESS0g2I9X7XL)nzGlcBJOald(mRr zJiqO14~*^Qd-R}z`SKXJ^r65k2*N#->PDTEn4UG!^ngJr#Gh7;1KsI}F@o`2rcnmh z*LI!?g*=b);}B|iuXW25gk~2YP|239JI3((C;2bLR~n|@#x+imT#`joKV73kn zfq?8@VovR+UrCQs8pcWLPQ}$4_8iOwBgoy&pxU;sBu>7l#vN}s#Udwjq^?E3P+4eK z?t1Qd7gD|Y&qq?9D*~>pImJ!5#}=t2i<(ubhc#R)na zfcx!d;{};<`3yc}wuwR%!kqxbG|i2sNcrG<4@H<+M74g^n{=D+;sDTPP_OMzX+)J>#Ez4l@@x(ah*oaE?_&|>y*?_V4x_C1C!-D-(@fLdVp2oku~i4$UMp3ijPnbMoyF#tRF1W#nmxZ zMu@q&k|l!Nk7rkv*!c(TVn4EtE)n8=ipBCfs$>Z5W@<1x=|dQe5qU2+Q%`bqOAmsU zF1yGNI+^Db=nu@g`f?S{Z)Yr&&s8c%2_g|E(LoS>R#KGVcOG^j{$~)J_NqZTj>&Ic zz%`lOkQwOS>uvAueK|^g0=&S!I3-G_ZX4xzn^Ngl4V5_R7Y?Jn7oj5vK#4k?qlh_R zM^uVg?q@STKOrO0P!kmRvCA=zIc3B3k{%Pb%UTC?SA7#;`gvr*0xmwl|>9IfemBKuS z2MVTI2+e*NKxLz7pk74cSnvR?y;RzZGYqsXSjQ!m4kQzsE~@J0P(Dz?lheBv*^u4C z>rHZIsG9_!?{GBdH=DQ8nnnmgcWl2;kj}MjJHFxXQQ6pG&SKE}0)c_U>k|s0H_PrQRtm)+^@eJkd1$fU1#g+>_wH)(e)bd)ai>+UL>!ICOj4XFY|Iq#c zkm=L-vn1H3nBrsOz3RCZ3!i(Ee;Rb9QpmP{g1z1Utv%1q+N&>hGnJc5K(zWzanj=UmrJNB^J4@PX4`nP=o!&uUpRpgY?S%S?~Iq z9?y{70>>8PobEeaylJ4HF~vxy+J)PBot**Gx26syhYBT+K-Ba;cU}+fj@QYDc$J}r z{5hLA#H$XiaMgMnmPEC)k#8L#3|^?x;AP69lscssBV<#<2}5JJ|JwcczKRwg#ZxOp zmJg}P?CA58Jym_at?y1eA=Qo7n<}g}aj6WR>1DwV5q!HE+Jqf?5PD-QyOjmtzgO~P zSI)78vhJf(l9VWOO4YVkSFF)7vc?w+ThO5{!yo%r?tJN`1hxEiiT~XUM(#S?tHD96ck|i@z=z8Ew}b} z(N6^O!411^gR>fxAL@j=v22qqXY+lHF{K3Gje2EcKNIJ2a^w*4n^dUpu1eylU{0n- zW9yeo2ebRe**2{Ur~k0nvYzX|1P2@~OWttV2s##OHS4jgzc{&IhZCfR4l!Q5r-`#k zlTQAVeDIIY-j&SJEH*jI_2o)WDn8@o(bt=i;iX}D+1t6ME^-$;VTmk{LJ*kkCB}4# zpYV$!7=SbU1bg2_H1t;jU-_Nna}-5diXE+Dt3X}y(WSyHrc#0;#dw`PF_bxLf23>d zy!jlN4ZkUad1pdUY0rlC`YVsI87PMbmG;lXr!ha4v|XvNokC}G%_9vK*QifPd$>F( zd}>1de5B9`yDB@+FKaYRDE*1PI}u*cX>c}QP9s$V_1! zQ=3zpmMdtfGg&&!?rJd2;~_&fFy?MMUiWz;`x5$|Y!$)TlJzfk;?5KuwoaqKv?AEH zsYqsN;>*diaB5s#N97+;dF@f0iaMZr>zFD*v%Q4|A8RkV2t5(}EZ%M!lTSCxt?&Ixs7Y~h>Y-%vL znICYOOB~3FTn&D`*v_>jy?wSG?P(i*$7V3suELSsm?{@0nY1vsavBAUPPf-tDx8d?4?6@ea;7f7$iSvD~vsqLrybepUqsUO)N*!N*(1{+vSJA=W4GdpI6)b=mjn z?aGI0v?9{}PU{Sw>-QNp`Q!dgGH@``h%0KjC^eGV)-KMP%?^;MLc<~HR+|jEee3`< zWOQu0QjycKQ-E%*`qp3g)^#(ne$$@!G^rxg#KPgSBXDNk^`Jeuy7QmdwokOn z*=FbOJ&+Q2s<}N(L<Td|UAoza`^oWvoK!F17PZE^JS*A%J_ZtQK}(-cL28nUV_ed-y!pC2&M z!9Yz#XS1~C+Znw!pafgtu~jkr_f%UUxW366nXbpK&)Q%^lsWOF{knruW}o$~>a}wO z;*?^qn-cz+sSYf3m7wFbB~ftEv%5hQd3}c((NTYpZ8Ugx%!SWO$@=C zH$PRo8mp;bt4Gd)ZWS6AlsOU_TU=va9JarL z_OOhyA`cz~d{uhr)WdequA}coL-JPFEEBn6T;x;&O5>lbn~NR_S@Yvow+XmR_0ERj zQeP0k2`i8E(a}hs{t(J~ZqMkkcv|#OpBYIo*I8T@2<%u0^ZfznOnUC^MZ=!)<{hsp zof=!hOZXdEb6PTLbM zr=Og!g&K0GZAOJct|n=na=6gY3JWx__mSodUi|0Z6xw(on0WeltDyxc9FU=~PMV_o zGy3Zba*<~TbWaGPesrhNdFOc)t{ippR-Y|~w@Z>Rah!ExG;!@M!ghR)d34sXvDQl` z+h2$sa|-N8>?CwK%xZwtYGbc$D?A!LPDHFq-LKZ-T-?B_^o$GUa z5Ijzri1`inU47;RDXz2t!D(BvRL+8bY{pag8Y3hhxz5CHKUA+AQd#O|U(tW#Q-i+L zAMI4lBSX5Zey_xWz6IYqA;~ZVrFp10LhwM&Y70z>*$TN?_Ev%+J)$Y#TUa1og}!-D zjhQq+*yW9$IwYThJp3Fz)@KYe#;DD5>iB~>sI*|*T(jm`j#h^; z$E);UuIS4kxqFSc^#M3z(sjQj`!Dpj?nOFzXoXQHH}$oFe0yfpIG;@S39DgjhOGun z)#Zy*e$m$}8P}J-@%j&0uKeo*RX!!3W%|<^VGePgP=)Dsl`0)a5fu;oJ_`UJAxlEN zl}H%;ttyd{N$v|dBCg(+c8frm*HDD(Whf&eb)sS{plpb(Buac0%Btnc8+7luNoz9n4hIK3jjstuS3ag43oV@}AD?J1%b> z%jD?OCh^I`%&WrsCXjiA|i zdbu8H$p{PyTVH0PK?b$MsUN3gw$TB4AXfyT;9F&K(edan?ly4m|6%MbgW7tdZVv@Y zDORMov}kcC?gfgbxD|pF*N{?N1Esh_ar+l{iUkN>+&w^WFA^ZQ_vXDb_w#!{WG0!+ z6JWO4%V`Bq6k3@h()(#EnKOo;+OuB4YE z{U0iAL z?OV(0-tGMAtGD^+#>ocIG4)vSY{`LDPaJsvqv;!w>kq58i=#Hz-26Or6GS=*Qi(DQ zFObP{S^I|}7c>vKGUGxHq&=vk%Um`4t*5D;#|$?}s5oSwBOCd8l9AZnKyGXxqGRgp z;rpL{RXi8p+YT+P5~T6FX1BD$09f z|1b*O0!4_c&mk|fi_UibVNAC`@Uss%5`!?3G%&ELz>5$3@ME4-A9Q*}eU*ugU1uVQ z+2WvBzO{2*TxcmTQlb|=-A&l*>rYma!ea1>HGeQWwrVGoTU^#pTHSJG6#)4`X`=COSx@ADn?neffw%EBz}9zt{7BuIc~(i}>S|lxu;pJv>njk(WXDF1}7xWcwX1 zl~^D73gsVBN(t%05F?cz2?f|^g7ut4f=ER_k}J4@%6VRGM^!9pAhwa1>gK#R)hp&7 z#=i5_Az>weroM;yz00}GmzL#$oJFy#YRx~sh`+FyT<0_aglX5+ysVwxdnspe?dC7v zaHU-{TTtdo=-rUtrc0+?L%u@kCuW=``p_XW$O=;-{Gz8AIOdP|{4_qxtO)gTH;9e0 z=6|XAOYCH|!`MIJnsnM}$SMEA1yQ5m7)9d3;lOuTeHSSI*Lb#*ppkyvq_0BxeId$L zkRWxN>-9JufeKyR_j)jVs|T@6nW%8Z$X|ubJR!Zc2XYLJyT(0bM>W-qBRa#7E<6`m zl7tdy(z#K-c%~5*E|U_w+ZQ4te#|~WEdOJ#v`Xsw zCML9ze^qDP&iZItlL~FGX3f8fb-aL}i}#7y+@~=qb0?8<_8Di}k5+Ev^X46GKM5z8 ziupy!f(l}yYB#Ga*Lu4g(n_)mgp}(<>f_WVYJkHAVNS_Fjr%c>VIqd!Lu# zY(i!V6u6k)17c+t-V}a*FZg(Qcr7}Nc#t|kc&tzh^{h`FfrX*0hy+QJuR%ix=1iM{ zQ<>S4Q);9SLnf?gA!)MmL#-9}%i&S75!w$cF~?XhF@=*i#dhZ}UI_2w%+`;5g*PP+ z?Nlm#_^-dTBJ4gSNl8$z1g}+b(R@M~#B;baKNqX^-cz$?89DQWdobK&C_mDdEK)pD z{esoI(4)n&N%GsTRE;8UY=-rhEgR{!lm3c!+pGJ8S4)-?d!y>j1_q;UR&=QA0M98~ zHdIH3&)#GC?zzfu%{nx>QSo(~-QHR@S}E}Cj@x~~>_fO( zZ2tGpXGx$p1f;}YFt!+OOJ|hQdcDZTN{oCA{-Ttu&Vv`msWd+*dERlu+_-Om4zD8;VnnH&8L|^^=9~`WkM5VU zoE9k!@o6KhtN+4X#5a15%!`UP5b*JbTs;wa9*o4`K)j zxM@yd+O?}3>2azZN&X(SbIt`{~l+?DZ*Zv{*OhF)+l^b@J& zYKRZ8<+rnQCPx1~@w=5|Yx3Rq0|j{4XC}7Inrq6!9{*ts-yQ4v>24bM{P%f!+sAS8 zHngZMW#PNF>k!KYJ(rtF(-Y#>E@B2dI1uSI6)U+w1bg;ZTio;BU z+A!>(?aWc&l~)OCQBjFUaYx0;eMET&MFV;`Il5cmTEk5O5R2OoAeAc8A&=Bc!0UI* z+cVBIs0!FrXF3}P&PAb9$zM%#vdA$*5{;mHvH}Bc<8DS*N%15_?b%ge!aq4>UQ!(< zuD#`7e^}A`T@Lj*-54N+V;ObGR#uAUpm|J8Z{%ouE6zgBvd>i5-)uBXJ8UM$h%{!N zLtCpvAY4R^vz~}G9xo;7fY>0W68KSQrFK^-M!j5B3^8#H>`51kmY@c#eaZ>wK(UU-V8qYwE1fsJ>MJlM%4SsyPp}Y}66&kq7?L5YOVeCq?M7f8D{ZuuFt%wmWlt zf5naSh{dMhV-A5thL%Vh^vFOUMaEX5n%Fnmc*+dFB~|P9LA+bj(W}0M@}94pa?E8I ze8!2qthrZrpSJ@9wOQZ94Z|rlrIKDJhn#I;B=}|yzj_>wa;N};Bv_CYO_`q1$DtUA z*KjLvq^QHpN#0ab!yFksvRP5ujg{7>Kl)76>kGMcl27;Gm|Ve9j;>Z?+@cFRz`kvW z)Cl@wNmh`9E;xyp4vyZOq#wI42s`Z5H{|Z}lsVue_nPT{V5OgO`?^Y(@2Wf+p}s)n{KiZ0=cW3E%)m$K2iP5` z=uy8DvxXodZr+PzdBBdVWD(&>(3`6kFR$UY_PoYhWY&@YG1YIuvOZIuhQL;p3d3z7 zc);Y+#H+$^mFiwO{5W>MVaBC_RWIpX)!7VKf5EipORAKgb+VBLbz$r=WK(O(=y{Vp za#4L%X8#VVIWZGuY*_TJ?{I|&R@`yF;#7V27D7tIafqJ1uleNz*N9iBR##`G5*ufH zDEy^o2n)jz|80Y)Sm>;2CQow;jej5_V$dlxB2%|bw4da^zMzGD$NSSE@K?N`CtNSi zkB4)6mCA(-2~U)tqG0)jS@-z7YnkjuAFoZdY-wR}`O|ON1KxoOLN$^0%W}WmfDjKJ*qbybN*-i4Zj&shxjfo!qpnq;ZK}mb$6HDUum5!8pR-Q-|;x%bT!W%Pl4bE4PHI>|&@O(Xyih^4n~} zeg5~s=l3U^O1i^z#OcRF^tCZMYw7{kr@#YO#KMqQ>0{%iaD?!z^}5JQMwno$Jyvc? zVGGM+7T}5Ix+!18l0)<>d5YAHMLU_!wP(GSKC-mBH~(%XD6LcNU)PHxzhao1w9l1+ zHH1l4q`)AAJX=dc->|`uZ$0k6!)?Wve|&$@MR!?_IEm`qV4eJLzPbU#i5sqMp9!FF za$vQh_J?A!>=CwleiH~z($LOvZ((QTDo%y%gSf9?olZ$b+V=CQd9nbXMDGpV9-5S+ zH*lBpAMavASw3}A@*)dxpGI~Yn z){5JHfStQ2M21Li!m)^`jvLt!eV;Mbchg1|{S)?n8Q4cloY22sDn7y?J~5r9GmGLa zszfOJ2hM+^z`xE`6ndWs`&8+T>j|911j=V!nGNT6YOf*z;`a{{+xJAL1HUp$k3`A26QCP?Op}r0>kA@jy4e9IH-7JYIMogdQ>Z#nWBfG?<-AutjLYm=E#Phx!~6scl6)`2L!0_?F2M8Q@)O^kRDI_?LPlh?#-e zoX@)4#&Tn@`pIQLF&_6czL$^u#@qO_y~J*(CB->X1P-T6R*X(lAWo0^5r|5Ra=~&n z;F{cQrN{l$a^q2{xM4xx6!P@e=)m^yiL~ZM1wn=6F&_Pgk-tki6}wcw%SADABxTzu zLmxQhC5xVt+K$1{qyme;`d!9U5!MADm|WZBSe$ zEpvP>4Sx1AOXZ)X+Y7p-eu1i*-YlrS$^s6Xpps`Z2T|W8!LK+rnY$_9G4Nsq)hdV zEh;_gQlK~8JLzT1vnI;%W{M&)E}2NS#%85O7D2mfq7s)E{c;o9pE8#R?6sBVb2`3N zv_139W|-S&kUZu69Z2Y{*+*GX@EER@dOp(fL#(4UVSISa!ILU6SedIa692k3F_!|w zv3Cb1FQy$JNJj5e(^fxXv_3#HC=v1pxG|kacf`hVcZ=1+?jH9XNvpW_SoL5-m-ipGY-MSH z!5KwPY0xK*xvJ_<*9k1Atj$rc9|sczNf-9)*GU7U_vd{N?Gc2zMV0%D?U9Sbi(7^w zOLgz@z&~GMNL{|sk0*AdoR?_aG*jlp45lKnWL@fc9a!SJjWtQsVARJJx`6}q=5Zg0 zmb7ZgZqwem9oduGlhwgd84_wauO9Yv?A(WH0pQ4+Gaz;BwurL|1cel@@qUy$fp&Cr!7C#XH;cqQVTK+oE&tQ|B6zJ_oj! zw`ctUsExj`Wyg6LAU>gH$q96tGz-YRlU#v|LYgC`l0=7^WA>=&Uu;|ELCThv5AqgC z`?zD>FzpaBTH$ZD_n3>(^hISaa%g>b$&mdFkR#TL;N_pLSHHfWJy+JW(ntC$)!o=i z%jp0{OP8UwwY-anCH>!DiF~ifgR<0{@k&PM+bdDgOkbkJmDU8mV7z7**Imdg;OTKJ z&5V&in|+N+MM8P!okP2fo+~r*F=y}5>8}{-H`jL7h0${G8te=Yy#ZA`i?NC9mmup` za_y5F8VOkMf0vop=ead*zPeJ6#_!eS39;M%mAe( z&vOF%gn(LnBiwv5A@OBHC-E9`ZI8usHQLoSge(g7gfAIzhlx~h+uu+03^8Ol;EdLr zwHHJh7?~XNq9yOgUx~a2j4_fm>Y64u;}G2Of-Ej9X>SOUZ}p(p|1j)3nnQ+~HS3X& zTg9ZNJ+d4pahEiXf3DT;^^*cBMVC!({cgLrFHUZ?E85QjvW@^Qi_LPbyL%BW%Z7}7 zGvpYDPH6V>nO%!R5$Es>XT(zWdXN}4@s3`}T-6V4IT}DI0DB+vaV>pP_KnKzHbF=# z!%YR*Vo~*P4{AG=sV`?QTrh6ya~9DVMu69GRWwC~VZfu?y}3Gpo^|dj-fBVVMu8~6bXy=+Q=oEdb|3I9B`~1rUUL;s{fF^r@<~;3p$$p3HG4NZ@7ez} zR=~%NQ+uwoV6!Jh6DdqqzAqD)i&8Ov1gcPRbaxLPF3h}YqNrbe%x6y?4u#%o;=lgs zB`z&-=b4XxYcp3Iv?S3(`kjqEoShCcz9w+>BC})>-Dn-;@?(i$+ z_?JzVwL|M@{1+KpWxA`rH!SF!b)j?yNy(ufsF0zb$3xpL1G0~f3(%X4%~nEgMbIXX z*&m`qJ`VD7;$Iy*i3&RFQE*ePF7=$`D_^2KA=sAX(yGGpge)+S%W3wDQoFC&HR8 z>DskSyl3po81pp0LFjmJZ9K!%D9Mcf*L8(Q_NM-_Q;*zCrs`T$g~rzRfBTKc*K1#jB=8P>ev`YuDTqu*87b z>Z;d24BFdlbXHU|Ye`-F)3dnprA@{8xW)=X#jg1_yR!P*CK7ew(3SlDn9jqLKP~oM z-G9rAzJ3!hm!E$St?Eh@kd645O1nM@Qj4^U^C{9{Q~JS7sUzy_yq$n~Vw7nY<{m)V zg}9&@uXQN73Gx11$uhmVt5f>@qx~@nRJlFN0#}M4Q^*u3H`hjJU*nrgIp4;gYyvcu zb3U7>`ZQ`CL-|3ffLdQ`6nL_2^*VXXPCM|7)2TJCqisq}-F*t#5z0-#T*V=FCklSR zS(Oc5zG43}<*#^CP~Jzl+FpL(Nnvh1Z8_&*&a5|mJnx40sg+A~8_fChh zqz$Sk58@SUC1nl*Ci|yGhg`+Cj81bqkqZ+Z%*VD-o9alY5wq>ySKjv=Xnjo{2zN=! z!)JXA9q~{U19Lmb{OLuu)KgeKwli2)r)2pLLp_|oOzdoMc&DPWuKmWYlM4Mr$G7SVOFDyt*YGFT-O?n&EA4s~WacQ-Qaai>yJZFf*YIO_`O;s=<4q;(;0}*K;>6l|0T|MLm$ahw?YscyYy$5@^7q^X&NZ0D z2XWGySg~Q|aewDAuz zM>zr2vz`y8`K5I)YZZSEavt}P{f@}ZK#?h(+BBFGNompyY|267fd7EpU zTj56*y&rR837-Et98!;SzRq02UGxtF%zD~Vb12dwI+uLUc778xTs(9VB@UjuEv0MJ8O%F~H3=0=o8 z9M7>7^;U-Mq%a^B&_kJ)8i?f=&uPv}8}`OzrJGFLK)0<@5&E#%{<@|ObT94y4tgq6 z;e2+ZIe_piaayN`Xw?6Hnw)>rdgj@~hfZ07>)uX%IvB36c#pAVfpN7UbX+EzjfU7w z>plcp9J#6+&6>aahjBF)h%1bu>=l)zmwCT$m}&M4w4oUZr6{wiGVdwZbnvJ!D|AH& za(+r3!Y;w_Pj8V-cl++B&eiXUW`3~!DsvDqMh*nKvo$v*cNu=8*MN7!mrqhRr=5a1 zf_Z7j?d(&qgLp6fNrwL7TcAh*0l2-nOtTNtD8Zg@yovd1E2hQ^e~tAUi>Y;dru?Vg zafun4?2MX=>gt%957hW`qxDi7AT-K@sHJHt|MVoHp#q(gBz)Dfxxedvum8Y5M*Y_2 zJr})C%8+kKbDt@l0wljyhjs}z$`B%5Pmd{M&fb{eOjTx`*F z9G*+s99e~yWKz|_!cRZAW9SRN(VxAICl%n;^eXp%KKI1#FOL$*D9ypwj_FD&|WWR{|&A$9Vte&o!O~B1MTTeEh=`bGnz+OuGk^dFt!0{ ze5m#N)LB)q0sco=D_M2h`Z4cK{zlq~&eKeJLyTo7a?t$5p|cmFRd|_(tfYUmJ+@8h`ohgAIc-+$`@gNnT1i-OIXF?OCBh6sa*`+RpoA2UsFI@Q2y z2&2zELeH?%Z_64iY~1aZ2S*ydzIrf{r4Em6Q{F`XLFo?6XyzJnn4id^qs4?uU07$W zQmmk7v*p1q&t7$WCQ_ljscz`mds4foc1$P-?(X< zp8OCB5ILLg!Rqyz7XXfws}p9a=xmbhf}7utG~CdJ%{`ID32q2Su}HY*GR*JIG#IA# zLnwsz7Ps!P6UI73;#A2)T6%oGJm2O$59_)(3C~5h3VwuaDphRcQT;V=d+@Js&C`L# z>(|Hq!}tWRnpb;HFAnGW(WLyve~QC|FZF%zL(0xwYW`3uq9iiu>7<|g_lmcZ?u;2R zla1x7+F;CUsZPn9B`<#Voc~<@XlYMNLuw9dt4=B;ZuqJ@ME){4RS_$r`WnaUF&o?b z29GXdDaKr`d_<$c44wdn^Pkvk`z(9-@q*ABF@JFNP1ITceNQgKW*Fi7xyvH^ixXs|ZR#7IAiiyWgkA!~@4C*@y@c^N2|3$4+Za#c zZR_KHI8x=LnaWQAFe*%C(^C5IPNiQCw?sh|jAHB+iHGs{8AZ11Tz!CCa8BNotgnE3 z?tVyw)s)Ir6<4$#-DOj*IRn;Ak!6sF{DQ- z*Ub6o7DrXJn(Q<$=#mI6w}5|L$s5}~^63Ae{k@%q45xWhp z`^#GNWlw_V7sfgfZdwpOE{2u3v?}}aD04*fe7gf=UGt&mUi1aDi17i39^YSmcJS6> za%-DzAm8X0V??wtQ2~nCd=6xW*BJX@N#$h&o`A|{h62kCh+1!cq;2{luaQBr=KaLO z09`8{rT26!+LqNhsIwHO$#N<5Q`-dh%m2bY`QO+m|L=Ruqd=;uTysJPn*;`cV*zh-$EUZ{0`LT=Vz3{OZfkt$7-Q8F^n+bA7OXUJt%1)$yi= z)=3q!?gaseK46F37>=H4Xd(bd&S_>fHTwCjGY}>uhphe6_*&j(!x^tPJ#rg9);QG^ zNBh@oVT`B1BpshPC6PR&^9_cw`kc#zstnOIcVk6p1G*8LVG*y<8ZxS^s8e||LFE=( zh?SU|qR?~YIFfhD(>skFC=RSfv*Oe=65(Zh)>nj9~t2pS@fYUZ`#gl{nR3u@fzad4OMmsqsX( zz12C788B79smErH>=)nuz$bWo&&a*0km-m(Uk_D&#A7Ye+qTE%C%P?@ORUB@n<6G| zd={4@+}^ov4l?{wCi>#sWvfIT{OAO&_o6Ie!JhOuO4e+i!6dJC%vvW9xAm;no%Zs}l_=I&Q_FB~ zok@e%(&&P=09HtY$Kbw^c6QPIwI349d(~cZ?MpqKoOS}K@VaEIax%yqPj+~Uq_4Ux zXYITbl4Hsg#=VXo|5TW(DUVTwUuCG-dRhfdYXw9fP14ptl}moZGOb!4>DQ!c#;$AQ zQvx_TiT0vD+(bLuHbY64+DdKDaeoFXQxmv$BQIYY_SYBJm(p9x*2@b!u%uKaK}1xj zNSZsbXwy>}1`x3aa+ zqV*SFh+a6m%UlZAt)R=I+Sa61(i75^4|N-JDZz*ZTonC_H+pGFH4*NHFm#07-2|h3 z>LxPR?{O>?QF0&j<$Q)*j{axhi%jM32*4hUM426tu1>lElri8p{4Q!&;b#zg&ZP=2 zOuM)`TwUQc7lv1$=|Tap>)VtEUD|<7+V*o}6R9L>V}Rir8O3ef3^F_L_4BGyG#=%E zRC61+1RgkES5K_Qpd;=%7dD1o)V%B#jc8~E<^VK-P7BjM#eg6j7+tE8C4b!)l91)7 z`Q;+=oheAqlj8kv)sg&n6PvUnIi&RBJ7d|zyUGlGx4>LCw1ST0WVL*W3Gg+V`PQ`_ zW1>kC*Ddbi9&G_a&IDwQ-HWELYG%dW3!WVhQ1=T)g*C)56&zQXn`b=&v{n6JCh!@T z%7zghJrcsv@ecJ00ExJciY?X+km}7PV~(_C{D*m)mfxQnTWPs%jgYiMpu_kaO$}8n z_M}Fo6CkW(hKGA6*`pEtNPjC5T<izg~_U&uM zP@kwu)C?fmU^dYo04^jEhGu!VJR_4OBzKctxi8=@cbkmkEU29K5=Hb!JMpI3S?nB> ztWY?Cw!ZX`QXNae+$V}`H&+xz(E(0gQ;(074^;JTy8$BL*1u@=EK@tYaP=LmCHHiB z`5=vlrhA78>Gmh#1N~PFDtafYPjGOh(9%-7k~jj>hAo`rWt64=v(l07bvt(KIYuG} z!J9w-le#RVE*;iDqx8ONeCDf?2}yIPe0j;Qy+cEfSQ%5%9ypC{QE?Br>`-u^yr+E3 zovOW|TwlRTOsA`bWp7reib|wx(bvJft#JyCeaFyerbK&@bYRl7~k3lVW)T`k63!KgJ_nkpw#5=J#VXX5l!(+vC5I~ zmipP4B&lfknq6wqhYi^A%Hf)@oywd!GL=Jk2DpR}d@oV_$!Gg&k3G%}UeMkWccSx? z@;L`D^}|`7%(U;i)nSam&&Nv6Z-CEB<5wL~kM8@O)yEqX)MxF6Ti2H}d$%pe!iExh zzt;w&XJ>Fy(ZRr&J(H*gGR3a1NePf zV0`tFm$rWuxCT^pP2o=sBAiPtjDJk3SEU&sZ<=vFtIz49#O3MQi*Y?rG|Vvj1E9VX zyt-JJdQ9B2NyRaH4TKSW!*$jBLL%pqd>eIM*mF%t%{l!1o8~9G7=x>VYLhVwn+jDw zIB3BKMyGS?4rGeKUAGmI^dV zl|)n`A6`<$2~O&*vP~O|n6@{^4HI(GD#sSo<{Bo93O4-Y#`IuSl@=4u3miT_P}aIv zzRJjAwq41(W)$?gSTeq=l<-&!=Vfc1J>l~h2`J6TR>kM|;?3g1?8FcrhRggs(oC4F zwZ0B|SiHhhReed9$34?pKQmIi7EsfYD8*N@x(pC=!vD)+#N5RHdOQ0<)*bV^;H>^% zDQyqd%vIHjk*h=6AGvVK@X_0!F|P(fvGUSN=*3HGSb>tMS=!!>8Q`Okf~qA7Xkr+7 z%Yo5{9ZkBZJoQPt)Xg;&D2?gE-S*ePx`7O{i6j*kf?rsY{X`fQ*RIX8S;GP}TLlD(Oqq`Zw950AbKk9hI zIL~0-643eriIgK#!5^%D-DUYJh}lIiXb~4(Sisn7HmEAs^zR8La}fYqaGF;Noi#>J z@WfbxkJNccpX%wne%O4Ugi=}Mfna+|TXD}w+~pQ5l)#z1jG%}KC+usN2Nm+O!FHM4 z7|T4s2|5It3)t37bze@c7#YdGE#T6cHg%_%yA(TaL)st!c-jSLyEe&Wl;&*`sIEN( zlv~*7L3}g5$va=Nj0`xVuu1$bE8QB?P>k9BPwo$q57(9T76ir}73DyB21yVb$~x+g zUkHDT0>{h5ZCgDI!rm>e3E!x3J|u@Qy_;t=?t%+*^V38El9F~?mPH#v%IBI((U>DP z8?Cbh7WOmZUE!O)+n-+6OUb+ZpHGCHl-zf0jgPe+BxCv8Zyl>BeT`1?LUoM+%Duh4C%Wpq z^8(|GXq^fyuEgG)k($uNBUhh!j$n zSsS17$8~^IDA?@EcP@H{$+7H>f~t6_YIMf_O3Ya-mk=4p7ad>J`Fem>ujelOpbm29 zO4Cm;pTj3RK!rEOJ=zOI$-6PNJsZg6?X|HR`MkhAEfc}Wr`8z9-W9@!zYB9tD4;qFCtCy8(l6yCxMH_U9w@`KXeHa z*o6z1qLtsFPtX0Lg-$)74RDE~POP0l}(%~g~PK%nmx=oj>Ei{)op-6 z`@B~!mp5&yrw2pFNTDSjFW^se;KITu0%NHbWwUW9aGAlf^` z02~fMhq;pu^O5fxuJS{H6R#A?7JE~Tf8YuD;W;nVWYyD-hiZStAl|&?D3kx+Zd!08-g3&{wSd#c-g=2y{J~P072OYis@wy`(DK zpL*j2`(~AoVbNSDGoY%uQwIcYL(#Qb$g+^A9TgF6GCGOunh5Mz0BeFL4-kQ^8{$kT ziZUD4L@4Tcs-6*WxPX$s0O{UrV4n2p6{Zx;+zn`phh6T*VpEpbJ49)UhZpQ@JL?{6 zaIPY_GQ!1_-&GUaP4)cUdU?UIRp%S5Ny1pkK3`}FitT=50O8#Bb_4Gu6(5Oj3?JEt z+s=*F^<6;?(IV9XNG7+7o%Ud#13J^DE^x}%plXYdU9$rg^5-tLIjx%plwDVfUi7V! z-iY{2D>F5vQQPcHUK@9z2qZK4OZgm)=uaM~HF8Yqj&=Zn8+KM$TaRfA<1~c? zy0`{bUn^*!)}mxc96Vj^uNl}*1ICMqS z5ZA&QQfILaA-}se?hOf$5}BF8G7&`lom<%>ePM?N^& zY}{U=@eQib?}DWV6o$!;@U*l*ZCjZB`tdjY7ushDKK+g<{W%*oB>wtS4Ssl}J@S-V z4owmT<5N|ew@VB+k#c8PZwY^Ivq_%or85NBln5oS2#vWxmArewBHNsPK@t$P+|4=K zPxc+-_4&mVl>M~yxUzEa_Ll?e!cVm&!|q66&t26{Tp4eg2TsmL%J4u->>2NJmUJt| z&r7Qy@z=wSX1Hxr{>p5@<#oUn?td6InSdaRSOq#%Ory?yzXW(vS}=$it)*?JBnkKE`dgfrf}wSg{T-3Xe606pV2EfB{L-5#aoV zxtKyP#-aR1hu`F0M}It5-W&Rw5E`e@99tA_xSj1w<8E;6<=NzFD&=|`w~xO>O3lpt zQdOF;Q6ljl`SvC|yv1A#*mLjCZ`e)1mwkq1LBekm?v>j)pda{=3QZD?qaH;LN zEc7F)ZL0tI;sEMDo@?b!GtN;C7MdSO)=BT3r5$-KzLemQ34@`BGK68+@x{W4OJDWa zd%wIS55u>`TxkRYJ1bpph*rulHG2M_K0DPrGTOIhI;12!*FFC{3q9ha#$X5$x^Hnu zKbTD>e7FipS3&1^mY=eeo>MMKhrfNn_Q3M9Dj@v+$3`k~k&46D+XAIQ)eSbvRD%UkLV0bv8DVb*Mo!AR& zlD+xlu3waPnkKX73nMs{g0M}=*j1pl|ALqh!DkvwJFx`7UQUO>GKlVB@noi$!!k;A zrbsN-Mj6-DAFVulc0FJ+^Q%+BHlMxTPCd^x`}JQ&^Y4mrNId)%)SLh5nmQDT7}Pl8iLp2f~H>W(%xD{d8T@XaZ~K zy=PI z=C?7t$8uX8tLev_M^nS|uj*tLX7dDGultE4eYY-)I|eUVthj@><)aw_72;F}s`y_S z4`({c*C)QuugNxaWwBz%oxhu{g{|~g(T169zZa1!1)+n0W~0d^t$t?Ys^5+zPcUxl zo&JHMjy~$iO}^`541LD8kLUWWZb6P_^xFCr)mdvG_-AtP%tb|{*Y3WA9>gZGB+PC5 zHcBcwlqZSE_dGZ*eL@PZ*Z)58Xr&c=A~@rzsp$-Qa5F_mmq;mqPg^%3VZwyC1H|?g zFabbW4r>vOl+LC&>noWJzT@o#Bo;fEF2N~Rug32DusxHtP!)VS-|Oqu4d`T0cE0lp z-I*r}cl9J7COdE~LF7YKuBr82oGo1)ZBesF9m-Jo6T+qf-#zfmHxiRB*qhOz_Od+h zE?4>*D-AYz&;v|vYyCtyfnSN_LP_tsy88`#oN9iY-rU$TurwqEJQKU5r9^#lTTwbs zy079hn9`5p|G2>XHq4e_{iwU<^lJajjkeE54rBi{qXX)(;FB zgEZ^Tbn<5EYzdQ2Tt?h372EevT}vGIWEO!7y}_G(eb+%e6F>YVWkVa9k=&On!2Wr5 zWxr-#=&C8=xqLV>c5kZ`@ocDli{crEuUq{dG%G%`-_nEYWNu7`nSpc(R^|{bz9go|D8^J?~r(S(=^L8OWPADaOx5w<&~+Cwh>wV79Gci zli!;3`5Uv{Y8m%*woCV0J;Hf^4-{5E0%x~slZ())-`A^`@FnW#>8%Mpke!vm_b&QKVc?ZnC*5BQD&c>QP}$6o@1q}i zRq#$;Tp(c$9fh;Bv0HWuG^)D^xdLN&*MFS72My^FUSV9(++CZknsVN0Ip?1562KbBhW%7~i_vE9%?g zCe%;W<9ifD<9I7Cqeo(`RAL(rooGRpcLo#)(2^*5 z6!Owv0Ub|tbJ*kgd+|mW&=ep;3-tbh$1)8Jyv6>)sBK1E z?~@*1*=`8KzVA=`FPVHHH8L~h%C6M^FqHhno*;s*!715EAA^`;Y8_=5<~leY6i~7; z9o)wMFhEUx=9sILD575;L^*cg5@Vj9&>dsAR*cKDrQsq9!Ju&FK*8{hn&^Vf>!3z~ zit6P5!`gX&v-$qGi>SSVs#;Z})Gpeh1QB}%EoyH?QMA+^sg;;fBlf6G zV#cbSP!TKdZ$AIP_lNKK{*ZHW&Yg4aocq46>%Q*S>-l^EP9tAR6NF~4A z<6Ro71!cGF^wRYF-7U`7bgeHOi|}gUvIPt}Ed`M$i%M&@GncX;)mq1&0dZT#({0+a zn11(69l{|9X()xI&CsNbb<0uTbhZr0F^peQ>mdFh3sJi4YKZ>2lY9Kc2q{BXNAan8 z`Um0@3bu?hbuzCW+=)iBrIpf|0aaFE)H?ML+Cq%P{)*>)GFziHM?yV=`kbeZ`lOlZ`5nmD89@%}VE>nUr(87;O8vv~Vogi{FkPyVAFw znfY`@=ADOqSG|+xn;%})Wa=^i(AaU0DA8k88r^179gq_u)jQeC+5$sY|1-6Go-pJs z=(fwi2u>-t`N8?1Htw%%M-+jVy}?l081Eh}pXBE2IzoBafpC}2)9z!PS9dU$@9GBq z3KaFS1D*L(q67lchF0Ofs_9Pl!qbWO*AJj`OxqPFyAj#o0GjL?Gzb1$p-(ISd%S)(!+{H z%854%uAw)_OD5VhakE`khOzHBR8xO!PZFg-8+aMGdF0@@0jzdCD@bgw^>dfh<2Amo zZRDUxu{QDQC2}&ERZTsf-sIQRt#}#EL;9@AONQGD%}wF5PiIE%w>~$p>3Ma)2zH~% zT04vaf^Z$Zs$4kUL|>3y->Y4g^P2QEJs6A45a^wg96zOL-vKi~05JLPO(5{v4~uo8 zxj}j#=@Amwn@SG4B1-oV{;&cOB!9Y?+`2*2YEOsclTtK}c! zxvm}5hXCL$@>%w&RzsUocEPZY&!rLjl0%F#<_|w>{!ZNZ^xn*z21Ct$J)%dqIv`Aa z5)M-3X_=KNP&I97?f6JdJ@>=xQHrDXjbE>Mf}N6%-(>P~keMh}#ao00--c7#->P;CNbd1!&)cjxho_g@%;nl>Yi7e3-1q#44Z3OgbcHCHhE2LW zw7e}Dh}a?930akA=Mwbjoy?X*c#$jU>dO(g5iafdgnL&H#nRw%$k&z0>VJQ0{+U#P z?6sy(>=#V6%5FB2#&J}y^81!CHu%>iK{&1v0}3+8Esg2kee^>Q5-7~qf6OluxG+q) zogTGqX)8U^u#Q(*jBLqIhi|o)-XHV z?-NCihlMS-|F5|~4+}s3zZ_R?=O^sT>lH z>58%jlfyJ_=8>|LP_)J&-|@nS*}nqL>Tc3gF=Jl@9cu@>!t-)xOOPcKnTX^uu!`^B zm*@gQas+aS5W+*hcXmDBBN@Cgid}Fg@yYw_T{}1B<_Bj9tH4Y5Mb{xsykgcdoX2y? zwhNPf$mELm7DXU&$L>D9g`edchGp22DVd8{@vsJ~+gNx@20So;hFaufb3fIsqf+O} z%5Cv>yR8LVa$AaLc@}$b?kdST7P|W=wDa+0!o}yYk>oF7jQFwI@=JAp@vF~Y#)Lk` zo}T&55N~3xQ#A*>?uS;m%P8fmI{}U6|-U1q#H46SkJe=!g`Ri zdkne~UzY{5fDsJ^Sja(gwNTtu{EM7jImWZ%YG`&S$V5Q(Jg+&F>CPj<3H%)bCu4wr!Q8xCUCuNy#|E z*%C=Txb=VN=5CUZxSc+!f64)Iyk7%t3neU`_Rdq_!ni`zD^>Z_+$CLj@qp<4X7cmA z;S8GCWNSk7p7I`($q6L=nfM=GA{MG@u-l!&f@W?<)ixtA z>q2ebJ!|;gZ}5e}T7r{Ge}$K;T|>i3$A(v~t8FD-B0f94TU$@}pF&~qt3a``xlA|7 zcX#9iDS-gxyFoL;+2v#x+*Q#P4?0YhCHi#y;OICxFNDoLLaVrheB_L`170xp`NP!^ z`9MKNJDYu~nXK#b{+z=U00v#uvJ96|HCXumlQ9N=C6NJtG^y>ytpTY6{D-*6c-0(y~KXP%?)@rF8mb#vbl){rYO55ect9B-y7&UJZnn*f6VRJ6;u+TVu|CVXg{IlSi`QeLOmxU&+9W^lkGt zja4#>dWAd~8hlz0l`M-eAhoaKXAp!pEv=}p$%41FB1%{DU_>#^PjsFbdT2Dc(Gn;A zM_tKA<}x8SgmFWZyL`W)oRsq^>VizsfmF%r3f#sIK|$5y5hrDweSBtU85=1 z;vfmjoX@(wDd3|p&==ZT-urrWNN&<^AGUfG`nlCr;hEKN>*0&cw4M1^Swoud zrrU2HD4EqDN>J76?33^6!_hN~A3{n2HUCi@jpPc}_AB(WjVV+;5|Wdb7H>PSS1wv= zHk6fK2;$YyJe}|GCP37#jL(qnYBTf4`2ZCPRLw?*p1rz2x@AuSSV|R+Hlrhd|jPmwh+5Il}^#Bk-eioAd94 za<(pbQ2x)m3RRGQVdP7A1}4CyF+=moV~UrLNg3X*1R1^E+~oSR&$hP(cs?vJvPrHT z+Q)r+Zk-gbx6?>!mwQ%~Yb7pGZXrSt-~Tz^(7Gyebi66@X3vx8rLyfhiGxbU+T~4?^dBvC@5`M^3dG7k?OgltSdlK_pTec+(>FFdTKYmh zxwj8W-~T@2c{4DOPLcLRvTri3n7gqzv9x$9^B0igi?QaN7gRoc(ho;9sQ%>SK--Pm z55cm?a#CnZ?X$&<3lQw}e-u*ssthHzy~$g>nXm(4cB=M((qF`7ON9cPP#3E_!vZxFNaynV74WAt!iOw;?SKF~c2Vf#{2i=Xk# zx~5Ta&~sZw_5O@YWwy!z6&{eHf6%6w1Fz=uNPb|r&jAxN{!#&>2f zsC~@0>y9xS5TaOb&ZES}VZTki_&b6A>}LF|1sP;5lfP=@bfTPcEP(9)sDmyGS~cem z&$kZzUjBxkoy>8Yamyr`<@$OD--lOv2BkjV`IS0g#@oY`oLedbNAnYtP3r5%vCTP~ z&e~tor2vi;S!l1D3wNbQtT*Z*5ZO|FhlV}dOn=Pz^q%E7|9=#k?U`Mqr6CqAr;Wt{T`2QVkWY9VQSuuC&hUK*UB^*daOnl62LqBwUrEV@?8 z!VRIfnC!o`HJtuV+0U2v5!b)9rNWu2+3p!ekbe#&qe{a|D7c`(y+`vV|D0624tRdd zWt0P+e;NX}vN^TdZ~60e2fZ66p|7tmMT}}3|EaUrs3PTm1Opsm`WsT;v_ijqA6@Y5 zRFF-rj4`_~zi`<1EerX6W`dE*4a^N(n*TkRU-@aN=C51mXU-1h%%JQa=|BAsMyDyw6f z*6%41YJ!$lcGA#qT!x_MjxF(qa!ax|o|QlTn2G>ykt@qUMJS2KxsgEzLZAPjsoru> zW$KNz0IfGCWyH5+mvKCo&cx6MkDM^h$v+{y_&^Zc#AMKdbt zksg65BH1v4+z)5gQC>qC`^$*59bG4^zVSu(YNKL}b@#;WhJlyVw^L#?bQx(Aa0cEB zzQXm5i_*ps`Uu_Br~=5nW;m^h7fPD@=i0Y4B|k#R(hylPRZ|-hh|rnvd+Kx~!1G+Z z_O)AL;2EYy`P)pxEYqb1j?8jmA^3IR5}!f;)Mywa4bpzPhGS*-8^bg8dOlAteK;bR zaWc6&874>KJR>~48h9j_6(&Jc0hre3_Zg9^VlV4H1{y!gL0eW`?#}wsK!5dne9v(A z{3xB@cwNpb&_ePHW(}g^o89}Si4KR zEF2}OUP%^*>61=iC-$yS@grH?Dvs7#^2fFy^zVEXmr+uPsx?ODT}=3+Ve7c)#k@h! zZF14Mx8oY|u39vl9Mw1}gjd-ZLG{-AR;h;o5lW^Bq8kGc*{n?9SE?4Ju?GN;-+4_U zqe$L>*4H>f%}kEaeoZ*g@ICs*6>3sIU64tts(607tzlKyk=>~DCLG9%4dGpV;bLZo z4(fLC&pP_sg6ho_FRg7K=e(nqGVutanC+F=wcjTo3^#}5bDkegTKk10MIKfN6AQ|A zkdF}!IJ;yv^b74tjJAq7sC70`lC!fjr)5dIvrpeC?k4!O6jB{o8lGgt((c7i{+` z=~G#leMeG*zKL~Hs(9#x8G7kIil-R{oqz?Iq`e|PX{H+rqoO%@^Kf6a8(~giAWTT^ zg;lTki^XQlOVeS!feIccAy8lHDi_6?xCTdX@!u*8-dQF*swfKJ78XDl;TAL`3vYJ}=O zK?lUIW8mF9*MImiG{{rQmi~a6wGcya?#HX0kXv%mYujQcFcY|Urp@dN%E!zEIV{K*y`3L|0{Lu2z`$g>@tbN59W0L z2_oxZW?w%oG6bF*kl;$@wJ=o+HCK*OaBgiLByp4A=$ooE`Mz_?0&7y(BG-ZU&FJ1nup#8f| zMpZ)`hrDvX4HT#rjE657er*A; z-TYlG5%Xl%u6{G3;!?GVBR{puCExH;$dBnN6N|PJ&%}-mq{=_(8fgC2ot`vTb7+pw zE9f4Jv}M7SCd&Lrao;MLZF{CAzcSEKJbl3XXWte)kGXE+3;mO5Z{Y!T^IIN{G#2zK zMALFj;YREjqYW8WSl?Ki>3RSBeij;P&iJB)jpEsL&i;oR}WCSFV z8!sCvbw?y^NvM{Ab(%vY_1|2Y7R6`7GuKm(-yfgVz6pz0y*?evcqxE;&ndBY0b!ft zeztiuX_{%#*tn3^m2RC<$@#lZbCdGTsWc% zD%zLPz%Aj2!ZBsmfj>+i_cxEO=oY_QZWj40qdB2^ml)q8&3g|$G&7(|H>mHaz*9 z0qyWO_j>%$2@FV#_(|TnD;E;ohxS$3kjFk7Q_w46Lpg`zIYg?@!h2`JN+~Xi>)Uvf zn}0rY{ZyC}Zxo3S&nWyk#Jk3JWVKrO3L^M^n?V?RfR_3M5FfZ*XtOL@5q?|9Q0klv z-st!^ZmUcFA(o!eP$a8l`?R*Pz0F9EjTanGIgOEO2vO%W_UGAUn^MZ{6o#X?v8$pswKY1WW3A|(qeU|AxJ$O! z@-M&LuPP(Z=l9au_M5%HW*dPNxqVcOdyw(YP5F2qZqcqVTA$XC7M{`?m#jNwVIT{a zF`3NF-s@`iIm^z^Jr2|6MZBc`F_YPaVbt5p*W}#W@VAnouLKLwtj0Er&t(+eb0(9M?)0=}IirsFG7s;v0x{lw~}=2G=rQIlPwkSfp&ZmF;M>vUpUoB)MG zn#Nk_M2D>Ag{~T*1XiN=&T-AT0er_0G0uFcX;0TSGx}*=N1CSMKZ**UcdY;~-G0=a zVHFxOx44UK4@$k7Ya=To!A#8UspBLjeJ&da39-NSI|=O6__|90V9l5Qb)B14<}jYa zrnD>ZW?xq(_8>&-sCU_Dmg!Y(OMQVJ(hZT4GW^s`XE5S1K**dY!yD@#+ZbZER+I5= z)jFBYVx-u5{;$lHfg)ry2Hqk0e zm-;-*13-0;KcU05^&@q*kW@dGuWwKYkzzp4&S$QNqtebo*)_aWf<++(#Sw`xsCrp( zkZM@4Q@Y{A9^7Cy#KA=z0!2cAlA-BJq^5eyblv(v67yl?2_0vr@ir1XER4BOfA0_`c~d9X$d5*AwUNLDV+MR{&NcMV z2YE*jb>Cezm)TeZE-}_G)Y^m;*@gimH*`vew6?MqquxLV>0g?C3B8AxNN6Kx4B1HU z`L`IvR%yz>Tik?oHk+F=sPVI&jDYp!TJGwsgq5bne6$7xW%vr-` zf>k};k$V;eWa)`L4Ul@57_!1@mgU%M8f>~#o&9a0B=f;ZR0 z$&pG>^*@*P7m6UWWhb0p23B9xBx-Cg$3OaKIO%9Y*;sW}_TVVFMI$QN`TcJ-^|%^+ z$R@zSacB9C*oWE%XQ0UsJ*dykS$A}Zx*t<7M)0@DzI}?liiaXMl`rg5&{8~>9QX`J z8~lLT1(a$=TQ$_yH8z1Z<4jYLrbpd!EOPISq*e{sR@VL?g|&;JW>?=}n9lgM-Tx?P zFGZ&9FCNWk<#KVD6_kBm-VC(Jv5u9PCaeXCse3nUHZR(tNJ8l=v*B${#a6rLn#++j zBDf)9HBe6`eWCtA<{gW70FD_2@cf_KNUgi`oeCB3Ookz1{BJn&E-?ZE7QZ^kE3&l` z-%l#`F4kv7{|L|%jAgnUPFVTwnL4#~4Hh6z@WT5igo^BhvQ0vjLxL;*{vp3vWNgaJ zXD-~ore!(EJeJFOV@KnzV0_YWLCGC)fJ%*1}@Wd74%?t zd@2p*GL}g|eMu7p{!%w3&shnoH}l&_dc4E&_GxJk%dC>aDb5w4)Ru#q$&;V|fCPPb z%A$zW;3$%ce0Ay_SNuKjn_4uI*Uk#6(}Y8opoL?hUDlQ*GbIdY^u5ogXAyi359hic zAZny;%kp-!{R4Ht|D%BWDvL|+ox35-)SM@6PxohalL1q10)xj=VFAmJ_t|R@So)+B zyK9&F^>_#dNLRf>5*)AgeTXqob5GVt4UaT4|Bu2nkTtFN%K?pblR`~2cC@j?Vn=S7 zY4*Yv)3YQT)oqPCnMq$gE_Ieee_^`O@fkVUw(vDh>t!m7S*F&4BI=sr^7Y2$Br@@s zv*4CRK;ik}tN*#rFRZ#d%|dyC%Nwa9sX1+`2Ol|NsIw%GBpDP2ZdO5Mh%oH#as>Jy z{T+9%Lg!!xIPsmdu_=adhccKS0=Q*%kYn2*%pkHA`Edcyb<{Tsug=BftNjPhS2@;U=hI{m7Tw`&8oR?VWZw}JM7*rCI_ zpcxMR>4Z?O%o*`(v-W46175c>FC2uQ7!GgLQKNiFGPuJ;;2p%NzQz>X5YA zr>)HlGOR}#^vKO+6B zF6Kp2X59l19{#j<#!qhZJ&EW(*GGJW3SlAi^f6gz?d~xin{A^+ExX&Je*)6j0I$bn zG^74qkS#fn6{MIk3pCrIcS8T5?e?kPkv+wiPE#jW&$?||BYHUOo&9vLiae_{8Lb5G zY2O#J(p|x@9ZRwuT__*&Kyas>Imsw%*N*7fSH!{7-WIp&Tb~=un&UX{P*b(Fgd1eh zBK6!7QkX!1Qon%W9iC`)yxPju;of{rKxwDiJqO}PB#RwwWt zjF$8rSoTI{22};)ZT?m|fgW37A{ZZLLo~-1tzIpoc-eRTgTRT!B{1wKLLLC**XByM zBDHrM3BQPY5pla>J>k>uT{T?#r8?2KJb>PK{3OvHWk-7efR#)^fI7#Tg&?zWL8f^P zmxFgSb^LO~*!K*tuYETam*~!CB^KeX-I1Up+F8Y8wIfNh6|OBGkqO)AsFY@VX~86R z;n*BOYR1(s(u~8u1x|R$AR-0gqpHwxvhbkGx)Q83iOu>95z%P``}fqRh*eDvfLYKt zEcxH3u?w4Nd@L7vpyfIS6vC2Gmokeqm<##eW_Gww+TIms2mFytoshZq zUi;|sb5!uOxPcncVu_(?x_;&A7KuUhjxv4iv(O>`YIi?FMf7@Qw+4UG!4-4m*joucE}Dj*0W>% zYj>|rqMR(qz}rlv>3J9ZRnpid7XG1?C|O$Iqi3wF)K>J%ci?2=1w3Vc^9DywzzuO)?TExY`?J?( z=(|!W9A(D=@+Wv|l^hu^ywM;;CJaEhV!{Q5A|jeTHJO5Hg-f#WHFo!)T2q(r#K)3r z8WJJhprU|_SB;ZyRyLEU^{-e}yL4K>_|uAEmS@a3e{+qR(9v__zy2KzKzi@Bi-P$y z8?!Dn(dr?@~VuAMO(U+Wnlpiw^Um{2|D?*8ISa!#~NMD2ZpJkKuWOv#rIOuXOZS zp2YZw(zEPVWiY_y!}`7_Z&QZzt(I>xaHAqL5PZKrXyuVuET9}XNGwpTGN5&(q`8>Jnhcw@HVkjco9zmw-zVoE z>4DaUVr@lTD+9&u2zu^_6@}!!{dnDhy_2%y-!d!KJ7RkBc&AMBaIBYW);dyarTcmq3Nx44p=b;bsYAT|^{c8HIxrmq1P?E#sPp zx%TS~3}>D?)tMYz)h_fnjGQuAC+(lj8s9CrB$=EjlXJY0K_c*O`f-@)3LAiUrZ)+TmH=_K7EWud0(fTplb$=T zC&slr>3+m@Put#x9tB#O#h%6rCZZJuW&qjT2JAZ7F?I@z*&6=o-(UmCixuiQNmP~sfg=Solzh<7-Zs%N9B$aHe*WfkBG zQ31K7E%&hcn`K%Vp6hRp)zLTd{sR|D%u*sKg8uF6I)>cL61>N)XOwQx6dy9>*PKvU zmtsQehtM225asxlAS8V9Z@I(9lyK27U(eR7-_ae`*Krn*NurI39>As?=q{BHu?0u6s!-jId7hsqDdMZJz`7 z#!*d(%%8Ys;J3TdFY*8u7m7A8H9h~1ug?k|ulqYU`u_+?w`1XTtIYz$625MXG%Y6i z+kYPedPZ0m-2V{&s;RCmT#X*{d`PGcvz>59B1<6j$cS0X&VSHz@bS5~mFtyxcjlTF z3kzXZ`ax{I0@a&0KO--5n-{1R)(XDdozDBd16!52SKO1ylI3MpFN$7P-+XRBld|0> zph(~|d$pNsDqlBgb9v!f>aB3BTTZ|X=XRUdzd^tG3rB|*_T3=3aZKH|3675VZ+iEK{P^#@YiqFxE!~zWdsO3s;Fj+DUVZ6-* zt#fi&r(JP43i$hYQj-VvA=b%$Ll4BH=PmNhdc=tJ8_!q8m9SuRP4SmzpL!y4*WawY zy8cQp?@RUg;g#J#x*#;xkK#6Di&w9B zIPcVZRzBSaahEq)^zIp0FmPlVHm5I;+wMzoX-2k$U5J_>47p_YL(!|+f16~TDZ|SW z5WQ-C8L$u%abe7Mpt|mLR(|XTjOsI6i`cb)PJMoCJxZtQU{N~z};+kAk$fK=vYMN zS&-anpUT4o=Cfws;J-EJqPvr`mr+H8>dIwsh;AcW@ibUudW(Ff;9R&R|I+onVfk!1 z%EV@cF&JAlglXuiz8pjjn4%@uW1XHoxbRJx=br5^^{ESE@=REP_RJVWmkq4iyk9!f zyJKBlVe_{AW1CdvBZ`bQfp5tkkCjnbRypTa;;T^)M9B1@Yua}S3Z`#x?H~7UJkqva z8gRQ@ia+1=l&wB2HO!Ax@;xMw!*ez?REICq0qbrFUZMsV&BnTkngam9?LhEC402s^ zr#(y*x%kgzHy+=t*IHPT+AE$Pv3U%5SdkPC*{)ahS)>YkyR}T-4|AenI;R zwE^oti(Y7Kh?s#lihfRUgf^ssyw+nU>UI{vR;ZyF?U*~D~argNe zA@4tm{X^8e>(TALEQ6NIewe_8gVeHnWBkZB*!&uKByINF_AAj$<9U9Rx-RisU@yc! zhdVKKyQwQ01-?qS?50XOvFg@tp7=L+63E}+`d%j%aQmI&fXQdV?x>Q}H&fk$3zwt7 zS`a95xmG(fnu7M>iE4pWfuG5yq0XX>k2~7BML_q(_NBb}-oMLN_c;<~X1p;)SkXM> z`xPk0KwBl~+$=LA6v;hZlRsoK$8t>|cW?f9Y|sy^h#3om1Qn)-frRo(FgkLIh6;(r zh$kDEKcV4`ko@JRxb-JmWKvFiR^Es7Yg+NQTrz<7Zm&D-Y6e4DW(>iy$Nn~1+jG8P z940g;sjv#+2+4k zJDcAS11r7bTDBQKykPU}TZ5w^XY^6APlzs{W<7`Z$rC>_H(+tHvUXU|(iP-*7l{E+ zo;SntNMR~)OzDZ2p1zaYtg%fWVH?2b95FaAS^Jwljb4D+d~YHocl2m^V6i@Q65%JE z@NZPqc;`dM6u3&3?gazLxs@@X=-61Y!JhM}_#c|l#+FTm4{2ewXFt}TLw={wbJm*Z zZ;voz+N&qf5=~!K09jjz)Z(JREG2SOX4;MkXGk ztzoy_V|TKPQM77i;=*)74AQ0_j8*y@SWe&-HlkKYu642w&K?RqZscX zPs5E440IVHI@Gt-sum@xXEY5110=*{Bm9F7THBi4=VCS=UmNt$dCy9<-RII$KB$)! z5)vd1Y`hpM%grpn1%s~KO)tbzi8Z<2f#k%y!M$-U$KR=@QMe~w%|NI7+muP8uDh0N z4RLzu9B83VY5tX83I|0chgQ~$*S5OlMbGmaf6+!+hwl*vp%l+tCi@obF+{HUR>tRj9=@&c4>w{Tc6T_nEmSqep{O= z(hJxI8Qy!=Ec$8=OH}~U+v*evAi^`MNf4s)NfH zf!2VavCPM>KhBv4Qc`cu%-n(B!Q?6>Ie zFQcol7c6571H$u83!WE^eIrSwf6Ud_uC&eYvNQ2?2ic|bdg67mY3MRLIrh5(w>A~1 zZc(hU1HH}VrY(vAr(i-o29h(^tgLT&PWr%+Ow?^0JM);lJhWR>Cs+A;J6;jo)46HUEp&S$MtWG%;D&0bCSHqvqM){%oFUGq&ZF3N6uD&g!^*I


-bty1`Hcv7;W?1##`3SJ+Na!S(dy#ag?n;Cw-_&2@~TF^M&6xQ z3fiqe#S2iL1WG_cR^xSmhF96|%0RztWHT{SmT%MS8I-M5I+N}n+$wpx`2*LOln1WS zkzJE*W5LTr@jgO~5;^VJdMCV747t2#V6OSx4b!s*%@YFQ6TNT6H$i}x)l}4S)HQb{ zSuVpV`p*m=s}v?Q^NiKN;VqDkoTD4cs^+KvE=M3yR;O8^P(#>IF)?na%R|#82T&b$ zu{-yZo>AL9sfOmcb)eCc@3g*^9Om6>#HT0X5VATfGGcY9o($q;p2_pQ%2PQ-3*dQk z`3nF`;zj$CC6ZDbe&s5zX?ULcO;Dzl+PshFRlFens%2DSY55SksVjZ)TQX9C&BVq$ z86vwVuo|h#Re-YPo^Ie~HNFFOdOKK-7_@4ER6NlB+>Q=aGQlMhPX8~7y-0m-^O@TEV#cq|sE?HP8JN2pY2 zyb2W;FNx5N)3RW+G-jqzH9a#A-*_UW@0ZETctX#6X^wBNsjnm!pqB2=&=+7i_o=kQ zMTahw?`c-gW^Tv(Tz@u_*JSn}RkEXNjcU)-| zToq2x;dHw7Ed?~8E747VcZY=*YPWjGzVKqkf2Jo_FVJV6-%RpF+Y3t!=yCVEm!3Hq zO1lzKN@KkeiRh@(%6a0kDQ>Z`7Oz$8UpB_L>mA_rh{0-`XEj{!VT7|y@t0o|*NWoM z5}(ypf2gVuqm5(RoUn$s|BeBgD{XA;tl`L<8*ODUQDBWg@E63xYvEdZ6f|+Uy{Vua zwcoAEY8;lt5-+Y(P{KJ(2*PV7iRJoyeT_QR|_vYPsL(7R3*P996#lbN?!?vVdMz~MNa#%bK@pa|_hFXboNbj1gz+!~hYM`RJ7*P>M5gN!O2&LB8oGvOia9!gt% zj3{dS2g-^oHJc`33SE{SPXEkRC;gskuoSsq{+2=(eSo^Xo3zraB8E&m-=!_m`Ptoo zYU3vRI3kvznk~O@**H?7YmqadMK#<>-^@>fy`$asInwCu(Z^RCY;*p?GZZWPs(cc$ zB*pE}2avt6>yM_Yg``1N?qHcuoLazt@F55WG5lzBbFA7wln<9!y8j9vx{2*W`DHDM z%mQ_M=BidFiW}p=Qk-FD)X_OF0mfoyw3y@kAR0)Q+9#{_oPgH8eC`=YUlf${s_1SO z4E+}zcvb94Yn`SjUN;8j`laYCQ@MdkVMn}gvWrZ~1E>V|&>|%fHcW`@28B-0qu0`Z=4_ZY4P)<3FDjL*lilF$`OqU6yA8&vEuM4;rm>4Fd*$ zhhP@F`;767vq37a_9awDVe$Y3UxB`)2Cd5ZszpZOf>SYt@D?P zuJ}~Abi#_6YIazWeBX!moI~CC=kaEl`$Ax$r7nvZtu$G=Pl(%gG)UXM&u&a8ZJf|$ zM_h|#U!>vr0nk7VYf2&;A7;b$I`;Q!3JCVZ(=f8#*h;9lF9s&Vdv|V!X(v&XjG!|uD2|@nAo3GJFHw^8w z9AoLTAVS6PM9(VOtZZ737ekB&BNsoDZ*+y<8q`vCnZ1gaS-!Em%u^*Z#uE^9+7ooQ z2qN==QzPI*xTc+qPA!^B=9^akYg)<&-lvbV_PTLPyQq!^G6=k~fO2FlzL%_FZ0dzNRIOE{y&%UEhG&in z^KkjjZdJ(Dd| z8p%}%SR}y?m*hsaRzk>xh*o`*F#S^XK!Hfj*JVGlbE=Y%ndcelZRN+ zK2TznTdhZxGrz0H!r4$ZKP#Z?_FB#zpS%65rpq1zo8rfG(iEP=&**=Ni`Hm8a>gPdC(&6S5ODpzr`CFDg{;Jk(?%tkh}Ib!+jsx7 z`M=-mt1TT=QG3^FjjFwAt9H?9%@nm~q-sTtloqv%q9|!=@0zhwn<_Db1R-{bEkYvw z-0%P4`~4x0M}A2jx$h*;>$=W4*E!dP#YZcD^vi8KC$7GU;ui1G&#LlTvj6yFv>p<# zd858#-?e#33S^YwD;ibU6+SQWnd*{0HIrpy6rv+(XPi)>R3bdl!Qr8L3toTQ(~hN) z)E3I(ByWM=(n-=H>4R6BK6EqF#h)0C&(-K~4&}3QI>mL8con}dLK2B*Qacglo|ar6 z#z`Sh_x2{&#$1uXu`%0e`c2ONIp(C0emne>dve|Wa#A&(KMKhls*=CSl~izIFL!CLC2IrrS z)dj1y&A4>>Xl^l$T#u@624vJ%6^1YB@4IztF@r+Y_re<%Nh|vmuBGX|ze8%p&jU3R9&PirLt%eJ!Ia*1C~WDRpUeuwdnx7zx=wPVV$B^fGnvfJ zJcI{Ly{?!!#*h5}EsZK1ZCjeMFEUkM%0F=yNzhyrg?uPNtDl|{EuWP#3nqp2YWu^zyGX!XIl8PbA zT1i|!nalhiZRV>Zj@m`-uL4aPNa6E@`(6RkE$T;-qHB`g!HHxXA?7rh^UC9JdbGTK zJnV{sg!HZXP=|e`*tWaHbHhJ6i}f>GG?U$Un8fAF1>K@q1D**!xs&L0F~tgStq7us zAnPn+r2+8`ZP<^)F4gu*z3vo_2Sh^DNTNon&m|G^RDa< zL#1KaVFrfzIwdc$+daMlb0ST1e|CmH{a2RA{{hj#y?2sW8G5mr1nXL0n<_?3h05Ti znYPL>Z5D?^qJm9vH#d3fN9DuKMyg%_BYuQ6I`0bLgUPzDPqHW5FEJ*-mK4U3wOS1; zEx`Kv5r2d6YFIg{>y-WGHg3(KQD~h``P&uhU5d&i<@p{ScFU%BQLc#e-(N;Ldq(>5 z)68%yn6x?kn)z~WZRAqiX~M0`Ww3h7B!B6+Y`3UTJqP{|{$V~l=nz}W?ggH`qiox% z^i`9ECkflzX@jyVB5B-@J&RK;I6TSjvK^K4|s z7Lbi6eN~xcOXxQ`wbLDMC9d$HmU^o)_v8DhxA*38efBjn7nsSir)u0t}HR z?0(WtHXRJ4!|G7k{i6J0p!aHkaeJ^wV4nl&PY@pmh{mGTa;q6RTOvI{w_I@?FKezp zAn4i1a3ZvCkzU}5yB=z}Y%I4_Ow@~R2(y@YJSMHRBp8yseSKhw<)zLl0_D4|dv)$F ztK7RcGS5iekH+Pd>+NH+>BBEKj{7L+hbCV(F7GH0@mkrLCpP7pXJ6%_6_Yw~dpNr9 z)4${oNGt25`j;$d3`oBwT2m3%>u4=K4=YT%H6Q?iXgg zlRrK?GcwemfaE%4Gx^P!YpDU96awZaJQ4-fNO})(|4>DIx$b?r33ZD|qj?V<&Pjsn zkusOgL0v5t)z!A105FMppch7WZ>%2T{db7oyY_yp$?hk&NC|BaGc>%vr$eZN^!^75 z4`bVWjpLS5#S-9{M^slOzy5H8InV<*lY;TN+`sN`*u>95 z-)!|@Gz$I~k!)RX6$S|socZDAa=0cQ)YW!J;Kfbr4ID$LUdY}W4nGyK=N4c2N>g&m z+h44;A#!JGEmisUz@b~B%L}Z$4r|Z1ly^EbE*@09U%1#q9LcLETmap{KkR!WIT#O? z)A!=^SxRvP=*i2!Zc9X6Xk3l>O?&BX1=wcw2*)xUtVY^ljM0>y%6qO(XxswTMX!rw zCGWU3J(z=MSv<$e<7l9G7!%ZSVri!p4=3q`(kWJ)tsKBy*Ii>>x-Q81Jgp%x z)cedQ$$^0Fl~AQ+2*ZXdUp3yIee107IQ=*;V(DDP;*P(uo%J$ECuN8Gx8h+cN-*B* zKX$QpnOpKHB{rtQfoJTA>JRt22|?MzMVWq*dk=kYJ?JJj(?94FjhQ`9gLH1RNN>gjGF*ags-0B{wiFd+T;2ZJLu-ZgYm6uyzJ&AX}*U1P-FWz zKK@27zQSTsAcLx@INECsI+zITGNktAWQ9f=xys6YMWfzPjLWQTw{Y~Ku)TH5{g|XS z9UzL)t83YQ(q&?|O+-|ft@PTTX8obLM|jz>KJy1!64|tNXmu7}phZfcDv-2;miU34 zPKJBx=0x6;aEZyNWvJ2i-u0Rl&xc=hh@T#Wa|eA%p)^%lF5AC5u71ard(sJE^02!a zZ#B`-8fLg`A9s5?;hLME3PQ7oZ zaJ7V7MS*0hgq*(anh@PLd~>DHi{ze;i_PPf-ETurFt)ApI;Gu$kx(aQy7WTMp1GT4 zjN+=UC8%PUcW==~1|MIW=}jB;{RIw;fm=Ix_WH{5iK~Ler5jDcM^$-R(b=XwBrg67 zRr$W9Hh+36AiqU=(5)D zliA9nZe#GrOs7Z1m)(=oJ|88e;opM?tLy?!+3f*%+6G&-9vjX0kbJ1c#8Z9Ix)_^J z@$sJu;S8TPhOf>x-JlEiH654d_NwNox8I98FOt6Mk=ob}FsNRi$-qW)amIJm9yc5vj&504W5zyc-_#=*<}~ zLnX-ky@58CL_{~Xnq=fJ3TgDT1QF!z6*%{WmQR#CRu^9fW?uX{u3hM9f1^!1cp2Iz zRG<`7p)iyyB2RcW{j@&PkNan1zyhDW)Q!ivS0DK0iQ}R}HO`UMoiO5VG@$MLDKzOs zR@h#!MMm%SB4iiOvyx;k487Jd!<_Ix3m8;rmwr0#52T7H;f)xCEb0-B`}DgatC4pS z4Xwipo7hS!j2_eUk9f9es?6`xcA?1HI(wExsa0S~c)`ch@JWBcOJynl)h<7!E|~+% zeVCG6{vCQ~Ns@89{F%LjADC}^Fj9}!pQP&$iq_~npM3Z)P4Jr4U7j-MPc%iaE z%buu&ZDagL!w26>J#QTWwv)*@T6L5^unMZQ7=K9al*5J}RfZH%P6BW}39`*D0XEa( zuWFvTld2_(kv#RKd~@SYmda3B$?mH(<=nLKiNzb`fQ8Jd*ol1Xs@-{dW!rX%6uI#< zliu)f+9w2UYjYqNb?e!ahdQ^OUig3bpbIK+XJ_$HtP=g@{xo9sXfb5W{za(Bo@h+) zUU|3dP`-!R(7iOzom~%Zxtge}!YPCD7C5WI*|g)g$sjm?D1fD>*5F~}>%fzZ^$NF? z22ea8m`*2FhzoItc8{{`_@NQu_aA93fuWyt`yQQDq952LxQ1(NU1J3_qdoY=S3kep z;pF>*+RDa%p8A|ReYWvr1p!KF_*@=Be1q&@TqO*UXZz$PDiz&r7F-kiI62B0AKgtC z&a+J6L&*)V{~1vvJJz?QSxUT^>e5$l5(?W0{X_Xi8A^VJfx8jGspt8q`TEmvJDFBG zPL%iZajE~N6gYFZ$+SKf8=Bawyw&=eQnUMFOCfmS9uW9oUwZAJ&G!6J5n1|-F?UUe zTIZJ8y1w~!d14{e+9||6-EsD|TgZ;spTXs%nNojTon8khc_A2zr4t$+d3YN0B;cg% zD<)Y1UJN6_x+`PuDsW@ZsK~{cY>8yqWz&>n&eX@RqV{?#(m|`@ej}>yR2|DbO_9%< zZU?sfNeErLBtHlLvi>!%?QD`&3(iP{WUjypf?L}N>pRQbfq(|V{po6u%{gvQk=k&> z&N85S&aM^h(otL2nn4aAL>RdX9?%>tJxmABbapP&WyAaYY{U}RQw3S4ioYa1_EG$; zSnALmX7VP?OZ@6m(uhA)eXsz#YSfl2L6@h>lccg~GF1iMRk$kL&`9QCNc?#kZTyuc z+-Y!dkm4nxBaSe@4Er}WhAAAKp4uxI_$|y&n=}%tk0`MU^Y?5OH#rH^A>I|owFRyF znztPT4@p7mag$^Ir#=*ZRqdj->Yz7*M&E;e(wZ~=?Ek8CA<6WlUB}r2?(~mFpX`P~ zP9joP2>)n6ee<(azUF=fFWbrOo%(sjg%R8kSyBv@zWhvhyk^KbsSFqm9}J7ffyKST z&#=appmy-2Xu)_S`53W&mW4i%wRs{OyP(3JFLYCH*|OR{s;*(8DqAh8uI>3Do7sqY zjp!&NP2l{~k@se^L?acJfp?rlwlrVbnUt6mhu0Ai7o znoXR-o7R(zTy!Rd>hgPc!CniXSmZ2U?9J5z1``YTgUKG0o18LDFXx5MODkY8npbW= zEABL&mLmiI0QpJF9TN7vHc_)R6Ov+ed0i4$7&C8`J$$omG$4DSn`z>cOs`pnG(iLD zRGSix^5F`LDj31F3sN^$Law10M!xU1^B2XtOb4x^*ZhM&hwW}r`2i!K=vZRw)~nMb z%>LKM+rQZQk4G*WxB>MZv3cU#%R1y~A+q+>=i#*n@9Be8B)KOV%qMPxhSBBVb=!GW zJs+woPAcAsW5e&0%BD?+NF=!narRO*sy%+#gX>S3B{U`Ib!y-%#gvGdyx@wJzv69Q zani<+j@DU1Sw{~-K@$YXbASm%tg$7FE9?*30t^l&=I+btk-PGq=Oy>Qd>d3A*z!1A zFHWeoy@vd_wZ|1ZGTZ(oG#{$W`>^CV2O@jtm{Il@%-ulZJbS*mvD^PHMF{@cc~9J! z71sD8*>EJwW9^A6*#))p+kx@7eeM1PuYTp)F1tu00%vOc)~oS+*rf~%o`!Ahi0muA zmpAqeQHkd~Hm=*F>Lsq@1IwDnA{7>^#`F^E5JSzGL97SKLm zO1PnC*DL^_xGZ+1Q}ySsjSCmr7iJ6Utwv_-G`{uUW;U5fw$I6%%EB9kWxs=m=Y=o8 zJrA}~I|M{(XdCRR{SFadn}65vtCJLO+lj5h6c**D>SGpZhFeFXV0o*%mq0UiVGZ{x z5|4lP2_xc%-A@Q3tCxc%b+2$}Fd7ba)Q}m|$Qz=EKdfQ?XHP zlq3}MJVs0xl07!+>kiT6t19BvsI$|c|6SvU81+rGmP0*CtA(tKLis1c`&r#g$3-XG z?l#lr34&G(TwjH5DBZgd*vBS$qOm3Sw2q2ugSO4M&L-!H&LyVgF@R^h4()keoo)F> zxLYCjKo+#hITxc765569oyj@0Tl5LjBV%wT-XVSUr+Zau%;=0D$ z5PUJaB_BsyOZ37T`{8%RgEnFPR3RGuOUbJ!R%BZttl_i}XRNg0RY?ID@$Nri1NBpq zJ`g@UH>mxWo*QfHCEtUD=n*prSSpJUj&6LJ1KPZ>)H))HF8`KdpcsH2Xc&$iB=CTq_u1jM!VZs_CZxu0WZ8=_K2X^fZT!%fD6CvU$dH-nZZ+n^PKa7D1eyg=HlYLDLSNr4fYvX z5$*?B0Syv!;cfnZQot&wjNV6@KXQYJ(%VCTaMRxVlsdHrK4_uj$e>J`cgJ(Q0w8R; z0X!KU-Ur(Uu7}r7IaDB-`Ody5Lo@~)5Z1Clo^Nj{#QJ<}^#J-Xx@pMP!0gW&YH#b5 zWZN#I?dj92lvDdZdYFseQLWAM2|<`J3C3;YhGtL}``K`w-7dVyFWK~MYksh*cHu~V z;ZTUj>x7>GEN}Tr*V^ia?|{%ksrBXwS4_^zLwV|BR}b}isnu_P`*~@0Jn#06zd?Gn zOA?A<2cp-8k;WmJPE+|UZH?Lb-ml1)#F^OUKDRil@V!Ebv}Pml{7hDV&%{LlI>CrT^^ksPneWpa~UOKyZp|kAF zxz3%PZF<*nc zd2y)y9nZRtU$3!;VQ!iGxaaQPSkS>%n8H|DV&C`z8o62w&zvuf!Cx;o4(gHBOe<2% z1*@1x54(Cr#?aj4pbTdWQhZHXVHQxfeM=~LzSMq>((J86? z+LoUa+fMKPT8!U3X+*d_ZgmytM<`!MC=cuc7QeZk7}V1Y9I)SN6W1$5!!YDZJH-Br z{=(eMAjB{AW<7ZSDe9dhG-I&qRjwJqh`yr6| zZXj7TLhde|hb@KatKVieWByGmd6ih*T8KwjIbxqk#*a!pKSmE!+(T3 zJtnKcLil0DCNRTM7*hi}O_+_#ewOuS_c}-}_S!(Vgal*9RSue?lZqH4=n=l+o(?JJ z(oOZBUnnPTd%d^TRYcgKvsJ@LTWW~ba8t8_TL46t8j?Eao?O&s&Uh$URev$ zuq_BlP-;>s8<*uPGS^snXW>t0vCKNJDR(24wX%SeW7#-yY^?Oy3o%~6JS-1$v*vXW zkWl+n3>iWQ-@NP&jp=1#&?1{m+h%OpPE}He%5>2YFZu>9n4i*c2bQH?6)WlWBU)ZG z9uvvKJSi+z|R#TaO-c=d6(Oov+xD(#+fw}bZFmFZ0M8h;lzQgoDFl1~BW*>xq zIT~Brrg-L3!FAqO`f9Y^%vwI#b6d7gX8O;A<{Qc@`xfeqLFG`!XRXuq=eiU6Q*D}^ zY}|=RkH9p46QS72Xz}Yl1E&vBHh)F~l;uM}|kIJtd zz*p(#S1^P9_OpYj;%26Qd*FZ&(PoY){`i1OI`+8 zy90$}`M*Iem&_7V=S^=yBsu;Q`UAhsa`5%S%k-5`?j5wXTtOeJTyt!2=hcP6X4<@n zbg>sd@XejxM&QN8?sGIthgvCt^=(8A`);l~> z==9J|RSb?&ewMu^rOxE?Jydj30mkIPCtKGsRgffoZK2<@W>YDdGjW&AT9~F;-!Qo1;02mEh}qt@kO5kd9Nb1Wrrg+6CpVkVb#veR%ncP&K;@Uhxw}gdN`y-*P12hGivow1zlP)em#Q3y~GRY*J7)e z(&}zeNd6d*Tpynkrg+p(^uh^qW~*q|mOiR!T$PlSRn2}&zXOEoYDgQ_?6G$beA*fd(*yk%jXGG}b*ZT?P$T(kjB&R|t1?IiL1YjLyTY+b4(7@j=sV7eo z!TE>MY-r_W2FO8;%GZ1-78;|O-HSIr}N?<=j5ee{UNvBc&`084bDsQRTo{Nqp8XR!A^x>kUv+A5`qA&%xd zz^2DOqo|Xde9t4QNz2;%xoagIFk;xrZ2jQT@khdZ&4)_m^c>F9|73Q&N=a&ac&(eE zm-gAd=i5*WVLbK=FvrcB4dQr5W_i!htvVZ-I8j-BL4y@&)~L7D4DE#|1F|91>jmlR z5(C{YMNLWI2b$c;Clrb6SA^|L7-<}gq&`S}WAp6G)6l|qr_B#^y)qg|KdE%UXU~CM zA!YWrXd=9V0$^o5*~zm*O7jh)xrD|(F6pVZLaL$ zh`GJU8A>jQ{Gj_hzQv6DL__pYZxA)t=ZWjmV&B3s9%*s>wb4mToKGjli$;|W`k`jO zx4PI4Tr545{mOHnXT|d2lJrL|#`j1!qjr`a*mX;*mg$|UYI)OJ2Cs=`5Adw-uFN|A z+3yy8*}vv3IU{~$SZA3r;_do7m}|Rq&s#(!b&$59tcPePOr1`oY=|_->Uj~(-{?Nd zQtzWl04smfMMgrTJ49as5MXbhDr47-`uTr5*Auyn*vuy!^c@+3Txd|~_c4kCpbPWo zUWp_LJbDjK5orwtoG`8+iJ8&6l8h9iaO`=N@GLcI^i^0?~kJ}lC?-_ zwl(A4deLpBVeHXW3K;=p+qMCuhnIVeK!AZzf7a(aziCEv0+F=d+u_PyS~nGP;*syE z4DD?bjuT+{dCz(8qm{!pM?Dx*MA=@|EKaw%d%o zzCF~;K6!**H}u+QXf4sc9%43@p30NutobV7=?kAZ<%(*$mn5YnQvwS_j3TmdZ?a9$ zp_M9@#~wqLGfxYv`A1_`2Tx;e?3)XIK>8~oy;xQFV-vXt?6rbz-O(Me=v~2|0F^2{ z8M;+hH>4kU|3Fk(&CR>))e6tFC0QUeq?N=}4UIdHX7V_b6f;WQQIjC>9&;#Qo6@7& z^MhUNc(QCiM07>w2kPDWwFWqP-}we#PWp&2TAqG)N{)&Ar3&C7dTIP_C|+MAHEXxp z08s0PZ)#p4p~w%EqBVt}HW2ogqz(ho81o$K7DSo}^m|jDtINmtYER5BNd7A2To<5pj}K?MtrVbvzIi^Iq^|9{$Pjk%#N>AI;^> zXI>pLa#?a^1Ijy8HS)5?|2K9vr5=qo>)|5z}}tMnn9aVxL|-hFOC?nYuT zN{InlLPquE(AO||xy9b=Ri|8r4- zBs9L2Pq9s`8Ge1k=1$zZ@r$WtAO(0n)IgYY?DZYwZj<+&+iTN-ExzQpB;=kR=D+LK z@Cf?KE;-+tSanALbAVKB@G0%b#Cijl!e zq97Ur0iIFXF3)KgD-6t!up`BHF0gcj`4QN;j`Jo8x}}=urhS7e8=nh)Y}tJ!lKL>U zb&v;^tZoppWS`tJQteRHU*V|=`6$-bh|Z4`G1@d+&ApeQAjNUxm-18V;Qrfb%cw|& z-53~$!nt%0Mk+ZbprKhwN!2AK0c#!nS4!0s8X%)zS@pvBiAxMc^p?I(pQ zIl&h7k6+2x?|$nfRF00+y_7c(^zZqCQY+ zNuO_aM&@a8l16CdC%H!>(znyN3%*Q*WKW@8lC1mpYzT>Vog3 z8AxNiixKYlOhRmn`Mhj>s}(KB%mdbetvuR2aLliHZoAt3X)MJf1UiZ%fyiu7WZf&; zSE6JG%@L1N3bP%B8T)GKVz2K$fZ3xLgYY8X?M*ph@gbq_;(AgN#zSjGE z{jBXY&u!lca_b79I!O-yZ=8CMVl@@2o$qOXjlx^>mybE7_tOSZ^>3$+9RZB2ElhZd91+9*ZG1JEt;?xcCqXWPMl82$&VaQL!o_jHK=%VXnr zDk_y;kmx`ha|aW2XZKh5MRb6XH0>4)<3~zeH+vr9lCNJY%yww~eP)>4m|^gP&b5DJ zk~9CY1)e$!=LAzVLv_YNpGwzr6HK3uO5LbD&&)>^i!{tgcU)E9Q=pk(TffMg*`W$Zu@L&hDALGvm(B{lmpfMhh@FNzb1SQaERH@>7z1| zE-c%!Ki*G@&xiUv2}9~OgJ6xG0D1TfEH-=6GlF%}!8J@fE+!fCMTD<0CU)FGP((3$ zv7st>X&zXY-gyoqv8cS%9uOFww+^|l9f&3(PWkL6ZTkb~-uDK;xQ`hxL2-*Q9~7zq z|Ce4H-Rc66H5B#&Nga;FX#=s?^9!zrLPHwZItiDLqB5zn;?te>Q7x!G##uyfBXTc$ z<84q(+dYW7@p(jz=www@CE;l>_I}k*S*^@9h&YFngZeZa%8bYM@NuI3Z6SS13;bi- zm11alGUIKpR{VWO$%{OA^iW7))C0k=WX#yDbxYnfhKrpdq$&ZZ;3uqG zs8coQ09c*=fw4$y?Lba`!0R&gdiQC1Q&z|#j=)}oS`72+w7=z}{=6Eh^|YaZic)+d zHARfksDJ;PEQaA9id2j(Oe9tr5}rk5uZCV&s=h*+z`NGv_cO-(2ux*!Xwmgv#1#HP zj2o6ZA`%6eJ`N~<`p%(o;|`KWIi8VbzQ%nhy8NLnqfRYBF3j{Dz-OL{KQ?n_6CqC?F~AD_`?IovDoHi4Ip3^YzZ zoZL=-C{W^hkn7CQ>capDrQ6r3?qrO6i;4{OT7=L-Bc+}{<>D(-nEfE@e$aQ&HOz1T zA{1Fz9{zBOQxlKdw&5yV;HoHCQe`*R!1rC|PY94gWog8DJiB09b^1 z!aIFdHl9n25nu5Q6#H*bFFdkqtZIWDd9%%EpKHRU|KqnwA+Mh3-x3hqLU1fM(|-o5 z-#mnWSDRm?&EKQVsiue|+kr3k=UoLB96uxxmzRhIm$%>Kp1Y|!9aM7EA??u2o zN!^_t{QqcDa>(ADL=8oB*gu;6&8S3T57pAbFLy5Gr9XhWiZzlFGN$vS_f2Y+;sxX{ zhIsi3TPmsE9!eIyv+BsKm@N4dF;MVM&!(Fc4>X4B6j3GkUMvg@n0IO&gk_TLf0Nzj zY{``BwB6l4tr(x+VHsW=@DbdSnL{BYDb403#>)`Io=)ZYZma^F@G%DC@KLz8E!NiX zROUWMf=t-_RgThd_Pp?A_=NE*y6AZD3tkh(|f}+h7oQImEr%{97FK{?G8W`+`}o9II?=^=@4l zb#LK+ujP*XKx}EOtAHvk<&`cP)Z5aYg28B(3JDP9ivENQ9`FmakLK5iJLa0375gNMM0ubG$0tjquUSHtWLksfR=f-s_EPyu!7 zRi!_(?At2EFW-4B@`$xEv(#l^}-yM-xZo zpuCL1C&vg*sEd^T%|uMMxKDU5ky$gdos+D-A=2I!7}nN`|5SeYYCqf3a_$Nw)Ksh& zMzfV2lc0IqD@b)MVg>eUQ#Eq#FFz*FKgTEV&mS|~kdB^O%HZUWIBBU>y_qMt7hPTijXTvu z1(Y>SN$$w8oK~iP(j5Dw;-V}NuxW8b0D;i;gAM#7J@7GfaSCM7I>~M9q142kch~my z50>0NUjtD8)vX)*i4~Vnva)`-t4jT&iLTm#DD3|9yuW)O+0iYGbnl8pw$XX+cvox4 zWW!<k=-4e zo4vj)-ehg?)_mfLoZ}DTT=caJm^Z z)4jAwF=ZqngSMLS04V@t&c`kk&yMa`(^v}){rC3Hsy?xh?#IgXS-7n#%kUdxiO1s# z$oliti5>*Zc`SPkc3U`Yu=%A=%AO|3AtgiW{;*yp)J`hIV(MO~NHH|}@HrYz0KZ;^nUJ*#6R7||fKoW54?tdRE%>JLYKp7)!G&r{15 z7;25c7kdyB*e%siaG4HG#u(cp4vo45{L^nKtvk8v7c0#=HiC?~hF)QI8p=o$-QleD z^?TD%JCemM6FXJZ*-PBB&zMc`m;X-HPy9r8;iEDSI{AaT241W7FOrqeCbF~zsFyt6 zeyEwp&h@f*{4`RWV!G}m@Fvbj2>b34rHxWlcPvd$a(gir>QL&g3QO{lKbP3HpFMg0 zkfqygO>tIpZbPwXjs7-9*Oa!E@oM-mWM8Pig%wak5x7qJHM!cFnNbDCp`UOVovVD# zmWKjNHo;`kgPcHXJ^uT>?Be|jdubN?Zk)1u`nzhEv>mwg91axAB%bg z#lKGDHU|mO5ITjKi_&)!^AJ~c6=oGJ_;HMse2Zl2A-sI2u)k3b< zE?-pe>gE&N8-U&Nl%ps&Px%*3R^F?8t6JeTTk-^{GZ!PNX_&Z4jQ z8_CIFKdiq;N~trusBSNYY+K*tf3EieWc2SqF^Ng4CNc7)@hQaIj+c5s?s)-NF`xI(pF|Nn>AQP|;L5Y>P^3c1Y)bizN( z;xupkqZz!thd7TQXdM|od%12iLz>3t&hNnY{d%72G^wC{oD*5KnTLfgB(*=>+hVahpopq|3L8Lm-o(786?`ZC`)``!PaV^pEsFyVc4;aIx-59(SG! z`-!yg6@M)WAKi_RvoMbq(Hyqoz#)xE3*X!99z1Tvuhig>O3Ri+!Il)qwBf{;AJTm0 zm(_U!hb6?s4F0xSQ$tvsu|-4zWZE&z=J(pTf9hsnJN|mQ3f-k^#g{w$kZzXRua&iap1*n!xa?-16BM2+^VIwef;#}@Q8ce`*m(ZC zVXCFF{@zS~P!YDOka3X9(7{?+`Au^lW6e=9&f5O3jh`3GJ#x@jko@ektpD7&^|bs0 z`o#YSPEyf0m&3Ls#nUF-#MkAd=Hks1?2vH0a4py4oVKy!yb0|)8TJ$?=NO0&F7UYofA*~0~)%L%B-&JX(ia@s3 zr>Pv7PrmjCvJhl#dbM_nQsjD^6K5}$5O?D;hBZ-mjtul)ncBrGKF-`X9Xc!p)-Qfn z*?i_1k9eB-%b|zyHZPqEavH(*0n~ zC)99K`pW6GQ=hlh8opbG3AbLA9(kQ@7Jqsk_w4DW!&%{vZZ)GzmJ&|#$war@*CX#1 zos+KexbbckPKPo&Xr>};*ooVN?c^8uCmgjru#7p08$UFy_&-IY?dBb`np@tv)9O|2S^=;u z?D!|Ar$5rRNYLznwFt$e={ zOB%RkDjTTZi><0dz;UjJx1+s`%;D;87!$ZcfZKbiuYxv(FX;U~n-TJg;}u-a_@eo|&2(qz{wcuOJ2BK_DtBXeuw zZ0^s`rbyh#A%Qy9A*%n62Ks!+Z;Z5+Y}o7ub}6*eA)X^%zr+GSluoAfMWrW4+|ep@ zNg-39O?&ffukV-cf5SEl+J4N9rdxVa*GA^gA(yxuI>}J?gS=7ujJmvuU=b9%TlI^) z5nK#R&Z0RZ=h%{3;R%h`HUh0iFk>bLY7MwdHFBj*6(DEKw^7NCz8x!zPM3nYlamuvsaPgo+z@5A`B_R7s!soGF)OEf`G*Ft?elPAxQP!H% z!fH4ITl#k)|AOGme*g1T7o495(u- z&~7Ac2m4$B7MGHutF}gUf;CoWn%+Her60}rxxw+DH7Mc0lw%q0X>znx<@GnC{n*GS zC;Deu^%Mk0L2%PnoK13t=fXmWVVeDa4nTvrmEF^vh(krI8^v+u9+fX=HW7io28|13 zx4fK(xSy-ReY%W=MnQmt4cP#s{Cu+s4$&H0K3||vkhf1Z(~e7E^)UQ%qUmkic~I`U z_xbJ<@cj7#>A31+uL8oWQZnxZ8`4Tuo0}3o3vJcdv6^&6jD_m0Z7MMvu+|lPdIES1 z(eNxrjMZTqbizXT3U5ub$nTb*UXSa~JmbE*^7TfLkJb~5BxI0g1U@AQtod2=4zEdW zbfo6Bn-@6fXwr^{U9cWX?Ac+%lfFBVD9BgryV<5C=-=R@l0vsDBeofcsZ$L#?9`Dc zo3B~8%`p`zJ7;$%1F$j~KMltgd*ngVASryf`>P$Vl)|?8{Km6N?2U^&GasQPaz$K| z2U9OdM9)0~2>u-yJC_7_=%Aw#QPjK)vp-#>c3fHwtA#BI@w)-rnFEI`ny#q&?PZv0 zrd9}lv?s55HIN93YE88#We)6Lu`wRH=yTeY0G#T+=nQ389oz52fWp2L=@k~F51L26 zBj%VjjHTnGp)qKBw-z^vB;B5S=pe2E%Yhov<%kRcdTPL%FbT4@bwXJFllO$*KC-poXq<`~!j4q`#6W&9~kbw>q)@Gp*&sh)*>7&}hm>vZ`8havyNm{xT3njF>#( z_dk0T7u9Grqb<_DoVCL`j%T$nmGb)~HTM37SJ+V^ZxwZp-;^oX-kmx`2A!j%i*u8Y zbNi{H!l@+>cs!UOk@n3LM@vx`<9$$R8N>@ z+kaUWcIs83N1Ri# z7wE5?`e8oUlk}u3-A3TB4ko1x*xUFfriOn0`$vRc`-vlvJ?CG`36YW9ACJGu`&d@>Kcar)Ox@iC3fwt-zmPhDNah9 z19MlPmHdJuz@IZBNiNA$sOD_nypk>>baxIenBLZ`wOXtpGxru<^Vz$QH)EkSu!V3a zWvI9YVpDLo6?bhwGwf+T-0`#~+YggVV1#+~J-v~o$%Wq74o#`f`Zofr?U)0D-Nv2+W;Jmdl{*0++t zg1T4wnV#Nymz&H(UaR8LG+BU8Q)GT@`!4|FWfV}Ft|VoiBLN_;n0P`F_Jw)C+|F~h z;WIgOIY4ovVv&LKxE5@}p{?!7`y(xS%C-IJk4_|5nWr5P9*ww>wFtlEnLXOjHfC|R zFyjHymlt8I&~geERWDgk!eE=KwMg+LTXlbljeG*3^X?f>H}{H!&i?>zZcmCC-klqW zRMPh0JYi*4ZAMb(7&q_aFZ;PJIo9ByftBH0B8@@ zE9CM?E{hkJAdww{q*%P^1z4B)BH{5INzG_dtC8A$o?NYd-It+1ol|yr^)Y9o>_>Ru zb!SJ!KN=^A7kldAGNhbxiqr)44pi?~hQ*%eQ+rQeo6bVh5Y=vo+T*`#%WAF(0*PH& z7juD%ng_tHomAGn-490+?brLX_EJ1E5ABKyfn6`>VIbo^#kh8sGA-hAxO~3G{)M{b zJY`BMKrWfV{`3QP6-Pv#%TNcX!w0b46HMqXi5B&CI>0xtlq^6Uyv?$>i=onj1a=$#kJF_%uhu*|1x7JjrCe7qw%@?V@2$`XE-^ zt>{OOPRFppCG-V}RV5(0IF?D>>R!_%J_%C!J|DR=T$2=0v;YlU?;V@_i&@BZV3^9v z5C&Z=>0aqemNx=(h{x9Jf8%YC#IebdVBSAOuq0J-?m*%--(J&R%3Dxk=8P%z2*Y`>8z~ef&Imv0%v4h5I&B-3Hx| zLHZf8k@bFkH;C;O8UA>bYEULUGl$zi(CwyWsqdU!3fbi(bxoCK3nCU1voeyq=6L|d zQ)Vxxr~uh6xiBYB0d<;^BMGT|&dCVZwOgQH?UcAa#X)lcfvc>W_IJpnCH@eRjtMT? zyDj^iANT@iGhKyKd3+%0pIr%gdZGeX^Z&e)OeWZH)ToV^&rq~rk8Rd4x-s7szDe93D#}!+hmrbg@mt@&pa%3h%5446$Tn_Za zQt&rpWK;iqDsua%^HE4n`9)9W^4RGZum=Db6x6?{1Ak|F5yJV4-jkz>tdeH@k3pt; z`K=7@(+R$;F=8=Q;f&5UpwrmP)c|hgqgu9FWcx!v!QF1NK18xXIS&E$r1~DBJcWR( zUygyUr7yCm%7k)}+ZS8-e{6xEB0LryF*)MV-)H>s6{xgz8 zLw^5wVIo@jQ>cg=A2Pps#QqD4%o)x<%bS<;ggj@+^hVgVZ(s^a*o@gJ&Mas zurgZgUc714XjfBg>FHoDCpvd=%G{wIUHAEEqP5{-OQVvZ{>#^f$qjG6#yirIwXSYy z*H~;X?n}1k@R5U@m+aWVvm3`seC^UP%6#y28Hd>QhI9cDJ@>ZrhO;%9zj!QCsm$ZG z1CsRXLfatrf1&&oP=xGj41F|7fj(XX&2h})AFkH;YLn|%Ipfh@sd3?diXEy6X7LVv z9$-HJ1b z%aN`h&FG-KvhI$lsts$rB&y|&`}l~@iJ5HbsrPkIo&?>uquvtY^MQis>=^Px`oKB> zAMR3QDWGlew?yRfJX0tQr{;-4xJ{6`^NO&T8D@hDG9Gzxt7-fgCw25nVLb;NYYP4{ z_2bu5zdzlG-@7b|Y1n8%NlUVCng1!o5(eF&iouSR(k4wsO(Q_F#p!&v z`KK-n?R*trp5Sg**VK7Vu2_r?5jPw?nllZtno!qNqHz*@d1L;Fggxv3Y46wmONxA0`miIyg(>H z?v<@Vy4X$KGzuWPUU^b;aY^8@{fh(Emq(iq6p^lMoc{8pSaS9o=RM?NPD#GCc6zIH zLZ5Hx+dF@{zMRPm@4ePX|B=0r<}NUqLj?heab!L8z@p^PrJZ5v47(bT0tP1+JdFX} zV=0#9dD+WSbe?Eq(S?cTi%o4_V0rP79RC9nm=n1uDS2^c+g(T()$!5X46175SA#cg zWb{D#i;9SI)|Qcpzv;4M&V^N0YyoME}ZV&&M8N&J691F0mYUR76JV(tFYjMhHctBB>pn+K%&Z#etQxHbb81 zXHR3Ry@jt{v>MzO`sfR~7W#)Su&+&W4&U|xv692qJ5X-bb^f*4rc3@^Yg9MAHyE5;N~THmoJ3cO7TTPuoy9|2QrXn&6Q zi1woN9v-!bWZs;}*rkdbS7W*IN^DJ7iZWfAnUhXDWBxR^|4f*=-CD6Q)QPzkI%Nki zzn`>t$e3<`%Q$RiW3Ee}b2sceHFJg2lHOP@!Ee2-zfDwH=)^;)nZsx&RRQj{ipyl@ zWoN1wavI5YNX9H)BRe8O0!S6t<_akkXy(x?QulPiE>A7=SB}?GNw6F(ldAJQ^l#vL zd#m^25LJ|}G3FB;ttoFrpO5RKNE{JTHzns)g?iHZKF9|=T?G4G`qRY_C%LG3)H)Oy zY@hEIsy@~tn2&d52_W6M+0anGFHLA>s;$aU`Ff{MzN+u0Brk6_&^7|;tSEHVlKqvu z#9F-&1SDby@XhqV9HKjuze#d_=(}>~%FU$b=m*aqy2ocU*-a6bI?;^ekI-)q_m+QS zuC47y6ctTjohzpDt9OV|7opAxAL?D7Hd{_x>RwI!xW@kZ(G%fn1Z5Lc=9?4K>|^C9vB{uVi-PKX0a zeU2ba+t-i09u-akyRJB<7@8zFZKP+l3tweU(^l@YUT>d|K%8o>f6_3jAm3i@)Z!zD zNcqukkHQqs74$(x31TgGsGq|xVQ+CHykL3fR?&@}XyM+cSfWu~z+pw>vEsE7gC#ar z+sL|{9h>^wE@H9I7%hdeqnd5>dAgjbmQ^Fm<32cocGu*M`{+r9f3=!!OG|?;VpU^~ zGNU+kLxb#uh4l9wX(WYCJ2k&ricGKzMf+2*axQ+0Ply`qs@7?MbfCNQ+TDLnLUWmU zMl6OM^OOKdv9+MWA(O zdgouFxN1=!)rLBRn1QWPB%fSiu%BI4P=>B0rN!3tVPByL*9#p29>?B&dZtq8+`-+g z*nk4@X!JG9IhRnTu_fe1I3QU-b$S?Sj@M#moVtp#nuAMh8eAq(c$8<9!O_|IE+eSj zVq`Z@ZSqnDi+{XL#sUO06DZhggDdFCMy;K2o{O~UQX+K7@~8mN>L;rjzfieRs!oCb z&k%d7vG4I#n3jlv!xM!$Lp@i~&mdlx`SS)hIFb+EM@{Ul)kC3+c2~BV#5+=28^|Gn zvKmG|Z39l@(nT*f zsc5)5D>U&|O*?zuscrpSD{{L}TB2LkbfMi;SLHZN7bC@rC}7QG+A z2ID?`u`;q`gPp=0e2A&d!?(WLP63x*Fub{Fr?7jG$B(n1fQL$7%zn6+g%;;eH(yhf^fnZ_aWE#F;M}ADb zR%}PkMB={FhbDK+xVJM8DJaSQ2G{R^DmC5A_v9CgH-@3*DTywI>ZqT;rdScF#lEir zf|ui`r3X6YyDJT!->!TAWw5m0zU|Lhb4_`@Z-FVW8awh+t*bM57hA@0z`OiG9Z40t zA@Uxm>~x|$ovI;r&r3}5xJ<6mHja79FvSL5KCb!A{?(}MF^H_^IWA19}T)x)RWApD%c|{Dg zwyL~1o7m5MV*^c~1<8?JnChbU&SO4yk!ZHR?mlzgK;zfO4Rsr%?i-!y0$X2h2(-sv6h2 z^p=ON;ryGs`67y33vnA)=X;&F{1zWStM+O;3zXovC;ZHPd6j|Tvc|h@I^9S#2=2&`#uQN7+L07H)^BzPR0K%gm zT?OROi6y|c>Xf>M=XH2Z;CR07t_AVxXE+~|H39!DyA7-#u7?!1?LKAPDlUMaobr)@ zO6ci1Pgf~}^Vw|7;M1W&dE~bttb=#0E)`K;*53!+I+FtQO#foYV%3Mc4I2NewKyC- zJ!s$!<)Zh}@!=FWMTa84Mnrd14^fI>bN?~O;&EA|0Z`G#saEka*ZZR@v64>$91eDh z!iQ4tbT8jHG%5A?w*1Z{@Nz}D8y5fs*i*PrB(~e*!l+|{?2IGtoUAqiA#`WqZ4=uk zx)|uQD`UN2YA&sa;~KWinv(^#a~3P`?ngVnW8IuQZJsj7pPHI;;q%J;Qa6>E_k`KWyCE_mlK1AyK9-|Tmfa04HUf8d9Cu%+ zjRZY$XqXm42{8G1-ohoF*uT%p@p3hqx3CE&5v??l3s+1lK5AHHaQ1N5-Pypcmx{%23nH-SLpOC}U4CkmfO^th0(y3#ok%BqJ@Q=gA5R~tn;HC9(mLk0SUpR$6J0=6%SM}-@V?gT?gsG3bu0x(s(4oKO} za6bwDv)nDcIOqk`Oog8-)6yp@S8tWj(LwLwulDd|dxbvH79&tDWB60zH=}RW3ZD9g zpI=Ib?mT!N!Oxs8@ZQ45sMUKx`I7>LlC2E-0#SR_7&mdkzJ@1_csxoogGItT^i`iH z#<6PUyxF(e$@4DT^2W`I-a81aI#fk{uSdh`a^T#xb(W3~-W_{QQBr`e)D?#dw ziDWPQ?Z6QBE{sjFhORvsdd-pye$ucXnqEwHHv4M{%l&JG-we9K^61&IpO-xLz$SE? zz0^Rbp81U88eWLr3#6IQ$LW6oX|915mSl|DCw33XBdFC|S>B_ZjgA%mI*%r62~DiI z6|RU3htwtuTm>+P`Ho6Jo8WgilkJ&0omXFXXx`a!iVVeC?#nM4QSXthPP@bRxjWP% zBQ9DG0SLu{4rFIQ6xu)X>N&p3C0y9tjD+j#YHel6;PWqoE`NBZyH8(Fj zbl5>t$SEr7+xe6JrrWOBX${vGKxje!VtQ zMFn~aK?|*)P*3+$V|{5YvWJ-shb%U8Gx)n7OsYR#p?uyGJo6`!L6r4NEtqX=jr!)N z>&(!n9T}f&Sqe8O8J^-uN^Lyw_$Gu`7MHr>J*q;m{PNuV|38gM$ufs5Q&+|HNb^U& z;M6k_Dsq)f`{#waD-R2D_8qF~s=2*w>|I{PB$dxrPR9j0YqdAA#X|V0MnJLw802}o z#J{Th57L9n=_P->^$)@*PiZ_$r!YI7#kgjgV0$m-!)G4VnJ$lqCl;d1svIVe={Y(m zXk#67WFMBFCOyB^`X57oUQiHeNb>ku*Q%}vZH6!(zXUhe95D8F)f`MsLqB$PkC8?c zGOnLPh^P*#k3)Wp@E3F4)tDOpW1vL9%eP_O$D`F>6^vAf`tQuVstbVgg|j;>oJ7_I z1&#Ve86z#OR~b}nu5cZDS-}r*@UIa{%Rh6z*UBCOXnv`4lBP*}K=6E3jo-l~<-D73 z7fz9^o?|y4d`)b;WUG1I2>xiHS_4NJr2$D9A+HFYbIjV&KLjP!1~2EoK3qGn!kzvd zEQ!i`OP^e}S2vC_HtY>T)`A~0Uz`Lxy++$JFpjJAyk$FEtS9p1rlXjp$wQ{|e7>ch zIs2iaq3&+Kn_##W=fs@p5% z-e1lMSWFr`udig7+0vt&yasG258t1RrI{Zqr$*2pHr-C^k#k_Kn_U(HxkU}q!EDOC zP_&Pe_<~?>V4T~|N_o9)pxx>TkQDUoqS3Ou6|hcycJ=T_BA=;_olw4 zONp2uf4$OVGZ2SVdfiP;8MCJRENs`bHpEmPn?SsHCG38SjAzXHw;$3+sswkKbRwz4 zw|>ATZ*9g)byM~5=aJ&!eej%Ihcb$%ds>Ne4x9TkMueldw#ZmvWa6ZP42^nja7VMr zbt-lFaZ}Cs$CyNDlhlvv9vXG`2R&yIC8ra)rT*X7^x;B7$;Otv-PeMDU1S^O{ig|0 zH%^`5MOb$qydT!nnXI^ZiumDNpEO~bl-IpAZt0=7XbF)>O|l-gQb*ut<|m0xfxUh~ zz}b*caWtDV`KqC6w7g6t8QQutq^cB-aqT6>#0VKekK(6-QS%R#v)TJ7MRV2K?f4k= zC|UFX1y%h&%rI?$=t-|8*DaF+?KOrALox})q#^C?+1&$AOm4S4*4n&T#;4V+)+tlQ z5x|&jGl+y4g=<5l)_<C&^d3l|w=ls1bG#nQwrS zwNYrX0If%8a8AjPb>LWrk9jQIYtq!PyqNMOCgfOCF7P$tbbsVq?X}vmx2ER83#x*T z*0aoFbxfv)6l*MQV^s`nSlM6=SSv4At4#RhdOZ|*tA`dbU-9onF{}kOccKNKz2QU+ zp_8$0KG!=0v;OVDQ%EOXaFO1&^|(lpgCFbf366J#HDGEb%-6`~nSD0WCwi^k{1>&DC;P3K4@!|aC1am{T%^jhvdNrH2Ig` zS`VbwBYQtmX&7}GTMYqfQC-l44-SE{XlmVdW}I)GtnF%`$WBR9D{4ZD)+oBvfRIp| zhV>%raT*`aDC$ap;;SP^14sATrf(K8cZKf4N`-g{F~_C#@0UMY=bcYhe-+0s=mF6I zkHdVO>T8oG)V*Q)aXjDe_Pt()V}!CL(x8uI^@5r=F-6Ch5lvAzaC3T!)7l!|Mr%fe z&{DiKzizz7MLh7r$UgbK99L86rmW^$F#gqE03r5xKZRF}^?@ockD|Z?J8nity->Je zZnaKtpk`qr&A1$P3PGdxP9e24g(fsc8Zk;2A}UG^d{EO&nXOAD23$8_>C}ceW^9Q_ z;2xZq1v>aDMuSIe=l!cDY2v0;W;t8lQvH<)OBzfn0y2NOw`Qttjycs;=gbLRvnCL^ z&;9SY+nOAy%p0g61~y9vPga=pJ%KnIo*o||Cy~Fw(Vs*s>*LgsGA_pfRVN=#rZqhO zzV^ggH6jG_ZN(g$t6E0Obd_8Ermr2LMZDv7?3WC8Yx)D7$ymZt)>@Xx-kEV{^o-Tu6O^sS+bDZ>5LE0qQ!r~ag8XL=%e(t`x!&Xp?S)Ak z^ksQE=Stm(=b1#ggV(`Rzj=9wU|$EEC-M`OGV^h>dZEmV^v6-5Z_TZ9)WWAmf2{I~ zhuEfWte)C@*!|zzoF||f958MKXgmGKU`VW|<@IZO11hW{TcG#`h%*_0R6%%)TJWM# zig>;?x%{j5Q~4&Vs2b^_s*l$U=UX^lPkF{`7dpWI*dxcT|`9|ysE zY;Sss%ri4QqU#6#V=$+u=4GiS$Ji}(w?U*Q05(TCxzBXB)?g;DSSuW#KeltT35}?$ zr$|Z1Rt9_|?aBA75R=K{vF7baW;>0ut5-CFtbY^2ihkytpcEY8 z3F!|fjT*$iuf2z?ehkVP{v7wIJq4254s9*&8fb?=|4!~3e^BB=-cBQ#r#?>57e`z@ zCv=*6{tQN2xk4-DGklent1(A6U&J`$ar3;pR!tn&{p+7o#JY3UP8w4XI|=#=_Jx52 zrsR#NJkQ{LoaPtrfYj*wiJ?#7Dl`0Jo-<}QKr9WqZ1;-?_ilJRaIqKyMMIkxmz}E-j3{CH2cz_ zF65%dKXlvbi8h9)9MC*8hn>TXR;ZRJ&3ufpTF5ch9;gz829vC*4HQ}+@zgAcU>WZ3(1(9LkIKV4fA%dlz>&33Sb41`2KrI-QOCLa)ZB;GXCjWfBq~z6rGqWN zXw06{%+QnOH`08dicHl$BLnyj*B#*`SMW~0n`L|`Ly2--!T>C3sw;3<=W_(49;qtope`yA-sCLJ4a2cjRw}dVc^@n< zC!}M4%9yz+t~_n>yumH8`T%8<7sB#4Pr_5xtN*EPy$m+;pMNac~!Pv3)!+9jNKI(zBfbi9i|7V|nHG^IME$aSVXR&yXO z&HDnrz@u`?@=k`Ggo1UCa8Hau>Uqx1Ru^AKrU6ADwhJ0KciKz>LGrmF=1=yocb^u0 zo-`iybt#)bvVdb{l&sUwdoDhb=eqe(!h@TE%iT8*YkPY<(_n-u8}M^_Gte$VV|N>v zJ>6a25_|h(rq4zM*U2|zU477H|1ZtU6%n=%z13obL??Hx=@8E{E|T|m?l#H2B@PZ0 zo!%jmtc8-G`GQ|}Q6|)hC<#94yc0|x{gOpxAkiv^?VROCA|$Qa(%9>`p3h{1Yi7nn zqc+V|op)Mgmhr)|;y=4fXhmy(ErMMyjs(rLy&QVpCAm4P`Aml`Nv4@nt$P%PO0 zGjZVRi#3JcsFj_xT_MYQ)-0H839f}lSHNFhh0Q-Iz6e+&mF zTFCVO7^JjFG?eyJGoeeHN@{vhKDgEwCiKZsY1mT6P6vSnPMR`n^AGMiNe&EajucT9 zlz?0rQh$&-0CitU^}C$(=5bGWLsnvzecVN=oAzb5nTYqL()2X(6oga!&1AQ_t{Jm9 z{+oN)`arj`lZrfBr1wFCx9z&#!VtSZgwFj5Xt`#QXbEXA~<4DZd6<9xrW)_u~zcEBe-; zbiO5plJxCbBiFKWzLBN7W=q))_iJP>N-Rc7JZ$^35mj4mXG@NM)`}kU6(5u3OmWCr zS}aIi7P@mQQ|uiBV&ROHs+G>BueQLE4Fn*MKd4ijf1kp`LWdTk??{DW^9%|BHPB2s zu;H2}BdNhgN+uhVt0Ccnk`_xsR8c;}_Rt>9SLlMjk>TH3S6R^!jVBNY&vpY4(eRBlKrav6SwNv>UK8wJ$E)S041*TV5O_iE(txshNc+FDWHL_l%zH)nY%E z!hC~bAKT4rHIK_c8K=g&+F|~^rKr0hjmds>LG2XmXgS6WSQD z0!)!Mb@MV?D@^^<;Xt-77@>J*V&-*mA4BrM zbTe!>%}>6|jtp9wZeiPJGaf5D6y)zbzNW6nmG*O*9|!JE$G-;@6SIZ*1dWGl*ovUA+%ks31+{Y|qKcesXUpIWYr<>=x{Eyy8 zt6TyOBb>Hw^?dUwu(u(9`<1Y*VfQ)&!|sJgt)aDp4ff$(yU~I5pMrgZXt_&eIz1F$ zY%;U0(;xdd?NrWJ-6D^L?g*-`E9}OE0##SWz-3gB@T~<~^V4*}nyOKHr@i*{#Ai%j zZQ5Je-51i$erqQYuSSj470$JI-p-h3YGJNJUugZS$Voxsf(@is4my@9<}1=xJ2!=+ zx3|6yeKA>@cITV^--FPlz1NN0OF*^@E$)&ZAr}?sK+wR45(n*>`5EmuMD6P1fE@TV z6@_2!o5qld2NN=1GT@)7S8~ByTB@xzT!E8QFAP!#gTDG?@;(Tt$h%b+La)5Z+~u87 zr2H{hAp;RD3gX;t7?H7$ejG`Wdk);!^SVxYX?~vYx_ed7;N)ibbEC|nllK$kbJ$QB z~i3H(4tBG?aXD#pxgVpc?&cVJIVYltCXS)x;aYz z=g``dYb+XXbeFmJx6hSJf(=IKH(WyH_G?osfBI+Ij7V))EbNsRCqlqpcJg|-p|1%xAM zGIiQbp{BF|iu;52w%Sv!z;??=_@n%1JjnrLIy`^0i>+{jL5h+q`et~0 z250@pV8IZrOz-lU{O5MIvnKn0*w^I(lD64}b1!`~7ZK0$%FrtM3Aw@51R(eIHzuFd zI*((jcVum(of=+VY89pwdPTaZ^f1IM740G7YFUIjPO*{PX7qu-EygQIH@0diJR+f6 zKM2m_O%-+4Sb5Q!T>n5xgR^W4tw08s_{-ASjjtQ*O(YTh>$d~HB({-oe->Z)>D+GL zRoC^XgkAOkJFV~&jSw#C9d-g6obtmAgCDB`5n$tkU2 zl8`EWfD{veHwQ|+{O4kv1)LRv!Doi23_KTYkl?*9Xz3v7vj;0UH}8$=KF^{}J7>gw z{pT027w&%%^~88|dCxFSA?w{SwOW(3^!1_{dSCs}0fL2YyPFm|yR6~NTP6*DwnxK| zYWVz6A)cJrWYU$Ao_3IHJ)`j-l*rBs+r#jQ9}tTP#JmGV5J0Rl9iou)H5ivK&OR-) zx!K^n_ff*Qf4_enXJ|&oz{J8vfJt1(a+RXNZThLm->Y5we)78os5qRLsn%j&@F=IC zbU+DZPfK^91UJJq3lH|b31v5`-b7(Js=nj@CGv-8nL(szH8;n9@woqVycSNdt48KofkQGbgdbnqCi<ytcv$AIVjd53y!r7l6aD=jR`(Iu{!MgBOvu|>yB z!H!9q=;w1b`Z#lqe#X^Xsq$^-Ru6CIj@4wDl7ml?HuODo-95gg5V%2oZ8!+12XfMr zsxpS3A=+FzUsI~~@gExxW40qwsUTM-7G8)0$(V$S~6u*o9EX6`w6LS;E?0YD*6s$(#&ch7QE6I}mp9f$k-&pu8zLXo;&5 zz7Vu~5gZ`rdOFwd#WU@(b;qI2{Lkj|GjoXt`!Px0vd}W;ap@~=P_?>xU#wU z!HXJ=wvB>r*v|^FN_XtjbaO}~o)=JD-=$~qSxkfXegaFuB~kn2#shvMlf5+jf$%Ax}gcEOq zs;QoC+lo_u(#YMzAGR}+*bL2i$lGt7S=3DZ6%SVLjV|k&F@mBXqo(S%v`DiqT!z|f zKXZv$Cngvh#u(^eKfAVSF>iw$Iw1ZkchqpH=YO33G#&*%EZXGS2b-Li=Uu*2)=)lj z>6{3!CTnOO(>ayvt}IX~v@w2a$zvWpW2EcZ_Ip#ab))I+!+YuC>CmylRqtzFuWoPv zdq7BWqe?5hXnDP8MKXS02(U-@&rb`%=tC#L6?IS|`rlkLyzjU=#;?n!siAtpM}J}T z@b24|+K18uBOp=Sumx+^{g3Apym19mXpxp-)}kWXPstL^$6cgcuDN=CEr$+!k@F<% zQ-Sd-07_iF-Utrbc&qm@p^4E>L%{JOQ||F{RElK&e1+ZCu3cH2gX`ug*gtNf7b?_& znDCg{Xf9ug>GP_WzScQuDRQwx4^oHP$aemp=?)E^{Wi9d9-li}#z zLcelaa0p%&r)6~3?mwZ&Mb%||Tmtjp&t1$8t1)?)r1Z?Q@(-_VByc^`_8HLqVw(=B zhTkl+vh@Xu0X}?*!+NFlo$=K(TYPbSIDQp(g`R?g#oDlo^@2&ic>n3Y=n*}D=w8_+ z8z>qxwb5_yJC;R8D6rLpWYA}Z2$hy69fQFa+k0+roUITgh%Udk{zAC%{cYSx&xl>7 z-=r&Z_NgCM@vNM3suC;Ppiu}Q+byVSMO(S9(-22js?mT*{!0KO+?n&g?W*KSct1rq zjdUUvI{tOq;&?c$ueP`TTz11hH*`JVeapEqLVzm7SGsXUAnWk7vQ|j1TZaYD5iS+m$CDF<8{0YPV7q9-(O-9vdL_C~@{_drY!^qBp)QC1!dWjiUS9EEoc2q*)Rg$^|1nHi0k%gyO^dy> zC@57X4SqY>zIgWO&xG2U-MBMZ^*ysWs((aoth^jAq{WMxQA?XiQ$)8miq@+V+Fbvf z1(H-SlrH7nvsSkuqH4fu@=8c&>}3-uO^Q2lAeiL&)#$^;{(3oCi4UyVCmNRvEU1d* z$adv2ogk7raIg_a?8pie-y};|tXan_tKL{JuZmu&Quq?mC;ZW_f!+`NSD|c@1Ryp% zb0{0*JWUFo!ci?Lts$GdHPOw`$Cf=1Pr+%&hv#%3f2g~sw5+Pib2=U|=F2&%{VP7> z7I&y;?R}P|VE02{h=?CmFu)JW4u!s#hB`T$4Is9)X8@h0Q%J?ObpX;0w|2-oh*w+Z zAw-oZ$in6IgsarpOH1#)jQbYVlx7wANqW0xY64tPJ5O>Ej`n7mm$yGBUKlWV-vnIj zL&sFK+}O0ac&Pmg2yA&mDq{!U-cQhD`Lp$G)8d#eHCEJ;+27PK zjds>Qm3Y^9OP7Ix)lKH)1U=A9N0s$7uVX-Vqx6e&{1j~(U}7Vn_JJMSiJ~=sM0KBU zCabLr9Clgnv4(Shrh;AVH7t_5v}ipp!=(csoKBv8kcD{#I=9-JAC+Uu@NSc~B5^j8 z=0O@;v6Zozk*OG&dtNFFre*!#Pi)GY(9O5Z)(j3>Dd<*a%%S!+@+5%%mx!4@2rk3q z5auH!%B)6xqhm#eC>l9-Gr5p}&}Rq{dyzz}NnVCgwnUK86-e=QckZB;)LB+q5exSD zP?-x#vL=V(W;-}ktW;GTq>xsZ5u9ojq!P>Rt^Wz9YY`xj+=Fekt8A(oX}RuEy)ilv zRBZGKCK_`wFP7;QuAH#Gb}sCmq(uLm+YPf1AQ7oimW17Qg~(N=^UIpmrVzi$8MEJ` zyHBGgkbYdrUR}-1o?#CLAF7lVa7voOhY&%s*dXh{=O$w~s&5q)Au#|KL(l!&Xw@lS z?OxTq2n@B8?6$7Jj-_9aSV;Wv`I_rcUu>gL$2`xLab=h>?3CxmnhM<}TCDS{{@B?E zLvJ>Yen^++SAR8Nj^~IT9*#=H{U|{stx}Ba4y5Nwe5G9O*;qrkmO7mX)&|@ryrJ$y zEbNe=yGiWyp55eT8uXoBH~45rvUneF(w<9Uq8idi*B{dBdk^aA$At(eeb@bTJkWeC zO#>QIHyPqfq~2)ySRvyG!vRa>DXn%3&`Lld( zpZdegP$pk#D-U|O@gvi~Tkk;H?YO>ar$8`2u{)k4=c$M8*`N2@7ea3$x=i8PdKgFM zJ?jTumvq}q<=8~_3vF~00i$KlT6gIqt-0oIe-%PT5*~j^3MROt(FimJJy}g&cOVWu zd_Sb=`smsR4%6cxFy^QNKcy>i|G5zev~@bGuW(ZCzMg&kKA1q{7g?S4kXXY6Xx4;b z30Dm+v_OPTr9O0s?>qm^$}v%k%7sG2R@znU0~}zVqF&|DF1(u9CP=~BE%6~u(%;fG zlDXJ4UekrL*$u|6Pf4TDCK?I1$C#Y4cH&9{m>>k7H7Ql;Snl=|>^Q)T6%aM;dj;Mr;M10#YgRL5rulna5 zymb~6nQQK|-jkodQJbyOqnBoT?6+HgSSNg`ps%7l8=%<|1wlb1--d9ptf{FIa5kc-hnX1 z_Na05?pSf3t5It`eo^&c8cmXSrw>u)wFiMO4#vm|A?v(xldU@DZ|hJtW4&OoLh@jL zA4`kFX%eTd3B%CB9r`#5C<#&jk6}1?SKDd$c)wnCYor3afhq5TgfMA-x0`*)`N6{5 za5(m#g*UINbdBsDz15B1)jk@T&YjtKxuRdUdm9hXaU;WJiY%>WsP9?2zwd#4-goc(6^QPySzwS|qu@HOz4 zmKXftsV?{QhTacHJ~uP#kt{of)7(|-QYKdQEv083N^ zEs06|-P9cJu<(n4>{kVB-z+llWj3C?HFWgD6_;s3*(Lkg*B<__1f??Y)%91cagtY@ z;xBSUB;VG_f~hVzi@fi8c%k$Dv`IWuxn%yK>13|_EoAle$oO9?ys!!VJ>D#YyR2`h;3Uwdg(y2c;*j_~S)Km3 z_dz$)+-ZiQ%?*EFYz+CH2D=cM$Mlix$c?6>r>9TN~Teg_=pv zzKl{R{LL?=ven>8FfDuU3w>(2ZfulY#*>-C%k)M&i038@i?k|$vdzHk)~dIMB9^w+PFdWOIr9iM1zwQdCw40slyZmnJ)-@Wq%JXu#|6-9KxV$9lfE06C3c)i4rWw*xTW7_8G&a#|*2kJIR9DTuzy(hmrxa4zghM7N1#O9BgcUajbnD`x3{$+=wP_az0f0+Tb|6O!gfw`f988*luBKI*GY4Nd~m)yY-{(Zq%Mui z8*C&-0cm!Yb8y`68hPi07LOkU@kL&WhZLcRle6R0^cL zymunx2&}}xyJ@|+*w%o#`J$%)y92GEPXeNAI>4)F(Y=ufp`Z#|SMh2HR9HMHm^Z7+ z7(@0vHY6RLKPq0U{ZbCt70~AOMIi5~FCFlojY@V#jan2|I~GH}-6eQdnFHTLd4 z!35msM+BPbVvlM1j?)L*bH};_eCs~pg>Gt|Nka2eSe!=fGbLG#ogq!Nx48{?@i#Yx zA9(zZxvIw_T-u>gX9bb`9UT43ukk$mW?Uqi5%XDN*4?+`A_RHgMJMyc$$@!;SbhS^7!*p!tM;p z8T>BeNRtoIUhHkOx62p|u`(ZBO5&G~mljoZTyWONIoUNp{G?Spt*N6ZmLeVIDO1ax z)iBi)9J%su;ANEcr0*4M&J4+>6NG*;lXo1|ET5pssIru79rqstC~Ttl&|RN1hvUTL z@49&6re0ugrr!rg$mx6`1wy;`w02QC5YC3PeVU<_UEFmL5Fg;;1P;~bQ9XmWK3{&} z25*y_h6t`|?-)9%%5@mDe(+pEO(2nE#|KPKFLB3_Y6Wyt;BqhQsQ z2cD%xEjsCNV!zrS@OyOZ2$Zv_3f?yd+m6*}a}0zq7JDfwWITcscEJ6KnYXg^S(lr| zvkrJp$KVAW;-5rnYO*W7Cq0f8eR&X*S^1k~G&wFr0$t$ZuE@I}(fcMbPok6ko_-rv zCuGuL>w4D%R%Dq^b1cF9D zt`{mk+(gtR*xFcEKk;l{b@>97jGYz4myjoX<|SfmsC7ib26F3(S6Rgr@Z`Y&qe*Q@ z^$JC40BvW73Jus86+E4&kF2P(xX<3DZm?y07=Dc#Ux4xo>;;XpC_yt= z^P7E$nBJ2@A&j*$6_{41TZ?n}#{h|-8!tgdq_)8r2lQxLNIV>TD0oRwee_3Tp0sU_ z-^NJ@t^HqUx=g`h{MF9aKo_&2(#)s7YY$%8^XqTwcwz(dG-RRjSYZV(-7d>luZsn) z>XjKN6?=OkNkt9WJK>Di6+ZmA*v-1r$is8`GGj&CdE80JmHR{8T9(r8y~HH%gb|0~{* z{On*i&!f^RfH`>l#0z)IS`-dw!@kT!9n}quo(6%R@jK?x>h)WjDP~!AZx8-s@D^=$ zYQRs?W|r5mFaAlahn3eD*#JF9f%t=^2_rv!bnk%Us+Ws*8#B;dZHQK0Mb?yTj0mTa()VYK0}b8}V0*aZyAzOcq=>-fEg;IF*$fSYk= zx~?Y$|Ap75Qow8KDef((x+kP~%jzKVR zR56^BP*6(Ba8G^qgdIE}{&hr@_|8a6zdh;xLEP6Lg|5!SZ=^MDtBATRM~d`YQ@bkT za!$5h^pp<#_$Lkb4ERuY=XH3GP>VKV_e?iag%!8LOVf!N7)?#uF7y-PTK{Q9WU^!S zPn`nifgHsvQaSdXE$h-@_wK21HnPRl#&h~#Uhg2v;>x7VWTj8^(cQu}F|!PIcW@pc z^riBk$KxU+jdk_`+G>F$RiCPCvoV}r&K#gf)%~)*?{D_L8~=?_JBT69b&~X#mcv_S-+WLf z@$}#aZrxsrBkn#BHxEQ{8UZOz3#`leRW;zg58Tb)cFy?1gKrq$h>#cXgt@t0hnfROcT(~SxFd3>y}Q6^ZC zn4Vs4E$Z1+%p@JY5ns$Ha7qQkYH;Z2;pnf$V#!x7uDyaO5z&uO&0FuoEr8S+MNKVr z$GE#oqdL}iJhUDUzVhWgpQHDJ{L;$2NN#O1*opt+fv2jLHTcsB?F>`an6W+c^SQ_- zklI{W=MO-rk;TscjRBCo@xk^{A!-2b$9BxvYNW(nwfXZjl%no0<0$WBm!tybT_7z0 zX28j38~sI~COvf0lxj@Ctyg8g=Xz9@SGR^1jmM>>%e00_5KQe!f>aXyA9m%Bcav7& za-1HMLYkdDeX#Z*bd-ca5!6X1A)&@!0dei|&lU4yA5b5a#^j(!Dwcj+`9veK!|kdDoskLLI@C|VxtQP2nboyTR=(@ zIx4+JIwU|)AfY1(1VTvGnd{llK4+i3-}l>j$N7*k7<|Z>Bak`o|8-y2?-GHXIUbhj z@TNohNsQc}kMEh(?ciH@WT|3m+CnS!h@V6UqQU@7QG4~c5y8CZ;ueM3qViV zn#NF$UY4(+OsIr?@&gB6wi~JWg_xmk+n`IMJEs-)q>PM9qE2y|yu>y6-{8BJ@C#L<%B+nR7yg1jLSiSG> zaf+{8_%rAI>eYkH6Pe$*Y3&Vd{ZRwMFu-?c_WN3HGDQTP^lMdw<;(uIly^>OXsVD_ z*1fA+y#_rTpMT~3322Hxs{;yO%Z|FAeB%_T#=_pgh%7dhw~EB)RwJf856?(2BH&jWo{KWjG5V&*3N&X^Teb+M7n0^Rr$adErESYORIWJ7y-NM zeKIYhfy{tkN;9d5=nN2QY-bMEe144Hbqk4_t6Ne;{izJCX1Sl`R&7y|@yR@<8?-I;nCBLwJ zBf4eWeWE_N)cMLvYwp>+jgg-RA7Xn#PVbi%X-|62L>kZAxxACRZjW$oOtUO&FZQ^f z-ttxv|MB-3_k*kemj1Q)qUmwv9o+r8+?PzB4^0bh>ht+cSoLytRKzqyF}D(-^ZRyV z`Y@RCMjcF2_s?(IxZgTnt+XS(bAoxB;Z>QpKoA{*~@ ze#*G<`)eXtT;%sD5ZADPVy>;Zm8PsSphc}c5X}+qr3t01ZIONF(Y*YoFR>xcUv8wPP22FZ+rJx%AD(q_+ct^B>uwo|S>dQrNztje@ z)hWbfO80-pWQt@O#`{CxRq6L98yQF2H20(g|Fy2*=+e95Y?!pxsG{%(-%DeCsfG?= zOd5H7pTSm4d+4%?QPBVwFV}8i+6l`#i;zvV0L9eU4XbsuJ(H`sX}mgm5TY4bB-ljT%po;T%Kbva&kU#2B)~apMr8)jzQJ@j9$La~D?d%zPksMvkOriw%KE&XXG! z3R~*!Cvq*uI~o8Lk%0fUtUn$@qtZSyIrrUXtRBt)jqQxRi!^zqjy71!?y>ZG@0U`z zCzA+JF8!GAzJ=314W}oTmhJ3SG>8w!*j*>KeY90W!?WgA6JMQn|6}Ydk><#5l zU&y9L=++$*8sJ5=7OfOOvGk7F&Wq?4^p2(98m1c`fpY8n$UrR>WP5Eo(NfaIr=$&7 zdGNLqQu!wYJ)6?B*TgfsA)g1(>)>w=b-5(EyD?e!u{Wt^4|*QYgh-~ zj2Dz1$Q_yI@&-t*{*g89+P*x+J0jc475AkIb{Hh0=lvl1H(d~$- zyo0GO7qbQXA5Odx0a`m6OPh2d@00`2)?WTA$=UlAdo~?S^y|kcx)E@e&6TH-luOFz z+Ok8Y)<>}BK)LUO1RJ;J)q&dNASj&x*{@p9+~{Wz(us_3#K2y{PGWfJ`t{q+P#wdL zS?b+#@tt$DYK;zU#Wl;5-mtJ^-Rf7p=3x`cZgq?{W;ZpZKDZv+oBhLEZK>MVv97;23w_kmIGit3y|p%`^uk72B9?@Igvipsoe#9L6s1v4TVPwO`QvJN;cVuul>c@@_Pkm zA$L3*Hh3vm6RH>SA#IQ_Ue^2bVJNQVAP2WY#*@hML$)ThWrRfM6VuC=s4p+!gJwDa8E2Fi#m^3T?kC=2%;a(Cx)$A z_CsWT7+*0FHfE1*kTETRs`1x5JteeIltkg=;Vmv_f%|NMxlGz) zv<~}ic6}-<-;~XDOg?XO>ucWr)X^<*XK7E9&RcMcLJCsW`n&vU`x#7IQ~KaU0Ld<% zL!F)OmG~w7DedjhX%e|AN=*nc{Ev!l1gO{x?(7M@_m8HoLiup0NQvq;-0kmM@n4br`EnFMpc+OCL^n{kddGtjWoxYzwnX|?I<`|+>ykh3| zDNUY%O0WHA^mk(8D=jZ=5(8m)2j^v#v5wB8ePo4^xl@g~ic(Ix-NyJGhtl87(stZx z(JpLut5}$u@8=s1ePfcPfj7y~{8sK+nr4iVzgD&y%{UrTj@T5$&B5w7b?DIxh%C3U z@=;zCsRRwo!Op=gu8}7}WqO>brJ^gaf}2To{*o;z2FAFX0J5z$WiLe)f@oz7xd$xd zL5CgUs=UT*>S*?MU6-4@=#OM+Vxu%-oH^2;{)`Tg7LL{`_;RMOM;najfgq!_zy(1RuMN4WvPZ+arc zQOcXu`z8hNs}Gt-I^U~;H}=*XLK{nYQp{l+#SAC6yO~FL9j}JmabQ(}1pZR7$O_5M z5Cv^*->BZ$zSmFOKK<$8pKqddJ}L%vd8nUPLRWf8c$!nF-tlV{kBWnZX_&6$wp4}q zQ1Ns@OZ|9tKAPr-E6N*Zz-#2uA-xv{8fu}Vi7To=rm?JGL|9~&?COz1O0@^@>izs| zZBEIct=Z`qfr(}n&UofOT)vb%(0UmV4P`nOy1<{naGe2I#Ro<#8kf%&@ zG2a%#NCf>@y4lzhq2;d4=4^!#;h8LI-66wQ$k#i0eaH4Y2n^^Iy>jy?s7`qh)&7bB z=9xW9%-<}+PrsjMeSyVrI&MEjflZa)Ncb0mYs+NGrT+DB#RslXH@~b+rgv&9EyhcA z3(MWh-Ro@49A~52XHemL2vs;vtMfoUDK|2Vq%TV=;*#jW6=vTO=P4u=v~@_GPV z*Cyu!s7ce(lj_s@A*W!*)lxkPR1TCXH3fH^_cm}A zy*-~g4dLp6o4%piLT8`&B-Lp`g$yWC=|FKUEZ8QUDY&rj7Tz{sf2dpYeiD^ReWI%4 z75)=6oZMKH>82VuP>Iq%F62JY*$>Cv>n@TI6Z>U^E6z>@>jYRtUhJ$Xwl&i}dXAwy z=1w1^oQv5EO`6@?L6}@@9RaK=KLZq3H=+wPzrj#`4=afyrI@Dw?9wiVqs zx>pQeBgf|y@tunOzUQ%Z3JX>>b~?`?;_;q16bdh%BXYae@R@)4xAoHTF{IF(4=xb* ztHV(B#pg7MQX#9NPj6WdEeI2qb!$73z!CF2Z}fom(DW6pwGzOJuimqLZ{kZ#J}f_0 z7M;`Bub)YpwrtNK2z1$MKxEfUWgf&1x|D7I(&{!0Qx#JzT(lOK^z?Q0(;LV5qIK4b{M;re5+ zz;Ce`ME97v-4=jZA8gAtTSjGeu#lCWCD1d+s=-sl1vP?)!N~hJhF&yuBZAxZAl-v)9y?vKyO!Q zrXJd!MOfzZ=JrNK=nS9fnZab?d$sZ-DTh;a<}JPtcJ|yh5wr+8ByVd48u72%Z{7Qf zdSHlx19C{{mXw2l(8ejs^VwBo>NjPdXgx^j(^yd26i5BQ8^g<;gVz@Co!LHhM;KFm zQY`I9%K7zg+torJX*xD%Bpz<-gywBbqLYm@c>4Rv7}4Tsgwy4|V@dvF-0`{ML<0YU z{XBCGyRcLeIq8>V5mm_>$we56Lg*mb6ojAYs~_=c9eoX9?eZp$ti6hIPcN7J;q0LJVg3p^nP^cMopt^S}`xR zrAF?JZF!}`bH*gd2(}cNeJwyNPOzlw;srPJ;j@RcBzL$)XtD;e)FmAB#W-M8Pe?ya zD9|}$K~E%f!aerEXNexZtT8;b{x~Y#E3NiITi2zTIb+fPkT9aZYkd-kSPfAl6{`$v zY}%WNXI*UxCEsiLu$ycsbA7?^!*AMcT?FPJF+1XSC>hvjS>i{g>Wkh5?SAo8TQwF! ztu&|k!F6wS9(g(iXM}Ir;i8P9ByWOb`BP`#;@HAZ>|NM0Dh-bMBXerYBQ9|vI<;S* zhuzppKJ{CnWqlh@SjHsw;}2(mAc+;*$zVUts?Ks{JU(Gz#3lM*d|CED&e_+}WO4e1 z(sE+n-64#torAsC2_0`M&86MaRZBl_<4J#+(W$ZZ$-qEiPg}~(IE?hmxy38T;)uv% zZ%lD?Mn*0P>C zG9eD!_z-=mg_N7%(f-(^fvDICLDL-a$P~ZS$io_~jcg2~fG{9U_2;`a6anr8jwQ!t zj9dnAf7Zo!)VBlcfZXVvX4L>ZnX$RVU+Yu~b%}B5K%P~KHq=RqNS~8QoW|VN6R~u_ zpO!@yt;zUvr3JCv%z9~31>XzY?4Siw399%3@-A%~`!ha`Or8QujYw1-=axYj1xq8c z)K8yk1|nPvlQkxHI0i$JYb1mE@hUkvxfO+?Ew1b5UZ1GwyZ1*>X-epZLvcSl+66Zo zlXutV%ambe0^DaMP_^AvFkGuGDgPr$2^|Tn1ax|tuOHua9-9&JKm*jw!bN z(vfA>;;;x#D+x#c(PN~^@Ttf3`_&I6Em5v&1X!s`t{Rsel&l$NmtZIxelhxW=W-on zi1Nd{-9r1uRz;9i-=5kqXoWKjy%VL3H8BNW27lju&c?+WpX-WvF!2lB-mW?I)8S^c z#N1WN*FEvZVrE}c>yI?g=J<%8_QC#j*V0bTzYzs!<+Q!xt;?35wqPBL;_ELN4yPSZ zvI-`mt@@caZEt2;H^uTjQKo*yqNQNECg~4;l%~^-Mz}tE!RyU}Y?mLk*~-7Xw`j|I z`blGpO@3f~S7@{OYwGT*BpL(q4C5Q+uesb2-&80Lq)zZ@>j#LURcROTh~;trC)Y{YOLCw;}t&gOkp3p;^|DD2F2x>uNlDepfr(PaX z3qI!0`MxYw|LjGX6>azwY<#C`N^8Cw{fI=3K}R3GWO>{ZoUi>=DPt-#GSc_l7qkYd zmFMnM{ljie&FjfvyhjpxsU}EcsnqQ|D(PURb!YC|t=uby^a+3}(bb-)$)kiPY|a}k zEDgMY3mK*lWJ8R_PHR4dSSMaubBxTa(JB5(k7cB~pKLfvaE4X$T9v3u!AB=4&!6+X zI(`~#azsn)MSYUvp7GO zf3Nt!;al)8xGHwyF=&&nFv_S~OzO+KnW9cYWJK&(ty%fG-kt;~1Wm0iO%uDso`Vyx z(!rB&$h~Y&`MgWis^ZJG28*WyHztgFU(0QYQ1A`Z?f-RZ^9?>iwpvTUNNSg{aCn#X1Rhxvl3WU-|O?(0%QH?2zhpSpLh-irdMy zS?cTZC6caCZNt0;$+*od*DP);KzOA8@%zGRfS41aCK97u-_|g80fMf0ZkD2u!CfZrJ zR&3pzfl9AtjPWM7=9Cd#LnE?nAZSn4p7p)5j;bmVw*q) z-Fl`vWFm;z;&yZgWq)5PLgtvRzCw8n5)bSfew!{XD6x~g=jy;n8DMNG&}!p!!|_1Z zG^mjMSLu(2K4r7)Yrl473X>JZs4lbL`2I*u#|D~;TS|lyKxWK8B#Q+eF9;)G%a;D* zy|a(+L1t6Z{Lk;W&nH85CY?6jcID{Cxg1B>TLbg-k?i@DZ7LS2u&xwOG)y|4nS5uA z$3$S+`0K5F5MFd&7(lsG)ja+bxcU#E;%ZuO337b*vfayC*M^4fhK5UX%3UCdWTV?= z0WJ`BPLLK!9qVrgb{=DXTb_eqw(`9*qf>+fR2P@Rqr3wxW(!&adHu*|D|R=?k`q}v zZl9v_m~P-h?3(2yQgsvFLHEYNCorkYfCt;DXMUC`(A29OGQJ?WR(=7KMg4fZ#kBa@ z;iU@3s$sdifi_eLc%9YQ=yoeYoA~UbnBwSZ;ZIu|cx|b?54GQ*SB9@6E~|N`1iQ)W zt%Rs^^RF+|cyjjCLl__HKu=#6yS(ciOsP>Po%`f*6g3rU8R|T*49FpGC*mB2-I#wE z@wfZ#%-0KtFEsANi{XjrVZ1{4_D1q-$z)0PPSvm1vP(dNkG)sK5^d&6n)3lGrr1Z8 ze=t%r-NB#~?qMd{h0*mJl(94_({8$96mv5J>mVlY}Sd3$%d{I{$b|k z)iu?!0dx8n=ggNc*0PdIex155^2ocKGpAL&a`XWH(hg75Kk%#^r7`cG7MnoYNgxei zsRG6kg`#MZ=%?h)X_Q{T2H)yP{*zND)79oQ6RD+6uIAny1OM%7p-WeQZ+4*l|7J0w zMCZ{2;oLnMdlh3E+E*B+qfe=FzCp%Sow5svQdsiT@Fi~nXgbmBhUzd@>pTZ2va--m z6(Eonwlt&YKK1vw7;z){)kL#hUYYN;>u`66(fs-bgz(+B$+fws$JO^9Q5FDTqPEYVbc|GhHBaI#ZhZvr( z`;otIoobAB23y37ZyxOBV+hqC&jajxCNS31{_ zPW7@qvp1hmO0y7BET`5&^Meu1>dFWRk3pD_p?KcqrZZyy;aNtQCZkZ$#rpbqF4@hF zG4K-~eh)>BMv?UNq{Jws$6TTI4&3~7fMr(HhmKL8+Gb^GYXO4ESXrXXBRV-9*ed^y?<7rkzrwBzVtye-*P@K%Z#%z zmWiQE7x2AE_g!EAlWIt?j>xN#t`)a+mjuvxZET zpDd>~0H%=RwM=xK>qxCpOJ4K&CGB-{3utw9VttSo?JL{!Gvcg2qHG{`074-zJvs!; z6j8U{Q&yT^L@gG*^wu5YjT;g^+5AW1g$ocFh^BAoZTHO%00rwP$uqW20L(K#}C zV)aSfmZw*iM;vA_<*|+zNQ>HS;JDuqd41K)`)a6j#o(=U?h!X1aBJk*_^S0dKmI9M z9{U8=taT8Em1Yx8?gjEc3c89RoNl?iytM~MHa+ImVX(+ED$^?Mv0KIQ5^o%Tx*+^E zZ?Fmm?=vK)es>f5RR@0DS&uFk^cyPL1LT12s68wtr3oIyj~+6gVgb1~aG+Zup?m5Bj) ztEDNTra$)t;|h_`$Y-wb>Ep{=+vGgE9@~3gPEC_x#~rv% zSD8bTw9C%XHGqPZa!{sC$Xjs*B{Cl%D3#(&Xh5SKHJW`y@Pw%-Tnyr=};YUZR`fj>lUQ zVYt4m^P==)uabDPwzIadI;V!wH&$y&tC5#d`_wjU3ym_qm&ptTv2cq_WMy3$S;ufl zH=Gr+yeZOCcxV*)#~LU#q$0$0YSIbR@`YwE6^rVqewFDcODw7YZ^?PH6P4w=hMS(x z**psSI-)Jr>2oc%(=S5#gsLc&*9CD~eII*2^piWrG2M7#U;CVyUnL|}HZke!m-i`h zR-fvg>s`PkExd}4=U_L3gkB9c_Y*t3yZy@&eNvnax@jEjFi_Y+%t(X(UZWoOg+eB0 zg*A|Vy6()ebh_@AoBPrr-H4$0*GTy8wC)=zz4E!WYtu*3)}JxWo(@!&L6siSd;Z?s zq(rZ@k#mBZG>^udK;4XZuJLvSuG%H;#TUa*NrBK~WHnWZh^`96%fi1Lr_{kqfH*v^ zb(~ofpw*VAL20S+eTlmpPgF?-_>3<+=7Fcbuy(y;kTH8(r9(e7TGhGZ$koPpxnePh z@GK2DM=mMlbi`fzc}sQ+y!dkL7hL|{JDFUzv!!hOFVwa{NUsW$c0+#Gqc&x9)^r>C z_?|Un#ccYBK7`M{?3B%;1Vk4^t;2!n!uf-4^D-#9pTBDA`+`&S_K>FtcsN3^S$QpXt$C=J6~j-fsvGcHC~y zSv-+7)T76B<{zk(U8^4Q{)X&JUn^fboshXRt_n!u&2#B3#KqvmrT9|6f6RL|n*W&h zbcX8z^B#$iANi~|@*_o!G6+-YSSf|U`Cqv7W;2T!)}4f>KqG)_PX4o64v9Q`^z7Bk zB%&HW2X`-DSjAKF%o@AElrSe#tEnhOriDY37xTGnZ%b^+j>5zWW>cR!LUkUg6zpp; zqC(BvnknHuX%19x?xSFk$>Lknh@yJ2 zb$uSq*qgl9lU4S#IdqtloNsbfO18g%KCkakyAJ*diTNL)5l-p?d$|X`QHlru*U9un$$0C;$07=K^j ziS5EXaAIKkn{wsPpX(Qs+!I*5aKiFIWtA*2yGbK=FrNOH#o>*HbqR;AcNh zBqRp5Oxu^Go8Nr2dva?8`HXtIH&E>JIj8=URjhtScjh>uJ>ko#SjYa#NRbe;@}4jA zq95L>WiQLW0{V9@uH_?=Y>+oOxkGyEcb*C@y04;^vc*er)eq~Mc7W@&QSrJqRFy+?w1 zfE8{S$VgHErbhjm1Iq7iBMLQnGirv1I3c)TRAuwtNKKeuW1qx%fsjEh*Gf_BTZryZ zu2Od% z7tiaRzcP4*U?!}JtHT%Cam^%`Pe_uGwo^NsHOzjhCdU`3O8?crSvq`TMkPkpp!AkT znlUS9;ZMPLR}M`Fe&IKHTuTFkHg09W|Hu{&I}u>p$MQZ1^rb9IBmRRm_*vkQfkHz| zi=SHqtYm!4)#C!6Tbtx^UvQk-MskD}--OEaE$>ji+Pu2E-zNUid#v~7O~FF@ahvnwncC ziqa0?I49nNlFlFQiR?4wVcH5zUf!tOzlhfi?>Q7*c>PU^W#mpzM2WA8>dUc(BT|$x ztYsjB5S;!P7ez{DQZ#0$n{56y}fw61i^DD*&0E*7#c-5@L6hVzV?n3-)?zl}-X%s$0mP{V@R1>-&2VUOB(By`WErlPg8PXJ?M~SnI(9tQnsn- zZw8D$g_N{t>d{0M)8&z)4Yj}^9P)+UeQB)@C`bQ{`x%Q&P7#|tu zwu~&qY|CQ;En104!!Xa_^5F#0WZqZgpGJ*f^mY(y=K39VH60XZCQ7^HOIE(SOa(N| zc0@k*xsisA>Qv9j*3!)^pGEl-OX%QUQ(0)ppwTphvV}(c)~H6iFQ|@&Ih*hWP{;nX zoR&CLUxrv8#exzZlB=s%=(4#mB)^K1!$Sz)%BdJD%}AS2->mB@L`hMfiya>!A!hE} zSl18EzUlK1@%Vf6toxlwX}y4Jqd(fEUOvpng2W*huxPt8PlX_fPapf~+)zW3~7 zr-=3kDg`89E9qLAgV3*=Xf;!EG)&D5)G&~8g0{GOpADH2kqeI3=kyztgMZBva=_!By*b{1JCFNB zo(YwY+9SULD$}F?6LInX-Fw1-KB7Sz`0IQg`QpsZV#kbmP1Y1qz>qrXiH(;E(0`+hJXa7|I&mljQj-+SBlmaaNP`I}`-Yrfs0 z^B_16-yF8Yc@k9mjdS>y2nCieoHyow3zMSvz^*d9qh@1Q$!R9%=@YYu4qgP|ZHn-W zaaL@vHpOZcaBWQ_Y<28zjWFBa@~dye$B*|hb`T_ZrH)%xN(Wwj>+XW_>`n6VjxLb` zarbu13XI7MwG_cUo8RBS9UOP`WmN=CyLL=J>d2Q)Ku6r9YZ>#pFSrE?lzc9)0*tyS zx_#bqXv;tk^V2`+6$5*I?a3d-rOlu+5NG#N>qX#FlWKQ>OSLval$jSVi2T;+x7KuG zSrX=FHe`l&bL0{`Ndbu!(JRqtZC--F2Uk~E%>ZLU9%>1o=)+qeONS}t0B^j33U+~R z0LEg97~u)-d{bjo%iBzYW)rR!K6erF)0g4sJQ0JpM(0cUPp_HrPo(OJ_y(mdMf5s{ zNNE%`toZ4ttxm;~@~XX|d@J(_^1W7(lU%~R!jv84Jkw^J zU}#Aa={lhX1G%* z7|J$VBH1R=yL+=wH^~(<5m=2B5Zscy%)543vM}n+xf^U!&d;QZ($jws%N=I>%K$)~ z+?t>oH>(==j(H;{%Is~t9%|`HqT-L_3tnU4v3}WbdrY~k_%`7|)7#By4uNG@qJ0Qo zrF)~!2m1fmbNK&{$H!#K;|F%RrC0Z*!v=S|J1{AVi$XVd<=K0 zvC%s8Rno&QrUPS_|CFXTq1dFb+uxHS-uN&v#K>0QicsIV=-J*!>b)@;>;-+eS40IQ zcWV4q^LV3(?^JzU*;%o;+1hbLNs%V7yl@dth5qLhoe@8g&PCkCtVdZ|ElXP^> z9Yz(@Jh*L6x;q-PuL_id-zsG9N!ZxIKy{m53W|v)9GGBYbmQ6{9w_zum%PMD=1X3d zq^z_^o)cqd=P-z!Dt+tHj2T_|;t=ekxD!E5`M68qW?mwoRQaKQRWo9kOX${7A-eam z856r=z^oslgfl56Dx~ptZJ%`9pkMuP^1b73_S_Fi1Cf{3wKoDSf46g|Y*LAQGQ-C->(=kBfC~H;BNB4u z?X6CX-_>7e3b;6ZC@H!sx@yL|zn8ULbHcVTEYuTP*st_vA5|VO*!2Be=p|~eOR2Ojz8lW%hnOzx0al@ zeok8cbv{uVQ5z`VkXp0rep64&8$b5f>q#-IjW&Zn2R{V}WLKUk|0VfZ`X(v_%ctY# zABX*;cJ4*D*OGFS%FbG831K?>f{E)iWbgQFhLYml%z9~qc4PcXe{0GuwtP)uuAh*h zMnf&FOrvD0>DX6eavdgV<n9jTKRssoazn{|P1gHYo#tQ&ct7usK0<>O5S0??)B>b5;4MJque{*)H1F=* z5hBt>_d%{%tH~nl|5*<=&Z~mql@}^Yw#w+WqKW1{GV;=uZ)Fo3mr7uozbYo{rgM%{ z%S-|s7cRyNr-)vPd?vtvtt&U@4{&ca8Gd*n#YvKiIN(zH{0v#D3SgiZhP=fAMQ@#( z!PZ;tfk&VNYKnQAeDa4*{*hcRcfM5F?-z^H|1?xvLv$9a@SX{f75gu22TAd^oOLA! z(KN$%;5$S2^j5Vs&N`>I6=a~{vhPEBsPT5Q%om=XVxL34d~aEfUi3J>=-sAdu@2NAS#o4wC3R6lsVGbVT_xrGx+CyugpEJBPRm zqI%ZX#xG&rG_3CXT{#}*)a}tov9xG1d$|ARLa_2YI>gHmw|x(5bg*Ax3%8gM#(c?S zi+Y~LuC;Qf(bLtQo21!cn%!e*VY+j~xHiAQv{V`c`!Ql(pUsEY!{Rxlv2^2M(l&6@ zlv`kE5VOHThQYk|@`3J(x_@_96cF!b{xV9^Dw~b7nQwW71+v19ZH~(8&cElFcEuRa zSZJBGYOH)|G+p4f4$2f7O`E4y1U|vrJhs<{e{bu2bS1i`~ksP^Er-_p{MQ4%r z^iDYKVsw}HUk7ETlYGc=_!{$-s1N4x@8Qdi14wq7U|=Tw9r-tOsojS4z8Lut!V3;j2r%jsPCXp; z>&=#hoO4xmN;`bHwxgW;HVuaxF~{@pKAYv?Usu2i*1u~T{>k~U z$X~*JF7aXn_5=j$TL~-2mP2(ycgR8y-D!7lv41UXSWNJ&&$~A?ISA3^!h40l9`pTJ zZc^;9oY^<)EUY~SAdLlwEJ$%sgc=&sm}@uVASO3)g=&mQ4y42MwFuHZ5-NTYnYBq8 zynlxK%!%~TThoBq`~Q&D}aC+hLUdo>LuOD_mobeju`t-h~6R(SiSe13#}5KwUGMLt5Vu{!zwq%rI_UMS z9%Hos%@R!pQ;OzAaw9#+K@yPAhRnEdz|wc2rVj~4IbPqo<%qx6-h7MI*|j5;S$|nV zSCRkYH|ufjB%3c|BZXHJ>%Jx?#tVmc_B~u$;on^-0ahkRrLt<__GGAN>IeNwiquP^ zB`o*XuR84$Pn+GbeAC5VbkR6#tyG1#iM2Q7(-}LauLnL$cA7_pk4?dYubawQGMkN=jsHX*ayHJ1FB7?!fKv z+vCQ2r)tFwyPAD&M_r+(kLOa0^w29GZV9t#TR*CQy24}9#4oJtDyEWynW z3gDyWnFiZzF`aLg)VXvTmPEHiYciSkGr@k@48rSvuB5y)|j%a;#Q{PtH zut1%ChOZh}C5TO2cp#;@1pawCffW&g?qhEK*qOZ zt)dg{5pH@jQI?gn=5oblgB@Fcp1}|2{-JugD*%rd|FUK)_ZMAhMYZVTKg*fJ@tQ52 zZ{efRRCA1=mU$Bg_u^EXxTu6qUb9OWvn69vslU1?<5`ra;`iT8UJpOK+TO zNwRtcrJ`u$66UWboV7`v)0_cI_D-XoBm*KW<1U!8G<+xI`iov}?u}vRondZ6x0rcA zU|hVq^K49zx}ke$7&E+#p}xf(6I7op4a_DrZRE`@6>IP!r3S6)(}8dodgC5X6`0%S65goHny{WuAJT0S|BQ`}+OL?%P})Y>Q+C$yOs>mkf9!I+ zE8SHdQgoJaefB`)f>3NTtniPyG&6O6(3cXwoWw}v*f4)lIP?y`J3Xigi-{7Fs| zs)NoT3Cx&cgGB4+<)i6YSm>)5Q7r5)->ROCTP?+WyCAVq6ItJOWQ-A5G( ztSI09&2m!}*|+Z3RFFGB{tOV7IGG`Md`lES_$db$C*M*WN*JDdZBLZ0ZBcF4mK>zT z!@9>yk_iu9thnro#E&$NtgxlVf+lx_+b2XK3LX~7giBS=$yq3{MJ7wSoB7xl%nQ4_ zZwn6s{XVn;9BFgGdwVH;=szdY;qMe`=Hyd@lr}8*L0|Fhf$CO;_j-Fmah{5%BXjka zP4>ldt#I?OtRcpn74)4o$$9Ian8StFE}nu^cqnk8Wi&nVjY}u*i&bNkLjF;g>LgIbV*=?IbXjoZ z=Kb{8*!r%W6$mUd(3E^WP+d^Y;-mv+lt7}mr!%#azWaNw&E!W$g;gkDDj&hcy67T- z`Cq}NDRwvOCn=(Zrn{vB4t<*M#NQhSd{_f-BEz~s4Q64F>cnVIQrzo;Tb>5IE#uy+ zghc-7Lzy9fIB`!MUw6{jxzCgJQ&5K^tS{DCuqcn^ripDTzT;R>ShLzw`X9`$`(&OS z@m$M6+7y2Cy^2aFky|B5ks<(6*G*Cce9lyWa_d29A0(=#liY`95n17CBl4eut)JRw zHpf(6#h~H1Yvp-VW^lq#-;L+_UdxV{4b3f{W0jZe0WFm3L>o1EKB2qv-qMM}3c z6U>m7vqh&Vl->Yje*Jm>9b%k_Lz*P_HN&+VY%D2AqlC8F_u9jL&$3hv%r6sHHBOJ2 z)0fG=|07{lnNw1J3Ka|q6>SYq@2?+-ACu=hlXz;WY|%S;c?#x;`r?2T$+3?})jPdl z=?Ur4_x?+)pg5hF4xj$4SQkB%aNywqGD4`+WQT0lF>v zi{?WQL3bjXo6o!QIRuP%Tsv7KK3+lqhQEY(k_j%WwYOH^%yb<@vX*DG@y2JNh z#ZHdbX?Wh+nMj1MpD|h)JOJ^24i$8CdKZJ0H}5+HrpZ$^IqUr!Os9-t*p=zyck5Gy z?wn}`D|1Ce+l6n&b9-zAJj#GAgF(<*nQWnb`%y zK)+zV%nkVuEQuE9J-kzU$H^6w%5$UtrCJHRHQ!dhX1`}bHM@#Fg0*#_E&FAdPy%1& zxTuLBM7w2T?F0#Y42+M=yK7fhz(e$elm>sAu=%?y%gzD4p*x1fbD65=WXw_1YHEOE z)mBM0#=K}0YN?usA$bm#u*X>Awbwt{-;%9P@ChN$i06Z?D4|{s#W#XlYgg4cWe&3J z(Bh!<=wO-l;JEY?I&L-QLy40JUH)nFO`W#%^^%lF=T5iRK#npH}OmjeQKm2y~_UDLx zoeVx5&sV{7ok7CsA{=u1BCdrP5VOtDkH=i2st$TDvVDH$Skh5zq!?{Sq1>gnj+BD6 z26X|J(XIsD4OjIy%SHO_1-nJ-ZHghG8X3_aQgD-fhyuLi? zj`Qu2B}AK9n2?#Kk|ph4q}bNXvCpwNfX0VxjPJS6R{~-hv)ZiKw|+HiE!3ZBvrF;= zvvHpg;NU+~F>weSc%v)uA8LjaQ-XK&Ek?UmIR?f4)zTKZuolj2H`sXgwiA%D`vEB% zr~}3)b)-akT!K=hDE;4Vc(blqyMiQ9nAgQ7!bxT~oTGD-@9FHHFzkx;+L}l2m)Wm` zG)WyJ=MdJpTUjCZYkT=T(J4~@7jy3!)>ON$i(*Bw@TpX33P>-~JA9~sh=6qIN^hY< z=qLyXQlv`@(mO~E9qB!xmjn`(4oQFnf)Ijd_|3W3p6i=y?{j{fv(MsUTo()yGR8aJ z^1RP|KliN={S_k@FnJyN&@mZwQ_$X4oymS=Oy+|04(c=E=6H*oSGIlZ%$}N;mjk=1 z*VSZp1+);xXYl!tl&UKadNx*lH$`Ow^~MX#cWysf zN6n7KwRs?!ZR|O^SR$02DG}Ay2?4(q0dapR0xszIP%gUKBm}6h)tYa5R)xogFBwSe zI(Eb~wca-UF9{$9+vrTCTFKyob;6N9t0kx_6ucD^bH-4GTfCQry>%Uw{91D<;4TNZ zZ|>n2m9~b#?N*h6XrEQUi*Yy>yF~3N$7cN^pa0QnCxf-q%5DGwk@o$z%=@_0J{Bfd zv7frgKkJXPvbp*M#7>|17LAcJQ*ytb08#9x8r*VM?*V(oNlL5t9ByuZsb3}qq?f>> z)?nWPLU!!OoQ08Mb;~8@rVlN~ z<%EEiPrLy^wiBAW!DFy=g0?F|P!c;%Us}n}M}DPbOP^QO;-H{r3xDy@p|))F;yi3_ z^3!K&L7~Xg) z)~XeP^8+{yG_6`);Jl(K#F&-okO}H_!ylW=Y8;2mGx*WPLa5;~5jTHul59U}`!j9| zhpoCB+JFeIlov=$5FcEV8DNWV27=-;d385u=c?yv9;kj7NsLD0`PcX`@VP;=6(mjT zZgfqM22rVLd?Pq)R-o!k#Zrh9Hv8@R3U@NRL(a^nEo^F2)IV9RNoOO&MxdR}g}k)? zc9YL#)_{9%Cs?jZQTubFuI3@L;LW`62{IQg_l1*P-s)X9fL|Yn_q7GeJ;sL4mgp)3u{KBGggR3Kp|o4+U|dCa9p-F6Ov zePpZVqZppg=l_2^sBQPUu-z3uwR>fKQ(5DRM_DtRY4hd8v$9p+D$5^A=eOJY9nu&v zB{z2zl5*Jk(Z~F(+(5}iBl;{p;H&@gioQVqoxjv_Jxqa(bLeWNU+!7YeCUbH&dsS4 zQ#P@Gn({K2ZSxnQ<~3fVC*Dv8ISQ_%#>hN)CHjchin4~5MI8hd%u0(rSH3Ro(Y_kgB27z6gGm?Mb=!Fnk+jx<(EwZ*K`T>xNHT2|O#Ige78KMR2;-m!`}R+X}DIV#;YRpQ3- z0~%^08{qV~W$6Jw;M!D2msJGCRmvpnlhrj860c02j(3OH$sZ~uZ1Pn(Dwmo%CL5b8 z-)Ns=r_Drpi>jI?Hg8mWW#9Z%iHMP$n}i;tb$OAd{M2dST-PJ}g*+n<*o5pk?DMh% z@*|KC;Dk~P*PX~K(Zar4V|f~%0oYaT!UL?$4a)wPb?*;(+N*Es(rDiP7i#bo)3I# zbBUvt7`A$H0$C2rYL7Tw`4={7iHg}g;B0!s#JJL>s~&5~BzU?aoc`wAaRN6t_kP8* zv5rsB)St!W`uC^dew00sNnvkIPO%c+w?MW`kwBT$_rFQrqI^4 z-S@A)B+<`sbxc)`3GIJ2fWDPBqoMeAS;p>g=cRrb7F5XtvVtWSn(rXq`KC!i>7lwC zHV>cJB<@|6esNWrBKLEF+LWsV)?{vAN=b5?XcI=WL?2j7RlrSQlQ{Duj{9ZXgwGWm z#E6isq;+I)a-6`LF9vFPS`Da>0$2kRXZjIM^PCryR_ezF7^mN6onLkFUIbv zyvR@1939e>JHBnwP0Z+VdrCOfaxd5~-OR5rU8-_5ooeX9sy`#=&!Jg1l3yu=_LS?W zaONQ0l=+u3N9M6m4f+fk(|W=XQr`oj`B)caJY2HWpj*9ohmnzzkrAs7gcbHzJ2>F` zGCc_cB^joWlb1$@>z(hQl1=;aDD(NuJ8o$~b)BvOWD$e%nIlkXcdLJApx+!%vOP)% z$uW)k{KPPNIOyTP>>%oJy*SG;5YhG1?E&GK$R${`8*2GRuHw-fE(Uuq``rK!L?WAY z_#1bxFlljw*F&DqLRVl~0ka4MpsP@W=Lb@QL{G&hq};Ys2PZxvMrFkr>QTWi{j{f=bs2gZs|B73hbJ-sbq zZ#}7RlWD8S2tob1U(azfw&bE7zqzYp)i754SlB9c;>MTibwE}<_wfszXYXy?%dc{N zqmbcBY6U^_WQ&oUX~+?1jOIQxD>v0t;L{;XM>(I-W2V$sKwaIfA@TAELVPdRheh*R z)Ce}oToT*W>F6#Q8;*ZFp}Y0vu}?s>htlF}nPs6KlArW9PydzuQhisKP+16WToCm6 zwa_u=#nwxta3C8b0ZDw812`=^GgheZSX%Ck^as?JESn;C3D}V7Y!LaoW@iUqqq@i1 z@!$x0jfkEbDfSr>yo8a}l zsm0kypvy1p9IgeYu*I1^hQya+DcogAxdA4G?FPDbq=VwfiMi~ST}0EIkj4xf~EPqVrxsxx0jcSx!hsCmF8%yevt;xFJ$L ztef^IczV8MDkVF~a(~zl-H@39mp2I^Yo6Ll zWVX?T+(2JU&~Lh8L0R>Ae-T=$!dOWr&cvno*&Ba2RuujLHhSPZ%&Jh-X?AHq?q=%U z7S$n6Hl4>!>oAHF{U#{fA?cF*(+H;cfxHriz(kV+_Hni4grP`CkIGxGcGW@t+*WNZ z-jwy!3|fub6-UbQ)I|;_cSYtV$i?f@gRIt<;4?pRg6-z$-R>MdJ_bHihQm>;Q3J#j zf7xBZQLfD52@X2Q+fpGdh&%i%L z%tiN4y8+(>GyQqTiyogNa+c_B4i;QLExhhA*iwF|bfQEApEi*!Gq7uz!HqVcY+*HL zx=pZ3kI7cR-K;{BK9>Qe=V87S5ED~apL(w?dNpA@j#*4qOX`h3<550dAA&QASK^cM z9A%JMxcbc=k&8U*x<^vQ)&F2&KkAt>HE|5JYIEL~m3)$QA0L)NpoV!KyI3>NDaJ|k zch)))qv#z)#VO;NA0p@Dn|Jypuc6stenF*{a3rD5cBLCW5@_F{Y&>09Kz|7eDIB2F z;@_XCuN?RAs5Dnt97m2}WmeJ!z}_p>0UidW`HeAkwazN9fRf$F{}ti!|Kxd-gh!4A zH`eUkVZjdN5jX-KcAm(%$y2SSxg>Kl;cp&0UX4?yHYy1}(9vN^pOhMf)TIZmrbe^9 z9XjRDtS-b=UxcPBxwJUSH~&~pNRvPm#JcnRPK=JKuMN^+f@-U0nXTU%ChIn8-l{t5 z>v9aT`!<~1YyUQ0dL>++pHHJ51fnm_oomhL_BTNYKQhf47MAZ4f%-q?u%PIP56iEh zJ3`ynHAfA1@+?u6WjTJ5aWkYK^;Gr0l{8ods-Il)yL$lb^l)!Tdb~V?$@Md7?S&BN%psQqGVPH^SJ|`f$I24fQKKt)&*dSZo;E~4K|(t z@$Owuzx$EFm%W;3n!^l0SP^P=h-A69w0yFT)7>ayR3hnvU(lyC;bktg7+W8zGBDHk zJ#lh-f~k)n2)0sAdPvQ<0+9tueT(-6UUxLc3F53X-e^R9IEtZ-zNFOF)?wR#s1FWm zoFpU9o`8gRP6$9DFMZN7hG3gy$$QbUBYL4AKS3F*Giiz}E7eh<`O3FkRMdd5U8-9? zmU@W6-@|_hF5tdF@HQ`i1k66;Rd{kpH90ASak-!7zmn#>U=yS9a-_mkJ#sW!c{NP- z+-@c;KP7ecZAHah#RqM*U7f}l>ohi5kq3P)u$Nj(o`RizQs5_AcHj`qZw#>HUh zIMnYuc|T$32mrbzMB$CJy!DKcDDf8v{QmD6Y@RNOt?z!^}VLB0Sp<85C1ZirV6(T^X&C zValUEi{rC*NoU{~U{Cuh&D$th{tX@2+4T6}g_~O9!B~5%yb&rux zozNNe50ZH8AdAX#G*umA=&SZ1B%tm(FD2xS4e9C=+?Vf5V;i*ZT( zRA}qUsCDH){PVE0@czKg&s&fF#II0kts|&iPV5RYP}qt);6Ui-Cov?bf$xu$KQb@9Gz zoFx}#0z!N&QaFpi^xizf3VLjKf40GO*IyKGR!$vt44=MXI{opJMRMiTOEXQ0?@^24 zppVSuG{Ia+GTIx9+(9bN$_;FND4K{bVh($#+?~&B!gztVo8^XpP#KR<)_m&*V;QTG zu=b-lT(Q~%E}7nQ-4|*%I+%o1Ysmgzwnk=$c=8J~zvCo#|Ir}~GlAWKU{1Y-S*61@ zI)!r=mJai`7ppSB=P$;vh^p}g=quz;(Mb;96#kL-gchZ=bO4_eqNCPAi3X`5Va2O;w zSA&}{y9X;xJZtJz=SNn31fX@}Vnb%T9*yr;+z)hSTo|JyX<$~4yJs6uaWd0obK8{T$+$q4 zagj>w+2)0rTWq3HLsH!x9f;t%0h$)6c$z09QK+aBsIeI3SUDyP)s-_;Q*%qPaZ%j9|*dIb=H)rVoZipb`nmZG+G zjvoy^?AC_>SbOM65g}+PwDL@_`Hb}wT*9KH9m3mQ!$-~S@-K*&=`zjHBXT|)2F?%g zQ@0d>&Z*>2`ZO@!Axp@tQK6aoGW7*mEe8HihExB$&ockelO`o15a%OW|7PqQ^Boo6 zOsV$*-zTxRAS|O)yfE1a8bjv6M=>HHVhD2jk3pa=!Jh_VSK$<>y>*VhG&eI@%)9g{#HLRF!!qZl0bDWK1!E*cU^VwmSl`iNz z&77a(k$P%kdpDMaNfa3 zGPDxJDvvUDfho5uuu=TmutCA;nOUc{QfIePq<|)EE4$?Ct>WcuPs-Yz!_w^FpTjCj zil}$Pfy1R}c3d&5 zG&nAcqE>yR7K%vJ2;Z}fF+9{J7-P=>sNdyhb^Qt6G;M1P$B1ZNghX?CK16pha-KV7 zJ=BfidrePkhvO+u4Xb=f&N@On0`)JmQmJd!WcxiF@M$oa@&f}2pVy5(uPW~5E_Nb* zQCI`kDFbjhrjzTxF;t`c56h@OgP?g5zmE#&TvLyyjV)WO*u#wk1LeiB0>%G;thnBjo;+Ps9Gyr_tXn8E58t zlzY#>(^FRJ*~s?o_O;GFa}^Ri_#NJgM47PxVDDqdH5Vnodk3u5Zk3mxD_~)W&M@_i zJl68S1n+3(WC`2b2_$hS->nQZ_v$#Z4=rJ-)nzzaJS%2_=o=?*z%V|pp{Yh?-1tsy z{xMQP2qqZ!lUU}2ygmP#D+`9i=VO20buhd`v=H(n*>32xo#zI@-UAn0#+43BX__@7 z>b&6{%>S~2=#h_99lhOm#Fazyp*D3a%l%n|yel>{zR)>&U3G-^`YQ^3AC8uzq6bAu zmmBIh@{81a)j6I*Uc0+{#fku|(z#+XM7#dDjcsJPJ_MZ(HnX2AQ(WotAnK?nOjS-D z-^yOsjA+{5!1W8X{SN~K^yE+0CDHVl7FZ}D1T^bGX{OsM1;vr z(oid6-@|J)Bqwt|`*0&NbkjQmV^D`US%tPU7wm3)10u;83`MqE2Six}gzHQjhTyFY z1M*+dUVx@y8JYAU578TqkM&UR!t7!g$M(XmfQlY72e6G4M^0U9BG0_NXn1B5_PuA< zV^)tPIKrxEloe!oxKU4v-5seRhdi)U0BQo10Q_<=BxQtmUu(h@;nDF7A{%aMGPeplXbdz2|OtVA)mRJ}0swQrP`bK<4fh{gd^YS$6 zay+M}qOn-RMz!pe8q+h9J{|Yx3tU-h<`=5p>NOzKIQ?ytXf8%jl8qJqq>OJE4Kx;l zV$6;m%v&}o^>n5j)e)<08X5@^vkxv!2OOELh>t*~?rme>cT0P6ma^~6-27Qu^rG&e zUdwOAw8R~Cb(w~%C0r5ezE4IQwJ@G)9IPpiZiVnSJzd$5#KC6(gfXS5|8_4&l8^)TXHUX=#}jC0C4%l@Y=Jg2v8yO z!yzS;PZn^Eko>sA2@uUzA;H$Jr}~E$%`566#VMQyQ$!jUVkaAr#4JB-%1W(jSP~TE z>}-CSZw_1h3KK)U2RJGyV*@W{X_VKrJXK5)84jS-Yc&Wdk_$2cE>k4ryall3X8U$0 zVu}Fkt@bVGNp60K)uj`c- zFO@$S3u8BV*vG+IXdkYA(ZYKuD^==?`ItMs0=!WUgWiH@XRx6cyTHTqjPN2sni|iL zS)5?i{9+J%xu5$}grW~@>4-H7l~-{K(Z`kZAV+V+aABmVuTu6LCfKQiYQFVuBQE+E zMZ*S3RAv23yoBvJzwZFx{FyXEE0sgP;Ono{Ns#hyOIRLU9t0|G^GayaM!JEcw4$j4Fifd9aHaM#a zd!$8N?cG08q3v76`3S~?|1DWEeQMX9L;x1@(}CqRC$LBj#p@^Vw`To51H_rN`7*h! zdbL;S50pHyji&Ca1Z0i%3%%bmC>sAEgW~u&3mdADC$dg@GWW3G1E40Mp4iJ3E||Kp zhUMi$_T)V{>ZH}hYTtjaou}+j$N>^tHA8_40|r^}y5m2{xmZ>^G}`|Y5~7Hc^Vz|^ zKz^OqD|8UWKQv(6);?bptdMUShh=ti={Avc%ZPXP*oi;9?V)QFI@dQ`QBl{SK?_d> z351w|)>qbTfozJOLOm+KLRM{2sll2QiU=8oXApxs?H|Xwu2chs_F8i@WuP*X;%QtO z49n@4W^1;_l()hfnU|lPUqnw|fAzrwI~s#=C*srzrXweP!Ri+UB*Y_~`R2y{>2}T^ z$xc|)6MVBuQ}t|EOk@6b?gAnOtYqKViYJgNJ{=7#Ui6eZgwIe_Xqzrbvg^DX!@Vd3H#R}<%GTZsL@7N^zN0s|vAB$f3Sg~Hi**R8-M)DwLjUF7nx zW7jCC(~1EZUmg$x4RnwS371dD2aQ+N%Ym(9PwcX^2)V=fBgruw;2F9T1EM0U)#&`E zky$)ln6Zv*$!LnJNY18K*37d&gmvlmnP|?=W|=*v&Y-c00(}Ef*krS6(^|yvSrul1 zl2WR1!|k6sd)NKZodn5aQ|jeG6#TDcvXCU6Ye#5@;=wLxK!zfAML{ek&~>nBB@e>c zkip7=??ek}uKK@}-$#odyQKvySbKwW7(f|?+%B)&-v(IA&pJ&sP3neHFIh^gRk~e! zX9_%wj`YMN$`Yl#gVLm!IrCF8-~gbJ>O=xam2>?R?hf2sNkt9uGS#%U$-|Gce-mu@ zmeT=7dQGD1D2ly|D;HR7+5cK>J(fr_J`&LpuG84_k8g&&%JrKRRKWG5WfJd~akl!u zikFmmTHjz@>@U8^ARem^()GOT_4bKq!|jT)-uu_7^Jq*?kUG0nk<;JaR@*Yt{;)i8j{!_QUB43>OCyI?+vv92bW_~em)k2c9 zr$$9+9c;K$M)DWMZRWC*yYVr6sZ%pf#F;OI;LHomy1VMB&%<3Gs!5;n$((j2kD`xM z$qS_AeXPz*lF2a5t)Y=e8aYvN&Sr5%T%2?x=2+9xydxo+-r(5rkbHB6WF;@^4l zrdnf^_611VIg}@8{t+|@m9Y#Zb=2?ZBewOL#$tYaudZe_l7pxU46>-NP7Nb;?GKGMN_N+f+D-k3KN$eWDV!* z_K&Twcj;!?Hwb5a4(pA7dCW>hMm<$DMm-IW0Iwah;EemXf6v7)+T8~^nSCfx=~_+D z7C@cMi|8gq=LbM4mg63iK;@d=*M7qa`n%ajhK5AkapXKWrA=+Ld6h6j*wI}9apcK2 zP08LG{x?D>Pv$a~xXXabn}>X!`Dn>P+)*Tba0U;(8+!CD`wQDLytEXzs$N~_P=L4o z%gy$$da#{GfPn{jXIoA8e*)w5-`smXT2k=!|STe?9>5RLi`f&NrVjX%P-)jb*rlW3kX5xV> z>8^?nNWPHBq&e|4_d4~p``aY2^swKfeafj_k|sJ(QS{#FUj%aANBW~ zZn#nLalW3?;Twi-T=a#PG%EiGhuh^pINa*o1y_wX2jF66&+#&&ZFJW0g;VNc3hUqGKBJ*CQKb{%p=f9C z;(?@v8=D8mY}w#{q`QWw(|bZhhN`1}1jn|f4+!7xrP@tAbndA5C>CvYbYjR_X4UFC zWNfR^0EblSm%^y9gSG3eGG*umXvJ2r%gGT``|EdCdSWmzH8)32tzgoxaSg2^bJJ8t za!X4~%R=C1(d)YjyO_ncjjimJsm7qPqb;*K} zZqylf@J?pRJEZ}=j%8p zPX!GLpZ|==WYU(Mats_=Vb{LBQNAcH}X+E1hwgOPtxWI#t208u^SZ_gry zJ6#@|jrU8&<;|T_lG{SY2VF7N(p%a3-Uc)@1|NXc``=6VC9HdswA>I^gsL!S^LKhVlRwsCI5=-B z4|wRV&bVrTRM&%PrT)F1E3f>oZT`d}koB+UTbBlMv%d>R9;?te&q!>)`~nSIfe~&-}?mlj-R?AM=sV%5eBWfSh4hl#EqXXUaNiAGjT{af__96Qm-!w z{haMI-wE@)`gP!3d1GdM&NQ%LGTeMtpR+r`i-%2Pm%M5p#mk=4&V&y)00NYB1nB>? zIeam@dC0F;s)qvqmLGibPx-;`faj1@#s<)xg;SwSvZu(lgRK}Y;3ReW?~_tlZNSO4 zz=NGkqj|UOp3XvXgJrrC*dR94rIrNFa@kiVt$)Davq9+z9njpAJum(8nyRSaM=`b5 zW$@x-lm>?I!@=fQc`2%NW6NN3?j*8!Fsi}yTAQ_EK}g!idU1eOpUUR?4fAO@p-C;s zd*|hWjvhk;(nVby*}@rOl*qL!HnuW4AW2#;$WQ$Tzd_r%NukkZ!s3|Dt9R|uSqM5O zS(x=N-uC9%WEM#ZlLf$gr)W7lO4NWDq=S!6H&%K3<_!V98ouAuy-T$@1@p9$aV?!z z4d6dysMM_IlB##=RlG_YK7R6TzW6?0gdOsUf-LrPmXEiQhw#Ap-CgHQWCYEY^}frcFoueO@0wV{vhv_Gb`fnC(mgb)Q`@|U}`!XY?RDl z))exskeqD(W`AK0GFflEXk2I7!jTgBSWJf7<74>X-dReTROstgo85_Lyv9)LHxEVn)dg3RO;zqlT1UxUrW{R9R#|XT z(KRyx6zT(3#{S%azX$*V&VZ$WBr{WTu05P-_fMc^4Yov7JlOeZ1#Pnlb8C1a(xe$7 z<+15>mzVRT*7yj>D3-ofp?UFlf5QJRzh8*J3_WD{=FU@=#LXk?eURUtp`ZdAuldl0 zHZu1Q)`B%74EeF)<9wwnQ84!*GO}NlwFyfODNHSg#Q~l>A1txd4dif`b^|%r zEoaS@iRilGyR;&2&saWV&|&aFU`NU3Y@ziGPSReG-ylgLB#%*sEA=5LDG*?s;}uh1 z>=Y1O6V)i^oFj%cIB zx6KEP3SuUA+ojaM2j5?-Z46sH-DUqFao)62dbxdr+wq&tO$DH$tT2cKRDcvAha%@b zoZ#$^0d01aMIQ+XU0L6X1=vR=$bMq<&`KPudJ&>L06? zp_C4Z8;xwGTQ$ykj`KHyon_6A+XM@;yqnrgDFc2{+{6{k7zUenp25xrYe`bb5Htzi ztf@<_8vXB?NwJVBrYxZz(HvEb;NEG62%>b32$$ zd)$xzDA9bptMj`H#K&+!44xQ*J!uV8HSSEDdr~WYyH2)F_I73EL;d*AG3=?IQ_UF@ zCn62?!V10bO$t=WSK`KStMy{cY20O8ajtilK<4{5Qj2pcHEu*45mWO)cwA6g)YwQ^ zh~7~5&?#RkjZd>r3%F0xFw?hIK$0GfFa)H1Tks}qVtiMRwK*s`_DX@JW0Vdq1v_qE zUO>*rb)5K&KUU!fm70PcRc=X15(D0OnwtjKU4m@}^|GD;td*he?o)sz2Le67_PO^m zjS5uWxnK*)P9F{`_DI!+j&}6I}uw6{ZU`Kcm;up6SRPOTM-)vxqY-{8|Y!bNB^60(p zG^+inP%fJWA0e4pIuPXJR>tuAU9SEEelS_PhQ@J8_|vc-%b#bf8lU1|3)MP0hD+5( z?xY?qWq_pdP2;rLgV#pb z8uf|dx7F>9@dlYZ@|DNcA-Z7SuZKJOe9k1LFXjyvE@GfT_#M~BiI5xix+1wP!aKX{ zjvC80;`;M@{cgU)7ts#ytzELHTvsM$+@NtSTd-iKnHsy+)bTF}o|0Y5dhBl^!YM#R zki>|j=uLfJiI`wZd+y4x6Q8oQA7ioCcsp$2Ucfke@w9b@QQ`9;ERx zla{v#M46Fs)wg&mZJc}D2lSR;Zu*)R&X~Z66IDz>@a}kQ(}aglcU1|}ipC*qMx-1g zG`v>Nc83We-_Tubft@0V{QPpn65#*K`vw4TDgGND=gQoIss4O3piXs8W=ADJJF=7B z;cirv0C%S2yJ@5v$D7?=+KXomMi~N}$d-h%_I4FFfy;EV{G?}{%>;GtE@yZfHZwc zO+~NGeI2^<&yfNq6)Rb0z4| zU_VT+Z!WUt@Le-auWN~SfGx7W+Vsf&!;`1AB@mgx^%0k3D73*a%*|C)<|WkQWHwsM zqWO9?xGH3N!=D+4uk9*ffU|hKnAD%0jhvkgD~@#dcZl8^`v;(K>ThZPi$a|MJ|+QP zx00Z(`Ru8Wg@WVb?XAHL9!P(^{x(?FnBd0hX_v6d*OmB2lb9BAIGFsFT(TDWnOuPB zbp3u-?}}}P1$bp!#c?zryl)kL?NlsPJ&n-?`U zQxg~3*SJHerph<;b@dOmd*M2>IZPVKW^;lr`8;)~=O6ETMO+`Fu}5aIq#|$76&gv2 zS}duH!|Ovj-^6@{u zcOpw+i5Vp+xQtmE3gZNB2L?v@n>@cL-bE75ZUM@_QsfJO05`r#_++_F%AS$bZY@nL zb!p^}lN%?=6O=awUZ;1|6U7OOrIVC@?fTM%lQulCtPz)FGJ$}z=;gzazL*>z0diz^r(hyIXEk0!YcSNxk@IPK7eX8QkV_HN4Es}ouY*=HU17Jx?I(NvddC6P6V4hA%Bi%NYAAnI zPYh4t56BOv@7j)F)rv;dB|Ihfj)t@20}RUSsX6>lK3QQp?CdpF?Cd3)O#=(t-#%81 zzxS3j&&!h^8lpabtcrDIZ7vCRk=uFQD7dQA>pn`;>21vrT;%mr@0Cxyx6p6Tk@Vl5 zBQs?IU*IxN*%$fh%A3(^;nS2e0W)oAWjXYt4k~1%8V4eV);IRtTdYCV$lUj5s=Pb} zrhq7-D({g$#B*jz zs?}3n2wGeU%)FO7gvN91>UKT+4SF83C@h=+2{3)YUx|m}zxi>Yee#Um#Mn{tOGD-x zhrB2EZNFZmkS6B00~8CBB>t@wZ)1j=+Ep|MLW2c=_h({>CI%w`vQZn8ByrGe?&v=k z7;ZR8-T&PR7n7eRK&@PQ-k>GHY$ig5>h^-nA-b#|+I*FOoo*`4yZn#(1k^Fn{qfo( zi0W>R5jB@qh&7s}oQk*M6NX0rBtFZd0Hx5e+&%}rwGyPKsx!~QaStzj?@Zic3wqZr zmH5H`GhyY9%DSr2*yG801^tyU>HJNh_dI2Sf)*#+(pKhE&%fXDicNCoX=@B*D!ZTR zJA5t02j&jY3%7~1vlulM+9Dt-%l-MJYn_AKMuZa;hl!xvBXmaB*##&n5+fHCsk>}-V;*&G>ATqOV{J-_EE5wqqV_4rNjg%gA+#~nhn%~LAt|90 z-Li7Ca4W7Tva@8;a6z3_t z`Sd4oeGab@6(Hcr46;(b)*KH=eDkqfux#5KsG>cL?NpgzTp&FL4e|Zle=6jAJX!HE3Hz5T)fOZr2Nebm_+y5!cueQ6vEFm$yPIeVY>a;s+<^w(Hq6t0 zOQ$|*e%c^#K~k&%EM2VgC%vHVfDA6}JI+R#>4WdPbFJFn1*rEh!uYdrg(;sEAk6)jlYiURYKWS9AH;?CoNIkvZIu z&7#e3SAP`0eUtSYh^_tphYQp3+AapNnI}ELqFbL^B2E31nF>;=L|1KWSOadUmqJT3 zKLmW7G-~X+f%@qMkZaXZdjmWS4Q|)Y$ zh&}*V1^%Jdc{Lv|i&=8wk>OHsyAdXQ~WE z_ypuIL&FsLxv?3*3?2is@Ed{u1<9+h4#FUhmZeq-venz*U#s0*@);}=N-cs{Sr#?c z`6mzOR5V}zcH3Xx`*OvcuV$mCw`;eGtTe*$e0iFkG{yBKha}0!N0mj!T30wO-fcVJ zA4>ms8CS;UnXZk7vnL_gwa;hI#12aN$PwA$Blz7{;nm z-F7CTC1_p%SPF9Z_;gnc$C4#-)Ml?xVTh?V^<~eG3A%kO#sQdOb~k+)a`9E1QD``q za-0|FPxUl5Ubf=;tta^7X*sOHQh!tFS2I8Ympy8RGja8ko4$~V(c1n(KxR5uW8j@Y zr=h3)4}eSw(tMx>q}IyU_fGNUhUW_I#OulLGNrTsQKqEZl-6vjaSo?e-X4sIr;N*B_O_K~&(H;o zDXC#-fMQY)hEK~37O6a{pFLl{z*B)p?P!opY`^$0Biek*?&a67_fyf zc{DQ2cuFeA66?b8ouUdJ&&%ga54WWUx|O?oy`^_F%U&5aCt4HE-*h+sQlX&jfr7J|9< z7lpykw<>C~vNJ64x&OvVnf%-2U+r7E_B&V!t0LFUldcVs*iPJX*Mlp@m9~j1ql?ou za;?PjRQVH7e^oa9ZPRgI!Q=SgsFT(uTJL5`;43WYjqy7%E>>K&9dz3Vbpr8teLIS&+ zloETB@k7AiY7wiu4G=I!hRcX00_i!hYiB(Aa1f3@selQTwobe)IqasQ}Gm)HvSct)gb(w zPL3Y6&a6OvYwK*)i#abDT2Wk3(B_baiHgmY>Z1{N$l;hyZ?r8z9?k8KKU!gGI)F)! zKX2(A$~pOC5|~=JJ4i~nPBG&<`1{O2bY_f+dkHUU&!ifDCE zRR7^6M1<4AV_<6g>4*W07!OxfdJ%3{QWdHE-?X!2_1gI$2$H^zzn`{sV&(i zSLBB2RO4vX9juaFI*?Ym0Rj-UpGcQ8kDW|dGU! z9*qk0$yK}9SttUCfd4i4Iq&~1QjUj(o4}O}&Z7Hm^eeOJDYH@p zJo%(A?6VOVLx(kNl0TS36*lPfYBj8@kNR2Ix?6*pe3p(>EvWQi1>|dh9#7eeXJ*SP zBQ+kALlZ-c>V|qBmAfxTb2=6Z^wog#@6!{62`X3ESLuL9SrpDso&wj$jUJLP#u`Q4xj zb9X7exUDvAaFk%=mcx)LL&+C#H!?<|Gkhj%_yb1KKIcE_H}MIf4pJ2h0?B!P1pgP^ zU2L5Ejr13osXoXdPY$?XtF#gk=mpm~OFrJFjn!1}{T1ez$e5<;$`PmSF(Aux>?79% z@kR5mc)hy*%^EtDSCMH@X>{I80PK3vM)lPT58m%m_O%=6sbWJ50vB-bwf~cH`g<0Y zF}(DT#Ux$3{%oTCY5T%!bS}gY&;y5P$`#g3fYmMYF45@a*{Y}1?Y>a9g-KCApJqVt zPK&mW8Tj&YmT$~e^WI6zq&3KRN|h@A&6^khvbP8Zs#&h2B0qvFoP&8yhMqItz$a+xsE4RO{# zm`=>;bW_g8{^dqB|BE6*_Pr(hP)4h3hl^dFQqU+z<%T?5+X zheNY*HkNiWv?qVxo_vk<{x6Dd7xbwn+uv_krDtrzq58w$-~DelBt&N~r{eu@?WOkj z>vgY}LGb7Q+uQ%%9v>nyV3X$be}DJi?^fJQ0OnhR-VA*;=^`AmXf1_2g)gZHZB;c% zqESMM=F3JihPi+HCo@NE7lSN8wwHSSoK1MW+Fog>ftj>!u2R$mx?WIFb(C7?7t6ul zKZ6nEe^DGHh`A*LGI934zaf6*{|8qj{6ak&t1Z7bY=54U>47H7CTp1B>9_Lv>*m6j9bW^wlIm+MmLk*! zzddeU|L-4SL12`yDKnOKT5Zq1f2x}^yjK>tP}|JJc!7EUD+l);CCj$b-+N4nx7dHx zkt#CXzSht=8A5ddN@2`(}zw}{7^cj(*(Nwl-4%p8P>&X0y*r_HmVjJW8MTrLxBFABCN+0K>0^B zQP1s+RD_p+5zF50Ap# z2|=MKDZOn;%fa6P|5ke0#u}-YJ3jO!j7M#)Se(2gX*k?Pt#sv%|$HR^u*oKr| z_kSs3#1H=4%N_o$6<8p#%&uNOcEOrOnagw1ubjR0_3m1GSpIM`Jd}U}eIDG8KH&Qa zpq!VIfe|kLi-IyplPE3UMfI}+e%y{l*t7w>h7dD=*pT7*e{I`3b=gvPeUr0=#-LS~ zXMo#BuY01KVN!o+?#J@KT>F%P`91}h@1r(d6wS`)%j1j ze%X%e$GlfRg`OY2r@Xaw^RDHX=UNxzrVlz z`D@toDho)n(< zx{F~wdiYG8P&DVRe|7b@^V;77jy`o${(I{!^n%sA{|sosEdOCSs3GsP9=J*DLnNp| z@%O%CSvBXbC-0qY4?3PqWK@{2#?9kNUFZe$@Wa&Vd-I*xzUNk-Bx5!UojI;Dd6KW$ zt_(ZwibIbAx*z5XG}Z52eroY&?JoHT`+I~`^MAPRac)0nxcrpI@fEix{E!q1iTk=TCuw&4IhC zp%-47r=_j(7^c3SV6h}b|AO$m8L}B54MJU0b)HRrcT~AnQ` z`dj37$ET$yUYW^h+MU#pfA!=)!#-cTitkKTS|OWf`Azhw>&p1e^U%D~=<#%8DDrtXr zTk&7b&x$jzgiV>pe|6!pzxshOAB=Mz+b>oBqhz(t`0vaW$=BbU|0fc|^Ge(0hjSQ1 z{gL&7&zJu){`@OwKKrYOp8rl?DX>(3bN={C*8^u40oUmz-+j`*=}u}@zsAR3p+!sN z+WYohiP1T-XyP1&lM1z&-Ic;}sy%-t0t+^)ELvQ>W6`mf$}wL~GtP3XryDF2Ig{m)R_Wp|(b&$sS>zeNt6nby_*+ll|@d;Y)QH2z%zwp-=_FK+~C zP+PP}{Da}6jQ&47!TYWQyFAl6fm*qk1HXi%eFL^Lbd!N0*UI!sss7q=kOae|uJl`r zJoc>)|E7f9IeK&c|C<18wiUtv diff --git a/spatial mapping/spatial mapping/README.md b/spatial mapping/spatial mapping/README.md index 933f9199..a0a30b56 100644 --- a/spatial mapping/spatial mapping/README.md +++ b/spatial mapping/spatial mapping/README.md @@ -1,11 +1,14 @@ -# ZED SDK - Spatial Mapping +# Spatial Mapping -## This sample shows how to map your environment. +These samples provide a comprehensive overview of how to leverage the ZED SDK for effective spatial mapping using a single ZED camera. With these samples, users can gain a solid understanding of how to utilize the ZED stereo camera to create detailed 3D maps of indoor and outdoor environments, all without requiring the use of additional sensors or equipment. You can find additional information on the Spatial Mapping module in our [Documentation](https://www.stereolabs.com/docs/spatial-mapping/) and [API Reference](https://www.stereolabs.com/docs/api/group__SpatialMapping__group.html). -### Features - - Press 'Spacebar' to start/stop the mapping process - - real time overlay of the mesh to the image - - textures and post filters can be apply to the Mesh - - final mesh is saved +

+ +

+ +## Overview + +This section contains the following code samples: + +- [Spatial Mapping Sample](./spatial%20mapping/): A full presentation of the spatial mapping module, which can create Meshes or Fused Point Clouds, all parameters are exposed. -![](spatial_mapping.jpg) \ No newline at end of file diff --git a/spatial mapping/spatial mapping/cpp/CMakeLists.txt b/spatial mapping/spatial mapping/cpp/CMakeLists.txt index d58e77bc..9d1375d3 100644 --- a/spatial mapping/spatial mapping/cpp/CMakeLists.txt +++ b/spatial mapping/spatial mapping/cpp/CMakeLists.txt @@ -11,31 +11,30 @@ if (NOT LINK_SHARED_ZED AND MSVC) message(FATAL_ERROR "LINK_SHARED_ZED OFF : ZED SDK static libraries not available on Windows") endif() -find_package(ZED 3 REQUIRED) +find_package(ZED 4 REQUIRED) find_package(CUDA ${ZED_CUDA_VERSION} REQUIRED) +find_package(OpenCV REQUIRED) find_package(GLUT REQUIRED) find_package(GLEW REQUIRED) -find_package(OpenCV REQUIRED) - SET(OpenGL_GL_PREFERENCE GLVND) find_package(OpenGL REQUIRED) include_directories(${ZED_INCLUDE_DIRS}) -include_directories(${GLUT_INCLUDE_DIR}) +include_directories(${OpenCV_INCLUDE_DIRS}) include_directories(${GLEW_INCLUDE_DIRS}) -include_directories(${OPENGL_INCLUDE_DIRS}) +include_directories(${GLUT_INCLUDE_DIR}) include_directories(${CUDA_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) -include_directories(${OpenCV_INCLUDE_DIRS}) + link_directories(${ZED_LIBRARY_DIR}) -link_directories(${CUDA_LIBRARY_DIRS}) -link_directories(${GLUT_LIBRARY_DIRS}) +link_directories(${OpenCV_LIBRARY_DIRS}) link_directories(${GLEW_LIBRARY_DIRS}) +link_directories(${GLUT_LIBRARY_DIRS}) link_directories(${OpenGL_LIBRARY_DIRS}) -link_directories(${OpenCV_LIBRARY_DIRS}) +link_directories(${CUDA_LIBRARY_DIRS}) -FILE(GLOB_RECURSE SRC_FILES src/*) -FILE(GLOB_RECURSE HDR_FILES include/*) +FILE(GLOB_RECURSE SRC_FILES src/*.cpp) +FILE(GLOB_RECURSE HDR_FILES include/*.hpp) ADD_EXECUTABLE(${PROJECT_NAME} ${HDR_FILES} ${SRC_FILES}) @@ -47,9 +46,9 @@ endif() TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${ZED_LIBS} + ${OpenCV_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} - ${OpenCV_LIBRARIES} ${GLEW_LIBRARIES}) if(INSTALL_SAMPLES) diff --git a/spatial mapping/spatial mapping/cpp/include/GLViewer.hpp b/spatial mapping/spatial mapping/cpp/include/GLViewer.hpp index 9ae3f9e8..2e92ff00 100644 --- a/spatial mapping/spatial mapping/cpp/include/GLViewer.hpp +++ b/spatial mapping/spatial mapping/cpp/include/GLViewer.hpp @@ -1,34 +1,108 @@ -#pragma once - -#ifndef __SIMPLE3DOBJECT_INCLUDE_H_ -#define __SIMPLE3DOBJECT_INCLUDE_H_ +#ifndef __VIEWER_INCLUDE__ +#define __VIEWER_INCLUDE__ #include #include #include - -#include +#include +#include /* OpenGL Utility Toolkit header */ #include -#include "opencv2/opencv.hpp" +#include #ifndef M_PI #define M_PI 3.141592653f #endif -//// UTILS ////// -using namespace std; -void print(std::string msg_prefix, sl::ERROR_CODE err_code = sl::ERROR_CODE::SUCCESS, std::string msg_suffix = "") ; +#define SAFE_DELETE( res ) if( res!=NULL ) { delete res; res = NULL; } + +#if _WIN32 +#define MOUSE_R_SENSITIVITY 0.03f +#define MOUSE_T_SENSITIVITY 0.05f +#else +#define MOUSE_R_SENSITIVITY 0.1f +#define MOUSE_T_SENSITIVITY 0.1f +#endif +#define MOUSE_UZ_SENSITIVITY 0.5f -///////////////// -class Shader{ +class CameraGL { public: -Shader() {} + + CameraGL() { + } + + enum DIRECTION { + UP, DOWN, LEFT, RIGHT, FORWARD, BACK + }; + + CameraGL(sl::Translation position, sl::Translation direction, sl::Translation vertical = sl::Translation(0, 1, 0)); + ~CameraGL(); + + void update(); + void setProjection(float horizontalFOV, float verticalFOV, float znear, float zfar); + const sl::Transform& getViewProjectionMatrix() const; + + float getHorizontalFOV() const; + float getVerticalFOV() const; + + // Set an offset between the eye of the camera and its position + // Note: Useful to use the camera as a trackball camera with z>0 and x = 0, y = 0 + // Note: coordinates are in local space + void setOffsetFromPosition(const sl::Translation& offset); + const sl::Translation& getOffsetFromPosition() const; + + void setDirection(const sl::Translation& direction, const sl::Translation &vertical); + void translate(const sl::Translation& t); + void setPosition(const sl::Translation& p); + void rotate(const sl::Orientation& rot); + void rotate(const sl::Rotation& m); + void setRotation(const sl::Orientation& rot); + void setRotation(const sl::Rotation& m); + + const sl::Translation& getPosition() const; + const sl::Translation& getForward() const; + const sl::Translation& getRight() const; + const sl::Translation& getUp() const; + const sl::Translation& getVertical() const; + float getZNear() const; + float getZFar() const; + + static const sl::Translation ORIGINAL_FORWARD; + static const sl::Translation ORIGINAL_UP; + static const sl::Translation ORIGINAL_RIGHT; + + sl::Transform projection_; + //private: + void updateVectors(); + void updateView(); + void updateVPMatrix(); + + sl::Translation offset_; + sl::Translation position_; + sl::Translation forward_; + sl::Translation up_; + sl::Translation right_; + sl::Translation vertical_; + + sl::Orientation rotation_; + + sl::Transform view_; + sl::Transform vpMatrix_; + float horizontalFieldOfView_; + float verticalFieldOfView_; + float znear_; + float zfar_; +}; + +class Shader { +public: + + Shader() { + } Shader(GLchar* vs, GLchar* fs); ~Shader(); - GLuint getProgramId(); static const GLint ATTRIB_VERTICES_POS = 0; @@ -40,70 +114,162 @@ Shader() {} GLuint programId_; }; -struct ShaderData { - Shader it; - GLuint MVP_Mat; - GLuint shColorLoc; +class Simple3DObject { +public: + + Simple3DObject(); + + + ~Simple3DObject(); + + void addPoint(sl::float3 pt, sl::float3 clr); + void addFace(sl::float3 p1, sl::float3 p2, sl::float3 p3, sl::float3 clr); + void pushToGPU(); + void clear(); + + void setStatic(bool _static) { + isStatic_ = _static; + } + + void setDrawingType(GLenum type); + + void draw(); + +private: + std::vector vertices_; + std::vector colors_; + std::vector indices_; + + bool isStatic_; + bool need_update; + GLenum drawingType_; + GLuint vaoID_; + GLuint vboID_[3]; }; -class SubMapObj { +class FpcObj { +public: + FpcObj(); + ~FpcObj(); + + void add(std::vector &); + void pushToGPU(); + void clear(); + void draw(); + +private: + std::vector vertices_; + std::vector indices_; + bool need_update; + int nb_v; + GLuint vaoID_; GLuint vboID_[2]; +}; + +class MeshObject { +private: int current_fc; + bool need_update; + + GLuint vboID_[3]; + GLuint vaoID_; + std::vector vert; + std::vector clr; + std::vector faces; - std::vector index; public: - SubMapObj(); - ~SubMapObj(); - template - void update(T &chunks); - void draw(); + MeshObject(); + ~MeshObject(); + + void add(std::vector &vertices, std::vector &triangles, std::vector &colors); + + void pushToGPU(); + void draw(bool draw_wire); +}; + +class PointCloud { +public: + PointCloud(); + ~PointCloud(); + + // Initialize Opengl and Cuda buffers + // Warning: must be called in the Opengl thread + void initialize(sl::Mat&); + // Push a new point cloud + // Warning: can be called from any thread but the mutex "mutexData" must be locked + void pushNewPC(CUstream); + // Draw the point cloud + // Warning: must be called in the Opengl thread + void draw(const sl::Transform& vp); + // Close (disable update) + void close(); + +private: + sl::Mat refMat; + + Shader shader_; + GLuint shMVPMatrixLoc_; + size_t numBytes_; + float* xyzrgbaMappedBuf_; + GLuint bufferGLID_; + cudaGraphicsResource* bufferCudaID_; +}; + +struct ShaderObj { + Shader it; + GLuint MVPM; }; -class ImageHandler { - public: - ImageHandler(); - ~ImageHandler(); +class CameraViewer { +public: + CameraViewer(); + ~CameraViewer(); // Initialize Opengl and Cuda buffers - bool initialize(sl::Resolution res); + bool initialize(sl::Mat& image); // Push a new Image + Z buffer and transform into a point cloud - void pushNewImage(sl::Mat& image); + void pushNewImage(CUstream); // Draw the Image - void draw(); + void draw(sl::Transform vpMatrix); // Close (disable update) void close(); - private: - GLuint texID; - GLuint imageTex; + Simple3DObject frustum; +private: + sl::Mat ref; + cudaArray_t ArrIm; cudaGraphicsResource* cuda_gl_ressource;//cuda GL resource - ShaderData shader; - GLuint quad_vb; + Shader shader; + GLuint shMVPMatrixLocTex_; + + GLuint texture; + GLuint vaoID_; + GLuint vboID_[3]; + + std::vector faces; + std::vector vert; + std::vector uv; + }; +// This class manages input events, window and Opengl rendering pipeline + class GLViewer { public: GLViewer(); ~GLViewer(); + bool isAvailable(); - template - bool init(int argc, char **argv, sl::CameraParameters, T*ptr); - bool updateImageAndState(sl::Mat &image, sl::Transform &pose, sl::POSITIONAL_TRACKING_STATE track_state, sl::SPATIAL_MAPPING_STATE mapp_state); - - void updateChunks() { - new_chunks = true; - chunks_pushed = false; - } - bool chunksUpdated() { - return chunks_pushed; - } + void exit(); + void init(int argc, char **argv, sl::Mat &, sl::Mat &, CUstream); + void updateCameraPose(sl::Transform, sl::POSITIONAL_TRACKING_STATE); - void clearCurrentMesh(); + void updateMap(sl::FusedPointCloud &); + void updateMap(sl::Mesh &); - void exit(); private: // Rendering loop method called each frame by glutDisplayFunc void render(); @@ -111,52 +277,64 @@ class GLViewer { void update(); // Once everything is updated, every renderable objects must be drawn in this method void draw(); + // Clear and refresh inputs' data + void clearInputs(); - void setRenderCameraProjection(sl::CameraParameters params, float znear, float zfar); - cv::Mat get_ocv_img_from_gl_img(GLuint ogl_texture_id); - - void printText(); + static GLViewer* currentInstance_; + // Glut functions callbacks static void drawCallback(); + static void mouseButtonCallback(int button, int state, int x, int y); + static void mouseMotionCallback(int x, int y); static void reshapeCallback(int width, int height); + static void keyPressedCallback(unsigned char c, int x, int y); static void keyReleasedCallback(unsigned char c, int x, int y); static void idle(); - - template - void initPtr(T* ptr); - - std::mutex mtx; bool available; - bool change_state; - std::list sub_maps; // Opengl mesh container - sl::float3 vertices_color; // Defines the color of the mesh - - // OpenGL camera projection matrix - sl::Transform camera_projection; + enum MOUSE_BUTTON { + LEFT = 0, + MIDDLE = 1, + RIGHT = 2, + WHEEL_UP = 3, + WHEEL_DOWN = 4 + }; - sl::Transform pose; - sl::POSITIONAL_TRACKING_STATE tracking_state; - sl::SPATIAL_MAPPING_STATE mapping_state; + enum KEY_STATE { + UP = 'u', + DOWN = 'd', + FREE = 'f' + }; - bool new_chunks; - bool chunks_pushed; - bool ask_clear; - bool draw_mesh; + bool mouseButton_[3]; + int mouseWheelPosition_; + int mouseCurrentPosition_[2]; + int mouseMotion_[2]; + int previousMouseMotion_[2]; + KEY_STATE keyStates_[256]; - sl::Mesh* p_mesh; - sl::FusedPointCloud* p_fpc; - ImageHandler image_handler; - ShaderData shader_obj; + // follow camera + sl::Transform cam_pose; + CameraGL camera_; - uint mWidth=0; - uint mHeight=0; - int svo_position = 0; + ShaderObj shader_mesh; + ShaderObj shader_fpc; + ShaderObj shader; -}; + bool draw_mesh_as_wire; + bool draw_live_point_cloud; + bool dark_background; -/* Find MyDocuments directory for windows platforms.*/ -std::string getDir(); + std::list map_fpc; + std::list map_mesh; -#endif + PointCloud pc_render; + CameraViewer camera_viewer; + + CUstream strm; + + float point_size = 2.f; +}; + +#endif /* __VIEWER_INCLUDE__ */ diff --git a/spatial mapping/spatial mapping/cpp/src/GLViewer.cpp b/spatial mapping/spatial mapping/cpp/src/GLViewer.cpp index 057d407d..aeef646a 100644 --- a/spatial mapping/spatial mapping/cpp/src/GLViewer.cpp +++ b/spatial mapping/spatial mapping/cpp/src/GLViewer.cpp @@ -1,514 +1,536 @@ #include "GLViewer.hpp" -#if defined(_DEBUG) && defined(_WIN32) -#error "This sample should not be built in Debug mode, use RelWithDebInfo if you want to do step by step." -#endif - -#if _WIN32 -#include -#include -#include -#pragma comment(lib, "shell32.lib") -#endif - -#include - -void print(std::string msg_prefix, sl::ERROR_CODE err_code, std::string msg_suffix) { - cout <<"[Sample]"; - if (err_code != sl::ERROR_CODE::SUCCESS) - cout << "[Error] "; - else - cout<<" "; - cout << msg_prefix << " "; - if (err_code != sl::ERROR_CODE::SUCCESS) { - cout << " | " << toString(err_code) << " : "; - cout << toVerbose(err_code); +GLchar* MESH_VERTEX_SHADER = + "#version 330 core\n" + "layout(location = 0) in vec3 in_Vertex;\n" + "layout(location = 1) in vec3 in_Color;\n" + "uniform mat4 u_mvpMatrix;\n" + "out vec3 b_color;\n" + "void main() {\n" + " b_color = in_Color.bgr;\n" + " gl_Position = u_mvpMatrix * vec4(in_Vertex, 1);\n" + "}"; + +GLchar* MESH_FRAGMENT_SHADER = + "#version 330 core\n" + "in vec3 b_color;\n" + "layout(location = 0) out vec4 color;\n" + "void main() {\n" + " color = vec4(b_color, 0.95);\n" + "}"; + +GLchar* POINTCLOUD_VERTEX_SHADER = + "#version 330 core\n" + "layout(location = 0) in vec4 in_VertexRGBA;\n" + "uniform mat4 u_mvpMatrix;\n" + "out vec3 b_color;\n" + "vec4 decomposeFloat(const in float value)\n" + "{\n" + " uint rgbaInt = floatBitsToUint(value);\n" + " uint bIntValue = (rgbaInt / 256U / 256U) % 256U;\n" + " uint gIntValue = (rgbaInt / 256U) % 256U;\n" + " uint rIntValue = (rgbaInt) % 256U; \n" + " return vec4(bIntValue / 255.0f, gIntValue / 255.0f, rIntValue / 255.0f, 1.0); \n" + "}\n" + "void main() {\n" + // Decompose the 4th channel of the XYZRGBA buffer to retrieve the color of the point (1float to 4uint) + " b_color = decomposeFloat(in_VertexRGBA.a).xyz;\n" + " gl_Position = u_mvpMatrix * vec4(in_VertexRGBA.xyz, 1);\n" + "}"; + +GLchar* POINTCLOUD_FRAGMENT_SHADER = + "#version 330 core\n" + "in vec3 b_color;\n" + "layout(location = 0) out vec4 out_Color;\n" + "void main() {\n" + " out_Color = vec4(b_color, 0.9);\n" + "}"; + +GLchar* VERTEX_SHADER_TEXTURE = + "#version 330 core\n" + "layout(location = 0) in vec3 in_Vertex;\n" + "layout(location = 1) in vec2 in_UVs;\n" + "uniform mat4 u_mvpMatrix;\n" + "out vec2 UV;\n" + "void main() {\n" + " gl_Position = u_mvpMatrix * vec4(in_Vertex, 1);\n" + " UV = in_UVs;\n" + "}\n"; + +GLchar* FRAGMENT_SHADER_TEXTURE = + "#version 330 core\n" + "in vec2 UV;\n" + "uniform sampler2D texture_sampler;\n" + "void main() {\n" + " gl_FragColor = vec4(texture(texture_sampler, UV).bgr, 1.0);\n" + "}\n"; + + +using namespace sl; + +GLViewer* GLViewer::currentInstance_ = nullptr; + +GLViewer::GLViewer() : available(false) { + if (currentInstance_ != nullptr) { + delete currentInstance_; } - if (!msg_suffix.empty()) - cout << " " << msg_suffix; - cout << endl; + currentInstance_ = this; + + mouseButton_[0] = mouseButton_[1] = mouseButton_[2] = false; + + clearInputs(); + previousMouseMotion_[0] = previousMouseMotion_[1] = 0; } -GLchar* MESH_VERTEX_SHADER = -"#version 330 core\n" -"layout(location = 0) in vec3 in_Vertex;\n" -"uniform mat4 u_mvpMatrix;\n" -"uniform vec3 u_color;\n" -"out vec3 b_color;\n" -"void main() {\n" -" b_color = u_color;\n" -" gl_Position = u_mvpMatrix * vec4(in_Vertex, 1);\n" -"}"; - -GLchar* FPC_VERTEX_SHADER = -"#version 330 core\n" -"layout(location = 0) in vec4 in_Vertex;\n" -"uniform mat4 u_mvpMatrix;\n" -"uniform vec3 u_color;\n" -"out vec3 b_color;\n" -"void main() {\n" -" b_color = u_color;\n" -" gl_Position = u_mvpMatrix * vec4(in_Vertex.xyz, 1);\n" -"}"; - -GLchar* FRAGMENT_SHADER = -"#version 330 core\n" -"in vec3 b_color;\n" -"layout(location = 0) out vec4 color;\n" -"void main() {\n" -" color = vec4(b_color,1);\n" -"}"; - -GLchar* IMAGE_FRAGMENT_SHADER = -"#version 330 core\n" -" in vec2 UV;\n" -" out vec4 color;\n" -" uniform sampler2D texImage;\n" -" uniform bool revert;\n" -" uniform bool rgbflip;\n" -" void main() {\n" -" vec2 scaler =revert?vec2(UV.x,1.f - UV.y):vec2(UV.x,UV.y);\n" -" vec3 rgbcolor = rgbflip?vec3(texture(texImage, scaler).zyx):vec3(texture(texImage, scaler).xyz);\n" -" color = vec4(rgbcolor,1);\n" -"}"; - -GLchar* IMAGE_VERTEX_SHADER = -"#version 330\n" -"layout(location = 0) in vec3 vert;\n" -"out vec2 UV;" -"void main() {\n" -" UV = (vert.xy+vec2(1,1))/2;\n" -" gl_Position = vec4(vert, 1);\n" -"}\n"; - - -SubMapObj::SubMapObj() { - current_fc = 0; - vaoID_ = 0; +GLViewer::~GLViewer() { } -SubMapObj::~SubMapObj() { - current_fc = 0; - if(vaoID_) { - glDeleteBuffers(2, vboID_); - glDeleteVertexArrays(1, &vaoID_); - } +bool GLViewer::isAvailable() { + glutMainLoopEvent(); + return available; } -template <> -void SubMapObj::update(sl::Chunk &chunk) { - if (vaoID_ == 0) { - glGenVertexArrays(1, &vaoID_); - glGenBuffers(2, vboID_); - } +void GLViewer::exit() { + if (available) + glutLeaveMainLoop(); - glShadeModel(GL_SMOOTH); + available = false; +} - glBindVertexArray(vaoID_); +void GLViewer::init(int argc, char **argv, sl::Mat &image, sl::Mat & pointcloud, CUstream stream) { - glBindBuffer(GL_ARRAY_BUFFER, vboID_[0]); - glBufferData(GL_ARRAY_BUFFER, chunk.vertices.size() * sizeof(sl::float3), &chunk.vertices[0], GL_DYNAMIC_DRAW); - glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, chunk.triangles.size() * sizeof(sl::uint3), &chunk.triangles[0], GL_DYNAMIC_DRAW); - current_fc = (int)chunk.triangles.size() * 3; + glutInit(&argc, argv); - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + int wnd_w = glutGet(GLUT_SCREEN_WIDTH); + int wnd_h = glutGet(GLUT_SCREEN_HEIGHT); + glutInitWindowSize(wnd_w * 0.8, wnd_h * 0.8); + glutInitWindowPosition(wnd_w * 0.1, wnd_h * 0.1); -} + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutCreateWindow("ZED Mapping"); -template <> -void SubMapObj::update(sl::PointCloudChunk &chunk) { - if (vaoID_ == 0) { - glGenVertexArrays(1, &vaoID_); - glGenBuffers(2, vboID_); - } + GLenum err = glewInit(); + if (GLEW_OK != err) + std::cout << "ERROR: glewInit failed: " << glewGetErrorString(err) << "\n"; - glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - const auto nb_v = chunk.vertices.size(); - index.resize(nb_v); - for (int c = 0; c < nb_v; c++) index[c] = c; - - glBindVertexArray(vaoID_); + strm = stream; + + pc_render.initialize(pointcloud); + camera_viewer.initialize(image); - glBindBuffer(GL_ARRAY_BUFFER, vboID_[0]); - glBufferData(GL_ARRAY_BUFFER, chunk.vertices.size() * sizeof(sl::float4), &chunk.vertices[0], GL_DYNAMIC_DRAW); - glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 4, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); + shader.it = Shader((GLchar*) MESH_VERTEX_SHADER, (GLchar*) MESH_FRAGMENT_SHADER); + shader.MVPM = glGetUniformLocation(shader.it.getProgramId(), "u_mvpMatrix"); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.size() * sizeof(sl::uint1), &index[0], GL_DYNAMIC_DRAW); - current_fc = (int)index.size(); - - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} + shader_mesh.it = Shader((GLchar*) MESH_VERTEX_SHADER, (GLchar*) MESH_FRAGMENT_SHADER); + shader_mesh.MVPM = glGetUniformLocation(shader_mesh.it.getProgramId(), "u_mvpMatrix"); -void SubMapObj::draw() { - if(current_fc && vaoID_) { - glBindVertexArray(vaoID_); - glDrawElements(index.size() ? GL_POINTS : GL_TRIANGLES, (GLsizei) current_fc, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - } -} + shader_fpc.it = Shader((GLchar*) POINTCLOUD_VERTEX_SHADER, (GLchar*) POINTCLOUD_FRAGMENT_SHADER); + shader_fpc.MVPM = glGetUniformLocation(shader_fpc.it.getProgramId(), "u_mvpMatrix"); -GLViewer* currentInstance_ = nullptr; + camera_ = CameraGL(sl::Translation(0, 2, 2.000), sl::Translation(0, 0, -0.1)); + sl::Rotation rot; + rot.setEulerAngles(sl::float3(-45,0,0), false); + camera_.setRotation(rot); -GLViewer::GLViewer() :available(false) { - currentInstance_ = this; - pose.setIdentity(); - tracking_state = sl::POSITIONAL_TRACKING_STATE::OFF; - mapping_state = sl::SPATIAL_MAPPING_STATE::NOT_ENABLED; - change_state = false; - new_chunks = chunks_pushed = false; + draw_mesh_as_wire = false; + draw_live_point_cloud = true; + dark_background = true; + + // Map glut function on this class methods + glutDisplayFunc(GLViewer::drawCallback); + glutMouseFunc(GLViewer::mouseButtonCallback); + glutMotionFunc(GLViewer::mouseMotionCallback); + glutReshapeFunc(GLViewer::reshapeCallback); + glutKeyboardFunc(GLViewer::keyPressedCallback); + glutKeyboardUpFunc(GLViewer::keyReleasedCallback); + + available = true; } -GLViewer::~GLViewer() {} +void GLViewer::render() { + if (available) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if(dark_background) + glClearColor(59 / 255.f, 63 / 255.f, 69 / 255.f, 1.0f); + else + glClearColor(211 / 255.f, 220 / 255.f, 232 / 255.f, 1.0f); -bool cudaSafeCall(cudaError_t err) { - if(err != cudaSuccess) { - printf("Cuda error [%d]: %s.\n", err, cudaGetErrorString(err)); - return false; + update(); + draw(); + glutSwapBuffers(); + glutPostRedisplay(); } - return true; } -void GLViewer::exit() { - if(available) { - image_handler.close(); - } - available = false; +void GLViewer::updateCameraPose(sl::Transform p, sl::POSITIONAL_TRACKING_STATE state_) { + cam_pose = p; + pc_render.pushNewPC(strm); + camera_viewer.pushNewImage(strm); } -bool GLViewer::isAvailable() { - if(available) - glutMainLoopEvent(); - return available; +void GLViewer::updateMap(sl::FusedPointCloud &fpc){ + map_fpc.resize(fpc.chunks.size()); + int c_id = 0; + for (auto& it : map_fpc) { + auto& chunk = fpc.chunks[c_id++]; + if (chunk.has_been_updated) + it.add(chunk.vertices); + } } -void CloseFunc(void) { if(currentInstance_) currentInstance_->exit(); } +void GLViewer::updateMap(sl::Mesh &mesh) { + map_mesh.resize(mesh.chunks.size()); + int c_id = 0; + for (auto& it : map_mesh) { + auto& chunk = mesh.chunks[c_id++]; + if (chunk.has_been_updated) + it.add(chunk.vertices, chunk.triangles, chunk.colors); + } +} +void GLViewer::update() { -template<> -void GLViewer::initPtr(sl::Mesh* ptr) { - p_mesh = ptr; - draw_mesh = true; -} + if (keyStates_['q'] == KEY_STATE::UP || keyStates_['Q'] == KEY_STATE::UP || keyStates_[27] == KEY_STATE::UP) { + currentInstance_->exit(); + return; + } -template<> -void GLViewer::initPtr(sl::FusedPointCloud* ptr) { - p_fpc = ptr; - draw_mesh = false; -} + if (keyStates_['o'] == KEY_STATE::UP || keyStates_['O'] == KEY_STATE::UP) + point_size = point_size - 0.2; -template -bool GLViewer::init(int argc, char **argv, sl::CameraParameters camLeft, T *ptr) { + if (keyStates_['p'] == KEY_STATE::UP || keyStates_['P'] == KEY_STATE::UP) + point_size = point_size + 0.2; + + if (keyStates_['w'] == KEY_STATE::UP || keyStates_['W'] == KEY_STATE::UP) + draw_mesh_as_wire = !draw_mesh_as_wire; + + if (keyStates_['l'] == KEY_STATE::UP || keyStates_['L'] == KEY_STATE::UP) + draw_live_point_cloud = !draw_live_point_cloud; + + if (keyStates_['d'] == KEY_STATE::UP || keyStates_['D'] == KEY_STATE::UP) + dark_background = !dark_background; + + // Rotate camera with mouse + if (mouseButton_[MOUSE_BUTTON::LEFT]) { + camera_.rotate(sl::Rotation((float) mouseMotion_[1] * MOUSE_R_SENSITIVITY, camera_.getRight())); + camera_.rotate(sl::Rotation((float) mouseMotion_[0] * MOUSE_R_SENSITIVITY, camera_.getVertical() * -1.f)); + } - glutInit(&argc, argv); - int wnd_w = glutGet(GLUT_SCREEN_WIDTH); - int wnd_h = glutGet(GLUT_SCREEN_HEIGHT); - int width = wnd_w * 0.9; - int height = wnd_h * 0.9; - if (width > camLeft.image_size.width && height > camLeft.image_size.height) { - width = camLeft.image_size.width; - height = camLeft.image_size.height; + // Translate camera with mouse + if (mouseButton_[MOUSE_BUTTON::RIGHT]) { + camera_.translate(camera_.getUp() * (float) mouseMotion_[1] * MOUSE_T_SENSITIVITY); + camera_.translate(camera_.getRight() * (float) mouseMotion_[0] * MOUSE_T_SENSITIVITY); } + + // Zoom in with mouse wheel + if (mouseWheelPosition_ != 0) { + if (mouseWheelPosition_ > 0 /* && distance > camera_.getZNear()*/) // zoom + camera_.translate(camera_.getForward() * MOUSE_UZ_SENSITIVITY * -1); - mWidth = width; - mHeight = height; + else if (/*distance < camera_.getZFar()*/ mouseWheelPosition_ < 0) // unzoom + camera_.translate(camera_.getForward() * MOUSE_UZ_SENSITIVITY); + } + for (auto &it : map_mesh) + it.pushToGPU(); + for (auto& it : map_fpc) + it.pushToGPU(); - glutInitWindowSize(width, height); - glutInitWindowPosition(wnd_w * 0.05, wnd_h * 0.05); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); - glutCreateWindow("ZED Spatial Mapping Viewer"); - glViewport(0, 0, width, height); + //pointCloud_.mutexData.unlock(); + camera_.update(); + clearInputs(); +} - GLenum err = glewInit(); - if (GLEW_OK != err) - std::cout << "ERROR: glewInit failed: " << glewGetErrorString(err) << "\n"; +void GLViewer::draw() { + sl::Transform vpMatrix = camera_.getViewProjectionMatrix(); - glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); + glPolygonMode(GL_FRONT, GL_LINE); + glPolygonMode(GL_BACK, GL_LINE); + glLineWidth(2.f); + glPointSize(point_size); - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glUseProgram(shader.it.getProgramId()); - bool status_ = image_handler.initialize(camLeft.image_size); - if (!status_) - std::cout << "ERROR: Failed to initialized Image Renderer" << std::endl; + sl::Transform pose_ = vpMatrix * cam_pose; + glUniformMatrix4fv(shader.MVPM, 1, GL_FALSE, sl::Transform::transpose(pose_).m); + camera_viewer.frustum.draw(); + glUseProgram(0); - initPtr(ptr); + if(map_fpc.size()){ + glUseProgram(shader_fpc.it.getProgramId()); + glUniformMatrix4fv(shader_fpc.MVPM, 1, GL_FALSE, sl::Transform::transpose(vpMatrix).m); + for (auto &it: map_fpc) + it.draw(); + glUseProgram(0); + } - // Create GLSL Shaders for Mesh and Image - if(draw_mesh) - shader_obj.it = Shader(MESH_VERTEX_SHADER, FRAGMENT_SHADER); - else - shader_obj.it = Shader(FPC_VERTEX_SHADER, FRAGMENT_SHADER); - shader_obj.MVP_Mat = glGetUniformLocation(shader_obj.it.getProgramId(), "u_mvpMatrix"); - shader_obj.shColorLoc = glGetUniformLocation(shader_obj.it.getProgramId(), "u_color"); + if(map_mesh.size()){ + glUseProgram(shader_mesh.it.getProgramId()); + glUniformMatrix4fv(shader_mesh.MVPM, 1, GL_FALSE, sl::Transform::transpose(vpMatrix).m); + for (auto &it: map_mesh) + it.draw(draw_mesh_as_wire); + glUseProgram(0); + } - // Create the rendering camera - setRenderCameraProjection(camLeft, 0.5f, 20); + if(draw_live_point_cloud) + pc_render.draw(pose_); + camera_viewer.draw(pose_); +} - glLineWidth(1.f); - glPointSize(4.f); +void GLViewer::clearInputs() { + mouseMotion_[0] = mouseMotion_[1] = 0; + mouseWheelPosition_ = 0; + for (unsigned int i = 0; i < 256; ++i) + if (keyStates_[i] != KEY_STATE::DOWN) + keyStates_[i] = KEY_STATE::FREE; +} - // Set glut callback before start - glutDisplayFunc(GLViewer::drawCallback); - glutReshapeFunc(GLViewer::reshapeCallback); - glutKeyboardUpFunc(GLViewer::keyReleasedCallback); - glutCloseFunc(CloseFunc); +void GLViewer::drawCallback() { + currentInstance_->render(); +} - ask_clear = false; - available = true; - - // Color of wireframe (soft blue) - vertices_color.r = 0.35f; - vertices_color.g = 0.65f; - vertices_color.b = 0.95f; - - // ready to start - chunks_pushed = true; - - return false; -} - -void GLViewer::setRenderCameraProjection(sl::CameraParameters params, float znear, float zfar) { - // Just slightly up the ZED camera FOV to make a small black border - float fov_y = (params.v_fov + 0.5f) * M_PI / 180.f; - float fov_x = (params.h_fov + 0.5f) * M_PI / 180.f; - - camera_projection(0, 0) = 1.0f / tanf(fov_x * 0.5f); - camera_projection(1, 1) = 1.0f / tanf(fov_y * 0.5f); - camera_projection(2, 2) = -(zfar + znear) / (zfar - znear); - camera_projection(3, 2) = -1; - camera_projection(2, 3) = -(2.f * zfar * znear) / (zfar - znear); - camera_projection(3, 3) = 0; - - camera_projection(0, 0) = 1.0f / tanf(fov_x * 0.5f); //Horizontal FoV. - camera_projection(0, 1) = 0; - camera_projection(0, 2) = 2.0f * ((params.image_size.width - 1.0f * params.cx) / params.image_size.width) - 1.0f; //Horizontal offset. - camera_projection(0, 3) = 0; - - camera_projection(1, 0) = 0; - camera_projection(1, 1) = 1.0f / tanf(fov_y * 0.5f); //Vertical FoV. - camera_projection(1, 2) = -(2.0f * ((params.image_size.height - 1.0f * params.cy) / params.image_size.height) - 1.0f); //Vertical offset. - camera_projection(1, 3) = 0; - - camera_projection(2, 0) = 0; - camera_projection(2, 1) = 0; - camera_projection(2, 2) = -(zfar + znear) / (zfar - znear); //Near and far planes. - camera_projection(2, 3) = -(2.0f * zfar * znear) / (zfar - znear); //Near and far planes. - - camera_projection(3, 0) = 0; - camera_projection(3, 1) = 0; - camera_projection(3, 2) = -1; - camera_projection(3, 3) = 0.0f; -} - -void printGL(float x, float y, const char *string) { - glRasterPos2f(x, y); - int len = (int) strlen(string); - for(int i = 0; i < len; i++) { - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, string[i]); +void GLViewer::mouseButtonCallback(int button, int state, int x, int y) { + if (button < 5) { + if (button < 3) { + currentInstance_->mouseButton_[button] = state == GLUT_DOWN; + } else { + currentInstance_->mouseWheelPosition_ += button == MOUSE_BUTTON::WHEEL_UP ? 1 : -1; + } + currentInstance_->mouseCurrentPosition_[0] = x; + currentInstance_->mouseCurrentPosition_[1] = y; + currentInstance_->previousMouseMotion_[0] = x; + currentInstance_->previousMouseMotion_[1] = y; } } +void GLViewer::mouseMotionCallback(int x, int y) { + currentInstance_->mouseMotion_[0] = x - currentInstance_->previousMouseMotion_[0]; + currentInstance_->mouseMotion_[1] = y - currentInstance_->previousMouseMotion_[1]; + currentInstance_->previousMouseMotion_[0] = x; + currentInstance_->previousMouseMotion_[1] = y; + glutPostRedisplay(); +} + void GLViewer::reshapeCallback(int width, int height) { glViewport(0, 0, width, height); } -void GLViewer::drawCallback() { - currentInstance_->render(); +void GLViewer::keyPressedCallback(unsigned char c, int x, int y) { + currentInstance_->keyStates_[c] = KEY_STATE::DOWN; + glutPostRedisplay(); +} + +void GLViewer::keyReleasedCallback(unsigned char c, int x, int y) { + currentInstance_->keyStates_[c] = KEY_STATE::UP; } void GLViewer::idle() { glutPostRedisplay(); } -void GLViewer::keyReleasedCallback(unsigned char c, int x, int y) { - // space bar means change spatial mapping state - currentInstance_->change_state = (c == 32); - - // Esc or Q hit means exit - if((c == 'q') || (c == 'Q') || (c == 27)) - currentInstance_->exit(); +Simple3DObject::Simple3DObject() { + vaoID_ = 0; + drawingType_ = GL_TRIANGLES; + isStatic_ = need_update = false; } -bool GLViewer::updateImageAndState(sl::Mat &im, sl::Transform &pose_, sl::POSITIONAL_TRACKING_STATE track_state, sl::SPATIAL_MAPPING_STATE mapp_state) { - if(mtx.try_lock()) { - if(available) { - image_handler.pushNewImage(im); - pose = pose_; - tracking_state = track_state; - mapping_state = mapp_state; - svo_position++; - } - mtx.unlock(); +Simple3DObject::~Simple3DObject() { + clear(); + if (vaoID_ != 0) { + glDeleteBuffers(3, vboID_); + glDeleteVertexArrays(1, &vaoID_); } - - bool cpy_state = change_state; - change_state = false; - return cpy_state; } -void GLViewer::clearCurrentMesh() { - ask_clear = true; - new_chunks = true; +void Simple3DObject::addPoint(sl::float3 pt, sl::float3 clr){ + vertices_.push_back(pt); + colors_.push_back(clr); + indices_.push_back((int) indices_.size()); + need_update = true; +} +void Simple3DObject::addFace(sl::float3 p1, sl::float3 p2, sl::float3 p3, sl::float3 clr){ + addPoint(p1, clr); + addPoint(p2, clr); + addPoint(p3, clr); } -void GLViewer::render() { - if(available) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glClearColor(0, 0, 0, 1.f); - mtx.lock(); - update(); - draw(); - //printText(); -#if 0 - cv::Mat img = get_ocv_img_from_gl_img(0); - ostringstream filename1; - filename1 << "./left" << setfill('0') << setw(6) << svo_position << ".png"; - cv::imwrite(filename1.str(), img); -#endif +void Simple3DObject::pushToGPU() { + if(!need_update) return; + if (!isStatic_ || vaoID_ == 0) { + if (vaoID_ == 0) { + glGenVertexArrays(1, &vaoID_); + glGenBuffers(3, vboID_); + } + glBindVertexArray(vaoID_); + glBindBuffer(GL_ARRAY_BUFFER, vboID_[0]); + glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(sl::float3), &vertices_[0], isStatic_ ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); + glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); - mtx.unlock(); - glutSwapBuffers(); - glutPostRedisplay(); + glBindBuffer(GL_ARRAY_BUFFER, vboID_[1]); + glBufferData(GL_ARRAY_BUFFER, colors_.size() * sizeof(sl::float3), &colors_[0], isStatic_ ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); + glVertexAttribPointer(Shader::ATTRIB_COLOR_POS, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_COLOR_POS); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[2]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_.size() * sizeof (unsigned int), &indices_[0], isStatic_ ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); + + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + need_update = false; } } -cv::Mat GLViewer::get_ocv_img_from_gl_img(GLuint ogl_texture_id) -{ +void Simple3DObject::clear() { + vertices_.clear(); + colors_.clear(); + indices_.clear(); +} - GLenum gl_texture_width = glutGet(GLUT_WINDOW_WIDTH); - GLenum gl_texture_height = glutGet(GLUT_WINDOW_HEIGHT); +void Simple3DObject::setDrawingType(GLenum type) { + drawingType_ = type; +} - std::cout<<" Size : "<&pts) { + clear(); + vertices_ = pts; + for (int i = 0; i < vertices_.size(); i++) + indices_.push_back(i); + need_update = true; +} - if (ask_clear) { - sub_maps.clear(); - ask_clear = false; - } +void FpcObj::pushToGPU() { + if (!need_update) return; - int nb_c = 0; - if(draw_mesh) - nb_c = p_mesh->chunks.size(); - else - nb_c = p_fpc->chunks.size(); + if (vaoID_ == 0) { + glGenVertexArrays(1, &vaoID_); + glGenBuffers(2, vboID_); + } + glBindVertexArray(vaoID_); + glBindBuffer(GL_ARRAY_BUFFER, vboID_[0]); + glBufferData(GL_ARRAY_BUFFER, vertices_.size() * 4 * sizeof (float), &vertices_[0], GL_DYNAMIC_DRAW); + glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 4, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); - if (nb_c > sub_maps.size()) { - const float step = 500.f; - size_t new_size = ((nb_c / step) + 1) * step; - sub_maps.resize(new_size); - } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_.size() * sizeof (unsigned int), &indices_[0], GL_DYNAMIC_DRAW); + nb_v = indices_.size(); + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + need_update = false; +} - if (draw_mesh) { - int c = 0; - for (auto& it : sub_maps) { - if ((c < nb_c) && p_mesh->chunks[c].has_been_updated) - it.update(p_mesh->chunks[c]); - c++; - } - } else { - int c = 0; - for (auto& it : sub_maps) { - if ((c < nb_c) && p_fpc->chunks[c].has_been_updated) - it.update(p_fpc->chunks[c]); - c++; - } - } - new_chunks = false; - chunks_pushed = true; +void FpcObj::clear() { + vertices_.clear(); + indices_.clear(); + nb_v = 0; +} + +void FpcObj::draw() { + if (nb_v && vaoID_) { + glBindVertexArray(vaoID_); + glDrawElements(GL_POINTS, (GLsizei) nb_v, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); } } +// ____________ -void GLViewer::printText() { - if(available) { - // Show actions - if(mapping_state == sl::SPATIAL_MAPPING_STATE::NOT_ENABLED) { - glColor3f(0.15f, 0.15f, 0.15f); - printGL(-0.99f, 0.9f, "Hit Space Bar to activate Spatial Mapping."); - } else { - glColor3f(0.25f, 0.25f, 0.25f); - printGL(-0.99f, 0.9f, "Hit Space Bar to stop spatial mapping."); - } +MeshObject::MeshObject() { + current_fc = 0; + vaoID_ = 0; + need_update = false; +} - std::string positional_tracking_state_str("POSITIONAL TRACKING STATE : "); - std::string spatial_mapping_state_str("SPATIAL MAPPING STATE : "); - std::string state_str; - // Show mapping state - if ((tracking_state == sl::POSITIONAL_TRACKING_STATE::OK)) { - if(mapping_state == sl::SPATIAL_MAPPING_STATE::OK || mapping_state == sl::SPATIAL_MAPPING_STATE::INITIALIZING) - glColor3f(0.25f, 0.99f, 0.25f); - else if(mapping_state == sl::SPATIAL_MAPPING_STATE::NOT_ENABLED) - glColor3f(0.55f, 0.65f, 0.55f); - else - glColor3f(0.95f, 0.25f, 0.25f); - state_str = spatial_mapping_state_str + sl::toString(mapping_state).c_str(); - } else { - if(mapping_state != sl::SPATIAL_MAPPING_STATE::NOT_ENABLED) { - glColor3f(0.95f, 0.25f, 0.25f); - state_str = positional_tracking_state_str + sl::toString(tracking_state).c_str(); - } else { - glColor3f(0.55f, 0.65f, 0.55f); - state_str = spatial_mapping_state_str + sl::toString(sl::SPATIAL_MAPPING_STATE::NOT_ENABLED).c_str(); - } - } - printGL(-0.99f, 0.83f, state_str.c_str()); +MeshObject::~MeshObject() { +} + +void MeshObject::add(std::vector &vertices, std::vector &triangles, std::vector &colors) { + vert = vertices; + clr = colors; + faces = triangles; + need_update = true; +} + +void MeshObject::pushToGPU() { + if (!need_update) return; + if (faces.empty()) return; + + if (vaoID_ == 0) { + glGenVertexArrays(1, &vaoID_); + glGenBuffers(3, vboID_); } + + glBindVertexArray(vaoID_); + + glBindBuffer(GL_ARRAY_BUFFER, vboID_[0]); + glBufferData(GL_ARRAY_BUFFER, vert.size() * sizeof (vert[0]), &vert[0], GL_DYNAMIC_DRAW); + glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); + + glBindBuffer(GL_ARRAY_BUFFER, vboID_[1]); + glBufferData(GL_ARRAY_BUFFER, clr.size() * sizeof (clr[0]), &clr[0], GL_DYNAMIC_DRAW); + glVertexAttribPointer(Shader::ATTRIB_COLOR_POS, 3, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_COLOR_POS); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[2]); + current_fc = faces.size() * sizeof (faces[0]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, current_fc, &faces[0], GL_DYNAMIC_DRAW); + + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + need_update = false; } -void GLViewer::draw() { - if(available) { - image_handler.draw(); - - // If the Positional tracking is good, we can draw the mesh over the current image - if ((tracking_state == sl::POSITIONAL_TRACKING_STATE::OK) && sub_maps.size()) { - // Draw the mesh in GL_TRIANGLES with a polygon mode in line (wire) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - // Send the projection and the Pose to the GLSL shader to make the projection of the 2D image. - sl::Transform vpMatrix = camera_projection * sl::Transform::inverse(pose); - glUseProgram(shader_obj.it.getProgramId()); - glUniformMatrix4fv(shader_obj.MVP_Mat, 1, GL_TRUE, vpMatrix.m); - glUniform3fv(shader_obj.shColorLoc, 1, vertices_color.v); - - for (auto &it: sub_maps) - it.draw(); - glUseProgram(0); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } +void MeshObject::draw(bool draw_wire) { + if ((current_fc > 0) && (vaoID_ != 0)) { + auto type = draw_wire ? GL_LINE : GL_FILL; + glPolygonMode(GL_FRONT, type); + glPolygonMode(GL_BACK, type); + + glBindVertexArray(vaoID_); + glDrawElements(GL_TRIANGLES, (GLsizei) current_fc, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); } } Shader::Shader(GLchar* vs, GLchar* fs) { - if(!compile(verterxId_, GL_VERTEX_SHADER, vs)) { + if (!compile(verterxId_, GL_VERTEX_SHADER, vs)) { std::cout << "ERROR: while compiling vertex shader" << std::endl; } - if(!compile(fragmentId_, GL_FRAGMENT_SHADER, fs)) { + if (!compile(fragmentId_, GL_FRAGMENT_SHADER, fs)) { std::cout << "ERROR: while compiling fragment shader" << std::endl; } @@ -518,12 +540,13 @@ Shader::Shader(GLchar* vs, GLchar* fs) { glAttachShader(programId_, fragmentId_); glBindAttribLocation(programId_, ATTRIB_VERTICES_POS, "in_vertex"); + glBindAttribLocation(programId_, ATTRIB_COLOR_POS, "in_Color"); glLinkProgram(programId_); GLint errorlk(0); glGetProgramiv(programId_, GL_LINK_STATUS, &errorlk); - if(errorlk != GL_TRUE) { + if (errorlk != GL_TRUE) { std::cout << "ERROR: while linking Shader :" << std::endl; GLint errorSize(0); glGetProgramiv(programId_, GL_INFO_LOG_LENGTH, &errorSize); @@ -539,11 +562,11 @@ Shader::Shader(GLchar* vs, GLchar* fs) { } Shader::~Shader() { - if(verterxId_ != 0) + if (verterxId_ != 0) glDeleteShader(verterxId_); - if(fragmentId_ != 0) + if (fragmentId_ != 0) glDeleteShader(fragmentId_); - if(programId_ != 0) + if (programId_ != 0) glDeleteShader(programId_); } @@ -553,7 +576,7 @@ GLuint Shader::getProgramId() { bool Shader::compile(GLuint &shaderId, GLenum type, GLchar* src) { shaderId = glCreateShader(type); - if(shaderId == 0) { + if (shaderId == 0) { std::cout << "ERROR: shader type (" << type << ") does not exist" << std::endl; return false; } @@ -562,7 +585,7 @@ bool Shader::compile(GLuint &shaderId, GLenum type, GLchar* src) { GLint errorCp(0); glGetShaderiv(shaderId, GL_COMPILE_STATUS, &errorCp); - if(errorCp != GL_TRUE) { + if (errorCp != GL_TRUE) { std::cout << "ERROR: while compiling Shader :" << std::endl; GLint errorSize(0); glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &errorSize); @@ -579,82 +602,353 @@ bool Shader::compile(GLuint &shaderId, GLenum type, GLchar* src) { return true; } -std::string getDir() { - std::string myDir; -#if _WIN32 - CHAR my_documents[MAX_PATH]; - HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, my_documents); - if(result == S_OK) - myDir = std::string(my_documents) + '/'; -#else - myDir = "./"; -#endif - return myDir; +PointCloud::PointCloud() { + +} + +PointCloud::~PointCloud() { + close(); } -template bool GLViewer::init(int argc, char** argv, sl::CameraParameters camLeft, sl::FusedPointCloud* ptr); -template bool GLViewer::init(int argc, char** argv, sl::CameraParameters camLeft, sl::Mesh* ptr); +void PointCloud::close() { + if (refMat.isInit()) { + auto err = cudaGraphicsUnmapResources(1, &bufferCudaID_, 0); + if (err != cudaSuccess) + std::cerr << "Error: CUDA UnmapResources (" << err << ")" << std::endl; + glDeleteBuffers(1, &bufferGLID_); + } +} -ImageHandler::ImageHandler() {} +void PointCloud::initialize(sl::Mat &ref) { + refMat = ref; -ImageHandler::~ImageHandler() { - close(); + glGenBuffers(1, &bufferGLID_); + glBindBuffer(GL_ARRAY_BUFFER, bufferGLID_); + glBufferData(GL_ARRAY_BUFFER, refMat.getResolution().area() * 4 * sizeof (float), 0, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + cudaError_t err = cudaGraphicsGLRegisterBuffer(&bufferCudaID_, bufferGLID_, cudaGraphicsRegisterFlagsNone); + if (err != cudaSuccess) + std::cerr << "Error: CUDA - OpenGL Interop failed (" << err << ")" << std::endl; + + err = cudaGraphicsMapResources(1, &bufferCudaID_, 0); + if (err != cudaSuccess) + std::cerr << "Error: CUDA MapResources (" << err << ")" << std::endl; + + err = cudaGraphicsResourceGetMappedPointer((void**) &xyzrgbaMappedBuf_, &numBytes_, bufferCudaID_); + if (err != cudaSuccess) + std::cerr << "Error: CUDA GetMappedPointer (" << err << ")" << std::endl; + + shader_ = Shader(POINTCLOUD_VERTEX_SHADER, POINTCLOUD_FRAGMENT_SHADER); + shMVPMatrixLoc_ = glGetUniformLocation(shader_.getProgramId(), "u_mvpMatrix"); } -void ImageHandler::close() { - glDeleteTextures(1, &imageTex); +void PointCloud::pushNewPC(CUstream strm) { + if (refMat.isInit()) + cudaMemcpyAsync(xyzrgbaMappedBuf_, refMat.getPtr(sl::MEM::GPU), numBytes_, cudaMemcpyDeviceToDevice, strm); } -bool ImageHandler::initialize(sl::Resolution res) { - shader.it = Shader(IMAGE_VERTEX_SHADER, IMAGE_FRAGMENT_SHADER); - texID = glGetUniformLocation(shader.it.getProgramId(), "texImage"); - static const GLfloat g_quad_vertex_buffer_data[] = { - -1.0f, -1.0f, 0.0f, - 1.0f, -1.0f, 0.0f, - -1.0f, 1.0f, 0.0f, - -1.0f, 1.0f, 0.0f, - 1.0f, -1.0f, 0.0f, - 1.0f, 1.0f, 0.0f }; +void PointCloud::draw(const sl::Transform& vp) { + if (refMat.isInit()) { + glUseProgram(shader_.getProgramId()); + glUniformMatrix4fv(shMVPMatrixLoc_, 1, GL_TRUE, vp.m); - glGenBuffers(1, &quad_vb); - glBindBuffer(GL_ARRAY_BUFFER, quad_vb); - glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, bufferGLID_); + glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 4, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); + + glDrawArrays(GL_POINTS, 0, refMat.getResolution().area()); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); + } +} + +const sl::Translation CameraGL::ORIGINAL_FORWARD = sl::Translation(0, 0, 1); +const sl::Translation CameraGL::ORIGINAL_UP = sl::Translation(0, 1, 0); +const sl::Translation CameraGL::ORIGINAL_RIGHT = sl::Translation(1, 0, 0); + +CameraGL::CameraGL(Translation position, Translation direction, Translation vertical) { + this->position_ = position; + setDirection(direction, vertical); + + offset_ = sl::Translation(0, 0, 0); + view_.setIdentity(); + updateView(); + setProjection(90, 90, 0.5f, 50.f); + updateVPMatrix(); +} + +CameraGL::~CameraGL() { +} + +void CameraGL::update() { + if (sl::Translation::dot(vertical_, up_) < 0) + vertical_ = vertical_ * -1.f; + updateView(); + updateVPMatrix(); +} + +void CameraGL::setProjection(float horizontalFOV, float verticalFOV, float znear, float zfar) { + horizontalFieldOfView_ = horizontalFOV; + verticalFieldOfView_ = verticalFOV; + znear_ = znear; + zfar_ = zfar; + + float fov_y = verticalFOV * M_PI / 180.f; + float fov_x = horizontalFOV * M_PI / 180.f; + + projection_.setIdentity(); + projection_(0, 0) = 1.0f / tanf(fov_x * 0.5f); + projection_(1, 1) = 1.0f / tanf(fov_y * 0.5f); + projection_(2, 2) = -(zfar + znear) / (zfar - znear); + projection_(3, 2) = -1; + projection_(2, 3) = -(2.f * zfar * znear) / (zfar - znear); + projection_(3, 3) = 0; + updateVPMatrix(); +} + +const sl::Transform& CameraGL::getViewProjectionMatrix() const { + return vpMatrix_; +} + +float CameraGL::getHorizontalFOV() const { + return horizontalFieldOfView_; +} + +float CameraGL::getVerticalFOV() const { + return verticalFieldOfView_; +} + +void CameraGL::setOffsetFromPosition(const sl::Translation& o) { + offset_ = o; +} + +const sl::Translation& CameraGL::getOffsetFromPosition() const { + return offset_; +} + +void CameraGL::setDirection(const sl::Translation& direction, const sl::Translation& vertical) { + sl::Translation dirNormalized = direction; + dirNormalized.normalize(); + this->rotation_ = sl::Orientation(ORIGINAL_FORWARD, dirNormalized * -1.f); + updateVectors(); + this->vertical_ = vertical; + if (sl::Translation::dot(vertical_, up_) < 0) + rotate(sl::Rotation(M_PI, ORIGINAL_FORWARD)); +} + +void CameraGL::translate(const sl::Translation& t) { + position_ = position_ + t; +} + +void CameraGL::setPosition(const sl::Translation& p) { + position_ = p; +} + +void CameraGL::rotate(const sl::Orientation& rot) { + rotation_ = rot * rotation_; + updateVectors(); +} + +void CameraGL::rotate(const sl::Rotation& m) { + this->rotate(sl::Orientation(m)); +} + +void CameraGL::setRotation(const sl::Orientation& rot) { + rotation_ = rot; + updateVectors(); +} + +void CameraGL::setRotation(const sl::Rotation& m) { + this->setRotation(sl::Orientation(m)); +} + +const sl::Translation& CameraGL::getPosition() const { + return position_; +} + +const sl::Translation& CameraGL::getForward() const { + return forward_; +} + +const sl::Translation& CameraGL::getRight() const { + return right_; +} + +const sl::Translation& CameraGL::getUp() const { + return up_; +} + +const sl::Translation& CameraGL::getVertical() const { + return vertical_; +} + +float CameraGL::getZNear() const { + return znear_; +} + +float CameraGL::getZFar() const { + return zfar_; +} + +void CameraGL::updateVectors() { + forward_ = ORIGINAL_FORWARD * rotation_; + up_ = ORIGINAL_UP * rotation_; + right_ = sl::Translation(ORIGINAL_RIGHT * -1.f) * rotation_; +} + +void CameraGL::updateView() { + sl::Transform transformation(rotation_, (offset_ * rotation_) + position_); + view_ = sl::Transform::inverse(transformation); +} + +void CameraGL::updateVPMatrix() { + vpMatrix_ = projection_ * view_; +} + +CameraViewer::CameraViewer() { + +} + +CameraViewer::~CameraViewer() { + close(); +} + +void CameraViewer::close() { + if (ref.isInit()) { + + auto err = cudaGraphicsUnmapResources(1, &cuda_gl_ressource, 0); + if (err) std::cout << "err 3 " << err << " " << cudaGetErrorString(err) << "\n"; + + glDeleteTextures(1, &texture); + glDeleteBuffers(3, vboID_); + glDeleteVertexArrays(1, &vaoID_); + } +} + +bool CameraViewer::initialize(sl::Mat &im) { + + // Create 3D axis + float fx,fy,cx,cy; + fx = fy = 1400; + float width, height; + width = 2208; + height = 1242; + cx = width /2; + cy = height /2; + + float Z_ = .5f; + sl::float3 toOGL(1,-1,-1); + sl::float3 cam_0(0, 0, 0); + sl::float3 cam_1, cam_2, cam_3, cam_4; + + float fx_ = 1.f / fx; + float fy_ = 1.f / fy; + + cam_1.z = Z_; + cam_1.x = (0 - cx) * Z_ *fx_; + cam_1.y = (0 - cy) * Z_ *fy_ ; + cam_1 *= toOGL; + + cam_2.z = Z_; + cam_2.x = (width - cx) * Z_ *fx_; + cam_2.y = (0 - cy) * Z_ *fy_; + cam_2 *= toOGL; + + cam_3.z = Z_; + cam_3.x = (width - cx) * Z_ *fx_; + cam_3.y = (height - cy) * Z_ *fy_; + cam_3 *= toOGL; + + cam_4.z = Z_; + cam_4.x = (0 - cx) * Z_ *fx_; + cam_4.y = (height - cy) * Z_ *fy_; + cam_4 *= toOGL; + + sl::float3 clr(0.1,0.5,0.7); + + frustum.addFace(cam_0, cam_1, cam_2, clr); + frustum.addFace(cam_0, cam_2, cam_3, clr); + frustum.addFace(cam_0, cam_3, cam_4, clr); + frustum.addFace(cam_0, cam_4, cam_1, clr); + frustum.setDrawingType(GL_TRIANGLES); + frustum.pushToGPU(); + + vert.push_back(cam_1); + vert.push_back(cam_2); + vert.push_back(cam_3); + vert.push_back(cam_4); + + uv.push_back(sl::float2(0,0)); + uv.push_back(sl::float2(1,0)); + uv.push_back(sl::float2(1,1)); + uv.push_back(sl::float2(0,1)); + + faces.push_back(sl::uint3(0,1,2)); + faces.push_back(sl::uint3(0,2,3)); + + ref = im; + shader = Shader(VERTEX_SHADER_TEXTURE, FRAGMENT_SHADER_TEXTURE); + shMVPMatrixLocTex_ = glGetUniformLocation(shader.getProgramId(), "u_mvpMatrix"); + + glGenVertexArrays(1, &vaoID_); + glGenBuffers(3, vboID_); + + glBindVertexArray(vaoID_); + glBindBuffer(GL_ARRAY_BUFFER, vboID_[0]); + glBufferData(GL_ARRAY_BUFFER, vert.size() * sizeof(sl::float3), &vert[0], GL_DYNAMIC_DRAW); + glVertexAttribPointer(Shader::ATTRIB_VERTICES_POS, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_VERTICES_POS); + + glBindBuffer(GL_ARRAY_BUFFER, vboID_[1]); + glBufferData(GL_ARRAY_BUFFER, uv.size() * sizeof(sl::float2), &uv[0], GL_DYNAMIC_DRAW); + glVertexAttribPointer(Shader::ATTRIB_COLOR_POS, 2, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(Shader::ATTRIB_COLOR_POS); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID_[2]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces.size() * sizeof(sl::uint3), &faces[0], GL_DYNAMIC_DRAW); + + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &imageTex); - glBindTexture(GL_TEXTURE_2D, imageTex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res.width, res.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, 0); - cudaError_t err = cudaGraphicsGLRegisterImage(&cuda_gl_ressource, imageTex, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard); - return (err == cudaSuccess); + auto res = ref.getResolution(); + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res.width, res.height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, 0); + cudaError_t err = cudaGraphicsGLRegisterImage(&cuda_gl_ressource, texture, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard); + if (err) std::cout << "err alloc " << err << " " << cudaGetErrorString(err) << "\n"; + glDisable(GL_TEXTURE_2D); + + err = cudaGraphicsMapResources(1, &cuda_gl_ressource, 0); + if (err) std::cout << "err 0 " << err << " " << cudaGetErrorString(err) << "\n"; + err = cudaGraphicsSubResourceGetMappedArray(&ArrIm, cuda_gl_ressource, 0, 0); + if (err) std::cout << "err 1 " << err << " " << cudaGetErrorString(err) << "\n"; + + return (err == cudaSuccess); } -void ImageHandler::pushNewImage(sl::Mat& image) { - cudaArray_t ArrIm; - cudaGraphicsMapResources(1, &cuda_gl_ressource, 0); - cudaGraphicsSubResourceGetMappedArray(&ArrIm, cuda_gl_ressource, 0, 0); - cudaMemcpy2DToArray(ArrIm, 0, 0, image.getPtr(sl::MEM::GPU), image.getStepBytes(sl::MEM::GPU), image.getPixelBytes() * image.getWidth(), image.getHeight(), cudaMemcpyDeviceToDevice); - cudaGraphicsUnmapResources(1, &cuda_gl_ressource, 0); +void CameraViewer::pushNewImage(CUstream strm) { + if (!ref.isInit()) return; + auto err = cudaMemcpy2DToArrayAsync(ArrIm, 0, 0, ref.getPtr(sl::MEM::GPU), ref.getStepBytes(sl::MEM::GPU), ref.getPixelBytes() * ref.getWidth(), ref.getHeight(), cudaMemcpyDeviceToDevice, strm); + if (err) std::cout << "err 2 " << err << " " << cudaGetErrorString(err) << "\n"; } -void ImageHandler::draw() { - glEnable(GL_TEXTURE_2D); - glUseProgram(shader.it.getProgramId()); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, imageTex); - glUniform1i(texID, 0); - //invert y axis and color for this image (since its reverted from cuda array) - glUniform1i(glGetUniformLocation(shader.it.getProgramId(), "revert"), 1); - glUniform1i(glGetUniformLocation(shader.it.getProgramId(), "rgbflip"), 1); - - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, quad_vb); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); - glDrawArrays(GL_TRIANGLES, 0, 6); - glDisableVertexAttribArray(0); +void CameraViewer::draw(sl::Transform vpMatrix) { + if (!ref.isInit()) return; + + glUseProgram(shader.getProgramId()); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glUniformMatrix4fv(shMVPMatrixLocTex_, 1, GL_FALSE, sl::Transform::transpose(vpMatrix).m); + glBindTexture(GL_TEXTURE_2D, texture); + + glBindVertexArray(vaoID_); + glDrawElements(GL_TRIANGLES, (GLsizei)faces.size()*3, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); + glUseProgram(0); - glDisable(GL_TEXTURE_2D); } diff --git a/spatial mapping/spatial mapping/cpp/src/main.cpp b/spatial mapping/spatial mapping/cpp/src/main.cpp index 1d2ab3e8..16c60a7e 100644 --- a/spatial mapping/spatial mapping/cpp/src/main.cpp +++ b/spatial mapping/spatial mapping/cpp/src/main.cpp @@ -18,179 +18,173 @@ // /////////////////////////////////////////////////////////////////////////// -/************************************************************************* - ** This sample shows how to capture a real-time 3D reconstruction ** - ** of the scene using the Spatial Mapping API. The resulting mesh ** - ** is displayed as a wireframe on top of the left image using OpenGL. ** - ** Spatial Mapping can be started and stopped with the space bar key ** - *************************************************************************/ - - // ZED includes +/********************************************************************************** + ** This sample demonstrates how to capture a live 3D reconstruction of a scene ** + ** as a fused point cloud and display the result in an OpenGL window. ** + **********************************************************************************/ + +// ZED includes #include - // Sample includes +// Sample includes #include "GLViewer.hpp" - // Using std and sl namespaces +#include + +// Using std and sl namespaces using namespace std; using namespace sl; -// set to 0 to create a Fused Point Cloud -#define CREATE_MESH 1 +#define BUILD_MESH 1 + +void parse_args(int argc, char **argv,InitParameters& param); -void parseArgs(int argc, char **argv,sl::InitParameters& param); +void print(std::string msg_prefix, sl::ERROR_CODE err_code = sl::ERROR_CODE::SUCCESS, std::string msg_suffix = ""); -int main(int argc, char** argv) { +int main(int argc, char **argv) { Camera zed; - // Setup configuration parameters for the ZED + // Set configuration parameters for the ZED InitParameters init_parameters; + init_parameters.depth_mode = DEPTH_MODE::NEURAL; init_parameters.coordinate_units = UNIT::METER; - init_parameters.depth_mode = sl::DEPTH_MODE::ULTRA; - init_parameters.coordinate_system = COORDINATE_SYSTEM::RIGHT_HANDED_Y_UP; // OpenGL coordinates system - parseArgs(argc,argv, init_parameters); + init_parameters.coordinate_system = COORDINATE_SYSTEM::RIGHT_HANDED_Y_UP; // OpenGL's coordinate system is right_handed + init_parameters.depth_maximum_distance = 8.; + parse_args(argc, argv, init_parameters); // Open the camera auto returned_state = zed.open(init_parameters); - if (returned_state != ERROR_CODE::SUCCESS) { - print("Camera Open", returned_state, "Exit program."); - return EXIT_FAILURE; - } -#if CREATE_MESH - Mesh map; // Current incremental mesh -#else - FusedPointCloud map; // Current incremental fused point cloud -#endif - - CameraParameters camera_parameters = zed.getCameraInformation().camera_configuration.calibration_parameters.left_cam; - - GLViewer viewer; - bool error_viewer = viewer.init(argc, argv, camera_parameters, &map); - - if(error_viewer) { - viewer.exit(); + if (returned_state != ERROR_CODE::SUCCESS) {// Quit if an error occurred + print("Open Camera", returned_state, "\nExit program."); zed.close(); return EXIT_FAILURE; } - Mat image; // Current left image - Pose pose; // Camera pose tracking data + /* Print shortcuts*/ + std::cout<<"Shortcuts\n"; + std::cout<<"\t- 'l' to enable/disable current live point cloud display\n"; + std::cout<<"\t- 'w' to switch mesh display from faces to triangles\n"; + std::cout<<"\t- 'd' to switch background color from dark to light\n"; - SpatialMappingParameters spatial_mapping_parameters; + auto camera_infos = zed.getCameraInformation(); + + // Setup and start positional tracking + Pose pose; POSITIONAL_TRACKING_STATE tracking_state = POSITIONAL_TRACKING_STATE::OFF; - SPATIAL_MAPPING_STATE mapping_state = SPATIAL_MAPPING_STATE::NOT_ENABLED; - bool mapping_activated = false; // Indicates if spatial mapping is running or not - chrono::high_resolution_clock::time_point ts_last; // Timestamp of the last mesh request - - // Enable positional tracking before starting spatial mapping - returned_state = zed.enablePositionalTracking(); - if(returned_state != ERROR_CODE::SUCCESS) { + PositionalTrackingParameters positional_tracking_parameters; + positional_tracking_parameters.enable_area_memory = false; + positional_tracking_parameters.set_floor_as_origin = true; + returned_state = zed.enablePositionalTracking(positional_tracking_parameters); + if (returned_state != ERROR_CODE::SUCCESS) { print("Enabling positional tracking failed: ", returned_state); zed.close(); return EXIT_FAILURE; } - std::cout << "Press on 'Space' for enable / disable spatial mapping " << std::endl; - std::cout << "Disable the spacial mapping after enabled it will output a .obj mesh file " << std::endl; - - while(viewer.isAvailable()) { - if(zed.grab() == ERROR_CODE::SUCCESS) { - // Retrieve image in GPU memory - zed.retrieveImage(image, VIEW::LEFT, MEM::GPU); - // Update pose data (used for projection of the mesh over the current image) - tracking_state = zed.getPosition(pose); - if(mapping_activated) { - mapping_state = zed.getSpatialMappingState(); - // Compute elapsed time since the last call of Camera::requestSpatialMapAsync() - auto duration = chrono::duration_cast(chrono::high_resolution_clock::now() - ts_last).count(); - // Ask for a mesh update if 500ms elapsed since last request - if((duration > 500) && viewer.chunksUpdated()) { - zed.requestSpatialMapAsync(); - ts_last = chrono::high_resolution_clock::now(); - } + // Set spatial mapping parameters + SpatialMappingParameters spatial_mapping_parameters; + // Request a Point Cloud +#if BUILD_MESH + spatial_mapping_parameters.map_type = SpatialMappingParameters::SPATIAL_MAP_TYPE::MESH; + Mesh map; +#else + spatial_mapping_parameters.map_type = SpatialMappingParameters::SPATIAL_MAP_TYPE::FUSED_POINT_CLOUD; + FusedPointCloud map; +#endif + // Set mapping range, it will set the resolution accordingly (a higher range, a lower resolution) + spatial_mapping_parameters.set(SpatialMappingParameters::MAPPING_RANGE::MEDIUM); + spatial_mapping_parameters.set(SpatialMappingParameters::MAPPING_RESOLUTION::MEDIUM); + // Request partial updates only (only the lastest updated chunks need to be re-draw) + spatial_mapping_parameters.use_chunk_only = true; + // Stability counter defines how many times a stable 3D points should be seen before it is integrated into the spatial mapping + spatial_mapping_parameters.stability_counter = 4; + - if(zed.getSpatialMapRequestStatusAsync() == ERROR_CODE::SUCCESS) { - zed.retrieveSpatialMapAsync(map); - viewer.updateChunks(); - } - } + // Timestamp of the last fused point cloud requested + chrono::high_resolution_clock::time_point ts_last; - bool change_state = viewer.updateImageAndState(image, pose.pose_data, tracking_state, mapping_state); + // Setup runtime parameters + RuntimeParameters runtime_parameters; + // Use low depth confidence avoid introducing noise in the constructed model + runtime_parameters.confidence_threshold = 50; - if(change_state) { - if(!mapping_activated) { - Transform init_pose; - zed.resetPositionalTracking(init_pose); + auto resolution = camera_infos.camera_configuration.resolution; - // Configure Spatial Mapping parameters - spatial_mapping_parameters.resolution_meter = SpatialMappingParameters::get(SpatialMappingParameters::MAPPING_RESOLUTION::LOW); - spatial_mapping_parameters.use_chunk_only = true; - spatial_mapping_parameters.save_texture = false; -#if CREATE_MESH - spatial_mapping_parameters.map_type = SpatialMappingParameters::SPATIAL_MAP_TYPE::MESH; -#else - spatial_mapping_parameters.map_type = SpatialMappingParameters::SPATIAL_MAP_TYPE::FUSED_POINT_CLOUD; -#endif - // Enable spatial mapping - try { - zed.enableSpatialMapping(spatial_mapping_parameters); - print("Spatial Mapping will output a " + string(toString(spatial_mapping_parameters.map_type).c_str())); - } catch(string e) { - print("Error enable Spatial Mapping "+ e); - } + // Define display resolution and check that it fit at least the image resolution + float image_aspect_ratio = resolution.width / (1.f * resolution.height); + int requested_low_res_w = min(720, (int)resolution.width); + sl::Resolution display_resolution(requested_low_res_w, requested_low_res_w / image_aspect_ratio); - // Clear previous Mesh data - map.clear(); - viewer.clearCurrentMesh(); - - // Start a timer, we retrieve the mesh every XXms. - ts_last = chrono::high_resolution_clock::now(); - - mapping_activated = true; - } else { - // Extract the whole mesh - zed.extractWholeSpatialMap(map); -#if CREATE_MESH - MeshFilterParameters filter_params; - filter_params.set(MeshFilterParameters::MESH_FILTER::MEDIUM); - // Filter the extracted mesh - map.filter(filter_params, true); - viewer.clearCurrentMesh(); - - // If textures have been saved during spatial mapping, apply them to the mesh - if(spatial_mapping_parameters.save_texture) - map.applyTexture(MESH_TEXTURE_FORMAT::RGB); -#endif - // Save mesh as an OBJ file - string saveName = getDir() + "mesh_gen.obj"; - bool error_save = map.save(saveName.c_str()); - if(error_save) - print("Mesh saved under: " +saveName); - else - print("Failed to save the mesh under: " +saveName); - - mapping_state = SPATIAL_MAPPING_STATE::NOT_ENABLED; - mapping_activated = false; + Mat image(display_resolution, MAT_TYPE::U8_C4, sl::MEM::GPU); + Mat point_cloud(display_resolution, MAT_TYPE::F32_C4, sl::MEM::GPU); + + // Point cloud viewer + GLViewer viewer; + + viewer.init(argc, argv, image, point_cloud, zed.getCUDAStream()); + + bool request_new_mesh = true; + + bool wait_for_mapping = true; + + // Start the main loop + while (viewer.isAvailable()) { + // Grab a new image + if (zed.grab(runtime_parameters) == ERROR_CODE::SUCCESS) { + // Retrieve the left image + zed.retrieveImage(image, VIEW::LEFT, MEM::GPU, display_resolution); + zed.retrieveMeasure(point_cloud, MEASURE::XYZBGRA, MEM::GPU, display_resolution); + // Retrieve the camera pose data + tracking_state = zed.getPosition(pose); + viewer.updateCameraPose(pose.pose_data, tracking_state); + + if (tracking_state == POSITIONAL_TRACKING_STATE::OK) { + if(wait_for_mapping){ + zed.enableSpatialMapping(spatial_mapping_parameters); + wait_for_mapping = false; + }else{ + if(request_new_mesh){ + auto duration = chrono::duration_cast(chrono::high_resolution_clock::now() - ts_last).count(); + // Ask for a fused point cloud update if 500ms have elapsed since last request + if(duration > 100) { + // Ask for a point cloud refresh + zed.requestSpatialMapAsync(); + request_new_mesh = false; + } + } + + // If the point cloud is ready to be retrieved + if(zed.getSpatialMapRequestStatusAsync() == ERROR_CODE::SUCCESS && !request_new_mesh) { + zed.retrieveSpatialMapAsync(map); + viewer.updateMap(map); + request_new_mesh = true; + ts_last = chrono::high_resolution_clock::now(); + } } } } } - image.free(); - map.clear(); + // Save generated point cloud + //map.save("MyFusedPointCloud"); - zed.disableSpatialMapping(); - zed.disablePositionalTracking(); + // Free allocated memory before closing the camera + image.free(); + point_cloud.free(); + // Close the ZED zed.close(); - return EXIT_SUCCESS; + + return 0; } -void parseArgs(int argc, char **argv,sl::InitParameters& param) +void parse_args(int argc, char **argv,InitParameters& param) { if (argc > 1 && string(argv[1]).find(".svo")!=string::npos) { // SVO input mode param.input.setFromSVOFile(argv[1]); + param.svo_real_time_mode=true; + cout<<"[Sample] Using SVO File input: "< 1 && string(argv[1]).find(".svo")==string::npos) { string arg = string(argv[1]); @@ -198,12 +192,12 @@ void parseArgs(int argc, char **argv,sl::InitParameters& param) if (sscanf(arg.c_str(),"%u.%u.%u.%u:%d", &a, &b, &c, &d,&port) == 5) { // Stream input mode - IP + port string ip_adress = to_string(a)+"."+to_string(b)+"."+to_string(c)+"."+to_string(d); - param.input.setFromStream(sl::String(ip_adress.c_str()),port); + param.input.setFromStream(String(ip_adress.c_str()),port); cout<<"[Sample] Using Stream input, IP : "<(mesh.chunks.Values); - viewer.updateData(chunks); + if (err == ERROR_CODE.SUCCESS) + { + var chunks = new List(mesh.chunks.Values); + viewer.updateData(chunks); + } } /// MAP_TYPE == FUSED_POINT_CLOUD @@ -237,7 +252,13 @@ private void NativeWindow_Render(object sender, NativeWindowEventArgs e) Quaternion quat = Quaternion.Identity; Vector3 vec = Vector3.Zero; zedCamera.ResetPositionalTracking(quat, vec); - zedCamera.EnableSpatialMapping(ref spatialMappingParameters); + err = zedCamera.EnableSpatialMapping(ref spatialMappingParameters); + + if (err != ERROR_CODE.SUCCESS) + { + Console.WriteLine("Error while enabling mapping" + err.ToString() + " exitin..."); + Environment.Exit(-1); + } Console.WriteLine("Hit SPACE BAR to stop spatial mapping..."); // Clear previous Mesh data diff --git a/tutorials/tutorial 1 - hello ZED/c/main.c b/tutorials/tutorial 1 - hello ZED/c/main.c index 748feb4a..e96e3d6b 100644 --- a/tutorials/tutorial 1 - hello ZED/c/main.c +++ b/tutorials/tutorial 1 - hello ZED/c/main.c @@ -51,6 +51,8 @@ int main(int argc, char **argv) { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; + // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 2 - image capture/c/main.c b/tutorials/tutorial 2 - image capture/c/main.c index fddb8e55..5c66de07 100644 --- a/tutorials/tutorial 2 - image capture/c/main.c +++ b/tutorials/tutorial 2 - image capture/c/main.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 3 - depth sensing/c/main.c b/tutorials/tutorial 3 - depth sensing/c/main.c index 47f622e7..eec837ea 100644 --- a/tutorials/tutorial 3 - depth sensing/c/main.c +++ b/tutorials/tutorial 3 - depth sensing/c/main.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 4 - positional tracking/c/main.c b/tutorials/tutorial 4 - positional tracking/c/main.c index 3da980cf..d67c7116 100644 --- a/tutorials/tutorial 4 - positional tracking/c/main.c +++ b/tutorials/tutorial 4 - positional tracking/c/main.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 5 - spatial mapping/c/main.c b/tutorials/tutorial 5 - spatial mapping/c/main.c index 396855f3..8bcf9087 100644 --- a/tutorials/tutorial 5 - spatial mapping/c/main.c +++ b/tutorials/tutorial 5 - spatial mapping/c/main.c @@ -51,6 +51,7 @@ int main() { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 6 - object detection/c/main.c b/tutorials/tutorial 6 - object detection/c/main.c index 5ec54e5b..8a58df05 100644 --- a/tutorials/tutorial 6 - object detection/c/main.c +++ b/tutorials/tutorial 6 - object detection/c/main.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 7 - sensor data/c/main.c b/tutorials/tutorial 7 - sensor data/c/main.c index 98e39693..1e027487 100644 --- a/tutorials/tutorial 7 - sensor data/c/main.c +++ b/tutorials/tutorial 7 - sensor data/c/main.c @@ -64,6 +64,7 @@ int main(int argc, char **argv) { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 8 - body tracking/c/main.c b/tutorials/tutorial 8 - body tracking/c/main.c index add5f9cb..eeee56a7 100644 --- a/tutorials/tutorial 8 - body tracking/c/main.c +++ b/tutorials/tutorial 8 - body tracking/c/main.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { init_param.enable_right_side_measure = false; init_param.open_timeout_sec = 5.0f; init_param.async_grab_camera_recovery = false; + init_param.grab_compute_capping_fps = 0; // Open the camera int state = sl_open_camera(camera_id, &init_param, 0, "", "", 0, "", "", ""); diff --git a/tutorials/tutorial 8 - body tracking/csharp/Program.cs b/tutorials/tutorial 8 - body tracking/csharp/Program.cs index fc84df6d..6b45d8f4 100644 --- a/tutorials/tutorial 8 - body tracking/csharp/Program.cs +++ b/tutorials/tutorial 8 - body tracking/csharp/Program.cs @@ -44,7 +44,7 @@ static void Main(string[] args) body_tracking_parameters.detectionModel = sl.BODY_TRACKING_MODEL.HUMAN_BODY_FAST; // Choose the appropriate body format for your application // (38 to have simplified hands, 70 for detailed hands, but more resource-heavy.) - body_tracking_parameters.bodyFormat = sl.BODY_FORMAT.POSE_38; + body_tracking_parameters.bodyFormat = sl.BODY_FORMAT.BODY_38; // track detects object across time and space body_tracking_parameters.enableObjectTracking = true; // run detection for every Camera grab