From 8a0e25d3ff435b8eab6adbdd68c8a9bb3dbcb05c Mon Sep 17 00:00:00 2001 From: Matthew B Date: Mon, 8 Jan 2024 13:49:46 -0600 Subject: [PATCH 1/7] Rename dial to gauge Update for new pubviz callbacks --- controls/pubviz.cpp | 6 +- plugins/Dial.h | 16 +-- plugins/Gauge.h | 329 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 340 insertions(+), 11 deletions(-) create mode 100644 plugins/Gauge.h diff --git a/controls/pubviz.cpp b/controls/pubviz.cpp index c35ac68..340ab79 100644 --- a/controls/pubviz.cpp +++ b/controls/pubviz.cpp @@ -51,7 +51,7 @@ #include "../plugins/Path.h" #include "../plugins/Image.h" #include "../plugins/GPS.h" -#include "../plugins/Dial.h" +#include "../plugins/Gauge.h" #include #include @@ -522,7 +522,7 @@ GWEN_CONTROL_CONSTRUCTOR(PubViz) ps_node_system_query(&node_); - node_.adv_cb = [](const char* topic, const char* type, const char* node, const ps_advertise_req_t* data) + node_.adv_cb = [](const char* topic, const char* type, const char* node, const ps_advertise_req_t* data, void* cbdata) { // check if we already have the topic if (_found_topics.find(topic) != _found_topics.end()) @@ -550,7 +550,7 @@ GWEN_CONTROL_CONSTRUCTOR(PubViz) //AddPlugin("image"); - AddPlugin("dial"); + AddPlugin("gauge"); AddPlugin("grid"); AddPlugin("gps"); AddPlugin("costmap"); diff --git a/plugins/Dial.h b/plugins/Dial.h index b13c111..1e1263c 100644 --- a/plugins/Dial.h +++ b/plugins/Dial.h @@ -1,6 +1,6 @@ -#ifndef PUBVIZ_PLUGIN_DIAL_H -#define PUBVIZ_PLUGIN_DIAL_H +#ifndef PUBVIZ_PLUGIN_GAUGE_H +#define PUBVIZ_PLUGIN_GAUGE_H #include #include @@ -29,7 +29,7 @@ #include -class DialPlugin: public pubviz::Plugin +class GaugePlugin: public pubviz::Plugin { FloatProperty* min_value_; FloatProperty* max_value_; @@ -66,12 +66,12 @@ class DialPlugin: public pubviz::Plugin public: - DialPlugin() + GaugePlugin() { } - virtual ~DialPlugin() + virtual ~GaugePlugin() { if (sub_open_) { @@ -304,7 +304,7 @@ class DialPlugin: public pubviz::Plugin { // add any properties topic_ = AddTopicProperty(tree, "Topic", "/image", "", ""); - topic_->onChange = std::bind(&DialPlugin::Subscribe, this, std::placeholders::_1); + topic_->onChange = std::bind(&GaugePlugin::Subscribe, this, std::placeholders::_1); field_ = AddStringProperty(tree, "Field", "width"); @@ -320,10 +320,10 @@ class DialPlugin: public pubviz::Plugin std::string GetTitle() override { - return "Dial"; + return "Gauge"; } }; -REGISTER_PLUGIN("dial", DialPlugin) +REGISTER_PLUGIN("gauge", GaugePlugin) #endif diff --git a/plugins/Gauge.h b/plugins/Gauge.h new file mode 100644 index 0000000..0b83522 --- /dev/null +++ b/plugins/Gauge.h @@ -0,0 +1,329 @@ + +#ifndef PUBVIZ_PLUGIN_DIAL_H +#define PUBVIZ_PLUGIN_DIAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GLEW_STATIC +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#endif + +#include "../Plugin.h" +#include "../properties.h" + +#include + +class DialPlugin: public pubviz::Plugin +{ + FloatProperty* min_value_; + FloatProperty* max_value_; + BooleanProperty* auto_minmax_; + + NumberProperty* x_position_, *y_position_; + NumberProperty* size_; + + TopicProperty* topic_; + StringProperty* field_; + + bool sub_open_ = false; + ps_sub_t subscriber_; + double current_value_ = NAN; + + std::string current_topic_; + void Subscribe(std::string str) + { + if (sub_open_) + { + ps_sub_destroy(&subscriber_); + } + + Clear(); + + current_topic_ = str; + struct ps_subscriber_options options; + ps_subscriber_options_init(&options); + options.preferred_transport = 1;// tcp yo + options.want_message_def = true; + ps_node_create_subscriber_adv(GetNode(), current_topic_.c_str(), NULL, &subscriber_, &options); + sub_open_ = true; + } + +public: + + DialPlugin() + { + + } + + virtual ~DialPlugin() + { + if (sub_open_) + { + ps_sub_destroy(&subscriber_); + sub_open_ = false; + } + } + + // Clear out any historical data so the view gets cleared + virtual void Clear() + { + current_value_ = NAN; + } + + virtual void Update() + { + // process any messages + // our sub has a message definition, so the queue contains real messages + if (sub_open_) + { + while (char* data = (char*)ps_sub_deque(&subscriber_)) + { + if (Paused()) + { + free(data);//todo use allocator free + continue; + } + + HandleMessage(data); + + // user is responsible for freeing the message and its arrays + free(data); + } + } + } + + void HandleMessage(const char* msg) + { + if (!subscriber_.received_message_def.fields) + { + return; + } + + current_value_ = NAN; + + struct ps_deserialize_iterator iter = ps_deserialize_start((const char*)msg, &subscriber_.received_message_def); + const struct ps_msg_field_t* field; uint32_t length; const char* ptr; + while (ptr = ps_deserialize_iterate(&iter, &field, &length)) + { + if (strcmp(field->name, field_->GetValue().c_str()) != 0) + { + continue; + } + if (field->type == FT_String) + { + // strings are already null terminated + //printf("%s: %s\n", field->name, ptr); + // what should I do about strings? + } + else + { + if (length > 0) + { + double value = 0; + // non dynamic types + switch (field->type) + { + case FT_Int8: + value = *(int8_t*)ptr; + break; + case FT_Int16: + value = *(int16_t*)ptr; + break; + case FT_Int32: + value = *(int32_t*)ptr; + break; + case FT_Int64: + value = *(int64_t*)ptr; + break; + case FT_UInt8: + value = *(uint8_t*)ptr; + break; + case FT_UInt16: + value = *(uint16_t*)ptr; + break; + case FT_UInt32: + value = *(uint32_t*)ptr; + break; + case FT_UInt64: + value = *(uint64_t*)ptr; + break; + case FT_Float32: + value = *(float*)ptr; + break; + case FT_Float64: + value = *(double*)ptr; + break; + default: + printf("ERROR: unhandled field type when parsing....\n"); + } + + current_value_ = value; + Redraw(); + break; + } + } + } + } + + virtual void Render() + { + + } + + virtual void Paint() + { + // nothing to do here since we dont render to the world + // actually, lets render to the world? + //current_value_ = rand()%11; + + glLineWidth(3.0); + + auto r = GetCanvas()->GetSkin()->GetRender(); + Gwen::Point pos = r->GetRenderOffset(); + //glLoadIdentity(); + //glRotatef(yaw, 0, 0, 1); + auto scale = GetCanvas()->GetCanvas()->Scale(); + //glTranslatef(pos.x*scale, pos.y*scale, 0);// shift it so 0, 0 is _our_ top left corner + //glScalef(scale, scale, 1.0); + + const int start_x = x_position_->GetValue() + pos.x; + const int start_y = y_position_->GetValue() + pos.y; + const float radius = size_->GetValue(); + const float height = radius/2.0; + + // draw it bitch + const int num_pts = 20; + const double radians_per_pt = M_PI/num_pts; + glBegin(GL_LINE_STRIP); + float opts[num_pts*2+2]; + for (int i = 0; i <= num_pts; i++) + { + float x = start_x + height + height*cos(radians_per_pt*i); + float y = start_y + (height - height*sin(radians_per_pt*i)); + //printf("x: %f y: %f\n", x, y); + // want to draw a half circle + glColor4f(1.0, 1.0, 1.0, 1.0); + glVertex2f(x*scale, y*scale); + opts[i*2] = x*scale; + opts[i*2+1] = y*scale; + } + + // now draw the inner part + const float inner_radius = radius*0.5; + float ipts[num_pts*2+2]; + for (int i = num_pts; i >= 0; i--) + { + float x = start_x + height + inner_radius*cos(radians_per_pt*i)*0.5; + float y = start_y + (height - inner_radius*sin(radians_per_pt*i)*0.5); + //printf("x: %f y: %f\n", x, y); + // want to draw a half circle + glColor4f(1.0, 1.0, 1.0, 1.0); + glVertex2f(x*scale, y*scale); + ipts[i*2] = x*scale; + ipts[i*2+1] = y*scale; + } + glVertex2f((start_x + radius)*scale, (start_y + height)*scale); + glEnd(); + + if (std::isnan(current_value_)) + { + return; + } + + float frac = (current_value_-min_value_->GetValue())/(max_value_->GetValue() - min_value_->GetValue()); + frac = std::max(0.0f, std::min(1.0f, frac)); + float angle = M_PI - std::max(0.0f, std::min(1.0f, frac))*M_PI; + + // draw a colored inside? + glBegin(GL_TRIANGLES); + for (int j = 0; j < 20; j++) + { + int i = j;//num_pts - j; + glColor4f(0, 0, 0, 1); + glVertex2f(opts[i*2], opts[i*2+1]); + glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); + glVertex2f(ipts[i*2], ipts[i*2+1]); + + glVertex2f(ipts[(i+1)*2], ipts[(i+1)*2+1]); + glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); + glVertex2f(ipts[i*2], ipts[i*2+1]); + } + for (int j = 0; j < num_pts*frac; j++) + { + int i = std::min(19, num_pts - j); + glColor4f(2*(frac), 2*(1.0-frac), 0, 1); + glVertex2f(opts[i*2], opts[i*2+1]); + glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); + glVertex2f(ipts[i*2], ipts[i*2+1]); + + glVertex2f(ipts[(i+1)*2], ipts[(i+1)*2+1]); + glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); + glVertex2f(ipts[i*2], ipts[i*2+1]); + } + // then draw the last segment + glEnd(); + + glLineWidth(5.0); + glBegin(GL_LINES); + glColor4f(0, 0, 0, 1); + glVertex2f((start_x + radius/2)*scale, (start_y + height)*scale); + glVertex2f((start_x + height + height*cos(angle))*scale, (start_y + (height - height*sin(angle)))*scale); + glEnd(); + + glLineWidth(2.0); + glBegin(GL_LINES); + glColor4f(1, 1, 1, 1); + glVertex2f((start_x + radius/2)*scale, (start_y + height)*scale); + glVertex2f((start_x + height + height*cos(angle))*scale, (start_y + (height - height*sin(angle)))*scale); + glEnd(); + + // draw the value + r->SetDrawColor( Gwen::Color(255,255,255,255) ); + char buf[50]; + sprintf(buf, "%g", current_value_); + r->RenderText(GetCanvas()->GetSkin()->GetDefaultFont(), Gwen::PointF( x_position_->GetValue(), y_position_->GetValue() + height ), (std::string)buf); + } + + virtual void Initialize(Gwen::Controls::Properties* tree) + { + // add any properties + topic_ = AddTopicProperty(tree, "Topic", "/image", "", ""); + topic_->onChange = std::bind(&DialPlugin::Subscribe, this, std::placeholders::_1); + + field_ = AddStringProperty(tree, "Field", "width"); + + min_value_ = AddFloatProperty(tree, "Minimum", 0, -10000000, 100000); + max_value_ = AddFloatProperty(tree, "Maximum", 10, -10000000, 100000); + + x_position_ = AddNumberProperty(tree, "X Offset", 0, 0, 10000); + y_position_ = AddNumberProperty(tree, "Y Offset", 0, 0, 10000); + size_ = AddNumberProperty(tree, "Size", 100, 1, 10000); + + Subscribe(topic_->GetValue()); + } + + std::string GetTitle() override + { + return "Gauge"; + } +}; + +REGISTER_PLUGIN("gauge", DialPlugin) + +#endif From 918ff6fa1a9cb229a0fcf0d57137641ffc760972 Mon Sep 17 00:00:00 2001 From: Matthew B Date: Sat, 22 Jun 2024 20:00:38 -0700 Subject: [PATCH 2/7] Improve pose rendering Properly handle various pointcloud types Support WGS84/Odom transform properly in Costmap, Path, Pose Add Satellite Imagery/Map plugin Add Measure plugin Add PlanPath plugin Refactor view centering/following and make it work more nicely Add view height to saved properties Add ability to reorder plugins to change render order Center add plugin dialog Add save functionality, not just save as Add alpha key functionality to costmap to allow hiding "zero" cost areas Add map click callback support to plugins in top down mode --- .gitignore | 3 +- CMakeLists.txt | 2 +- CMakeSettings.json | 27 - DefaultSkin.png | Bin 39462 -> 44538 bytes LocalXY.h | 14 +- Plugin.h | 19 +- README.md | 8 +- controls/GraphCanvas.cpp | 3 +- controls/OpenGLCanvas.cpp | 138 +++-- controls/OpenGLCanvas.h | 200 ++++++- controls/Parameters.cpp | 32 +- controls/Parameters.h | 72 ++- controls/pubviz.cpp | 178 +++++- controls/pubviz.h | 4 + plugins/Costmap.h | 108 ++-- plugins/Dial.h | 329 ----------- plugins/FreeImage.h | 1117 ------------------------------------- plugins/GPS.h | 12 +- plugins/Gauge.h | 11 +- plugins/Image.h | 113 ++-- plugins/Map.h | 808 +++++++++++++++++++++++++++ plugins/Marker.h | 122 ++-- plugins/Measure.h | 200 +++++++ plugins/Path.h | 81 ++- plugins/PlanPath.h | 237 ++++++++ plugins/PointCloud.h | 445 ++++++++------- plugins/Pose.h | 168 ++++-- properties.h | 49 ++ pubviz_2d.png | Bin 0 -> 199786 bytes pubviz_3d.png | Bin 0 -> 400849 bytes pubviz_screenshot.png | Bin 373799 -> 0 bytes tools/sackviz.cpp | 1 + 32 files changed, 2406 insertions(+), 2095 deletions(-) delete mode 100644 CMakeSettings.json delete mode 100644 plugins/Dial.h delete mode 100644 plugins/FreeImage.h create mode 100644 plugins/Map.h create mode 100644 plugins/Measure.h create mode 100644 plugins/PlanPath.h create mode 100644 pubviz_2d.png create mode 100644 pubviz_3d.png delete mode 100644 pubviz_screenshot.png diff --git a/.gitignore b/.gitignore index 391d6c6..6fd6177 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ CMakeFiles/ CMakeCache.txt Makefile .vs/ -out/ \ No newline at end of file +out/ +.tile_cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e95a07..8b5996d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ target_include_directories(sackviz PUBLIC ${pubsub_INCLUDE_DIRS} ${librucksack_INCLUDE_DIRS}) target_link_libraries(sackviz GWEN_opengl GWEN_static ${pubsub_LIBRARIES} - debug ${librucksack_DEBUG_LIBRARIES} + debug ${librucksack_LIBRARIES} optimized ${librucksack_LIBRARIES}) set_property(TARGET sackviz PROPERTY CXX_STANDARD 11) diff --git a/CMakeSettings.json b/CMakeSettings.json deleted file mode 100644 index 5b8aad6..0000000 --- a/CMakeSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "configurations": [ - { - "name": "x64-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\build\\${name}", - "installRoot": "${projectDir}\\out\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "" - }, - { - "name": "x64-Release", - "generator": "Ninja", - "configurationType": "RelWithDebInfo", - "buildRoot": "${projectDir}\\out\\build\\${name}", - "installRoot": "${projectDir}\\out\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "msvc_x64_x64" ], - "variables": [] - } - ] -} \ No newline at end of file diff --git a/DefaultSkin.png b/DefaultSkin.png index 5fe26537da48b28d654a1a5837827cfdd0f6add5..186546285d79f5ffb341135744e85e5872ee04c1 100644 GIT binary patch literal 44538 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 diff --git a/LocalXY.h b/LocalXY.h index 44f414b..d824048 100644 --- a/LocalXY.h +++ b/LocalXY.h @@ -50,7 +50,7 @@ class LocalXYUtil rho_lon_ = (rho_n - depth) * cos(origin_lat_); } - void ToLatLon(double x, double y, double& lat, double& lon) + void ToLatLon(double x, double y, double& lat, double& lon) const { double dLon = 1.0 * x - 0.0 * y; double dLat = 0.0 * x + 1.0 * y; @@ -61,7 +61,7 @@ class LocalXYUtil lon = RadiansToDegrees(rlon); } - void FromLatLon(double lat, double lon, double& x, double& y) + void FromLatLon(double lat, double lon, double& x, double& y) const { double rLat = DegreesToRadians(lat); double rLon = DegreesToRadians(lon); @@ -72,25 +72,25 @@ class LocalXYUtil y = -0.0 * dLon + 1.0 * dLat; } - inline double OriginLatitude() + inline double OriginLatitude() const { return RadiansToDegrees(origin_lat_); } - inline double OriginLongitude() + inline double OriginLongitude() const { return RadiansToDegrees(origin_lon_); } - inline double DegreesToRadians(double angle) + inline double DegreesToRadians(double angle) const { return angle * M_PI / 180.0; } - inline double RadiansToDegrees(double radians) + inline double RadiansToDegrees(double radians) const { return (180.0 / M_PI) * radians; } }; -#endif \ No newline at end of file +#endif diff --git a/Plugin.h b/Plugin.h index 1e7005c..6d0ce26 100644 --- a/Plugin.h +++ b/Plugin.h @@ -63,6 +63,9 @@ namespace pubviz // Returns info about a selected item including bounds (todo) virtual std::map Select(uint32_t index, AABB& size) { return {}; } + // Applies only for 2d + virtual bool OnMapClick(double x, double y) { return false; } + // Returns if the plugin is enabled and should be rendered bool Enabled() { @@ -104,8 +107,14 @@ namespace pubviz out += tree_node_->GetToggleButton()->GetToggleState() ? "false" : "true"; // lets just write it as CSV int i = 0; - for (auto& prop : properties_) + + for (const auto& prop : properties_) { + // skip ButtonProperties + if (dynamic_cast(prop.second)) + { + continue; + } out += ","; out += prop.first; out += ","; @@ -225,6 +234,14 @@ namespace pubviz properties_[name] = prop; return prop; } + + ButtonProperty* AddButtonProperty(Gwen::Controls::Properties* tree, const char* name, + const std::string& description = "") + { + auto prop = new ButtonProperty(tree, name, description); + properties_[name] = prop; + return prop; + } }; } #endif diff --git a/README.md b/README.md index 3f51059..08c1ee4 100755 --- a/README.md +++ b/README.md @@ -11,13 +11,15 @@ This repository contains three tools: A tool for visualizing incoming data in both 2D and 3D. Largely uses immediate mode OpenGL for rendering for ease of implementation. -![Example screenshot of pubviz.](pubviz_screenshot.png) +![Example screenshot of a 2D view in pubviz.](pubviz_2d.png) + +![Example screenshot of a 3D view in pubviz.](pubviz_3d.png) It supports visualizing: * Point Clouds * Costmaps -* Basic Markers (to be further improved) +* Various Markers (to be further improved) * Grids * Images * Time series plots of individual data fields @@ -27,7 +29,7 @@ It supports visualizing: # Sackviz -A tool for introspecting and playing back Rucksack files. Also supports both time series and scatter plots of data. +A tool for introspecting and playing back Rucksack files. Supports viewing both time series and scatter plots of data. ![Example screenshot of sackviz.](sackviz_screenshot.png) diff --git a/controls/GraphCanvas.cpp b/controls/GraphCanvas.cpp index f87b382..534e43f 100644 --- a/controls/GraphCanvas.cpp +++ b/controls/GraphCanvas.cpp @@ -49,7 +49,6 @@ GraphSubscriber::GraphSubscriber(const std::string& topic) ps_subscriber_options_init(&options); options.skip = 0; options.queue_size = 0; - options.want_message_def = true; options.allocator = 0; options.ignore_local = false; options.preferred_transport = false ? 1 : 0; @@ -156,7 +155,7 @@ GWEN_CONTROL_CONSTRUCTOR( GraphCanvas ) ps_node_init_ex(&node, "pubviz", "", false, false); //ps_node_init(&node, "pubviz", "", false); - node.adv_cb = [](const char* topic, const char* type, const char* node, const ps_advertise_req_t* data) + node.adv_cb = [](const char* topic, const char* type, const char* node, const ps_advertise_req_t* data, void* cb_data) { // check if we already have the topic if (_graph_topics.find(topic) != _graph_topics.end()) diff --git a/controls/OpenGLCanvas.cpp b/controls/OpenGLCanvas.cpp index 1e8183b..c0bb032 100644 --- a/controls/OpenGLCanvas.cpp +++ b/controls/OpenGLCanvas.cpp @@ -4,18 +4,18 @@ #include "OpenGLCanvas.h" -#include - #include "../Plugin.h" #include "pubviz.h" + +#include + #ifndef _WIN32 #include #include -#include -#include #endif + #include #include @@ -26,8 +26,8 @@ using namespace Gwen::Controls; GWEN_CONTROL_CONSTRUCTOR( OpenGLCanvas ) { - view_height_m_ = 150.0; m_Color = Gwen::Color( 50, 50, 50, 255 ); + glewInit(); } bool OpenGLCanvas::OnMouseWheeled( int delta ) @@ -47,15 +47,18 @@ bool OpenGLCanvas::OnMouseWheeled( int delta ) return true; } + double start_height = view_h_->GetValue(); + double rate = std::max(0.1, log(start_height/4.0)); if (delta < 0) { - view_height_m_ += 0.1*(double)delta; - view_height_m_ = std::max(1.0, view_height_m_); + start_height += 0.1*(double)delta*rate; + start_height = std::max(1.0, start_height); } else { - view_height_m_ += 0.1*(double)delta; + start_height += 0.1*(double)delta*rate; } + view_h_->SetValue(start_height); // Mark the window as dirty so it redraws Redraw(); @@ -65,22 +68,42 @@ bool OpenGLCanvas::OnMouseWheeled( int delta ) void OpenGLCanvas::ResetView() { - view_height_m_ = 150.0; + view_h_->SetValue(150.0); view_x_->SetValue(0.0); view_y_->SetValue(0.0); view_z_->SetValue(0.0); - view_abs_x_ = 0.0; - view_abs_y_ = 0.0; - view_abs_z_ = 0.0; pitch_->SetValue(0.0); yaw_->SetValue(0.0); Redraw(); } -void OpenGLCanvas::OnMouseClickLeft( int /*x*/, int /*y*/, bool down ) +void OpenGLCanvas::OnMouseClickLeft( int x, int y, bool down ) { mouse_down_ = down; + + if (down && view_type_->GetValue() == ViewType::TopDown) + { + double cx, cy, cz; + GetViewCenter(cx, cy, cz); + auto scale = GetCanvas()->Scale(); + auto np = CanvasPosToLocal({x,y}); + x = np.x; + y = np.y; + auto height = Height()*scale; + auto width = Width()*scale; + double pixels_per_meter = height/view_h_->GetValue(); + double x_mouse_position = (x - width*0.5)/pixels_per_meter + cx; + double y_mouse_position = (height*0.5 - y)/pixels_per_meter + cy; + // todo is this the right order/priority? + for (auto& plugin: plugins_) + { + if (plugin->Enabled() && plugin->OnMapClick(x_mouse_position, y_mouse_position)) + { + break; + } + } + } } void OpenGLCanvas::OnMouseClickRight( int x, int y, bool bDown ) @@ -110,7 +133,7 @@ void OpenGLCanvas::OnMouseClickRight( int x, int y, bool bDown ) // Now create the framebuffer using that texture as the color buffer glBindFramebuffer(GL_FRAMEBUFFER, selection_frame_buffer_); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, selection_texture_, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, selection_texture_, 0); // Do a dummy check if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) @@ -282,12 +305,59 @@ void OpenGLCanvas::OnMouseClickRight( int x, int y, bool bDown ) select_start_ = select_end_ = Gwen::Point(x, y); } -void OpenGLCanvas::OnMouseMoved(int x, int y, int dx, int dy) +void OpenGLCanvas::WorldToPixel(double x, double y, double z, int& px, int& py) +{ + auto scale = GetCanvas()->Scale(); + auto height = Height()*scale; + /*auto width = Width()*scale; + + // for now only works with 2d todo should use matrices + x -= view_x_->GetValue(); + y -= view_y_->GetValue(); + + double pixels_per_meter = height/view_height_m_; + x *= pixels_per_meter; + y *= pixels_per_meter; + + x += width*0.5; + y -= height*0.5; + px = x; + py = -y;*/ + double wx, wy, wz; + double m[16]; + double p[16]; + for (int i = 0; i < 16; i++) + { + m[i] = model_[i]; + p[i] = proj_[i]; + } + gluProject(x, y, z, m, p, vp_, &wx, &wy, &wz); + px = wx/scale; + py = wy/scale; + + auto np = CanvasPosToLocal({px,py}); + px = np.x; + py = Height()*scale - np.y; + py -= 20; + //printf("x: %f y: %f z: %f\n", x, y, z); + //printf("x: %i y: %i\n", px, py); +} + +void OpenGLCanvas::OnMouseMoved(int canvas_x, int canvas_y, int dx, int dy) { - // now convert to units - double pixels_per_meter = GetCanvas()->Height()/view_height_m_; - x_mouse_position_ = (x - GetCanvas()->Width()*0.5)/pixels_per_meter + view_x_->GetValue(); - y_mouse_position_ = (GetCanvas()->Height()*0.5 - y)/pixels_per_meter + view_y_->GetValue(); + // convert mouse position to physical units + auto scale = GetCanvas()->Scale(); + auto np = CanvasPosToLocal({canvas_x, canvas_y}); + float x = np.x; + float y = np.y; + auto height = Height()*scale; + auto width = Width()*scale; + double pixels_per_meter = height/view_h_->GetValue(); + + double cx, cy, cz; + GetViewCenter(cx, cy, cz); + x_mouse_position_ = (x - width*0.5)/pixels_per_meter + cx; + y_mouse_position_ = (height*0.5 - y)/pixels_per_meter + cy; // now apply offset if (mouse_down_) @@ -296,9 +366,6 @@ void OpenGLCanvas::OnMouseMoved(int x, int y, int dx, int dy) { view_x_->SetValue(view_x_->GetValue() - dx/pixels_per_meter); view_y_->SetValue(view_y_->GetValue() + dy/pixels_per_meter); - - view_abs_x_ -= dx / pixels_per_meter; - view_abs_y_ += dy / pixels_per_meter; } else { @@ -315,9 +382,10 @@ void OpenGLCanvas::OnMouseMoved(int x, int y, int dx, int dy) if (selecting_) { - select_end_ = Gwen::Point(x,y); + select_end_ = Gwen::Point(canvas_x,canvas_y); Redraw(); } + Redraw();// to get numbers to update } #include @@ -376,6 +444,8 @@ std::map OpenGLCanvas::CreateProperties(Gwen::Contro props["View Y"] = view_y_; view_z_ = new FloatProperty(tree, "View Z", 0, -100000, 100000); props["View Z"] = view_z_; + view_h_ = new FloatProperty(tree, "Height", 150, 1, 1000000); + props["Height"] = view_h_; view_type_->onChange = [this](std::string value) { @@ -407,23 +477,18 @@ void OpenGLCanvas::SetupViewMatrices() { auto width = Width(); auto height = Height(); - double view_x = view_x_->GetValue(); - double view_y = view_y_->GetValue(); - double view_z = view_z_->GetValue(); - if (wgs84_mode_) - { - view_x = view_abs_x_; - view_y = view_abs_y_; - view_z = view_abs_z_; - } + double view_x, view_y, view_z; + GetViewCenter(view_x, view_y, view_z); double yaw = yaw_->GetValue(); double pitch = pitch_->GetValue(); auto view_type = view_type_->GetValue(); if (view_type == ViewType::TopDown) { // set up the view matrix for the current zoom level (ortho, topdown) - float half_height = view_height_m_/2.0; + float half_height = view_h_->GetValue()/2.0; float half_width = half_height*((float)width/(float)height); + view_width_ = half_width*2; + view_height_ = half_height*2; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho( -half_width + view_x, half_width + view_x, -half_height + view_y, half_height + view_y, -10000.0, 10000.0 ); @@ -461,7 +526,7 @@ void OpenGLCanvas::SetupViewMatrices() else if (view_type == ViewType::Orbit) { // set up the view matrix for the current zoom level (orbit) - float half_height = view_height_m_/2.0; + float half_height = view_h_->GetValue()/2.0; float half_width = half_height*((float)width/(float)height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -485,6 +550,11 @@ void OpenGLCanvas::SetupViewMatrices() glClear(GL_DEPTH_BUFFER_BIT); glDepthFunc(GL_LEQUAL); } + + // save the matrices + glGetFloatv(GL_MODELVIEW_MATRIX, model_); + glGetFloatv(GL_PROJECTION_MATRIX, proj_); + glGetIntegerv(GL_VIEWPORT, vp_); } void OpenGLCanvas::Render( Skin::Base* skin ) diff --git a/controls/OpenGLCanvas.h b/controls/OpenGLCanvas.h index d1e88fe..b758e8a 100644 --- a/controls/OpenGLCanvas.h +++ b/controls/OpenGLCanvas.h @@ -9,6 +9,8 @@ #include #include "../properties.h" +#include + #include "../LocalXY.h" #include "../AABB.h" @@ -32,8 +34,26 @@ class OpenGLCanvas : public Gwen::Controls::Base unsigned int selection_frame_buffer_ = 0; void SetupViewMatrices(); + + bool wgs84_mode_ = false; + + bool show_origin_ = true; + + double center_x_ = 0; + double center_y_ = 0; + double center_z_ = 0; + + + double view_width_ = 0; + double view_height_ = 0; + + Matrix3x4d map_to_odom_; + Matrix3x4d odom_to_map_; public: + inline double view_width() { return view_width_; } + inline double view_height() { return view_height_; } + LocalXYUtil local_xy_; GWEN_CONTROL( OpenGLCanvas, Gwen::Controls::Base ); @@ -62,6 +82,83 @@ class OpenGLCanvas : public Gwen::Controls::Base Redraw(); } + enum Frame + { + Map, + Odom, + WGS84 + }; + + void TransformToFrame(Frame src, Frame dst, Vec3d& pos) const + { + if (dst == Map) + { + if (src == Map) + { + // do nothing + } + else if (src == Odom) + { + // transform to map + pos = odom_to_map_.transform(pos); + } + else//wgs84 + { + // wgs84 to map + double x, y; + local_xy_.FromLatLon(pos.x, pos.y, x, y); + pos.x = x; + pos.y = y; + } + } + else if (dst == WGS84) + { + if (src == Map) + { + double lat, lon; + local_xy_.ToLatLon(pos.x, pos.y, lat, lon); + pos.x = lat; + pos.y = lon; + } + else if (src == Odom) + { + pos = odom_to_map_.transform(Vec3d(pos.x, pos.y, pos.z)); + double lat, lon; + local_xy_.ToLatLon(pos.x, pos.y, lat, lon); + pos.x = lat; + pos.y = lon; + } + else// wgs84 + { + // do nothing + } + } + else// odom + { + if (src == Map) + { + // transform to odom + pos = map_to_odom_.transform(pos); + } + else if (src == Odom) + { + // do nothing + } + else// wgs84 + { + // transform to map then odom + double x, y; + local_xy_.FromLatLon(pos.x, pos.y, x, y); + pos = map_to_odom_.transform(Vec3d(x, y, pos.z)); + } + } + } + + void TransformToView(Frame frame, Vec3d& pos) const + { + TransformToFrame(frame, wgs84_mode_ ? Map : Odom, pos); + } + inline std::string GetViewType() { return view_type_->GetValue(); @@ -77,50 +174,75 @@ class OpenGLCanvas : public Gwen::Controls::Base paused_ = paused; } - void ResetViewOrigin() + void ResetViewPosition() { view_x_->SetValue(0.0); view_y_->SetValue(0.0); view_z_->SetValue(0.0); - view_abs_x_ = 0.0; - view_abs_y_ = 0.0; - view_abs_z_ = 0.0; - view_lat_ = local_xy_.OriginLatitude(); - view_lon_ = local_xy_.OriginLongitude(); - view_alt_ = 0.0; Redraw(); } - double view_abs_x_ = 0.0; - double view_abs_y_ = 0.0; - double view_abs_z_ = 0.0; - - double view_lat_ = 0.0; - double view_lon_ = 0.0; - double view_alt_ = 0.0; + // okay, so the view has two parts, an origin (either 0 or set by a pose) + // then an offset + void GetViewCenter(double& x, double& y, double& z) + { + x = center_x_ + view_x_->GetValue(); + y = center_y_ + view_y_->GetValue(); + z = center_z_ + view_z_->GetValue(); + } // sets the origin if it hasnt already been set void SetLocalXY(double lat, double lon) { if (!local_xy_.Initialized() && lat != 0.0 && lon != 0.0) { + printf("initialized local xy to %f %f\n", lat, lon); local_xy_ = LocalXYUtil(lat, lon); } } + + // Sets the transform between wgs84 and odom + void SetTransform(double x, double y, double z, double yaw, double lat, double lon, double alt, double ayaw) + { + SetLocalXY(lat, lon); + // okay, setup map to odom tran + // okay, lets calculate the transform between map and odom + + // todo change all this to doubles later + + // first we want to get the position in vehicle frame + // todo add angles + Quaternion odom_rot = Quaternion::FromAngleAxis(yaw, Vec3f(0,0,1)); + Matrix3x4d odom_to_vehicle(Quaternion(), Vec3d(-x,-y,-z)); + Matrix3x4d rot_vehicle(odom_rot.inverse(), Vec3d(0,0,0)); + Quaternion map_rot = Quaternion::FromAngleAxis(ayaw, Vec3f(0,0,1)); +//ah ha, missing these + double abs_x, abs_y; + local_xy_.FromLatLon(lat, lon, abs_x, abs_y); + Matrix3x4d vehicle_to_map(map_rot, Vec3d(abs_x, abs_y, alt)); + + odom_to_map_ = (odom_to_vehicle*rot_vehicle)*vehicle_to_map; + + // then we want to add the vehicl + map_to_odom_ = odom_to_map_; + map_to_odom_.invert(); + } + // Sets the view origin void SetViewOrigin(double x, double y, double z, double lat, double lon, double alt) { - view_x_->SetValue(x); - view_y_->SetValue(y); - view_z_->SetValue(z); - view_lat_ = lat; - view_lon_ = lon; - view_alt_ = alt; - view_abs_z_ = alt; SetLocalXY(lat, lon); - local_xy_.FromLatLon(view_lat_, view_lon_, view_abs_x_, view_abs_y_); + + if (!wgs84_mode_) { + center_x_ = x; + center_y_ = y; + center_z_ = z; + } else { + local_xy_.FromLatLon(lat, lon, center_x_, center_y_); + center_z_ = alt; + } Redraw(); } @@ -132,13 +254,25 @@ class OpenGLCanvas : public Gwen::Controls::Base void Screenshot(); - bool wgs84_mode_ = false; void SetFrame(bool wgs84) { + if (wgs84 != wgs84_mode_) + { + // recenter if we have one + // todo + center_x_ = 0; + center_y_ = 0; + center_z_ = 0; + view_x_->SetValue(0.0); + view_y_->SetValue(0.0); + view_z_->SetValue(0.0); + } wgs84_mode_ = wgs84; + Redraw(); } - bool show_origin_ = true; + inline bool wgs84_mode() { return wgs84_mode_; } + void ShowOrigin(bool yn) { show_origin_ = yn; @@ -159,6 +293,11 @@ class OpenGLCanvas : public Gwen::Controls::Base } } + void WorldToPixel(double x, double y, double z, int& px, int& py); + + // always on 0 plane + //void PixelToWorld(int px, int py, double x, double y) + std::map CreateProperties(Gwen::Controls::Properties* props); protected: @@ -169,20 +308,14 @@ class OpenGLCanvas : public Gwen::Controls::Base void OnMouseClickRight( int /*x*/, int /*y*/, bool /*bDown*/ ) override; Gwen::Color m_Color; - double view_height_m_; + //double view_height_m_; bool mouse_down_ = false; Gwen::Point select_start_,select_end_; bool selecting_ = false; std::vector selected_aabbs_; - - //double view_x_ = 0.0; - //double view_y_ = 0.0; - //double view_z_ = 0.0; bool paused_ = false; - - //ViewType view_type_ = ViewType::Orbit; // Properties EnumProperty* view_type_; @@ -191,9 +324,14 @@ class OpenGLCanvas : public Gwen::Controls::Base FloatProperty* view_x_; FloatProperty* view_y_; FloatProperty* view_z_; + FloatProperty* view_h_; double x_mouse_position_ = 0.0; double y_mouse_position_ = 0.0; + + float proj_[16]; + float model_[16]; + int vp_[4]; }; #endif diff --git a/controls/Parameters.cpp b/controls/Parameters.cpp index 39f5af3..38f032d 100644 --- a/controls/Parameters.cpp +++ b/controls/Parameters.cpp @@ -31,22 +31,18 @@ GWEN_CONTROL_CONSTRUCTOR( Parameters ) //p->SetPos(0,0); } -Parameters* myself = 0; - void Parameters::SetNode(ps_node_t* node) { // lets also set up everything we need here node_ = node; - myself = this; - node->param_confirm_cb = Parameters::AckCB; + node->param_confirm_cb_data = (void*)this; struct ps_subscriber_options options; ps_subscriber_options_init(&options); options.skip = 0; options.queue_size = 100; - options.want_message_def = false; options.allocator = 0; options.ignore_local = false; options.preferred_transport = true ? 1 : 0; @@ -63,7 +59,7 @@ void Parameters::SetNode(ps_node_t* node) void Parameters::Layout( Gwen::Skin::Base* skin ) { // Update all of the parameters - /*for (auto param : params_) + for (auto param : params_) { param.second->Update(); } @@ -74,9 +70,9 @@ void Parameters::Layout( Gwen::Skin::Base* skin ) while (data = (pubsub::msg::Parameters*)ps_sub_deque(¶m_sub_)) { // assert that its properly formatted - if (data->name_length != data->min_length || - data->name_length != data->max_length || - data->name_length != data->value_length) + if (data->name.size() != data->min.size() || + data->name.size() != data->max.size() || + data->name.size() != data->value.size()) { printf("ERROR: Invalid parameter message.\n"); @@ -84,9 +80,11 @@ void Parameters::Layout( Gwen::Skin::Base* skin ) free(data); continue; } + + //printf("got parameter message\n"); // add parameters to our list - for (int i = 0; i < data->name_length; i++) + for (int i = 0; i < data->name.size(); i++) { // todo handle more than double DoubleParameter* param = 0; @@ -96,21 +94,23 @@ void Parameters::Layout( Gwen::Skin::Base* skin ) param = new DoubleParameter(this); param->Dock(Gwen::Pos::Top); param->SetNode(node_); + param->SetName(data->name[i]); + param->SetRange(data->min[i], data->max[i]); + param->SetRemoteValue(std::atof(data->value[i])); + param->SetLocalValue(std::atof(data->value[i]), false); params_[data->name[i]] = param; } else { + // configure things that could have changed (not name or local value) param = params_[data->name[i]]; + param->SetRange(data->min[i], data->max[i]); + param->SetRemoteValue(std::atof(data->value[i])); } - - // configure it - param->SetName(data->name[i]); - param->SetRange(data->min[i], data->max[i]); - param->SetValue(std::atof(data->value[i])); } data->~Parameters(); free(data); - }*/ + } Invalidate();// we are being hacky, just always invalidate so we keep laying out } diff --git a/controls/Parameters.h b/controls/Parameters.h index 5471090..11d9ef1 100644 --- a/controls/Parameters.h +++ b/controls/Parameters.h @@ -62,7 +62,7 @@ class DoubleParameter : public Gwen::Controls::Base max_ = new Gwen::Controls::Label( this ); max_->SetAlignment( Gwen::Pos::CenterV | Gwen::Pos::Left ); - max_->SetText( "10.0" ); + max_->SetText( "0.0" ); max_->Dock( Gwen::Pos::Right ); max_->SetTabable( false ); max_->SetKeyboardInputEnabled( false ); @@ -80,21 +80,23 @@ class DoubleParameter : public Gwen::Controls::Base label_->SetText(name); name_ = name; } - - void SetValue(double val) + + double remote_value_; + void SetRemoteValue(double val) { - text_box_->SetText(std::to_string(val)); - slider_->SetFloatValue(val); - last_commanded_value_ = val; + remote_value_ = val; + //printf("setting remote to %f\n", val); } - - // from acks - void UpdateValue(double val) + + void SetLocalValue(double val, bool send = true) { + //printf("setting local to %f\n", val); + if (send == false) + { + last_commanded_value_ = val; + } text_box_->SetText(std::to_string(val)); slider_->SetFloatValue(val); - - // todo, how to handle this messing up the slider } void SetRange(double min, double max) @@ -111,13 +113,24 @@ class DoubleParameter : public Gwen::Controls::Base void Update() { + // if the request timed out, reset to the last received value + if (!FloatEqual(last_commanded_value_, remote_value_)) + { + // if we fail to update after so long, give up + if (pubsub::Time::now() > last_changed_time_ + pubsub::Duration(2.0)) + { + SetLocalValue(remote_value_, false); + printf("Change timed out on parameter '%s', resetting to previous value %lf\n", name_.c_str(), remote_value_); + } + } + // if value still not equal to expected and the last request timed out, try again - if (slider_->GetFloatValue() == last_commanded_value_) + if (FloatEqual(remote_value_, last_commanded_value_)) { return; } - printf("%f != %f\n", slider_->GetFloatValue(), last_commanded_value_); + //printf("%f != %f\n", remote_value_, last_commanded_value_); // retry if value is not equal to expected after a little bit if (pubsub::Time::now() > last_commanded_time_ + pubsub::Duration(0.2)) @@ -128,23 +141,37 @@ class DoubleParameter : public Gwen::Controls::Base } private: + + static bool FloatEqual(double a, double b) + { + return std::abs(a-b) < 0.000001; + } void TextChanged(Gwen::Controls::Base* control) { double value = std::atof(text_box_->GetValue().c_str()); slider_->SetFloatValue(value); - SendUpdatedValue(value); + last_changed_time_ = pubsub::Time::now(); + if (!FloatEqual(value, last_commanded_value_))// prevents double sends on update + { + SendUpdatedValue(value); + } } void SliderMoved(Gwen::Controls::Base* control) { - text_box_->SetText(std::to_string(slider_->GetFloatValue())); - SendUpdatedValue(slider_->GetFloatValue()); + double value = slider_->GetFloatValue(); + text_box_->SetText(std::to_string(value)); + last_changed_time_ = pubsub::Time::now(); + if (!FloatEqual(value, last_commanded_value_))// prevents double sends on update + { + SendUpdatedValue(value); + } } void SendUpdatedValue(double value) { - // todo send the param change + //printf("Sending set param to set %s to %f\n", name_.c_str(), value); ps_node_set_parameter(node_, name_.c_str(), value); last_commanded_value_ = value; last_commanded_time_ = pubsub::Time::now(); @@ -163,12 +190,10 @@ class DoubleParameter : public Gwen::Controls::Base ps_node_t* node_; double last_commanded_value_ = 0.0; + pubsub::Time last_changed_time_ = pubsub::Time(0); pubsub::Time last_commanded_time_ = pubsub::Time(0); }; -class Parameters; -extern Parameters* myself; - class PubViz; class Parameters : public Gwen::Controls::Base { @@ -189,9 +214,10 @@ class Parameters : public Gwen::Controls::Base ps_sub_destroy(¶m_sub_); } - static void AckCB(const char* name, double value) + static void AckCB(const char* name, double value, void* data) { - printf("Got ack for %s %f\n", name, value); + Parameters* myself = (Parameters*)data; + //printf("Got param change ack for %s %f\n", name, value); auto iter = myself->params_.find(name); if (iter == myself->params_.end()) @@ -199,7 +225,7 @@ class Parameters : public Gwen::Controls::Base return; } - iter->second->UpdateValue(value); + iter->second->SetRemoteValue(value); } void SetNode(ps_node_t* node); diff --git a/controls/pubviz.cpp b/controls/pubviz.cpp index 340ab79..9180df9 100644 --- a/controls/pubviz.cpp +++ b/controls/pubviz.cpp @@ -52,6 +52,9 @@ #include "../plugins/Image.h" #include "../plugins/GPS.h" #include "../plugins/Gauge.h" +#include "../plugins/PlanPath.h" +#include "../plugins/Measure.h" +#include "../plugins/Map.h" #include #include @@ -87,6 +90,11 @@ PubViz::~PubViz() } void PubViz::OnConfigSave(Gwen::Event::Info info) +{ + SaveConfig(info.String.c_str()); +} + +void PubViz::SaveConfig(const std::string& file) { std::string config; // save our own configuration first @@ -132,7 +140,7 @@ void PubViz::OnConfigSave(Gwen::Event::Info info) config += "\n"; } - FILE* f = fopen(info.String.c_str(), "wb"); + FILE* f = fopen(file.c_str(), "wb"); fwrite(config.c_str(), 1, config.length(), f); fclose(f); } @@ -168,8 +176,16 @@ void PubViz::LoadConfig(const char* filename) FILE *f = fopen(filename, "rb"); if (f == 0) { + ((Gwen::Controls::WindowCanvas*)GetParent())->SetTitle("Pubviz"); + current_config_file_ = ""; return;// failed to open file } + + current_config_file_ = filename; + + std::string title = "Pubviz (" + std::string(filename) + ")"; + ((Gwen::Controls::WindowCanvas*)GetParent())->SetTitle(title); + fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); /* same as rewind(f); */ @@ -332,6 +348,18 @@ void PubViz::MenuItemSelect(Controls::Base* pControl) graphs_[graph] = true; } + else if (pMenuItem->GetText() == L"Save Config") + { + if (current_config_file_.length()) + { + // save! + SaveConfig(current_config_file_); + } + else + { + Gwen::Dialogs::FileSave(true, String("Save Config"), String("pubviz.config"), String(".config|*.config|All|*.*"), this, &ThisClass::OnConfigSave); + } + } else if (pMenuItem->GetText() == L"Save Config As") { Gwen::Dialogs::FileSave(true, String("Save Config"), String("pubviz.config"), String(".config|*.config|All|*.*"), this, &ThisClass::OnConfigSave); @@ -422,7 +450,8 @@ GWEN_CONTROL_CONSTRUCTOR(PubViz) Gwen::Controls::MenuItem* pRoot = menu_->AddItem(L"File"); pRoot->GetMenu()->AddItem(L"Clear Plugins", "", "")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddItem(L"Load Config", "", "Ctrl+O")->SetAction(this, &ThisClass::MenuItemSelect); - pRoot->GetMenu()->AddItem(L"Save Config As", "", "Ctrl+S")->SetAction(this, &ThisClass::MenuItemSelect); + pRoot->GetMenu()->AddItem(L"Save Config", "", "Ctrl+S")->SetAction(this, &ThisClass::MenuItemSelect); + pRoot->GetMenu()->AddItem(L"Save Config As", "", "Ctrl+Shift+S")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddDivider(); pRoot->GetMenu()->AddItem(L"Screenshot", "", "")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddDivider(); @@ -448,12 +477,12 @@ GWEN_CONTROL_CONSTRUCTOR(PubViz) pRoot->GetMenu()->AddDivider(); pRoot->GetMenu()->AddItem(L"Plot", "", "Ctrl+P")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddItem(L"Change Parameters", "", "Shift+P")->SetAction(this, &ThisClass::MenuItemSelect); - pause_item_ = pRoot->GetMenu()->AddItem(L"Pause", "", "")->SetAction(this, &ThisClass::MenuItemSelect); + pause_item_ = pRoot->GetMenu()->AddItem(L"Pause", "", "Space")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddItem(L"Clear History", "", "")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddDivider(); pRoot->GetMenu()->AddItem(L"Orbit", "", "Ctrl+O")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddItem(L"Top Down", "", "Ctrl+T")->SetAction(this, &ThisClass::MenuItemSelect); - pRoot->GetMenu()->AddItem(L"First Person", "", "Ctrl+T")->SetAction(this, &ThisClass::MenuItemSelect); + pRoot->GetMenu()->AddItem(L"First Person", "", "")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddDivider(); pRoot->GetMenu()->AddItem(L"Top", "", "")->SetAction(this, &ThisClass::MenuItemSelect); pRoot->GetMenu()->AddItem(L"Left", "", "")->SetAction(this, &ThisClass::MenuItemSelect); @@ -522,7 +551,7 @@ GWEN_CONTROL_CONSTRUCTOR(PubViz) ps_node_system_query(&node_); - node_.adv_cb = [](const char* topic, const char* type, const char* node, const ps_advertise_req_t* data, void* cbdata) + node_.adv_cb = [](const char* topic, const char* type, const char* node, const ps_advertise_req_t* data, void* cb_data) { // check if we already have the topic if (_found_topics.find(topic) != _found_topics.end()) @@ -550,14 +579,15 @@ GWEN_CONTROL_CONSTRUCTOR(PubViz) //AddPlugin("image"); - AddPlugin("gauge"); + //AddPlugin("gauge"); AddPlugin("grid"); - AddPlugin("gps"); - AddPlugin("costmap"); - AddPlugin("marker"); - AddPlugin("pointcloud"); - AddPlugin("path"); - AddPlugin("pose"); + //AddPlugin("gps"); + //AddPlugin("costmap"); + //AddPlugin("marker"); + //AddPlugin("pointcloud"); + //AddPlugin("path"); + //AddPlugin("pose"); + //AddPlugin("plan_path"); add_button->onPress.Add( this, &ThisClass::OnAddPlugin ); @@ -671,6 +701,19 @@ pubviz::Plugin* PubViz::AddPlugin(const std::string& name) box->SetChecked(true); box->SetMargin(Padding(0, 0, 5, 0)); + auto b = new Gwen::Controls::Button(node->GetButton()); + b->SetText("v"); + b->SizeToContents(); + b->Dock(Pos::Right); + b->onDown.Add(this, &PubViz::OnDownPlugin);// should be on up, but it gets triggered twice somehow + b->UserData.Set("plugin", plugin); + b = new Gwen::Controls::Button(node->GetButton()); + b->SetText("^"); + b->SizeToContents(); + b->Dock(Pos::Right); + b->onDown.Add(this, &PubViz::OnUpPlugin); + b->UserData.Set("plugin", plugin); + plugin->tree_node_ = node; plugin->enabled_ = box; plugin->Initialize(props); @@ -690,13 +733,105 @@ pubviz::Plugin* PubViz::AddPlugin(const std::string& name) return plugin; } +template +int find(const T& t, const B& value) +{ + for (int i = 0; i < t.size(); i++) + { + if (t[i] == value) + { + return i; + } + } + return -1; +} + +void PubViz::OnUpPlugin(Gwen::Controls::Base* control) +{ + auto plugin = control->UserData.Get("plugin"); + + auto p = plugin->props_->GetParent(); + auto pp = p->GetParent(); + auto& children = ((Gwen::Controls::TreeNode*)pp)->GetChildNodes(); + + // then reorder our plugins + auto old = plugins_; + int index = find(old, plugin); + if (index == 0) + { + return;// nothing to do + } + + plugins_.clear(); + for (int i = 0; i < index - 1; i++) + { + plugins_.push_back(old[i]); + } + plugins_.push_back(plugin); + plugins_.push_back(old[index-1]); + for (int i = index+1; i < old.size(); i++) + { + plugins_.push_back(old[i]); + } + canvas_->plugins_ = plugins_; + + // then add back all the children + auto start = children.front(); + children.clear(); + children.push_back(start); + for (const auto& p: plugins_) + { + children.push_back(p->props_->GetParent()); + } + p->InvalidateParent(); +} + +void PubViz::OnDownPlugin(Gwen::Controls::Base* control) +{ + auto plugin = control->UserData.Get("plugin"); + auto p = plugin->props_->GetParent(); + auto pp = p->GetParent(); + auto& children = ((Gwen::Controls::TreeNode*)pp)->GetChildNodes(); + + // then reorder our plugins + auto old = plugins_; + int index = find(old, plugin); + if (index == (old.size()-1)) + { + return;// nothing to do + } + + plugins_.clear(); + for (int i = 0; i <= index - 1; i++) + { + plugins_.push_back(old[i]); + } + plugins_.push_back(old[index+1]); + plugins_.push_back(plugin); + for (int i = index+2; i < old.size(); i++) + { + plugins_.push_back(old[i]); + } + canvas_->plugins_ = plugins_; + + // then add back all the children + auto start = children.front(); + children.clear(); + children.push_back(start); + for (const auto& p: plugins_) + { + children.push_back(p->props_->GetParent()); + } + p->InvalidateParent(); +} + void PubViz::OnAddPlugin(Gwen::Controls::Base* control) { Controls::WindowControl* window = new Controls::WindowControl( GetCanvas() ); window->SetTitle( L"Add Plugin" ); window->SetSize( 200, 100 ); window->MakeModal( true ); - window->Position( Pos::Center ); + window->SetPos(GetCanvas()->Width()/2 - 100, GetCanvas()->Height()/2 - 50); window->SetDeleteOnClose( true ); Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox( window ); @@ -762,17 +897,28 @@ void PubViz::Render(Gwen::Skin::Base* skin) { double x, y; canvas_->GetMousePosition(x, y); - m_StatusBar->SetText(Gwen::Utility::Format(L"%i fps X: %f Y: %f", val * 2, x, y)); + if (canvas_->wgs84_mode_) + { + double lat, lon; + canvas_->local_xy_.ToLatLon(x, y, lat, lon); + m_StatusBar->SetText(Gwen::Utility::Format(L"%i fps Lat: %f Lon: %f", val * 2, lat, lon)); + } + else + { + m_StatusBar->SetText(Gwen::Utility::Format(L"%i fps X: %f Y: %f", val * 2, x, y)); + } } else { if (canvas_->wgs84_mode_) { - m_StatusBar->SetText(Gwen::Utility::Format(L"%i fps Lat: %f Lon: %f Alt: %f", val * 2, canvas_->view_lat_, canvas_->view_lon_, canvas_->view_alt_)); + m_StatusBar->SetText(Gwen::Utility::Format(L"%i fps", val * 2)); } else { - m_StatusBar->SetText(Gwen::Utility::Format(L"%i fps X: %f Y: %f Z: %f", val * 2, canvas_->view_x_, canvas_->view_y_, canvas_->view_z_)); + double x, y, z; + canvas_->GetViewCenter(x, y, z); + m_StatusBar->SetText(Gwen::Utility::Format(L"%i fps X: %f Y: %f Z: %f", val * 2, x, y, z)); } } diff --git a/controls/pubviz.h b/controls/pubviz.h index 103bd84..2cc303d 100644 --- a/controls/pubviz.h +++ b/controls/pubviz.h @@ -68,6 +68,7 @@ class GraphCanvas; class PubViz: public Gwen::Controls::DockBase { std::map properties_; + std::string current_config_file_; public: GWEN_CONTROL(PubViz, Gwen::Controls::DockBase); @@ -83,6 +84,7 @@ class PubViz: public Gwen::Controls::DockBase pubviz::Plugin* AddPlugin(const std::string& name); void LoadConfig(const char* filename); + void SaveConfig(const std::string& file); inline Gwen::Controls::TreeControl* GetSelection() { return selection_; } @@ -92,6 +94,8 @@ class PubViz: public Gwen::Controls::DockBase void OnAddPlugin(Gwen::Controls::Base* control); void OnRemovePlugin( Gwen::Controls::Base* control); void OnAddPluginFinish(Gwen::Controls::Base* control); + void OnUpPlugin(Gwen::Controls::Base* control); + void OnDownPlugin(Gwen::Controls::Base* control); void OnCenter(Gwen::Controls::Base* control); void OnShowConfigChanged(Gwen::Controls::Base* control); void OnShowSelectionChanged(Gwen::Controls::Base* control); diff --git a/plugins/Costmap.h b/plugins/Costmap.h index 95cc8b4..dc03e2e 100644 --- a/plugins/Costmap.h +++ b/plugins/Costmap.h @@ -33,18 +33,20 @@ class CostmapPlugin: public pubviz::Plugin FloatProperty* alpha_; ColorProperty* color_; BooleanProperty* show_outline_; + NumberProperty* alpha_threshold_; TopicProperty* topic_; bool sub_open_ = false; ps_sub_t subscriber_; - pubsub::msg::Costmap last_msg_; + pubsub::msg::Costmap* last_msg_ = 0; unsigned int texture_ = -1; void UpdateFromMessage() { + if (last_msg_ == 0) return; Redraw(); if (texture_ != -1) @@ -52,24 +54,27 @@ class CostmapPlugin: public pubviz::Plugin glDeleteTextures(1, &texture_); } - if (last_msg_.width* last_msg_.height != last_msg_.data_length) + if (last_msg_->width * last_msg_->height != last_msg_->data.size()) { - last_msg_.data_length = 0; + delete last_msg_; + last_msg_ = 0; printf("ERROR: bad costmap size\n"); return; } // make the color buffer std::vector pixels; - pixels.resize(last_msg_.width*last_msg_.height); + pixels.resize(last_msg_->width*last_msg_->height); int texture_size = pixels.size()*4; + + int32_t alpha_threshold = alpha_threshold_->GetValue(); // now fill in each pixel with the intensity - for (int i = 0; i < last_msg_.data_length; i++) + for (int i = 0; i < last_msg_->data.size(); i++) { - uint8_t px = last_msg_.data[i]; - uint8_t a = 255; + uint8_t px = last_msg_->data[i]; + uint8_t a = px <= alpha_threshold ? 0 : 255; pixels[i] = (a << 24) | (px << 16) | (px << 8) | px; } @@ -90,8 +95,8 @@ class CostmapPlugin: public pubviz::Plugin GL_TEXTURE_2D, 0, GL_RGBA, - last_msg_.width, - last_msg_.height, + last_msg_->width, + last_msg_->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @@ -122,18 +127,7 @@ class CostmapPlugin: public pubviz::Plugin public: CostmapPlugin() - { - // just make a quick test costmap - last_msg_.frame = 0; - last_msg_.width = 10; - last_msg_.height = 10; - last_msg_.resolution = 5.0; - last_msg_.left = 0.0; - last_msg_.bottom = 0.0; - last_msg_.data_length = 0;//10*10; - //last_msg_.data = new uint8_t[10*10]; - //UpdateFromMessage(); - + { // dont use pubsub here } @@ -142,6 +136,11 @@ class CostmapPlugin: public pubviz::Plugin delete color_; delete alpha_; delete show_outline_; + + if (last_msg_) + { + delete last_msg_; + } if (sub_open_) { @@ -161,14 +160,12 @@ class CostmapPlugin: public pubviz::Plugin if (texture_ != -1) { glDeleteTextures(1, &texture_); - last_msg_.data_length = 0; - free(last_msg_.data); - last_msg_.data = 0; + delete last_msg_; + last_msg_ = 0; texture_ = -1; } } - virtual void Update() { // process any messages @@ -180,15 +177,16 @@ class CostmapPlugin: public pubviz::Plugin { if (Paused()) { - free(data->data); - free(data);//todo use allocator free + delete data; continue; } // user is responsible for freeing the message and its arrays - last_msg_ = *data; - free(data->data); - free(data);//todo use allocator free + if (last_msg_) + { + delete last_msg_; + } + last_msg_ = data; UpdateFromMessage(); } } @@ -197,19 +195,26 @@ class CostmapPlugin: public pubviz::Plugin virtual void Render() { // exit early if we dont have a messag - if (last_msg_.data_length == 0) + if (last_msg_ == 0) { return; } + + double width = last_msg_->resolution*last_msg_->width; + double height = last_msg_->resolution*last_msg_->height; + + Vec3d pts[4]; + pts[0] = Vec3d(last_msg_->left, last_msg_->bottom, 0); + pts[1] = Vec3d(last_msg_->left, last_msg_->bottom + height, 0); + pts[2] = Vec3d(last_msg_->left + width, last_msg_->bottom + height, 0); + pts[3] = Vec3d(last_msg_->left + width, last_msg_->bottom, 0); - if (GetCanvas()->wgs84_mode_) + // transform to view frame + for (int i = 0; i < 4; i++) { - return;// not supported for the moment + GetCanvas()->TransformToView(OpenGLCanvas::Odom, pts[i]); } - double width = last_msg_.resolution*last_msg_.width; - double height = last_msg_.resolution*last_msg_.height; - // draw the bounds of the costmap if (show_outline_->GetValue()) { @@ -219,16 +224,18 @@ class CostmapPlugin: public pubviz::Plugin Gwen::Color color = color_->GetValue(); glColor3f(color.r/255.0, color.g/255.0, color.b/255.0); - glVertex2f(last_msg_.left, last_msg_.bottom); - glVertex2f(last_msg_.left, last_msg_.bottom + height); - glVertex2f(last_msg_.left + width, last_msg_.bottom + height); - glVertex2f(last_msg_.left + width, last_msg_.bottom); - glVertex2f(last_msg_.left, last_msg_.bottom); + glVertex2f(pts[0].x, pts[0].y); + glVertex2f(pts[1].x, pts[1].y); + glVertex2f(pts[2].x, pts[2].y); + glVertex2f(pts[3].x, pts[3].y); + glVertex2f(pts[0].x, pts[0].y); glEnd(); } glEnable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0); // Now draw the costmap itself glEnable(GL_TEXTURE_2D); @@ -238,24 +245,25 @@ class CostmapPlugin: public pubviz::Plugin glColor4f(1.0f, 1.0f, 1.0f, alpha_->GetValue() ); glTexCoord2d(0, 0); - glVertex2d(last_msg_.left + 0, last_msg_.bottom + 0); + glVertex2f(pts[0].x, pts[0].y); glTexCoord2d(1.0, 0); - glVertex2d(last_msg_.left + width, last_msg_.bottom + 0); + glVertex2f(pts[3].x, pts[3].y); glTexCoord2d(1.0, 1.0); - glVertex2d(last_msg_.left + width, last_msg_.bottom + height); + glVertex2f(pts[2].x, pts[2].y); glTexCoord2d(0, 0); - glVertex2d(last_msg_.left + 0, last_msg_.bottom + 0); + glVertex2f(pts[0].x, pts[0].y); glTexCoord2d(1.0, 1.0); - glVertex2d(last_msg_.left + width, last_msg_.bottom + height); + glVertex2f(pts[2].x, pts[2].y); glTexCoord2d(0, 1.0); - glVertex2d(last_msg_.left + 0, last_msg_.bottom + height); + glVertex2f(pts[1].x, pts[1].y); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); } @@ -269,6 +277,12 @@ class CostmapPlugin: public pubviz::Plugin show_outline_ = AddBooleanProperty(tree, "Show Outline", true, "If true, draw an outline around the costmap."); color_ = AddColorProperty(tree, "Outline Color", Gwen::Color(255,50,50), "Color to use to draw border of costmap."); + + alpha_threshold_ = AddNumberProperty(tree, "Alpha Threshold", -1, -1, 255, 1, "Costs at or below which costmap cells are invisible."); + alpha_threshold_->onChange = [this](int number) + { + UpdateFromMessage(); + }; Subscribe(topic_->GetValue()); } diff --git a/plugins/Dial.h b/plugins/Dial.h deleted file mode 100644 index 1e1263c..0000000 --- a/plugins/Dial.h +++ /dev/null @@ -1,329 +0,0 @@ - -#ifndef PUBVIZ_PLUGIN_GAUGE_H -#define PUBVIZ_PLUGIN_GAUGE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GLEW_STATIC -#include - -#ifndef _WIN32 -#include -#include -#include -#include -#endif - -#include "../Plugin.h" -#include "../properties.h" - -#include - -class GaugePlugin: public pubviz::Plugin -{ - FloatProperty* min_value_; - FloatProperty* max_value_; - BooleanProperty* auto_minmax_; - - NumberProperty* x_position_, *y_position_; - NumberProperty* size_; - - TopicProperty* topic_; - StringProperty* field_; - - bool sub_open_ = false; - ps_sub_t subscriber_; - double current_value_ = NAN; - - std::string current_topic_; - void Subscribe(std::string str) - { - if (sub_open_) - { - ps_sub_destroy(&subscriber_); - } - - Clear(); - - current_topic_ = str; - struct ps_subscriber_options options; - ps_subscriber_options_init(&options); - options.preferred_transport = 1;// tcp yo - options.want_message_def = true; - ps_node_create_subscriber_adv(GetNode(), current_topic_.c_str(), NULL, &subscriber_, &options); - sub_open_ = true; - } - -public: - - GaugePlugin() - { - - } - - virtual ~GaugePlugin() - { - if (sub_open_) - { - ps_sub_destroy(&subscriber_); - sub_open_ = false; - } - } - - // Clear out any historical data so the view gets cleared - virtual void Clear() - { - current_value_ = NAN; - } - - virtual void Update() - { - // process any messages - // our sub has a message definition, so the queue contains real messages - if (sub_open_) - { - while (char* data = (char*)ps_sub_deque(&subscriber_)) - { - if (Paused()) - { - free(data);//todo use allocator free - continue; - } - - HandleMessage(data); - - // user is responsible for freeing the message and its arrays - free(data); - } - } - } - - void HandleMessage(const char* msg) - { - if (!subscriber_.received_message_def.fields) - { - return; - } - - current_value_ = NAN; - - struct ps_deserialize_iterator iter = ps_deserialize_start((const char*)msg, &subscriber_.received_message_def); - const struct ps_msg_field_t* field; uint32_t length; const char* ptr; - while (ptr = ps_deserialize_iterate(&iter, &field, &length)) - { - if (strcmp(field->name, field_->GetValue().c_str()) != 0) - { - continue; - } - if (field->type == FT_String) - { - // strings are already null terminated - //printf("%s: %s\n", field->name, ptr); - // what should I do about strings? - } - else - { - if (length > 0) - { - double value = 0; - // non dynamic types - switch (field->type) - { - case FT_Int8: - value = *(int8_t*)ptr; - break; - case FT_Int16: - value = *(int16_t*)ptr; - break; - case FT_Int32: - value = *(int32_t*)ptr; - break; - case FT_Int64: - value = *(int64_t*)ptr; - break; - case FT_UInt8: - value = *(uint8_t*)ptr; - break; - case FT_UInt16: - value = *(uint16_t*)ptr; - break; - case FT_UInt32: - value = *(uint32_t*)ptr; - break; - case FT_UInt64: - value = *(uint64_t*)ptr; - break; - case FT_Float32: - value = *(float*)ptr; - break; - case FT_Float64: - value = *(double*)ptr; - break; - default: - printf("ERROR: unhandled field type when parsing....\n"); - } - - current_value_ = value; - Redraw(); - break; - } - } - } - } - - virtual void Render() - { - - } - - virtual void Paint() - { - // nothing to do here since we dont render to the world - // actually, lets render to the world? - //current_value_ = rand()%11; - - glLineWidth(3.0); - - auto r = GetCanvas()->GetSkin()->GetRender(); - Gwen::Point pos = r->GetRenderOffset(); - //glLoadIdentity(); - //glRotatef(yaw, 0, 0, 1); - auto scale = GetCanvas()->GetCanvas()->Scale(); - //glTranslatef(pos.x*scale, pos.y*scale, 0);// shift it so 0, 0 is _our_ top left corner - //glScalef(scale, scale, 1.0); - - const int start_x = x_position_->GetValue() + pos.x; - const int start_y = y_position_->GetValue() + pos.y; - const float radius = size_->GetValue(); - const float height = radius/2.0; - - // draw it bitch - const int num_pts = 20; - const double radians_per_pt = M_PI/num_pts; - glBegin(GL_LINE_STRIP); - float opts[num_pts*2+2]; - for (int i = 0; i <= num_pts; i++) - { - float x = start_x + height + height*cos(radians_per_pt*i); - float y = start_y + (height - height*sin(radians_per_pt*i)); - //printf("x: %f y: %f\n", x, y); - // want to draw a half circle - glColor4f(1.0, 1.0, 1.0, 1.0); - glVertex2f(x*scale, y*scale); - opts[i*2] = x*scale; - opts[i*2+1] = y*scale; - } - - // now draw the inner part - const float inner_radius = radius*0.5; - float ipts[num_pts*2+2]; - for (int i = num_pts; i >= 0; i--) - { - float x = start_x + height + inner_radius*cos(radians_per_pt*i)*0.5; - float y = start_y + (height - inner_radius*sin(radians_per_pt*i)*0.5); - //printf("x: %f y: %f\n", x, y); - // want to draw a half circle - glColor4f(1.0, 1.0, 1.0, 1.0); - glVertex2f(x*scale, y*scale); - ipts[i*2] = x*scale; - ipts[i*2+1] = y*scale; - } - glVertex2f((start_x + radius)*scale, (start_y + height)*scale); - glEnd(); - - if (std::isnan(current_value_)) - { - return; - } - - float frac = (current_value_-min_value_->GetValue())/(max_value_->GetValue() - min_value_->GetValue()); - frac = std::max(0.0f, std::min(1.0f, frac)); - float angle = M_PI - std::max(0.0f, std::min(1.0f, frac))*M_PI; - - // draw a colored inside? - glBegin(GL_TRIANGLES); - for (int j = 0; j < 20; j++) - { - int i = j;//num_pts - j; - glColor4f(0, 0, 0, 1); - glVertex2f(opts[i*2], opts[i*2+1]); - glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); - glVertex2f(ipts[i*2], ipts[i*2+1]); - - glVertex2f(ipts[(i+1)*2], ipts[(i+1)*2+1]); - glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); - glVertex2f(ipts[i*2], ipts[i*2+1]); - } - for (int j = 0; j < num_pts*frac; j++) - { - int i = std::min(19, num_pts - j); - glColor4f(2*(frac), 2*(1.0-frac), 0, 1); - glVertex2f(opts[i*2], opts[i*2+1]); - glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); - glVertex2f(ipts[i*2], ipts[i*2+1]); - - glVertex2f(ipts[(i+1)*2], ipts[(i+1)*2+1]); - glVertex2f(opts[(i+1)*2], opts[(i+1)*2+1]); - glVertex2f(ipts[i*2], ipts[i*2+1]); - } - // then draw the last segment - glEnd(); - - glLineWidth(5.0); - glBegin(GL_LINES); - glColor4f(0, 0, 0, 1); - glVertex2f((start_x + radius/2)*scale, (start_y + height)*scale); - glVertex2f((start_x + height + height*cos(angle))*scale, (start_y + (height - height*sin(angle)))*scale); - glEnd(); - - glLineWidth(2.0); - glBegin(GL_LINES); - glColor4f(1, 1, 1, 1); - glVertex2f((start_x + radius/2)*scale, (start_y + height)*scale); - glVertex2f((start_x + height + height*cos(angle))*scale, (start_y + (height - height*sin(angle)))*scale); - glEnd(); - - // draw the value - r->SetDrawColor( Gwen::Color(255,255,255,255) ); - char buf[50]; - sprintf(buf, "%g", current_value_); - r->RenderText(GetCanvas()->GetSkin()->GetDefaultFont(), Gwen::PointF( x_position_->GetValue(), y_position_->GetValue() + height ), (std::string)buf); - } - - virtual void Initialize(Gwen::Controls::Properties* tree) - { - // add any properties - topic_ = AddTopicProperty(tree, "Topic", "/image", "", ""); - topic_->onChange = std::bind(&GaugePlugin::Subscribe, this, std::placeholders::_1); - - field_ = AddStringProperty(tree, "Field", "width"); - - min_value_ = AddFloatProperty(tree, "Minimum", 0, -10000000, 100000); - max_value_ = AddFloatProperty(tree, "Maximum", 10, -10000000, 100000); - - x_position_ = AddNumberProperty(tree, "X Offset", 0, 0, 10000); - y_position_ = AddNumberProperty(tree, "Y Offset", 0, 0, 10000); - size_ = AddNumberProperty(tree, "Size", 100, 1, 10000); - - Subscribe(topic_->GetValue()); - } - - std::string GetTitle() override - { - return "Gauge"; - } -}; - -REGISTER_PLUGIN("gauge", GaugePlugin) - -#endif diff --git a/plugins/FreeImage.h b/plugins/FreeImage.h deleted file mode 100644 index 549a195..0000000 --- a/plugins/FreeImage.h +++ /dev/null @@ -1,1117 +0,0 @@ -// ========================================================== -// FreeImage 3 -// -// Design and implementation by -// - Floris van den Berg (flvdberg@wxs.nl) -// - Hervé Drolon (drolon@infonie.fr) -// -// Contributors: -// - see changes log named 'Whatsnew.txt', see header of each .h and .cpp file -// -// This file is part of FreeImage 3 -// -// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES -// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE -// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED -// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT -// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY -// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL -// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER -// THIS DISCLAIMER. -// -// Use at your own risk! -// ========================================================== - -#ifndef FREEIMAGE_H -#define FREEIMAGE_H - -// Version information ------------------------------------------------------ - -#define FREEIMAGE_MAJOR_VERSION 3 -#define FREEIMAGE_MINOR_VERSION 15 -#define FREEIMAGE_RELEASE_SERIAL 0 - -// Compiler options --------------------------------------------------------- - -#include // needed for UNICODE functions - -#if defined(FREEIMAGE_LIB) -#define DLL_API -#define DLL_CALLCONV -#else -#if defined(_WIN32) || defined(__WIN32__) -#define DLL_CALLCONV __stdcall -// The following ifdef block is the standard way of creating macros which make exporting -// from a DLL simpler. All files within this DLL are compiled with the FREEIMAGE_EXPORTS -// symbol defined on the command line. this symbol should not be defined on any project -// that uses this DLL. This way any other project whose source files include this file see -// DLL_API functions as being imported from a DLL, wheras this DLL sees symbols -// defined with this macro as being exported. -#ifdef FREEIMAGE_EXPORTS -#define DLL_API __declspec(dllexport) -#else -#define DLL_API __declspec(dllimport) -#endif // FREEIMAGE_EXPORTS -#else -// try the gcc visibility support (see http://gcc.gnu.org/wiki/Visibility) -#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#ifndef GCC_HASCLASSVISIBILITY -#define GCC_HASCLASSVISIBILITY -#endif -#endif // __GNUC__ -#define DLL_CALLCONV -#if defined(GCC_HASCLASSVISIBILITY) -#define DLL_API __attribute__ ((visibility("default"))) -#else -#define DLL_API -#endif -#endif // WIN32 / !WIN32 -#endif // FREEIMAGE_LIB - -// Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined -// If your big endian system isn't being detected, add an OS specific check -#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \ - (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \ - defined(__BIG_ENDIAN__) -#define FREEIMAGE_BIGENDIAN -#endif // BYTE_ORDER - -// This really only affects 24 and 32 bit formats, the rest are always RGB order. -#define FREEIMAGE_COLORORDER_BGR 0 -#define FREEIMAGE_COLORORDER_RGB 1 -#if defined(FREEIMAGE_BIGENDIAN) -#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB -#else -#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR -#endif - -// Ensure 4-byte enums if we're using Borland C++ compilers -#if defined(__BORLANDC__) -#pragma option push -b -#endif - -// For C compatibility -------------------------------------------------------- - -#ifdef __cplusplus -#define FI_DEFAULT(x) = x -#define FI_ENUM(x) enum x -#define FI_STRUCT(x) struct x -#else -#define FI_DEFAULT(x) -#define FI_ENUM(x) typedef int x; enum x -#define FI_STRUCT(x) typedef struct x x; struct x -#endif - -// Bitmap types ------------------------------------------------------------- - -FI_STRUCT( FIBITMAP ) { void* data; }; -FI_STRUCT( FIMULTIBITMAP ) { void* data; }; - -// Types used in the library (directly copied from Windows) ----------------- - -#if defined(__MINGW32__) && defined(_WINDOWS_H) -#define _WINDOWS_ // prevent a bug in MinGW32 -#endif // __MINGW32__ - -#ifndef _WINDOWS_ -#define _WINDOWS_ - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef NULL -#define NULL 0 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 -#endif - -#ifndef _MSC_VER -// define portable types for 32-bit / 64-bit OS -#include -typedef int32_t BOOL; -typedef uint8_t BYTE; -typedef uint16_t WORD; -typedef uint32_t DWORD; -typedef int32_t LONG; -#else -// MS is not C99 ISO compliant -typedef long BOOL; -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef long LONG; -#endif // _MSC_VER - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif // WIN32 - -typedef struct tagRGBQUAD -{ -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR - BYTE rgbBlue; - BYTE rgbGreen; - BYTE rgbRed; -#else - BYTE rgbRed; - BYTE rgbGreen; - BYTE rgbBlue; -#endif // FREEIMAGE_COLORORDER - BYTE rgbReserved; -} RGBQUAD; - -typedef struct tagRGBTRIPLE -{ -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR - BYTE rgbtBlue; - BYTE rgbtGreen; - BYTE rgbtRed; -#else - BYTE rgbtRed; - BYTE rgbtGreen; - BYTE rgbtBlue; -#endif // FREEIMAGE_COLORORDER -} RGBTRIPLE; - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(pop) -#else -#pragma pack() -#endif // WIN32 - -typedef struct tagBITMAPINFOHEADER -{ - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; -} BITMAPINFOHEADER, *PBITMAPINFOHEADER; - -typedef struct tagBITMAPINFO -{ - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[1]; -} BITMAPINFO, *PBITMAPINFO; - -#endif // _WINDOWS_ - -// Types used in the library (specific to FreeImage) ------------------------ - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif // WIN32 - -/** 48-bit RGB -*/ -typedef struct tagFIRGB16 -{ - WORD red; - WORD green; - WORD blue; -} FIRGB16; - -/** 64-bit RGBA -*/ -typedef struct tagFIRGBA16 -{ - WORD red; - WORD green; - WORD blue; - WORD alpha; -} FIRGBA16; - -/** 96-bit RGB Float -*/ -typedef struct tagFIRGBF -{ - float red; - float green; - float blue; -} FIRGBF; - -/** 128-bit RGBA Float -*/ -typedef struct tagFIRGBAF -{ - float red; - float green; - float blue; - float alpha; -} FIRGBAF; - -/** Data structure for COMPLEX type (complex number) -*/ -typedef struct tagFICOMPLEX -{ - /// real part - double r; - /// imaginary part - double i; -} FICOMPLEX; - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(pop) -#else -#pragma pack() -#endif // WIN32 - -// Indexes for byte arrays, masks and shifts for treating pixels as words --- -// These coincide with the order of RGBQUAD and RGBTRIPLE ------------------- - -#ifndef FREEIMAGE_BIGENDIAN -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR -// Little Endian (x86 / MS Windows, Linux) : BGR(A) order -#define FI_RGBA_RED 2 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 0 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x00FF0000 -#define FI_RGBA_GREEN_MASK 0x0000FF00 -#define FI_RGBA_BLUE_MASK 0x000000FF -#define FI_RGBA_ALPHA_MASK 0xFF000000 -#define FI_RGBA_RED_SHIFT 16 -#define FI_RGBA_GREEN_SHIFT 8 -#define FI_RGBA_BLUE_SHIFT 0 -#define FI_RGBA_ALPHA_SHIFT 24 -#else -// Little Endian (x86 / MaxOSX) : RGB(A) order -#define FI_RGBA_RED 0 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 2 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x000000FF -#define FI_RGBA_GREEN_MASK 0x0000FF00 -#define FI_RGBA_BLUE_MASK 0x00FF0000 -#define FI_RGBA_ALPHA_MASK 0xFF000000 -#define FI_RGBA_RED_SHIFT 0 -#define FI_RGBA_GREEN_SHIFT 8 -#define FI_RGBA_BLUE_SHIFT 16 -#define FI_RGBA_ALPHA_SHIFT 24 -#endif // FREEIMAGE_COLORORDER -#else -#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR -// Big Endian (PPC / none) : BGR(A) order -#define FI_RGBA_RED 2 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 0 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0x0000FF00 -#define FI_RGBA_GREEN_MASK 0x00FF0000 -#define FI_RGBA_BLUE_MASK 0xFF000000 -#define FI_RGBA_ALPHA_MASK 0x000000FF -#define FI_RGBA_RED_SHIFT 8 -#define FI_RGBA_GREEN_SHIFT 16 -#define FI_RGBA_BLUE_SHIFT 24 -#define FI_RGBA_ALPHA_SHIFT 0 -#else -// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order -#define FI_RGBA_RED 0 -#define FI_RGBA_GREEN 1 -#define FI_RGBA_BLUE 2 -#define FI_RGBA_ALPHA 3 -#define FI_RGBA_RED_MASK 0xFF000000 -#define FI_RGBA_GREEN_MASK 0x00FF0000 -#define FI_RGBA_BLUE_MASK 0x0000FF00 -#define FI_RGBA_ALPHA_MASK 0x000000FF -#define FI_RGBA_RED_SHIFT 24 -#define FI_RGBA_GREEN_SHIFT 16 -#define FI_RGBA_BLUE_SHIFT 8 -#define FI_RGBA_ALPHA_SHIFT 0 -#endif // FREEIMAGE_COLORORDER -#endif // FREEIMAGE_BIGENDIAN - -#define FI_RGBA_RGB_MASK (FI_RGBA_RED_MASK|FI_RGBA_GREEN_MASK|FI_RGBA_BLUE_MASK) - -// The 16bit macros only include masks and shifts, since each color element is not byte aligned - -#define FI16_555_RED_MASK 0x7C00 -#define FI16_555_GREEN_MASK 0x03E0 -#define FI16_555_BLUE_MASK 0x001F -#define FI16_555_RED_SHIFT 10 -#define FI16_555_GREEN_SHIFT 5 -#define FI16_555_BLUE_SHIFT 0 -#define FI16_565_RED_MASK 0xF800 -#define FI16_565_GREEN_MASK 0x07E0 -#define FI16_565_BLUE_MASK 0x001F -#define FI16_565_RED_SHIFT 11 -#define FI16_565_GREEN_SHIFT 5 -#define FI16_565_BLUE_SHIFT 0 - -// ICC profile support ------------------------------------------------------ - -#define FIICC_DEFAULT 0x00 -#define FIICC_COLOR_IS_CMYK 0x01 - -FI_STRUCT( FIICCPROFILE ) -{ - WORD flags; // info flag - DWORD size; // profile's size measured in bytes - void* data; // points to a block of contiguous memory containing the profile -}; - -// Important enums ---------------------------------------------------------- - -/** I/O image format identifiers. -*/ -FI_ENUM( FREE_IMAGE_FORMAT ) -{ - FIF_UNKNOWN = -1, - FIF_BMP = 0, - FIF_ICO = 1, - FIF_JPEG = 2, - FIF_JNG = 3, - FIF_KOALA = 4, - FIF_LBM = 5, - FIF_IFF = FIF_LBM, - FIF_MNG = 6, - FIF_PBM = 7, - FIF_PBMRAW = 8, - FIF_PCD = 9, - FIF_PCX = 10, - FIF_PGM = 11, - FIF_PGMRAW = 12, - FIF_PNG = 13, - FIF_PPM = 14, - FIF_PPMRAW = 15, - FIF_RAS = 16, - FIF_TARGA = 17, - FIF_TIFF = 18, - FIF_WBMP = 19, - FIF_PSD = 20, - FIF_CUT = 21, - FIF_XBM = 22, - FIF_XPM = 23, - FIF_DDS = 24, - FIF_GIF = 25, - FIF_HDR = 26, - FIF_FAXG3 = 27, - FIF_SGI = 28, - FIF_EXR = 29, - FIF_J2K = 30, - FIF_JP2 = 31, - FIF_PFM = 32, - FIF_PICT = 33, - FIF_RAW = 34 -}; - -/** Image type used in FreeImage. -*/ -FI_ENUM( FREE_IMAGE_TYPE ) -{ - FIT_UNKNOWN = 0, // unknown type - FIT_BITMAP = 1, // standard image : 1-, 4-, 8-, 16-, 24-, 32-bit - FIT_UINT16 = 2, // array of unsigned short : unsigned 16-bit - FIT_INT16 = 3, // array of short : signed 16-bit - FIT_UINT32 = 4, // array of unsigned long : unsigned 32-bit - FIT_INT32 = 5, // array of long : signed 32-bit - FIT_FLOAT = 6, // array of float : 32-bit IEEE floating point - FIT_DOUBLE = 7, // array of double : 64-bit IEEE floating point - FIT_COMPLEX = 8, // array of FICOMPLEX : 2 x 64-bit IEEE floating point - FIT_RGB16 = 9, // 48-bit RGB image : 3 x 16-bit - FIT_RGBA16 = 10, // 64-bit RGBA image : 4 x 16-bit - FIT_RGBF = 11, // 96-bit RGB float image : 3 x 32-bit IEEE floating point - FIT_RGBAF = 12 // 128-bit RGBA float image : 4 x 32-bit IEEE floating point -}; - -/** Image color type used in FreeImage. -*/ -FI_ENUM( FREE_IMAGE_COLOR_TYPE ) -{ - FIC_MINISWHITE = 0, // min value is white - FIC_MINISBLACK = 1, // min value is black - FIC_RGB = 2, // RGB color model - FIC_PALETTE = 3, // color map indexed - FIC_RGBALPHA = 4, // RGB color model with alpha channel - FIC_CMYK = 5 // CMYK color model -}; - -/** Color quantization algorithms. -Constants used in FreeImage_ColorQuantize. -*/ -FI_ENUM( FREE_IMAGE_QUANTIZE ) -{ - FIQ_WUQUANT = 0, // Xiaolin Wu color quantization algorithm - FIQ_NNQUANT = 1 // NeuQuant neural-net quantization algorithm by Anthony Dekker -}; - -/** Dithering algorithms. -Constants used in FreeImage_Dither. -*/ -FI_ENUM( FREE_IMAGE_DITHER ) -{ - FID_FS = 0, // Floyd & Steinberg error diffusion - FID_BAYER4x4 = 1, // Bayer ordered dispersed dot dithering (order 2 dithering matrix) - FID_BAYER8x8 = 2, // Bayer ordered dispersed dot dithering (order 3 dithering matrix) - FID_CLUSTER6x6 = 3, // Ordered clustered dot dithering (order 3 - 6x6 matrix) - FID_CLUSTER8x8 = 4, // Ordered clustered dot dithering (order 4 - 8x8 matrix) - FID_CLUSTER16x16 = 5, // Ordered clustered dot dithering (order 8 - 16x16 matrix) - FID_BAYER16x16 = 6 // Bayer ordered dispersed dot dithering (order 4 dithering matrix) -}; - -/** Lossless JPEG transformations -Constants used in FreeImage_JPEGTransform -*/ -FI_ENUM( FREE_IMAGE_JPEG_OPERATION ) -{ - FIJPEG_OP_NONE = 0, // no transformation - FIJPEG_OP_FLIP_H = 1, // horizontal flip - FIJPEG_OP_FLIP_V = 2, // vertical flip - FIJPEG_OP_TRANSPOSE = 3, // transpose across UL-to-LR axis - FIJPEG_OP_TRANSVERSE = 4, // transpose across UR-to-LL axis - FIJPEG_OP_ROTATE_90 = 5, // 90-degree clockwise rotation - FIJPEG_OP_ROTATE_180 = 6, // 180-degree rotation - FIJPEG_OP_ROTATE_270 = 7 // 270-degree clockwise (or 90 ccw) -}; - -/** Tone mapping operators. -Constants used in FreeImage_ToneMapping. -*/ -FI_ENUM( FREE_IMAGE_TMO ) -{ - FITMO_DRAGO03 = 0, // Adaptive logarithmic mapping (F. Drago, 2003) - FITMO_REINHARD05 = 1, // Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005) - FITMO_FATTAL02 = 2 // Gradient domain high dynamic range compression (R. Fattal, 2002) -}; - -/** Upsampling / downsampling filters. -Constants used in FreeImage_Rescale. -*/ -FI_ENUM( FREE_IMAGE_FILTER ) -{ - FILTER_BOX = 0, // Box, pulse, Fourier window, 1st order (constant) b-spline - FILTER_BICUBIC = 1, // Mitchell & Netravali's two-param cubic filter - FILTER_BILINEAR = 2, // Bilinear filter - FILTER_BSPLINE = 3, // 4th order (cubic) b-spline - FILTER_CATMULLROM = 4, // Catmull-Rom spline, Overhauser spline - FILTER_LANCZOS3 = 5 // Lanczos3 filter -}; - -/** Color channels. -Constants used in color manipulation routines. -*/ -FI_ENUM( FREE_IMAGE_COLOR_CHANNEL ) -{ - FICC_RGB = 0, // Use red, green and blue channels - FICC_RED = 1, // Use red channel - FICC_GREEN = 2, // Use green channel - FICC_BLUE = 3, // Use blue channel - FICC_ALPHA = 4, // Use alpha channel - FICC_BLACK = 5, // Use black channel - FICC_REAL = 6, // Complex images: use real part - FICC_IMAG = 7, // Complex images: use imaginary part - FICC_MAG = 8, // Complex images: use magnitude - FICC_PHASE = 9 // Complex images: use phase -}; - -// Metadata support --------------------------------------------------------- - -/** - Tag data type information (based on TIFF specifications) - - Note: RATIONALs are the ratio of two 32-bit integer values. -*/ -FI_ENUM( FREE_IMAGE_MDTYPE ) -{ - FIDT_NOTYPE = 0, // placeholder - FIDT_BYTE = 1, // 8-bit unsigned integer - FIDT_ASCII = 2, // 8-bit bytes w/ last byte null - FIDT_SHORT = 3, // 16-bit unsigned integer - FIDT_LONG = 4, // 32-bit unsigned integer - FIDT_RATIONAL = 5, // 64-bit unsigned fraction - FIDT_SBYTE = 6, // 8-bit signed integer - FIDT_UNDEFINED = 7, // 8-bit untyped data - FIDT_SSHORT = 8, // 16-bit signed integer - FIDT_SLONG = 9, // 32-bit signed integer - FIDT_SRATIONAL = 10, // 64-bit signed fraction - FIDT_FLOAT = 11, // 32-bit IEEE floating point - FIDT_DOUBLE = 12, // 64-bit IEEE floating point - FIDT_IFD = 13, // 32-bit unsigned integer (offset) - FIDT_PALETTE = 14 // 32-bit RGBQUAD -}; - -/** - Metadata models supported by FreeImage -*/ -FI_ENUM( FREE_IMAGE_MDMODEL ) -{ - FIMD_NODATA = -1, - FIMD_COMMENTS = 0, // single comment or keywords - FIMD_EXIF_MAIN = 1, // Exif-TIFF metadata - FIMD_EXIF_EXIF = 2, // Exif-specific metadata - FIMD_EXIF_GPS = 3, // Exif GPS metadata - FIMD_EXIF_MAKERNOTE = 4, // Exif maker note metadata - FIMD_EXIF_INTEROP = 5, // Exif interoperability metadata - FIMD_IPTC = 6, // IPTC/NAA metadata - FIMD_XMP = 7, // Abobe XMP metadata - FIMD_GEOTIFF = 8, // GeoTIFF metadata - FIMD_ANIMATION = 9, // Animation metadata - FIMD_CUSTOM = 10, // Used to attach other metadata types to a dib - FIMD_EXIF_RAW = 11 // Exif metadata as a raw buffer -}; - -/** - Handle to a metadata model -*/ -FI_STRUCT( FIMETADATA ) { void* data; }; - -/** - Handle to a FreeImage tag -*/ -FI_STRUCT( FITAG ) { void* data; }; - -// File IO routines --------------------------------------------------------- - -#ifndef FREEIMAGE_IO -#define FREEIMAGE_IO - -typedef void* fi_handle; -typedef unsigned( DLL_CALLCONV* FI_ReadProc )( void* buffer, unsigned size, unsigned count, fi_handle handle ); -typedef unsigned( DLL_CALLCONV* FI_WriteProc )( void* buffer, unsigned size, unsigned count, fi_handle handle ); -typedef int ( DLL_CALLCONV* FI_SeekProc )( fi_handle handle, long offset, int origin ); -typedef long( DLL_CALLCONV* FI_TellProc )( fi_handle handle ); - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif // WIN32 - -FI_STRUCT( FreeImageIO ) -{ - FI_ReadProc read_proc; // pointer to the function used to read data - FI_WriteProc write_proc; // pointer to the function used to write data - FI_SeekProc seek_proc; // pointer to the function used to seek - FI_TellProc tell_proc; // pointer to the function used to aquire the current position -}; - -#if (defined(_WIN32) || defined(__WIN32__)) -#pragma pack(pop) -#else -#pragma pack() -#endif // WIN32 - -/** -Handle to a memory I/O stream -*/ -FI_STRUCT( FIMEMORY ) { void* data; }; - -#endif // FREEIMAGE_IO - -// Plugin routines ---------------------------------------------------------- - -#ifndef PLUGINS -#define PLUGINS - -typedef const char* ( DLL_CALLCONV* FI_FormatProc )( void ); -typedef const char* ( DLL_CALLCONV* FI_DescriptionProc )( void ); -typedef const char* ( DLL_CALLCONV* FI_ExtensionListProc )( void ); -typedef const char* ( DLL_CALLCONV* FI_RegExprProc )( void ); -typedef void* ( DLL_CALLCONV* FI_OpenProc )( FreeImageIO* io, fi_handle handle, BOOL read ); -typedef void ( DLL_CALLCONV* FI_CloseProc )( FreeImageIO* io, fi_handle handle, void* data ); -typedef int ( DLL_CALLCONV* FI_PageCountProc )( FreeImageIO* io, fi_handle handle, void* data ); -typedef int ( DLL_CALLCONV* FI_PageCapabilityProc )( FreeImageIO* io, fi_handle handle, void* data ); -typedef FIBITMAP* ( DLL_CALLCONV* FI_LoadProc )( FreeImageIO* io, fi_handle handle, int page, int flags, void* data ); -typedef BOOL ( DLL_CALLCONV* FI_SaveProc )( FreeImageIO* io, FIBITMAP* dib, fi_handle handle, int page, int flags, void* data ); -typedef BOOL ( DLL_CALLCONV* FI_ValidateProc )( FreeImageIO* io, fi_handle handle ); -typedef const char* ( DLL_CALLCONV* FI_MimeProc )( void ); -typedef BOOL ( DLL_CALLCONV* FI_SupportsExportBPPProc )( int bpp ); -typedef BOOL ( DLL_CALLCONV* FI_SupportsExportTypeProc )( FREE_IMAGE_TYPE type ); -typedef BOOL ( DLL_CALLCONV* FI_SupportsICCProfilesProc )( void ); -typedef BOOL ( DLL_CALLCONV* FI_SupportsNoPixelsProc )( void ); - -FI_STRUCT( Plugin ) -{ - FI_FormatProc format_proc; - FI_DescriptionProc description_proc; - FI_ExtensionListProc extension_proc; - FI_RegExprProc regexpr_proc; - FI_OpenProc open_proc; - FI_CloseProc close_proc; - FI_PageCountProc pagecount_proc; - FI_PageCapabilityProc pagecapability_proc; - FI_LoadProc load_proc; - FI_SaveProc save_proc; - FI_ValidateProc validate_proc; - FI_MimeProc mime_proc; - FI_SupportsExportBPPProc supports_export_bpp_proc; - FI_SupportsExportTypeProc supports_export_type_proc; - FI_SupportsICCProfilesProc supports_icc_profiles_proc; - FI_SupportsNoPixelsProc supports_no_pixels_proc; -}; - -typedef void ( DLL_CALLCONV* FI_InitProc )( Plugin* plugin, int format_id ); - -#endif // PLUGINS - - -// Load / Save flag constants ----------------------------------------------- - -#define FIF_LOAD_NOPIXELS 0x8000 // loading: load the image header only (not supported by all plugins) - -#define BMP_DEFAULT 0 -#define BMP_SAVE_RLE 1 -#define CUT_DEFAULT 0 -#define DDS_DEFAULT 0 -#define EXR_DEFAULT 0 // save data as half with piz-based wavelet compression -#define EXR_FLOAT 0x0001 // save data as float instead of as half (not recommended) -#define EXR_NONE 0x0002 // save with no compression -#define EXR_ZIP 0x0004 // save with zlib compression, in blocks of 16 scan lines -#define EXR_PIZ 0x0008 // save with piz-based wavelet compression -#define EXR_PXR24 0x0010 // save with lossy 24-bit float compression -#define EXR_B44 0x0020 // save with lossy 44% float compression - goes to 22% when combined with EXR_LC -#define EXR_LC 0x0040 // save images with one luminance and two chroma channels, rather than as RGB (lossy compression) -#define FAXG3_DEFAULT 0 -#define GIF_DEFAULT 0 -#define GIF_LOAD256 1 // Load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color -#define GIF_PLAYBACK 2 // 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading -#define HDR_DEFAULT 0 -#define ICO_DEFAULT 0 -#define ICO_MAKEALPHA 1 // convert to 32bpp and create an alpha channel from the AND-mask when loading -#define IFF_DEFAULT 0 -#define J2K_DEFAULT 0 // save with a 16:1 rate -#define JP2_DEFAULT 0 // save with a 16:1 rate -#define JPEG_DEFAULT 0 // loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420) -#define JPEG_FAST 0x0001 // load the file as fast as possible, sacrificing some quality -#define JPEG_ACCURATE 0x0002 // load the file with the best quality, sacrificing some speed -#define JPEG_CMYK 0x0004 // load separated CMYK "as is" (use | to combine with other load flags) -#define JPEG_EXIFROTATE 0x0008 // load and rotate according to Exif 'Orientation' tag if available -#define JPEG_QUALITYSUPERB 0x80 // save with superb quality (100:1) -#define JPEG_QUALITYGOOD 0x0100 // save with good quality (75:1) -#define JPEG_QUALITYNORMAL 0x0200 // save with normal quality (50:1) -#define JPEG_QUALITYAVERAGE 0x0400 // save with average quality (25:1) -#define JPEG_QUALITYBAD 0x0800 // save with bad quality (10:1) -#define JPEG_PROGRESSIVE 0x2000 // save as a progressive-JPEG (use | to combine with other save flags) -#define JPEG_SUBSAMPLING_411 0x1000 // save with high 4x1 chroma subsampling (4:1:1) -#define JPEG_SUBSAMPLING_420 0x4000 // save with medium 2x2 medium chroma subsampling (4:2:0) - default value -#define JPEG_SUBSAMPLING_422 0x8000 // save with low 2x1 chroma subsampling (4:2:2) -#define JPEG_SUBSAMPLING_444 0x10000 // save with no chroma subsampling (4:4:4) -#define JPEG_OPTIMIZE 0x20000 // on saving, compute optimal Huffman coding tables (can reduce a few percent of file size) -#define JPEG_BASELINE 0x40000 // save basic JPEG, without metadata or any markers -#define KOALA_DEFAULT 0 -#define LBM_DEFAULT 0 -#define MNG_DEFAULT 0 -#define PCD_DEFAULT 0 -#define PCD_BASE 1 // load the bitmap sized 768 x 512 -#define PCD_BASEDIV4 2 // load the bitmap sized 384 x 256 -#define PCD_BASEDIV16 3 // load the bitmap sized 192 x 128 -#define PCX_DEFAULT 0 -#define PFM_DEFAULT 0 -#define PICT_DEFAULT 0 -#define PNG_DEFAULT 0 -#define PNG_IGNOREGAMMA 1 // loading: avoid gamma correction -#define PNG_Z_BEST_SPEED 0x0001 // save using ZLib level 1 compression flag (default value is 6) -#define PNG_Z_DEFAULT_COMPRESSION 0x0006 // save using ZLib level 6 compression flag (default recommended value) -#define PNG_Z_BEST_COMPRESSION 0x0009 // save using ZLib level 9 compression flag (default value is 6) -#define PNG_Z_NO_COMPRESSION 0x0100 // save without ZLib compression -#define PNG_INTERLACED 0x0200 // save using Adam7 interlacing (use | to combine with other save flags) -#define PNM_DEFAULT 0 -#define PNM_SAVE_RAW 0 // If set the writer saves in RAW format (i.e. P4, P5 or P6) -#define PNM_SAVE_ASCII 1 // If set the writer saves in ASCII format (i.e. P1, P2 or P3) -#define PSD_DEFAULT 0 -#define PSD_CMYK 1 // reads tags for separated CMYK (default is conversion to RGB) -#define PSD_LAB 2 // reads tags for CIELab (default is conversion to RGB) -#define RAS_DEFAULT 0 -#define RAW_DEFAULT 0 // load the file as linear RGB 48-bit -#define RAW_PREVIEW 1 // try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit -#define RAW_DISPLAY 2 // load the file as RGB 24-bit -#define SGI_DEFAULT 0 -#define TARGA_DEFAULT 0 -#define TARGA_LOAD_RGB888 1 // If set the loader converts RGB555 and ARGB8888 -> RGB888. -#define TARGA_SAVE_RLE 2 // If set, the writer saves with RLE compression -#define TIFF_DEFAULT 0 -#define TIFF_CMYK 0x0001 // reads/stores tags for separated CMYK (use | to combine with compression flags) -#define TIFF_PACKBITS 0x0100 // save using PACKBITS compression -#define TIFF_DEFLATE 0x0200 // save using DEFLATE compression (a.k.a. ZLIB compression) -#define TIFF_ADOBE_DEFLATE 0x0400 // save using ADOBE DEFLATE compression -#define TIFF_NONE 0x0800 // save without any compression -#define TIFF_CCITTFAX3 0x1000 // save using CCITT Group 3 fax encoding -#define TIFF_CCITTFAX4 0x2000 // save using CCITT Group 4 fax encoding -#define TIFF_LZW 0x4000 // save using LZW compression -#define TIFF_JPEG 0x8000 // save using JPEG compression -#define TIFF_LOGLUV 0x10000 // save using LogLuv compression -#define WBMP_DEFAULT 0 -#define XBM_DEFAULT 0 -#define XPM_DEFAULT 0 - -// Background filling options --------------------------------------------------------- -// Constants used in FreeImage_FillBackground and FreeImage_EnlargeCanvas - -#define FI_COLOR_IS_RGB_COLOR 0x00 // RGBQUAD color is a RGB color (contains no valid alpha channel) -#define FI_COLOR_IS_RGBA_COLOR 0x01 // RGBQUAD color is a RGBA color (contains a valid alpha channel) -#define FI_COLOR_FIND_EQUAL_COLOR 0x02 // For palettized images: lookup equal RGB color from palette -#define FI_COLOR_ALPHA_IS_INDEX 0x04 // The color's rgbReserved member (alpha) contains the palette index to be used -#define FI_COLOR_PALETTE_SEARCH_MASK (FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX) // No color lookup is performed - - -#ifdef __cplusplus -extern "C" { -#endif - - // Init / Error routines ---------------------------------------------------- - - DLL_API void DLL_CALLCONV FreeImage_Initialise( BOOL load_local_plugins_only FI_DEFAULT( FALSE ) ); - DLL_API void DLL_CALLCONV FreeImage_DeInitialise( void ); - - // Version routines --------------------------------------------------------- - - DLL_API const char* DLL_CALLCONV FreeImage_GetVersion( void ); - DLL_API const char* DLL_CALLCONV FreeImage_GetCopyrightMessage( void ); - - // Message output functions ------------------------------------------------- - - typedef void ( *FreeImage_OutputMessageFunction )( FREE_IMAGE_FORMAT fif, const char* msg ); - typedef void ( DLL_CALLCONV* FreeImage_OutputMessageFunctionStdCall )( FREE_IMAGE_FORMAT fif, const char* msg ); - - DLL_API void DLL_CALLCONV FreeImage_SetOutputMessageStdCall( FreeImage_OutputMessageFunctionStdCall omf ); - DLL_API void DLL_CALLCONV FreeImage_SetOutputMessage( FreeImage_OutputMessageFunction omf ); - DLL_API void DLL_CALLCONV FreeImage_OutputMessageProc( int fif, const char* fmt, ... ); - - // Allocate / Clone / Unload routines --------------------------------------- - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Allocate( int width, int height, int bpp, unsigned red_mask FI_DEFAULT( 0 ), unsigned green_mask FI_DEFAULT( 0 ), unsigned blue_mask FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_AllocateT( FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT( 8 ), unsigned red_mask FI_DEFAULT( 0 ), unsigned green_mask FI_DEFAULT( 0 ), unsigned blue_mask FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Clone( FIBITMAP* dib ); - DLL_API void DLL_CALLCONV FreeImage_Unload( FIBITMAP* dib ); - - // Header loading routines - DLL_API BOOL DLL_CALLCONV FreeImage_HasPixels( FIBITMAP* dib ); - - // Load / Save routines ----------------------------------------------------- - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Load( FREE_IMAGE_FORMAT fif, const char* filename, int flags FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_LoadU( FREE_IMAGE_FORMAT fif, const wchar_t* filename, int flags FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_LoadFromHandle( FREE_IMAGE_FORMAT fif, FreeImageIO* io, fi_handle handle, int flags FI_DEFAULT( 0 ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_Save( FREE_IMAGE_FORMAT fif, FIBITMAP* dib, const char* filename, int flags FI_DEFAULT( 0 ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_SaveU( FREE_IMAGE_FORMAT fif, FIBITMAP* dib, const wchar_t* filename, int flags FI_DEFAULT( 0 ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_SaveToHandle( FREE_IMAGE_FORMAT fif, FIBITMAP* dib, FreeImageIO* io, fi_handle handle, int flags FI_DEFAULT( 0 ) ); - - // Memory I/O stream routines ----------------------------------------------- - - DLL_API FIMEMORY* DLL_CALLCONV FreeImage_OpenMemory( BYTE* data FI_DEFAULT( 0 ), DWORD size_in_bytes FI_DEFAULT( 0 ) ); - DLL_API void DLL_CALLCONV FreeImage_CloseMemory( FIMEMORY* stream ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_LoadFromMemory( FREE_IMAGE_FORMAT fif, FIMEMORY* stream, int flags FI_DEFAULT( 0 ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_SaveToMemory( FREE_IMAGE_FORMAT fif, FIBITMAP* dib, FIMEMORY* stream, int flags FI_DEFAULT( 0 ) ); - DLL_API long DLL_CALLCONV FreeImage_TellMemory( FIMEMORY* stream ); - DLL_API BOOL DLL_CALLCONV FreeImage_SeekMemory( FIMEMORY* stream, long offset, int origin ); - DLL_API BOOL DLL_CALLCONV FreeImage_AcquireMemory( FIMEMORY* stream, BYTE** data, DWORD* size_in_bytes ); - DLL_API unsigned DLL_CALLCONV FreeImage_ReadMemory( void* buffer, unsigned size, unsigned count, FIMEMORY* stream ); - DLL_API unsigned DLL_CALLCONV FreeImage_WriteMemory( const void* buffer, unsigned size, unsigned count, FIMEMORY* stream ); - - DLL_API FIMULTIBITMAP* DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory( FREE_IMAGE_FORMAT fif, FIMEMORY* stream, int flags FI_DEFAULT( 0 ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToMemory( FREE_IMAGE_FORMAT fif, FIMULTIBITMAP* bitmap, FIMEMORY* stream, int flags ); - - // Plugin Interface --------------------------------------------------------- - - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterLocalPlugin( FI_InitProc proc_address, const char* format FI_DEFAULT( 0 ), const char* description FI_DEFAULT( 0 ), const char* extension FI_DEFAULT( 0 ), const char* regexpr FI_DEFAULT( 0 ) ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterExternalPlugin( const char* path, const char* format FI_DEFAULT( 0 ), const char* description FI_DEFAULT( 0 ), const char* extension FI_DEFAULT( 0 ), const char* regexpr FI_DEFAULT( 0 ) ); - DLL_API int DLL_CALLCONV FreeImage_GetFIFCount( void ); - DLL_API int DLL_CALLCONV FreeImage_SetPluginEnabled( FREE_IMAGE_FORMAT fif, BOOL enable ); - DLL_API int DLL_CALLCONV FreeImage_IsPluginEnabled( FREE_IMAGE_FORMAT fif ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFormat( const char* format ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromMime( const char* mime ); - DLL_API const char* DLL_CALLCONV FreeImage_GetFormatFromFIF( FREE_IMAGE_FORMAT fif ); - DLL_API const char* DLL_CALLCONV FreeImage_GetFIFExtensionList( FREE_IMAGE_FORMAT fif ); - DLL_API const char* DLL_CALLCONV FreeImage_GetFIFDescription( FREE_IMAGE_FORMAT fif ); - DLL_API const char* DLL_CALLCONV FreeImage_GetFIFRegExpr( FREE_IMAGE_FORMAT fif ); - DLL_API const char* DLL_CALLCONV FreeImage_GetFIFMimeType( FREE_IMAGE_FORMAT fif ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilename( const char* filename ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilenameU( const wchar_t* filename ); - DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsReading( FREE_IMAGE_FORMAT fif ); - DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsWriting( FREE_IMAGE_FORMAT fif ); - DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportBPP( FREE_IMAGE_FORMAT fif, int bpp ); - DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportType( FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type ); - DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsICCProfiles( FREE_IMAGE_FORMAT fif ); - DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsNoPixels( FREE_IMAGE_FORMAT fif ); - - // Multipaging interface ---------------------------------------------------- - - DLL_API FIMULTIBITMAP* DLL_CALLCONV FreeImage_OpenMultiBitmap( FREE_IMAGE_FORMAT fif, const char* filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory FI_DEFAULT( FALSE ), int flags FI_DEFAULT( 0 ) ); - DLL_API FIMULTIBITMAP* DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle( FREE_IMAGE_FORMAT fif, FreeImageIO* io, fi_handle handle, int flags FI_DEFAULT( 0 ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToHandle( FREE_IMAGE_FORMAT fif, FIMULTIBITMAP* bitmap, FreeImageIO* io, fi_handle handle, int flags FI_DEFAULT( 0 ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap( FIMULTIBITMAP* bitmap, int flags FI_DEFAULT( 0 ) ); - DLL_API int DLL_CALLCONV FreeImage_GetPageCount( FIMULTIBITMAP* bitmap ); - DLL_API void DLL_CALLCONV FreeImage_AppendPage( FIMULTIBITMAP* bitmap, FIBITMAP* data ); - DLL_API void DLL_CALLCONV FreeImage_InsertPage( FIMULTIBITMAP* bitmap, int page, FIBITMAP* data ); - DLL_API void DLL_CALLCONV FreeImage_DeletePage( FIMULTIBITMAP* bitmap, int page ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_LockPage( FIMULTIBITMAP* bitmap, int page ); - DLL_API void DLL_CALLCONV FreeImage_UnlockPage( FIMULTIBITMAP* bitmap, FIBITMAP* data, BOOL changed ); - DLL_API BOOL DLL_CALLCONV FreeImage_MovePage( FIMULTIBITMAP* bitmap, int target, int source ); - DLL_API BOOL DLL_CALLCONV FreeImage_GetLockedPageNumbers( FIMULTIBITMAP* bitmap, int* pages, int* count ); - - // Filetype request routines ------------------------------------------------ - - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileType( const char* filename, int size FI_DEFAULT( 0 ) ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeU( const wchar_t* filename, int size FI_DEFAULT( 0 ) ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromHandle( FreeImageIO* io, fi_handle handle, int size FI_DEFAULT( 0 ) ); - DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromMemory( FIMEMORY* stream, int size FI_DEFAULT( 0 ) ); - - // Image type request routine ----------------------------------------------- - - DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType( FIBITMAP* dib ); - - // FreeImage helper routines ------------------------------------------------ - - DLL_API BOOL DLL_CALLCONV FreeImage_IsLittleEndian( void ); - DLL_API BOOL DLL_CALLCONV FreeImage_LookupX11Color( const char* szColor, BYTE* nRed, BYTE* nGreen, BYTE* nBlue ); - DLL_API BOOL DLL_CALLCONV FreeImage_LookupSVGColor( const char* szColor, BYTE* nRed, BYTE* nGreen, BYTE* nBlue ); - - // Pixel access routines ---------------------------------------------------- - - DLL_API BYTE* DLL_CALLCONV FreeImage_GetBits( FIBITMAP* dib ); - DLL_API BYTE* DLL_CALLCONV FreeImage_GetScanLine( FIBITMAP* dib, int scanline ); - - DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelIndex( FIBITMAP* dib, unsigned x, unsigned y, BYTE* value ); - DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelColor( FIBITMAP* dib, unsigned x, unsigned y, RGBQUAD* value ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelIndex( FIBITMAP* dib, unsigned x, unsigned y, BYTE* value ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelColor( FIBITMAP* dib, unsigned x, unsigned y, RGBQUAD* value ); - - // DIB info routines -------------------------------------------------------- - - DLL_API unsigned DLL_CALLCONV FreeImage_GetColorsUsed( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetBPP( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetWidth( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetHeight( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetLine( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetPitch( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetDIBSize( FIBITMAP* dib ); - DLL_API RGBQUAD* DLL_CALLCONV FreeImage_GetPalette( FIBITMAP* dib ); - - DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterX( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterY( FIBITMAP* dib ); - DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterX( FIBITMAP* dib, unsigned res ); - DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterY( FIBITMAP* dib, unsigned res ); - - DLL_API BITMAPINFOHEADER* DLL_CALLCONV FreeImage_GetInfoHeader( FIBITMAP* dib ); - DLL_API BITMAPINFO* DLL_CALLCONV FreeImage_GetInfo( FIBITMAP* dib ); - DLL_API FREE_IMAGE_COLOR_TYPE DLL_CALLCONV FreeImage_GetColorType( FIBITMAP* dib ); - - DLL_API unsigned DLL_CALLCONV FreeImage_GetRedMask( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetGreenMask( FIBITMAP* dib ); - DLL_API unsigned DLL_CALLCONV FreeImage_GetBlueMask( FIBITMAP* dib ); - - DLL_API unsigned DLL_CALLCONV FreeImage_GetTransparencyCount( FIBITMAP* dib ); - DLL_API BYTE* DLL_CALLCONV FreeImage_GetTransparencyTable( FIBITMAP* dib ); - DLL_API void DLL_CALLCONV FreeImage_SetTransparent( FIBITMAP* dib, BOOL enabled ); - DLL_API void DLL_CALLCONV FreeImage_SetTransparencyTable( FIBITMAP* dib, BYTE* table, int count ); - DLL_API BOOL DLL_CALLCONV FreeImage_IsTransparent( FIBITMAP* dib ); - DLL_API void DLL_CALLCONV FreeImage_SetTransparentIndex( FIBITMAP* dib, int index ); - DLL_API int DLL_CALLCONV FreeImage_GetTransparentIndex( FIBITMAP* dib ); - - DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor( FIBITMAP* dib ); - DLL_API BOOL DLL_CALLCONV FreeImage_GetBackgroundColor( FIBITMAP* dib, RGBQUAD* bkcolor ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetBackgroundColor( FIBITMAP* dib, RGBQUAD* bkcolor ); - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_GetThumbnail( FIBITMAP* dib ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetThumbnail( FIBITMAP* dib, FIBITMAP* thumbnail ); - - // ICC profile routines ----------------------------------------------------- - - DLL_API FIICCPROFILE* DLL_CALLCONV FreeImage_GetICCProfile( FIBITMAP* dib ); - DLL_API FIICCPROFILE* DLL_CALLCONV FreeImage_CreateICCProfile( FIBITMAP* dib, void* data, long size ); - DLL_API void DLL_CALLCONV FreeImage_DestroyICCProfile( FIBITMAP* dib ); - - // Line conversion routines ------------------------------------------------- - - DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To4( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To4( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_555( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_565( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To4( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To4( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To8( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To8( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_555( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_565( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To8( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To8( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_555( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_555( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_555( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_565_To16_555( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_555( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_555( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_565( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_565( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_565( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_555_To16_565( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_565( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_565( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To24( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To24( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To24( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_555( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_565( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To24( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32( BYTE* target, BYTE* source, int width_in_pixels, RGBQUAD* palette ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_555( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_565( BYTE* target, BYTE* source, int width_in_pixels ); - DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To32( BYTE* target, BYTE* source, int width_in_pixels ); - - // Smart conversion routines ------------------------------------------------ - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertTo4Bits( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertTo8Bits( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertToGreyscale( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertTo16Bits555( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertTo16Bits565( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertTo24Bits( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertTo32Bits( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ColorQuantize( FIBITMAP* dib, FREE_IMAGE_QUANTIZE quantize ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ColorQuantizeEx( FIBITMAP* dib, FREE_IMAGE_QUANTIZE quantize FI_DEFAULT( FIQ_WUQUANT ), int PaletteSize FI_DEFAULT( 256 ), int ReserveSize FI_DEFAULT( 0 ), RGBQUAD* ReservePalette FI_DEFAULT( NULL ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Threshold( FIBITMAP* dib, BYTE T ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Dither( FIBITMAP* dib, FREE_IMAGE_DITHER algorithm ); - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertFromRawBits( BYTE* bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT( FALSE ) ); - DLL_API void DLL_CALLCONV FreeImage_ConvertToRawBits( BYTE* bits, FIBITMAP* dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT( FALSE ) ); - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertToFloat( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertToRGBF( FIBITMAP* dib ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertToUINT16( FIBITMAP* dib ); - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertToStandardType( FIBITMAP* src, BOOL scale_linear FI_DEFAULT( TRUE ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ConvertToType( FIBITMAP* src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT( TRUE ) ); - - // tone mapping operators - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_ToneMapping( FIBITMAP* dib, FREE_IMAGE_TMO tmo, double first_param FI_DEFAULT( 0 ), double second_param FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_TmoDrago03( FIBITMAP* src, double gamma FI_DEFAULT( 2.2 ), double exposure FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_TmoReinhard05( FIBITMAP* src, double intensity FI_DEFAULT( 0 ), double contrast FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_TmoReinhard05Ex( FIBITMAP* src, double intensity FI_DEFAULT( 0 ), double contrast FI_DEFAULT( 0 ), double adaptation FI_DEFAULT( 1 ), double color_correction FI_DEFAULT( 0 ) ); - - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_TmoFattal02( FIBITMAP* src, double color_saturation FI_DEFAULT( 0.5 ), double attenuation FI_DEFAULT( 0.85 ) ); - - // ZLib interface ----------------------------------------------------------- - - DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCompress( BYTE* target, DWORD target_size, BYTE* source, DWORD source_size ); - DLL_API DWORD DLL_CALLCONV FreeImage_ZLibUncompress( BYTE* target, DWORD target_size, BYTE* source, DWORD source_size ); - DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGZip( BYTE* target, DWORD target_size, BYTE* source, DWORD source_size ); - DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGUnzip( BYTE* target, DWORD target_size, BYTE* source, DWORD source_size ); - DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCRC32( DWORD crc, BYTE* source, DWORD source_size ); - - // -------------------------------------------------------------------------- - // Metadata routines -------------------------------------------------------- - // -------------------------------------------------------------------------- - - // tag creation / destruction - DLL_API FITAG* DLL_CALLCONV FreeImage_CreateTag( void ); - DLL_API void DLL_CALLCONV FreeImage_DeleteTag( FITAG* tag ); - DLL_API FITAG* DLL_CALLCONV FreeImage_CloneTag( FITAG* tag ); - - // tag getters and setters - DLL_API const char* DLL_CALLCONV FreeImage_GetTagKey( FITAG* tag ); - DLL_API const char* DLL_CALLCONV FreeImage_GetTagDescription( FITAG* tag ); - DLL_API WORD DLL_CALLCONV FreeImage_GetTagID( FITAG* tag ); - DLL_API FREE_IMAGE_MDTYPE DLL_CALLCONV FreeImage_GetTagType( FITAG* tag ); - DLL_API DWORD DLL_CALLCONV FreeImage_GetTagCount( FITAG* tag ); - DLL_API DWORD DLL_CALLCONV FreeImage_GetTagLength( FITAG* tag ); - DLL_API const void* DLL_CALLCONV FreeImage_GetTagValue( FITAG* tag ); - - DLL_API BOOL DLL_CALLCONV FreeImage_SetTagKey( FITAG* tag, const char* key ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetTagDescription( FITAG* tag, const char* description ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetTagID( FITAG* tag, WORD id ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetTagType( FITAG* tag, FREE_IMAGE_MDTYPE type ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetTagCount( FITAG* tag, DWORD count ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetTagLength( FITAG* tag, DWORD length ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetTagValue( FITAG* tag, const void* value ); - - // iterator - DLL_API FIMETADATA* DLL_CALLCONV FreeImage_FindFirstMetadata( FREE_IMAGE_MDMODEL model, FIBITMAP* dib, FITAG** tag ); - DLL_API BOOL DLL_CALLCONV FreeImage_FindNextMetadata( FIMETADATA* mdhandle, FITAG** tag ); - DLL_API void DLL_CALLCONV FreeImage_FindCloseMetadata( FIMETADATA* mdhandle ); - - // metadata setter and getter - DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadata( FREE_IMAGE_MDMODEL model, FIBITMAP* dib, const char* key, FITAG* tag ); - DLL_API BOOL DLL_CALLCONV FreeImage_GetMetadata( FREE_IMAGE_MDMODEL model, FIBITMAP* dib, const char* key, FITAG** tag ); - - // helpers - DLL_API unsigned DLL_CALLCONV FreeImage_GetMetadataCount( FREE_IMAGE_MDMODEL model, FIBITMAP* dib ); - DLL_API BOOL DLL_CALLCONV FreeImage_CloneMetadata( FIBITMAP* dst, FIBITMAP* src ); - - // tag to C string conversion - DLL_API const char* DLL_CALLCONV FreeImage_TagToString( FREE_IMAGE_MDMODEL model, FITAG* tag, char* Make FI_DEFAULT( NULL ) ); - - // -------------------------------------------------------------------------- - // Image manipulation toolkit ----------------------------------------------- - // -------------------------------------------------------------------------- - - // rotation and flipping - /// @deprecated see FreeImage_Rotate - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_RotateClassic( FIBITMAP* dib, double angle ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Rotate( FIBITMAP* dib, double angle, const void* bkcolor FI_DEFAULT( NULL ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_RotateEx( FIBITMAP* dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask ); - DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal( FIBITMAP* dib ); - DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical( FIBITMAP* dib ); - DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform( const char* src_file, const char* dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT( FALSE ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU( const wchar_t* src_file, const wchar_t* dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT( FALSE ) ); - - // upsampling / downsampling - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Rescale( FIBITMAP* dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_MakeThumbnail( FIBITMAP* dib, int max_pixel_size, BOOL convert FI_DEFAULT( TRUE ) ); - - // color manipulation routines (point operations) - DLL_API BOOL DLL_CALLCONV FreeImage_AdjustCurve( FIBITMAP* dib, BYTE* LUT, FREE_IMAGE_COLOR_CHANNEL channel ); - DLL_API BOOL DLL_CALLCONV FreeImage_AdjustGamma( FIBITMAP* dib, double gamma ); - DLL_API BOOL DLL_CALLCONV FreeImage_AdjustBrightness( FIBITMAP* dib, double percentage ); - DLL_API BOOL DLL_CALLCONV FreeImage_AdjustContrast( FIBITMAP* dib, double percentage ); - DLL_API BOOL DLL_CALLCONV FreeImage_Invert( FIBITMAP* dib ); - DLL_API BOOL DLL_CALLCONV FreeImage_GetHistogram( FIBITMAP* dib, DWORD* histo, FREE_IMAGE_COLOR_CHANNEL channel FI_DEFAULT( FICC_BLACK ) ); - DLL_API int DLL_CALLCONV FreeImage_GetAdjustColorsLookupTable( BYTE* LUT, double brightness, double contrast, double gamma, BOOL invert ); - DLL_API BOOL DLL_CALLCONV FreeImage_AdjustColors( FIBITMAP* dib, double brightness, double contrast, double gamma, BOOL invert FI_DEFAULT( FALSE ) ); - DLL_API unsigned DLL_CALLCONV FreeImage_ApplyColorMapping( FIBITMAP* dib, RGBQUAD* srccolors, RGBQUAD* dstcolors, unsigned count, BOOL ignore_alpha, BOOL swap ); - DLL_API unsigned DLL_CALLCONV FreeImage_SwapColors( FIBITMAP* dib, RGBQUAD* color_a, RGBQUAD* color_b, BOOL ignore_alpha ); - DLL_API unsigned DLL_CALLCONV FreeImage_ApplyPaletteIndexMapping( FIBITMAP* dib, BYTE* srcindices, BYTE* dstindices, unsigned count, BOOL swap ); - DLL_API unsigned DLL_CALLCONV FreeImage_SwapPaletteIndices( FIBITMAP* dib, BYTE* index_a, BYTE* index_b ); - - // channel processing routines - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_GetChannel( FIBITMAP* dib, FREE_IMAGE_COLOR_CHANNEL channel ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetChannel( FIBITMAP* dst, FIBITMAP* src, FREE_IMAGE_COLOR_CHANNEL channel ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_GetComplexChannel( FIBITMAP* src, FREE_IMAGE_COLOR_CHANNEL channel ); - DLL_API BOOL DLL_CALLCONV FreeImage_SetComplexChannel( FIBITMAP* dst, FIBITMAP* src, FREE_IMAGE_COLOR_CHANNEL channel ); - - // copy / paste / composite routines - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Copy( FIBITMAP* dib, int left, int top, int right, int bottom ); - DLL_API BOOL DLL_CALLCONV FreeImage_Paste( FIBITMAP* dst, FIBITMAP* src, int left, int top, int alpha ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_Composite( FIBITMAP* fg, BOOL useFileBkg FI_DEFAULT( FALSE ), RGBQUAD* appBkColor FI_DEFAULT( NULL ), FIBITMAP* bg FI_DEFAULT( NULL ) ); - DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop( const char* src_file, const char* dst_file, int left, int top, int right, int bottom ); - DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU( const wchar_t* src_file, const wchar_t* dst_file, int left, int top, int right, int bottom ); - DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha( FIBITMAP* dib ); - - // background filling routines - DLL_API BOOL DLL_CALLCONV FreeImage_FillBackground( FIBITMAP* dib, const void* color, int options FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_EnlargeCanvas( FIBITMAP* src, int left, int top, int right, int bottom, const void* color, int options FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_AllocateEx( int width, int height, int bpp, const RGBQUAD* color, int options FI_DEFAULT( 0 ), const RGBQUAD* palette FI_DEFAULT( NULL ), unsigned red_mask FI_DEFAULT( 0 ), unsigned green_mask FI_DEFAULT( 0 ), unsigned blue_mask FI_DEFAULT( 0 ) ); - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_AllocateExT( FREE_IMAGE_TYPE type, int width, int height, int bpp, const void* color, int options FI_DEFAULT( 0 ), const RGBQUAD* palette FI_DEFAULT( NULL ), unsigned red_mask FI_DEFAULT( 0 ), unsigned green_mask FI_DEFAULT( 0 ), unsigned blue_mask FI_DEFAULT( 0 ) ); - - // miscellaneous algorithms - DLL_API FIBITMAP* DLL_CALLCONV FreeImage_MultigridPoissonSolver( FIBITMAP* Laplacian, int ncycle FI_DEFAULT( 3 ) ); - - // restore the borland-specific enum size option -#if defined(__BORLANDC__) -#pragma option pop -#endif - -#ifdef __cplusplus -} -#endif - -#endif // FREEIMAGE_H diff --git a/plugins/GPS.h b/plugins/GPS.h index 144c528..38ca844 100644 --- a/plugins/GPS.h +++ b/plugins/GPS.h @@ -54,14 +54,6 @@ class GPSPlugin: public pubviz::Plugin } - void OnFollowChange(bool state) - { - if (!state) - { - GetCanvas()->ResetViewOrigin(); - } - } - void OnHistoryChange(int length) { if (messages_.size() > length) @@ -206,7 +198,7 @@ class GPSPlugin: public pubviz::Plugin { double x, y; - if (GetCanvas()->wgs84_mode_) + if (GetCanvas()->wgs84_mode()) { GetCanvas()->local_xy_.FromLatLon(p.latitude, p.longitude, x, y); } @@ -263,7 +255,7 @@ class GPSPlugin: public pubviz::Plugin { double x, y; - if (GetCanvas()->wgs84_mode_) + if (GetCanvas()->wgs84_mode()) { GetCanvas()->local_xy_.FromLatLon(p.latitude, p.longitude, x, y); //p.z = 0.0; diff --git a/plugins/Gauge.h b/plugins/Gauge.h index 0b83522..c9189a3 100644 --- a/plugins/Gauge.h +++ b/plugins/Gauge.h @@ -29,7 +29,7 @@ #include -class DialPlugin: public pubviz::Plugin +class GaugePlugin: public pubviz::Plugin { FloatProperty* min_value_; FloatProperty* max_value_; @@ -59,19 +59,18 @@ class DialPlugin: public pubviz::Plugin struct ps_subscriber_options options; ps_subscriber_options_init(&options); options.preferred_transport = 1;// tcp yo - options.want_message_def = true; ps_node_create_subscriber_adv(GetNode(), current_topic_.c_str(), NULL, &subscriber_, &options); sub_open_ = true; } public: - DialPlugin() + GaugePlugin() { } - virtual ~DialPlugin() + virtual ~GaugePlugin() { if (sub_open_) { @@ -304,7 +303,7 @@ class DialPlugin: public pubviz::Plugin { // add any properties topic_ = AddTopicProperty(tree, "Topic", "/image", "", ""); - topic_->onChange = std::bind(&DialPlugin::Subscribe, this, std::placeholders::_1); + topic_->onChange = std::bind(&GaugePlugin::Subscribe, this, std::placeholders::_1); field_ = AddStringProperty(tree, "Field", "width"); @@ -324,6 +323,6 @@ class DialPlugin: public pubviz::Plugin } }; -REGISTER_PLUGIN("gauge", DialPlugin) +REGISTER_PLUGIN("gauge", GaugePlugin) #endif diff --git a/plugins/Image.h b/plugins/Image.h index 5bc30b1..8538356 100644 --- a/plugins/Image.h +++ b/plugins/Image.h @@ -14,7 +14,7 @@ #include #include -#include "FreeImage.h" +#include "../FreeImage.h" #define GLEW_STATIC #include @@ -46,26 +46,25 @@ class ImagePlugin: public pubviz::Plugin bool sub_open_ = false; ps_sub_t subscriber_; - pubsub::msg::Image last_msg_; + pubsub::msg::Image* last_msg_ = 0; unsigned int texture_ = -1;//okay, now show image in a new popout // returns false if the message is invalid - bool CheckSize(const pubsub::msg::Image& image, int bpp) + bool CheckSize(int bpp) { - int expected = image.height*image.width*bpp; + int expected = last_msg_->height*last_msg_->width*bpp; - if (image.data_length != expected) + if (last_msg_->data.size() != expected) { - printf("ERROR: Invalid image data length on topic '%s' got %i but expected %i\n", - topic_->GetValue().c_str(), image.data_length, expected); + printf("ERROR: Invalid image data length on topic '%s' got %i but expected %i bytes.\n", + topic_->GetValue().c_str(), last_msg_->data.size(), expected); // mark message as invalid - if (last_msg_.data) + if (last_msg_) { - free(last_msg_.data); - last_msg_.data = 0; - last_msg_.data_length = 0; + free(last_msg_); + last_msg_ = 0; } return false; } @@ -84,65 +83,65 @@ class ImagePlugin: public pubviz::Plugin // make the color buffer std::vector pixels; - pixels.resize(last_msg_.width*last_msg_.height); + pixels.resize(last_msg_->width*last_msg_->height); // now fill in each pixel GLenum texture_format = GL_RGBA; - if (last_msg_.type == pubsub::msg::Image::R8G8B8A8) + if (last_msg_->type == pubsub::msg::Image::R8G8B8A8) { - if (!CheckSize(last_msg_, 4)) { return; } - memcpy(pixels.data(), last_msg_.data, pixels.size()); + if (!CheckSize(4)) { return; } + memcpy(pixels.data(), last_msg_->data.data(), pixels.size()); } - else if (last_msg_.type == pubsub::msg::Image::R8G8B8) + else if (last_msg_->type == pubsub::msg::Image::R8G8B8) { - if (!CheckSize(last_msg_, 3)) { return; } + if (!CheckSize(3)) { return; } for (int i = 0; i < pixels.size(); i++) { uint8_t a = 255; - uint8_t pr = last_msg_.data[i * 3]; - uint8_t pg = last_msg_.data[i * 3 + 1]; - uint8_t pb = last_msg_.data[i * 3 + 2]; + uint8_t pr = last_msg_->data[i * 3]; + uint8_t pg = last_msg_->data[i * 3 + 1]; + uint8_t pb = last_msg_->data[i * 3 + 2]; pixels[i] = (a << 24) | (pb << 16) | (pg << 8) | pr; } } - else if (last_msg_.type == pubsub::msg::Image::R32) + else if (last_msg_->type == pubsub::msg::Image::R32) { - if (!CheckSize(last_msg_, 4)) { return; } - for (int i = 0; i < last_msg_.data_length; i++) + if (!CheckSize(4)) { return; } + for (int i = 0; i < last_msg_->data.size()/4; i++) { - uint8_t px = last_msg_.data[i*4 + 3];// just use the high byte + uint8_t px = last_msg_->data[i*4 + 3];// just use the high byte uint8_t a = 255; pixels[i] = (a << 24) | (px << 16) | (px << 8) | px; } } - else if (last_msg_.type == pubsub::msg::Image::R16) + else if (last_msg_->type == pubsub::msg::Image::R16) { - if (!CheckSize(last_msg_, 2)) { return; } - for (int i = 0; i < last_msg_.data_length; i++) + if (!CheckSize(2)) { return; } + for (int i = 0; i < last_msg_->data.size()/2; i++) { - uint8_t px = last_msg_.data[i*2 + 1];// just use the high byte + uint8_t px = last_msg_->data[i*2];// at the moment use the low byte uint8_t a = 255; pixels[i] = (a << 24) | (px << 16) | (px << 8) | px; } } - else if (last_msg_.type == pubsub::msg::Image::R8) + else if (last_msg_->type == pubsub::msg::Image::R8) { - if (!CheckSize(last_msg_, 1)) { return; } - for (int i = 0; i < last_msg_.data_length; i++) + if (!CheckSize(1)) { return; } + for (int i = 0; i < last_msg_->data.size(); i++) { - uint8_t px = last_msg_.data[i]; + uint8_t px = last_msg_->data[i]; uint8_t a = 255; pixels[i] = (a << 24) | (px << 16) | (px << 8) | px; } } - else if (last_msg_.type == pubsub::msg::Image::YUYV) + else if (last_msg_->type == pubsub::msg::Image::YUYV) { - if (!CheckSize(last_msg_, 2)) { return; } + if (!CheckSize(2)) { return; } for (int i = 1; i < pixels.size(); i++) { - auto y = last_msg_.data[i*2]; - auto u = last_msg_.data[i*2-1]; - auto v = last_msg_.data[i*2+1]; + auto y = last_msg_->data[i*2]; + auto u = last_msg_->data[i*2-1]; + auto v = last_msg_->data[i*2+1]; if ((i&0b1) == 0) std::swap(u,v); int8_t c = (int8_t) (y - 16); @@ -156,14 +155,14 @@ class ImagePlugin: public pubviz::Plugin pixels[i] = (a << 24) | (b << 16) | (g << 8) | r; } } - else if (last_msg_.type == pubsub::msg::Image::JPEG) + else if (last_msg_->type == pubsub::msg::Image::JPEG) { - FIMEMORY* mem = FreeImage_OpenMemory(last_msg_.data, last_msg_.data_length); + FIMEMORY* mem = FreeImage_OpenMemory(last_msg_->data.data(), last_msg_->data.size()); FIBITMAP* img = FreeImage_LoadFromMemory(FIF_JPEG, mem); FIBITMAP* bits32 = FreeImage_ConvertTo32Bits( img ); FreeImage_FlipVertical( bits32 ); // copy! - memcpy(pixels.data(), FreeImage_GetBits( bits32 ), 4*last_msg_.height*last_msg_.width); + memcpy(pixels.data(), FreeImage_GetBits( bits32 ), 4*last_msg_->height*last_msg_->width); FreeImage_Unload( bits32 ); FreeImage_Unload( img ); FreeImage_CloseMemory(mem); @@ -201,8 +200,8 @@ class ImagePlugin: public pubviz::Plugin GL_TEXTURE_2D, 0, GL_RGBA, - last_msg_.width, - last_msg_.height, + last_msg_->width, + last_msg_->height, 0, texture_format, GL_UNSIGNED_BYTE, @@ -213,8 +212,8 @@ class ImagePlugin: public pubviz::Plugin Gwen::Texture tex; - tex.width = last_msg_.width; - tex.height = last_msg_.height; + tex.width = last_msg_->width; + tex.height = last_msg_->height; tex.data = (void*)&texture_; image_panel_->SetTexture(tex); } @@ -242,10 +241,7 @@ class ImagePlugin: public pubviz::Plugin ImagePlugin() { - // just make a quick test costmap - last_msg_.width = 0; - last_msg_.height = 0; - last_msg_.data_length = 0; + // dont use pubsub here } virtual ~ImagePlugin() @@ -253,6 +249,11 @@ class ImagePlugin: public pubviz::Plugin Gwen::Texture tex; image_panel_->SetTexture(tex); page_->Close(); + + if (last_msg_) + { + delete last_msg_; + } if (sub_open_) { @@ -272,9 +273,8 @@ class ImagePlugin: public pubviz::Plugin if (texture_ != -1) { glDeleteTextures(1, &texture_); - last_msg_.data_length = 0; - free(last_msg_.data); - last_msg_.data = 0; + delete last_msg_; + last_msg_ = 0; texture_ = -1; } } @@ -290,15 +290,16 @@ class ImagePlugin: public pubviz::Plugin { if (Paused()) { - free(data->data); - free(data);//todo use allocator free + delete data; continue; } // user is responsible for freeing the message and its arrays - last_msg_ = *data; - free(data->data); - free(data);//todo use allocator free + if (last_msg_) + { + delete last_msg_; + } + last_msg_ = data; UpdateFromMessage(); } } diff --git a/plugins/Map.h b/plugins/Map.h new file mode 100644 index 0000000..cff0c96 --- /dev/null +++ b/plugins/Map.h @@ -0,0 +1,808 @@ + +#ifndef PUBVIZ_PLUGIN_MAP_H +#define PUBVIZ_PLUGIN_MAP_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GLEW_STATIC +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#endif + +#include "../Plugin.h" +#include "../properties.h" + +#include +#include +#include +#include + +struct Coord +{ + int x, y, z; + + bool operator <(const Coord& o) const + { + return key() < o.key(); + } + + int64_t key() const + { + return z*100000000000000 + x + y*10000000; + } +}; + + +#include +#include +#include /* getprotobyname */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +std::string http_request(std::string hostname, int server_port, std::string url) { + char buffer[BUFSIZ]; + enum CONSTEXPR { MAX_REQUEST_LEN = 1024}; + char request[MAX_REQUEST_LEN]; + char request_template[] = "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: pubviz\r\nConnection: close\r\n\r\n"; + struct protoent *protoent; + int request_len; + int socket_file_descriptor; + ssize_t nbytes_total, nbytes_last; + struct sockaddr_in sockaddr_in; + + request_len = snprintf(request, MAX_REQUEST_LEN, request_template, url.c_str(), hostname.c_str()); + if (request_len >= MAX_REQUEST_LEN) { + fprintf(stderr, "request length large: %d\n", request_len); + return "";// fail + } + + /* Build the socket. */ + protoent = getprotobyname("tcp"); + if (protoent == NULL) { + perror("getprotobyname"); + //exit(EXIT_FAILURE); + return "";// fail + } + + /* Build the address in sockaddr_in + * Possibly does a DNS query to get the IP from a hostanme. */ + { + struct hostent *hostent = gethostbyname(hostname.c_str()); + if (hostent == NULL) { + fprintf(stderr, "error: gethostbyname(\"%s\")\n", hostname.c_str()); + //exit(EXIT_FAILURE); + return "";// fail + } + in_addr_t in_addr = inet_addr(inet_ntoa(*(struct in_addr*)*(hostent->h_addr_list))); + if (in_addr == (in_addr_t)-1) { + fprintf(stderr, "error: inet_addr(\"%s\")\n", *(hostent->h_addr_list)); + //exit(EXIT_FAILURE); + return "";// fail + } + sockaddr_in.sin_addr.s_addr = in_addr; + sockaddr_in.sin_family = AF_INET; + sockaddr_in.sin_port = htons(server_port); + //fprintf(stderr, "debug: IP: %s\n", inet_ntoa(sockaddr_in.sin_addr)); + } + + socket_file_descriptor = socket(AF_INET, SOCK_STREAM, protoent->p_proto); + if (socket_file_descriptor == -1) { + perror("socket"); + //exit(EXIT_FAILURE); + return "";// fail + } + + /* Actually connect. */ + if (connect(socket_file_descriptor, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) == -1) { + perror("connect"); + //exit(EXIT_FAILURE); + close(socket_file_descriptor); + return "";// fail + } + + /* Send HTTP request. */ + nbytes_total = 0; + while (nbytes_total < request_len) { + nbytes_last = write(socket_file_descriptor, request + nbytes_total, request_len - nbytes_total); + if (nbytes_last == -1) { + perror("write"); + close(socket_file_descriptor); + //exit(EXIT_FAILURE); + return "";// fail + } + nbytes_total += nbytes_last; + } + + /* Read the response. */ + //fprintf(stderr, "debug: before first read\n"); + std::string output; + while ((nbytes_total = read(socket_file_descriptor, buffer, BUFSIZ)) > 0) { + //fprintf(stderr, "debug: after a read\n"); + for (int i = 0; i < nbytes_total; i++) + { + output += buffer[i]; + } + //write(STDOUT_FILENO, buffer, nbytes_total); + } + //fprintf(stderr, "debug: after last read\n"); + if (nbytes_total == -1) { + perror("read"); + close(socket_file_descriptor); + //exit(EXIT_FAILURE); + return "";// fail + } + + close(socket_file_descriptor); + + auto start = output.find("\r\n\r\n"); + return output.substr(start+4); +} + +struct Result +{ + Coord coord; + int texture; +}; + +struct ImageCache +{ + std::thread request_thread; + std::mutex map_mutex; + std::mutex queue_mutex; + std::deque request_queue; + struct CacheItem + { + int texture; + pubsub::Time last_time_used; + }; + std::map textures;// todo limit size + + struct Incoming + { + Coord coord; + char* data; + int width, height; + GLenum format; + }; + std::deque texture_queue; + + bool run_thread_ = true; + void StartThread() + { + request_thread = std::thread([&](){ + // create cache directory if it doesnt exist + mkdir(".tile_cache", 0700); + while (ps_okay() && run_thread_) + { + queue_mutex.unlock(); + if (request_queue.size() == 0) + { + queue_mutex.unlock(); + ps_sleep(10); + continue; + } + + auto coord = request_queue.front(); + request_queue.pop_front(); + queue_mutex.unlock(); + + // Load whatever we got from the filesystem first + if (LoadClosestCached(coord)) + { + //printf("Not loading from server since cache hit.\n"); + continue; + } + + // then load from the server + char url[500]; + sprintf(url, "/%i/%i/%i.png", coord.z, coord.x, coord.y); + std::string res = http_request("tile.openstreetmap.org", 80, url); + //printf("Got %i bytes\n", res.size()); + if (res.size() == 0) + { + printf("Request failed.\n"); + continue; + } + + auto i = LoadPNG(res.data(), res.size()); + i.coord = coord; + queue_mutex.lock(); + texture_queue.push_back(i); + queue_mutex.unlock(); + + // save to cache + char buf[500]; + sprintf(buf, ".tile_cache/%i_%i_%i.png", coord.z, coord.x, coord.y); + FILE* f = fopen(buf, "wb"); + fwrite(res.data(), res.size(), 1, f); + fclose(f); + } + }); + } + + ~ImageCache() + { + for (auto& i: textures) + { + if (i.second.texture >= 0) + { + GLuint tex = i.second.texture; + glDeleteTextures(1, &tex); + } + } + run_thread_ = false; + if (request_thread.joinable()) + { + request_thread.join(); + } + } + + // returns a coord and texture + Result GetTile(int x, int y, int zoom) + { + Coord coord = {x,y,zoom}; + map_mutex.lock(); + + // request the tile and insert if we havent already + if (textures.find(coord) == textures.end()) + { + // request this texture and mark it as requested + CacheItem item; + item.texture = -1; + item.last_time_used = pubsub::Time(0);// todo + textures[coord] = item; + + queue_mutex.lock(); + request_queue.push_front(coord); + queue_mutex.unlock(); + } + + // try and find a close enough texture + Coord ncoord = coord; + int range = 4; + for (int z = zoom; z >= std::max(zoom-range, 0); z--) + { + auto r = textures.find(ncoord); + if (r != textures.end() && r->second.texture >= 0) + { + map_mutex.unlock(); + return {ncoord, r->second.texture}; + } + ncoord.x /= 2; + ncoord.y /= 2; + ncoord.z -= 1; + } + map_mutex.unlock(); + return {coord, -1}; + } + + bool Process() + { + // turn any queued memories into textures and add them + bool loaded = false; + while (true) + { + queue_mutex.lock(); + if (texture_queue.size() == 0) + { + queue_mutex.unlock(); + return loaded; + } + auto item = texture_queue.front(); + texture_queue.pop_front(); + queue_mutex.unlock(); + + // create the texture + int texture = CreateTexture(item.data, 256, 256, item.format); + + //printf("Created texture for %i %i %i\n", item.coord.z, item.coord.x, item.coord.y); + map_mutex.lock(); + textures[item.coord] = {texture, pubsub::Time(0)}; + map_mutex.unlock(); + delete[] item.data; + loaded = true; + } + return loaded;// should never get executed + } + +private: + // returns true if we had the requested tile cached + bool LoadClosestCached(Coord c) + { + // fill in the texture for the closest one to requested if it isnt already + auto oc = c; + int range = 4;// try down this many levels + for (int z = oc.z; z >= std::max(oc.z-range, 0); z--) + { + map_mutex.lock(); + auto r = textures.find(c); + Incoming tex; + tex.data = 0; + if (r == textures.end() || r->second.texture < 0) + { + map_mutex.unlock(); + tex = TryCached(c.x, c.y, z); + } + else + { + map_mutex.unlock(); + } + if (tex.data != 0) + { + // add to queue! we got something close enough + queue_mutex.lock(); + texture_queue.push_back(tex); + queue_mutex.unlock(); + return oc.z == c.z; + } + //printf("http://tile.openstreetmap.org/%i/%i/%i.png missing from cache\n", c.z, c.x, c.y); + c.x /= 2; + c.y /= 2; + c.z -= 1; + } + //printf("No usable cached tile found for %i %i %i\n", oc.z, oc.x, oc.y); + return false; + } + + Incoming TryCached(int x, int y, int z) + { + char buf[500]; + sprintf(buf, ".tile_cache/%i_%i_%i.png", z, x, y); + FILE* f = fopen(buf, "rb"); + if (f) + { + //printf("Loaded %i %i %i from file.\n", z, x, y); + fseek(f, 0, SEEK_END); + auto fsize = ftell(f); + rewind(f); + + auto fcontent = (char*) malloc(sizeof(char) * fsize); + fread(fcontent, 1, fsize, f); + + auto i = LoadPNG(fcontent, fsize); + i.coord.x = x; + i.coord.y = y; + i.coord.z = z; + free(fcontent); + fclose(f); + + return i; + } + else + { + return {{0,0,0}, 0, 0}; + } + } + + static int CreateTexture(char* data, int width, int height, GLenum texture_format) + { + GLuint texture = 0; + glGenTextures(1, &texture); + //printf("Texture: %i\n", texture); + + glBindTexture(GL_TEXTURE_2D, texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGBA, + width, + height, + 0, + texture_format, + GL_UNSIGNED_BYTE, + data); + + glBindTexture(GL_TEXTURE_2D, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + return texture; + } + + Incoming LoadPNG(char* data, int size) + { + Incoming i; + i.width = 256; + i.height = 256; + i.data = new char[i.width*i.height*4]; +#ifdef FREEIMAGE_BIGENDIAN + i.format = GL_RGBA; +#else + i.format = GL_BGRA; +#endif + // todo get width from file rather than assume + FIMEMORY* mem = FreeImage_OpenMemory((unsigned char*)data, size); + FIBITMAP* img = FreeImage_LoadFromMemory(FIF_PNG, mem); + FIBITMAP* bits32 = FreeImage_ConvertTo32Bits( img ); + FreeImage_FlipVertical( bits32 ); + // copy + memcpy(i.data, FreeImage_GetBits( bits32 ), 4*i.height*i.width); + FreeImage_Unload( bits32 ); + FreeImage_Unload( img ); + FreeImage_CloseMemory(mem); + + return i; + } +}; + + + +class MapPlugin: public pubviz::Plugin +{ + std::unique_ptr alpha_; + std::unique_ptr max_zoom_, default_zoom_, default_tiles_; + std::unique_ptr show_outline_; + + ImageCache cache_; + +public: + + MapPlugin() + { + // dont use pubsub here + cache_.StartThread(); + } + + virtual ~MapPlugin() + { + + } + + // Clear out any historical data so the view gets cleared + virtual void Clear() + { + + } + + virtual void Update() + { + // redraw if we loaded a texture + if (cache_.Process()) + { + Redraw(); + } + } + + static void get_tile_at(double lat, double lon, int zoom, int&x, int&y) + { + double lat_rad = lat*M_PI/180.0; + double n = pow(2.0, zoom); + x = int((lon + 180.0)/360.0*n); + y = int((1.0 - log(tan(lat_rad) + (1/cos(lat_rad)))/M_PI)/2.0*n); + } + + static void get_tile_ll(int x, int y, int zoom, double&lat, double&lon) + { + double n = pow(2.0, zoom); + lon = x/n*360.0 - 180.0; + double lat_rad = atan(sinh(M_PI*(1.0-2.0*y/n))); + lat = lat_rad*180.0/M_PI; + } + + double pixels_per_meter(double lat, int zoom) + { + double tile_width = 40075016.686*cos(lat*M_PI/180.0)/pow(2.0, zoom); + return 256.0/tile_width; + } + + virtual void Paint() + { + // Draw license attribution + auto canvas = GetCanvas(); + auto font = canvas->GetSkin()->GetDefaultFont(); + + auto r = canvas->GetSkin()->GetRender(); + + std::string string = "OpenStreetMap"; + auto res = r->MeasureText(font, string); + r->SetDrawColor( Gwen::Color(255,255,255,255) ); + r->DrawFilledRect(Gwen::Rect(canvas->Width()-res.x, canvas->Height()-res.y, res.x, res.y)); + r->SetDrawColor( Gwen::Color(0,0,0,255) ); + r->RenderText(font, Gwen::PointF(canvas->Width()-res.x, canvas->Height()-res.y ), string); + } + + virtual void Render() + { + auto canvas = GetCanvas(); + if (!canvas->local_xy_.Initialized()) + { + return;// we need an origin + } + + int zoom = default_zoom_->GetValue(); + const int max_zoom = max_zoom_->GetValue(); + zoom = std::min(max_zoom, zoom); + + bool show_outline = show_outline_->GetValue(); + + double ax, ay, az; + canvas->GetViewCenter(ax, ay, az); + + auto xy = &canvas->local_xy_; + int xmin, xmax, ymin, ymax; + if (canvas->GetViewType() == ViewType::TopDown) + { + // okay, lets get each corner of the view in current frame coordinates + double w2 = canvas->view_width()/2.0; + double h2 = canvas->view_height()/2.0; + Vec3d corners[4]; + corners[0] = Vec3d(ax-w2, ay-h2, 0); + corners[1] = Vec3d(ax-w2, ay+h2, 0); + corners[2] = Vec3d(ax+w2, ay+h2, 0); + corners[3] = Vec3d(ax+w2, ay-h2, 0); + + // then loop through and get wgs84 min and max for each corner + double minlat, minlon; + double maxlat, maxlon; + for (int i = 0; i < 4; i++) + { + // transform to map if necessary + auto src_frame = canvas->wgs84_mode() ? OpenGLCanvas::Map : OpenGLCanvas::Odom; + canvas->TransformToFrame(src_frame, OpenGLCanvas::WGS84, corners[i]); + + double lat = corners[i].x; + double lon = corners[i].y; + if (i == 0) + { + minlat = maxlat = lat; + minlon = maxlon = lon; + } + else + { + minlon = std::min(minlon, lon); + minlat = std::min(minlat, lat); + maxlon = std::max(maxlon, lon); + maxlat = std::max(maxlat, lat); + } + } + + // determine best zoom level to use + // find first higher resolution tile + double view_ppm = canvas->Width()*canvas->GetCanvas()->Scale()/canvas->view_width(); + zoom = max_zoom; + for (int i = 1; i <= max_zoom; i++) + { + double zoom_ppm = pixels_per_meter(minlat, i); + //printf("ppm %i %f\n", i, zoom_ppm); + if (zoom_ppm > view_ppm) + { + zoom = std::max(1, i-1);// todo, maybe dont do this, but it makes things faster + break; + } + } + + double zoom_ppm = pixels_per_meter(minlat, zoom); + + // Finally convert to tile coords + get_tile_at(minlat, minlon, zoom, xmin, ymin); + get_tile_at(maxlat, maxlon, zoom, xmax, ymax); + + //printf("Lat: %f to %f\nLon: %f to %f\n", minlat, maxlat, minlon, maxlon); + //printf("Zoom: %i TilePPM: %f ViewPPM: %f\n", zoom, zoom_ppm, view_ppm); + } + else + { + //set to center + default_zoom with default_tiles on each side + zoom = default_zoom_->GetValue(); + + double lat, lon; + xy->ToLatLon(ax, ay, lat, lon); + + int x,y; + get_tile_at(lat, lon, zoom, x, y); + + int tiles = default_tiles_->GetValue(); + xmin = std::max(0, x - tiles); + ymin = std::max(0, y - tiles); + int maxn = pow(2, zoom) - 1; + xmax = std::min(maxn, x + tiles); + ymax = std::min(maxn, y + tiles); + + // to do this i would need to intersect frustum with plane to get a shape + // then would need to estimate a zoom and intersecting chunks + } + + if (xmax < xmin) std::swap(xmin, xmax); + if (ymax < ymin) std::swap(ymin, ymax); + + //printf("X: %i to %i\nY: %i to %i\n", xmin, xmax, ymin, ymax); + + // todo this probably craps itself at map edge + // First get a list of all tiles to render in the area + std::map to_render;// todo try something with fewer allocations? + for (int x = xmin; x <= xmax; x++) + { + for (int y = ymin; y <= ymax; y++) + { + // todo need to wrap coords around edges properly + //printf("Tile: http://tile.openstreetmap.org/%i/%i/%i.png\n", zoom, x, y); + + auto tile = cache_.GetTile(x, y, zoom); + if (tile.texture >= 0) + { + to_render[tile.coord] = tile.texture; + } + + if (show_outline) + { + glLineWidth(4.0f); + glBegin(GL_LINE_STRIP); + + glColor3f(1.0, 1.0, 1.0); + + double lat, lon; + Vec3d p; + get_tile_ll(x, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x+1, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x+1, y+1, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x, y+1, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + + glEnd(); + } + } + } + + // this is kinda silly, but works well + // Then sort the tiles by zoom level and render + for (auto tile: to_render) + { + int x = tile.first.x; + int y = tile.first.y; + int zoom = tile.first.z; + int texture = tile.second; + double lat, lon; + double px, py; + glEnable(GL_BLEND); + + //printf("RTexture: %i\n", texture); + + // Now draw the costmap itself + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture); + glBegin(GL_TRIANGLES); + + glColor4f(1.0f, 1.0f, 1.0f, alpha_->GetValue() ); + + Vec3d p; + glTexCoord2d(0, 0); + get_tile_ll(x, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + glTexCoord2d(1.0, 0); + get_tile_ll(x+1, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + glTexCoord2d(1.0, 1.0); + get_tile_ll(x+1, y+1, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + + glTexCoord2d(0, 0); + get_tile_ll(x, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + glTexCoord2d(1.0, 1.0); + get_tile_ll(x+1, y+1, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + glTexCoord2d(0, 1.0); + get_tile_ll(x, y+1, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + glDisable(GL_BLEND); + + if (show_outline) + { + glLineWidth(4.0f); + glBegin(GL_LINE_STRIP); + + glColor3f(1.0, 0.0, 0.0); + + double lat, lon; + get_tile_ll(x, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x+1, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x+1, y+1, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x, y+1, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + get_tile_ll(x, y, zoom, lat, lon); + p = Vec3d(lat, lon, 0); + canvas->TransformToView(OpenGLCanvas::WGS84, p); + glVertex2f(p.x, p.y); + + glEnd(); + } + } + } + + virtual void Initialize(Gwen::Controls::Properties* tree) + { + // add any properties + alpha_.reset(AddFloatProperty(tree, "Alpha", 1.0, 0.0, 1.0, 0.1, "Tile transparency.")); + + show_outline_.reset(AddBooleanProperty(tree, "Show Outline", false, "If true, draw outlines around the tiles.")); + + max_zoom_.reset(AddNumberProperty(tree, "Max Zoom", 19, 1, 22, 1, "Max zoom level to download/show.")); + + default_zoom_.reset(AddNumberProperty(tree, "3D Zoom Level", 17, 1, 22, 1, "Zoom level to use in views other than top down.")); + + default_tiles_.reset(AddNumberProperty(tree, "3D Tiles", 2, 0, 5, 1, "Number of tiles to show around center tile in views other than top down.")); + } + + std::string GetTitle() override + { + return "Map"; + } +}; + +REGISTER_PLUGIN("map", MapPlugin) + +#endif diff --git a/plugins/Marker.h b/plugins/Marker.h index a008cb1..d3659e1 100644 --- a/plugins/Marker.h +++ b/plugins/Marker.h @@ -92,15 +92,13 @@ class MarkerPlugin: public pubviz::Plugin { if (Paused()) { - free(data->data); - free(data);//todo use allocator free + delete data; continue; } // user is responsible for freeing the message and its arrays markers_[data->id] = *data; - free(data->data); - free(data);//todo use allocator free + delete data; Redraw(); } @@ -126,14 +124,20 @@ class MarkerPlugin: public pubviz::Plugin // draw the marker Gwen::Color color = color_->GetValue(); glLineWidth(line_width_->GetValue()); + auto frame = OpenGLCanvas::WGS84; + if (last_msg_.frame != pubsub::msg::Marker::FRAME_WGS84) + { + frame = OpenGLCanvas::Odom; + } + auto canvas = GetCanvas(); if (last_msg_.marker_type == pubsub::msg::Marker::LINE_LIST_2D) { // 2d lines glBegin(GL_LINES); - for (int i = 0; i + 1 < last_msg_.data_length; i += 2) + for (int i = 0; i + 1 < last_msg_.data.size(); i += 2) { int ci = i / 2; - if (ci < last_msg_.colors_length) + if (ci < last_msg_.colors.size()) { uint32_t c = last_msg_.colors[ci]; uint8_t r = (c & 0xFF0000) >> 16; @@ -145,30 +149,10 @@ class MarkerPlugin: public pubviz::Plugin { glColor3f(color.r / 255.0, color.g / 255.0, color.b / 255.0); } - if (last_msg_.frame == pubsub::msg::Marker::FRAME_WGS84) - { - if (GetCanvas()->wgs84_mode_) - { - double x, y; - GetCanvas()->local_xy_.FromLatLon(last_msg_.data[i], last_msg_.data[i + 1], x, y); - glVertex2f(x, y); - } - else - { - // todo - } - } - else - { - if (GetCanvas()->wgs84_mode_) - { - // todo - } - else - { - glVertex2f(last_msg_.data[i], last_msg_.data[i + 1]); - } - } + + Vec3d pos(last_msg_.data[i], last_msg_.data[i+1], 0); + canvas->TransformToView(frame, pos); + glVertex2f(pos.x, pos.y); } glEnd(); } @@ -176,7 +160,7 @@ class MarkerPlugin: public pubviz::Plugin { // 2d line segments int i = 0; - while (i < last_msg_.data_length) + while (i < last_msg_.data.size()) { int count = last_msg_.data[i]; int end_index = i + count*2; @@ -184,10 +168,10 @@ class MarkerPlugin: public pubviz::Plugin // draw a line segment glBegin(GL_LINE_STRIP); glColor3f(color.r/255.0, color.g/255.0, color.b/255.0); - for (; i < std::min(end_index, last_msg_.data_length-1); i += 2) + for (; i < std::min(end_index, last_msg_.data.size()-1); i += 2) { int ci = i / 2; - if (ci < last_msg_.colors_length) + if (ci < last_msg_.colors.size()) { uint32_t c = last_msg_.colors[ci]; uint8_t r = (c & 0xFF0000) >> 16; @@ -195,32 +179,9 @@ class MarkerPlugin: public pubviz::Plugin uint8_t b = (c & 0xFF); glColor3f(r / 255.0, g / 255.0, b / 255.0); } - if (last_msg_.frame == pubsub::msg::Marker::FRAME_WGS84) - { - if (GetCanvas()->wgs84_mode_) - { - double x, y; - GetCanvas()->local_xy_.FromLatLon(last_msg_.data[i], last_msg_.data[i + 1], x, y); - //x += GetCanvas()->origin_x_; - //y += GetCanvas()->origin_y_; - glVertex2f(x, y); - } - else - { - // todo - } - } - else - { - if (GetCanvas()->wgs84_mode_) - { - // todo - } - else - { - glVertex2f(last_msg_.data[i], last_msg_.data[i + 1]); - } - } + Vec3d pos(last_msg_.data[i], last_msg_.data[i+1], 0); + canvas->TransformToView(frame, pos); + glVertex2f(pos.x, pos.y); } glEnd(); } @@ -229,7 +190,7 @@ class MarkerPlugin: public pubviz::Plugin { // 2d polygons (just draw outline atm) int i = 0; - while (i < last_msg_.data_length) + while (i < last_msg_.data.size()) { int count = last_msg_.data[i]; int start_index = i; @@ -238,11 +199,46 @@ class MarkerPlugin: public pubviz::Plugin // draw a line segment glBegin(GL_LINE_STRIP); glColor3f(color.r/255.0, color.g/255.0, color.b/255.0); - for (; i < std::min(end_index, last_msg_.data_length-1); i += 2) + for (; i < std::min(end_index, last_msg_.data.size()-1); i += 2) + { + Vec3d pos(last_msg_.data[i], last_msg_.data[i+1], 0); + canvas->TransformToView(frame, pos); + glVertex2f(pos.x, pos.y); + } + Vec3d pos(last_msg_.data[start_index], last_msg_.data[start_index+1], 0); + canvas->TransformToView(frame, pos); + glVertex2f(pos.x, pos.y); + glEnd(); + } + } + else if (last_msg_.marker_type == pubsub::msg::Marker::POINT_LIST_3D) + { + // 3d points with a radius in pixels? maybe negative can be pixels, positive in meters? + for (int i = 0; i + 3 < last_msg_.data.size(); i += 4) + { + const double x = last_msg_.data[i]; + const double y = last_msg_.data[i+1]; + const double z = last_msg_.data[i+2]; + const double size = last_msg_.data[i+3]; + + glPointSize(size); + glBegin(GL_POINTS); + int ci = i / 4; + if (ci < last_msg_.colors.size()) + { + uint32_t c = last_msg_.colors[ci]; + uint8_t r = (c & 0xFF0000) >> 16; + uint8_t g = (c & 0xFF00) >> 8; + uint8_t b = (c & 0xFF); + glColor3f(r / 255.0, g / 255.0, b / 255.0); + } + else { - glVertex2f(last_msg_.data[i], last_msg_.data[i+1]); + glColor3f(color.r/255.0, color.g/255.0, color.b/255.0); } - glVertex2f(last_msg_.data[start_index], last_msg_.data[start_index+1]); + Vec3d pos(x, y, z); + canvas->TransformToView(frame, pos); + glVertex3f(pos.x, pos.y, pos.z); glEnd(); } } diff --git a/plugins/Measure.h b/plugins/Measure.h new file mode 100644 index 0000000..7f6e893 --- /dev/null +++ b/plugins/Measure.h @@ -0,0 +1,200 @@ + +#ifndef PUBVIZ_PLUGIN_MEASURE_H +#define PUBVIZ_PLUGIN_MEASURE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define GLEW_STATIC +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#endif + +#include "../Plugin.h" +#include "../properties.h" + +#include + +class MeasurePlugin : public pubviz::Plugin +{ + FloatProperty* alpha_; + ColorProperty* color_; + NumberProperty* line_width_; + NumberProperty* point_size_; + + ButtonProperty* clear_; + +public: + + MeasurePlugin() + { + // dont use pubsub here + } + + virtual ~MeasurePlugin() + { + delete color_; + delete alpha_; + delete line_width_; + //delete show_points_; + delete point_size_; + delete clear_; + } + + // Clear out any historical data so the view gets cleared + virtual void Clear() + { + points_.clear(); + UpdatePoints(); + } + + virtual void Update() + { + + } + + struct Vertex + { + double x; + double y; + double z; + + Vertex() {} + Vertex(double x, double y, double z) + { + this->x = x; + this->y = y; + this->z = z; + } + }; + + std::vector points_; + std::vector transformed_pts_; + + virtual void Paint() + { + // draw labels between each point + auto r = GetCanvas()->GetSkin()->GetRender(); + + for (int i = 0; i < ((int)transformed_pts_.size())-1; i++) + { + auto start = transformed_pts_[i]; + auto end = transformed_pts_[i+1]; + + Vertex middle; + middle.x = (start.x + end.x)*0.5; + middle.y = (start.y + end.y)*0.5; + middle.z = (start.z + end.z)*0.5; + + int x, y; + GetCanvas()->WorldToPixel(middle.x, middle.y, middle.z, x, y); + + double distance = std::sqrt(std::pow(start.x - end.x, 2.0) + + std::pow(start.y - end.y, 2.0) + + std::pow(start.z - end.z, 2.0)); + r->SetDrawColor( Gwen::Color(255,255,255,255) ); + char buf[50]; + sprintf(buf, "%g", distance); + r->RenderText(GetCanvas()->GetSkin()->GetDefaultFont(), Gwen::PointF( x, y ), (std::string)buf); + } + } + + void UpdatePoints() + { + // Now transform the points + transformed_pts_.clear(); + transformed_pts_.reserve(points_.size()); + for (auto& pt : points_) + { + + } + Redraw(); + } + + virtual void Render() + { + if (points_.size() == 0) + { + return; + } + + Gwen::Color color = color_->GetValue(); + + //UpdatePoints(); + + // Now render the points + glLineWidth(line_width_->GetValue()); + glBegin(GL_LINE_STRIP); + glColor3f(color.r / 255.0, color.g / 255.0, color.b / 255.0); + for (const auto& vert : transformed_pts_) + { + glVertex3f(vert.x, vert.y, vert.z); + } + glEnd(); + + if (true)//show_points_->GetValue()) + { + glPointSize(point_size_->GetValue()); + glBegin(GL_POINTS); + glColor3f(color.r / 255.0, color.g / 255.0, color.b / 255.0); + for (const auto& vert : transformed_pts_) + { + glVertex3f(vert.x, vert.y, vert.z); + } + glEnd(); + } + } + + virtual void Initialize(Gwen::Controls::Properties* tree) + { + // add any properties + alpha_ = AddFloatProperty(tree, "Alpha", 1.0, 0.0, 1.0, 0.1); + + color_ = AddColorProperty(tree, "Color", Gwen::Color(255, 50, 50)); + + line_width_ = AddNumberProperty(tree, "Line Width", 4, 1, 100, 2); + + point_size_ = AddNumberProperty(tree, "Point Size", 6, 1, 100, 2); + + clear_ = AddButtonProperty(tree, "Clear"); + clear_->onChange = [this]() + { + points_.clear(); + UpdatePoints(); + }; + } + + std::string GetTitle() override + { + return "Measure"; + } + + // Applies only for 2d + virtual bool OnMapClick(double x, double y) + { + points_.push_back(Vertex(x,y,0)); + + UpdatePoints(); + return true; +//okay, need to get the frame for this, then add to list on tap + } +}; + +REGISTER_PLUGIN("measure", MeasurePlugin) + +#endif diff --git a/plugins/Path.h b/plugins/Path.h index 887d40c..63421f5 100644 --- a/plugins/Path.h +++ b/plugins/Path.h @@ -43,7 +43,7 @@ class PathPlugin : public pubviz::Plugin bool sub_open_ = false; ps_sub_t subscriber_; - pubsub::msg::Path last_msg_; + pubsub::msg::Path* last_msg_ = 0; std::string current_topic_; void Subscribe(std::string str) @@ -78,6 +78,11 @@ class PathPlugin : public pubviz::Plugin delete show_points_; delete point_size_; + if (last_msg_) + { + delete last_msg_; + } + if (sub_open_) { ps_sub_destroy(&subscriber_); @@ -88,7 +93,9 @@ class PathPlugin : public pubviz::Plugin // Clear out any historical data so the view gets cleared virtual void Clear() { - last_msg_.points_length = 0; + if (last_msg_) + delete last_msg_; + last_msg_ = 0; } virtual void Update() @@ -102,15 +109,16 @@ class PathPlugin : public pubviz::Plugin { if (Paused()) { - free(data->points); - free(data);//todo use allocator free + delete data; continue; } // user is responsible for freeing the message and its arrays - last_msg_ = *data; - free(data->points); - free(data);//todo use allocator free + if (last_msg_) + { + delete last_msg_; + } + last_msg_ = data; Redraw(); } @@ -135,7 +143,7 @@ class PathPlugin : public pubviz::Plugin std::vector transformed_pts_; virtual void Render() { - if (last_msg_.points_length == 0) + if (last_msg_ == 0) { return; } @@ -143,32 +151,32 @@ class PathPlugin : public pubviz::Plugin Gwen::Color color = color_->GetValue(); points_.clear(); - if (last_msg_.path_type == pubsub::msg::Path::PATH_XY) + if (last_msg_->path_type == pubsub::msg::Path::PATH_XY) { - for (int i = 0; i < (int)last_msg_.points_length - 1; i += 2) + for (int i = 0; i < (int)last_msg_->points.size() - 1; i += 2) { - points_.push_back({ last_msg_.points[i], last_msg_.points[i + 1], 0.0 }); + points_.push_back({ last_msg_->points[i], last_msg_->points[i + 1], 0.0 }); } } - if (last_msg_.path_type == pubsub::msg::Path::PATH_XY_Y) + else if (last_msg_->path_type == pubsub::msg::Path::PATH_XY_Y) { - for (int i = 0; i < (int)last_msg_.points_length - 2; i += 3) + for (int i = 0; i < (int)last_msg_->points.size() - 2; i += 3) { - points_.push_back({ last_msg_.points[i], last_msg_.points[i + 1], 0.0 }); + points_.push_back({ last_msg_->points[i], last_msg_->points[i + 1], 0.0 }); } } - else if (last_msg_.path_type == pubsub::msg::Path::PATH_XYZ) + else if (last_msg_->path_type == pubsub::msg::Path::PATH_XYZ) { - for (int i = 0; i < (int)last_msg_.points_length - 2; i += 3) + for (int i = 0; i < (int)last_msg_->points.size() - 2; i += 3) { - points_.push_back({ last_msg_.points[i], last_msg_.points[i + 1], last_msg_.points[i + 2] }); + points_.push_back({ last_msg_->points[i], last_msg_->points[i + 1], last_msg_->points[i + 2] }); } } - else if (last_msg_.path_type == pubsub::msg::Path::PATH_XYZ_Y) + else if (last_msg_->path_type == pubsub::msg::Path::PATH_XYZ_Y) { - for (int i = 0; i < (int)last_msg_.points_length - 3; i += 4) + for (int i = 0; i < (int)last_msg_->points.size() - 3; i += 4) { - points_.push_back({ last_msg_.points[i], last_msg_.points[i + 1], last_msg_.points[i + 2] }); + points_.push_back({ last_msg_->points[i], last_msg_->points[i + 1], last_msg_->points[i + 2] }); } } else @@ -176,36 +184,19 @@ class PathPlugin : public pubviz::Plugin printf("ERROR: Unknown path type\n"); } + auto frame = OpenGLCanvas::WGS84; + if (last_msg_->frame != pubsub::msg::Path::FRAME_WGS84) + { + frame = OpenGLCanvas::Odom; + } // Now transform the points transformed_pts_.clear(); transformed_pts_.reserve(points_.size()); for (auto& pt : points_) { - if (last_msg_.frame == pubsub::msg::Path::FRAME_WGS84) - { - if (GetCanvas()->wgs84_mode_) - { - double x, y; - GetCanvas()->local_xy_.FromLatLon(pt.x, pt.y, x, y); - - transformed_pts_.push_back({ x, y, pt.z }); - } - else - { - // todo - } - } - else - { - if (GetCanvas()->wgs84_mode_) - { - // todo - } - else - { - transformed_pts_.push_back(pt); - } - } + Vec3 p(pt.x, pt.y, pt.z); + GetCanvas()->TransformToView(frame, p); + transformed_pts_.push_back({p.x,p.y,p.z}); } // Now render the points diff --git a/plugins/PlanPath.h b/plugins/PlanPath.h new file mode 100644 index 0000000..b04cf20 --- /dev/null +++ b/plugins/PlanPath.h @@ -0,0 +1,237 @@ + +#ifndef PUBVIZ_PLUGIN_PLAN_PATH_H +#define PUBVIZ_PLUGIN_PLAN_PATH_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define GLEW_STATIC +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#endif + +#include "../Plugin.h" +#include "../properties.h" + +#include + +#include + +class PlanPathPlugin : public pubviz::Plugin +{ + FloatProperty* alpha_; + ColorProperty* color_; + NumberProperty* line_width_; + NumberProperty* point_size_; + + EnumProperty* frame_; + + TopicProperty* topic_; + + ButtonProperty* publish_; + ButtonProperty* clear_; + + bool pub_open_ = false; + ps_pub_t publisher_; + + std::string current_topic_; + void ChangeTopic(std::string str) + { + if (pub_open_) + { + ps_pub_destroy(&publisher_); + } + + current_topic_ = str; + ps_node_create_publisher(GetNode(), current_topic_.c_str(), &pubsub__Path_def, &publisher_, true); + pub_open_ = true; + } + + void FrameChanged(std::string str) + { + + } + +public: + + int frame_enum_ = pubsub::msg::Path::FRAME_ODOM; + PlanPathPlugin() + { + // dont use pubsub here + + } + + virtual ~PlanPathPlugin() + { + delete color_; + delete alpha_; + delete line_width_; + //delete show_points_; + delete point_size_; + delete publish_; + delete clear_; + + if (pub_open_) + { + ps_pub_destroy(&publisher_); + pub_open_ = false; + } + } + + // Clear out any historical data so the view gets cleared + virtual void Clear() + { + points_.clear(); + } + + virtual void Update() + { + + } + + struct Vertex + { + double x; + double y; + double z; + + Vertex(double x, double y, double z) + { + this->x = x; + this->y = y; + this->z = z; + } + }; + + std::vector points_; + std::vector transformed_pts_; + virtual void Render() + { + if (points_.size() == 0) + { + return; + } + + Gwen::Color color = color_->GetValue(); + + // Now transform the points + transformed_pts_.clear(); + transformed_pts_.reserve(points_.size()); + for (auto& pt : points_) + { + auto f = frame_enum_ == pubsub::msg::Path::FRAME_WGS84 ? OpenGLCanvas::WGS84 : OpenGLCanvas::Odom; + Vec3d pos(pt.x, pt.y, 0); + GetCanvas()->TransformToView(f, pos); + transformed_pts_.push_back({pos.x, pos.y, pos.z}); + } + + // Now render the points + glLineWidth(line_width_->GetValue()); + glBegin(GL_LINE_STRIP); + glColor3f(color.r / 255.0, color.g / 255.0, color.b / 255.0); + for (const auto& vert : transformed_pts_) + { + glVertex3f(vert.x, vert.y, vert.z); + } + glEnd(); + + if (true) + { + glPointSize(point_size_->GetValue()); + glBegin(GL_POINTS); + glColor3f(color.r / 255.0, color.g / 255.0, color.b / 255.0); + for (const auto& vert : transformed_pts_) + { + glVertex3f(vert.x, vert.y, vert.z); + } + glEnd(); + } + } + + virtual void Initialize(Gwen::Controls::Properties* tree) + { + // add any properties + alpha_ = AddFloatProperty(tree, "Alpha", 1.0, 0.0, 1.0, 0.1); + + color_ = AddColorProperty(tree, "Color", Gwen::Color(255, 50, 50)); + + topic_ = AddTopicProperty(tree, "Topic", "/path", "", "pubsub__Path"); + topic_->onChange = std::bind(&PlanPathPlugin::ChangeTopic, this, std::placeholders::_1); + + line_width_ = AddNumberProperty(tree, "Line Width", 4, 1, 100, 2); + + frame_ = AddEnumProperty(tree, "Frame", "Odom", {"Odom", "WGS84"}, "Frame to publish path in."); + frame_->onChange = [this](std::string frame) + { + //clear the path and set the frame + points_.clear(); + frame_enum_ = (frame == "Odom" ? pubsub::msg::Path::FRAME_ODOM : pubsub::msg::Path::FRAME_WGS84); + }; + + point_size_ = AddNumberProperty(tree, "Point Size", 6, 1, 100, 2); + + publish_ = AddButtonProperty(tree, "Publish"); + publish_->onChange = [this]() + { + std::vector points; + for (const auto& pt: points_) + { + points.push_back(pt.x); + points.push_back(pt.y); + points.push_back(pt.z); + } + pubsub::msg::Path msg; + msg.frame = frame_enum_; + msg.path_type = pubsub::msg::Path::PATH_XY_Y; + msg.points = points; + ps_pub_publish_ez(&publisher_, &msg); + }; + clear_ = AddButtonProperty(tree, "Clear"); + clear_->onChange = [this]() + { + points_.clear(); + Redraw(); + }; + + ChangeTopic(topic_->GetValue()); + } + + std::string GetTitle() override + { + return "Plan Path"; + } + + // Applies only for 2d + virtual bool OnMapClick(double x, double y) + { + printf("map_click %f %f\n", x, y); + Vec3d pos(x, y, 0); + auto src = GetCanvas()->wgs84_mode() ? OpenGLCanvas::Map : OpenGLCanvas::Odom; + auto dst = frame_enum_ == pubsub::msg::Path::FRAME_WGS84 ? OpenGLCanvas::WGS84 : OpenGLCanvas::Odom; + GetCanvas()->TransformToFrame(src, dst, pos); + // transform to correct frame + points_.push_back(Vertex(pos.x, pos.y, std::numeric_limits::quiet_NaN())); + + Redraw(); + return true; + } +}; + +REGISTER_PLUGIN("plan_path", PlanPathPlugin) + +#endif diff --git a/plugins/PointCloud.h b/plugins/PointCloud.h index 20d020f..785586e 100644 --- a/plugins/PointCloud.h +++ b/plugins/PointCloud.h @@ -18,6 +18,8 @@ #include #include +#include + #define GLEW_STATIC #include @@ -29,42 +31,42 @@ #include #endif - +#include #undef min #undef max class PointCloudPlugin: public pubviz::Plugin { - FloatProperty* alpha_; - StringProperty* point_text_; - NumberProperty* point_size_; - NumberProperty* history_length_; + std::unique_ptr alpha_; + std::unique_ptr point_text_; + std::unique_ptr point_size_; + std::unique_ptr history_length_; // Coloring Properties - EnumProperty* coloring_mode_; + std::unique_ptr coloring_mode_; // Used in all modes besides single color - EnumProperty* coloring_field_;// point field to use for coloring + std::unique_ptr coloring_field_;// point field to use for coloring // Used in interpolated mode and clamped mode - ColorProperty* min_color_; - ColorProperty* max_color_; - BooleanProperty* auto_min_max_; + std::unique_ptr min_color_; + std::unique_ptr max_color_; + std::unique_ptr auto_min_max_; // Used when auto min_max is false - FloatProperty* min_value_; - FloatProperty* max_value_; + std::unique_ptr min_value_; + std::unique_ptr max_value_; // Used in clamped mode - ColorProperty* floored_color_; - ColorProperty* ceiled_color_; + std::unique_ptr floored_color_; + std::unique_ptr ceiled_color_; - // Used + std::unique_ptr yaw_, pitch_, roll_; // Used in single color mode - ColorProperty* single_color_; + std::unique_ptr single_color_; - TopicProperty* topic_; + std::unique_ptr topic_; bool sub_open_ = false; ps_sub_t subscriber_; @@ -82,6 +84,7 @@ class PointCloudPlugin: public pubviz::Plugin unsigned int point_vbo; unsigned int color_vbo; + int stride;// number of floats per point pubsub::msg::PointCloud* original_cloud;// used for re-coloring // position of the cloud @@ -94,162 +97,180 @@ class PointCloudPlugin: public pubviz::Plugin { glDeleteBuffers(1, &point_vbo); glDeleteBuffers(1, &color_vbo); - free(original_cloud->data); - free(original_cloud); + delete original_cloud; } }; + float latest_min_ = std::numeric_limits::max(); + float latest_max_ = std::numeric_limits::lowest(); void BuildCloudBuffers(Cloud* cloud) { auto data = cloud->original_cloud; point_buf_.resize(data->num_points); color_buf_.resize(data->num_points); - uint8_t alpha = 255.0*alpha_->GetValue(); - Gwen::Color min_color = min_color_->GetValue(); - Gwen::Color max_color = max_color_->GetValue(); + uint8_t alpha = 255.0*alpha_->GetValue(); + Gwen::Color min_color = min_color_->GetValue(); + Gwen::Color max_color = max_color_->GetValue(); - // now make the right kind of points then render - if (data->point_type == pubsub::msg::PointCloud::POINT_XYZ) + auto fdata = (float*)data->data.data(); + + // x,y,z,intensity as floats + int color_offset = 3;// intensity, give option for other values + auto field = coloring_field_->GetValue(); + if (field == "X") + { + color_offset = 0; + } + else if (field == "Y") + { + color_offset = 1; + } + else if (field == "Z") + { + color_offset = 2; + } + else if (field == "Intensity") + { + color_offset = 3; + } + else if (field == "Other") + { + color_offset = 4; + } + + // make sure we dont read too much + const int stride = cloud->stride; + if (color_offset >= stride) + { + // todo enforce this better + printf("WARNING: The field %s is not in this pointcloud.\n", field.c_str()); + color_offset = stride - 1; + } + + // get min and max for the field + float min = std::numeric_limits::max(); + float max = std::numeric_limits::lowest(); + if (auto_min_max_->GetValue()) + { + for (int i = 0; i < data->num_points; i++) + { + auto value = fdata[i*stride+color_offset]; + min = std::min(min, value); + max = std::max(max, value); + } + latest_min_ = min; + latest_max_ = max; + } + else + { + min = min_value_->GetValue(); + max = max_value_->GetValue(); + } + + float byte_scale = 255.0/(max-min); + float scale = 1.0/(max-min); + + if (std::abs(max - min) < 0.0001) + { + byte_scale = 0.0; + scale = 0.0; + } + + auto mode = coloring_mode_->GetValue(); + if (mode == "Jet" || mode == "Rainbow") + { + auto table = mode == "Jet" ? jet_table_ : rainbow_table_; + for (int i = 0; i < data->num_points; i++) + { + point_buf_[i].x = fdata[i*stride]; + point_buf_[i].y = fdata[i*stride+1]; + point_buf_[i].z = fdata[i*stride+2]; + int index = (fdata[i*stride+color_offset]-min)*byte_scale; + if (index < 0) + index = 0; + else if (index > 255) + index = 255; + uint8_t r = table[index].r; + uint8_t g = table[index].g; + uint8_t b = table[index].b; + + color_buf_[i] = (alpha << 24) | r | (g << 8) | (b << 16); + } + } + else if (mode == "Single Color") + { + auto color = single_color_->GetValue(); + for (int i = 0; i < data->num_points; i++) + { + point_buf_[i].x = fdata[i*stride]; + point_buf_[i].y = fdata[i*stride+1]; + point_buf_[i].z = fdata[i*stride+2]; + uint8_t r = color.r; + uint8_t g = color.g; + uint8_t b = color.b; + + color_buf_[i] = (alpha << 24) | r | (g << 8) | (b << 16); + } + } + else + { + Gwen::Color lt_min_color = min_color; + Gwen::Color gt_max_color = max_color; + if (mode == "Clamped") + { + lt_min_color = floored_color_->GetValue(); + gt_max_color = ceiled_color_->GetValue(); + } + for (int i = 0; i < data->num_points; i++) + { + point_buf_[i].x = fdata[i*stride]; + point_buf_[i].y = fdata[i*stride+1]; + point_buf_[i].z = fdata[i*stride+2]; + float frac = (fdata[i*stride+color_offset]-min)*scale; + if (frac < 0) { - // x,y,z as floats - for (int i = 0; i < data->num_points; i++) - { - point_buf_[i].x = ((float*)data->data)[i*3]; - point_buf_[i].y = ((float*)data->data)[i*3+1]; - point_buf_[i].z = ((float*)data->data)[i*3+2]; - color_buf_[i] = (alpha << 24) | (max_color.b << 16) | (max_color.g << 8) | max_color.r; - } + frac = 0; + color_buf_[i] = (alpha << 24) | lt_min_color.r | (lt_min_color.g << 8) | (lt_min_color.b << 16); + continue; } - else if (data->point_type == pubsub::msg::PointCloud::POINT_XYZI) + else if (frac > 1.0) { - // x,y,z,intensity as floats - int color_offset = 3;// intensity, give option for other values - auto field = coloring_field_->GetValue(); - if (field == "X") - { - color_offset = 0; - } - else if (field == "Y") - { - color_offset = 1; - } - else if (field == "Z") - { - color_offset = 2; - } - else if (field == "Intensity") - { - color_offset = 3; - } - - // get min and max for the field - float min = 100000000.0; - float max = -100000000.0; - if (auto_min_max_->GetValue()) - { - for (int i = 0; i < data->num_points; i++) - { - auto value = ((float*)data->data)[i*4+color_offset]; - min = std::min(min, value); - max = std::max(max, value); - } - } - else - { - min = min_value_->GetValue(); - max = max_value_->GetValue(); - } - - float byte_scale = 255.0/(max-min); - float scale = 1.0/(max-min); - - if (std::abs(max - min) < 0.0001) - { - byte_scale = 0.0; - scale = 0.0; - } - - auto mode = coloring_mode_->GetValue(); - if (mode == "Jet" || mode == "Rainbow") - { - auto table = mode == "Jet" ? jet_table_ : rainbow_table_; - for (int i = 0; i < data->num_points; i++) - { - point_buf_[i].x = ((float*)data->data)[i*4]; - point_buf_[i].y = ((float*)data->data)[i*4+1]; - point_buf_[i].z = ((float*)data->data)[i*4+2]; - int index = (((float*)data->data)[i*4+color_offset]-min)*byte_scale; - if (index < 0) - index = 0; - else if (index > 255) - index = 255; - uint8_t r = table[index].r; - uint8_t g = table[index].g; - uint8_t b = table[index].b; - - color_buf_[i] = (alpha << 24) | r | (g << 8) | (b << 16); - } - } - else if (mode == "Single Color") - { - auto color = single_color_->GetValue(); - for (int i = 0; i < data->num_points; i++) - { - point_buf_[i].x = ((float*)data->data)[i*4]; - point_buf_[i].y = ((float*)data->data)[i*4+1]; - point_buf_[i].z = ((float*)data->data)[i*4+2]; - uint8_t r = color.r; - uint8_t g = color.g; - uint8_t b = color.b; - - color_buf_[i] = (alpha << 24) | r | (g << 8) | (b << 16); - } - } - else - { - Gwen::Color lt_min_color = min_color; - Gwen::Color gt_max_color = max_color; - if (mode == "Clamped") - { - lt_min_color = floored_color_->GetValue(); - gt_max_color = ceiled_color_->GetValue(); - } - for (int i = 0; i < data->num_points; i++) - { - point_buf_[i].x = ((float*)data->data)[i*4]; - point_buf_[i].y = ((float*)data->data)[i*4+1]; - point_buf_[i].z = ((float*)data->data)[i*4+2]; - float frac = (((float*)data->data)[i*4+color_offset]-min)*scale; - if (frac < 0) - { - frac = 0; - color_buf_[i] = (alpha << 24) | lt_min_color.r | (lt_min_color.g << 8) | (lt_min_color.b << 16); - continue; - } - else if (frac > 1.0) - { - frac = 1.0; -color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max_color.b << 16); - continue; - } - uint8_t r = frac*(max_color.r - min_color.r) + min_color.r; - uint8_t g = frac*(max_color.g - min_color.g) + min_color.g; - uint8_t b = frac*(max_color.b - min_color.b) + min_color.b; - - color_buf_[i] = (alpha << 24) | r | (g << 8) | (b << 16); - } - } + frac = 1.0; + color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max_color.b << 16); + continue; } + uint8_t r = frac*(max_color.r - min_color.r) + min_color.r; + uint8_t g = frac*(max_color.g - min_color.g) + min_color.g; + uint8_t b = frac*(max_color.b - min_color.b) + min_color.b; + + color_buf_[i] = (alpha << 24) | r | (g << 8) | (b << 16); + } + } + + // transform the points + Quaternion rotx, roty, rotz; + rotz.FromAngleAxis(yaw_->GetValue()*3.141592/180.0, Vec3f(0,0,1)); + roty.FromAngleAxis(pitch_->GetValue()*3.141592/180.0, Vec3f(0,1,0)); + rotx.FromAngleAxis(roll_->GetValue()*3.141592/180.0, Vec3f(1,0,0)); + Quaternion rot = (rotz*roty)*rotx; + Matrix3x4 matrix(rot, Vec3d(0,0,0)); + for (int i = 0; i < data->num_points; i++) + { + auto res = matrix.transform(Vec3d(point_buf_[i].x, point_buf_[i].y, point_buf_[i].z)); + point_buf_[i].x = res.x;//fdata[i*stride]; + point_buf_[i].y = res.y;//fdata[i*stride+1]; + point_buf_[i].z = res.z;//fdata[i*stride+2]; + } - // upload! - glBindBuffer(GL_ARRAY_BUFFER, cloud->point_vbo); - glBufferData(GL_ARRAY_BUFFER, point_buf_.size()*12, point_buf_.data(), GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, cloud->color_vbo); - glBufferData(GL_ARRAY_BUFFER, color_buf_.size()*4, color_buf_.data(), GL_STATIC_DRAW); + // upload! + glBindBuffer(GL_ARRAY_BUFFER, cloud->point_vbo); + glBufferData(GL_ARRAY_BUFFER, point_buf_.size()*12, point_buf_.data(), GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, cloud->color_vbo); + glBufferData(GL_ARRAY_BUFFER, color_buf_.size()*4, color_buf_.data(), GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); } std::deque clouds_; @@ -319,6 +340,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max void AutoMinMaxChange(bool value) { + // if we disabled it, update max and min values from latest if (value) { min_value_->Hide(); @@ -328,6 +350,12 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max { min_value_->Show(); max_value_->Show(); + + if (latest_max_ >= latest_min_) + { + min_value_->SetValue(latest_min_); + max_value_->SetValue(latest_max_); + } } // Recolor all clouds @@ -356,7 +384,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max } auto r = tree->GetSkin()->GetRender(); - r->SetDrawColor(Gwen::Color(255, 0, 255, 255)); + r->SetDrawColor(Gwen::Color(255, 255, 255, 255)); // Measure the text to determine the best texture size auto s = r->MeasureText(f, value); @@ -425,17 +453,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max } virtual ~PointCloudPlugin() - { - delete min_color_; - delete max_color_; - delete alpha_; - delete point_size_; - delete history_length_; - delete point_text_; - delete coloring_mode_; - delete single_color_; - // todo use smart pointers - + { glDeleteFramebuffers(1, &frame_buffer_); glDeleteTextures(1, &render_texture_); @@ -470,8 +488,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max // user is responsible for freeing the message and its arrays if (Paused()) { - free(data->data); - free(data);//todo use allocator free + delete data; continue; } @@ -483,8 +500,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max clouds_.push_front(clouds_.back()); clouds_.pop_back(); cloud = &clouds_[0]; - free(cloud->original_cloud->data); - free(cloud->original_cloud); + delete cloud->original_cloud; } else { @@ -495,6 +511,11 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max cloud = &clouds_[clouds_.size()-1]; } + cloud->stride = 5; + if (data->point_type == pubsub::msg::PointCloud::POINT_XYZ) + cloud->stride = 3; + if (data->point_type == pubsub::msg::PointCloud::POINT_XYZI) + cloud->stride = 4; cloud->num_points = data->num_points; cloud->original_cloud = data; @@ -521,7 +542,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max virtual void Render() { - if (GetCanvas()->wgs84_mode_) + if (GetCanvas()->wgs84_mode()) { return;// not supported for the moment } @@ -536,6 +557,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max { glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0); glEnable( GL_TEXTURE_2D ); glBindTexture(GL_TEXTURE_2D, render_texture_); glEnable(GL_POINT_SPRITE); @@ -585,8 +607,11 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max if (render_texture) { - glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + glDisable(GL_POINT_SPRITE); } glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -604,11 +629,12 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max { // its in this cloud auto data = cloud.original_cloud; + float* fdata = (float*)data->data.data(); int i = index - current; - int increment = data->point_type == pubsub::msg::PointCloud::POINT_XYZ ? 3 : 4; - float x = ((float*)data->data)[i*increment]; - float y = ((float*)data->data)[i*increment+1]; - float z = ((float*)data->data)[i*increment+2]; + int increment = cloud.stride; + float x = fdata[i*increment]; + float y = fdata[i*increment+1]; + float z = fdata[i*increment+2]; props["x"] = std::to_string(x); props["y"] = std::to_string(y); props["z"] = std::to_string(z); @@ -618,7 +644,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max size.sx = size.sy = size.sz = 0.2; if (data->point_type == pubsub::msg::PointCloud::POINT_XYZI) { - props["i"] = std::to_string(((float*)data->data)[i*increment+3]); + props["i"] = std::to_string(fdata[i*increment+3]); } break; } @@ -639,17 +665,19 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max glPointSize(point_size_->GetValue()); glBegin(GL_POINTS); auto data = cloud.original_cloud; - int increment = data->point_type == pubsub::msg::PointCloud::POINT_XYZ ? 3 : 4; + int increment = cloud.stride; + // todo handle more point cloud types + float* fdata = (float*)data->data.data(); for (int i = 0; i < data->num_points; i++) { //glColor4f(1.0, 0.0, 0.0, 1.0); //glColor4ub(start_index & 0xFF, (start_index & 0xFF00) >> 8, (start_index & 0xFF0000) >> 16, 255); glColor4ubv((unsigned char*)&start_index); start_index++; - glVertex3f(((float*)data->data)[i*increment], - ((float*)data->data)[i*increment+1], - ((float*)data->data)[i*increment+2]); + glVertex3f(fdata[i*increment], + fdata[i*increment+1], + fdata[i*increment+2]); } glEnd(); } @@ -694,47 +722,53 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max glBindFramebuffer(GL_FRAMEBUFFER, 0); // add any properties - alpha_ = AddFloatProperty(tree, "Alpha", 1.0, 0.0, 1.0, 0.1, "Point transparency."); + alpha_.reset(AddFloatProperty(tree, "Alpha", 1.0, 0.0, 1.0, 0.1, "Point transparency.")); alpha_->onChange = std::bind(&PointCloudPlugin::FloatConfigChanged, this, std::placeholders::_1); - topic_ = AddTopicProperty(tree, "Topic", "/pointcloud", "", "pubsub__PointCloud"); + topic_.reset(AddTopicProperty(tree, "Topic", "/pointcloud", "", "pubsub__PointCloud")); topic_->onChange = std::bind(&PointCloudPlugin::Subscribe, this, std::placeholders::_1); - point_text_ = AddStringProperty(tree, "Text", "", "If set, visualize the points as the given characters."); + point_text_.reset(AddStringProperty(tree, "Text", "", "If set, visualize the points as the given characters.")); point_text_->onChange = std::bind(&PointCloudPlugin::TextChange, this, std::placeholders::_1); TextChange(point_text_->GetValue()); - history_length_ = AddNumberProperty(tree, "History Length", 1, 1, 100, 1, "Number of past pointclouds to show."); + history_length_.reset(AddNumberProperty(tree, "History Length", 1, 1, 100, 1, "Number of past pointclouds to show.")); history_length_->onChange = std::bind(&PointCloudPlugin::HistoryLengthChange, this, std::placeholders::_1); - point_size_ = AddNumberProperty(tree, "Point Size", 4, 1, 100, 2, "Size in pixels for points."); + point_size_.reset(AddNumberProperty(tree, "Point Size", 4, 1, 100, 2, "Size in pixels for points.")); - coloring_mode_ = AddEnumProperty(tree, "Coloring Mode", "Interpolated", {"Interpolated", "Clamped", "Jet", "Rainbow", "Single Color"}, "Coloring mode."); + coloring_mode_ .reset(AddEnumProperty(tree, "Coloring Mode", "Jet", {"Interpolated", "Clamped", "Jet", "Rainbow", "Single Color"}, "Coloring mode.")); coloring_mode_->onChange = std::bind(&PointCloudPlugin::ColoringModeChange, this, std::placeholders::_1); - coloring_field_ = AddEnumProperty(tree, "Coloring Field", "Intensity", {"Intensity", "X", "Y", "Z"}, "Point field to use for coloring points."); + coloring_field_.reset(AddEnumProperty(tree, "Coloring Field", "Intensity", {"Intensity", "X", "Y", "Z", "Other"}, "Point field to use for coloring points.")); + coloring_field_->onChange = std::bind(&PointCloudPlugin::StringConfigChanged, this, std::placeholders::_1); - floored_color_ = AddColorProperty(tree, "Floor Color", Gwen::Color(0,255,0), "Color for points below the minimum value."); + floored_color_.reset(AddColorProperty(tree, "Floor Color", Gwen::Color(0,255,0), "Color for points below the minimum value.")); floored_color_->onChange = std::bind(&PointCloudPlugin::ColorConfigChanged, this, std::placeholders::_1); - ceiled_color_ = AddColorProperty(tree, "Ceiling Color", Gwen::Color(255,255,0), "Color for points above the minimum value."); + ceiled_color_.reset(AddColorProperty(tree, "Ceiling Color", Gwen::Color(255,255,0), "Color for points above the minimum value.")); ceiled_color_->onChange = std::bind(&PointCloudPlugin::ColorConfigChanged, this, std::placeholders::_1); - min_color_ = AddColorProperty(tree, "Min Color", Gwen::Color(255,255,255), "Color for the minimum value."); + min_color_.reset(AddColorProperty(tree, "Min Color", Gwen::Color(255,255,255), "Color for the minimum value.")); min_color_->onChange = std::bind(&PointCloudPlugin::ColorConfigChanged, this, std::placeholders::_1); - max_color_ = AddColorProperty(tree, "Max Color", Gwen::Color(255,0,0), "Color for the maximum value."); + max_color_.reset(AddColorProperty(tree, "Max Color", Gwen::Color(255,0,0), "Color for the maximum value.")); max_color_->onChange = std::bind(&PointCloudPlugin::ColorConfigChanged, this, std::placeholders::_1); - single_color_ = AddColorProperty(tree, "Point Color", Gwen::Color(255,255,255), "Color for points."); + single_color_.reset(AddColorProperty(tree, "Point Color", Gwen::Color(255,255,255), "Color for points.")); single_color_->onChange = std::bind(&PointCloudPlugin::ColorConfigChanged, this, std::placeholders::_1); - auto_min_max_ = AddBooleanProperty(tree, "Auto Min/Max", true, "If true, determine the min max values from each pointcloud automatically."); + auto_min_max_.reset(AddBooleanProperty(tree, "Auto Min/Max", true, "If true, determine the min max values from each pointcloud automatically.")); auto_min_max_->onChange = std::bind(&PointCloudPlugin::AutoMinMaxChange, this, std::placeholders::_1); - min_value_ = AddFloatProperty(tree, "Min Value", 0.0, -1000000.0, 1000000.0, 1.0, "Value at which min color is used."); + min_value_.reset(AddFloatProperty(tree, "Min Value", 0.0, -1000000.0, 1000000.0, 1.0, "Value at which min color is used.")); min_value_->onChange = std::bind(&PointCloudPlugin::FloatConfigChanged, this, std::placeholders::_1); - max_value_ = AddFloatProperty(tree, "Max Value", 255.0, -1000000.0, 1000000.0, 1.0, "Value at which max color is used."); + max_value_.reset(AddFloatProperty(tree, "Max Value", 255.0, -1000000.0, 1000000.0, 1.0, "Value at which max color is used.")); max_value_->onChange = std::bind(&PointCloudPlugin::FloatConfigChanged, this, std::placeholders::_1); + yaw_.reset(AddFloatProperty(tree, "Yaw", 0, -360, 360, 1, "")); + pitch_.reset(AddFloatProperty(tree, "Pitch", 0, -360, 360, 1, "")); + + roll_.reset(AddFloatProperty(tree, "Roll", 0, -360, 360, 1, "")); + // build color lookup tables for (int i = 0; i < 256; i++) @@ -747,7 +781,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max jet_table_[i] = GetJetColour(i, 0, 255); } - ColoringModeChange("Interpolated"); + ColoringModeChange("Jet"); Subscribe(topic_->GetValue()); } @@ -761,6 +795,15 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max } } + void StringConfigChanged(const std::string& str) + { + // Recolor all clouds + for (auto& cloud: clouds_) + { + BuildCloudBuffers(&cloud); + } + } + void FloatConfigChanged(float) { // Recolor all clouds @@ -771,7 +814,7 @@ color_buf_[i] = (alpha << 24) | gt_max_color.r | (gt_max_color.g << 8) | (gt_max } // Returns interpolated color ramp values in a Jet like fashion - Gwen::Color GetJetColour(double v,double vmin,double vmax) + Gwen::Color GetJetColour(double v, double vmin, double vmax) { Gwen::Color c(255,255,255); diff --git a/plugins/Pose.h b/plugins/Pose.h index c915227..1e374b5 100644 --- a/plugins/Pose.h +++ b/plugins/Pose.h @@ -14,6 +14,7 @@ #include #include +#include #define GLEW_STATIC #include @@ -41,9 +42,11 @@ class PosePlugin : public pubviz::Plugin BooleanProperty* follow_pose_; NumberProperty* history_length_; FloatProperty* sample_distance_; - BooleanProperty* draw_line_; NumberProperty* point_size_; EnumProperty* draw_style_; + EnumProperty* history_style_; + + std::unique_ptr use_transforms_; TopicProperty* topic_; @@ -61,15 +64,26 @@ class PosePlugin : public pubviz::Plugin { if (!state) { - GetCanvas()->ResetViewOrigin(); + // set the view to no longer follow but stay at same position + GetCanvas()->ResetViewPosition(); + } + else + { + // center on the latest pose so it works while paused + if (messages_.size()) + { + auto data = &messages_.back(); + GetCanvas()->SetViewOrigin(data->x, data->y, data->z, data->latitude, data->longitude, data->altitude); + GetCanvas()->ResetViewPosition(); + } } } void OnHistoryChange(int length) { - if (messages_.size() > length) + while (messages_.size() > length) { - messages_.resize(length); + messages_.pop_front(); } } @@ -189,13 +203,16 @@ class PosePlugin : public pubviz::Plugin messages_.pop_front(); } - // todo is there a better way to do this? - GetCanvas()->SetLocalXY(data->latitude, data->longitude); + if (use_transforms_->GetValue()) + { + // update our transform between wgs84 and odom + GetCanvas()->SetTransform(data->x, data->y, data->z, data->odom_yaw, data->latitude, data->longitude, data->altitude, data->yaw); + } if (follow_pose_->GetValue()) { // center view on me - GetCanvas()->SetViewOrigin(data->x, data->y, data->z, data->latitude, data->longitude, 0.0); + GetCanvas()->SetViewOrigin(data->x, data->y, data->z, data->latitude, data->longitude, data->altitude); } free(data);//todo use allocator free @@ -211,66 +228,114 @@ class PosePlugin : public pubviz::Plugin messages_.clear(); } + inline void draw_frame(float alpha, float line_length, const pubsub::msg::Pose& p) + { + // first handle yaw + float x_x = 1.0 * cos(p.odom_yaw) - 0.0 * sin(p.odom_yaw); + float x_y = 1.0 * sin(p.odom_yaw) + 0.0 * cos(p.odom_yaw); + float x_z = 0.0; + + float y_x = 0.0 * cos(p.odom_yaw) - 1.0 * sin(p.odom_yaw); + float y_y = 0.0 * sin(p.odom_yaw) + 1.0 * cos(p.odom_yaw); + float y_z = 0.0; + + float z_x = 0.0; + float z_y = 0.0; + float z_z = 1.0; + + // todo call begin and end less + + // Draw axes + glBegin(GL_LINES); + // Red line to the right (x) + glColor4f(1, 0, 0, alpha); + glVertex3f(p.x + 0, p.y + 0, p.z + 0); + glVertex3f(p.x + x_x * line_length, p.y + x_y * line_length, p.z + x_z * line_length); + + // Green line to the top (y) + glColor4f(0, 1, 0, alpha); + glVertex3f(p.x + 0, p.y + 0, p.z + 0); + glVertex3f(p.x + y_x * line_length, p.y + y_y * line_length, p.z + y_z * line_length); + + // Blue line up (z) + glColor4f(0, 0, 1, alpha); + glVertex3f(p.x + 0, p.y + 0, p.z + 0); + glVertex3f(p.x + z_x * line_length, p.y + z_y * line_length, p.z + z_z * line_length); + glEnd(); + } + virtual void Render() { const double line_length = line_length_->GetValue(); glLineWidth(line_width_->GetValue()); glEnable(GL_BLEND); - //glEnable(GL_POINT_SMOOTH); + glEnable(GL_POINT_SMOOTH); float alpha = alpha_->GetValue(); auto color = color_->GetValue(); bool draw_points = draw_style_->GetValue() == "Points"; - if (draw_line_->GetValue()) + + // first draw history according to the history mode (so it is on bottom) + std::string style = history_style_->GetValue(); + bool is_line = style == "Line"; + bool is_point = style == "Points"; + if (is_line) glBegin(GL_LINE_STRIP); + for (size_t i = 0; i < messages_.size(); i++) { - glBegin(GL_LINE_STRIP); + auto p = messages_[i]; + if (!is_line && i == 0) + { + continue; + } + // start with just rendering axes + // + // todo handle rotation - for (auto p : messages_) + if (GetCanvas()->wgs84_mode()) + { + GetCanvas()->local_xy_.FromLatLon(p.latitude, p.longitude, p.x, p.y); + p.z = p.altitude; + p.odom_yaw = p.yaw; + } + + if (is_line) { - if (GetCanvas()->wgs84_mode_) - { - GetCanvas()->local_xy_.FromLatLon(p.latitude, p.longitude, p.x, p.y); - p.z = 0.0; - p.odom_yaw = p.yaw; - } glColor4f(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, alpha); glVertex3f(p.x, p.y, p.z); } - - glEnd(); + else if (is_point) + { + glPointSize(point_size_->GetValue()); + glBegin(GL_POINTS); + glColor4f(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, alpha); + glVertex3f(p.x, p.y, p.z); + glEnd(); + } + else + { + draw_frame(alpha, line_length, p); + } } + if (is_line) glEnd(); - for (auto p : messages_) + // finally draw the latest message on top + if (messages_.size()) { + auto p = messages_.back(); // start with just rendering axes // // todo handle rotation - - if (GetCanvas()->wgs84_mode_) + // todo dont do this hack + if (GetCanvas()->wgs84_mode()) { GetCanvas()->local_xy_.FromLatLon(p.latitude, p.longitude, p.x, p.y); - p.z = 0.0; + p.z = p.altitude; p.odom_yaw = p.yaw; } - // first handle yaw - float x_x = 1.0 * cos(p.odom_yaw) - 0.0 * sin(p.odom_yaw); - float x_y = 1.0 * sin(p.odom_yaw) + 0.0 * cos(p.odom_yaw); - float x_z = 0.0; - - float y_x = 0.0 * cos(p.odom_yaw) - 1.0 * sin(p.odom_yaw); - float y_y = 0.0 * sin(p.odom_yaw) + 1.0 * cos(p.odom_yaw); - float y_z = 0.0; - - float z_x = 0.0; - float z_y = 0.0; - float z_z = 1.0; - - // todo handle pitch and roll later - if (draw_points) { glPointSize(point_size_->GetValue()); @@ -281,28 +346,11 @@ class PosePlugin : public pubviz::Plugin } else { - // todo call begin and end less - - // Draw axes - glBegin(GL_LINES); - // Red line to the right (x) - glColor4f(1, 0, 0, alpha); - glVertex3f(p.x + 0, p.y + 0, p.z + 0); - glVertex3f(p.x + x_x * line_length, p.y + x_y * line_length, p.z + x_z * line_length); - - // Green line to the top (y) - glColor4f(0, 1, 0, alpha); - glVertex3f(p.x + 0, p.y + 0, p.z + 0); - glVertex3f(p.x + y_x * line_length, p.y + y_y * line_length, p.z + y_z * line_length); - - // Blue line up (z) - glColor4f(0, 0, 1, alpha); - glVertex3f(p.x + 0, p.y + 0, p.z + 0); - glVertex3f(p.x + z_x * line_length, p.y + z_y * line_length, p.z + z_z * line_length); - glEnd(); + draw_frame(alpha, line_length, p); } } - //glDisable(GL_POINT_SMOOTH); + + glDisable(GL_POINT_SMOOTH); glDisable(GL_BLEND); } @@ -333,7 +381,9 @@ class PosePlugin : public pubviz::Plugin sample_distance_ = AddFloatProperty(tree, "Sample Distance", 1.0, 0.0, 100, 1, "Minimum distance before dropping another history pose."); sample_distance_->onChange = std::bind(&PosePlugin::OnSampleDistanceChange, this, std::placeholders::_1); - draw_line_ = AddBooleanProperty(tree, "Show History Line", false, "If true, draw a line between historical poses."); + history_style_ = AddEnumProperty(tree, "History Mode", "None", { "None", "Frames", "Line", "Points" }, "Draw style for history."); + + use_transforms_.reset(AddBooleanProperty(tree, "Use Transform", true, "If true, uses this pose for the transform between odom and WGS84.")); OnDrawStyleChange("Frames"); Subscribe(topic_->GetValue()); diff --git a/properties.h b/properties.h index 1da1c37..7327e07 100644 --- a/properties.h +++ b/properties.h @@ -3,6 +3,7 @@ #define PUBVIZ_PROPERTIES_H #include +#include #include #include #include @@ -88,6 +89,54 @@ class BooleanProperty: public PropertyBase std::function onChange; }; +class ButtonProperty: public PropertyBase +{ + Gwen::Controls::Property::Button* property_; + + void OnChange(Gwen::Controls::Base* prop) + { + if (onChange) + { + onChange(); + } + } + +public: + + ButtonProperty(Gwen::Controls::Properties* tree, const std::string& name, const std::string& description = "") + { + property_ = new Gwen::Controls::Property::Button(tree); + auto item = tree->Add("", property_, name); + item->onChange.Add(this, &ButtonProperty::OnChange); + if (description.length()) + { + item->SetToolTip(description); + } + } + + virtual std::string Serialize() + { + return ""; + } + + virtual void Deserialize(const std::string& str) + { + + } + + void Hide() + { + property_->GetParent()->Hide(); + } + + void Show() + { + property_->GetParent()->Show(); + } + + std::function onChange; +}; + class NumberProperty: public PropertyBase { Gwen::Controls::Property::Numeric* property_; diff --git a/pubviz_2d.png b/pubviz_2d.png new file mode 100644 index 0000000000000000000000000000000000000000..4c3fdb4d3e156b260164e3d298134836fbff2627 GIT binary patch literal 199786 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

urG zLJBy27`3xqF9eDK)C;Azu7N?N^K>IDK-3W6ML?hWcrF{z^OA=;zP{HmIl+1QMa{;e z1gby={R$FDprT-?qW#%}{AFW>Ub`zGV~x+GyywY`T>`%dd?XM67%?6u%wm{5%oBUD zvA0nU@keUk>o`%){A^%*`+9G`L)?cBS=^~@)Y$;7#j-~G6bsv5U5QQ|R zbr9{FZjT@C{Os|QupK1cS(MVKj<`zQaWunfVU6>1@Xu6Gi>RzC`zs?64KAcJ>(n|e zZn$}l61SGGq+E`&Z}IL#nr2eEbEH{(yO8)hiuew!#P9K?He4-_rh5r7X%KzS3kUVO zd(STCg}u(YlDq_)a~xXHvXWxk6X|aQO3{s7>80 zQ43anIP;C$FKTr$PpF_#zKr7g)8XWYarwanVgZrz1nA3{Fke)?WFGjt4CYN@$l4gQ z&Hv&mgLofIVp<~T-4}ko!_4%?^MV+}4mfN;w)fs`qY8b#84aE!7cO3Wx-nsV1SH&F z-Q8eO+516>^iwC;AzxkX18*TMfsqAz_z-sLv|-7==V1Ma>a6d>eoOo_e0`M|+KEqx zJN8-B@~F${DWLbxbxJOTN`5FjOu&2F@96a``a)@|qK2*KWYDL$(5t;ZGof1< z-`|A<3D!J{&N)3X+Awo`$}W~2m_lZMofwH!R-~5l%Z_fBkoz)HPo}H?iM!k9l9GBe z!YSRkHBZ!@JG#QOCcxd4;3+?WcbzGK9I5xia&@jwc3^tje6^@I*q&f}7Jrng1QfX{o&X4;CMq z|J5-!-sRu>qOs*_KFcz7o8-s4K&M|x{Uqxg?{`K??Izl9t8a`tjD~UH2HJ?!H)nH6 zs=x&iyQO*VJl?-+In;RsFnkDrOTU1&42>-f9=rdZ%#0-gkxkEEyZ|5MI)K3exx?V1 zKw5>4GkA@FCcngwGzb#ZG0bL;v;URZtU&X+kuYI@>yN(vlS%qrk@T99;q1`cDjYt| zyG0w$vh?5l#WsZ3WC<6Tw_Nce6K{JN-j4X|Qt)PTclmc^U!>>GJsZ)*`;NJ>U-&N9 zlJkt`h3mVLAX7noCU5i2g%D@Szk-tl)&?&v=AUsG-26Q`X;M0I?)K-?r$IaXYnD{H zvt_h*dM^%=CTl>45?t(6%FRdDewpQVJ}3qa1@c z0R?`uC9HY{Xu9AE24Is#GC-O31L2Av0%EG3EMYzY^80>RB+aJ|`zkXbQz?x}6jh~` z{*lesJ2i`nW;V-zdTT!%D9-w5o$GY!Tpc#F*3YgP)D%CvAbL*)x8lK9N>v(v3#2I( zL64u@L{6NDkaZm7!n5CHj)|F!6*=PtKdB!kO}s8%E0`O0I4#aLh@I2BX2GUuI!;U#HpAxz9Z= ziMwqn-yMf|K??11lyW6$)Rer`FG+BQOg96;L-0EDEIfGI`}%J_oyD}BkUvh-o8MdD zO9FaX!g}y3|Ko82J~$Xi9YX8o-l)fz*2C!ggBJ(T^I@!i(yWeG?L*U+=hSs7CN6Fe zUVVMQz9X!Mh7FJ(LM~5!Ql;*Y0>CgJ=2%u4Gw##8b(J`zc#eVRi>U_G*pWS2_gSLF zPe-e`6)XL@8>g$dVoI&SQ`wx2w{6xNgs%NxoSk)4mF?H(?{nx*=|&n!=@cnJLP1jL zk_M&g5E4pChZ54QfQZx)=>|bS5Dul3lyuH@{JrnYtXXU3k72odaH)^yzV55`-rxQC z-VMZr2%(Q9@_W_5g+W*q}!6lZqkJ9MsX!B9vM**6XZXk{qLP7wC4gxrC*?$dma(4f=jSLi} z<}F774CD$&jr*Q&#}UhnQ-G%ruZ@wbs)>Hc^IYsSlfh)twC6^aXFWTiK~p~pQLSG? zUe_@tk<u%JVq~>3QHIt@r|{@WqIJ@5Z$Evlf0Yn&@ecGWefTh*r>(ns zB?^Gi;J&H833}!-KsiG<4ZVGw_OU@oO2{{QFA9=Rc)xC`2fcZpRs{Nl8UK>Syg}(Q z_P0BXzhz4Di7PSrxO(LzV(P4&>w0C64XrD@lroRCMUsw4H)KfvG~?=+`Fr&->9xtw zVZj9T!k(S5GE|9yABu1B>Zr{*;>Fzu1+Pj}XS*fW-tY=cd?JAo#q{4-?5aS>;x!k0 zI%<27wt8oG_ShuGkj$3XWp``f5QtT_CZDc&qx_JHmhJe^Nx+Aphy-rBT5_7Ke6gM~ z^kG||f;3mJsxu9*LrX7kDdb-u(zyBWw=xKDU~qPz`#I2rWzcS`_HGQYM~W`m&bJ3l z&{ycp|0I)(d?!FfpLmoU9i+KEkcq#) z_Y?B4abnU%D>@UZ8zNoZlIcs@Zt7HzWvFZT35y&v8aR|5qBpBlTR>B z{nAOAeB5sEfX*lAJ2%-!jRw&x$7wd~)elZO#T2!Nw7n%5PV`ohqOv3JhdywKqZ&gmg{xLb=o((jAIN>v6e}|4S>9PiGBF+=dn_Er{Dlw=zn~NB?vL&hQxXOB zyVSnR3air3kXLX1a^GcW!5PTHGxA8ey*}pfWADM=G`nB&>Fmc!-cl#RkRn!X=5jHj zIJdZ^%8eiZu8xnivl7!(H`!1fjwEPq;qVb*!Wa}UbQ$M|EJz&PR*#>iXNQNt#cv?C zVEn3~X`QH_$W&F@uv0p&ON#3JBk0$%cK9&yod}Blb9BXRMGVMgBlJLBpfKL=-_b~X zPxbbtV3mu)y}wVFEm)`KKP=n(D^Wy*$bMyE!!8QSl$FsQ6lF52xHU^kez+m?CX>vy z4^Q%IY`q)>|EeiNl)z5}t`Q>+!fBYt`FUp!Nu_J8Q*DuUdrRpbjzGtPKw}$| zqXW&E)L!fN+8R*ra($^Kg2yg0P`Wa*>-b!Iz3YQ|cfZ_bU&v%u^p2XFCy5xp#uQ=_ zT&&JM{h3hoGT_NqVeCN3uivDL%VU@4EKT$XqL!9d2gawqoj(#eFSdR7@DZPO!siRZ z-JS6t#((5bOZI=r^A(rlZ5ePyT0FEe4Z#oOCHZ}r(L|@Cu_36?^h8fgfwQ7rMMwk6 z!TzSMJxC+jKKx@Pwy#Dv2M3DY>8QQ3J9fbd=F?QEYm<^H-Ve?-P#>>~RZh7c8(Il9u`5c}aK~ z?&-B>XGOUAXJ^E#sXyQN|^Dr}+0(czpjT9TvyOVo3Ji zU|yT)P&JmBdUcVbO?4>o^-`k1GjHb`GtdP8IiP=vbM>-iTT@^;Z2)v%GC)^ZtKDym%F`-*q=(aTQBSHq9cl#m*N{=9JhBE4oH}IgGXHSLxB?g>2NGURUZ*|o8 z@lA_QzQ!h`kjid-cJ1XW{rouf=MSUK)8_1%y9`whJ|ifN8O0jp`O=a`tO9-j})-wkh@tXAiH5$#DK z=T@Y%^V{#>w+VLKOe`^#Y_I>c;SIG=NMHAp_q9CZUg?M&aiC!&p%KTOqZ|yCm+H$F_r2 zzFkdhA0l%|r4>y%DwG^lmFneAn^L#hU&`$|51yV|_+aF6D9nct<%&g?VOccfIqkkK z5AT(sU3NSV!k9gG%*wx;{LsF{`$a&!WoRYL2QxnG9oJU_zh`cW4?~8g-?7kir{f71 zy$Ec+P^rDgnI*Q?Rr|Jl>HR^1jMVw_LGm{g~xjQehOT(*dl-1ds)z zk<`f@aL-53DKcW6{XY3IGTq#C$?>m)9qf=aK!mPWtgG7*i2C0I-Q%d_&`MU0aAaFu z_Rp4fsg-I+#8=Tw9Cnu1&wlGazqWOe_!3?^%qeD(Eavh(;O8j$OqCP3X?xr zyZv~FC_XzUkZr<7q%2VT;wl6ZzUsoS!8c7B_Zlhg3jEdH;THVnaR}wf%t5{U$r}rT z+h^hiAxW`W@g7LCM{mxN!T67Pj@@5)Ybwnz1WAkGQqZ(B>)~AxuknV&VnFA3Cyy_m z=rbXq`JtvA+5g%Td-6#~mFa*fNE|3C7{v-x#n8w-VHspug*e+C!Jp}n__Xz$jY58X znuB}A>xwaehM}1Vey3v6JW4X>>#!GQvQ@DZ!uLv%?GA8@5J1! zKG^)iuN}Qn`3vcV}Im}4MLBcP{zKp$%xJydAf75?^kp2+|?Zyt>oinYS z^)G`73H_T2IKgiP44ul`9f@JkXAH<6evX($h?P4gzEVCE!>iE|5FXUbAt7MsW|lfr{LK8tb>$Jf^htaCVPbScHO;T z@87=_gLODXVB$M(zJ?jn#xq;B zg7?SD(CyBDb~VgJ5fEnm@2YX(>OLvZjv4^sUegB0RS?NW--LRs-iL+3sXE+~o3MX_ zjuI&cKJ;Smptwk|T`MuVq2wnf*q5PV5cN|vsK~s+!T(aaUg4$PfP63d{~Y4D9pe8bHV0bE z!b8wW3;qk-h;l=&PQgB31I&!U-5+>2gM<-)7apcq44(p}`3^|j0g+9U6TKz&|0yrO z^20$N7=DDm?Y=>ER8%IlMOa}+`mWDyg<1_1FAw4m3)pqct%Pb^*k&{L|HyYxi-?O& z(uc&nKbB;sf9;gD>3^m=p^fynPV?gT;#9dm-P(5uBU9ph<>=b~l5GD%XiV(9O^a_@ z4<#}1WP$LA>oUu2)Ae=JHfW9zzt9@ayKyliE4o+0l~0b?NjD5WqMCm6iNF`{MDO#t z;5DBB<^I(+1{90s-#gr99eRwU7CpLa`NMp~Jz;lmPanfMGyE${%NNPR8euuw>ea17 zsw2I)e|MiST>SKZdUQa$^aA2>2n@qJDPj4g4A17$7+R)4*d=D#iKuP}sR$Z*x=0Dw#yphERc`KNL5w zFe#=#zIUeXI*k4F826mkUDYATl_H(P7E)4PdCYS6aZis8w_g3|AY_CW6Wbfk1-({3`p`fXXolg8|0cAo|B-Z z5-@*3_0@9G!JuQ!v!tb6{Dj0(Hl*jac#v!LoBpjwv1^zUHfh4Uc#EHU$dom^dUP4k z%a9C?7PW(XC4s;vMH4_CIRQePYtV%I91Js{P=hZZJ}RxQc6D`?2O=+^bS01J1YlT@ zf|~_-J0KxWO;6X90clMTvR{L?Y9Q~t2Ar2HG56bxSZMwrKw1N;Gg(3puo|15n7I9P z{ATjM=3Wq=4d*JffBfhTwCZ(sL%g?!=$^!ax4rvkd-uP!04$F=6>o60-_R4p{@#>c z)oi`}GHd%8jg6ry@+hX)|G6t;+n=xXHi|TXYo|&xlh1h-epBQTP0PnuBZK4mX=@CM zUzjw=nq^t%)I6;WifYd=v6l`h+oQ+i`K;a?Pj^IKIE^Y9rLd@y8czjdkMT+2NoUZY zkYat%d(?)r8Vhhp>AkdtZv=N8Mob{tsmUe0od!M)8(Mu>I4j_M+B zo$1j=O(%VZ#b>a*TS}BpK1^q}oA-lJ2E#o|1AGfX4i2O_#3dwZOd2*oX36D8Jz6*i zNIC55Hh_f_aD90Ue%&V(0+0^!=lrMC3`4_xgfI{KB&EaAEZ?O)Ns`5Qm~uUPDu4m8Hwa4W|7E@3O3#<_*KYNJP^<-x90- z`hr8o$;48NuX5R$(SBLm>iL@otH!8f>yFD4PIoFvg5aV|f#**#ws4LHHg=5sV53B9 z`3(b-O<~Ghku-M)kFacDYHC@>&X73t7vXp2byPQD1z-36;%5i9fEZ%yBp5RO=`q3J zQn@c+7_l-XfI|c1)6ZlUPU9a+0(~{uPC>5*K&yZPCK%{-kRaHcD5F3W6cm8M9FQLq zDT0y*sCVG7(8ZxKE%UVZ)_@UXDEI>)xvI$wP&@!H4)ECi2kMtn%^}ypL(-siJv8Oj z$J1^gT)*5&LGMfl>hdmx>PtgTKH}%TSx1wH!i`fFwQZ=ks-clhH>-(B79>gQSC%tY zC5zxnK*W-6k-~e(3q9kSiBzb2U>kQ{YO?3TK2d}5@YH;+nPq9F0^xSA zN{}|=@ytpVol|)< zT8~p7lWF^B6%$xc3t_pnb#)VDR&mJr{x$8ekx6K~WlAWfSW*xF7^4FPyutdP8?1xW zCqby@Ni%@4;3LcQNJORd2YKrcq%E-< z1b+KNHk`LdZkg3+zlK#*7!zUsnY~fyCwbv2g@54S*KBZM|4r_b_wB6;176WCsB}2S z;q?(s;Un!@n|bq?2rSWuAbw9h*E)7x!Q~8yf0_KFYrR0wO(Tx!RZ(P7IVIHX@M|;G zFHIEkc?H}N@i)ILz#wm_=|?<7G#}1pA33F)Ljb%{L`@94*7~5LcS$~c`ld++$%o|F ze%_0jixq60)*nc7X~7x|{o28o1L#0Ds=A#mRW1-5r%rDj8*2Ph2gf|25h zZ$wGC=POHo?-eOijPlanr%ZtVGF8w(-&T8da#p*ZV?KQ^kMbXWGW95si}M95Ulq)i z_Lu)l^S^YpB?9Y57NSz~b`CB&Ti&Y56%7%?e(?h{cf}+!yXJ0w;5vJGp@3@MAG^#9 z6?``Rw#bbt{+_@!4>L{yii-v^kWS5gY-DRy(mc5@)IP3`kv11{Dr1pO(EK>nWCx}$ zSh4fX6*Z(u3thlInI{Fukmgn4m*|kJ4^~Uacw}Z8dAZrvD3K~Bf(s1zylgcd=8ym| zNEQ^7&;#zJmHGLLVBVwEuf$BUxTu!D!_R)+?7&7R$ZKj0V17t;Mv z+3!t6I8}3qa6_YY!eWoF=kWZ9r0AP6goF@M-6w>?H=-_z@C`!L;l;Jwn+Eb`1|;dQ z{A&{d3h|#Ll^A(^5MSb1Hoc8(vq;rd)~dlDt8RtW&wHc)eG6lh9fVb?fodiIa>EWl zIv)tDcffY>$neP{b911i9szAGuOS9_ObKv_VKnCKW#DhYp4UvmA`|w60diH+Y_*0s4w9-;M{Zsh7JHoaSR0LfNtIf znuq|657eH`!KH8PxFlt5`u#GHW0(c}X#l?`cKdcE;LL%=3b51A_Zsuu%*-<7O|evFKTNfS}l-31cuoa#5bHJhgWqB*jp@t=wg@YrS ze3NEk#N2u_%ckcdT;Psd(;@0R>nj5|MW{q9;{gW`G)I0>JP3DO34!H{5@Fz`1hp}b zODx?3)Ix-z(ron{JM=ijTKBicrM;b3F_B()8*AOQd`U|gAW{+#L$74Z zXWb`;MzX{-pS2FGW=Xic{U8g}Vj!U4tGht=BLciWXcZX(Nk!>58sUnX5Ln3|ZWi-N zv>9denR^eK1@`wnc~<=ZmgetJTRX1ve2Wx-qIX7e^xBz--;{wyF79enlYSYbH_KwJ#aX3TPjv^#)6*Xke($DMnOUp z3RuA#riXi*KCV#=6DMYA;Sq`F4~2EnCIpW2{Jju1+Da+7Y!G(eTTfSacl0g^Fy)nG zAWpB?V;%z~+4vvb<%ea4W@do>pTKumil${Qsz*nc`aQI}KEy(h1;H&se5Z-U!iQ{T z!@l0L{cE9QB5R}imSJeTe{@DztZcs9NyhZ*`{-3zwCEOo)7{82+I?*oEhmY*K$Rwf zQ4R3t z5}eu3B!?DtUFFZgD-XDS*}){%xCV6;NF+|!+ny;zblzDttHk<#HtXE2WnIg#YoJdk8vsp2dGd^QC zsh71#a_LA`gCUoHc}M@KDA8PfjJ7o{GeCsQimy8{wj z8<6M#hZjBtg@uhpQZh0zcAkNldf5m&sCyTXNucYnC^*!A) z;#3vHu5=}BXtit1YAy4ni@c)xG%5ZzE2c;h3#2PrY|diZ6NUY?52S@HT0v18JU7l zEGyLRC@W*8@Y1#!TnP*RVP^_{YUt6}_xO}DdihuP=T~;)?)|R1EAGL(xydvFS$dHi zF#614$zqz?UkClcX6$Mc1=U!Lbc7#W=mHI6Ud7cXZ}^35-qv1`g^+uXb8seLPxhvT z=W3kKlqM^Ob6c7zNtYTG-#BOZV6Zs7=uO*L6Vz?I#Y~{@F|%OFgNTY9t_i}^#bKd7 zwuhDMW_&PUJi`(qc=wBk@#uKRkkEO2V@JEUBFx}1^+irEGd(@En9N@&+VU?Hp&SB3 zwN4~Np&ci(7_kv(JE-xu(_9#j@;H=V{<?>&z`1r~aV(S}+^U&ZIns z1+PR`)*O*i^$(^u$MYX4sq*3L^Oe8$nO2^EWH~kc?whVo<)3##0byQ?nlDo$L)0*} zcxzHxyid$rpTiWNx(9HaZSEVowPCdf;U%>}4j*h6((v|2 z5sOBOqq#dpH8_@m*SE(ehI?paCS2lqlOE8{N$ka%Er;LNpcKE0ujp^xrhU}19Le3+ zwkQfStyWI$GW|ibg^6H5IU5D&xMvF>7jMQ7m)`p_(xvwxi{L^f;A`gS@1T3rgtDR1 zBh{m~beGyBH0QRyXq79-&V{N`SsIZ2x-$|v4YEFSo0v0?3E>EmMK8UHmP`uB4A`FY zTqdp-Yrk zE^_lgTfr2rST&!(sh>s0$aMratDxRicot7CvDZoo=^?q^FOZ^vVt z$|FI0m}clK1W9P*Q-+ukDDrVh=5b3B2D(~1G>L4JoyEZs?`B7Xh2l@AunOAyj|3Zz z_#y(ucf-caAFeYz)=<$q-+{OnBuGvP6WFX?ZpS{-GR{ZjxqBt_g#miCooX9?8&{vo{qjh23B1%*4Rs>z6qibfa|N7p3MWv!&Ww=Z;!ndgIPS zYF-wJGGRnAE|p!?PkmCe8aZcDIxqGOGgnoI6DLt$h$LkVYST)my449|zM2#ac^R{8 ziY117A<8+xyxBV5{>#g@fF8%}#)o&jVFCDcX$4o}vP3AS1A&e&-8CY;ujSUTAsTw7 z8AgFFyE#nA6Hi%c<(Z`Dt=k90io+yvCveC_a}ge_OC2r0(4I$oc?(-rad_;9vdt*- z1xe1=>!(y=XPW2-OyMPj^his-WumifsjKdiG>~@A)aIeD?AR=LznN-V$#w>z1|@4< zMmgeL&T^kDynzariK5}|ip&PheST?1Jt490uPB;=3hQ(^%JEM$sVV}h8!iN1a4tsX z#^(=8u%d+n|H#CYaD4-Y?e@>0PmD;nN1KKY zCHq!yjB%*wc*X-J9+);^LcF1(-w=w$H6dvWNKHu5X^zBC0imb#){!}|y%@Fty+Cs2 z0qIf0x@vb2k3dM$lGj4P^N64f;k|V9G2q;N2Gvdht(1>jjalnsf%FfF$;sA-d0B!S z(AINlQBlzswO2Lj>)IMKqoWpw++Zydb)Gv(yj9@D&z~2bH$UFM)i8oRl8GSHO3G4q z2}>V%%Q}n6{$cbbBU{>EjTsg7d1P3*;#c?gRspXT+qmm?yD727eFIx*c749wJ?HMG zsl8Dcn)n(SaMe|fB!eE#7r5?92ioR{x$J6H5I~!VqJ9CBD542J?AnR+b<^tx=}!dg z$)r=~O6@O2k0DErPpg4Yl`w^(!yGkI3<_g!bA0h*%=~IuLW|aqAcKSS5{u<(L2FmX z_LfSzdh@;YfX^qf=*9WKF_QrbK3z>uU{-9{U|ZY=$NF>+K}=FSD@;{Z@^OR8TS& zDtFXy5e`kPZ+Q{a!q#r4qG+n5=nDqYp(&dD_n}4FK8~~;c7BxTtO9x;0MzKG4to;00 zdPv-$s<9It>H*VEVEXh9ger@srz;d>Nn-kcFN=STB&07lUb&%^A64h8cS6pM> z8}eNW#RuB~j$!c1Z^QiZZR&H!@V&!?4uM+fo3b<~xQa$) zmh>4UWDUW89Vb1>y2~q!&6!<(v++O^7z!xjn5KS>Q0=|g$;Q9871<90vMHgokLgev z6C+lsQu~zhRxK&?uAQ=^JF4mYI5gEW96|)V`_pop=Po*GU=!)RARk4yY5&f71{aj^ z+Bg7$H~?q)pp`8SX#@5R_&u~zdTneOBvV8$*K7(v2QV-|dk!?%ObPbDLe91E{8zS{ z_%u4SKr6EW#rv(KhZX1>05U}L;NUh6AbTnJbx$KMEbN26MXq0ukjRc3OISg@$pM+J6UvXdX_M1Hw_xahfpx> zGYRj}b|wv3$;f(?(7O2}83V!Z7M|5^ehuEqlgNbBB6>tTlJTrHC~g)$08fS~w&423 zcsuQ}LA}5Ao%AQ)rk)0M$%Uj@EqN|{mT>LRfRGQJReoBSkNTic-D^Ab(UWg!kBg!) zhl%(#w~lHqipu-o&TmFf9D6;SUHI&R>EE6-n-}Qx_VkTpBagrRn^tigt=%=R)7STW zp_a>|Sd;4FG11g=J^_BBT!;H12q)r*#;|V6JTC}4DoyQ6OdCkW_PJH zaqD|w0yv~9Dp&}R7ghkQ(X`l5Fl8sIlEgLe6i-5yR;k*UQ|+kL@7?cR)wtN{EcVG@ z$&T&W-^{}e@u6YJxF3aUTR=U-7pPEG|Ir}2J695qLjFL>S6>0PFui6MBSrd5=vjP< zm^Fri6AW_l@;0tE#Q3p;bAM`q#>HN1!@|8MfG+(UR;0*NUGepmm=W*IP752H9T_5{ z;>q8*z3q3e-i(>QR7O2EKkylFT~%`qRZLa9Av7Ye@~utJPQ1g=W)VxKh;w z0+SohF@=<#-ZZ|*L=O_beK5AWi_0I7yoJQGTrH#$veYcv7-GT?Cn_`dMo zkr8v?*}#$hc*(QrJ~IZ#Ht0|nNaqt`eg?Rgz}pYB_5<7qhD+P&FZv;I5T<>!Y4vyJ z5d{q?6U-@K#6;fThbM+^p^C2zdkd+;TtyxgTc^fmjT;o{(lZ2}@O+&Z>rTO8m>7I> z^z7wYYl2b@vd@8wE*ge29>xb7C=Pp1aQJuZ#4jX2Wb^!CJYH)peb{ek9v|ZNfGN6N zoa8xvJGMNoy18M^XSSDM_d3K<7K)wlK#-d0EV}c-%*b68d8dUxuVD_AnM* zG?My}L&G@Us#5&hFIsRvahr%1sLBWp{xO|fI;hDh!bF@Ckp+Adm%kQKvyd27FiF?C zRQUXFZav9hM*9mdt1$;*0^sYa0VbkWJex6S%WKyXA|fX$|wG?(I6FcR?o3{3lHtdJ`*=>pWZH8{K3_ocVwpXuZUc) zW8eKjvch25GQw%D9V74N1lY!duD#0g5zTsiF9X^D`x^zq*bKd2s&3#V2n#S{rEQ6y ze~fgwIvZ)nf@0y~5Ojnpn*X%AAjaKCC$sYg@7v1_;?8eU}BF6XhECz6&qUAp_bK+lEHzU%}~f zfjjBsxvn3>r;$c(L5qX`Tw!`HAa_MTF8~FjMysxu08;g9Wd$?@g1!y#y+I5P;2!fz zNT7K>v9mLJ0CfN;<*1_BKcH&rjHVud8r0KwGu?~sMjz%2^|(Ng$c9;{Z^f!qSj}Sj zQQ74iu6~hvGRZBc;=W>*9NL8!T6f?c$t}xSlXdye(zOUj^dwjLzWXzuhG0RZT$cSf z!=+|SomvoLRl2nu4z8cI0={2qQRKb9S&Cs-_swmMPt6sYF0>b3<47(nY*vvoUfjYa zJ{l^Jz9qR$uZu|uXGgRqHad_bb4x$^zB3hz)*|l?hAoI4c%(I{s#w*x7I-y^{Bw&?4iSt5fXi z#ka(es2q$_k((8AdM(my73?2UR#U%5>{E>YLLhs08~0cHm>K?!K-ql(m>k&K6U6{O z30$)tr4bMi0Hbk`F*Z&gxY2v*1$-HQ4e6y}5ZK`O%z5;LVG)2@NKpz%6wePyoL{lk z0+!#_))qkRC_7kBo=s#cgj@lof9fiLw}HFc*YYF~la@&p?nb9XrR6+j9DI3apZ7cG zd|lJCp2&3N_~x(58q6i1oIRK9UA|LT9lIBVicV%z8~=Sv*P9pc-&%kVRP|4ZA&rlJ zG~(jmbx~?FA;Rv>A%0Re?rk;PQIFw-d+qa(2MN@B3Iz@*3T#(ii9r^|qfc%m-~0i4 zp-62}GQ7tHWh3yA=8)o*T)%saQY^_Ce-de3Y7ukZ#n48m!n?g1ovEL=F(rEoif)%o zj}CL0(;@c-JW-tc=;>?o`Q|XF6=h;%Y}MrDq4J}c%FD_;BpCz@t&?g24qeR!{q%f- zf*}`sJ)nRLAmu`Uwo0I;1j-C{cMhg}PC2N{h{58f+%y+<6Z(RXfHJ7cn}j2D!nX;&G1*y9Ha7~3mt5M z0m)vFLy*LI9dd;kV$jzVO5?5;vUdDg0fwXp!Zi|>$^xVqQbEa3-t}}x2)z%medWi6 z^!$Y%ni$u_J=)acQBVj0h;RaGffj&}15r&C6EVo%s(Ipfrgih&xW$ztB71R{EF-%v zJB;|2{Y7lYGrweI(PAg}#E+jpK2VX;yF3m)!5Y(qM|$`q$#44O@^FZY zVIyuF-iedXPAJ*=@@+Lk9zzm-G0`Y*BX4Pb&?vh?>Y1{uB_u}bnTHz@+~x96fZ_q? zS*vP83(mgr1yQY^vdjvzs3Sbsv07qO<)Q}6K zGsJ+Hg7BZg|Gv4R@oeLrF$`y571BTa5gvvmdCE1pt5ncF1-)>HRpzr4=lJr8dF2Ti zu?l7QcO^*j#X_Xp*%fYW_qEmM@59@ube+<)#&Y?b$lJ*}LI0jXlMsF7AbVgnp?6)J zcTgeM`2^cI`SO{!UYZ8IC3JLsw|Vc*kE7>u~6V%J;wpDi^99UQ{jB_JeluMoA!T%Zd!K zPw#u5VS?Mq9piRoJKd;YnU}SVCHvU4B@HE_lF*!No2(jo&1jKeASpXH5B*!sc#5Vr z811C(I%MQgUmo=TY(iC6X@?Ez*CYTY?m z!X)4cW;^b0r`nZC2g^{2jP7ImRr}%Bx))vm;^s_Hk&daBCptdpIdQF=-M7Iv^UY~Sy z!}~wgh1Uif5-5e==*%a#i!jLX7N#&Il;r2b5V+T``McCL${r8m5gS2mcK5E>10+_!+qLCP2V@=llWiY@pAtwJMSK3FSbT)4*={?K9Ax0(PUX(r2+COtJT*LLWOiC&?vv%TcMFcIne##R~%HccQD zFp-O}ix@KpQ@z?A@lYMtmROyjNF++ItFLG1mfTp%#glA(1#!s}W!2d^CK8o7dqydB z=DDh*(Yl5u;+tHgp;xB5y@uMyt5ej_r+h1Bi*v$Q$tBC}2Fu9){D3Yq%t zMO^a;*9VBxx6@y*bI8I`tJx6h*J?SPL@KM;dezN$&MxXq%A> z4Q|RN1mv#R}AXJ$S0gJvA1bG$y6*x7psJq9RbwtoML+oz^4)!~$UhEasi;e|UAcVk}h6ztD z_^J2rNL*zGjo`ez;4?kD+ulEI-wj|BfPc8vH1K`s747vLoov75N6!?E63vN zw)s!J_NnL>F>c725vk4#^mD$esfK_lOi+O{u1rZyz2LhX2l};Y{aHXRnt#n8RQ&ap zm2^q{-5YDaSc_Dgv~oKozBAp%h$t@l`x#3lEL*Zjb>wX1qgLBlB5ruYn?pJrZ@d^7 zd$&;SUiS|o(OCUp?eMS>xL>Gk%*KiIjIV&W#S(W5Rm*2SR9Hryi5|`;_}{~Rkx*us z9t4>pWV}>AX*dop2M|Fh&)((>*7}ZGapjovoo*E`*jiSi-8BsI71pp9&*4X)AB5XA z2O}d)_P+qL1O5G#OzP}4Q_VnG1=yf1EiG$RF28^~h*`bE7@)vaG2w!vz{x5zg;f2E z&()j~s1T$r@s6UH-7jzdMf{;!e`&2QjKwpQehYT@UXggqkK$LPb7H>R{>eBM%{TnY z*=b0^yD!92o_~HarTF-dxfvEuaKR66%g1srlc1FZeQHY~clp|H$hJQarq%)9HPaML z^dQUih5GWbLa?1fI`WxdwPwe^j~@Ln9%g~>xzrg043joCB->5iMuSpqwOQ*K00M$g zMv$L>3p8y6gh{31moMb6&(rg%Sba6F)ecCAL zlaKdJZhYq+m%z0jDHw|3g3aF461VEJz=)L_KMK5HD{1RaLO9u^8`+)4DJwywWxz2> zgF627Ee>@^yq6nV*<4L$P2{E6joB%m>3PXciG7({>a0QVOpR80 zF65Kx)@-CotdX)cKaFIk;Gbg1OUGf5XBHx?j~y+M55bu?qMOY~@(Wp@EYB=2fgu8! zmrSmeTOb3=LP010H{GnR3|O{TC;2}vUr}?QuavC1lr2@H&`RBd9(5by&{yyQ^6PQu zXCH8*(>&f{y9J}Sx`IwH4&MP=VHWhef`?6At6>ur{R?=3*t+J-C&AKax&^p(1F&uj zh^+Vwt7XAM19@ms3L5eZbVXo1fWaS7UtA+GNLGITzFrj!L0e>ln8Xj@LBY?f1poxP z^b$yp#$qyiwCfW!%unVG4X z#!m~nTLD=;fl)@>x|^`%o3V+>55UU>InW%?;)jM=gC16Zd4}28+t&b^3UK8Ed8yQr zw9LLn8c^$*BhQm{Uadlk5Ogbfd>h30_{Y5RkL*X%4UcZxcZVm`2Y-KBo)eHW6;C$D z_&@#rz8hgpPKj;sp*nTIl?Akb_q7&jeEFSsZ%(CrD&a1~p@4qGEVZBPLwimCpD#!sMg}WY zm`CEoh+X6wG%{kMND4?W7?4zdTDwfi5xyfKI%jvPkKLM8en&6fy{S>8rgEB&BpAyg z()gl_-v6VWBY=TH;!>?GP%He)_yEb@Hz)Rp($Z3Q={K~rwEbC?mHZI+W@csv;0kuY zdIbXUbMRdQSg|cFk7p>kncpNOdCb_Rudb{Jv4O&u*4rF7Sq_Z<=-wKRCbvi5D}kua zZs!}_+JVkTB*x~`D6Ro-A-j+LdU>yJ@ODfkqkbnVRp zhnnsoVK$Htd<6dWIq?D4HSG;}7lcSwY` z@4v(e(Vq}&9l=I#K5Rs^1|*0r^};!?sVB#v?OgE5=K~PwBtCo#HrbJotG^&j2U^Ce zPTd!zAo>Rz&?PFIBt;A)cNX_l@Eaur3gQG5q1 zeYl`veB|RA-mCjId_^XF0dS}d9|RPt#`}1Pp6k2l183s7Fh+)wF?rM0_o~^NkjqVg ztsTr&Soq_Ou{PVd6H6-!vNxqE9#l%8xHj)S>oSloi0(H6y$zuM9-weukfJjh;N_wb z24P`gKmrXqZQ_{ZOmKw(+#8&*piI{Ydhb^~f4YAq3f&*$`AP$_NHY&kZYDn{6J=?A z|HsLNP9PcaEuQCT=bjh&aej7TMz!in_nk~%Z10Hy>@?SW+MvceDh_;ogfNI0#bn`m zaMZ!R$Fah~+LpRTT#rdUc(B^io+5ILI|xC*Q;}%PY3{=cX@BU}5ZyAPoWHGgQpz!D~Ks5^jigj)6cK)Mpp{bpttJxWF@a;JOJ6>?UQDcr!hKBTaG}tL)dq}=LVIhW z!Ok*TZuryQX;$p)WBd+;)-vK`8V`e~?<4VBok~wzUw(3Hofn&ue<}0O&#_Q|&^cX= z#liE~l)ZuSnrC%YiQ#oWW&4t8i~+=wtF^QnegB(|Mb5^m9=10vSt}kFgw8h>aK?h` zng}r518%8pV4ycbZ<7I0!$p^1uqFBu79I9pQAN7WQrddy>G$HBjy+Q``9{UB58oQ3 z=1yA2{dwwv*(xH3UFnm3@Gw*?0e*>56aY&3JsP3lv)uf4>i`&VQkH$ zH7i?z-3||~dPL!?B8`>77EbqriJqK6jrsk#Hg7D zwCYgc=8GP(0$-r4VUl+K#B)i?@f93r-&@YNL1R!&Q-fZKc6vN$ws6b_hznp9(ET%a zySiNZolhmzt^Eu zVGzb;4aTA{$H93)D`uNqRZU!O%1%m<=~t9(~c} z#Sda>->bR*argG72{&fT)nwQ^Jn;@S#_M5y3GnmZA78w>+^M

3dCkJg9HBef9hpeDY*Es2cc5pI!$X&YO?) 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 IUSse70wN1C-~a#s literal 0 HcmV?d00001 diff --git a/pubviz_3d.png b/pubviz_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..f7692242f8327092b35c0813c1c1e713cb6d7c9f GIT binary patch literal 400849 zcmZU5bzD?k*Y*eqg3=b>cetPL z{XMVWH-8K><39WBz0cZfU29#}HsrIs1SSR%1_%Vgl#&!x0)ZYsKDB#>1pL9)iOK{1 zAUl4PQhE058FW=)1^D{fNle2@+1AtvZ0KMDGPAL@Heq%&axgKmaWuDeI!1020)fau zQlcU%t|bUjzr`aoGQT`5t|uh@yKLy0KwwYisK!CpQ#=Puq)tw?3ilyMBtQ zKMZQ3!#yyB8!PaU&ZLAvb#Uv@yE#$nc;71A$Oqr1V0ho~1rv*{ab?y^ksqC>fzy{u zSytrPipTi67LBV<8mg>A6WZG*(iqn^~#5Jn+M z?H^+*+Rj{NG7m{)%1TNbX2U5B_YZx65p9>Q;ipbHBK7l7U7^;d5ysVM;W!%yzEZcZ z3me7)Cr%4nc_ZPaQcV(e$?5vd@3~Ozd*H6KMe9;g^%D*C5QT{3=Jy+FQT4_++!{D@fy)z;I-^-O!#Z7wY6^g%rLcsN!<-U zs`~zuHs0V?3@@}g{BqcdD_NG-v38e;IEAdOI6tHE+NsEIjF(V$n@(6+BPHIFD^Z?T z;Pm-Zv^|zs7gK}3Zn`LjW@6D4|JsGcZ{gI&(zH$2v0}qPJ%`~PMdR{!{w}=ngG=t$ z7mUK5UVFFt7m`O)Uu0>r4I$iBi0gSYhU1M_{P>ERiXFCOt==O(Lf~AE=Ua8y`fYs; z1_^8PS{>oxvLj(cbRt8rsQ_(Bue$y z$VRoo2$>x|H}YH0R}Vk$X??}u%NVNgRH6?%{ige*K;fcwcY5olQLIc@ODkbJ+K5qQ zZ}&VdsGB$To-AU+7Ed6z)P3A zh279l@D)u?ce7Hg{f|9=I&&n;26^kNxjk6j^lMWn-QtWrObG|l=89c5e{;^~(N?Jj zL)-a}piNdHz0Ar<7KNcOn;HT0z0nG_kX0k74|np9T}oPPlPeE`I*$tJ}_(65!&JRF*T@h!q*6F@lYk-OAmahv*WsrqW+vqPH22 zFItebb?wKi$ER@YBvtu5IIR3abByzvFuQx1p7GgVKDo_MY%wRgKkdFV#$(%7i*w^h zBE)<&6`R?6^V>JDzz*4)xiw3azg98zlg@6F`B)b0MZNjh7m6e<>q39#VarXTcDxWD z*WaxT1Nk#1tooxm+CyBxjiCrA-jd}^q`o;Zu{+h(!aGD8u`t3n*aE_Gpxf#T<|*IW zKI5Q8iE%qVdm26!%O0R~xZd|*Sy=K1zUkqwXXdAZSuKu=(%Nu2f%is7CdIw;M#5X3CH!feXLI5n5zSV+0 zIL6Kw#Uo3?mS6wrsWS;2FFS!eYdR z{>@hIY^%Tg(PHgt6{5VuL^?-$eV>rXkc-GMj@7)dfGSHB;niR_6L|7#DJQ@!x$SzT z-8O8F{99Co$k=I~LoME4%jcBZ6ZWbCG210J<1nSDF+Ni{#>K1-ax{%OU5Hw6lyI>1 zzA)(%q@1{^v@k%NwNMb&S z&IdM9BV4Vnt7$2e+_l5qR(CR6*YnD2RTwCxQqKAir8^g60w=DdS*L}vGd(~ujVSs?n zN6(`D?`89~F`Tb1VA{1zys_4Xv+~A(gvxLFvbAUM6qR+u2Qo%dJZ;mHZD%+q`Ddxw zYgjG6cT;oEOsT}blK6cA!wzHmvosFABQ?W1iu<#Hp4cUe>c6RH8uN9ixX$DE1<`fT zZ87R3H#brB(9*ZJGbGe4WR}0uc{5AOFl8i7u)FXlhG>lBzOq5_-eUCTPs|^bonlwJ z@ok!6Y)Y#dsHBkN;9@rHE7p!V{4DQwsv6MH)goC1)&V8RVs$-SS*j*1eR_C9YX?-UGBlr0quqdJ# ze|a0?vNwEOkRb0k%j}eKbaTpy4or?0DPY|(c&b4^L*z;R8hgs*7jZQm2z1jG&I);8(Wo4CY|Jct_i0AeVTyXbjhOk%WAP@Na|6)fKD8YN&} zAVoIw1QWfCp1Bro75Pi=VKoX(jrA?C7yXNTLYoYORcP?h@RNQrs23hw(o*EagV$q? zVHMW<7+`Cvtl;Vw%PZwxjD*qT@2AvC5>D3&77kYjTJE|iv5Onn`;&_Nc~~iG%2Z1G zq4j>j7Sdsn*4k!pE9b8jK9M_Wn9u&2X6n~@0_!*5%zX0XlK-5y#&LYClZFtq!+s>d zHl~laNObB{NQ2KMM^dJKuqL#;0Y|*xcRuD`E?n zaZYwP%V5rLMq_mLKAjbwO}Db|2Q2<+LW=y^hEVVB_pcOY0d_=+QAF)p5nudAiuV8kr~18l35-=Y+>$P_zZc68k zo8$f#Wq(h*+~l~L7oU#*{oL(VdcQ0N>UP%OYsS*5tR>ScG|P&c=Ugi>*bAEbKVV^Zy`D4Z9V6{06}It(heL zRQV<_F6OEq8?-xo=_`v{O#R4iy#f`>>ux#uK7wPsJHEaAe;aQ)R!iJ#Ii|<=PEgnn zklQ#WcTx-NPT8kB+M@$-eBs@0hKLS(C^68Xb2n`$;>DS5mtF+28)e?~Qh6Bj)~{FC z<6jPsg&i!G>)y<99!JkOT9nbaJ$2_9@|X*|s%}9_2;RWRX^~0}k=#67?^NetVq^Zg z(hqn7jkuR#5j*?j|IpqRy?2S3uDyi{n}?xP!J7z=B6d0Kc3Kp6YKDSlm=8T5siMa0 z|5W>8SSO_{YmS#P^719}#P$j zgUUI?!CJ_FHwKaX#2-6KZ#&w12U=kWfxh@F16>Sg{T@v1n{`&5G#KX;vS*v;{fKcxlHg-Bc_(sd% zBJi(^;N_vt3G?@4Suw2-03;AQ_zoa(@6FEX8%Vz2jbk;FH zf0kR#Rifk5(8Wr(+HVi1PEAeG)6+8v{M8X?WF?6{qpPdyR#&D#g($pt6B4hkuCDDo zJT!FwaC=P1s^_^g`Zk_q@muDnpd{H`uUptDvmdz?wAT7!XUw!}j$OcBg;Bk<+4Ypd zl8ndB;Bdai^Si#!eN9$YR<{3NCit2_#KgqNXoOv74V`ZDLHPRmzRKQ%)*YX&_l4vGYh78%PD$x6 zDByl!ZedX+|QIiHVw@KabYgF1zTx|9kH7G5Ary)VJwkXcf|U z?6Wps`FFGjauS6%1AXKu6_|LP0Ir?@L+lpW&T6AS3KGxSb`OJsj}~6z;QUNUv3i}> zlK=7J$4LukMMXtDJw0h@X(c5kHMKbTJbv%HYf|vS*cjX2TctWKB^X7-d<4gjT#^c} zLC2;h3e$2=V);v|xDb#;~K`^(9IMzu;ck!PhCVi`C&orjV*MX8>3!VaNk zLrGKUi7Ejf*_?JpFZXBSCc&py0sJ!eTFx!|W#r^{)=Es1gO-&Va4GI3NKmzE;V!DNF711~ZkvT7iaLH=-o? znvfErAe%M`X3iu3Z#iX>6W!qNOYC_6Kfi?X|2o+>ALT`teGp#iL4TVm=#ZK=%PieX zEpNivnaUuZ{FyE(l2b8Y@1(g~q|4hp+ zq!U++019U2Ltt6Y&(8MtG<<`f%>jAw$n}nWOHOHt{3wT>=)ZHcV;mY9vTeCkGcvh2dEL|*F z!Y=6f4i?+vs6T8Q5w!P@i||)KixCf3Z6&R1h8i}SJ6`LQL^3M`(u z(OiFCZU9%ZZ}p#Q6C{zn)sMBIGWYF&=A@206l^ z`=zhLJM}Ww>k_jKIJ&Us%^ZmLPHXz&W>*&LyLFp{WpYecqSOIoK6j_OfCFhj;$dYy zKJ^)9;$|FCBTA9l)x3W{FWWFTH+EWnH&+x{;(}W$h%q;B9^3!26m!&+YWl0>{*$M) z5o zb@}0zUj+T`^NLYl-uLU^m$)vcJrUww;Bp?*KYqJo(f@$tOI@_Q-H-O@FI;N@ze~$r zGtz}{T{evyZeT5j)^iw~AH52(r4NQVdyaHCutMIJ?HbsA;OCaIx~vW@b*4P8?SWa^ z4pf_xBtzk-9%4vqRaIans6=zEi5t#o^7lnkud77>KQAM+Y`}KeQ#5%u!FM_- zjXF!5K~vroF0)HRV^a?6{@{AA>y&l)S*V=NREMni`l^20YrgyA2fd}k;Mc&#e4*zAjW()~=fG#s zO2Lo$-1({ikpgZFn@R4;>2y{MY1_qa-)WT0qiZ2KtHw!4U%`>7@`o@_AL9Y6?qn8J%+eqzIeTu8}QvsJs=T-;ez9{uLt##`hIww-SJv`$ojX#@5&_ zx85E#vC`1we!||!N2<@gNYQsyX@lm%nyf84SJ)bRZcje(24K00%L%0P`Bft50tKbZ3RxQ^% zRb~`@dK|6%`0Q*#Z0uB-e%m7myQt98K%V9PEfHDmU7YH=F4xv_wJ@NoiHx|TgMJy` z$Eb|U`;qed>^XVXeC1j+C9h!LvXrQJ%hBXfaql0Qw;_W5YfAFRbF-Fff?l_O)6_-xG@5rezKVc$QY)MtJ9oQ zgz~p20XY$^s^94U0V3?eAb>AXF^S#-_^58#yQ#i@7EZC^=jT^hSy^G!R~f|ba&Q8J z9WA%D`Ri&`p_YrTk>c4*a-L(-__vZUu2^P1hICw$|A$<>D#7`emMeONg%`mPI z@7wGk3>56d;eA|8Gt;X0W2cx9N5WyYy=udP*T6R9!y?%Q zvD|iv>0AT2krO$RWefcE2 zwY1Rb_76wfa9h1)_?$U;R%i<5W!`yFdwwQBdF zktkKX@7WF~k1(6sl7}Q9`d3woWta-P+MebkX=FmX-RF;cEsm3m>j=ne?ygTA8t&q> zZ8U2vV$W~IB_zspn_%tVkVOIfTko_xzO!TA*TjX?w|>C}&!wV5Q}D)H@+O@|Ge%KVvQ<-s6_R z6KVE{u#SmizeXs;YY(GR#yfR;#qSx7(Pf0b944ozO4a$y+47dmF9tD5mCZs#k=A+6 zk<~Z8Qib!7h56#A#Xdu!4MT3wSO9|(wIxw=T;yR_9Xdly_aY9XB&c4?geFb<d7n1Q4{}`aBtIFKmI}X zzHsK6AEK}Y?hOI9tM3Gt)$HiMsVInoNXYYguF7mAm49YU??-z2^8M9voAE$&V`F2$ zbHXL(8Qsjx%n0yTLyR3GZ6E&Fs@PyB%o-a1w}-hQxxj z-QeHF%Y#^FiHQuiZwsGbMBoHpT-Jo= zm<3C!D=Rjd>9*x9&4~6sN22#aRw#R@?HdhY@^0(a!_7X%K@lNcSf8CijL)dur)8|ih|;eI@Z)S9=(wJJ5+h{tlTW*z_asJ>{iNW#$0=Q z;1YmQLQ(w^NKslRK=+ZHeLBuE(n`78>>t)tjud{PlO0)218kGBRm>tG6GZL18Pz>l z*;Ok-zp|W1ggitc!)5|}_OLFss>k6_7jD3X8zt)A@G>v+Oli8$_RI`%edIa)OitDe zGei_m*lrR|=`nJ!_+`|xX!up)5Ah{oDxq*rq-;D%9HKumEq6#EbivD(moUz~YElnr z;DL|S?WUtj0v)3t7%_K^{ybW|ea7N{^J-{L81X=wo^g@^NWM0am5775Sj zo+iXA@fBXXeIjLaP&h3`!N*;E5}Mcn(vnmAP2OxhT4lPjH=jx>=5%S)HLRnGnr+-q zyUx*E;s`cgS?jHm;<35jEUS8di|_}EV7~Gb52_xgQ!J0hvBQFty{7r8;1q_1-ZTy~ zl=&@16+QbTTlx%^HneCl`L!r4Y*3sMm-AQrA631jxA8KRAC)=&U^s;2w_cFos;2NL zDgKfW4cwy1E^Vl2{0V}X+xFO8`dML;&>)G zG$8P;|F<>!Zc+_F&fZT+in9%h5Itt7DJ={Jb zrJB0;X-Ag{}(x8Wdg{bN_iHW2{YfQFV{5ymDA*^({va%-MvcG-%*4f#)qoZRjkLk)pOA_P(M@7+r|7PrM ztu^J+eLza8Z4Km9Y4rwzd({|uEMsu~!`jn6i3%#^!Zp;$a8iNZeCwstU1%P-R3`oX z6nyas$m%1U)fd`X@~?=%PFo;b9519kx+BASN#NGG%y%VW5Ela&^o)+SLtL=zbPjI3 zZ7;eXdDI_S_2^=}5GuEY^g{x9oT#~sGG0ff`_epMUux6W{Bv$$@X81SDM}Pia7&?* z(daBtw3M7;RXTSxTGWNwa<;PvC+hSz6fb1(X6;$yR_O6k+zqPRB@vCHNAl&6)oX)} zjF|qiv|v%UP5B)1pDGMH&fTpX3{eb0@^5n%!zNnjIG0xGy&|mj2<8}Lf{ii6>`02H zYwqu7WyIj&s+%!-w~`Do_=*KR4r8K|I@-<+it3+40UibG1u0;x^U@5le>Ryn411bp zp>@s8o?U^M*n$_M(bO_P6^WFL%+^*v*BPxg>*P!=zlA}b^!X2|ac<6(fw@1mLEU*$ zn`g>R+*FY%lb`k6S-?dx$gj3-1X~;z%W0S63MQ2TlxWleBWFHF1-2*vZUq!>Eu$WB z8E8Ix&DdMn8D6h$DsAlWZD(x^*{bQ!cG7ropv>crh`yDiivF%xSM}>%(Wdh|5&6sA zY&{V}2802{S-2GY*W^J|K}ec~C4&YTqI-!dN;JG)uJEjqWc2q8Zd7Jzk~7EqNxZ0q zymR(|#KT@(a}eXuj^7r{S{7nC2Tn+FsKr5Lw2SMEz-oXJBnaZImy9gL5c zT4?2xs)3kBsP8#uF>F?3q#J{2%>t1dD^H6r!>+Q40%t^RyQbZ|Ub6F*{ zwIMRTepJ&8Fqwu)Q@r(a=?HndkmM5k-U97GNED#QnZ- z8ApV?K-PuEL)q>l5$=HM9zO!?)<>^SB>FNg>9j9V7&l61(|P?9Yw`sjaP>G;oko2g zsQR|MCEUHvNG%rPUpZ!f+$SJ>90D@#o!oG;76x^Xr=ql2jfgUSArCNgfm=fGN)OSL z&R4kxUDt$oe#*v^SX4WKVq3)vDd(myws_wn^v0%CA*y;_4;MU5+F&7%Y}o=VseM~s z@2QZk5d6~8A93C@6Wd$}2OFq#qBNtlCR6nI0FD4lxJ*XR0? zt$f?p4{n=q;T}^;e_9Gj>}>a@l$mBN9)PA^p9u3GtC{sM<`m%|i%Flqka{*fNApfOGvwQ`mXwUv$aLQVdFaXW0229sgQ+MCi8I z-z(8Y?#WR9OAJ;7c~()~_or2EhqogEITwcs>me0Rmn(P4G#>yfs{y@^{j zKzDUUlQnSc1yOQ}x(^h;AZB_-75iuSaFOJn^glP2eq9r`O~O;g?=6xEh?W^YDQ$I? zg@oyH9QkMx;B=Cq(p;j;?ira|{Bm={SG>+(vufg_WAa|p|I$YsK5yF4JLB-raew#H zh^K*heypYE(~$3^S$%Ro7^Lh{6v{tUl1_)eto|{cTnh2>XsH?P=!s&O8n9)-1AwZe zr_tMGHm5(1cNuzL{U^Wr&$=MA$*xHA2nK0Fq$zO%THh^Oap6ZXc$KqXic{eIW{;)=2~p4#?N&e{wZnENb;a z6r~E;96&koo4vzo>D_w6=&#n@x+TkT3x#71Vjt_T-&JVT-EV6X7B4Wc2t_Y(9awFX zZ>5YKfMs#{zBHZqF;UCN)=js=3IInTlI0pX37o(6mP+o0@LgN zL<^MGnQkol=@miS^rn0kYB~lqVT4xEMU!~j)ANtHZ0Tkv#){e@#7PpMwUM&$#08y) zvXax_v4S8wBcSeEPh2#Dgm9{LHwjtp&I+c)U9?$mI(($3l3;<QfsY^V@6=n_(_~!QZ)zM;;st52Px#dnH8}qi%^FD;7Jcu;*zw}JK z5L|-#h1VK$7DV6qCE=ON`+|?0D1eKbOFM8De8@*;VWH*b!?SIYxyl^Hew zvIPmqPK|Z1sP5e?M6Pd7ec6hF`f!&!+693UVK4iY6YrChxH#A! z#CH?p!wdJnJa)3)+PPFd49X|A>Y8bW-N7oBNGm`@j2r|{n(?pT(^_`>N|bL zllF;>JHk>&YsO(0YpJ@H<0Zapd6w4Fe@mvRFEshgg*|)7fc6Xc0MWGa_2+%S{!g^Q z{_xn}|00-w$EEXeehTeMG9)Gk11REoJB7sV_o4HST}t zbRLdj-#pMMR_dq2e;92%>#viv;@FN4PY&A(taA#MSW_E6FAm=Y>YReQMuO!ZopFU}RDw@KJ zN>3;A(9qNzAi@an;{?d!;@+~dGBZp-Ha~4{Wkp3%qc!w~iFn=)h!%STlUN5`jER_CyVTg&^2^q;RFUwKcP4^ToJK@#$8wEgya%b=v3S&ufz1 zWsf%R3$48UwtFyFMG57uRx4Wk8SA_?xEmUZ5i3nViqBy>I17~6DADZ!^JDp)8@5TaK{_;ACW z3juPWX1j9$oJnl?W_|JwK{B_kt4G20dc6TKk6 zc%j1R*2iqnb#FJ1l9H12px&V;wDt9C?gcx4r2@~}^kXNr=9LO2pN#gJpZABJEDE)n zSi!6+U_(J2_eHY&kQno4DJfWNmFdywu`+=^TO{!hLZ( zQkN{dMao~R&(y?Yu+n~g?OLl?HnV-O=&{-f_w{WT^12Zf7vp{A0k1T9o0+K~eE;G( zB?BKHCFS}#98q_%ou2OT;Fdj>P~&}HzS?zl2w`qhd4r3~=6P+`@Ug;jdl;VG#`u02L5STs4F4f$gMStmANvw>z z8f`7*U8K35 z9VtW+rgF5M?lVj@B5?kq<~QXTP!gkpH77L}7p#vu3?C04py=OF+}L#Z1qR-X zafgp_agQWl?dl)-kP8Yfn*M`{c_|V3N&vp09A^mRv)VMW34pZ&3LkH8Z%xg8g%rAj z#U_Q1UpjN;lI7Ew+>LLty&oRjTbBCz`bK6(%-@@ulpH6I%>d6qFCVx7D268g0@N^Z zjrLu=&k2VWd@k5TaD?uSZ2+-~gS51mTaVefkk{^}`n8z}$PWD%0;!%?J=Tf8jmnNV z?W52mj|uuGE`vI3vRFQ^>Y&|H+s!7{R*@mL_^saB3_}~FD)Y{6O_xXL0I<sdly zFY=1Ep4X*nWzBE4GI^KYa>K6RVD(5Qt?GWb*JJb)Pzs{*ol|*tH<5*8pTo}qw}yAu+QD=@R2#`CscxQgG+3%C3G=|V&ucE`okCX-X5*=_DzDKIcG?~RWZfQSO@5a1}*ugS@a zG(k9;mq(_>`z6s|DV}aPA)=L5yGj&%V3-x4nu3%y|9O!58J)xsER=-&fgfONN8wt7 zkuFzm&4*L?kHFuzZ(UQ$o+e>cQz|WflXvpw#(f%R`*TS!qc7<}C!>8ybd5lag{q#F zln(VBAZx4W{Y9_buQr@;+!+Z`NE|t_B7h~^whp`jWIQtrc&Apg>E1W=mgP+@0^Z)Q z1Tu$BjE&2C0YOkn+8RMGljOgAGpOFChULlNwr4Fb<$E*EOgUhz3%q3KW(fFjQ?sta zDiBLQIXS)e_=l9#h&_=-m%&VX4S#J81~}Egz`(P!v-0xtC&*}Tcpa!{&C2xhguzEl zh&NgP+zv84;N{3NP*YUxo&|MYUw>zm2ziB)nbn-)6Ehaw@_Bu|C4`QPCC>T^1~Vj6 z^$-;WVg%wiJMo@_V`5?g&<3SyhCKzP1f4A($)u2XANTElFVfqQ*XEw@SaF^B5Bhjq zHV+G3q*?o=cq18K9VW)-7#I{3KEiDhxeByd^+mqtcxr;8C!QBjOdu}00`Yo*q1bUwW`{Ej=8BSTn1qsLN~kAw17Kp;i% z;;hm0rCOooJ0h!yEgqHDKn#VmLY2aJeK!-t!~IjZTQZl;3rtL}i;6zYAvRDoS!EmO zs0$8H6hy}e_}4nI%d9sqQJYHv-Q%F8EC9AN{No2h!4>N0D;Xa@==74aU_D&U=ns6s z{UR@*Uga8SRYIEq2$xxbHASJn{Ll)KR=}D6%W8M%t0T^av9LwpY$1k8q7iZPaJcy2W(GF z)FFU^iz_0yn`{;d8M#Kw+R?EpKAsSFYH||LAl29Nz!Ga}YvY`Yii%;K0CibW zQ6aDkIbrC>J7d{cohMgUk>TOcMia{~U!pf*KroRI75)A_P>)xdR2Tynexv2Xuh&w1sAWwhp5ybCdZzIcrL zCok6MGu+amOK^Mfs|B3@6k%QKGU@B<7a5jBr((TY*jzs^{=GSG9A^|dk+p_WJ_SfJ z&ew`yOO7Lg#T^q_o@*v(RZ4_}gxV2qfCzJXrKmGDHdgb{(zeFP`xmzG-A_*WG=Tvk zi3pO4y@fmlvgz_9RxN>RKyjr>$;cSS=?**iI@L#d)(XfckM?jtrIy-tHqIwZ-XELz z`^t{LA)~!w(Q&=G_(}*=ZQiZ|QiXkhnttB*-KJx4NuD$sM3Y4imQCc?UVpmm&GB`- zB-7B4CZ-@i-~2F%v-v14BrFUY3u~#-1kx=PgCa89Xd>f2l6JSQpH#1Q-NA!ER}u&4y{1qK73{o3`Z5mqZIU6f?*g4=epg0N<#>uLSzy1&1_WnmHc zV77vr|8{^jeNAG{W0P)f&g1U>9)LO_k|k<0Q&RxSYq=D2aBy(3T7J0T7|B;*2>6)! z6EdZak@O@Z_45Oinq*@HM6$C{7uwRr`z(8c=GWu%@IC7Ml3NE!e>KNYb!UU8|C(D! zD2)^7r`TmR_0U9+bYT+j_=~OPS}db_WnjIrn&(KUts!kcNB5oQ)$#HO5wPU%EX&ul zDAvGlIEgSV%asgH_pAg!-mxq?iS3c#TJX`Db5sMb<5oGUzGOmP*6TE;ZC6lAeF7C5 zTNI~!DxV3*?_o9%m{q{X4l}Y}l2jTpSQ*&>?IeQp1`uw&^3ZztK7SjFb<{gB172!& z1GbBSscG(W>__#Y+xeE)X%8U_34Y^Kum?YHGH9y^!AH-|uotVYuia`j2jJWnsQv@S z7#J8tJm#YbY(~t&t^LN8Xk_lLr&$5FuuZ_f56}-7^+f=VZBA75{`Ly7EJ2ni+k0|y z()8d-hzlIr#UyfCA50`GoZ8#jNkDt!X}*+~J_vV(#V80`bNm44Btm_6c>E^B)cg7y zpgJBfuCTZF@i?W9+cdek*yZ2%A=|xlFHr*{kg>~`SCG*#wHm(kbReUpxt`JYWzNS$ zMMZ%(`jc(%DBr!yFDPJRqyO67A63#A2r|I0Y)ivHH;o)C(Qkq&n1zEM3x2+6D{j(4 zSHv=gr5Y7}f+TL6G$S{c`}An!YH?xUB;^IO%~nL}l4foc(J{D%{is(M3bKLKQ~K2mUbZ?oHZ zaiA9iBjiRQeTg94HIy~e~ghwzJ2Zkqio%)FB zz)Zm2$vp1tMR4}^_hY34v<`dHl^9~HOnnCD+1S|1T47hYximnY=i^a0rB~dw((&oK z7&6$RoVNte6Hb(+sXY}w9s$@)miY50C4e4#y&x|g7bP>Zb*XPg{ce?>hHEPpw~X`s zdsh#Sb2D1m1Rg-S+#t)MPDc{N5G&1$otl&cYtyU>k<3vNyz8fQZ)q(k7=S{P%OZgg z^}YBXCw$maekt=y@!@}g(h6VSxC}>S}puQccti@>`a-MuS3Y3jc&#PJrOQ|0?rPv?`tl26IZcvL#LNvo`z8C(ibDf%| z#mv0VRDXDJ^ur%OEC2lQc{2Y(Q=HJjd)gdrWQ`iI1CSl}+SfR^F1?yqw~RcTy{_5& zm-Z1$C&3c23b1hN@8hC%Cd+mpnfZkrQ;e=AP=QnVfV+!0Rh>89(=vt+h4 zm{`naxALKqGm&FCK0Tm5QdRX8D-qVSX9nSU>9vATGEF8GtDM~2UJD42J0Dq3=feDA(T8I0GhXHop&d%-~Ui)aclPl8f z5J0qsptMy!X+$&jY2v(t5D2Iyn}zqfcRfz#NL+xnN;M*`%tTvFt(Qo^v0%!A*(17y ziUooahVS7iBQ1?#c|sr6Q+#9|=2*A(zP3J7si6Clrpw9YWet(sg1NaldDu&yky-%b z#{+4CeFSZfrhF>d5rCo$!|9cCXL;NxDid680ewlu!qL3PeX1-&Y~?^Y+tc?S%pA_p zhU#{oNc@i$;EeVq`ic!oo8&4VSeMo}R(jJ1v5fXuIQnqqt023gCQzR-cQz@o+x$5A zg>)YOezVBxB)^C}54T*k=8LlWlz2hvRFSV!&buQ(S4K=iFx092znR5%U%+% zavFhC0@Zx1rs*O`Cy{ap0AG zK1+u_QtPjOy}+%b98$e)`Vz})w8m+5eJ@U+s8Jfx>G;f#{F&dJ)zP%Rh%*@-;?k81 zU-wPQ2C~A`mY>1nV0Rn@{OQt&=L)Ifw^`vXMQ&*WKwWR@<>*?cPTD8u&xWS4Th&Q2 zi6pt-4^52WlcS!u9sX#5dudll6ZkrnS5cuzg01;G1{oPylTuiCxiE4{teoK)O&Fwq z?*}ub;U?q@pj+pvtHa0W2X2?a-&o4%`y_){1U5rTPWpUQg^3D)-+ma|5n@)*-y&n6dVjVRSD7zf73W1R&u|6 z<~K#w-4%qLF6c4sAfu`I8ut)d7m4_46o^Gigoj7*rrd}kz~;l9iv_~hdTE9fza2RD zkdZ-7PaonFc;o<_%m9S(Ex;KF#Ah2<7Xt+k8hD4T8{tP7VTL15dPK_`ygJgMfv`ZC zM}6aHVt0s=hihlFf&`QNoYoML9Bc;kYJ`aS&5(tn9$FpKwY5ZRS&L}dwWr%r+%cq% zNvHlN=e6gU8tHVYE`-Ro6;5M$^2;u4pTcqN`_&Nl@*q(|LxY;cLYt4UrAEod9vDde|M+F89ZQo1B2S81E(2gXEkO5XH2(8(h)#G za0w9IpDJsWxByu?@V`V90Cl+^KV&5(>rZ=$TUuHUF*gIv(6Ee6O=}HVA6Rkh&;cs= zgREy0q=T6cG8}Qd;p`STb&A*dAH}p2o&74Sf<~o)iK}b<6ic&d{Bqj*Yq_Oztv4De zO*MQNxb(5o)8%zP%M)C`8lJk%$)KMHHPZ@XEPr|TPjT;Zl^M2X@jRmt$+DP0u_}^A zO4d@1C86cy)RZQs!+JP(C2AYLZP_2c8HblIU(OzUcmxJ!;mBxMvj-~~Ux4gWtXF>$}C+peELHnmCfc?nG$dqu&r|>A=p-(upbD^!T zq1b6^YC1VN0Vsz2Sv-sGe3hAkp579KwQV6yS{e+L`5uqQ04HLAB2iFapqje6?NT$Z zurLBZe=mK8s-TH%M!h{@gz&D7jSb+$LR_#D-y-+2XH0T3W6S^`w{%(dx(ZRKErLBA z@jufCj|QY`3Y0Tca@5!ir=z)C5S)Q zk^?UkHe{3>mGIJ0y8Iu)-a4wPJ!%`>bSN!KBP}IJOM`@@bf?lF(j@{4N=ZqVbb}z> zt+aqNA|ZmLAfYsOZqECS_q*f%arYR<<4|0C#V?-u#9YycT1D0HYyO`|6vIzol&D(5rm;k+x))VcExg$!El1H=YMnKx>K zd7Z4i&J}({hRc`Goqv0Coj3lu2Tv+Qi=Q4mzQ%9!FXR;S&5(&jNFEeZ5KI1rsX23`r784 z_kQ-l!XPgzdwg^>EjpuJqH}z5BECP!yR{Muqg+YJu)<6VLPI`2jYAJhLqw)UbMC6E zsX1+y)m4(v(fbj>ChWTYH4oAuT^2k;@5KzurzHMPKXI(&@*=bF|DK>E{wXtoXin|l z3&U9@7tb6`S|JiC=hlvQF6^e3mEsl1VAlsG({I2FBG0S8$m=II2 zB4&86lGC4Tl$2k`>Fx*1IQ5bIUCs6$MGk-gV!$XYaGvt-X$m%_| zXW>w1f1>>1Sy2i&tWA~EUdspf2(af!qOJ+Des=-VF)>;0uMWX-j4UOHIF0Hn8XJ88 zxWTP{{_i(wM!IUjz`#J$<;5vy?7mBbFCgmDr@X`iL|g6^!Z{zlj*N^HJj#FvZ{S#3 zSU3%|d)j?hVq)SD8~Di`NYCK!6Xv zPf0j5bzQgagmiAT#LVGQE;EuN( z{Rrn+JUKae_l~&a1v?uXx>QI=NX7limWN)dQzlqC{)5AXC1eqD@Ki=^ApZt&Jz$dz z{Z{81TMCyVFjOR`&YvPe^G<@P^Q{rGVOb-Ovj!-Mf+QF-8`_+R5C2zL2t+5s&@X6iFgn;MT2rP7Tkg14b{tNLHYnRaY?n;@OEl;!Mx?*guciJ#l&9MK37<(wH_yf z=e`)K1wLfmsk9J=oQzum^-&Wz!gnUz z^GAQ&K6ClV^)L3^^;RPGemAegwfAp-y?_}%K#?l=j5*tVbMj-b=E@{Np0S=$R$^d!O0)1*#A;^BeyqN0{Is=OA}0W|b5^zylDpgYd9DA4R%q53U^^ zCfem~d&{wW6$Ds zmw;ODBCFZ{A4UK^eS^RRW4%4*N4(<-fr63g$lu=7bEdz_bv9$lZ@h!)3=SaqG#o2D zlMG?+J&VagqyU)^$QUlH<&06We`L(+r_}%Fr$;0~Pu;Ga!RL;k;U5}i&hgyeewe+t zeqXs_O-C~{e^;kw%EDR2YA~sTVsq-!|L+%3(J;2Brv+8df*1*J(_OQm!%@0Tg#L=~ zI=xKHEp#av88bPfBqDTA!X9-kr(|^$bxDjESwgjFPAMItnHY59cei_0|3-_gpIivh z{@SinEpBYo{BHdH#pT_*ATYZf75E%MnLV~{Q0t%% z8=9J$nuZ3C>#FhzD#LU4ySHy==I7@(Hl|n|WfpUj>e%{Bfe%|wR@QxEyl;589Jb)B zte5jVK;%^Q5kdWcC&IzWdHCl~Xh=wA`NhX?MjoDbWo2Y!pc;DdLae2MgOzn@6DEti zy!_5g6$>3*$1WA{2Kli0f++jcg?X!1+pf63cJjy3$w?$R@0(fSbmZW&pDcy%dp1!V zzw~=zYD!mI`<|}tw^|H*v^jtN*DFCxRZqSdNNv7K%SVqm5-tf({~&EQTmKF@D-ei^ zYY^FWaB#4(Aw);n;6hA7&$dzfdp!K>f^m}Hs%US#Ux48X;Nh-uW3MiykW=PfR#jys z2pw@#SondR1AUAsuJ?<$5L58Yy1JSSf`Wn~BG2KpP*6}{Glqrs<;$1e-rfMn4_3mV zsIGOGaT$Iu23OSraq_QuN`SGH+LRz;ytK3gl-D8@jQ={XaY2Z;V`AbEnWXvk{yFZo zYf;o9lRwu$vxoTiEbJ9P$pY)x=I?K0lolQyURPI_m^cMsoScRR0(MLjX+&gXYdbra zr#o%`Hm4rtUpycXt9DxIM3xI;Vq&1`!wwB4(#*_^t*tFGQ|`j7j7Uf+mNQ{sg;OzyeR-Ar zNkxH1w$N9eYrk9(;mz5{wH$lAsl2qEDt!Kv3Gw?aAAcQjwHy%h|8BeVvpa)k0zuJW z*?LQ(njvni^-|tG`9+4$2CLyC6vS|p*k!5}VwsU4 zOSpjIva;>TvTp!5?AMa~hsFMZ$mj=we9Zz?Y6v;44yE$)@Bo^{x=vPMIdId@O;>jc zAQTMdRbZ!ETU!CNZB4wzqVZbnq4gJaS_}Xn+U9p&>-e3mE!uhcGsrz>djniBCZHBs zsCQ;CW#Qm(fQeaMoKt;l^h+O4NNC_P+vU>?3D`Yw%h2I{kTChVyq8+%X z7eLv4pPPFZ8>?HY_XkE5pMZcLTm(FDI1K}vYgB0Um%`Wc!(3H#Dk|rCS2J0Y$8@H@ zGfNU6Ib#H3NQN1Un{&w(0SH2UIV+eZ8#7#M@LJ3G;%jrvg&>^v1>b!BS0G-~t(9QO{F;wY`9CMPT4B^*H7z9A?Y zKzwLQZzd7e^?rz?KNZ731TY@G5f*5jM2o~NayW%x}_Xi5MI>d`9H#Mf?eWO^tg zKi98~a=6a|kmhyY(2^o#V`KAu@nWVaLW9@Y)6<$kK>wv_j7rGcw`ow+AkPQp8o;Zy zwKaG!W2V$&fL$g0FBqak>9M6@pk4m0YqQPebV6ia%yLoO_@+e=R>GTCHY6xxh5BkM ztIO;ijRXH5GB$qXbAWWYtW*r+AX`O`&`#T>I6uV3c2vS{56wxC-;BVcPqvq_hZ<8kP3U8N z{ZSXdaX=ft8-CGvJi+4#RxP-Ojm@oPP7X6|kFB(97WLHfOWOU~_pdY=&KCSBXhZzp zW@&0ie&s(T*zMhlVq=-LOUz@#CcdO1wbo;}`i}p8`5U4w7Lcj{8wE6OvD?%~`~nGS z84gqxus9s~(%tQLdWZjzqa#k7ym4(=+MKV1mC~@OouZWpc?my?pW4+?78%v7buP3I zb;=CXmtlz-U!?Zc?=;?+H_*|MBamJC6Y?^)M48^asC|H^LYQ9n3HgqRpQ11IEGI2P zN)*P>6cJuGTLs4efWQ3Duq-M>%+4CvRT#Cw&ZhDq{C-5Q=!E%G+4etI&3GbTis7^) z^vEwD$Ey0elMB(xLLtN1GGp?J*KnVnkLucEZnSS#LU2#Ouo^q=<3Ts%@}&`&w`j@6 zMZ!U@e3%=?RZh51Ldd_g`4Fc|h2nY){ebYVc!S9Vj7O`M#-ntpIGT3)UUtcZBiYPn zjni>@X1_r99Bq_A<<^YRMv=-wZt-SOk_gOpD@ik}_VcO83O6?!vlm;sA9#H_D)N%u zY}Yw_S&M6yQe4=Pel~>D^&_L^Y>tLfX@DgBU(!Wbiu?FfP1f=-%bj_q15p#si}Um4 zwDcJf`ybkyJNUE&{7;B7(2_hSR%)C^9gcAwT$6;q)WvTEasEOsmY-i?T$54JvrPDr z`1>me|0)Df;1*@cG$Dxy{=y*trA`cWjI}HKNrn7v1RBEO`nV}pzJhF6;$&{O!2Y<1 z8T<7|b(5;e%|f$jH$D|BOO~l~L?k@A>belXwi{VN4~&!yQ*#RY@;fDo$E04r3|bB6 z(e#S*m028Qn1^_Dt-=O7XXKmda8ZWFElq}2Bp%z}!fEH}?&%2^CgMy!?7L1&OKa!0 zIT=9#GF))sH(&+rWaQ;3(~;f=L_kYsB%;}2hDZAZMF6XS7{Sur?-yisP_92E=l8f@ zaO~rE!FaB@+<6X0;o_QOs{;miavM{Vc%nced8I}#yk*?$8LQ)@X>X(<%X zMvvsLk+^iK4fea*_mOfhPs^9HWOhbd>+^)8JIHWb9;VLS3;rkh^hezs^SrOrgqQ<4-C)ZVK|6}S!3F7;U ziuVuu{TW@7R#Tx6796j4UVby$5ZZsN+@<)=3B0nDWmi{g#&sK=k8o^cq{4PAA9mlw zxVVQCz(Rq%_zP02Vxpp@_XQWtV3Fd{ghhHlZ(d4<^eDi=@W>L6elPU7$B>1U3+r>sP&@h!Q`!!{6w(E*$~ZJ3H=m zUA_nTr$8^oU!BXt3TQnF9g~?^SO#>FZFrFA$!@%mh(V5Qdmru)?A#}Sn}(7I;EJsv zPxGw#kDQts;puwk^7{IHVDj{WlQq#oa0%BCLj$ld!laEJI%+28D@OTX{aFcu%7zU6yDWCii~zeJhxQ$}NGy%A^Mu z`t@xp)kECcu!93PyBoJ|X)bq%l8l20jY(&L>=qThtqmqw{`bCn3hH${xQ#`;SGLgG zLGZJnZ0PFf^y}u-Jpg1PXHP5*cnt|d_g8cB5zWx*35Xe}n8&)nwgYVNzxA;K5NNA^ z0!9TN79~W7{wt$^5`w?JcI_I#`>xJTOnj>8))&tWG|Q)U7TPX>!vLnn(a{l-axk!? zqM}%WfQCY1X&?jLoSj3%!W17pdN!KNp`H11W!(>seaI)!S|_RbMq)_Y}FA3Nc+x zt*cv$Fnj3jeaw>K3#Qwz;Mz#hpXllW=k9NKd{_iDzR(GXo}ONdR!aq?UN-zDl0QS; zg%N$%wAJ@VHx4u6*XpWCo1YjXV=g!`Mzdw1&O*byj*XB1p|n&Ko^SzhoWPfXmQN&I z`)t8)W4s84z7YI;YwHDk2>@gNzcbcgr~pEqf|QgWI$uG{4k&BN4QjwtnqlR7hm{r9 zCnXrvw1#g8UCvJqfvZ!ma7a+bK$!6_Uf6qL<0pR54itKWj<407yOWN|MK&7ebd>>- zJncOy_!F z0@vfc6(C}s&eg|Q)f|BZ$sY)hjSV~LUg*iXz&zzV;FQl7~ue&59P0o&7G1-C}&~4BE5C1r@I?!=Vdras7&|&{iEeJ zLtHy`1%9`=Srl+32u*%Mh%~CgHpKL;k?lKsr)G4+x|G5zC6QuZkeyBtUodHl^w2e# zl0BZUe`T^e*#4GC0hQysLi|{(q7MAL@eyY8m^{{I$pKL+y{|@Z;^f#F5c{~*TG%#4 zE$?>3?bARj7N|t$oIH<0Fv0yy$py?u#MmM z{7uzTQ}2810%r|33~cxhq@_9T6{es%X=%k36j-aO;=3OY_4SeSSoG#8CGPF-gG&xW zs&{CJ8u&e+Ky-8_a}{D``UJpc)wu8sHaQGhErwJ*6oMA$W~`vN+%;(?qoPvYDS-Ry4R{fz#`yR+hkoTxa3JT{xyi|W zhHn>!$_tLeZ$F82#}+pyCnv*nf!%^7$N}^x78Ywzc0j;{i{F9%Uj_y#`XaFDO5(36 z{5OXYq~`tEahq%zF@n6jn&S#r1;fFb`l$Q?(M=MD<0XqA4S{SM=Ii2zT)Z0_8!~92 zDf=4LZ*SgRVHry3`n*#1TJ-vt6wo@O{m35(Z)cg4O6L?*~a1O%M<0ns^7;qe${~s^FlPAVd z{23c(fH5DBQXoypS-N}*SOg>)P_1BYZVrpA#Kj+iW5T=0X_S|;w7sp88WbEXvD=Oo zL?}fF-wTHXQUQk!ZYr!_;1kQ4fIr=V!a(|=hsR%7YA!)5A(VzYC7N5Gut{}jwxV+AmkAxlDfL#1)s9+t zhk41q%w0Vd+@*6<*%ja`SomRh6@B#FF|qr(vJ%P`j;@~1vG<{Ui=ma1B%p|gEr)Rb zONTPTDg>2lzzad?j*;MOszdzPVBPTlyhPPVnACGq#C96epL=3smw<*%_h{qWA}b@}DwC_LBIb%`MYp{%2+& z|Hsj@F;P-()Bq(l4GGEqVjzLvB?xAIr`rpc7oOMf3Mvs)w6twNsI^_3u(PlPe^!o+ zjJykk0w*WvDahJ@E~s&09*CbicR~n%0Eq{r53%$I)3#Q}@4}Puss-V1ksnYSK{zt1 zwCEd_xP+#NK5HXc4X(d{bs(08fxQ3)decs;h=@p2ZLI(Y$5wgUMfNj(lO~U$iHUeC z1_2A0=Yg1bb}oDHV8+3Zb`0MG@DTRq!pi4|8`?S%Eo!WltgmiEnX7g$>BD3A2c_0< ziITW?oC5SX5-ZeiV_t3UWS#QTHyfhg1P5ydHjq~gHZ{kxKlhahWK6wfm{gPfMj0WR z+&+-){!#V17_E$oMYETzW4Ev2e7G*#Zsj|(QD39qkkQc$#Qb5>;KC$^!~t*ra?wgv zD7=-6KynZPu?*O#N?~-_m6dy-VgX-C!DI0drW$y7!Jp_4J0Vp0CjER{BU^oi9Edub zQF>8PQK0fNGtJrqP=W~Iw*aJ|$^?sB2H!w=U7aULXFwj=EZ%^v1)3vvslqeBrx8s` zNLXE3l2QVGN5p*t*<%v~9l$!p7hjib&infn0rXI;zjg$6O$2x%h{kiKWQB)cE1wO! z10Pn_EYSNvc-bVf1M$!G!zqwOZTUKjMtVx_JdnV=J z@ZPh$euj@F*CYyGq+c0f0#>^i<^EzvZN&I4T4F}v$Y1}#xu5mEXsx%PcjZuBT)Gkj zA%57VLmfh_k}qVTN)I$(`%-28Oaqm>?Y?5QxiA*FdKzc&-84clz%$wT9*oM5XMW7o zZ?}FxK%&mV!^p%$Bn@r_x|A%1bOdQkST{Z&zG_0OSHXO+y8nZb*Tvq!OWwt?=+6(p>l80owChm9TR`rUp!vz=h>9 zfzo7J@3hn(&kkKpiK(dOpw(7JMjOmW*n)_q&(6;78rAQ@^gwEzip>B;MPcay-~oME zVOB%usNap7cclR{$TzpNz_tpD_B6Vkot@S2`*Rqsn3$L;bwRLU0*C`odwYBPe^TDc z0xisaVBcV#n0LLwdA0lPSzEfWyBz?+dUpA=m zIR%i*Ei(4}Zk0hkQWTa_z{z^*>Pt{5!LvNo@Na2u2E`SM2}`3q(EZm!t5&-ah=kAY zFSKSP2>Z6EzrE)%lnoO=Gul92XNA0%dTavsuvtEO_>IRdJ(TfeM^lwL^v`se6p@?# z&Ow*wK=eD^__yo~I7;4#eOF!zjZ}ZkPdXhQQA|cpo?i_6U&K-X78Gz8C|Bysxv!oM zz5=qRS8&TLM77|FXMml%jfdeO#v)`FKrCsm0HcY9mNd34Fo}?n%5CBx1hPBtJg|)2qfIXJDJadI5sO%54_>usupgKu$)T+A72aF@XMb)trDNVimEP`f%bN z+i!sxog1`kD{LhlyPMr^-pE#Kdk#Ag-YvPWipGdSa{9K*ZfwHq$RY zLeU%)7bK4%P;dXTtSmA(;F(yZ|t;zDIGq54B`wD zwG^ND8NJbRvmw7_K2MsYEwF(y$Yq2n>;^W1QD*3}ohzrI@y<76_bMA6pn#5!ZeeNZ z4w

z4WT6d0osXGesCB&b|^qEX2}Qcl>Vq_hag2}n+McJ>N_y2oz0gEqyUJ?G;G z0uCD+WdF9d0^EV#J6$Lea9Aj~e5u<&ZD`zwKLis7Xno^j^Vo|+A|b3eKn;6&kBobM zX=y2AoC{U!)(ts3 zxpw^R)QcylCQXb^9gDkgI(K9qH<>Ej-v8%W+v?LgY16}<*0zIOr}Ksnib+VMT-Aw_ zXBbgwoEe`HHbw@#(O|-*KK8<4)j+NN`DKlgiBk7I3^sNh*|wA)itMNGPx%bi*!B42 z<>enQw)YV;8-41mLp~lpmM`@`X5l<)kht; zXo&tjgbf`YLtxSvS6S|WohSiGrTADN6}NG6a&mKHk|1@tE#_;kRj%7;Zs$^ILU_W_ zq%d#ZvjafE%^6&hd1S)CxlHhrm~{4Qu=ZLN>>|iXo^yF}_1 zSyd^!tm+*)^^tfPhZjmRF+{b;8KYA*WV?ET-q&+>uHE41AWHruB*R>1U1Tg9^}KLF zUVaSG=54jL2jw{TbG?Y(N93*EXt0p9-#ls)wYRDJ)Zlf2vl)7b4S@*|xvd}g6U2~B z+JU4d;M@HzEi%|y@!;SwF?{C^7wD7T2Cq5G+PB+wy;BdK0?miZuJ2DIx8kp$-de$z z2-^j;6)S3`CX1K{fG%>nDN(HgB4Z+D62VLQNDM7k8UaegaLK9P@)2)Qu=6e9;j?=73Wj z68sdJpJ*qrri)ShwXelIee&c8czIOvA(2SizznjMEvZDo3YZ&j=y;LS{m_?Pzs-Nv zyoV=5L@6)qd+bPLL+jLlE-$SXJ#a2pWG8w-&(y#*x57y2MzI-2%n^TR}{qaYc}f{~PEeEhfpQI=-3#3QdOCgzy2@i*9M`j}-epCFFr)Zf6Ds(qN4 znNLmMXD2`MMX!i|tmR$$;bzpixVFaJ{g_v;ykC|D8E0gf+UA!z_v==co^kMAf56DhtX=)p4eQb6)jyZL18QgQqYiAk ze_!_P(&E7Fh0D#O7n_-7M=#qZE-dMPM-f4U@TU~ry~~*z>FSlWg9@e;4CzHAGdw-u z{IG9r?#qThA8bEPw+mw}8fnI%SFetYj-FgTD~yEcNLWLnqM$@LaYTtk%nfrX#U(dH z-SWA>A;nh?NeD=tMiWFditgV($=}j$Pd=~#c^vW4jeaEdqq#Y%uF#=w@=a6=>XHAW zd98<0Snb-a1G2GCLSRpcG_Rl_Xkm)uGSRXy=0htKQwH6Iu$@c^0Wra@uKCPm)`TUnPRgZnj zTQ6SZ_qe%MX7_uuYW`ER9WqxgZ+{T9r%$nZ-_4KHY@0TT*dmEZ%WPQQ{CWJ!-LU6> z^;%=Ddo2hEtq5}D-J#;=;_5(u%q?Mx!jWJbu}p#6fyPE4(oy6$|3XWAP+Pn0d@S~N zKtsYJB9>?E!r53@SfHkcc8-;SA({O;Jqa}j5F70n4}JxFA2<{$mWQR~6l7=@_WR7G zTV_LP{~ZB{r%nyQR7Z?E#^B6Ov*W5LA_e}v_KLk+?TlT&q2(w40GDWlPux)Y=xLFN ziP2l(f#*w%dd`=f`<=j@SYd7XB(JY>B!I@E)~?xby%=Q=1*5d89qYzc8%4Z_uN69Z zosF6*a@uOk@1S=!nZ}QYth!|g6Am8J9iBn&kW6=L;^0jNYL?x1HQvk9OUMR)VOmuN zS~9%#dPGFm_aPi_W$sa@D(TW9AY3`RZthGbftvN|T)=0<_VUVa=_1%s$>9Eyn~nIA*{CU>?KKv&*=aXm;9DF!b8+O(r0`2L=3$r&ZaJebPEPi~)Xe;zp~&41_4uWriDtSxzE0+oTD zy+m=>L6H`ruOy54TL{O<4?MVxk66}6;M8+UEC;@w+IwWX#KZR06N--n4r^XG{%GPu z?29Wuvb0a0+&=b$>+IQ4WMjN)kW%oVHKHopsdIAP%sVmBa7Bx)n$Em_-8~eOG<&Cu z)*12P_=iBI)3>f?=H9(~$WDLuOdNWt-YtKTzIf$3=F?-NfHq1Q*b_3F%dC}g9e`LR zyQKnV(jTj06t!3>RGIRb|B_xm*qi>i^5r@==9}{w+*fvHG0vatSc}kFYn5CmmOlT1 zuAg0)HbNUy;Mf|guDV_2NOm_xVn2!dekVjqH!@nYtrRvlAKa6b%J?l$hjP|OM~7EL zS)dZLn1ynr&a+>Ou}OADw6i=qMjpq&VCjwaz``sXdDCdy7qoT+y__e!vM{%nfl)@L zJtHe?m%UtmbiAyBg!Lv;lz@>UqxYbv-;&kuaCLKQRZd^IO@RYV`idC`&kA+Ddi}Sn z^eX-UTS}!@Z@A*Jl>%)ZZF6%o2;Zp`8YogXmLnOsA#GrI7`E(9yu3v6(D3kS%bg>Y zh0DJT$Ct&}j(Ckkgy{Y{Pix0eY&y$ukZsoJ&?@JfrT{sQ)f4)wJ}+ln_xz@e6mtY{ z{#xQheti_H%O!38cx-gh~XRLobi z+wyl=|XXq+5ve~VxFv4x#ogXIA?@1E8C^Ng9cOpEis$J@gc_$NO)F@Ug` zi-iyp6V}r6^Nq7jUplmF|8}R<@cMbmhJ8-_bynoze>;da@!@D{-H?7ZmqB+lJbq)X zTkePMzoPmpg-pzSw?DoMSl@R{h~BO{eELk}W7-=xav0a{$cZ}@-mH4~e({Q|T1Sz5 zsTQ^YeyT>*?=wTTHo>~rvdGNz4mC~^kRL=DHjN0TE)gS*6sW_WPyP7OEGx&yB2QVx zgocnvfbK1EPPz7IgZskCj0zI9WQNQoRL?iel=keoGj`Wkt3*D%@I|BDUe8!Ks`Bh{ zpZ0n6vyq?4>`L6udH@{>YE+DfIz$hA{IG?^M+k610}>z%j?;9bln3$gfPQ%Zunt00g)_#rIr{Z^fiha2HtZDOMHcg=?4EMEP)m&%3vbJ4hd&=7LJ10+X$GhmNeQZ!V z@a-caXKfiic*n(cndOkUxcC|@%qUFWR7}*Ifj4u}LUaV?b~+tCV?RGowXWBF?~Dh9 zA}BAIKc^>MULF4yAzj%^cebwQ51=l#MqkjO7_hpp_0S5Fb6QBp$T7O<6JF9XWPu<- zx+nofK8>tE-MMS`+ZQ5<8L^~+ryW7)0dT35SNLdxh9o=EOYQ}4HCX2WG} zbIcoS-?e2h?kQ{jr)(Wo%6LL<4IuUmNNJt_F7ny|sO_N0t`b99`G9(L1hTcD!s_tC z)GvAxa&3nSPoLB^*ZFnTOTp?i?)#=&?mY%wy?Fh&Qq*Y?np3o zo{-&)YdRJ>_=iu1xU1B)ZoqzJ&otHjLyLVtY9hkYel;A5OF~!*oB=hpA5h%nYlZ~2 zN|;v>eujjEUJ|-XfIiYTC3BF$z|Yb427>U14<8~m1B8wmW|!qgWugUu&K;P}{OqhR z=;0*(y88OBiZ0L>8_s~Q^T1qU5QsZNK-Y`{p2IYT$4`k_jSBMeMD|HtB&on%L!$}^ zGvZLK!`7}Hq~`Uey`@d$q2e_)b(1D{(Z0}<>3d({LgA6q&HcMw>iGvH**Im=Wj8NZ zyk(&d*NtwyA2XxdAa7aW2H54e9VoG#Q(wyu~WQ%f)qBh$_# zT$58@2z9F(+zHf~4^?QHDK12bv_&rubIVO?HXqaz8N0CL>bvYJ7xd5*Xn7nWD zN)ZyGqVy~*r>CXaCDhkbup&$|cURw9bmiY*l$=FZvepn9ys|EL^);F$`i9Xxc3Cen zsxzIZE+vKXAHH>6|9zY87hCQzSK<&6rIy(Do$*jn2m|%|hH@cYnVjkY(P~RX41S!! z49e6RycKUKqPb`X(08yWC^k`LtwJ0dda%WhdV)gRSS^zVPQe&Gh(Jf+g=grS93jnd zzJU76b~M*k@?E`#{nnc-L0Er6`IGAuLIf|?A_g0XQNqKAk5HT=z!td>1`p)MaosTn zNC|T}FrtjK0~w4`Qbc4dP*k5rXy^#hE57aDw_qY{di#el3a}iYNk}BT0TrwBIcS+i z6*`*IZWo4JRI`yBO>WkxgYa93r780`keXzi@h~9) zC4ptO_D0Gq`$v995?A`F_}Zg`i?Y$7rtS~0F&Ak)*V6FdGGxE?@$yO!Ep=&3c-Mai z2XPZg{noS^Aw>2KVh1ZFU^k;7?SR5iO)Zhl7@)F^jUUi>1ci-Bowv6iP-HD~hH`Nl zBB0Pdq@-xx!U6&L3>hsVqi%0g^9R=h7#Xu0iQ9oO3M8T-!{f)c7VN^62@^>OuoQx2 zCbGR#f{{asL#iSpV;n{gxH6FHSqC|01{HCF;VdIq3Sdi?fLQcxlD8Cnx)NnU_1bsA z1>g~qA?Qh1N1z&j_2}yB18G|RRoCaJCV zV9Vu^A_dDlHm8RV`E4`N%BhNq>byiyxIb_%e18vj_X#AYkF}n0O~} z?3nV|6p^f#`E~E|Y8#1TTc=w2bAp9|wO4xFqt`qWh!y;KmoA zEhOOaeKTNjwYtCGjgxr;e+M7B=8#BWc8JzQo-{l&AnKd@`zuOH{$j`S-0$Sd-f%}) z57=e}*bfBg%&-Eht^NFY2^o{kA3g+3WIRRwF(T`GJ32fudlEP%Cz;q0G2Ch?5ke^N z=e9oM!h7{X4+sU&kKuoV>iTh~fJI{BVLpgV9Dd04!B$4_-TL}CTY*}(I~D>poc)g% zA;K=%*b6Pc1CoSA`w`*z5gRIgAw0Af_$a6i^+G(Y zKRy*UV(@o2Vc{X#`MNrL7Z>ztE>2Dun_I@xC*3c5%~2+lSoh3%F7tN zXN* zOg~N2G@892MHwtRuyf-G8O~WooSwV8`vaua8mx>X{;SWu(9*`jV)5tK1LC8-#cl@{ z#=!JuxQ#Y%g(d;F7CRumJc#>l@`LcEIfM=j41mFgr=leB=4v$X=>)bJAjgL9Tu~9= z2p_gAD_S2++nqvL_$}*ck9&p z#+pCJGEBf4B4``;984nANPT^MxcLM(xbrh^Aa3?H->KaZgQhvQEQ!~!z@hFYKypAa z=p75kcCeQN&b~C>HjH_gFq8Otdd`8dWMX7gjF_F9yId9utOdtV1fJ>k_M3$zF@D}a#M4R9JIRgw71vCxL*=3Qc9Bw}&`h8phNw3TW1w&%kJw8t6~-wx=E zextbFUagOqXjMCDMH;C*^yh#mhg$j*zem@yc)pmP-?plEJ@B{%cHi){)*|)edtWBS zP?@+mUKv!380>imI$HuXqKuRFD{_!Epni~ z`ly>Gf$HHOGpV`r)XJ}V$R9Q(DRic&dz&x`@mz5ZCE9}QFkFs}TlU_RI*+3a{xm{t zPybbM7XqP4B#q2Y#u%jY%ZrNI!QA z3RF~;k*^Bc3;qafQ0XSmNC&QBlC>-T=3F|EwGakQgd`(%T1)tASKzWhrMid5EGqZw zH*T!`?XDo7fKN<2WgNgchG!82Enu9%yt5lFB+xKev@EQwA|VK3$K(MvGEPNO87`>{`4di0(bxidRbsd^WZ<&FJ=S(+wjE1r!+mDzxl8XVR_>r#aXgfZ2D7S=EJxV zqdu=emc|P%Tt)6{$6jAeUfwK3|BdQr?2VuC2lGTPo-pwFW}9pfSAV2D-)r5A_s&bl z1M`xAKJYWd@B5y=3vgTT-WOMOJncyvDHpA~az&l$CINsMts^V8eV-1Aglghuw=R9L z2!1H}Li!E*ha%Nc*l@TUY3_zFU`rlXWh#17)dvb$f+0nRD7h2`un(et=F+!<#(yKmSOv~LUO2jpO`0pe>IGaML5L~jBD3Y)xhqs`$oQU%pz+-$rjPBMh_ zEj>Mo5T@Wrk&~0lmB*f)ZJJ36JdA4C;nl~-dt^w}Z{G(0U{ZG?BdZ<6HCC^ct?eTi zYkkv`lTQ##`A&l~=K~P>@420Xd7_9YgMI+<-0{&?CRC>MMJ%gMY?ErF%}bZ3etvLe z4G6kOUGqho?ckdqa{iNgFUYM=alhEAMY&cBh`kYrRyPPYrppubBoG!9c=LDR;f2oV z*fF~wKPdl83vdi&hO9X(xOf@b+Wr_FJxK2j#R&rmC#YwwU#!l0j72meup5HBw*m&_I`j_M zTIaM|aq>M;*-wR0AAIw5BE#AV(n35Jf8}IW9pu|(`r&g_T!^)}`;my+eL?H{#yv?Wi6vunLK)T$kbppLrsbSJaq z)9|dvP!kxw?e9Er4Xpj!Gl$bJcA_!tcpTQ@1xk~1c4&C9n zr<%)tUn9d0%4ffw6+dG@;FcO(tY@3<+N9t+^Y#fwFUUcEBY_|+rAAFKY# zIq|yd`)*NHs%nFqit1i`8$;*TBoer<_;+L9QkUNOa!0 zthE9O4zK%9#qxuMBqkZR?$M>Xsyw4z7Y|oG>C|vT%$%@jp$tFm?8#vR+tc^No7i;K zIS2z99VUUX?0#=6S1f{3r-O=`cOa&2i+a3Yyk?m-fpOCsNkTe-#6~_uw7PTnSZ-j# zT)sD*oiRT~m>3w47N-Q>9<#gABJ5w8Ysa`0u0ZZLn7{&Nw-%gvdmMODplrzgd`d&q z!)PlA5ka{#VpWkh2E@+(@-!%V2e}6T#jyE9Ud7klc#)zgdD3la{`l`!)1k|){T(Be zF7pj^Ysp-plKmmySf9`_WiLlXn#~tPTy=cgNSr^Sn}qj$pK)&|+iS>}4|A|Js5EvJ z_)i><^cTx|DG{A}*2vOQmu2F?+aodaJFjZKA*=6fF;%#pVmKTWMB`|oZPS#-io-dDswv=un>8d?*ifLR5mcCk1m@wxhk^mJ!>IG2)mTSLMc@TU3ct>(rUqP`_fJaG8(phq48u2^GeB;*E(aDzZfIuUd|@XW;=Z*GN--M71dusC7 zX=|Ue`*Mc3hru=^Vz2UeD#_ewVrw>>k3eGCs_v{?Xx zbt%Z4BbpS5fKiy2xcNKb=VSOntfU2b@CbG|s}q`3iD6r}FiCk2>XzKuz1FKy#jD}T z{+A~=JK|h^f!Lj5vsl?ZN-4Qo8p6DI7kPVx4takxDK2AdK}h`d?syQt7r7K^-)fkj zlsWYk7)FO5gVl1CYD!U2EFZRZVnRmiXYRuSU+9Vt4xX8e)wy)~>d)qZ0bi8d$qjQQ zRYO{P0A~$I?#Tb=4mRwps^@%5|PF(Ws&7fel63}Z4?`lJp6Wd^BddBtvWzvZm<9n z^C20$;fivyxOJC1(7~ffgqSma^uUg@*^8Cc$UJRO!Gt&MTWDAf*F{sz#U8&nE$nJ4 z%H3+{z~I~3Q&c8Wg4*i}+f10+vc_N9RHjOy!GGiUux_~m*{iKF2BZ&loy5lLKPtFX zY}$_175u6{MjCjm6x6fn?%H_umSV! zSea;Y=UOdxbFf~~+ZFPD-GZq=t`LF7UE>tI`Ar3&nIr6UfeH$?tJ36f1T6p1yC-Yk zX&gGCZsB$yar`Qc|@fq3EJbACN>2Mum*2`B8DM=hoNbJiAfA9s# zckIgXHe3G==10YUZf_;lo(}c@T7~9`kbwF_iyION#()JQsz6Pjx#)$VTmKUGCMG8n zp(%m->|T33L0q(~1F#!02pnttx$$9VyZ!vN49>0cn=cD!-=v8fu;TuceM^zqG~8G) zC+M6jmso#|&n5cJn&-EktXO{ktGjv|pCYoD!M zAVAchFedBx`>z7dC!EsvGf1Xd0@Plh=kn)*dmh4J0i&9FG|m40d)H!kszXin^zU-A zy$fpmM&I@<*FXA<)r#Z2SZ?#@if>1%x#U6;!UwPNK}=av zjynHFcRfrs$NLVaUt%Yn!mNstopq0-$6i;W7V;KGtxzIOPzZe{)a=6d6bf`6p4F@N zIza3`@o(L%;S<4h3zWtX2&3?p!4fP8PR_@GC);fXr6<;kcmIg83@DoC@U)q z3aVcUht>wpDFkqp|M_+U08BwH1_|xlISK#-;Y-jG9yT%Ik~;5#$Vu;6^x}{Q6F`pW z2A~Rx5%F>k9MQ|OiE9XycLFTPKmxZ;NT)Cfdn}_IVNJ;0uZEgE{qtL*nRAi!*auSV zsIl>>@eO%Wz-5Z&x!Bf;o;Xn8?3OER+4$aiIfE5 zj(v1HU9axMX_%^sDrpa+_a|<*pTi`fh3ob&_vK-aOp9(AfhX#*v_|G8H~<_flLo0AQkrMy z=l!PgYX9X0A_sfJu~&K zeQyxXB2SQLMj0kTz5?vmTKFs77mrB{dGnsgTd>l-90Hd5dDN<~Ncj_`<5S;K%nzy_ z3u<$CVCVcqBDe4P;VtVA*x#eG6{giVtW5&_{7Gtk$cZ8v2?nNX)k1u!I`sCoJL!ZS zZGhV!xCIPwA~v`I`K0Q%kU4L765-SxRB4+7%K|+M&8lxN_OGofIj6)$gZ8))BtP@^Nx#G2i<&nr^5qY{NW=t{VWvY`mX<4%<9Fxf$-IR{4o z@8R`^3u?7*F0}luex}^6xbm`1aZv$z)Im36>08JWJGL8f;d1xIkdA zu9$gYBr#bB8;`&Leo`tn4ZyspDFHLITJ^QGRJ!q3FOPNS^h4gsSk8h>ZazHUQ2b-> zWZk$C`2R8rOgzJc@(p1<81X``gW3~$JsE%X=#!(;&z(ERK*Fbdgg*r1&wyxTbhKQ+ z>N55k82;c+v zbQA5(TXoJ7@A!=9YhF+PQ3Br>{|0@L zZcSHvd}1H1Gh*A`PO>xy?K;c3b(CVe)isRm+6)M;AVF5bUkO2J&61Kxh%5h7(@eBu zV|sXEQS^SOtsMne-fp!Dns2NjfM7Yx0f-vCMSsMGDwu3hN@QJN%&j>%IB4$bj1gv2R^%ClKG)#oN7kfISTO&-BfUp3R!0pT%;{8>T7zs#^ z@kS!mYkA5|c$TRTG9QNHA$%PHQ3C2g&pF$W=rbXP zdx9t0$JciiJKbJQImb=u%UJodyGavmkzH7V)-DIcEdC{@dXS4 zd|5ztb#()P;f6tB`LvTyR zoaRELFZ9Bfp{geQCUbK;LJ$#0BzzD`SIL!^?zpdb+0#%=sX*W%`&bW=x;{S2T+b~F zpA{5v*8JmczNJc&sEr@ ze<{Ktb{0W6Fd)GCGu7JlBB7d0FZJfzY58qsR~a{?S<@!p8xT1c8nEqSm|=v148?@) z%*l5~va+{(cwd3+H2$R@o-KbC$=5!b4L-GYYg^0_<$5Dz{LP#AbsYh{fJ5Bnqx5ICRm^&<) zJ_JD{z_Vc6UzJiUKAbOIu)+PW>AI?lipB8V;n_jCiYcEII4jE+!Z9omDL6PEfXO59 zd=I!zoN_Hv=P>XMoW4zgeJk*Az-*jcTm`2aH{mG4CdfwCzR8;h>m>>~7~x`cA2>`j+KrKW3RJHW!BSL?hQm-5j9*{Us?2{ILbHE=n^JUO|CKin15pCUl{CbQ|y}D zcL1|>!6m~VRD$gwF3t>~=!!m<_!_+Mg~&?)$Am$2h|NrR;+v#4hFR3(P;X<=A*pMO zE?DQL}L3AT-1^+}@1cM$M56>kCy|HV6aNiFZEygUJ2TG5++Vgx^TYLLPe#M{A z`hcy2X8Ub>`(4ILXiY%#Y*F=*D=!SceLGS4g7}5QcqX0o_21(NSf8+C=T5?bYR7X- ztWJyy%G{dj>ScId1gVaf`xItnIiaBZkA{OhA7}__c` zdzE$-$md<_xtW)AnmPyiGCWws=Kr2Z9!DVMz-iP&J;;i~Qn$*bXdFAn&3(GM5tTV! z$ie$(j3ino5)6xBE^l>@9JyNA9F1J7EZg!D^c0(7V`7Yw6_k}ruybI3P-iFi#j+~f zT`{_a#H8No&o4Lnz*-aBdom;vNL)vUiQ{=})c7@GEv%w-g!&#E$CfRn$X$Ti0_O`S z*&mQDb^$0DP-IyqKYsiTzF6$A9i5*(e@4053n2;8HNcpI?1#!nzd>(V9A`Yv$Pz@6bj<@&1#hdufk z1jm60eTCnG5tJo)>ihSVnl0zm3t@G@*@W#c+1=tpo4x1LQw&b8NuNy5dHm*Bv>?qI zeRAJtr|-3myeuOaaf|%=Ld@;ZXo`@AYv)$W>+X`mM{|VL*?9n%j`S=$m`OvVx^L8G zuf6Q&YC)$*Hc^5#t~%MKoMc?`alPHJx;se({zp6uVJ`BVl z^f}>ETy%YxXZ39vCOw);t*4l=4!wl4wuQHd9q`uBpq582K{|Cr1q|Ow+FoA8ea~Bd z;YZWvN$*J2{G$ddN3{g3iDS>o=o&NrX7cP!e(Iub@u*-&+eRVw`|AgAClL|5j4Ov+ z(P!D&<;ZG=9nU2cup1j0mUePsC1@EK9&tND!@}Bm`*An0=)l8C!T(C*iUWNrK%rL#w2>(l-7=}F3gK4`~B%0@=A?A#m2>Dnmhw}j)_H|KYo0bo^B7< zp4^;*E66&0Pa^cAtcX0!dUa1?n3e4BA3+Y6IJFN`^`B1dv|IhL!FTPB0?XZU-&+^T z3y)dbThz$&?kD#!lxChmsnZz6mfk)+Y0~b^IXgp+Gb!3PJm18&n6ic4ui3lf z&9_~xPvzRbPay+Kre{;l`YZQ&mYF^KG1p?rHcJ79vhO2tc4JS!qvPt&SiftfxP|*a;mSmI2Nx zB;c{XI;M3v2^q5Jo;xD0UBiNCwbIWvMVY-9Lw0uT2pKF!#ROf)bBh;r{IgnKsNrhe zK#`y~6e5bFQ&<^bNy3V-E5p6yjY?aZuGmoN8*fhorw*-fsfoC^OZfeybJ9Wgg1P+_ zvt~b^dgAY}KD5o;&BS4IkWn=uO7>*`HJRp~q~mVEULI){CN+ACtQkY;W8}4JKJw@S z>yv9C)TYUxb(_(q}`IXeQ#v5YUS7l$;Y@ zUVp#|;lSHt-;#vT5$Hhy@_2iBfjzon_5xxo7~YYd$HK$}bm%RNZ(exTAYlCXAx(Z3 z8r_u-Ys(u8@l;FgphEfttU>|FMY?H!0cVtfJ%XO@pr$4-{~PRuY)JaxB-63-6PeM( zbaA<%W|YrRq(VntdDJ_!Ve7_sF5yMAjNT!}b#kecgGX`A^3Fxi`kf2aEHh5E;2biZ z6wUgkT+s05jqI~JY|GloLr-nSF}O)C>bc_- zP=&ldSNbo-ib&dVy#)QLy7_*--v<0+EVPt~2Ik2SutKWx=F@$+07k*P_{U>g8nQMu zL*buDiF(CwMWFKENzlVS!&C`<9!PWyH!jAu2UVxnL1+uHOQ3t#zQy;>?F($M2rW@S zaBhq)HwNcHdX4oD4g+!r_^+0iFPG<8WAlD$oPkj_nBlaxu(sNd69wOd811w)USNqm zN&NvgF*y;ujO&86nOUtHzaN#14vvD}FJAyqtfQf!CqWd`Qk0Y=h&hGZw+HXs!4#t+ zpzAN7J;h~xr|8npt(t61CoI35Y*&8yRW09$F^#+WjN7U1qiGLAqcvhiUIU`Edpgj* z>wgY9bH2s(6mlJu#7K?C)UK5H%FSNz5yH|I202VFd^+&!A%WF1%m&F$`ysoktJC?r zM^4TYhzDwmvJupM%jic?eVk~w!038RLHtB1=N5=n3!HWfI<3JTVEfm^a;Kz?2pB^7S#Dt7cY?04izBYWtf|lDN{}ld7IM;EWFK!iI z^X_3Z4|ru*V#XOH%IH~1W@~p%O;aHWx0wf6Z;onx*Y((VcL@!eRr77bYTtuu7`|;Y zn3t=>-U_>`tk!QT6y>23>_v`;*E1Mkek$84+%_&0H`{=hhDFcbKgpZ4rZeffkN7cXI zou*=|$jLV!9<$`cOR9Z)7}A)2iC&DwYMmE58|~NKV4AE9sEI=czbu*d&QfW!g^>gW z2SBRFrAZJjCH$6MU8&7Q)%wRL64QLYHSFPxQZjGmHrH0O`PI_!u_j~HG&QX0tvn+2C9`|??wx^<=iSE#+KCa@ zuYcCnYnKe_u)sKa!By3n;N-V+&IVwR~M zoRJDApO;x?Ig}q-D^Psq?$nX3lc|5}reL`08{Ma6H**E$@=J2UIV5)&=pNeA^xNPT z(B1a9q()r^i_1ticVynS|KS+@TeN{>ea#*JNniUAA7!f#H9=pr;3>YFIv0-ro>I5z zD{$b<;Y@!U`?F6`G)(Nu;pW#o2w6y`)8}Pwtw=WD<9nb}SNre%>#8q*ZR|5sV;le9 zO<`a4vn5+@I80gy{$}wHgyk@+GW>whs(yOqhgW@K<5JPBA37i0n|dnoI*8=&KReqc`r&F|1E?rqz%P+3I|W?w5h+iyW?i>#!Itgn#8MwR%Uet!-z^h z$0|_2Uyr)?5`>%`z@Iw;n_kO&f!fkrxaeIpGe;(1@XkhB4%_zMl$RuUd*i z!N-8@42}9u8HGR}-WU4nT4&<_-HCs6bJW2B#pkbH-S3;?yO|iw8#1W)yIw>3;@rL| zUi0SqL%R;!?%(A0oy@;6^s+U3wSYt6+Wr!uhgt#BO(sh>+w82qmpVKh*b*j~&9db4 ziTm2m!z^M^AzBZE9VAQ_VmP=yQSRBJsh9aiICk;?4Uu(#Y5CQQ7Yr@O3o?F_|?9Qg;T8pXOTQbZNn;fm09 zx_M@i5FADa>|Op<3WB-^{%`t_?Y^5#m`?EQ!Fkw^HY}ahV7sogET%Gw2Enst<1d6)M;e63>;$0nx7>Mgp@8Xm z3FKpC9JYUsvzt+(ifhUG<}b~Xf3`{vbTD~e#D;UuHUTxhNxCicJGiow%2iv*t(&Y(U?2khXbdZ8b{wxEn)BiF_`>G%UL*v4VwDK!SGm5-(_Ws-E8V zU71BetuUqaK5*J^`J3%CL$;)F*^8=<3e@=DVuI~gh*9GwfoRd}{97S=C97OWBmQHP zDY4_wu~5Hn1Lq-eg4?BT_u(t@qJ}{qy_)e^2?uNUXEm75Ihezeta$0gkFFEfssC?z z(myuG_9CE>(u(F0FGUrV6e|4i?AVtFc{L8d9hx_^Hga~(Jzv0ei!p9D+dI2Ym*Nuq zQ@_i($Sxf?xjJ-u?bn_c2TsP{u)fl@Sb9@eCaA!2s(B@D?C2l$)zmO`E-oW)i_L8V zqEn<`iz}cBHIKh};*nmdTcl2i?w}#OV6YPf2_Ni4X>`Rj2PTeh`nkf*$734XGaJNQ z%9WhjsCh67Bl7miS1R!E2YAQv)vUmzl0hv{nU%#9yt~3=Tx~Gs$g~BDxN$HY7f(@Fw#SRv)H>IZg zoq7Jq?vc&MyoiIP47#~_s@v%w^G_MAbgqxpq?jp8k3SmSt9#RJbXbY@#z{lZ5Juy@ zNe9ZtAdqR}pnp&>R;4-Wsm`#8$b1WlMD%jl>kvw-4CilJjUyx8TXO{}*)m@NiX?N2 z?%LJm$M7b%E{*ExSvDU`#GGs1G;E6xk{Xly{{pE!K0@J5K)I%Yjv)$V_im$?xp1k2 z*+vD6)`_s)U^)_nW=D{hf>cYiprZQ_&kn8&1;PK#YKVPs5AQTQvP1huGj(@0`)t)| z&+4j3fqr02{$JjnU|_B}BGc0n(r-OnT4Fg@vF^MXNJ&cfgftE#yGvswd%mu+(C)sD z`WD&okEy1-@a90dEuz)Bb^CU=y__K-$3W!_9^z8JpINLC{`W2dbHIr$e?K3PA`C^} z8qyzC{~yBM103u2{~x{x8QFVfl+r+ilp-S(87W&xMrMkNgd|BBC0Ugj%2p(MBo(q( zh%&M&vuw}n)BSs%wc^VLVzWDi4z_ z;ss%LD7iEe91)=pU=e5-2!a~NvnU=#LL>Bl9sT`BWM%)v*gZ=$RY&hR8fJVTz6l*d z+SEb(M3}9=48t@6`7x+I2omDt+>$C#8HIutcf=flbL9yM3?2FT69=m&5fL@KL?9?5 zEp2{tM>w%tBg!rE*|V)&TpzX`Q+If7Rr6P6xpAkDJ=3Hgqbfcx_dSv#kDQj8zmQp< z`b(>U(ZPA&NNyEt)ZcrbSzcz%Mp~ATB)0jB(yw@Iu+OB9JpUcpN|PhzUTlK%?ZfxFXFEK9|$GI}pcMvy;ARk^kcDVrDgvc-Efa_VP6|kw_^7jYY2r+3P0UtHPvrg4n1 z*M!Bs!4VJ_pB%{@vZ>)^*cJe!JJ66pC>DLoO7uZ7TUjEVuPsjn0CbOu5$WgL;ZWpZz6u`1=&mz_*j(?2u3HaeAeD7VufYm zop@#Zo&e!A($vHR59+Jo2)aqaQLY12IH6USk%5Byn5rri&rrdn0fmFk8?PLY9}*`t zH8hG4efsLvWo6}mKDwOOuU|vj4vZDc6M@A5g86k6pNP<~unpXXcAuYkg3=%~@(?*n zJ)^EZ1?n9mF?5(XAu4M?TaR-uv{v6Fk$3|*3i~oqsRg14I28fhBA`h1g>sgyaG1@?i1FX+VgXB+X4{PhVan4Lvny4 zzz#kMecs`KH(3%Ndq@^1E$GcL4x_n|S_p_b;=E`M3kp&DRTKp|KM>b^z564Xn?_2; ztHnkqHs$R1`9BPr&m0{&shWa+D`GpVX|PnEW|{SAIJ z9dKNi!#F0!S$I2*=FAnFn+B(sDSgetldPU@J~4qzg_hKlybgXOt*#)1IC(mIE#SUS@MT7=aEY#=*{)((9umdS6!&oSwu96P8 zgcKjZlnFlg9&o_d7^&b&;Hzul-&A<)Z#&cNgzyCg&CTBLZEW6AToaI8WfKajvCJQ{ z5n{A9S3P{!hPx%;@*C~lHWBP6<20hxDBB7{R|-@E#B-_^p+YpGzJ7IsQY<`*{hr43 z`gsr4PNB#y8dLGwP2Gdu=(N1u6@0`Zoz#+uTl6?Rli&EdPixX*b&>$@fw;))iN0TB zS$YG+B(Ftw#|r+f?(4Siz4+_2B^9TYP!`X>A@QAfxG{-=mUg1`c|9?#qs9a{BVm8v zxpUG0^f-giFf>J=dxQdz#MjZ)HBfR@0-|grMrCw>@+90z($cSsilS*Nr#cTS2bpB~ zAhd>%*pys#olp!mVkqDaOzp@-K2SARHdG zi4U5@F#&HU%-WE-czV7)@%#%`EU;8hpFRa*N-#<)zO2d)j*fppV1q>gxCb((|0WL) z5AYHhV0)#M>TJ|ImI;(ne(!^(4wht%2ijs;tubvC?&fW=z4{HOP5HYA+G*o9fr30d zg|^oJ&bv%^lx+XwaaOQzquzQJZuyyo1<+e1zw|1(CzxTj&G~HF0RFq!-wr@tyHf77=&6#`)71C7uaH0W593D<8{4# zdr(5+_q)5Sr^hIPG0I&WtVCSYeFVHgvx1lax|WYC=&1!bi@6QKz4lta!INL&<78ul zntr=7L^$d&gux-~%cB(ZI-v7KMh4O4V;y#cYK`xZ`-i3`iQT(DB^i>GQmorwrr+iW z;&<)m&LdyUQ!-&6wX=-+|y)OojV)ux`Ap1y`m25KQV z)gUATP%jt2g*TIMu{_Tq`E#k}P2N9sYA2!KPPI}G)8C=_IrXhiz6zJS{^P&rV!3C# zXpLJ#B6qV-p3UsOD}>M-zM3^d=+rL>^76zse%bR#pTp8d?*R?hqbF7)^zH-L>GiEY zJ``yu8AnCcK0c#j2;F)qSd4#?`*6LJQsU>4mmyR|A(D>kl$qa!Yf)3 zF2<#n_<-6YE~u2Q^dQ2=PTgYvXSDi{oydiW5Bf1&Y#6$Fb1W3U>fwHc5g*$UuunI> ztFRhC#@J$1j*E|V4^(e54Z(?n9(8klniUir+!~T~1LsqqTyaM(Bn`mw^$cr0BFt0X ze86{1bmwjB=P>zS;^fF=Z~~qj9W?+ez{GTv`UL`rssHVqCfJa#mN16#>*_(?adzUc){hu zPHpaF?s};+ZI3KhWjHsR-(-GQC>OY_IsZ0$cHVFoc~;Q&y+^_%OzQ@0^AzIbmbMy_( zA_ZNUJocng7qs8)ICPcR>hkDQDLIw+w*J2n{7sTp?wxZbhJ60~_8Z(h zJjEbvAnej?V3K?cQC*h7b!1c^ckm(8rLkrq971@=mtl=@C^#f5TZottK*xYaeV6Jj z?6WO+%1i!NI3Dhd*D4s60P|yYLDl8{?c3ksG9x7R7v=|Sv~U=eL-~utE=E-J3A_jS8?Liwdns33R}`q8}` z%L8lbV5BZl4f|D;)cyogh#UqP!4tA1_MpZ@{* zZi(v)MuYqmjJAoN{^4>dum35mDfARLnEgOFRyg%Y^|RoW<7}y40_Gm1Fb^n1bMvR! z%19h4hlu1FH)a7&&YcR)perQ?GMOcDBp?F!5cKQ~3n9e)$t_xtg9I)g{D;|_;uHSr z)!d$((uYrFxD7Cj;qZV*^EaHAt&Cy+C{^0|_DHt)XuT8rdLz#&wU>vx&3-!VfA@w9lM>VQ zcUFDA|B;bQ@2qlzNP8*m?Ci?ctAfs<3D6e?9|#+<(;W>J322Cwp_}@DLgLIrz{;Mo zw@5?0KO#PPczGu$C#`P1{AIK|GWhR7Ze-U(sy=d9a!%uaL+G>8ZW(dxIlmd&Z>1DL z^CBtZ^#_Ir9!gS3o+A&YPjrfv&%d3|Uw`QaTLy(bo5B%_JPW?#YwUM_IOV2l@SnX) zm>Rha3E5jYCT{?#V13G?|;0`Sl z|NSb>wn3{~jLG|y9e!LDS&$S}HI|Eak2d}ZlaovP6Y`%UNi z_nxwH#~*BeH+7V$>}_f36CS}eo~dDhjm6EsnOxVWp7gMu@1@N<|B=PPk1vks2E`do zcay5whoSm7*8-h|Y3VU9+6rvjZIRU3XLUzMKZ;I(vKy4_Vsp^%G)8u)^f(=hj85hK+X zHnrLx{2X;zIP@OS7uv-6$xAfguvO5`h4h7MJB1yxn}cA~oEO>NcAF;G>)>`?qRzmh zguKb}!}%@6IggH?BD%3c0t2ZWDoq82yYKNS|2uN!Sr9-!MV{uqG{W^#xx#RIvGwV@ zi_Mol+8S)t<~Z+0DVt?lpV+;xJ=JP`p-!F~nlV1DHIXEtgcsi?CO$cydvxy8q}eBm zE!Bs*f&)&BF6Ba%7r}#tuHD|jAxVv(nL*U5hd`7+yUe&{%k}_3e$#=sXfr83-0UjW*_8_j|;zE@=VU!b}cTMVp8nU)xs+?+$u~fwKMxzJmUue`!cE=vV1iEdbsE1shEf4zIVkC^7hAK9^oK^CuQ z-%%t!%1T|0zs4r75@TN*|O3`u|e3C*r*({hPAYlD{obJ$RjX9{YMbd?XU@bSNG=6DjvR zFs(?+7}cHo`lTM<^`a%iP~z+xsNV+*DC;cjYd3k{er|U8zj5xiU>K>?s)ovVS;^@$ zyekfqyKrS_7c=h)1|^>p$~(c)5cTN(5qZsPo9fv)zwoW;q-P~n@2FqVlm7XI_T`L65h)Ee)pZw!xGADF*7Amo&v zH^h@6z2|2mOMJ!rtB3;QmY3WB@ythx%z>{N>c>I5EMf(38lox)p7^DhNem>)0(B`CdMSghX(`Q)+ zpD67z6gfmsxg7ZA1Pw=pu2;+Th2cy59O`4cj~}L+p`~3t4L9CU<%C4bkJ|dV)JT>e z#wo0c-&A*0ZvEa!!KC*f5pj=MF0A3lJhjV;(>okydXyJ!s2BGpjpm=N7LIv!?c~wF zKf7`SWMI)aMn5q~r(M?kPq|fHQ{#biQ)qpuChgP8@uQ3O|J^1dx5)R+Qe%0==?#yb z9&SoNgboGDCA!S-jM%0L5caT|6cXKA8$fqz~Wb6;*3Bo*wjJKdwi4VQQ^($K$WuIEuDh}!5>T1X z&U-WFP<8cL&rTbI?d1E9max06Qg*x4u54dky>aXzJv0#$Pj}1r5!@Qtx5jH(mTbGe z)-->_IqJ6BaFs0^Rows(Ox;`AWk(Ie$2diI@BSX?S27La=9&l__2QOfG@abjVgEOo zgS`L$!@e(~Ai~ymM^1BpKY#MnC;t=AFI~CvFMX2dh+m`n@C!zz;bVu3go)+pq^hdI z<-RM=@yYu|+YtJkBISCciJ0oE7{jkSVxPDA?==0@cxup&OKFO;&cOFy^n5$%1tUw} zDel(vI`8o>Vy42a1{$3%82pW1x@#~A(O+}v;;rX_A|?An1{ijA~eUiexWPkpbwNA-j7`+@P5h8`Li z-6~YY@9XMnesT&8!_f&XBSa)fbj#kG49FZoc6?_q@%=@xae;HM!Q;=&geoF!qv`9@ zJL-BPD?^I?8e?@8+V|UZuHEiEvJm7%^TuKH<{^Wzg=idWXW zW|1@0@j}1j&9%SR2DCGv5<~Zt=Gxi`S>C+@S}_M9XZL!CjHuyI0^fvnQT(-iT0=smWm>z_C<>4 zR?LrE{PmZz@S#`S$wn`~WcHZxL=R8QrL&%^H`}RgDQ)eyc^gu$FIa3uif0<-Rr^XP z`F4MBSY23!I%bTh@}`ki{|&|32~LHTsaFX%k|8h2Hd5i;>9e1f=-BFxe?~Tq9DPC= z4>PwpavR)3ntrTc7jP;1Mit+LM9@@x4Q7D|V%$i?C>K>986U5R)NkbvSch?j?nu)S zQ2u~`1{@q+-i~m5sm7n9gt!=eG%d1EwRiU4hG$G42{*{<^*GEd7~p>8N;%|^$cVzR z_pG(GH6+Tsh%*J%XVfpzd%@mbbk{DT%Y4@^RAJb4#|M$rR6e8EubS&mB}2;t=7>d} zmQ-+17+Y~Kw#U(dRb63z*sq-Xo~?ajBLo++-Rl1v@A zTY>bn8=?^@FOQ{pllF>I+Oo~OO!#WZv~|xp^G+3?<(B~NMLSpPD^}^u7YA=Kj**w0 zd>3dB4~3pQpW^-f*H4I%44jy9A3*HiOnFFDT7X1%$)Zq_cfy!n-UZ<&*EDfaNh{5l z?^}e`?MJ{If{gvM4g$tRMhcNKx8MaCix*~Nqf zrHnxIJthqfv1p?09pHK_GSH@j5DtZ`o)tvYHYg=3AO#B zM_|S?xJs79=B} z`ctK2| zXYgBDn2f?C2_Q*eefkcfK#2GcJ-r7TR0!4B767X*rhjPAJ3BiI3kwlMQ=X7u30?^8 zU05tJYQm<0|07L;Nr~E5FsG};sVCnt`)wfo0eUs$Wt@ej0GUA;o>#7+T9`yS=TQ6Z z{@DW}_wDsJ@o#e4AJLLfm#^~vg=@I0{k)@!k{w-W!ez2t-Kms{cdo-fknLaG45vx) z(apZ25hgx^HfNiEx6uik7Tj2}dTi6VFZe6uqj$t}w=AH0B$2LSu~vdDD=+5Zcx8*r z8`GafQidg?ogb>LtNc3H+1b|_*LH^KBN#G)4(JE{B3s2)JU2m>alZfV zv^Q9UU~;#^cnYonIQx3jvbRE7+ecb|eulb~;}MYg!y*?M9)1x>Az)ZoA4UJmKq7k0 zFm|J}!S@lglIZS6aKc*gUjeo;^$lD`;Cp5s9cK)#ZWfHCETg=8iiJcvF&AF=$FBFd z_g&}e(FEy~7A0%txP9(lhBV%y{5CL&b&aLsg)eukIxX!P$|c9<@8(Jc8DHM>NLl+z zlaT*1>#MPPX#f?_0pg|et(xvPMUwHRxPL+FQZl-_UdC5{^?w}6qW1qjDGm|zs0%$5hKx{b)fI!t?xr$ z0DST>)B&(=X!>HRt9ucq4FX<=j&R$yWaOd(q`VGY^h&nK9D?6KCn0~zZ$pk@8BotM zLQ=J<4+3+BanTHIk66kx?zf>lzyVs35y1#;vse(!g)eehT;Il$ayud&C4vq#Qavu6iL! z7-brj=F~#LF<-jBwV%4Y;oQwE;58;xOvGWad>?CE^=oCr=R)1;?eAQxn)YX>wuz2Y z;kD;h2o6NIRsOt!n5R^fqYG=Ve^5T~RzKFb5$7PlyLkEPMS=Z%)dJkI-ka-|S*FADB{9itd67`|Esz($w=5RF;oR_;ZMj{QtRUF>hgxzpF ziUW4SRf~-U3uKHZFv5zcfaWy$Uqvc;D}-6>&>_^wB^qsXTZhr}$u$SH-6cX#v1@AU z=n(Csyu7^N7*ISSZCOdmSfONkO8%AperzvVSFLFGOSKf1T(BsSO#j?5c1}0q-pK-f zZIyxTca;7tIcJto^8_1D{|X6hl9d{w5Pd)L$Glv@^7hqt=9~Sxw{uy>ux!z7_??md z-R60*lajOM24#U;%97fm_N;jl-PAWz*RtnV4y`h?N36f>7@|7tg5#*UC@P%j;6i%1 zGTWv44R@Zrx#jap1R%I8l}|@mrG2!tmB#f65)7oM1j^;)&-7_%rW9Go?gZ~c*r|S_ z9Hq0bC2sm4Vl8$8-qM#Rao%4s$=1FNo}oKdu{a=z;f@%IS)G_Dli0 z4OXX&6&rZ~B#0-aHW%N!_lcr!dBNJvpyaNf{Xs=1w~$CJ>SD1nJ2&==?upbIp%1xP zOTN`)_E13Ew|zRD1|wa?0(yLmdklm(1qLw}3+&sq+OrK}+G0F*1%E z=0uw`yUs53t;kmjXfsW=I#ZNTbF}B4vaHox%`^UCbTaqL2mj1x(XK?Pab@9NIzORP z@SPgW%yCjW@NJf$+tL#SO3s>70okdDN)nA9J#mmmy z1iKWuldiDhLT}fl+$W+h#p})+lOk(B@o{sdP~_ZhS=-A#2uTVSpMEQmobExK#O77S zT>lKHwP2>Mzi$uSno}`skUY5=hysx@Pv|HkyZ$gfUWXHEbdFr+KxZ1_%KB3KkyWF* zW(K&FX+JKuUr<`nN6yb<<+Il*52uIrnu@m{43xQ3CAB$U_QI9)`})rIsatJ_iW>@? zK0lYWH?fxw?kR=Pd2E$px|wQ;fgi|?X1 z9mtql*2wL58t`48i+8`tK-;JmU~8@VO6=BS>VHT4&E%FvS`b+n8b&q!7^)j4qaUk% zUCe3eSUeDXjM!QpN8BZy)DRI-47mM;wfrHMKZ{wfXi+p-llE#^gs7Zj&^ghK=fpTr zoDjV!dV|+uUtiuAS^t=;Hm!XLB_H~Nbfx!nizq0Z%~Nx$50XKVP@2)UqPN=z$b9ZQ z#=N-A-aTKow{s+K?7*Okzfb}$onVq6DX@OgyPQ~Z_n**+s5^R8AwDeLmRRkRqR$>n zms&_oG}v^ZP84oK~2ZaQc8fX>S|r(sXpk6w#dMZUsgsIK-GKBmEt_mSKZ>HP4}sLyYg1b5e72 zb@S*1wA;F3BbV~iqeZHU^oVD`tQt>R#ObBwIe%^+whRXkPLiPX;wCnd-`!71#kxCZ z3QSjQX=Ceyb@nwJ)idLEvi;0&T+L@1H$Z2|PMUxIVb$pQi-v3UPS(dLa|KK2?b!0d zX?@veh@Q%f?u4WyfALK75`+AcRi2bt+K-P1E#2s0H}GEa0e9p64IdnLqKq{7#*$KE zzsrG{d%=V~u-lKGgE+BS`YuycTIWhX<0sGV6e5f*al<5nM%8y(%Db)gg1(! zf5(9XuBdWjw=k5Jl}+d0BO>B4J-8a@`nF@FcuJrv{;S?+72^J&RSOHwxuPSTG8Fjb zcw6dJ$H-9!y(i+4$q(f3WXDch=w_U_R4Z|lep9>XVyyq*nrjUmgCyMuQRht}>D7D^ zN`M!Y0dd-}DuJfjSb%vB=4JksYW}0qomu9lW@bdvwqMh)fr|LYxtse(izTfeMm+Rc zo3sEw@`8U7FaR_=NLn9mB=@bCZm#jHf-`I7Aj@o|GNjuT$P> ze35%eW_7-@9bqEvUe&qAH)Eh9{%6-_Mr|P;E3c$Tf4s^BZY)-9+gMH)CMkGKl-T$# z&E50${`fLf=@HSW3zjV|HkMpL9+5-|Ln=N1xG&^+Z$*n<;} zme$DJpJii0VediLwkUhuM}Ph*-mUH4tVUX-cJJ5!gD^Yr`~ z^E>aJZ7{u4xxLA6gpfOMLhYx`$#ye+m9K2wNcCmmy#~=w!D;71>+RkIk6&Mkev3ib z{uOv`dGmx#60g2R^^nI?yxO!&oRUVGGsomd4YxpCU7(-s0Z)6KeJw=$tt#@nueDSg zc07yS_)RA*Ag`dX{&r)|w6SCpSIUbQ7cfttkaiLi-j9ZunobagX(=h`&nqmRtz23d zFx(j6-N@Q_pU^$KS5Z;Y zaX6}CRmA+-P{;xQU-h<>gh$5Lu;;vyluSwRo?S(3vog(!NZlQ;hIX#q#M zUoB8^eWe%Lx+il6@~l@XOK;ZDBI@Uh^tboC5D}p^ebJ^mnps+U z7)iazVOKZ|F*33FIDe6@wT14SA0-1ANrfKSHjva+Gn zIM+j-vk(v}D7vjK;(6}~aO#;IAoOWoYQ;N+swNj)@ZW}EMa38)>!ZX_$zC$jY3lIO zvAp|LUBX$V`x%IS_g>sb=T~1}5AcC~fY%vW_Mk@~&~S{Z_kf{3+oEC}^Sa^dR};T8 zQt8)x^CUHiEw9qWUwgn&6stt!uI`Zo3@>a7I`=Z$%JJB)*+lPpnlv|iJhwrqrms># zLXs3sGg5KR;Y^y)nar0V<_$SN7}T|yr8S379ui|CoMLX5zmo#*DC$Sk3Syn?hRa$ zx6Gcc+ipJ}eTf)SEy-q#O1`PqUrArsa%Uu2+A;9KHFk2_R_6Kj_CNk6MpyR~4U)y@ zZ)lPpP>;Ln1_zxEAE#|KtJU}J{`i~4o$tbu!ix2a-TWksOZvtIg@rHqLj}r=-Q;|d zER?qMN$YZ&@%f~luiZ7b^3|iu+}#RXMQ|EK!YZ6>cYgzTWH$v>UO<7TBB&g|L3$+_ zzbTZu@pM=FwZqRKQ(VqXNEpl=cryW|6kBh+g2yLy>XSGQ!h;|G`z!ycI?_AnzVI$! zaBjnK7wgw*Ag>F011`$(8Jc^ruXyXc`3Q6dC5Z#JPh}hpu3wkm$ZAp<5D>njq2zVb zcUk_%pu6lhVsql!{hdWVX31sYNU+IJ;Ap|OJGX^8`0iMI&+I-{XSm%yPT_6iqPbwY zXwaW+Z+#}ZHR$g+|Xiw7j39?mF7#hB+Cof*1VDFYS zcyv`v?hpN9YU++!eW&yv6B7=_nEu^17^bsmvhRM8m9lo6-EL7ido-w{5-$4gR4GC z51W3gKWng=pdbWYm&&B{qb_0B??hXh(z=#Q%7Kt44Dy)OU~ zLLCj#UQO*i{(Iwx?|R+j0)lqD;2?oO7E?ACt^mr6<`J?6`C>rv*NHh|NulF9<#_#! zOLqOp7i*|oB;m#?2@0S_1pe<2whqrAc)>u zv{{5D6(6wdtbaD^E9X4+Iy98QWc}VeCjs3EkNDc(&@@!xcRwVY>P3IS&z|M$@sCl% zCqh;EFB%xeC{XY>_CAw{IlIZ-R5<05UEJxBFDbm3RBK4J-Xbo|Y80lkl;sX8!gIHj z>6#DvEm>t4Q%+;6TYIzJhdpm*Wi_jV#$*?}Kh$ke zTF1)qN5rYzIgR#U>+$P?+o;wGb?mc*!tCzL(G_I;3}5+5bu?XfeNWi!Sm|iCzT?gN zK3~?Tk=xvOW69iT;^V0^g^l`{6)GG^76_de+K*XV2&qIUsS98 z&3&eC2{hkEDpM<^!AeGV7aw%82<`g;e=2wp)Fd}T_-b~!QHGzNf2v;@^l;0HwoulA zA!2K*wB5o@UW_!%+XEZEOG~$i4gPgOf$Kn_b9D%-&6SjK3BPhAtzi-|Gcw|u?m<*q zo8onUm&*$s+hm=(FA`1KJ9oA%9RIaFzNxFPuc6QhK=N>ePN2n&g0DNV=rFBS-#;?H zyQ#o)`CL5tiR)6*dt|cRVz`XT`ORZzce*qx9DB{9dalT2JxYvpt`8@sF=eC-1gRd( zR8;7sU)1g6v3QsvG&TG}1}=d>%3!BqyFeE$b?qGiuL}!zU$JW3eZqq>jrG*jrzoC` z2iz2)venrn`Fmi#9*D!Z@bRzMc1X&-khTG}A$DUG>bFCo@`xa`YmDuHGz(yBp|PoH zFJui!8yvh+qGIBz8h?`d!!3sE41dmlr2DbKc&K$?pTSeQ_1a^?r4E9&8l)-rLw1e3 zO+Y&dpt~IF`T_0I3-Cj#@lhXr&**dQH-3HMAIT#K=D73st2#AJ@kyl4rHzbKEH%1z z$4egukyVs17%IPGy!A5P2*E%RzF2jiP#&q4sKQ6usj>%B4jLo}E@s|3>%8>3wPES% zl5IgqWXN`-ldsn=lQI%kIV%H+Vn1XKwOJ^Ch%`Kl)3oopH_FJ6jYWi|9V+~e9sJ1F zCg^W**ye8an*5AylC;-a1G3Ta_{fFsp)lTdxuY6^45*11(~W7w`})KDYQJZfxtBXF zp49ho1tFLFbOkS)hTRgkg_=CGizsSgS-t0IvYl^wjO;+}sz*zbNog|v>c3n7gI|0X z)vRKCPug}mY|_>6RjGZsbKL%8W_6&%rI8mMqn}PEQ$1~t%2}}DrFMA0T^wSWIf_2@ zAo1K_BOhKb=0)Z}%KhuKqsx(IzjexI?>c*8=6&ID38^PaVfNuz!mgEl1^D0!>>(gr zacx`&v;{UF4Nc9G$?OuJxwwH3ENf!z!z-x$BPXTI@al*%?nl6NUaV8KL*$)x`N9G|<9Q;hB^ z=w0Cer>~{PKSiDP+V_tP50^qUijo^5l>(U>fVUyty>M{_jK|^mW)-}8h4|k{BJ+Vx zdQ3bq8*`AKk@acHeX8lW3yS+)-t_*wDCh5U=uQH@9S4zrxQjY2#?*(^vFc{4cpIuy zJFEh#Mu$^n?_LN=cMUB%Wx4XV*`)Jqyx(Seqs@EYyE=_d_cJ+S%{uND5ul?*>6X)w zQtDv(GLm`oQ!T^Nz&|0B$dFK96}Ae@b}Q)*7VD{H?lYz}S*+)vSa>(AWdVa=sfvyZCSf^I;)ZeyIf z-KhDv%qrEC?LCu)iyF@>-6t$!hQ9Av$FF8m!pp*vL==GL80CFOA=8QD$Ato%kOYDa znDOwm-?@5BPv|Bq18)f)?=t*K=H~rGj4i^NK{-vwQ_J*%&VnWwr_&dPxAH2--El7+ zBFk+XcXDzvgJ0nK^%Z0Q_Q*nQ1>PHs5dH!6C)D32mU`o5^U#VpA(k%-z74?(&^yptc zb^KS;7r1dv1pUX%zI(QvJh1S4z!%25fN-Q^A&v0}CIxTv-|$ud_9q%3aGJ#X%+A39 zLU^a7WFFF*U36hpJ$se_7l@4AYzzn8kcOay_=eG$GX)SlC~Mf+?KH2ztB2?rxz#WY z#W3X~pa26Xj;T}qC58i+@AHE)CJNB8Pa;F*B#pJVlQ4Yy^+YNeJh#r(M>%D_x{^#T3bk6k+J z?2pECn{s^x&yo4^A5>nIp%ffK6JS9xonCDfvr|o{oJ8G$YE1CFRa8?)XLky>9Vm|g z*^Gyig}@!>@t^N`^qh7Tk$eAG`onHI%PYD(rDz#<&U(Fwwd8Fvjrd+X8^4odd?b0k zP*edS^3MU64L1N_2e@_&o!UTz>FK$lq;xqdq}VJQO?W~oflSJ>u3t+5M?zj>V`sOq zkmHMZF)^W(hgx@-Cf#U^{27!>HDF9-9eE>Gm&-Lc@Yom_i_2|GxeLAZ$93KSW1O^J9 z5a*=5ln)v_r0w(!j-@F?3fy8yixRzlbzIm)BIuW^c3XOx=2E&*@5;gaY$|)ds(24o zm8v2a?{hD^TNTgzoJ#HXE7%cHxcdv^myYlxGoO$Kn%()PJMa9C6Wngld-UQiX{INk zU)a09o($iEUk5mEeZW}r_;Jtas?9_)GxE;?v)vgOgkb;gk~i7rdXWGS3t06~!HH}6 zud)XLfnEr9&A8$Ez(xMp}wTbc07VcIoT_9j0BCM4-od@A&D=a1!J*EK54`W=VH#zUJZZchbIDY*td7+R3@)v?Ylrc~99&#R=`N0Q zZtWoNhto|~Mh2g&c!h>fpC+cJGT|RaK;vN0-Y_j~Z5L-}`o9!M&7sNMaGbbOa%8Ix zR*VL!O8ijC4?(-G+4$401QZmTk;Uk?HQ&7%^6Yq2Gz;qlOV@4pw|m3Ny?6XkQlJ^V zN>=}IXO%zww7;74qYa1Y<;k43+pw0J%{=<9#-S)6)|4p4Dd8Agaq#_{)J_cz_B;j` z@v~m`weQ}4XGlL&p8v`+i{|q^F;UyE>`YEf^TN|lqddR02dQ@ucyKQJnqm=HS0CuZ zQ9_F#K-0IEL^gJb9XayUCAF}m_ouBub)U-tn)w*5mc4O4Dmi3UM^D<>rG1|h=db_p zl2~?+Zf~{OYq0J8?*fO3#&m&uMt|KBL##hLGEbixlP_?dqW0w)PQNqB8W+Cqkj$0Q zBfu{Z9j|1Nr&P%cAjGcLt17(u+m@k*1NC7aGr7zUrp!EMw^o=lKWBK?HU3CP%Sj(y zn{pX?YpJ=Xr+XjD_~;*KAlpLPF})EPn7N5moj9k?k<+z;L?8?+ElTiq6B{=#A^RLS*%?F$o8n<&f`Bd>A>?gooj8HwFBeD0Q`>;j(;2Gd$Pvrg_l^id#GVs+$tl0k={b`=I7 zl9Toi+CkKZ%JVTCT5!d)*YTN+Kt|^2GiP?mmf$#xy0Qhp@*~)-u*~5lniV*7z<>y7 z5uhs;jxq=yl!Kan^diwiN$F zaMn`E5K;tV+IpLSQ^^>oR^+;kSTTwpmjSnX-P>Q_$<>I{(EM?|nQO*+Odm^jJd!YSL zWue<8ijErZD0}1my?#0IqnbB+^uM|U%PuL@x32_C=v8+5y9izrqxku6p$T}#UWsjn zAl-@0`RZ68t^`c7=m7CWpThd4l=C(=Vn(@xIH{T-o?l&kvk>xrh2V`tL8V~8>Xer!Hg`&wQ50A3x>@s~g%V`#_)%{PKk$Lu6z+ z#@(SSea7_N{Sc~2Z3>A25(t}W)XtN!=r2%hXh`fql?Dh9)hGm;(g;+jca zCmM!#1u9PGv{>b8t$Z8yf5@qRd4=pM<9P3u+0Bujjy+;D4BdjQ`sXTMo9-1pM8lJ? zdVnu;-#p50$qrn!=OK^nU%14zFZ8t~Ct2Ny%F#Vk=Q*a}vt9XBGF}Z8_gdH7v8Jha zOSVf7o_EL&$_rlGJ!U-JD=KSya;9w)-Ht8));ivMHF|eyfWe3P>9id5V>c5wgkNr? zS4TsmxqH7L;y0uRm-l2BeTS;W(ZvPsbu9Wj{(f@#Kd3qI7AEkPjYf66d1SDuZO142 z-K$b`$6Vc_T6c6Af3h~mPJ4}?xw6;3M|xJ`$*(glWXJ#P9DF7Fks;*T-Nv_zq%FWBXlT#$_V(Vj zIQQvJ$*R7$ZDx=;x6&)`6(vpEC3FABy|W=W8imz%nUu(VuQQW|ZO)%RjD$mXDo6a`^-E^!LlA0FJA^oH&52&44rQ0V zLc8#&z+9vto61?Np-W`7>-5E^9-eQg&#KnyxxXFkoPAM|P<*x9#jw(4t>vD|;{h6(2f0E?w+??AHIJf3b5+T-zhl*eB%suJTR(GUYD8&WrCUjb3HC zf?vYpnTykr61HrY)p7?;v(ZwnD`y{0s`L|gh~T9}azbN4QclitfB4m$RlVBw>&<)R z?w{h_Zf%W|eUjf|Q#Bga>{!h#(@w$bwLGhGwyu4w`TnYFsZohk0zH*4@nc9NDzbfM zfj)^HKjvoIzWPzkpEDs;EToXV8;V-J7c+OHIPw%4^1eCv#8%Arru6>ljz(Jnci9UYhZ9muq+5!qFt@=8%&7yx%Dy`&x>_EJ^2~Z&d8Mj*1Y7}EA*sg3 zTfqXmc-N%JVoJv5_$GCU9oWe42QB-{*3ziGGq$Ib`x#+-+xW6mJgZfMgaSik`H?Mi zB22$+Y8>s~nSOprdtt`)Fz?w_qrh208y0;Zi`v-5#cRcaMdV6p>ya_Ma`tTer-Cy(GcCWK>l4Kq?nj-ZLs|s_G1kgp z^b7n2&hB`+mio+Ib$i;k>`3`}l9%ydg06Z~XW5%?bpf^vq^)tsFIJ8}$vUTMH}xcS z(x;p`>h`S*;p-C``}kr_uGHH-!Ehfe6I@0?lb3L#K#ihgx+hoo!ej1rF?*dw)*tsC z+7xeBI8iAhmFKqDP8&+>s#6We<`=_Ho0(;*+f|+exBjY_E{`%9>I=U!TJPD0npyUS z*mI`yPwty^?}})jb!4OSANsUKQcQ6=-{e$=eK1pX;8D6m&C&ztzY3rJArjy3FiG=k z8qdbB-;&zCr~wk|f0)Y^Ilk2*6{g*XHt(BwNk*#tyvVH3NV8Pkr?&U~?@De?sTT!K z%|TVGH{F@%m&eZT&T>{ed&|Ee{OeY=u)|J$*E>d&3pD?z&-qa}sBiHyKDQcW7ofaE zhzv-iY2vnk*3$dm!_172d~h1Mp(t_uck}w?a&bNhh>`9VYk6SjE|YsdNHmJA`HhKT z>ZsgcXyA9otlw@U_aeo(U&h+6vEQWLFF3P@j+uTu=fc?H`zcp%r5SNWmi%+pF|?LS zyDnDVA$!B7byl-$`gyTb4gVe!>#hKS6_aMxg74NbN$1Po1Sf+Q`%G6`f@j7QNjx=s z($tj_bMdGKI~S(8C2uE+?YKNamK(aAU#b=M|H!1bIKLp9Aj&J%wVuYBtNlpQv(<4% zsQN`{$fJtOPP2h`AJwzR>8@wUS3M0!Tnm#j&OkD+Q-f@6@_Q4KRW?5zh+4e;)WKS+ zUbThXJ+8I&)UhFNmIlS=e>^;Wd@QPD?*kW?ilEp`@8{-A0G`4RV8;LfLnLb;=qDh6 zqVN(%LLdt_FstOulAgRJnZ_c}Xx$xo6{c=wG=Auu_pNsaUTXOtP=hQqAQ=^!E z(!VT-GjfXoL2ci$!@$6xl^#GFG#^A20tBtC1kHjjB?o)^1V-Q}Fr1vA z9-o>@nMAr!9s)IBNymd#8M110juYY+^w3RQ3zdA1D0>V6HZZ0Dwpi;z;Kn@eNCN!D z*_EhJ0vVR!Wxp9pFq|OphT)%6YtUgbDe?6yKAfZxD*q+WwkXYi`XX%tr+QFV&yxc> za_V{0?o)H21v)y_iElSXH-hORR2Eq;TD$2h9qSVbK0%bAbeI$C3glX?p7#ebGc%Fy z7Kv_PHwndsOfFTVn{ z%Oor~G(xxx(CpX@q+;0aDRkyF{|bf@kv=Fw^6~LOP8ULOXoNr-+q)8><;PJ8`IpaH z9rZg%_Bv=)O|cP)mk6~1dN(odeQs=gDrv0-8-}Lly)#c=n*sXv@Q@Ko!Jrf3g;9?w za=v&d$G)yQ{kUni6JLR5qN}1xh||yauRqtHzi?j(5*pL$<^va-FTeRwk?`ThbzY%C z8|JjyqQF0Qs^UZ1IzoJ3;xwM0-&*B%Whg#)@_lD>s&{|4mk)i|f~uQY;WPfvAN8j8 zRQ}HBBwKekDVZtR=QQM4LU}`PvD0W9;BaTAix#!Dj9&zBCH;aDelRt+L+$8^831u} z{D4Q)6_@qkj6HV?RNmJgbCi60qX>aLVevVA8rfvWsBsmL2t5uQC0kZNZ0)=(ECdL{ zd#V6G10#(P6yGjyt~VzrNuQ>o-+FD3O!))ovQ?9t-47Z0be{FmtkQRwm_2@hWpq z#QFE!Vm4lbdk=3lU^eJVXc<1uen7Vyyd=5WqyR+FtlfKw&9!a_Zl#bO63%~u z6SqC<>c<9E>v%5}Up;e~YP8~c67%KMsWT-nzi$hU?^si%Fg)%(e=(c4m-DKBNB733 z!DEj&=S_ro-cWq zQb4*(NLzF_RJw;LI-c-9?r zUh|5`CKZPqmcPoH=01><;4*<;2v#%*&Ik{kz;l)9Cv>{7%a_u?d$JyonzU~#ig#M5 z{&2*t`e|UwRZJhCBg?Pu6FiZd3^L7$(^=0DJgM} z#n%wSV|>Z(!|hPRi&#{V2k$W*C1!I_G)klZHwnsrr7ult7OcY|w+~_%u8KZl<>lpt zG#F4ifZGiV3Z?|g68JcYr1Z77w?nu)xI+CUDNU#`q0_&*B>Hg!94GI~Z`CK_fjX0Ct`{ogsyJ&Kka%r0oZnD|cu&Cu)xy-+c&SGY@>wtX4mpxo~a3 z0uz&b|MNz}+LDF$evXpr{ddN(Wo9W*zow9NCrQ5yAgligeehpBvH8CPKD^)lSKxy{ z^8L#2|0(dnWxL+_jU+pIX-L=U{jjY%p>a2Cfayy~+phxYAR|01mQ@}AQc)I;&OuY))RX~9e3&d$zw39qVe z%Z~Q;O6uyiX)(A=aG8L((;e=EFF&>~EF^qS58*Tfq!&!~#ZvkJO1UhXtiB8qte&c_ zZ{Pe-BhnopkOKRcdaFC0@jlq9uE}}3x$!goeA;wk3h)YWn;Iiz#M?pMPFm!>%H;DpMsab~+Z7aAeaw#E0F`9;dh836cLl}Cor&X82c0%zz znb|ecX}e`oqT-B73UW3JTrLefy<>s<_99V@n;o#bbd;dSU4{g=y#Mt~Qiev?hkEbg zo|_LU$rJVy(q6{B;`>EY^^%c+;^)_jN*IKtNCM=i;}}^qf8X@@ZOw176`D$NLrGX{ zRIDINLLd(8+(dr6iU5h4bnE&--auOS;%~5O^gda8ENYLEa=4zs*4>_d{Oy*oFeKzX z7pH&YWg`rH5GZ=ApzytO=ME?$M`mE(;i%1e5C8PCxYN%1n!drn;CucisoZgff7C>k z+7_Mf_rlRKnTYezU~Dmu7cMQy38@(LrnAQu+m+#VWw2%casl3>aeQbxXvr|4yj)dT zd3_XomgUB_R?fZm7UzUau-l`IdCIDDP^R1dQ!;=+s@sXtp|9!X4qn zjpzy1#rJIcC4h);zL@1`EQLe&kb6`Qsa*fh{hkwm2hXzU}60S zXvg@%w}`Nf1tSR3C0JJCm*KmS==A5Z40EwQDt{A=T_e;)GmgWa798ABM#@iL`Ry&y zc&W9h+MVRrxSN++c)B_wM|$IL(0eUY|(CAKHGVNcH@8yvl+Oup*7*4E@X+Y8nvvFfxTp9-sn>m zVk%r|dbkyTk9NR__K4~#{CGwrN?hWOYBZl5c}sf#9>Hpe*ZTvv6`1W_ObLhy-n2ha zBG(dBZEa+~X;Vj|r6#c4PnfqeokkILWk)0Ok(q)=H;%{ruBiezvgCJfcDu-pmChxk#HC}L;ttNB z<^T-YA3pSB0f|@UNtw|PbZ;~DKZ72Z*zIv|K3s!WEX^tl^nvXoZ-A2aFa+;Z;ii3C zzV8HBdWEdQ>r_{L3mxQHk8*<0eHgspdY;rPARKEFs@N-QZl{oWT?dqg?H5i^) z-*3*~)O-}h@DF5tdx1h`5dK0S7TK)djpAANU!?chyH|i}e-R-9%YBkN7!93vTWD!` zw`_#PBnaQ&Ub^}G;bb(CT^jk2tS8|W=WmYolT*aAMIWU;G{urcn5wDz4h;^jw85Ba z5X%=~*@E*eykru8384oJ5m$<44_vHNT?B$*psCanYyKXS5%YQF>Ps z-jaJ%jK>*4;i$QZ0%8Va(hy+AV}KH}`~!=?CrO5^cjEaJ$)a%Hf37C|vV@x~G@tgi ztEHUqHsZX{N0e`ouboTgQ39$81>q{f=h^S!>$NE1YAs`@CWTB%2wED(!$J@8#%mFi zh0VxR0ByH$KN{)KMNevr zA@Tc+$B4{g8o+L(-Grr1BUFlPu7oUI@l44(Q%=oWa+p)PjM{Z?~cltOPhd zx$Uv|{IIBHu=sqSvwtV~_q2tPo`a9Js_~VCqs~K3ar=p43yhBExRdg3e_t*Mip5bq zb(P`o2NhK)Lc|+pF*h+7;5d}O+>k*&Z6Sb6c#-WL-sR#VOgU;5;%Wb*5iyT5+?cW| z-Gd5pf7Ah~kvbo{#u2PRb!(fz1 z&N7s<%#$`S`g{`eMEw*@k5s6Djd1rg++{6XMf~|Ug5Lfc{xz_ z;xIwAc^hgD3}W&0P58}Gc!(HSmxRCi1&P~0bG9S~-s#`L%>N{yaGp&0-<$fJzke+D z-*Ay82-!hU&j{p)QKyes3o+=34&%OHk(G~VaeR|J`0zE~)>gOy(XW!qLxZ>(+PwUH z=761hLU{a5sy;pvrkX$NZeBhsGc`B~zlFTw2THdit~WeeKlloIDY=?GJ1Gswdh9-* zF5-z@DYZ}?H9q=PjTvYMmo?^ zQ$ghb@CIbi0FVITnfnq{ny7;1>eK1hpe>h|pps|9-2|`$K_=}N}*0A}ZPg{y8`!JqPUGHSUyaAKV z$Lx2vR^vU5=!I6lqp4!&QO0RI`oFJ|;pMofB$gy`c5>RA^$$im1*Dnj7Zt}9Ez6m- zh&P7cI_2@+=-!I#m&9S`TVl~Ym#&~sEO};o@>Pvn&G<*Al`qx#b%o@fKhad~Uo9nd zDBmig?&$H@zWb-ySy=np|0OhX z5#=ytP-!;X4NPHRSKP$`iZm*Hci))~OevxPOb-OGh{R`Ycj3;E6#usF$hO+m-%^wD z7o45$lEVVwVSlu8FUsfqn1>k8DlzPY&4m@K;T=g#q^W9DO?lHsbB|8Jf4z0I{fV}? zdk|7eyRz+5-S#D`DK4{mFdpehnHi5=<5)}F8hcY@ITU@*$-D~f;$~h-oCOtq)5pz6 z0H{|0^oOwEPPyUF@N6ysGEh+=eo)N=xC5+b_)yO&FD>m~_aOc!7F#mS1^OWPJe*2F z(EwWlU8x!@Dt&!v_$-fcL@p4ze)UA@uF;oV-l7NkkElc z4u1e}_i^1!Q1noahL?Ei+L}}CL^P8eXfB`^1l8Jjqr()OaK>fdn_T9-j(_Dmae~>o z)ti}(oJ&{rMTd!KC3YSY;8mthrE3{Ad4lia(`Xt03B?#SZtdZakJ=drB&8&T(-o!RR$dom|Ja z9Mwyhwr%LUyRAEp!y*2Z5vM&{a%?vaw2U>-L6+v35w8))V47gwc3?xL$RBh|%Jd^a zC4U-LIqB{crn5Gmw|jpSKMf6Bu87j)J~Te2_IXzTd*EZ*W6Bv?BOvaAoTdxq$s=U% z>}(2D03)MG5Cz4=!~iuAsL$Q0ca@Z)MZZG!5STT9n{fq9Re|0H9@_U2ls+TF!@zwP zc7G16Y@Rqr*i%3hhJ@PvBX1Z2z+yqAU7-jvCFD6nd57&KRgt=@a&;u|iul_qXpL(9 z?C;~^#l%FbJW#ea%i>6K8d({_J&xsD_Y4t@m44f>5it{kIm}>;^{d2Z3zykA{m*5C zuQ!y~CWKB+n%o6%NmAP$<|I$=HMqBQ^$PYV=6JIgiI7M+^BG&X@y?=k&{R57L^JN{ z%`NN15?f*MzJWg*^VUSb3qVw5*&(L;`%B?BntE8r4P2CBWp#CW@n?M9q95`4S4t*ChT4On-n#P)81(NGV8XQIcga{AO2+PwzHFJOPXmw6Z}w#E{Gi2NIAi zq*ENdurvn{}I#VtX4XBWfTf0;MR5WMTUm2<~uD zhW}9W0}HHnA^Zl289~qLm+up8RmV|i-t>LmwLi~KTT2T_IB8r^%K!uqW`bE!IhTK+ zdVYstjssA(ssi(T2Bsgs+JG*Y_AM?xejFesQ0%}qjEEqR?R;_h8Vun8AU{h24Ie?x zT`Q{$w$n+JZN1#s^)kI2 zXJ3NyMH2%v{#UC#v&w>sT5xymt?>+RahC^R>+1z`X^NvVD*ftv=&P2LkFvsMM(?Y{a1GsHiBw(Sbq;WJj>@ zebgRC3aM|vyK{1MJOTf&hxOZ^p@Em}1kf1P*7XZGD(fnQuF-{yG&OV{#<;K6T52c6VCTub@JSF zYMJa_l(f{O5l-jBW&C-$e~e=gwL{N|=AcwbJKxI*ie6f>gD)ashA|A=#;$J?mTE6;0`b+j^qu)`e+2_^@3-DzzrvQ!rgSPQ~E>VY&tEDrm60 zK-ybxwyCRcx(~XS!8lv^v}!CDT3x9X58CLKt%Jf7Lh9k_Vx?Tb{@3M^}%ubP{2 z<)#pNT3$)GX?0|J=(A{d&_UM>ONK-SY_bykpTwR&FTFVA3%9fz_CRw4ndeWLx;_}Z5S1La~A{>usEv$qW*B=a;@!BmI znhauzErN`;ZlV3TH(B9$d=omsY~frz(!)PT3CTYv0KcaErA%~-Fcr|0!dwe2E#``m zp)+m4=qmHSQ**Mk&E@$^^! z!O>?(GNG+){_P2->l#$*sp861j~+c*k%a=DiB(k8aKP@|Ra~L(Yn(}ev+^lVqxFv% zQ@mOr1}JHxuBY@a-Qj+L1VnKutagzG=!;DU?Oz(g9gHN=t!YbjVz^7GwO((QRlEx>L@LGecIiSh zYEF`zz92u|25YrH7-e?GQ%YS2QLy0;n?SM}6m5QSJmz5f?uud}56W+1rBs9uf?xzS&k#gsjEpSq z9v$9$C5_?9U$mj%e)A}meB(KqKkI4j+`N?RmYwB9R^ve70~eH0-{M^)OgIC!UA}PnDyb;m@yagFhi} z+KjT*hV*VujgDrI$KB1T^gZ*e<%3WR1xKjn7=y%N_`5d`)4n{B;+~#5hgB>L!|ord zK_h0sZnF4i1Sa?YgHdKBarQJ)m&m;(85-hAI8UEoAxPU>FL?J8Nd=O%`;*1y9^Z+; zKlT{$DRtZZmBf{pfVq0x*S|4RbufBjmsY;Nkvbj*y~9cys^)DTEv>s!R8-_X4+~n7Be{#s2nC3+X$_*Y%>KdC?1tp*+l677nS z+mqMC@jF9jzmr8!?}?lWIq#3+N!=j)RnKfMyAUluy4GPi+Ir`!ORCZ@J1)6n$H(4{ z-MR13%Qd5Uv6eCoEB8;^t51>4vy1m_TTDKkw!#n)2jx=A<8uhA;sGp5M2Tr#EDy>k zo(H6?D%(21(C}k%!Wex6Q49mY@TF0?nn5+l2Z4c06X;0gu*Fpd&FiQd6XiYgKQJ*5 zrkc9@1#~wS=Bg4%_Y&Ln?==5uBIR}bAm7Jym!eSh;JP1Dh+$d;8Dn8}@-i3p1@xhAahx`pL+SI|DnpUoo0Lsgu_qsSgmom~`%*>_WDtY#e;!A;>%j2Ke=jHx`Ocaj+47kth9$)_X=;&ZV z5Si=iQ=K$&uc*$_stGlH!$FWpCYZa2+|i3^GFqoh3WyT)lW9rLHyq+jdSX3QZz%9a zgEbkS`h`n;I&;GX>{DUpE#3FwwPwD*%|jTD5IKbm3T_?5S-gK70@VqVluuV4_KIoDs}DFdipJ!xi4nlXp9M- zYL5t2R4zSD?;7fzyoO7p6c=thB<7^;W5VLeebu2y)mk9 z2B2~}j#kK7BO+*O{u3nGajo4O(Q~aVT)F}RUfdzKgdrQh>EdjYBC>SBqH2>+cv_kY z0u5f6+phV6N)jy~eQHalFvJvd3U!dnv!!6nfy4jvkhIbA=;5Y68QB-&D!_o)t`HCzI-r~hTSGQaLaLjjRs9Hg(QDb1jsD0m&XKcH=g@EuTOnUz#GH2Czy^TXo< zv48|jEdl%iw{DP8<1j%dWL)J0ilZJ7kAV{+bV#R9Eki*O2ngsTq^v<14_1!L|IT?@ z@#0B$g}xaa69doKqLY)=sA73cjkLAPEn1Mk&;W@A6!}0b=RD9wp_pPocls~h!Vt!} z?<{46d;VYK_gz=$SrLRe8W825bggT|hDi&k)>C?Ph7ShO0h0G&II# z{iho+%EV)JN@S&P>@0Jx=JXQ6Dt6KZ*Ld6XoaK6%Z?}S`K1)i-pO^$i-2D`irF+)r z35V!s@y+?O>e*NIONj3;xf`4lUXJnKHa-hwuNvy-Jh@-TQROZ|7gzh7cWl7fQ`m#@CY7R_<-|PZNtyF_LHa1p zEX_qmx%2P=;XENq5Mx0rrjL-?YQ{h{F7v@u(5L~R2&w`204krQCCqE+1?~IcAOf{8 z{2TsiXlMw8H#{cL0K3S@pq6`FEYb zJ#ocR^7^GWn?A+iXq?aE5E_3=T|F4Y_G_AdyAV|Jf<$kQb=0U!omKkhp%UI$3<`I z<$CL@)*`fjZlJL2#|TtFJ>b>e&{ux zy%{VSTgtxE!kdc22fDboH7Mv@+3$WAz|c;GB&FId)FI5{4H>%b z0X`JIV6ENG>$0@1@BhvI*GBCJyo-Nv0gx*xF7l=9b8;D}!Y}{C%%TeU=7-R5;xZA1 zvY_1NuPvj@t054EoBIs9XnNm67)OIl2VCr6IEp%=Kv+3C>T$4U2vO*=$e#hwG656_ zTCx0HTm(~4G(glYjYlCoKw+I+d~_FL$N+bMP3!)B5xx#A$YG+u*(mtiU5tX^Yy|eN zk3AI}^j7{M{?`^BqAOEoy$}}ID`eS-xx-Irv*>yC-jeIhsg*-@A^{(QeODSHQr~g9 zQbXE7z1y^;%B2LA9zPXdXli<4%vFDkg6%38i&Zv-BUt+OI`@9b<8%XN)l7NG>37PH z4K>IkOCK5gQZ>FoQ9ghjHsL2R73a(cOxh0ZQxbbvISfqT3nTy0=I-4{D?)S2!j&XO z>vz{#vhlrpdN!GJ!(*j*;F0;C{knn>78G2Y{;C;#2o)rz7mr^I8wNNEkf~J9 z-`9_y??K8NqzVeA+st@) zJYfZ^ALsJd3hHj)J-S}Eu&|E2M32wO$Wew2GhspoX`|t?{_Oj?_UBd1m+XSNoL9f^ z+oo=YzLFf$Hr1UG7)r=9zers^+y*|@z#$w5ssL5q_Tcha*?tCwTD!n7hQz#Fh--z* zs#M>{#|NH+r)O==jVvM1>qR*UKer`m7=IIR#V?WxXW>zg$u{eWgL1LsGtGwM@S|a( zT*2{(kzaP}bZqqlJYWPaLKxA#;fS$jAe6?jUUR_trP>M2chE*=pXzVW1B6fH%w0!Z zV`qnni9Je22rhDW8@#}V2bf{R;3!D4@aF_jb{r;1hJtnvd=ddN1a>8mcryo6+)MGT zq=2tSxjf3l%PR#GRajFiZPJX4II<=tCLl!zo)%;xgEcSHPbkkM(@GRxQZ7LBt^?Z? zJD?)3*AJ4Ll|C;PNEMp~%8|57)SSw`S2Yswz8gC;z^r{gx2`~r>JK@#kW_L?!kZ2Q zPtBMHlLE}TAkEjsmBd#$?aU~ZCx3Tht~b4pQen30l6zNMJ~#1B#AiabzVHb}>dujO z%qQhX?B$J9AU37}>Zo#+^x%WZbKB?!33#K&{|GJgU3+OAlbE~(aHRpc1zDIfM! zy+>OWu*IDW@sSDi4E`t5$OK0NZT!dfG@zzkh(`P-5%iV z@xpgGK0byDzYZ1%=vQGT)8M&p1j8_ZpQrl!w?GnV>iH`Rir%1T0CGJWzC-40h0}yq z)m;dVWtmEmjKg85C<&Y26u^{mYCFe|sueZ3kEIfcai!0%pqlM>%faObRTeqP=?6Dj zLcZLTDprx=k-r~vii1{Z%#(ghTbpam89R)y)iu*A4a$-B%W_Ufvvw)Y%X=>amhFVn z9$2K+_4OvxQmly~*v+t&SW`gftUTHOedX$IP&BNXq2|@ICwW_wjwM+TKpS8^`-R>s z0$UJ^(QD9PfW{*0Vb;2l147mRhs~w393nT?w*!m0 z9!YzcQ`vRK^QIm@v(espv0E2ZIbL5ZzS@vcv$m4U#_~Qad|Q8k--fnSC=?KMquw%9L~cWR}OJR@G|duE!CgV`ce)KH;mV5r_5payaM;u4R6Pcc=qAcH`>vn_C?{`( z;84_*JgIfqCYOm;lJ*G}ix8ks%G-CuP*1qULg}?5yGqk%5Lz~#DeM?mT~vi$_l8ds zdG*_$^s;+ZkrXZz^&$oS2eZ+4uFnfJXJhG2U{!&ZcVMn3K|r3hOt#Tx99@OaKDX3G zS^32?d)G{G7BE?z=YO0@G2O0>)msD5qafm!JDiPzxy8lVXr>PW@?@_H>mBJ$$cE~5 z?G}ExQl48As;gtxrEL^*??0YE8l#OkiG0MDA20%ct*ZriO(18XigWU0Uoc!Aa5sZ! z*a6V#tu|cJAEJNKBruq8kn)V4ahXBo;C#A>^XS5fx({0|Dr+@~_{)zS*JGsJRQK1j z8yONV3imr31=mzO8PPUB-L zbcfSm?zwcVZZ1K8_4Ib$x97nP_Se9GD7r$2DL0g&Dv;_*VKd6D-ySh>ZXrLpj!GG4 z`0m<97&AYf?B}Y^YNu7#tM4%x!_{kaKsb3P&xHSP^puj4KRU#fZ=gG#L8z1cwV$J_ zY-7#=xH_dd99&k^Io1lME(E6Gg((TeqTykauLi;~-maV9j*6SKnP(&Zp?gDCdS969 zUJP|5>y;3KZ|R#VoSU+qcAC%MzX7j4<$8RkpHSfnrt6MC2r0*d=8T38qXd za{WFs8@=7#nKE#PYgOx1p0zQYOEd65DgZX4dLW`FJTE54{oOg%c+g-O@yN-S_P)Oh zJBW<~!Lr;BOvd41RvhHdP(mvL&zmW!Saz-J&qy#|Sh$L&;!`F(9k{&48SyK-eI=&{ z`$wT!n;XYM7#UZBG4bMCY{7knb(!`(jVro?P5CCrnTy==b!Cfq6HS>YXl6% z{Vvp8p{jxqM%7vg_Z1St=9~CsZjf5Prlv!FcWX@61ijh} zcvcD!Ha|~}j%NH7WE7Cc$c@d_%6EBmt{^DfzNoBOR^!%H)W<#ngh<*R|4s+cl8EQaqs9yFv_Q1lw|p+(Nzj*;=7m@AiWI;##lJuAd{*lTO@pvT?gBS;i$q85VW;pWsgcd<56i^8ky5i&H5O;@R%`RB;a0QLgLZj($(y zAxpx{GXI-sWrD?k_6$r>Opayf?0^HMt^uiqm@+1KR1@*tWzpfx-I6v2)qHOnM+`9Z zi+->?Y%V>CE+H#C|9CUxwyxcY!mZoiFnD`@a8`l8x!U?;gHRzAODR_44ax` zLCBesuzq+BDv9J&^aV5IWK$t6@1 zxO%P9t%xZ;ZSnEoSuaA?x}|tVF#=f3P6);8tE=yPI8MlaJ`U08ve*LDmyP)`x6b!q zY=EEMxO)KwCF>#EVdE#A-yUQirFC+fuOf4AkVF^AW0t;0T{7I&L`>}1$+mGasaYSU6KrA*Z z*F7qwH50V4Mu!r%>hgfwzH6kZq+?bhycLc<6*6^;@smbzVV&Jk50c27=6;h4?YvJ| zXxSj0yN*mvu;*eXu}wb{=ECI^DWO#$;$}8xn$gsDjYXNQJfH-qVm;whQjz4cg`7t+Y>(lZDf{D zu5P0n8+yiUwA@eW`H;#rwci+d9BJWCxz{u0-nFeAI@AoVjAi}2mnq=S^snL0FifJ za3lAlL26BWbCDRTrUd_`t%lU_;{(oX6xQlSXVek#e5#4O9bKHyW+d^^8rI7S>u-28b8+E-MSD>X(rmkvcWrO>wpHWma z0h>_)STH6x(KH`J1~(29%6H#qy#D#)E?35Da?Fk-{%j92-U*sMVYO54kmzYWe(}yW zEObRvX_0j!NtwJ@7Vw@T7lSvU%R>>8w>KrYykAZYo^cYk6Y{Y$3L@-P=2raE7MY~$eNb+qGqT_y;`vL=4G+8CZHBT|aFUe9X_l=Y21elg~QL6hqgh%Y^PX^C$gX*+gjuBL(tgQ&K-)#!Sy9o!BI`oCv3 zGi4w87Boi5kmmB_w@!X-B`g?_CYFHnHDILb>O@S|KwE(B4{%hNBLQS!bj-!U0rP!n zuy05rIaDppXK`L9=hZ_U=y>0AYN-1ltE zZ}Krdo?FPRSTn1vaN|4Y891uZ3@1${;zz|R%5{It$L~7%s{1IfYp9s5yVja63JiKZixkgi(bMR*F))x=22s}fqg``HsC z+iE0lvaTD-zbo+f+<6ZTWDP*uQc@Q%rlauU0h%amq)1f4I9U8ZpHukZ!%t`%Q5r}H zCJXdPN=!tpWk_!Pkexlqje$*&-d1EgVO-g5z$ zfS%iA+e>D}>Tv!SXhI z&dP~`nsVTyJ*$dtudF{GmK((@{f(@ks;u^A4`viH1tZu8S7+E{bdT#-kV0J~wd%#+ zxKgsgEpmUL5_01pohVIYmB0@g&be%jwC~w>X=RljJ=y_vEeKGkEBe=NjhXC1%ZLhg z1Kbq`_kOt%fN{7Iz>o;yZwyt~ja2jPARL zcD8rhg#>ZX1@r7~4XQYA3Ew_!!M*>O&rMd5ApESPa?qeSf9|E^judX`8cL;#&#oYG@G+n2@e$bK`SnE1y>*+0ZdZ=Pq1S$OBjPRmF z?LZxz?w9XkAGO- zGBpq%XQS@4eQ!Np$x&G+!Fzeqk0l`emOs<%O;&I0AH3AA?~*g2vKI9B+GttAS06n- z_UzJz!zU}C{b>Q)%*PmQ$|^f+Yo!BJ1k;03*LhhQus>2h$WX-72BM;%#SJzLO$zEk zZB>tZc|W>&L{-e#x%UGnu3rxzviSSRWNA{-`OeCofdeGC(jOSgkbukFoMXY4A6H;> zrXzR{#Bmis2!wYQ-~!0_GAgs~f{_!Dvf15|fc(cnf}@r!Li*L0nx5$1`;Q;*?F8TE zwRvOVvRu(IMLb_$ZKQiOb^81d&G-*TMK4^IvAa{cPy)MP$7 zk=WuN(9;%F;BR;H`K^~(3VDGUW*^7%q|EwKFXuotT5s7s!TBJebfJB88|x}Lxjcur zYPIyJJ;^Ie5k1`Ef`T_aK^_?je{8BbD0+kE(-$^t+&UHCgwR^;|2zX zm_C8OW};9PtI~%SZ3OrRb@%msFSV2de(ho1((TRqA-GE6QF)4|f?tHHjzNuvW-J`n zFr*~BDkjLz9`aCGNoi%WauvR=y%!Zz;y6|efJ)obM7UYIi9+K)zzwlA6+)r~mW@K$aemPxkSDK`~gL>#x*1l!33NKD&Sw2h4U!pZoS&^O0 z$o_TZGm4=~cSi2zkIU(h%H&5nMMZY-;OV;v8Sz(SImAEQNy4&|HkP$ zFK?V6f|M#18H`gUY-B)%cP6WO?;g`bX?YdCutYMs{P3^co^}DCh#Z;&<}rJQf@oD0 zzw7ts%L9n7WU95nK1>!xwSa{R!c8j6^!2AG2%b~+jkgn1EYK7HmDuN!GIy0;sz?B!t>1> z{2YjEk+f(=*gu9C5)>Q>9T@OIOYc1pc}L4i%3T445zMo4bHkQ4B*A|I)S?3!!LdT% zEfeKbea8BrBac;yMC82wCgz=Z<&=l*yNNWf0+=)m898I~BNqgs4*VCm}$=u%QSZCck+yN=}I?7@JSmL-$ zAVBMbwTH_DZTc=MrwYs|!M5Qg$qv};YH7O|8YUF4FN8n%+u6wDBxB8iz8(g_-f&(+ zlt7O8B{A>PQj$ zEitZFGbWyU&WvM43aBZVcPzt0gJB6OgaOn%;5zt@L<@Q)X!%D>WIG}65tzcnbRwEM zIv*UpV0={bZK6+C&t!n`o|E^y?@2K!&nD%yR~#mNmev6!iOwQ6zXh=E&;T?@NDu`o zm<$O#ImpXw7skkj;1u940QZvs6CHXX_snn0Ndk66kxV2YS^0M$m@%t-b~9)F8i444 z*?K5W%#*CccEQ+C04RwiNE|rcUQ{(J|V-T>yrlv$an6HYz_7ZJ$D)_Po}1?Z;n zm-^?sczAgB)Bm8m#u6E5vWtnVUAqyCN=lh$Uw=%N$+EXD z#;O@uo_kCNK}`HN$$9U41%4jxiAG6xWcf`?kC0PndXJc>1lJVeCK(;~V0vu71$^JZ z=FLB<2f^Ver|$F?Sg4R|3?3nD0-rW&S6LNX)Nx0TSJ29^p0?2Urrs&dz&4cvJo$M( z+v-f=ZoG3B&+8k#?R^yAfjI%94cGxLP+A6p8zNi}@K`|4{cLTV-|ay;3?xAA4{ZX} z=f5T&1|$BW6Jg!+ya;V^dJSNUt!YDN_xY#6eLeNIHYO;|U(ck*#vTCK1X36j6&2fF z;mLN&5lfI)z};8G@*k*i?`;%nOnc{N6k)Ns$@76=!Ux2p?YagZctctgyS%^an9a~M zpX*d}K9-K=VVigl5?C(Q_vay8U-(%Y(Oc$Mx?7)8D$Gb_9${El= z#6WdfWj~Ms!|U4o4=RU->Ef4CQUf}IW>rIi2sccUZ0#2BIg_YUmu9^ zB0WNj*Ua zef1h)9vQHHH*@YMXC8*kbVOi6!i>o^k<&S2gOt0N&I69uri#{5teO5?#aM45#VNR@ zr9eqn0kS1Qi#QXRwIGDNN&Y+81KViz_r`krK|b#ZlN^o8@DYjpHL@;H%+a8-G0Prf zYw+!1r%2xuda-~nV7;%88bwSwYrZ{gl$YbN=Z-0r|K{-_!U~`naQApcCpws?eN9$L zR~N2d@Lh+qnu~`=67C=v_2Du>rMiD|25Sqh+1jcpKl#5`iAdDm4RUDxsKhh;;1e5P z#4^h*IuE|u*qA)JIy%K&^1z#_Gt}4!xPSkjTHd00QD9aeYr3(t0Cu zC2KtdeIHe71mb&`)sb-592pgD6Gr^zMKbDLW?=A}a;`pGv zMD05o@)pZFQTK{rKm8mqIII)E{5n{P$xl zTApEDo7EX)<{o%dW};c&gV0n~wVQTsh?LUjujcc>Sc>Fz-XFLSGh0A8z?Lwm$lxO% z2t|%c)E-=+Z;8t^X1@|vq_OhU_t>N0b(v+e4BdVeLUPfai9W4Wc2FBqLG0in6G{Su#`z_p)R<~VUD?{G} zZ4dW%^pwC2e49X-ysHpU{L|Iq+&yNCGkmI4L8tjC%U@?vfok%?$w#FLOwQT+j&VgzJ8y1L*8M^J^zj&BPgggyrXcmZ3xlSnEn>ACWJZA9b256C8yWZy7 zP*xaIjv5eXBmL2Be9*Gc+l>4({U5^~SDNd;fQs^gE9mz3A6A}RuHdMYNgK>yHV&QL z3>A)vfBTkv;=r@|pWjUsemCF(*6am}5H-G~BgG70AA0EE;0bbQFW|mRi#<TE)n-bZ|=;J|dlC_d|CQL!Je zC;Tz_C$RUkO?%1;#jPhZ{T5}XRmU7At}n>ega~q9kb1H4XQCN9T(8nj9zE|;U~mmW zoah?6Yq_QV4({iYAo+xAUiBCw#8>SWUpE!SSj9ZuzhgH}d6C16W zD1is~kQ=p}s)(8g)e0p$BJ!8^RBLPfL$aO< za71>P;*Kihc7K$~DLNOUImv(UO3Yqk(bkmXL9y+_FqwPWl*CNnQ11ELX~&E;!+&;% z(LuKM{tE=br^Jc0i}WRAzLBA!av=C0@8gzo@+Ju+a8KWOkS7aa>V%A<<<{o?=9VIz zrv!EWBBuB5$>0QFN$Az-CM3mpbYpYX(%iUZ!DjilOo?_yHX-P6FoEIn6gq!^%qsxd zh3b#W+#AkHq}Bh?$LVFgZMQ>9FK(yaHJlRB%HOPPkVZpu?_bje#W{;E*%QXSGCnrDzDZjzS%odNW`92m)un%6KQfiDr zfJ{UXvaYa~YO?vQv>6N`7S<6s-_nJFuB0+aPDS<7E3nP78@v3#My&W*4B0OotKaW@ zICHfMw4Uo{`PC}C#E4fIZ1O09NjF@+VM+5`h&X_f&FV!&MW1iYwZKdRID>}3{e>WQk8U zrjHs=Ht=U8N%gr~f-rMWm~muvc(H7Y3ycm%Mw(c3RYx`jEPTdkG}z6I+UQkxg)XNs zT-qf|A9S5wG}!%m!~8JYS@?(Xt&&?ti7a0bWU3WiH|o1;`&hYny7!{YCWN^?v)i!Q zMBy9{Wc+G$pKa=W0bmDF*o?hpWjxLVsYX=+*5uoiIIK&i2v%dw5<}L6*mPU5y=%W>;-5~q=~f)1r<(G_aNiKmB>THnm2g@N-=0Bj53?myo7*G; zZjAp8`u|W^xK_8>Sdg2$0v-jZbTRsIY(VWnBK&D3<0bH$fWeeQFX6eBB9MV%b^@y= zE;W@%^d$}xl2LrS{W4Td@RkGc3~uGyp!GZ7yf}Y_>MZ#{NqQ`M`O}G-T&_mDmiWn& zO=LnEDJJd%Bu{qIHn~{ViG$#HmjhYZdM|IzC(d`mR-`;#Q%=P7Q5_Oy4pvGJ|7=x- z;(Z3!OYUSR=zz0uZ<1(3*2=ns3`V53F zLzqke=nljfy%IAY*eBqT74D_!Pznt&G^p0r*3v?>?bsm26bAh`G?2bfzLtK3utf=p zGicQRny!O{0Iy!Js0wE4G4_B~#Y6%X zrBxcFLj)v5TDrTtOA!PCrKA-kB}KXg1tg^#>F%zx_W1tKIewY(8fQlLzMuP9>z45Aw;EkOUb8L77?zZ7W-JM<6QwE|MREI2I3gyWpd5Bg7hc861LnTEXPR@L{&L=j|)!v)J45C`EAa(=p@HOk-97R z_E!rdGk578u9-rsTXj_~wcgST<9kxV5uC-H-D}=SgL~a|T${{Q>w|4c!h)=^yvdEH zNRI5$r?(jtFmtauzo45*i+?AEu;^g3?vI4kBz-paeQ#n{Fl#uGKIhUhf5v%@nr|*A zhm8yEFBT<`KTDzTk^AXD6+*?>BaZ({MeLipidwK@+|a8yLBmkPxZeXd^w#Q>!$Ri& z-Mj?HO{z#=W>P-LxloDv)%`1~IWUAYRN!3Uamk%57{~y?8LYt6LQW|xEunx(UxPgc zaKw9bS+Ms0chNvPAIPR)5bH^N_!-#Fx$&Ix9bM~^&3L!^r1aA-zGTw^@M2|3OYI7h zmylfv+SX%t_)TF&C|CTsKu%+?g6VD;8`I2w(KA6?rgt@Nfq#}hm#=7B>1}^&aqOv# zueSBdlD^#*JiXXjst_Qjk$7>N?(Iy%uQwlKH#7EH$odGye}p=j9WWCFWFqVECX!M! z;u(-awT2})9@spwYjhiY1n3r^wKW6ZkmnsoGC_<8)C8M!G$6E$8&$M4vfHvszVuJHaJEI$Srgl9e?Cp}X3@+AH$s`gDwqv9#qB_%r@ z_tL4rR{(ZuOgiZDg8g%4qS78V9dvOxWqfc?mjlWSu*S|hmrKlLwvm(CAn!=AUI^dU zjhCm)FM0?V-j@Cf>73H)x|A^SQ*Mwqy^nF%$cELSKo`r*y??Y^PDA^_-TO7_%fnHD zw<(k%n;tUl2*g+cK1SP1YvYMJS zY9GJ2WSk9h(rt<+2ks}_G5bAm>a8AQvomMF8CP0}RViA?nN98snv$iGV7FC!VT1;KcfLjC21l&qFr)PURBdFQl|>IBR2f2^`D{jMPel$O zSsW_R1lZZx2{4=7C&6oSa&iK7uBS*=Rw#NU5pHW{ehj|y@?&q%DZY`-p@MR^-lDpDBT{oMXvo@yf` z2bKv$+6_E4^+4^xW%~QqFYt!|7~6}3jSb55k7SFpn1-Vu385CYm(xAkFm78dNS zI^YdbZBVlp9)ziG0G|L`Vlw#cq2b)X7}z|po1a5d;T;SV5E#Ly(^9B(qtp;9xY1a_ zyvLl6Hu(>!cuN|le}T~R8!BA_mHtyR-wE$tu)n@ZcIk3fQf@3uN;1U)nhRTwX#f<&?hkf>@lurnFRxktaK4HId#J}gwgNX-v? z`{zGc0oqcuka{{hKSIsljXORMpv>^&O>hR7uMOsLFLr&coIZo2;RAV70I32d0a3Sv z+mzJQU#F2uZ-1-<9t*g?eturw@0po~Ta(q$y!5N5=hcP`;Q#Q-f0z znSlXaiy#D8E(k`i3XLX+jf*=3)OL7q@Z{3(WMFCk6fU991GI2#DQMlCK)VYv{{9oV z7Qy%ohaDg)_&(^(MIrGN1=BayD3K(uXYU-!PRxtvaX3$iuWI0Wa<(*N+iCJ&6Ihs)d zfZz1(&3JZ0oYuTSq+z_31|*k99yCjvMVJFHzSf;w>cfp6zB|^$Q zWhc8ZABi>%HC|(zka-b1bpyN0O03i{5P`KXIpyn4NuDdMVbh&k#VMH7GM3gK~43nv; zN)$~sR{I9De{J-Q6U)8cn!((6ccm>tL6cYa&;FY(M`ko?3LH5%(v-&EFQM_YwfR{A z!yJ!W9X47hsL->lMf@)K=}droJD3Y2ylWAimZpfR>@0p&xAf84LX1oFeR=#0w0Lz? z*+^KHib^>J#F`AU73%e9=Q66AR*K1Q(w8Q&P5ygwqljO%KlvdJ7(2|tCPy8Ftr6%H z{xOMKZeH+G5KNn?cmhrXw73r$>-|0>rISA41d*e~ez%*J zp1%4a&>u?qxcTLv9jbF*L&SV>t!-YuB+kCO_UN1WZTf%n2bwrN6|CS=xY{@@v2(d6 zd(s_;)E$H`PY77A~hnkCm~7KrR7`ZGmuittwiol5EOy7|P8mgMr95Z!(c90?QQD z9X^yT29DkA9emwMp{d3Cz*?6FRbdt`CL;Sr2yC*9j)@UR&AoHeYz36~6k^mfdwWif z_aF`Ji@2p_o(X^A;{_`-rHqA?k`m?&u-(taD0Ott{Ul~b;K-%WK z=uS=J>7kjQy7T4LpM{rFy0=-53l3O9whDr2V*-Q{Osamf#>w%Fi@7bLIdEMzR` zD~Uke)Yu1T^i%aUD5UIg`*qiM;TK^C8WN)xxmm6+`IsfE?Q7pS1~>NSfW;to)N^s< zTjKQSn_V15t_W#%6;(Zsgj{$~#&}$*=|KkTc>CK%?cp&=-Md)ElNrty36|`sSx@Ve zyz>n77z5+Z5*SH%6xkn@*t)leSgd`>kdBdD6f;q|zMH+sg!+)IKBkX;gIDuL$&c2~ zGe@lsb<>EfX?9jFR<+6@6jo`}LK61fsj|4YV>zQ^&k@b36c><+E`AS5wuZ-Gi1fxc zTo5sDv>X*LAgQk+#O>k)KPnJtKAqCSWI%rGkyi0KpOYd*Pza;CPsmrDuKtN~w|5!A zvjZ9)pC7VUKeX}Qzx7AiR-S;}vY0#Nl%a!()P;j5cx?Iv?<>b%UYFlXC+333*8P;z zV$YC;RHc4>40w~NbmOPM{zp=xBQz9b3fYvhl0{fR59SaU-UGJ{O^N`$mBXu=adilB zL*40luGz?0@Uz!$ONX6VaS9N9 zq+vkGW{d)JZoXCfn}SbMWqWldD7kz8Bt$g-KX`K|`{upElMW*`x}4`r=24dE&w@m^ z!*C85&`JY$Jkr+%u_N=cVlaQ=s?TQZ5N#IH^wi{+GI@VLMRQ6CE<)9ay*U)&tLZM` zVJbQtM*8}5ePzZID?JBS^|B!kB}v(rD*w{peBS?n zdW7q*Cv|@_>L@SzbgV+{R{x*U-JR|0px$10`#c2IKG*L+mL%bip4()xAxoHuv{wpPj-HMO#ThaCKn@$Q+#~-!V*;`x*nHtx~J5;U)d&HOL;h z0r|L#3&~d!Fm%L){fT|s_ty@btQ?-<-5rHljS{H5)O-nRb>m7r`VVRTJsvc0PxTl= z+#hU0-XJbYP5WgJ(-&lj3d6)kN7uYsy|M%fRecZ}!34m6)UkUnBX%+2ul9Vgo`bXu z^4Y5PhBTmNCEBsL9p%eJ1(NS*MkeIvMb=zs} z(f7L02NR`4PFx?$234JGs@9zo7mTBCsXtU*BNDJMzA0?ui(ZJ`32Mjs*|pV0@ev{{ zB^J5*XQDo-Pd|bhcO=$YmrH=d)pGQ6tS5NqyXIY9-ijT9No~D1cutmqy);?TXdvNjb zlP$T*jc*E=Adj*XGnMEgq|@U5X5y-^Ohy;|E4qZ!qQK@JhKv5M{mDjue~N>RvG*9D zbd3#Uc#S#_a4O3)td)`CJ9H*M9>;DPWNl5?3*o|UmOY3Sr!n@P$&$9Vc;QFBhi3)m z@7RP}O}~5p8xTV1K~`S`W2pz2+JH+0wx#R$Z#HJ;Q`nWDmd6!_dLiM8zE(AP*?{S9 zy-UqA=Isv4=QqS#Xd(-yUy5XYXZ#{VPlf6^QlY6hWrj{hTqIX=bXDD|(Zy%8`(jK* zL%{0r>JZQN9^P;nX`^@dyGMZFjX53t^KHNt6TJg0*ALPI}x>}ATu{NGlS-qdf53~KnXPg z=>Y48ULd2Hb<-e+|0P?P;Zuoul-GgT1lhlPeVjz(L-d5x43e!b$q1Fcu!AG(@BJfh z|L&^Ex0xIzW0uRVFH^)e0==h=3*-ydh?X}FIE1p%gisQQyLOu@a;xcFyf*1_@iqtZ zi1En}aG6y6`)|Cxk1V5EQXlm51BZB_PNiZQ^+u-hSpv^hS>OVlHTsvXyX{ExobmwC zStvtX1f~G!gcxuwtSojvjNT1pAGG?7mt!=f_DIrNX}d5eyj!EqkjjPM1?m4g%=}P* zx(Uz?uwD#Tp7V!Zh^#$&IVvg4Q$SOp$mSvNuh0<$VT&~U4hCRg1Sk|X0g$S!0vfNP z(hq_Z=u<3(u^JS6kg9J!n5zQH5in>kfht7i?X9_{IZLrRqTS?Mg{Mm{KNF_Z9*OQh zy0TI_FI+cIasZzl_b6x3lHHKcMi8wu?lt8(RQcfF$m%w&S^J4HCnzyJ7=_L z>BIUbz)q^LHF4TlM4*K7xxx+U^N!NLM9tJ1t0r|JGV-i@PP_SXub8&Hjei-X5>e5l zGim+SzeU&(u!hwZV5riven?au(o0bC_aUp`z?9)(u$rWyzOq#}U@{mK+=#_1I{fwr zvrhQFE&G5jr=a3@5PNLC`_1tCL5dGZ*$(F7H1wF05Ni*k>T@Dht<88_EN68hFSVng zfyQ=>e?u}IGImqg2gt4r562dI^4M)7kror4g|hhpePu+J)#4)5qJpGLsJyHU6A)Z? zct3)ofd%+@-?Ia_xP3+R6%`eM(*>cCoV@%r(S4XkI;qhKFS5!b`k+VgGH4)56JO@x z=<~uq-h-}BbbCa<>#z&gp3+;gCGj5njI=NKYnYZNq>{RKC(FN%YUFZV?OVIUT`+aM zC)}HMIavK!C#z2IN{)`n@K86}HST+G7?`m(^oY)x3(nMsywDt^FyB(J@oaVe&{W~lw*K2f%Ki;nrLHDH0Wx6%E(5-JCp*YD zZLnC7g3B5cpt7w2SYnfp8>pAq_S2ex?n-4Xo_JuP3+JrbsNf8 zJD3CAiUm>x9lX$~anFu6<%2P zj3yq$FA51n?^#HZ6{oOj0KMwyWG(opylGW;l|kN9Hkc%k%Ro>*)$__lG% z+|A9UuCg_v_P3#Xg*9TEU2l8L|F~uEE?~mJ>9hk4w5Z`t~T#-D|5_O(Nn$ z6l2o=4UOWz!PiOO=6AyZ8t>fPju4@Y_1^BgefIT->Y!8MteQm;EPyB$F0sRk1Ri|b#~zRU8XH0K2Tcrs#zU0dB;YsOctwVy zKaO@>Fmh}`Gpb4W8F#-!i8^bu_EHmlZG<7Q!+kv`UA3#Ew(m;s=Z8 z*%n%$m{?h;YoXll=E6$SBdF;^+|{VE+c(|x+?bHqS9E|Rz0Vh>Ng#L&Sjie-)cdwvpn~a3yCMEA%#rFAK7)9uS>w(-)iibvE_tEz~RD*lQ#pM9* za!3kYXIA}ka(R`Qcq_e^oRV_=_#Dt2#FJ$98!!;K(UakGR!Vx*mWpTaUX+<3y!h^t zL9ZxQzje8$OGDy|BwLVD0b z-WunQyG>tP{M0}33;xDc&F6(Tg-44gjSK-g7NFq9+6t&m#hn(7Y^=nCV1 z{QM~&C9x>W3{~ZHxb0EYtYeFyea&nRKt{CyT1-3gC;IK#7eqogy6=9a4=nfY4;Xr@ zg7xp}AwgU{MvVad4nVvvB77GiYK7O`%2Wk7hv1H}@Bf5;=?J$IWP(Dl`7UTpV90<7 z-v)49z#agaT40WPdV9gKW(GM;V9)=Ehap;Fi8JR5xu@TZp`fdqa>=UrUq4W_pSl~7JdtFPhgwCVsml` zszlJP<$#`8j21+^7R#kbur4&dRH5t2 zP#fbKXMc)pQ{KC$w`BMJz0d*3xIq#SokPo$NGWbn>h zh7jzLum$b(kk~Gtg^g>D$BMqj9p8M13Ezswt>f=QLeB2TUH{B`Gt<9631L~x{AY56N}eLd@3E@`+}*^(gB`%30XTk z4qwpF%1~^~G^S%jqvcN!b~9X5DDvEWQPB}YG5O@WEL=HPP+_wuufsrukoCB z^zHhHBR$I!Q+h&4=xDO@#$A8~;6`BYNA{M&(pJXai+F^wA+Y4WH7L4=- z1I#O1i@0ySd@HLtVbPcb?w)}WQkb7`lAZY}DKSMy!sac=F?ILchD;ZDGSIA7pZPu- zca%!S#r~=B`1cyxzQof2mz?|e({eT@e~<9S3)2;b*y~-Y3AC=|OljJol0>|0LudrY z_JFnMGXUvsNHnE=U5to{n%=N6wx1EBN_1RO#r|S~{(u1}K;&#QbO-{F^BWnM%Fj2N9@LOGWfEci=NAZOWyClZ`6_0 z2W>Xu{BU^yKS)#DaPF$YdKfTH&az%0%J;$%bfx%&%f{%c|MkR&Mxn;CG6~DVA3w6- zR=i2$R6XL|^O{vubf)Qdcj2nX(fahF#ysb}!-SEbLHow^4@3Hu?0#Ay@#(RIPAmj` zO?>VJg4!2+6!#2bq(_m)dlQcY*1tY~tMN9hrKguo=%q!by!s%A&fas@DXn|_gK-9o z6}jc>`UCTq8&qJ+VH91pVI z_U}K8pv{chXn7UP%VvDnNk7d|GF}#~6jz9N0sCtY^;yUm9{b0-qlf@oJ`;W?(FC7mMd8jCN#_LrM)=b*Dq*jMxNP~H8PQ;o-!rL=uIuU?C?(l9h;s8h zS5qtRKuM~y9y&6R?65xTsHriY+rV@SbhkXJ1;}VVBKC2oE_V1!C~vL%rWYL4WFBh_ zzIM4$XDg*jvMF!_twB_GQyo%ah}^jOX3@+H+2Dt+%d-1%xL=e~jcJt?&kJMp6CS51 z`{Qb^voWr$z4P886(iud&sg&<*ZKYZxX2f`<-HZP_tWiOipWd`3sJx`%H-ghj&NzS{J%;di#6-^-V zXQY#SsawqpJLEYQ1VG{}HG)vV>9j8sq4|=NgBrJ~w2KQE*Stu7a50LU?X;#r(9-Ik zCnI|87NG8&KOA`yNs|hy%gT+3%1XeCUkX+phL720yJrUm z)=$ll03;I((CT}PXdEvHpo<-olX|9(7D~}n7%2YK%@^bVtCIWzFa>8L|Eljw;7m{u z8+ao(Z6hWf6X#OEt;Rm}Y4RT->XC8S(1NIEneu?Ap1I=MVX+g8%a(s~z!*X-0m(Y= z-zT4UvdZJ&;5a)0O9|dU_3j=%q)|Sf<6qz%NfqI&FNG ze6)RC3UN(EMMr=pU2ObOx}oO;C7ya3I9lOlHtU8Vu;(%2$ zb=*)MTy!?RclaV7Qer`C0M!wRDIXLtwaSWKQ zPm)t_0tJhxOb(Y1hkce;;+J)C11Mx4di+`p{P?jgg8W(4;de-efUlRwT4bj2`X@9m zxoiyXMsPOpJ7hQ*rM+mHF7=em%6qwB`Wu6QuUCA_qqmqq+% zeEltEGJ^~77`V8~LHh}}D}~ePqIzASVH3>JP+EYBvQy)_4#+TLBQ{Lgi1Y|icmwGb zBh(TXfc)hsB+;*$pW=7@T)twW3_i1_*_VI7B5W-_b!dHS=Z3Xb3}INx8RhM^fc}#R zhu0bn;+5t3?Ev%4E1sRD8f`FGCY5Kr7(m zU6L8v<4H4?G5vmrQbd`e&7Nz^O81WNSi6tEl2%M6g`+5>RG{F}itmC)ODY)P2nkt9 zNmSoldL-7>h8+?YlqL>wSA8dShF9^>H}ypv+}z8FFqa}uIIneMGamQyxiQCsM0b(S+d;w`BbkK6>)-Ek94HRot3seVl z)V?JsgVZlXTLIOe>!GXlNMUB`^3syq>NpP<*Lwn}9KG0#?}p;w19_cg4&9<#yl)9& zV`54jnu9<91x}~kNj#dz4joN_I}Y0o^`K|o_jnA5Dj+{oci%n!IQ9vhj$!zYj?3DM z+M~@WH`>&)a(t@$QplQbU?dkl-zW!99Q?LHod})mRiM>juthxJFbVzHhr+)msDHU5 z?8ObSq?2Y7Z){;$sywI(O)0oCYj=vjuhw~4b0f~Fk$!%=xTbhcp+8Mwsz5fPcgiq) zlC!qt3kGVV_Zo)9Fvqo1aeTd5nY&l(LecBZ>~Q?*`!ZrntU_Y*`zOBtUU>-E-a$GY>83!sDVGFl zr4v5SBKOoRc0oZz*vLL}JaM*%J+v)yp6HrB(MJ3>)dGzfGKPfjjOMbYzqf8dN+Lu!F zw_oDphU1dnsran-wBL4$J}ek>d3tO`ODRltw*qrNDMi32r|rG>71E8VUMBQk897sR zv7JXv^6kUk@8h4Q7qr)nZG@2-E|U7!HWy@cg(bw zt-z`)m0-tSfq$FXvc#yZn3WW`kep_OX9=~Wa-gnzBSq`FpfhG*h-fX6DWvXb+?u-z zL~)io@L!W(`eKr({&f7eo#9mLU}vGpTAVP)rUACae_yf$p|4R~%@z)~eVRBX7-

;{OSqgZ9@@$Pi{kfPCJpu~d@S4c8i1D&H_=byLx>8WkTtgOKMQtI!TS>+ET9b4-Wpq2 zxP*FLpu9{Nb+^)TKx-Xqnkr2ZK}A+&`OrO2#1QAD06~L;e3GE+opaT2^(j{&JtS6X zH(7KyjZy7moM2K)P-74gNu_us`UjmKc+^5E-V0*1tVFB!mDlFv4T%|)WnFdg`WWSH zVfgWYIe{LuwZACY93GnfS%`=+c4L*k(0N4#& z9T5mp^|gI#y^d^+2v^~x{$LfIN*n{7yQC(%^l?3eI`tk*-_{tXzF6dX4XfIuvybLk_^LuXdGpBna=e=Ep}+A7$$&|;EvhlpKq z&Hhar*R$OfU&G|-Svh(0-qN_wldJz^m}|Im0P4SCU}j=cn9w4QzhbK;8T1qoH__=J zoXp1755Y@e2F0wY&8n)ZoSYne4r)zyAyJSfUx0HIdRyv!pdiw(tNbzh8IM-n7xYB9 zaP0caS!#m>f~T)m+-&wO9&QfH+sTv|v*kBNr)ZHAI8Vcu%r95Mvw(K6gKNT);u0Ln{B(I+D9TFcDkbtA_Act+Uf?DxbjV(SRDMNH2 z^kEA#W>#6=ECqEWp$q7BcEInX6T0mERPaekOXDc++dM#i4zBTXax- zmQzmYZJWMRLcz8NSZFR!_V2NJAr^4`q2>n1xTOWUx!zaL>{n1tSIq$K-_iB=;iQFey?P^*Z4E26kTnZRnL z`J#WIQ5liXP^s$06mR=k@i9+$zsep$U^bzraG7g?^P6j}q#x-4L#u0RA5^MLZ041Y zAZ4HZgmJjSe)R=5Sb1DCtc+0Kfz}U&^~J>nvMv(!+6B0bw_pth@JlF*J$}#W8ygQ9 zfUDKg%F1!JdL6jnY71a(z`H;GrN1A1$pkeRQqv8t*3Ql!moifYp4xqHJcM^Qd;=LC zXl7svL8q?)!wT3t3DL7Yesl(Q3HS{pEdq_-*UZ5qPnY}QgChWUw>b!J0)I>>t%qR; zWHFTQ$QL63YRy#8Negzjo+78=IlL9X{PM)!(5?RhMLNXkmnkp1y=z7pZ{DhrgTXXY zSbMsu)JcY~D|W^Wrm4U|*&h#2LkIpZ8hM&99%C^e0Kt}D`3@d2vhI8isBjuv=Vx=2~B*UU9tO2ci7z0mu3as0;eo zT99GM6^!B0h#o<4&B4Z&EmjKkcUD%%*jQCo799ga4$!KEm0*Vkqk)`^j8U_fGf>4^ zRsyBbF)<%urGt?1^z<}9*iz#ro$uRUg?c_v8@l_D*5FMn2$(!|5M<3X&b%FuDYpW)mP>@fL=0OsPyNq;>-AT!t$3bwfsf~DMhk7`uwPx^m(H!= zH;U{seeiU0z4|Pfk?Pe6;|nkeqfCN@AiIx}-ayDyiZt$kD+Q;`iRs!6YMukC2v4(g zx7NVX0ftL_Ir}SQJxvw=Kr)K#-s4YUq~Om5{U98+LNG5yL|A&7!LS0iNDv`-Sb(@9 zkw%vi0+t<67$^+bbnre8JKVgz^iXJggt!geM^;hWktm^vB+wFw{Bg>wR*~ z?wdF1a*dljvXjA`4I~d}$(R@zMAG0nqXi4erI~33_NT#$rcx(UbU4>^w>_Zu3=E8fEit8UN+x;!^>l5eH`AS z!g2be()NB=#D3O0@>f3yM|hIoS_)@j0tS@`$Kd2w@Ebd7?&Yb9e`VVR)~P-It9`FJ zu%E{S&e(b|$r;SuP}Rcb02u;kjsPju25^Z75w7BH0WbV|8dzKa^`K3>PY8bf8rtE` zH@dUmz3T|`(WgZm;x0hs0uRB(6@}Xl!2b=y*HnoMP6?mOA;(p?m3NArHYYhBJsO6! zYOD*UCBHXiPvtFm1<2(1cv2mw$IyD`Si!Z+HbDVx{}*B}3~L?M9Z){Lyso3;U&eqk zOT|PH$~1YG_k%L7o>B(JW{7K~4<`zu6s`Ix+?aM0?qZ`#7v>%wqC{QSWP!o!#dy50 zlia_spsl(qvZ5qSae1p4$W3bNNr3^_C?7{DdM@{uV{G~^Zk^3GPhXV2p?FS(`ZOBy z%vc@%E8Sej|1FQNyFvI7J}{bKA%dQF$54YpDo^sd4P81jr#AP2*<|2i5E4ovbb-4dAtBMV*V!p8ML1i1eAy8O6|2mC zX-UZwLFl`jx$Ejd^BcEebGqiq)`;4m=LOX=PamGc5$^ zip|6&xhN#_SmN?e$Fk>`)cV$G;C`U%cQ?i4da@rf=bic%Lj})d*eYc1wWUYYzc4HJ z-0ZnOnmoSIS8ez*oyP}JjMUXX!m88QD69i-g85dY$&&J@P61Ng;Jky$v~F%|TND-b z2(sD0`$3gIJY0b41WPo~GhoQyTwWfleQMZ6gG>q2(<2w_jboto;1)v482ShJfy}gZ z^9(E>`5&g1$YZ&gKf2S`WL==LmM&j}Z-qjv)8%(c;)Gs)C3V^NKK1v{rr!>BOOlo* zI2*}Yv|cDqzLG$O(EsPtPF%=}I6XcFi}VtBcghP3GnxK}w2_v6r4$# zPU0=qeGTR`CGczkA@6^>Ehzoa+8>Ub)GEScgs@ZIq z#`0PBH3wMRvG^Kdw@700e&FLYRjr?$_+)+&fZRX6NG?+!P{BR{pH6BwPp2j{cIOuO zuOVUA?&{U+S~97}ucMTWtwXM&4#+OhGPQMd0KUTuU2@@* zm#4t*?Czcp{pVnZj--_U%RVKvZh~~?i8{y}a1Y_tNDp_~Vdx7u&Upa@`;#ssCkOZO z1@LjSFAmg!{3$81myziP;eZxGX}pHdp6$Th0R`kf$eTh!UO;=o?6;jfp~e966Z|@l z9zCK!v-bUQWSCbs7uu9{@(q+tQ&X-marA&jq0kMpd7h`l=z40R3419jkE`iQGCRW2 z|0HiGGC#VhTDT!}Orv;yOq^1DwGnSJ#Cq%A2ub>c_xJEH50e%VH9^FLw(5#D5ahi2 zORk_BKbU}4H3Im2wPlbd1!q&SO~&JH`QRD$q5G~rxVIl7ExE5^fvP_+XlnN*dt@v~ ziNHurO_Ct?-8-4|G_mJ8emAZL-FBu6KJ4`YaBalWFzSJ@xlXc)wD}E2Mno7_n4#3b zW@I&#qHS!vy}oX{Rh69BhybvaKjjdS4Ju{hrEq(f z^XvY+Jl)yc66e^JVgd^ss>M#km(b=TEFuH@-ZQDL8RRyxMa_)MlN`+&evnLB(*Csr zJi7wp>v+NOpVYLli@iFAWLMA_f zyAn@Z&YvHR>8UIO+h}ow$3SgJc^?a!09zO@hi zG5RDtLz6=O7>8$BOYuBKux9S#OUXiKnbU=zGqxAB!f9?;nDgy$g#mcxE?hgf%Cbhx z_fAevHFK(~wZ?T@=Y`Iv>B@me^#%L}^)B9%gtf%W^3DE6?_oZ;FTczBf9Lh1nJS96qyID8|*T zym<8=%81gu){a2zs~Mlmipy#y7R5ZZu^T-j2~(0jou2zd{@>&9 zSX^cce}_`#ax=OCbT*3Skbz*I{270JLm;pCEnOxxx^i=CHQZAe;@E7n8PTh;{YW)L zB!!+PP3>4Vf^SFmc=fe4lFNe2Vz><}*TvtBdna#+e z`^#_GBN=*BptEY0Nq_Ss^~yT>t+VMHPhtHU$fN|2>n`jVm&*UX*Jq#Hs)S*t6C2Ta zt-X{)yqq%~r(ChWH^YHBJ4&zN&cwZ#p?G$-dkV5vv>#vQ#+ixJRuR883{p1C!EJmO zan;gqgo7{u1;K1aeR!*_uoUfbOh2pHg6`9;B)r<$`_3-Uo)4I(7Y;bw7$xN4LVtLL z(*nYFdFWzUY(=e^Q7X9ynllRDnm&8+qGgFLoQN}rUg?;=D)f(v*I`PqK;oZ~m3RZz z^9e=*Grz>#l!4x9jjyF|%emWFS~SFY*tp#|zQB<0Q?&nVD$RS-KC7(`pH>fvj4Dvo_K~x+qy%z;vrGl;H&_(PD+2abUdlP+4eRe`z$b)(Bisx4c#e;D?kb>h5 zAFWmL@hVT?B#~?ov!`gFf@W3{`CxE7MJZ>7dJ=&?$IAM^>G&R9<`CgP{1FM|(~@qp zmQk@K5#1j@I7p9^$sxl!zBboTb@ubWL5Lx@1bnm)E|+KvBD1@@}V}v;!kQ-;x`aK=hSpP25pc=ffOWu?@5z4%AZYXiu8t> zxBBfrpE*RZb@&>ZObbwKrPNr`HCZy6voh5~U9X~pJT_v42l>PW+SUDeZSQkfyZ)VH z-hZZ=Z?0l1Fq=Uq8>oqTvs3*N)t>gGM&q9F)lAlsXZ9=|)v6gBO7#A*XX~>r?~BnI zlqjIzX?8;7dbYw+jxPLE{N+b2m1JV3Wj0U7mnoJ1#|zND!roiY8jkKjUcLei5=Z5m zt7^uXCI4MD*AsipgrZkIWo>N@ft9Luz>OlE!oS-PWEk{J2!U?$_s^3l+#Bvc*v)wu z+QE!*fE+H8u7t;@pyQgfC_>Y{^LR2Z1c);lPhbH3kGGC*K&i7j$QzSaB~h2pTV6Yc zvDs-!+D`Ozt7?4FT~Xje+(o~ANhvd}8Vu22-}ZzXwG91?ueXxq&}CYh84ht5uMH?) z-7Cpcz-i@%b$9RFS%cm-yc`@{T$jLW(E9FnsH6(0B=h7QqwYct0YLj`5B3-dI=Zan z^gyfZsZDsx-YjqdSLhmKHGnTb2!Dczi;gSW5Xwe5T{C9UpPoM&`gHNilx>brBlGxo ztV~*>e-24jE9p!>m{{pz7SrEGy|!J;zu&6leup2+i|l`kcOg1E+;*^1z^1IEqGFk> zgiR+OMZ?L?4h+;X5G~r|dBCti`DUynpylQtUYmrJihyT(g zr7=S>dkA?2?RR{A7eNi~g5GD)VMyPu;;ePcmdy1mo+rtb^Le#~k&!Yo-x6_$$M0mF z#Rs$j9d#1SR7Tfiv-7d|F#J#l;>Rm@s}xZcd4Cyiq_UHMyLw^}^RZt`wG4A}+!MF+ZM1wj<73{wLex&pT?^dxTX!6+J0H-yWBDY~kyrno0=MWcv|J`pJ zlGV^GtG_EK8f-rRGKKm14--xO*8h6}H$@O{R~1b!FZH6 ziHVVpB;Z$6;2#2%hbj+OFTPm} zVsO!Z?>kRka`AiMudE z0Vx9Z6|k^@Jrlf#F91>k&jIuXlqF+dzhcvolatpueuw*70PiIMmISze=q*!hfeMC8 zSUoxZ^+8k^R9c&0h=J~aYy%|?NV1x0YP(m)j+C^}Fv=ff9EPSC6Bsk0m|e%aOP5<+eE_vAz-?qJ0vtLZIHB;}08<*& z0N`1HGzny#fKh;VbwbNo0P^sMaOVKl$G@Eis}N|!nIILz=m*pbuEHF-h-^WBST(@* zLLY>Vg~er1U07WmNBH%p@{Pz9#<=)+Y6-uy2*G)7UlHwsF=S>NNsq%r1xuHp!?e@I z*)h~iAln+4A8t&5rW_s`st?qkukRUT%)Wzh9NY#l-mx$+CMG8V14HO|+D4@vUCa6M zQ+Q>q?D56s7F|dQW&tC{hcm0MXEt9oR0g|Vx>~Wvq?MIw?&avYK6@I!_WdOFs*WW0 zlGi>l3!>&Jiy`0Y!{I{k5+zQWukdi|$FWw@AG?Acd$9Y=|CEy7!fgSDNdg5BnSw^Q z+NhXNom|b(?vc(F7WXUFHkVh$rLgDFQ&LC9q^GMyfE?ae_aBbJhj10VJO`qMP_RLd z2R&`=33!#_JqW#a;qv7U0tYjkA@K+s3~3C;w33537gGQ!IeXbJJ>8;RnTkK?88-4||F`TnFM84VBHeme)eosQe zl$iz}tg|otz=Q!e3f@oq<3rPL7kBqO)QY+~!7@oxZpfoXrzq@uw#Q`d6z=ue+Tc9r z)QS^Ne)EDk2#gw8&CO@9%yGP~Vz}qJItUGc;`91I2?yIz{?h^r%fVRmtshcVm>6U= zBlVFs_mvxWZ=AgEAJ+;Q9m|Rp*AmPs_g0Ece*ey|n#)%J>v>d7$!>Si^GUwvc!hq% z5hgT>m0VYwodc{N42MJ+GrB*&44moAZ`D@eZ&- zRMbIaDvX8(GE#ij^L_EAQ{X;R!d_o!lMu6TEFWx07)ti6BYiECfZID~K>{Ha+~k#t zhR}`P!JvOMt4(=P4M%)~9BKmZP_Di`Qq2?rHojA^t0X}q3NQwP$uPvR0j9Z|u(6#T z8&}QePoE&WfxO2|OnI>ULxB!X8AustiRa@gC@arZ+iI$+enF1rr?Y%ICXjWCfDXvg z4KGJ0urPEOiW)K zPQc!87w*ybL7nNS>V>&0E&t~2J0Uw8T1f}{#$^j98jVF0XG!rv)!O!M`&8zf|MX<9 zf#k=HRm1J$_q1Lw)wjvJ`f?Vp`6X=dLX-znzk$73_*tO5^rXDGN}ft<&9afJd@qdn zoEVK&eLO60ga=1}Fv7OS`fO!I!KBF&*%+5lLrv{=3Y}s7JHAE@618_?x*H6wB+1-g zvL)vft?1FVgJ>gP2mA()yYI+V62OOs_K&F7wK2-b=JX(>FUwV7V z;Jp^Nv5{OmkRBVE~z~>{ksQ))-S0sADOL-2Xb++F52~2dn_+^;qK-W%yZSmiN z|G$6#2yk#fGKfhD#cf)=gX|ss`7@9xvOkxbV5J9g5L7s3Loj=4=H%vf4-Ih&3#UAi zSSABOp!wot6KtlxOUhf>YAFAPpp~=<5Zox$ujWuqLTRJYOxM(wKMXHR79XlVO6?|2 z46pY@O%9-Cf8krDN3nh=K7(eB`9H^Lhf592Q!cebaAPKhB24xAh;1w3m-rLP)AG4%f}}YUQ|7A23dG; zCTW99{D7N{%?>~kgl{v*bCB-}AIX$@^V+!4?HEo5+R&J4YVyK@;zPi~PtuM|uQIFn zKu`(#-Uva&1y;YCH*Y$^Er;MTOnIa#qcJlCeJkJ%o8P~G_di}qgg0G*;|gqMsvZtCk1VBw!`72f%C=!WS~gEQ18v^luL&c~Zl-Kn!m$Di=}!@Ux3 zYqp&^X5DSaHTXNZL{xiciUJ9$e6Uk$7OG8P}xab0}A zJfUNPMcUD?|E&Lk*0o_Fmx~gOggG6Hlc5v{~{~Ch+bQlPdC4Yj{KVvTm{3_opjs3bA$LJPisGv3fG?dq_}xMEV_7AY1hxfz)Rcx z8p^%JXd$PH|AbnEOg#~0%k1jLMsefn?DVu3u=4;ZkOp0j{V+Np=_ivz1Bq_l{0n{D zabKxH8UQeTR~<8$(cv9wZ?O0keebWPpNC#feN8=3)=uAnaq$Y$CdU8+j z&(x-0CgxK&XweBcmo3ZR8$PeTA6V>_Pj%!|OQ)fm@BWTlDQoiIr<19-v4!t$Hi~jI z@`hZ42h)DvJW5=q!S8syt@#o6Gwx>)()}(^KiHHw^b-WRakIYBx6E@Zc;pNEtENid z5f*8lmeP_{%6%HWN2hz5*}O}dLcA8fnX>mXj&WfNCUFOLqxi{D9aap;9K~it1ZIXG z0nI|qTLYCI+;l#Ue+LIYmnRUKpa6g^vVU`+cSBrU+-?wC5B;xnwd=gC(BHAAv2#?^ z&)HLC{Q45634N&ho7!Lt1L zdOem2vIoz4f8yjbZM+G%_z})kh};3}w4h1DGO&3XWrY|0znbDl9rLQq$>S3Rz5b-u zzUylq=o*$`i>y`{M#~emuvv7>{u_D)0V?j`Ga(3QKw4ky$d>l>{O39E-NU?((%$Oy z#!2rBbM&-`%EggDu}0F8eE2mq!T}@9$>!>}ex^r#Hh=pCMa(L-ByhhOct42y*(fmH zKA z6~Sn%g2x8g_wzu=``rj!rj}7RzT2=!eQ0D!!(}hb9hobBA3133VX)s{{Z#a6tWzx)N4FWADL#SbE7|!BaM0Vy%lTu|DJBw=-!Q`GTYpj28X>{a@3uC&&>5Z8#oby&9^McDu2^MZN z6g^_Y3=`J?q(!j9pWxfdf|Y&N*v3U~uF%A4P#GrGOwEH>;&fk(67$cAvZwgzR!0wb z%e1cPIR@u>gfpv4rhSz#1g;tOuqU)yCBZ$(P=+> zIid9Y^Bpnu*N|%&bt(>u_CMb=&5p|T2yA4gr0}(|2f8NyC*tq^J_#P?^=8S7H#m35t zEZ)uC$uZQk#RAI&;Y?V6z@*ti$$TX^isDSQg! zKcURYd!tNdZ9t!sw3l+vRK9wG!gUrND?vmcABZvF9Ez$%K`ksJXED{bkHd3V8fc^#gVfbrs(w|?*HNIJ;1Si+)PJnso0^q11=k(Aft?}n3Oz0^_QJXTe*7okDR_S{ zFU%ZmJCxkf4<0o9pl(u+Ir5MV!n?JwHJHpGJjF{n;mF7cuc&5DH&f70SQkN9+-d25 zE3|N2W#!t*nproBhm-r+Nhik47uh^N(?xshj~_8kbX-)(`hD_vW76fBiPv9F@|@j7 zJeneO0Z)Eb`Dux=)&&y(9+9ZXdvPxM@TAF9RCeeaD zE9meaLfTwe^#^?y!bPGUJ$g;43c`edbHoMU3Iv7-$>DA2uV6m8h~PwQ3MlSM-~Z4j zt^s}Jz}f&l{MUc4i3vvP;zdXzTW?Dw?edzFge<9NA0>nC%6`U&jKb`xTKSLN*DQy( zeY_5lRjL}hP4c+#Gk^OEuxs$iudVlG1> zk?@7emY@tbJ>bg~VGFEUyTVwBpASE*S6<#CeGtOsD3caCd(JlVXG~RC*4$JPvToQH zdsJ15i@I~fUUR4E{$2hm=G*jb@KX-xO@_fJcN0Wq@H zX+Ca&^K{G0A@6D1Smt{%xuaB)eS0L5{hv26#m;x}-@7FJ0nJ24)i?2q*=CiFq(`r( zTwzKQIv_sqg4D4PcZ@PQ?05F#!KMVWp=)|46*<>!JH3}bU>6Xibm*>}-?}W)_cf{9 z4^Zj1Cm-Lhw_6Q-pA7dtw+(!nY$4Fsl>dCgga)Ufz8)h?&@k+J&zJ{P0>FT;j}I%K z+*s9yZKw288&FFw0r*0;OQA!1jcYidB3Nx7srp{T91kp)v{3X@IJD>M@9u;h19uR> z#wE+Xo}OZeg+T9bprhLlGicVsUm$pyf@B=pc9;?YbxRm#0{M{eKR+SB+IKw1Q}u|( z97ozQOUu86(BIUy#M8mhum!mpS#7HhJo4)YpiU&DcPM@B7G8%$0&#RV-JDdB0t zws)70Gmywf^V6Iabl;_a(&l+ws9EOtN|D$NKV31{)fjT%uk{Vp8N1f_MM!-%yJ}q* zyODPJ*EcOkknInY&x&NM!VJppHwPf@hAuc}EtV4XzfK*l&5|2_!Z0EFVBdKN*k@Z~ z7Db%unZ;LT&VP9Epv<^&Zz99z4#GD*b^<+uz4dF()oZuXS*LkUn8>0yl&wtMMDYNd zpWQtPywM*&5qJSeZq}{JY-FT`5t0y4=gSbu;IjB3R>T$)H15yT3iwXJHj5!fWEYno zX#GzsRs)FzEC|Kf{6fWAIf`beYe*scu>N2NK^%>?g~dl?7cJo3ux{QH!nVhIW(eOD z{jwCagFq{Ne@~%VK4l|iTjqtpuBC-(g{c4tn6W_Qw$`XjmqCd&OPFmoY)HhL0)5=r z-24Ltxw&}{?q3qJiZ09wm$ z-^iR)uvHQ>zp)mA1d&E@8{<`AcV#oSv~+Y_MBRz;CZpfK_oB*2X7B7m3ltmBPVK)i z5e*d#(lk_IQ}KD<^X$tGK-0hb;atSULjUEB1-Kclf|_ zd$ZM*_XR4h4ZP&pSZQP-jUFucII45>Eaz=@JP(RH-!rT>NnC~~bK5U>>EM_;(HnEy zTS>e1783S4^T~VlE);g#rqHz;61hXI;d3X}=k)G*dO{>0-C0*I!`C^Rs4{2z%=#@( zoFmN%ddwkbZMDt_AKr21zTf?RnHYcML8)(C`2P9eEiAF?SMPf39#Fe;h~wr?==(aa z{ADVrMB>PF>GXaco;YM0T>d-$6c%Hw1}N;>V59WGE}ELUgRBFOklNbfhk)h5ZLqfJ z$NGACIYHG4Q63CVLLt`Zn(*IF;ehM;{B|fS|3zE63fcU64PIr>vH!$+^dv+|5`YGB z!~kVus?Pm{1d#p)^bT;+_V7_t*%W{aq#S9nLk8}}FE z#v{8HPf97o#b9iX`!5ay2!?`V4|-oB&OurEld|tQD?Af6Ha4|4Hy_BkjYbuI@f;#~ zRs93P-&Wx5dT#xSgN>~P?qr~=9)O6wcHmh9YD?hWBP~wzoWaG z(6H{6G&_QDvp1nkP*|boCjKTIgyfhNv#lG7;|%j@m$_cZMX>i-$jMcR`tppX3RTf0 zG0s`$FRW#!XKu<2J*4ER&-k4(mqqd;NZ2syi~s-;qRI6N%2|@N@jji1>NE%xk3;zc8+4X)|?MX*N81^aaM%VoQ?Twd;9OQe|hSyp$BOq@tqSAcn*@{0pHN z7!w>cY=O=?5DZf&19uJf9~xf7k`90;5wJW6ERmSwhbEx#XkGp6M~~{x@sUK z!N~YN?gd9mL`BFf)ySZL#3-cDoH1p{uYUZs=LOG%$AMzcA|i)NHPxkfCNt7~ba=%M z>1Itz_ipzs|0td2Alr}WyuJU^E!9HkM6Blh_qTlh?y2n;Q1#)pVI|5F>tf7&3PSF4KLgsw}=IBRu5dYanHY z8IqXFEFiGo_IV(6afN>!Of}SKN;)=*br2UhS z!7+xf;+ez?DTiQU;9vvm1uz=h3ve%d5mImyKNoc+{CvsX%p~F_!Dj+4?MW>9*jJ^c z?dB~Zk#%)-I2GXTM=5R!GjAhe*-Sz~1=QAdcXWI~iX^gfMTSMRZ1-3fX4ntK1t;up z?;a@lZX{_mrhcX-#*wE{fkDM4D&fc$`)#$H%ZJ_53+L{3ko{3&tbdYok|}00|b5amT?kIyi`N$E1t%Z`q