From 9142f21fc6e03b6c63cee8628d82f70c24032dad Mon Sep 17 00:00:00 2001 From: stevemacenski <stevenmacenski@gmail.com> Date: Tue, 17 Sep 2019 12:19:17 -0700 Subject: [PATCH] remove nav2_dynamic_parameters --- nav2_dynamic_params/CMakeLists.txt | 76 --- nav2_dynamic_params/README.md | 122 ----- nav2_dynamic_params/doc/dynamicparams.svg | 1 - .../dynamic_params_client.hpp | 432 ------------------ .../dynamic_params_validator.hpp | 89 ---- nav2_dynamic_params/package.xml | 31 -- .../src/dynamic_params_validator.cpp | 167 ------- .../src/example_dynamic_params_client.cpp | 100 ---- .../src/example_dynamic_params_validator.cpp | 115 ----- nav2_dynamic_params/test/CMakeLists.txt | 37 -- .../test/dynamic_params_test.launch.py | 53 --- .../test/test_dynamic_params_client.cpp | 204 --------- .../test/test_dynamic_params_helper.cpp | 44 -- .../test/test_dynamic_params_validator.cpp | 198 -------- 14 files changed, 1669 deletions(-) delete mode 100755 nav2_dynamic_params/CMakeLists.txt delete mode 100644 nav2_dynamic_params/README.md delete mode 100644 nav2_dynamic_params/doc/dynamicparams.svg delete mode 100644 nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_client.hpp delete mode 100644 nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_validator.hpp delete mode 100644 nav2_dynamic_params/package.xml delete mode 100644 nav2_dynamic_params/src/dynamic_params_validator.cpp delete mode 100644 nav2_dynamic_params/src/example_dynamic_params_client.cpp delete mode 100644 nav2_dynamic_params/src/example_dynamic_params_validator.cpp delete mode 100755 nav2_dynamic_params/test/CMakeLists.txt delete mode 100755 nav2_dynamic_params/test/dynamic_params_test.launch.py delete mode 100755 nav2_dynamic_params/test/test_dynamic_params_client.cpp delete mode 100755 nav2_dynamic_params/test/test_dynamic_params_helper.cpp delete mode 100755 nav2_dynamic_params/test/test_dynamic_params_validator.cpp diff --git a/nav2_dynamic_params/CMakeLists.txt b/nav2_dynamic_params/CMakeLists.txt deleted file mode 100755 index 8a7f930c..00000000 --- a/nav2_dynamic_params/CMakeLists.txt +++ /dev/null @@ -1,76 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(nav2_dynamic_params) - -find_package(ament_cmake REQUIRED) -find_package(nav2_common REQUIRED) -find_package(rclcpp REQUIRED) -find_package(rclcpp_lifecycle REQUIRED) -find_package(nav2_util REQUIRED) - -nav2_package() - -include_directories( - include -) - -set(dependencies - rclcpp - rclcpp_lifecycle - nav2_util -) - -add_library(nav2_dynamic_params SHARED - src/dynamic_params_validator.cpp -) - -ament_target_dependencies(nav2_dynamic_params - ${dependencies} -) - -add_executable(example_nav2_dynamic_params_validator - src/example_dynamic_params_validator.cpp -) - -ament_target_dependencies(example_nav2_dynamic_params_validator - ${dependencies} -) - -target_link_libraries(example_nav2_dynamic_params_validator - nav2_dynamic_params -) - -add_executable(example_nav2_dynamic_params_client - src/example_dynamic_params_client.cpp -) - -ament_target_dependencies(example_nav2_dynamic_params_client - ${dependencies} -) - -target_link_libraries(example_nav2_dynamic_params_client - nav2_dynamic_params -) - -install(TARGETS nav2_dynamic_params example_nav2_dynamic_params_validator example_nav2_dynamic_params_client - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION lib/${PROJECT_NAME} -) - -install(DIRECTORY include/ - DESTINATION include/ -) - -if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - ament_lint_auto_find_test_dependencies() - - find_package(ament_cmake_pytest REQUIRED) - find_package(ament_cmake_gtest REQUIRED) - add_subdirectory(test) -endif() - -ament_export_include_directories(include) -ament_export_libraries(nav2_dynamic_params) - -ament_package() diff --git a/nav2_dynamic_params/README.md b/nav2_dynamic_params/README.md deleted file mode 100644 index 7d244e04..00000000 --- a/nav2_dynamic_params/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Dynamic Params - -The nav2_dynamic_params package implements a class for the validation of dynamic ROS2 parameters as well as a class which enables tracking and convenient access to dynamic parameters. This package was motivated by the lack of -[DynamicReconfigure](https://github.com/ros/dynamic_reconfigure) in ROS2, which while not ported, remains an important tool for the -handling of dynamic parameters during run-time. Thus, using current ROS2-supported parameter features, this package aims to fill -the gap in functionality. - -## ROS2 Parameters - -In ROS2, rather than on a parameter server, parameters are hosted on the nodes themselves. Nodes may get and set their own -parameters via the node interface or may create a parameter client to any remote node hosting parameters. By default, any client to -a node may get and set parameters to that node. A node, however, may register a callback for parameter change requests and choose -to accept or deny such requests based on arbitrary criteria. In this vain, nodes are responsible for the validation of their own -parameters. Parameter clients, on the other hand, may register a callback to parameter events from a remote node. Thus, all -parameters could be considered by default to be dynamic in ROS2 as anyone can get or set them and receive callbacks. - -## Dynamic Params Overview - -Two classes are implemented to support and extend the functionality of ROS2 parameters: DynamicParamsValidator and -DynamicParamsClient - -### DynamicParamsValidator -- validates parameters against type (using rclcpp::ParameterType) -- validates parameters against specified upper/lower bounds -- allows for providing custom user validation callback -- option to add parameters as static and reject changes -- optional to reject all new parameters - -### DynamicParamsClient -- adds parameters from any node to be tracked -- registers internal callback to filter events and pass to user-defined callback -- keeps cached map of dynamic parameter changes -- provides interface function calls to access latest parameter change or default value within callback - -## Example Code -Below is an example of using the DynamicParamsValidator: -```C++ - -auto node = rclcpp::Node::make_shared("example_dynamic_params_validator"); - -// Create DynamicParamsValidator given node, rejecting new parameters -auto param_validator = new nav2_dynamic_params::DynamicParamsValidator(node, true); - -// Add Parameters to Validator -param_validator->add_param("foo", rclcpp::ParameterType::PARAMETER_DOUBLE); -param_validator->add_param("bar", rclcpp::ParameterType::PARAMETER_INTEGER, {0, 10}); - -// Set Parameters on node -node->set_parameters({rclcpp::Parameter("foo", 2.0), rclcpp::Parameter("bar", 3)}); - -// Make "foo" a static parameter -param_validator->add_static_params({"foo"}); -``` -In the code sample above, the node will be able to validate parameters "foo" and "bar" from requests that violate their -respective type and upper and lower bounds, whilst rejecting new parameters to be added. If a paremeter has already been set, -either within code or from launch, setting the parameter as static prevents future changes. - -For clients of parameters that exist on nodes, whether themselves, or remote, they can use the DynamicParamsClient as below: - -```C++ - -auto node = rclcpp::Node::make_shared("example_dynamic_params_client"); - -// Create DynamicReconfigureClient -dynamic_params_client = new nav2_dynamic_params::DynamicParamsClient(node); - -// Add parameters by node. Note that there are different ways to add parameters -// The namespace must be provided, if applicable -dynamic_params_client->add_parameters("example_node_A", {"foo"}); - -// Add all existing parameter on node. If node is not available for service, -// then none of its parameters will be registered -dynamic_params_client->add_parameters_on_node("example_node_B"); - -// If a parameter is specified but not currently set or node is unavailable, -// it will be registered as PARAMETER_NOT_SET. -dynamic_params_client->add_parameters("some_namespace", "example_node_C", {"baz", "bar"}); - -// without node path, adding only parameters will grab parameters from member node -dynamic_params_client->add_parameters({"foobar", "foobaz"}); - -// Create a callback for parameter events -std::function<void()> callback = [this]() -> void - { - // Check if a parameter is part of the latest event - if (dynamic_params_client->is_in_event("example_node_B", "bar")) { - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params_client"), - "'example_node_B/bar' is in this event!"); - } - - double foo; - dynamic_params_client->get_event_param("example_node_A", "foo", foo); - - int bar_B; - dynamic_params_client->get_event_param_or("example_node_B", "bar", bar_B, 2); - - int bar_C; - dynamic_params_client->get_event_param_or("some_namespace/example_node_C", "bar", bar_C, 3); - - std::string baz; - dynamic_params_client->get_event_param_or("some_namespace", "example_node_C", - "baz", baz, std::string("default")); - - // Parameter not set on node - double foobar; - dynamic_params_client->get_event_param_or("foobar", foobar, 5.5); - - int foobaz; - dynamic_params_client->get_event_param_or("foobaz", foobaz, 25); - }; - -// Set user callback in DynamicParamsClient, to be invoked if a tracked parameter is found in the incoming event -// By default, the callback will be invoked immediately with an empty event -dynamic_params_client->set_callback(callback); -``` - -Here, the DynamicParamsClient is created to listen for parameter events from several nodes. When parameters are added by namespace and node name, the DynamicParamsClient initializes the current values off the nodes, creates a subscription to that namespace's parameter events topic, and registers an internal callback. If nodes are unavailable or a parameter is not yet set, the parameters are still registered in the cached parameter map as PARAMETER_NOT_SET. The utility of the map of cached parameters is to faciliate access to these dynamic parameters at any time, where even if the parameter of interest is not part of the latest event, one may receive its current value or use a provided default if unavailable. The user-defined callback is applied whenever an incoming parameter event matches a parameter currently stored in the cached map. With parameter event messages now containing a fully qualified path to the host node of the event, duplicate parameters names may be tracked across different nodes regardless of namespace. - -## Future Plans / TODO -- Validate parameters set at launch. Currently, launched parameters are set on the node before the validation callback is created -- Set validation types and bounds at launch time via file (within YAML?) -- Provide GUI for dynamic parameters diff --git a/nav2_dynamic_params/doc/dynamicparams.svg b/nav2_dynamic_params/doc/dynamicparams.svg deleted file mode 100644 index e2ace048..00000000 --- a/nav2_dynamic_params/doc/dynamicparams.svg +++ /dev/null @@ -1 +0,0 @@ -<svg version="1.1" viewBox="0.0 0.0 591.2965879265092 280.9396325459318" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><clipPath id="p.0"><path d="m0 0l591.2966 0l0 280.93964l-591.2966 0l0 -280.93964z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l591.2966 0l0 280.93964l-591.2966 0z" fill-rule="evenodd"/><path fill="#cfe2f3" d="m124.14698 35.058002l0 0c0 -7.175497 5.816887 -12.992386 12.9923935 -12.992386l178.45618 0c3.4457703 0 6.750458 1.3688374 9.186981 3.8053818c2.436554 2.4365444 3.8053894 5.741209 3.8053894 9.187004l0 51.967983c0 7.175499 -5.8168945 12.992386 -12.992371 12.992386l-178.45618 0l0 0c-7.1755066 0 -12.9923935 -5.816887 -12.9923935 -12.992386z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m124.14698 35.058002l0 0c0 -7.175497 5.816887 -12.992386 12.9923935 -12.992386l178.45618 0c3.4457703 0 6.750458 1.3688374 9.186981 3.8053818c2.436554 2.4365444 3.8053894 5.741209 3.8053894 9.187004l0 51.967983c0 7.175499 -5.8168945 12.992386 -12.992371 12.992386l-178.45618 0l0 0c-7.1755066 0 -12.9923935 -5.816887 -12.9923935 -12.992386z" fill-rule="evenodd"/><path fill="#000000" d="m196.67584 45.961994l0 -13.359375l1.8125 0l7.015625 10.484375l0 -10.484375l1.6875 0l0 13.359375l-1.8125 0l-7.015625 -10.5l0 10.5l-1.6875 0zm12.676071 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.563217 4.84375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm15.906967 1.71875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm13.059021 5.765625l5.125 -13.359375l1.90625 0l5.4687653 13.359375l-2.0156403 0l-1.546875 -4.046875l-5.59375 0l-1.46875 4.046875l-1.875 0zm3.859375 -5.484375l4.53125 0l-1.40625 -3.703125q-0.625 -1.6875 -0.9375 -2.765625q-0.265625 1.28125 -0.71875 2.546875l-1.46875 3.921875z" fill-rule="nonzero"/><path fill="#cfe2f3" d="m240.22047 199.3756l0 0c0 -7.1755066 5.8168945 -12.992386 12.992386 -12.992386l178.45618 0c3.4458008 0 6.750458 1.3688354 9.187012 3.8053741c2.4365234 2.4365387 3.805359 5.741211 3.805359 9.187012l0 51.96797c0 7.1755066 -5.8168945 12.992401 -12.992371 12.992401l-178.45618 0l0 0c-7.1754913 0 -12.992386 -5.8168945 -12.992386 -12.992401z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m240.22047 199.3756l0 0c0 -7.1755066 5.8168945 -12.992386 12.992386 -12.992386l178.45618 0c3.4458008 0 6.750458 1.3688354 9.187012 3.8053741c2.4365234 2.4365387 3.805359 5.741211 3.805359 9.187012l0 51.96797c0 7.1755066 -5.8168945 12.992401 -12.992371 12.992401l-178.45618 0l0 0c-7.1754913 0 -12.992386 -5.8168945 -12.992386 -12.992401z" fill-rule="evenodd"/><path fill="#000000" d="m312.23465 210.27957l0 -13.359375l1.8125 0l7.015625 10.484375l0 -10.484375l1.6875 0l0 13.359375l-1.8125 0l-7.015625 -10.5l0 10.5l-1.6875 0zm12.676056 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.563232 4.84375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm15.906952 1.71875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm24.059021 1.078125l1.765625 0.453125q-0.5625 2.171875 -2.0 3.328125q-1.4375 1.140625 -3.53125 1.140625q-2.15625 0 -3.515625 -0.875q-1.34375 -0.890625 -2.0625 -2.546875q-0.703125 -1.671875 -0.703125 -3.59375q0 -2.078125 0.796875 -3.625q0.796875 -1.5625 2.265625 -2.359375q1.484375 -0.8125 3.25 -0.8125q2.0 0 3.359375 1.015625q1.375 1.015625 1.90625 2.875l-1.734375 0.40625q-0.46875 -1.453125 -1.359375 -2.109375q-0.875 -0.671875 -2.203125 -0.671875q-1.546875 0 -2.578125 0.734375q-1.03125 0.734375 -1.453125 1.984375q-0.421875 1.234375 -0.421875 2.5625q0 1.703125 0.5 2.96875q0.5 1.265625 1.546875 1.90625q1.046875 0.625 2.265625 0.625q1.484375 0 2.515625 -0.859375q1.03125 -0.859375 1.390625 -2.546875z" fill-rule="nonzero"/><path fill="#cfe2f3" d="m362.95276 35.058002l0 0c0 -7.175497 5.8168945 -12.992386 12.992371 -12.992386l178.45618 0c3.4458008 0 6.7504883 1.3688374 9.187012 3.8053818c2.4365234 2.4365444 3.805359 5.741209 3.805359 9.187004l0 51.967983c0 7.175499 -5.8168945 12.992386 -12.992371 12.992386l-178.45618 0l0 0c-7.175476 0 -12.992371 -5.816887 -12.992371 -12.992386z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m362.95276 35.058002l0 0c0 -7.175497 5.8168945 -12.992386 12.992371 -12.992386l178.45618 0c3.4458008 0 6.7504883 1.3688374 9.187012 3.8053818c2.4365234 2.4365444 3.805359 5.741209 3.805359 9.187004l0 51.967983c0 7.175499 -5.8168945 12.992386 -12.992371 12.992386l-178.45618 0l0 0c-7.175476 0 -12.992371 -5.816887 -12.992371 -12.992386z" fill-rule="evenodd"/><path fill="#000000" d="m435.48163 45.961994l0 -13.359375l1.8125 0l7.015625 10.484375l0 -10.484375l1.6875 0l0 13.359375l-1.8125 0l-7.015625 -10.5l0 10.5l-1.6875 0zm12.676056 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.563232 4.84375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm15.906952 1.71875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm14.449646 5.765625l0 -13.359375l5.015625 0q1.53125 0 2.453125 0.40625q0.921875 0.40625 1.4375 1.25q0.53125 0.84375 0.53125 1.765625q0 0.859375 -0.46875 1.625q-0.453125 0.75 -1.390625 1.203125q1.203125 0.359375 1.859375 1.21875q0.65625 0.859375 0.65625 2.015625q0 0.9375 -0.40625 1.75q-0.390625 0.796875 -0.984375 1.234375q-0.578125 0.4375 -1.453125 0.671875q-0.875 0.21875 -2.15625 0.21875l-5.09375 0zm1.78125 -7.75l2.875 0q1.1875 0 1.6875 -0.140625q0.671875 -0.203125 1.015625 -0.671875q0.34375 -0.46875 0.34375 -1.171875q0 -0.65625 -0.328125 -1.15625q-0.3125 -0.515625 -0.90625 -0.703125q-0.59375 -0.1875 -2.03125 -0.1875l-2.65625 0l0 4.03125zm0 6.171875l3.3125 0q0.859375 0 1.203125 -0.0625q0.609375 -0.109375 1.015625 -0.359375q0.421875 -0.265625 0.6875 -0.75q0.265625 -0.484375 0.265625 -1.125q0 -0.75 -0.390625 -1.296875q-0.375 -0.546875 -1.0625 -0.765625q-0.671875 -0.234375 -1.953125 -0.234375l-3.078125 0l0 4.59375z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m226.36745 100.01837l116.063 86.36221" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m226.36745 100.01837l111.249405 82.78041" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m336.63083 184.12392l4.62677 1.3839569l-2.6547241 -4.03421z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m465.17322 100.01837l-122.74014 86.36221" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m465.17322 100.01837l-117.83313 82.90953" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m346.38962 181.57704l-2.7609558 3.9622955l4.6619263 -1.2605896z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m257.0404 92.51918l82.14172 59.118103l-12.787384 17.763779l-82.14174 -59.118103z" fill-rule="evenodd"/><path fill="#000000" d="m252.45872 116.08069l5.5775604 -7.7481384l5.605438 4.034279l-0.6572571 0.91304016l-4.578186 -3.2949677l-1.7070618 2.3713608l4.286499 3.0850372l-0.6572571 0.91304016l-4.286499 -3.0850372l-1.8987427 2.6376648l4.7557373 3.4227448l-0.6572571 0.91304016l-5.7829742 -4.1620636zm8.635727 6.2152023l1.9042358 -7.1384277l1.0018921 0.7210617l-1.2142944 4.227577q-0.19317627 0.6695175 -0.45733643 1.3841858q0.44631958 -0.35256958 1.1218872 -0.8096466l3.70755 -2.5294113l0.9891968 0.7119293l-6.1654053 4.0716476l-0.88772583 -0.638916zm8.987854 3.7350082l0.89437866 0.8169327q-0.84902954 0.69802856 -1.8300171 0.72354126q-0.9591675 0.021957397 -1.935669 -0.68084717q-1.2301636 -0.88534546 -1.4053345 -2.1664734q-0.17514038 -1.2811203 0.8016052 -2.6379929q1.0223999 -1.4202805 2.302124 -1.6735687q1.3015137 -0.25684357 2.4682617 0.5828705q1.1286926 0.81233215 1.2911682 2.0843277q0.16247559 1.2719955 -0.8416443 2.666916q-0.06390381 0.088768005 -0.18258667 0.25361633l-4.1850586 -3.0120163q-0.6156616 0.96222687 -0.5024414 1.7945023q0.12234497 0.8195877 0.81985474 1.3215942q0.5326538 0.38334656 1.0921326 0.38173676q0.5686035 -0.014289856 1.2132263 -0.45513916zm-2.006073 -3.7924118l3.1324463 2.254448q0.43865967 -0.7430954 0.4025879 -1.3080902q-0.054901123 -0.8865509 -0.777771 -1.4068146q-0.65945435 -0.474617 -1.422821 -0.350235q-0.75424194 0.111701965 -1.3344421 0.81069183zm2.8835144 7.1575394l4.0348206 -5.6050415l0.8623657 0.6206589l-0.57510376 0.79891205q1.275116 -0.48760986 2.441864 0.3521042q0.5072937 0.36509705 0.81066895 0.8529587q0.30340576 0.48786163 0.28723145 0.9382477q0.0056152344 0.44683075 -0.19772339 0.91651917q-0.1409607 0.30281067 -0.6156616 0.96221924l-2.4829712 3.4492645l-0.95114136 -0.68455505l2.455597 -3.411209q0.41989136 -0.58332825 0.5065918 -0.94446564q0.095825195 -0.3738098 -0.06451416 -0.7394638q-0.15118408 -0.37833405 -0.5316467 -0.652153q-0.60873413 -0.43811035 -1.326477 -0.37713623q-0.7177124 0.06097412 -1.4936523 1.1388626l-2.2091064 3.0688171l-0.95114136 -0.6845398zm8.707764 4.977234l-0.46298218 0.9373474q-0.46972656 -0.20329285 -0.7867737 -0.43148804q-0.5199585 -0.3742218 -0.69299316 -0.7489929q-0.16033936 -0.36566162 -0.08276367 -0.7141113q0.07757568 -0.3484497 0.6983032 -1.2107544l2.3186646 -3.220993l-0.69750977 -0.50201416l0.52944946 -0.7354965l0.69750977 0.50200653l1.0041504 -1.3949203l1.3619385 0.11389923l-1.4149475 1.9655609l0.9511719 0.68455505l-0.52948 0.73550415l-0.95114136 -0.68455505l-2.3642883 3.2844086q-0.29211426 0.40579224 -0.33624268 0.54730225q-0.031433105 0.15063477 0.027954102 0.3088684q0.068481445 0.14555359 0.28408813 0.3007202q0.16485596 0.118652344 0.44589233 0.26315308zm3.839264 -2.8196259l0.77593994 -1.0778809l1.0779724 0.7758179l-0.77593994 1.0778961l-1.0779724 -0.77583313zm-3.2588806 4.5271454l0.7759094 -1.0778809l1.0779724 0.7758179l-0.77593994 1.0778961l-1.0779419 -0.77583313zm11.130249 -1.7689514l-0.79418945 1.1032562l-1.0145569 -0.7301941l0.6298828 -0.87498474q0.51119995 -0.71014404 0.90426636 -0.90852356q0.5168457 -0.26330566 1.1539307 -0.13204956l-0.023742676 0.5411835q-0.3829956 -0.08312988 -0.69592285 0.057418823q-0.31295776 0.14053345 -0.65426636 0.58792114l0.4945984 0.3559723zm1.6359863 1.1774292l-0.79418945 1.1032562l-1.0145569 -0.7301941l0.6298523 -0.875q0.51119995 -0.7101288 0.9042969 -0.9085083q0.5295105 -0.2541809 1.1539307 -0.13204956l-0.023773193 0.5411682q-0.3829651 -0.083114624 -0.69592285 0.057418823q-0.31292725 0.1405487 -0.65423584 0.5879364l0.4945984 0.3559723zm-3.1908875 7.4830017l3.5054016 -4.869522l-0.83703613 -0.602417l0.52948 -0.7354889l0.8370056 0.60240173l0.42904663 -0.59602356q0.4107666 -0.5706482 0.71307373 -0.7766113q0.40420532 -0.26734924 0.9109497 -0.24916077q0.50671387 0.018173218 1.1408081 0.47453308q0.39315796 0.28295898 0.82385254 0.72769165l-0.7546692 0.727417q-0.25515747 -0.26065063 -0.5214844 -0.45233154q-0.43118286 -0.310318 -0.7456665 -0.24789429q-0.3053589 0.04975891 -0.6705017 0.55700684l-0.37426758 0.5199127l1.0906372 0.7849579l-0.52944946 0.73550415l-1.0906372 -0.7849579l-3.505371 4.8695374l-0.9511719 -0.68455505zm4.439575 -1.0592804q1.1228027 -1.5597687 2.5364685 -1.6781616q1.170166 -0.101119995 2.210083 0.6473236q1.1540527 0.83058167 1.3418884 2.1208344q0.19699097 1.2775726 -0.7706604 2.6217651q-0.7759094 1.0778961 -1.552948 1.4619598q-0.76434326 0.39318848 -1.6322327 0.28833008q-0.8678894 -0.10484314 -1.6034546 -0.63423157q-1.1794128 -0.84884644 -1.3763733 -2.1264038q-0.1751709 -1.2811279 0.847229 -2.701416zm0.97650146 0.70280457q-0.7759094 1.0778961 -0.690094 1.9482117q0.09851074 0.8794403 0.8087158 1.3905792q0.71017456 0.51112366 1.5628357 0.3162384q0.8617554 -0.20758057 1.6559448 -1.3108368q0.74853516 -1.0398407 0.6500244 -1.9192963q-0.08584595 -0.87031555 -0.7833557 -1.3723145q-0.71017456 -0.51112366 -1.5755005 -0.32536316q-0.8526306 0.19490051 -1.6285706 1.2727814zm5.039795 3.6271973q1.1228333 -1.5597839 2.5364685 -1.6781769q1.170166 -0.101119995 2.210083 0.6473236q1.1540833 0.83058167 1.341919 2.1208344q0.19696045 1.2775726 -0.7706604 2.6217651q-0.77593994 1.0778961 -1.5529785 1.4619598q-0.76434326 0.39318848 -1.6322327 0.28833008q-0.8678894 -0.10484314 -1.6034241 -0.63423157q-1.1794434 -0.84884644 -1.3764038 -2.1264038q-0.1751709 -1.2811279 0.847229 -2.7014008zm0.976532 0.70280457q-0.77593994 1.0778809 -0.690094 1.9481964q0.09851074 0.87945557 0.8086853 1.3905792q0.7102051 0.51112366 1.5628357 0.3162384q0.8617554 -0.20758057 1.6559448 -1.3108368q0.74853516 -1.0398407 0.6500244 -1.919281q-0.08581543 -0.87031555 -0.7833252 -1.3723297q-0.7102051 -0.51112366 -1.5755005 -0.32536316q-0.85266113 0.19490051 -1.6285706 1.2727966zm7.961975 -0.21826172l0.79418945 -1.103241l1.0272522 0.7393036l-0.6298828 0.875q-0.51119995 0.71014404 -0.8951416 0.89582825q-0.5386658 0.26686096 -1.1757507 0.13560486l0.03643799 -0.53204346q0.3703003 0.07398987 0.68322754 -0.06654358q0.32208252 -0.15322876 0.65426636 -0.5879364l-0.4945984 -0.3559723zm1.6359863 1.1774292l0.79418945 -1.1032562l1.0272217 0.73931885l-0.6298523 0.875q-0.51119995 0.7101288 -0.8951721 0.89582825q-0.53863525 0.26686096 -1.1757507 0.13560486l0.036468506 -0.53204346q0.37026978 0.07398987 0.68322754 -0.06655884q0.32208252 -0.1532135 0.66693115 -0.5787964l-0.5072632 -0.36509705z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m357.06943 145.84117l108.25195 -78.3622l12.850403 17.669289l-108.25195 78.362206z" fill-rule="evenodd"/><path fill="#000000" d="m378.02997 157.58041l-5.6152344 -7.7209167l5.59433 -4.0496674l0.66171265 0.9098358l-4.5691223 3.3075256l1.7185669 2.363037l4.278015 -3.0968018l0.6616821 0.90982056l-4.278015 3.0968018l1.91156 2.6284027l4.746338 -3.4358063l0.6616821 0.9098358l-5.771515 4.1779327zm8.618591 -6.238907l-6.1884155 -4.046112l0.99990845 -0.72380066l3.6377869 2.4782715q0.5758362 0.39331055 1.1723328 0.8681183q-0.19509888 -0.533905 -0.41760254 -1.3180084l-1.2409668 -4.3097534l0.98721313 -0.7146454l1.93573 7.124588l-0.8859863 0.64134216zm6.3713684 -7.3512115l1.057312 -0.59176636q0.39709473 1.0242004 0.11349487 1.9625092q-0.28015137 0.91648865 -1.2547302 1.6219788q-1.2277222 0.88871765 -2.5005798 0.652771q-1.2728577 -0.23594666 -2.256195 -1.5880585q-1.0292969 -1.4152985 -0.86846924 -2.7083588q0.16430664 -1.3148651 1.3287354 -2.1577911q1.1264648 -0.8154297 2.3866577 -0.5703125q1.2601929 0.24511719 2.2711182 1.6351318q0.064331055 0.0884552 0.18380737 0.25273132l-4.176758 3.0234985q0.7214966 0.8858185 1.5482178 1.0396423q0.8175354 0.14118958 1.5136719 -0.36271667q0.5315857 -0.3848114 0.70562744 -0.9158783q0.16488647 -0.54371643 -0.0519104 -1.2933807zm-4.2347717 0.71221924l3.1262512 -2.2630463q-0.5687561 -0.64920044 -1.1171875 -0.79229736q-0.86001587 -0.22616577 -1.5814514 0.29608154q-0.6581726 0.47642517 -0.7795105 1.2393799q-0.13052368 0.75032043 0.3518982 1.5198822zm7.7091675 -0.48820496l-4.0620728 -5.5853577l0.86065674 -0.62301636l0.5789795 0.7960968q-0.06335449 -1.3622437 1.1010742 -2.2051697q0.5062866 -0.3664856 1.0652771 -0.5010834q0.5589905 -0.13459778 0.98205566 0.022079468q0.4265442 0.1348877 0.8092346 0.47511292q0.24362183 0.22872925 0.7215271 0.8858185l2.4997253 3.437149l-0.94924927 0.68714905l-2.472168 -3.3992157q-0.42276 -0.58128357 -0.7388611 -0.77682495q-0.32528687 -0.20819092 -0.72320557 -0.17089844q-0.4071045 0.024658203 -0.7868042 0.29953003q-0.60754395 0.43977356 -0.7748413 1.1395416q-0.16726685 0.69976807 0.6138916 1.77388l2.2240295 3.0580444l-0.94924927 0.6871643zm7.4643555 -6.6957397l0.7457886 0.73321533q-0.34069824 0.38165283 -0.6571045 0.6107025q-0.5189514 0.37564087 -0.9295044 0.42210388q-0.39794922 0.03729248 -0.704834 -0.14561462q-0.30691528 -0.1829071 -0.93185425 -1.0421906l-2.33432 -3.2096863l-0.69610596 0.5039215l-0.53305054 -0.7329254l0.6961365 -0.50390625l-1.0109253 -1.3900299l0.53570557 -1.2557983l1.4244995 1.958664l0.94924927 -0.6871643l0.53302 0.7329254l-0.94924927 0.68714905l2.380249 3.272873q0.2940979 0.4043579 0.41479492 0.4906006q0.1333313 0.0770874 0.30236816 0.07044983q0.15988159 -0.01928711 0.37503052 -0.17503357q0.16455078 -0.11911011 0.3901062 -0.34025574zm-1.4755249 -4.525757l-0.78115845 -1.0741119l1.0758362 -0.7787781l0.78115845 1.0740967l-1.0758362 0.77879333zm3.2809143 4.5112305l-0.78115845 -1.0740967l1.0758057 -0.7787781l0.78118896 1.0740967l-1.0758362 0.7787781zm1.8114624 -11.110199l0.79953 1.0993729l-1.0125427 0.7329788l-0.63412476 -0.87192535q-0.51464844 -0.70764923 -0.5798645 -1.1426697q-0.08810425 -0.57276154 0.2366333 -1.1357422l0.5069885 0.19237518q-0.19921875 0.33709717 -0.16381836 0.6779785q0.03540039 0.34087372 0.35357666 0.8049545l0.49362183 -0.3573227zm1.632721 -1.1819153l0.79956055 1.0993729l-1.0125427 0.7329712l-0.63412476 -0.8719177q-0.51464844 -0.70764923 -0.5798645 -1.1426697q-0.07546997 -0.58192444 0.23660278 -1.1357422l0.5069885 0.19237518q-0.19918823 0.33709717 -0.16381836 0.6779785q0.03540039 0.34087372 0.35357666 0.8049545l0.49362183 -0.3573227zm6.757721 4.907089l-0.87332153 0.6321869l-5.6152344 -7.7209167l0.9492798 -0.6871567l2.003479 2.7547607q0.052642822 -1.176178 0.9892273 -1.8541718q0.5189514 -0.3756485 1.1308289 -0.49066162q0.61535645 -0.13681793 1.1821594 0.031547546q0.570282 0.1465683 1.1208191 0.558197q0.5505066 0.41162872 0.9916382 1.0181808q1.047699 1.4405594 0.9086914 2.7371063q-0.13897705 1.2965469 -1.1388855 2.0203476q-0.98721313 0.71466064 -2.1541443 0.3055725l0.50546265 0.6950073zm-2.0585938 -2.8305817q0.7260132 0.998291 1.3134766 1.248169q0.988678 0.40307617 1.7480774 -0.14665222q0.6201782 -0.4489441 0.68984985 -1.3095169q0.060455322 -0.8732071 -0.7207031 -1.9473114q-0.79037476 -1.0867462 -1.6101379 -1.2841644q-0.8163452 -0.21922302 -1.4365234 0.22972107q-0.6201782 0.4489441 -0.68066406 1.3221512q-0.047790527 0.8640442 0.69662476 1.8876038zm10.342041 -4.226593q-0.20074463 0.8397217 -0.55651855 1.3865967q-0.35229492 0.5250702 -0.9092102 0.9282074q-0.9239502 0.6688309 -1.7391968 0.58387756q-0.8244934 -0.097595215 -1.3391418 -0.8052368q-0.29406738 -0.40437317 -0.36502075 -0.8738251q-0.058288574 -0.47862244 0.09844971 -0.9006958q0.15670776 -0.42207336 0.45370483 -0.81066895q0.23251343 -0.26474762 0.7469177 -0.752861q1.0506897 -0.97276306 1.4570618 -1.556282q-0.1378479 -0.18954468 -0.17459106 -0.24008942q-0.42276 -0.58128357 -0.8631592 -0.6289749q-0.59680176 -0.050209045 -1.3182373 0.47203064q-0.6581726 0.4764328 -0.8126221 0.95474243q-0.15100098 0.45651245 0.12905884 1.1603775l-1.0158691 0.5424652q-0.3053589 -0.68553925 -0.28076172 -1.2627258q0.02456665 -0.5771866 0.43096924 -1.1607056q0.3972168 -0.5961609 1.1186523 -1.1184006q0.72143555 -0.5222397 1.283905 -0.6786423q0.57510376 -0.16555786 0.9706116 -0.046783447q0.39898682 0.096969604 0.77246094 0.42456818q0.21258545 0.21260834 0.6720886 0.84443665l0.91903687 1.263649q0.95578 1.3142014 1.2763977 1.6222153q0.32058716 0.30801392 0.72753906 0.49565125l-0.98721313 0.714653q-0.36328125 -0.18069458 -0.6953125 -0.55757904zm-1.6107178 -2.0553284q-0.36270142 0.59046936 -1.299469 1.4807663q-0.5178833 0.5099106 -0.6756592 0.79772186q-0.16696167 0.27516937 -0.15911865 0.57814026q0.020446777 0.29380798 0.19506836 0.5338974q0.27572632 0.37909698 0.7379761 0.4302597q0.47491455 0.041999817 1.0317993 -0.36112976q0.5442505 -0.3939743 0.7999573 -0.9455795q0.2557373 -0.5516052 0.15496826 -1.1152039q-0.07788086 -0.42585754 -0.53738403 -1.0576859l-0.24813843 -0.34118652zm4.4500732 1.060852l-4.0620728 -5.58535l0.86065674 -0.623024l0.6157532 0.84664917q-0.102874756 -0.83213043 0.02508545 -1.2140808q0.14059448 -0.3911209 0.48233032 -0.6384964q0.48095703 -0.3481598 1.1951294 -0.40220642l0.3050537 1.1101379q-0.5014343 0.054351807 -0.84317017 0.3017273q-0.31640625 0.22905731 -0.43170166 0.6018448q-0.102630615 0.3636322 0.035064697 0.76548004q0.20306396 0.6245651 0.63500977 1.218483l2.1321106 2.9316788l-0.94924927 0.6871567zm-1.5160522 -9.125839l-0.79953 -1.0993729l1.0252075 -0.7421341l0.63412476 0.8719177q0.51464844 0.70764923 0.5706787 1.1300354q0.084625244 0.5945587 -0.24008179 1.1575394l-0.49435425 -0.20153809q0.18655396 -0.32793427 0.15115356 -0.6688156q-0.044555664 -0.353508 -0.35357666 -0.8049545l-0.49362183 0.3573227zm1.6327515 -1.1819153l-0.79956055 -1.0993729l1.0252075 -0.7421341l0.63412476 0.8719177q0.51464844 0.70764923 0.5706787 1.1300354q0.08465576 0.5945587 -0.24008179 1.1575394l-0.49432373 -0.20153809q0.18652344 -0.32793427 0.15115356 -0.6688156q-0.04458618 -0.353508 -0.34094238 -0.81411743l-0.5062561 0.3664856z" fill-rule="nonzero"/><path fill="#cfe2f3" d="m27.76903 199.3756l0 0c0 -7.1755066 5.816889 -12.992386 12.992384 -12.992386l113.76326 0c3.4458008 0 6.750458 1.3688354 9.187012 3.8053741c2.4365387 2.4365387 3.8053741 5.741211 3.8053741 9.187012l0 51.96797c0 7.1755066 -5.8168945 12.992401 -12.992386 12.992401l-113.76326 0c-7.175495 0 -12.992384 -5.8168945 -12.992384 -12.992401z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m27.76903 199.3756l0 0c0 -7.1755066 5.816889 -12.992386 12.992384 -12.992386l113.76326 0c3.4458008 0 6.750458 1.3688354 9.187012 3.8053741c2.4365387 2.4365387 3.8053741 5.741211 3.8053741 9.187012l0 51.96797c0 7.1755066 -5.8168945 12.992401 -12.992386 12.992401l-113.76326 0c-7.175495 0 -12.992384 -5.8168945 -12.992384 -12.992401z" fill-rule="evenodd"/><path fill="#000000" d="m67.436745 232.27957l0 -13.359375l1.8125 0l7.015625 10.484375l0 -10.484375l1.6875 0l0 13.359375l-1.8125 0l-7.015625 -10.5l0 10.5l-1.6875 0zm12.676071 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.563225 4.84375l0 -1.21875q-0.90625 1.4375 -2.7031326 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.5468826 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.1718826 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.0781326 0 1.8281326 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.8906326 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm15.906975 1.71875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm14.527771 5.765625l0 -13.359375l4.609375 0q1.546875 0 2.375 0.203125q1.140625 0.25 1.953125 0.953125q1.0625 0.890625 1.578125 2.28125q0.53125 1.390625 0.53125 3.171875q0 1.515625 -0.359375 2.703125q-0.359375 1.171875 -0.921875 1.9375q-0.546875 0.765625 -1.203125 1.21875q-0.65625 0.4375 -1.59375 0.671875q-0.9375 0.21875 -2.140625 0.21875l-4.828125 0zm1.765625 -1.578125l2.859375 0q1.3125 0 2.0625 -0.234375q0.75 -0.25 1.203125 -0.703125q0.625 -0.625 0.96875 -1.6875q0.359375 -1.0625 0.359375 -2.578125q0 -2.09375 -0.6875 -3.21875q-0.6875 -1.125 -1.671875 -1.5q-0.703125 -0.28125 -2.28125 -0.28125l-2.8125 0l0 10.203125z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m97.64304 186.38321l128.7244 -86.36221" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m97.64304 186.38321l123.741875 -83.019394" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m222.30516 104.73545l2.848297 -3.8999786l-4.6887665 1.1567078z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m92.00377 157.38687l113.00787 -71.30709l11.685043 18.456688l-113.00787 71.30708z" fill-rule="evenodd"/><path fill="#000000" d="m110.140305 168.09871l0.958992 -0.73443604q0.45054626 0.5655823 0.96556854 0.7948761q0.5066681 0.21607971 1.1988983 0.111846924q0.70544434 -0.11256409 1.3925858 -0.5461426q0.60785675 -0.38356018 0.95334625 -0.86021423q0.35869598 -0.4850006 0.39110565 -0.93037415q0.024047852 -0.45858765 -0.21833038 -0.8414459q-0.24238586 -0.38284302 -0.6425476 -0.5183258q-0.38694763 -0.14382935 -1.0144577 -0.025009155q-0.41394043 0.076431274 -1.6911011 0.5128021q-1.2771606 0.43637085 -1.8768845 0.4822235q-0.7604523 0.054901123 -1.3353424 -0.21051025q-0.5616684 -0.27375793 -0.9127121 -0.8282318q-0.38446808 -0.6072693 -0.37522125 -1.3521271q0.009254456 -0.7448578 0.4944458 -1.4389954q0.49840546 -0.70248413 1.3176956 -1.2194519q0.8853531 -0.5586395 1.7563705 -0.7017975q0.87101746 -0.1431427 1.6004181 0.19107056q0.7210388 0.32099915 1.1904373 1.0040131l-0.9673462 0.7212372q-0.5772705 -0.70732117 -1.2953644 -0.7899933q-0.7264557 -0.09588623 -1.6514511 0.4877777q-0.9646454 0.60868835 -1.1882629 1.2486267q-0.21040344 0.63160706 0.10720062 1.1332703q0.27581787 0.4356537 0.7552643 0.5211029q0.49266052 0.07711792 1.9798965 -0.43637085q1.4920883 -0.5350342 2.101532 -0.62397766q0.9225235 -0.120224 1.570488 0.17298889q0.63960266 0.28001404 1.0575027 0.940094q0.40118408 0.63368225 0.39894104 1.4480286q0.002609253 0.7928009 -0.4971466 1.5515594q-0.4949112 0.73721313 -1.353836 1.2791901q-1.0967865 0.6920624 -2.0373764 0.8421631q-0.9405899 0.15008545 -1.7646332 -0.21676636q-0.8324051 -0.38006592 -1.3686752 -1.1687012zm12.211296 -6.70755l1.09272 -0.5232086q0.3304901 1.0477905 -0.012619019 1.9663544q-0.3382492 0.8970337 -1.3557434 1.5390625q-1.281784 0.8088074 -2.5364838 0.49197388q-1.2546921 -0.3168335 -2.1490097 -1.7294006q-0.9360962 -1.4785919 -0.69272614 -2.7591705q0.24822998 -1.3021088 1.4639359 -2.0692139q1.1760712 -0.74209595 2.4175568 -0.41693115q1.241478 0.32518005 2.1608658 1.777359q0.058509827 0.09240723 0.16716003 0.2640381l-4.3607025 2.7515717q0.6629944 0.9303589 1.4778824 1.1367188q0.8065338 0.19316101 1.5333176 -0.2654419q0.5550003 -0.35020447 0.7626953 -0.8692322q0.19933319 -0.5322418 0.031150818 -1.2944794zm-4.2703934 0.44056702l3.2639236 -2.0595093q-0.52576447 -0.68440247 -1.0637131 -0.86227417q-0.84347534 -0.28070068 -1.5966873 0.19458008q-0.6871414 0.4335785 -0.85710907 1.1874695q-0.17832184 0.74069214 0.25358582 1.5397339zm9.329292 -2.2470245l0.69698334 0.7795868q-0.36434937 0.35923767 -0.69470215 0.567688q-0.5417862 0.3418579 -0.9543686 0.36201477q-0.3993683 0.0118255615 -0.69381714 -0.19036865q-0.29444885 -0.20219421 -0.86279297 -1.0999146l-2.1229477 -3.3532257l-0.72678375 0.4586029l-0.4847641 -0.7657013l0.72678375 -0.45858765l-0.9193878 -1.4521942l0.6149597 -1.2194214l1.2954941 2.0462494l0.9910736 -0.62535095l0.4847641 0.7657013l-0.991066 0.62535095l2.164734 3.4192352q0.26745605 0.42245483 0.38232422 0.5162506q0.12807465 0.08546448 0.2971573 0.08963013q0.1607132 -0.009033203 0.38536072 -0.15078735q0.17178345 -0.10838318 0.41099548 -0.3147583zm6.0770493 0.5441284l-5.1151276 -8.079422l0.9117737 -0.5753174l0.4764099 0.7524872q0.032974243 -0.64897156 0.29566956 -1.1103363q0.26756287 -0.48291016 0.83576965 -0.8414459q0.7400055 -0.4669342 1.5505981 -0.44262695q0.82380676 0.015975952 1.5574951 0.53222656q0.7337036 0.5162506 1.2686157 1.3611603q0.5599823 0.8845062 0.7025299 1.8107147q0.13420105 0.9129944 -0.24449158 1.6877441q-0.36546326 0.7664032 -1.0526123 1.1999817q-0.48892212 0.3085022 -1.0190887 0.34742737q-0.53015137 0.038909912 -0.9818115 -0.119506836l1.8053436 2.8515625l-0.9910736 0.62535095zm-2.3527222 -5.7024384q0.7187958 1.1353455 1.5107574 1.3931274q0.7968292 0.23622131 1.4443207 -0.17233276q0.6607208 -0.4169159 0.7854004 -1.2715607q0.12466431 -0.8546295 -0.61920166 -2.0295868q-0.70207214 -1.1089325 -1.5156097 -1.3715668q-0.8218994 -0.2758484 -1.4561768 0.12438965q-0.6342926 0.40022278 -0.74710083 1.3028107q-0.11282349 0.9025879 0.5976105 2.0247192zm10.559906 -3.6332245q-0.2541046 0.82547 -0.64408875 1.3486786q-0.38513184 0.5016632 -0.966568 0.86854553q-0.9646301 0.6086731 -1.772522 0.47180176q-0.81625366 -0.15007019 -1.2843018 -0.8893585q-0.26745605 -0.42245483 -0.30812073 -0.89564514q-0.027450562 -0.48150635 0.15596008 -0.8928528q0.18341064 -0.41133118 0.50460815 -0.78030396q0.24893188 -0.24943542 0.7934265 -0.7038574q1.1105499 -0.9039917 1.5534058 -1.460556q-0.12538147 -0.19802856 -0.15881348 -0.25082397q-0.38446045 -0.60728455 -0.82077026 -0.6830139q-0.5921631 -0.08824158 -1.3453827 0.38703918q-0.6871338 0.4335785 -0.87190247 0.90119934q-0.17991638 0.44607544 0.054351807 1.1666107l-1.048233 0.4766693q-0.26068115 -0.7038574 -0.19914246 -1.2784882q0.061553955 -0.5746155 0.50439453 -1.1311798q0.43447876 -0.5697632 1.1876984 -1.045044q0.75320435 -0.4752655 1.3243713 -0.59547424q0.58436584 -0.1285553 0.9713135 0.015274048q0.39179993 0.122283936 0.74339294 0.47317505q0.19845581 0.22581482 0.61634827 0.8858948l0.8358154 1.3201599q0.8692322 1.3729858 1.1693268 1.700943q0.3000946 0.32795715 0.694046 0.54125977l-1.0307007 0.65037537q-0.35081482 -0.20358276 -0.6579132 -0.60102844zm-1.4750824 -2.1546478q-0.39970398 0.5662842 -1.3913269 1.3952332q-0.5493469 0.4759674 -0.72520447 0.75320435q-0.1842041 0.2640381 -0.1958313 0.5669861q0.0015869141 0.29460144 0.16038513 0.5454407q0.25074768 0.39604187 0.70861816 0.4766388q0.47109985 0.072250366 1.0525208 -0.2946167q0.5682068 -0.35853577 0.85868835 -0.89286804q0.29049683 -0.5343323 0.22610474 -1.1033936q-0.05038452 -0.4300995 -0.46829224 -1.0901794l-0.22566223 -0.3564453zm4.37146 1.343216l-3.6942596 -5.835144l0.8985748 -0.5669861l0.5599823 0.8845062q-0.04925537 -0.837265 0.102874756 -1.2103882q0.16534424 -0.38146973 0.52212524 -0.6065979q0.5021515 -0.31684875 1.2180939 -0.3251953l0.23313904 1.1277161q-0.50372314 0.022232056 -0.8605194 0.24736023q-0.33035278 0.20845032 -0.4692688 0.5732422q-0.1257019 0.3564453 -0.014099121 0.7664032q0.16253662 0.63645935 0.5553589 1.2569275l1.9390717 3.06279l-0.9910736 0.6253662zm7.1260376 -5.5126343q-0.25411987 0.82547 -0.644104 1.3486786q-0.38511658 0.5016632 -0.96655273 0.86854553q-0.9646454 0.6086731 -1.772522 0.47180176q-0.81625366 -0.15007019 -1.2843018 -0.8893585q-0.26745605 -0.42245483 -0.30812073 -0.8956299q-0.02746582 -0.4815216 0.15596008 -0.89286804q0.18341064 -0.41133118 0.50460815 -0.7802887q0.24893188 -0.24945068 0.7934265 -0.7038727q1.1105499 -0.9039917 1.5533905 -1.460556q-0.12536621 -0.19802856 -0.15879822 -0.25082397q-0.3844757 -0.60728455 -0.82077026 -0.6830139q-0.5921631 -0.08824158 -1.3453827 0.38703918q-0.6871338 0.4335785 -0.87190247 0.90119934q-0.17991638 0.4460907 0.054336548 1.166626l-1.0482178 0.47665405q-0.26068115 -0.7038574 -0.19914246 -1.2784882q0.061553955 -0.5746155 0.50439453 -1.1311798q0.43447876 -0.5697632 1.1876984 -1.045044q0.75320435 -0.4752655 1.3243561 -0.59547424q0.5843811 -0.1285553 0.9713135 0.015274048q0.3918152 0.122283936 0.7434082 0.47317505q0.19844055 0.22581482 0.61634827 0.8858948l0.8358154 1.3201752q0.8692322 1.3729706 1.1693268 1.7009277q0.3000946 0.32795715 0.694046 0.54125977l-1.030716 0.65037537q-0.35079956 -0.20358276 -0.65789795 -0.60102844zm-1.4750824 -2.1546478q-0.39970398 0.56629944 -1.3913269 1.3952332q-0.5493469 0.4759674 -0.72520447 0.75320435q-0.1842041 0.2640381 -0.1958313 0.5669861q0.0015869141 0.29460144 0.16038513 0.5454407q0.25074768 0.39604187 0.70861816 0.4766388q0.4710846 0.072265625 1.0525208 -0.2946167q0.5682068 -0.35853577 0.85868835 -0.89286804q0.29048157 -0.534317 0.22610474 -1.1033936q-0.05038452 -0.4300995 -0.46829224 -1.0901794l-0.22566223 -0.3564453zm4.384674 1.3348694l-3.6942596 -5.835129l0.8853607 -0.5586548l0.5181885 0.8184967q0.0016937256 -0.6107483 0.2921753 -1.1450806q0.29533386 -0.5558624 0.87677 -0.92274475q0.66070557 -0.41690063 1.237503 -0.41134644q0.57681274 0.005554199 1.0578461 0.38562012q0.056777954 -1.4584503 1.1667786 -2.158844q0.8721466 -0.5503235 1.6438904 -0.35369873q0.7766113 0.1750946 1.4034576 1.1652222l2.5408478 4.0133057l-0.9910736 0.62535095l-2.331894 -3.683258q-0.3761139 -0.59407043 -0.640625 -0.77819824q-0.2596588 -0.20567322 -0.6110382 -0.20567322q-0.35136414 1.5258789E-5 -0.69493103 0.21679688q-0.6078491 0.38356018 -0.75839233 1.0512848q-0.15054321 0.66773987 0.4178009 1.565445l2.1480103 3.3928375l-0.99105835 0.62535095l-2.3987732 -3.7888794q-0.41789246 -0.66007996 -0.8779144 -0.83169556q-0.44680786 -0.17996216 -0.9886017 0.16189575q-0.42285156 0.26683044 -0.6375427 0.7163849q-0.22306824 0.4363556 -0.11418152 0.9588623q0.10888672 0.5225067 0.61872864 1.3278198l1.9140015 3.023178l-0.9910736 0.62535095zm6.6831512 -10.812775l-0.71043396 -1.1221466l1.1231995 -0.70874023l0.71043396 1.1221466l-1.1231995 0.70874023zm2.9838257 4.7129974l-0.71043396 -1.1221466l1.1231995 -0.70874023l0.71043396 1.1221466l-1.1231995 0.70874023zm2.519577 -10.97541l0.72714233 1.1485443l-1.0571442 0.6670456l-0.5766907 -0.91091156q-0.46806335 -0.73928833 -0.5052185 -1.1777267q-0.05117798 -0.57740784 0.3088684 -1.1186829l0.49346924 0.22442627q-0.22035217 0.3237915 -0.20690918 0.6663437q0.013442993 0.34255219 0.30111694 0.826149l0.5153656 -0.32518768zm1.7046356 -1.0756149l0.7271576 1.148552l-1.0571442 0.6670456l-0.57670593 -0.9109192q-0.4680481 -0.73928833 -0.5052185 -1.1777267q-0.037963867 -0.58573914 0.30888367 -1.1186829l0.49345398 0.22442627q-0.22035217 0.3237915 -0.20690918 0.6663437q0.013458252 0.34255219 0.3011322 0.826149l0.51535034 -0.32518768zm5.7530518 5.7554474l-3.209488 -5.0694427l-0.8721466 0.55031586l-0.48477173 -0.7657013l0.8721466 -0.55031586l-0.39282227 -0.62047577q-0.3761139 -0.59407806 -0.45428467 -0.95121765q-0.09701538 -0.4745636 0.109313965 -0.9373245q0.2063446 -0.46276093 0.8670502 -0.87966156q0.4096527 -0.2584839 0.98350525 -0.4912567l0.3930664 0.9713669q-0.33735657 0.13896942 -0.6148529 0.31407166q-0.44929504 0.28349304 -0.5089264 0.59825134q-0.067977905 0.30155945 0.26634216 0.82962036l0.34268188 0.541275l1.1364288 -0.71707916l0.48475647 0.76569366l-1.1364136 0.71707916l3.209488 5.069435l-0.9910736 0.6253662zm0.6766815 -4.5100784q-1.0280457 -1.6238022 -0.60939026 -2.9780273q0.3436737 -1.1221542 1.4272461 -1.8058777q1.2024994 -0.7587662 2.4704132 -0.45027924q1.259552 0.2952881 2.1455078 1.694664q0.71043396 1.1221466 0.7763977 1.985817q0.079193115 0.8553314 -0.3426361 1.6203461q-0.42182922 0.76501465 -1.1882629 1.2486267q-1.2289276 0.7754364 -2.4884796 0.48014832q-1.2546997 -0.3168335 -2.190796 -1.7954178zm1.0175018 -0.6420288q0.71043396 1.122139 1.5503998 1.368103q0.85317993 0.2376175 1.5931702 -0.22931671q0.7400055 -0.46692657 0.87789917 -1.3299103q0.12953186 -0.87618256 -0.59762573 -2.0247269q-0.68536377 -1.0825348 -1.5385437 -1.3201599q-0.8399658 -0.24595642 -1.566742 0.21263885q-0.7400055 0.4669342 -0.8911133 1.3382492q-0.13787842 0.8629761 0.57255554 1.9851227zm5.2513275 -3.3135452q-1.0280457 -1.6238098 -0.60939026 -2.978035q0.3436737 -1.1221542 1.4272461 -1.8058777q1.2024994 -0.7587662 2.470398 -0.45027924q1.259552 0.2952881 2.1455078 1.6946716q0.71043396 1.122139 0.77641296 1.9858093q0.079193115 0.85533905 -0.3426361 1.6203461q-0.42184448 0.76501465 -1.1882629 1.2486267q-1.2289276 0.7754364 -2.4884796 0.48014832q-1.2546997 -0.31682587 -2.190796 -1.7954102zm1.0174866 -0.64203644q0.71043396 1.122139 1.550415 1.368103q0.85317993 0.23762512 1.5931702 -0.22930908q0.7400055 -0.4669342 0.8778839 -1.3299179q0.12953186 -0.87618256 -0.5976105 -2.0247269q-0.68536377 -1.0825348 -1.5385437 -1.3201599q-0.8399658 -0.24595642 -1.5667572 0.21263885q-0.73999023 0.4669342 -0.891098 1.3382492q-0.13789368 0.8629837 0.5725403 1.9851227zm2.774414 -7.459572l-0.7271576 -1.1485443l1.0703583 -0.6753845l0.57670593 0.9109192q0.4680481 0.73928833 0.4968567 1.1645279q0.046325684 0.598938 -0.31373596 1.1402206l-0.48023987 -0.2327652q0.20713806 -0.31545258 0.19367981 -0.65800476q-0.02180481 -0.35575104 -0.30111694 -0.826149l-0.51535034 0.32518005zm1.7046356 -1.0756073l-0.7271576 -1.148552l1.0703583 -0.6753845l0.57670593 0.9109192q0.4680481 0.73928833 0.4968567 1.1645279q0.046325684 0.598938 -0.31373596 1.1402206l-0.48023987 -0.2327652q0.20713806 -0.31545258 0.19369507 -0.65800476q-0.02180481 -0.35575104 -0.2879181 -0.8344879l-0.52856445 0.3335266z" fill-rule="nonzero"/><path fill="#b6d7a8" d="m132.96588 55.937008l186.80316 0l0 30.141735l-186.80316 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m132.96588 55.937008l186.80316 0l0 30.141735l-186.80316 0z" fill-rule="evenodd"/><path fill="#000000" d="m144.81847 76.087875l0 -10.484375l3.625 0q1.21875 0 1.859375 0.140625q0.90625 0.203125 1.546875 0.75q0.828125 0.703125 1.234375 1.796875q0.40625 1.09375 0.40625 2.5q0 1.1875 -0.28125 2.109375q-0.265625 0.921875 -0.703125 1.53125q-0.4375 0.609375 -0.96875 0.953125q-0.515625 0.34375 -1.25 0.53125q-0.71875 0.171875 -1.671875 0.171875l-3.796875 0zm1.390625 -1.234375l2.25 0q1.03125 0 1.625 -0.1875q0.59375 -0.203125 0.9375 -0.546875q0.5 -0.5 0.765625 -1.328125q0.28125 -0.84375 0.28125 -2.03125q0 -1.640625 -0.546875 -2.515625q-0.53125 -0.890625 -1.3125 -1.1875q-0.546875 -0.21875 -1.796875 -0.21875l-2.203125 0l0 8.015625zm8.974899 4.15625l-0.140625 -1.203125q0.421875 0.109375 0.734375 0.109375q0.4375 0 0.6875 -0.140625q0.265625 -0.140625 0.421875 -0.40625q0.125 -0.1875 0.390625 -0.953125q0.046875 -0.109375 0.125 -0.3125l-2.890625 -7.609375l1.390625 0l1.578125 4.390625q0.3125 0.84375 0.546875 1.765625q0.234375 -0.890625 0.53125 -1.734375l1.625 -4.421875l1.296875 0l-2.890625 7.71875q-0.46875 1.25 -0.734375 1.734375q-0.34375 0.625 -0.78125 0.921875q-0.4375 0.296875 -1.0625 0.296875q-0.375 0 -0.828125 -0.15625zm7.390625 -2.921875l0 -7.59375l1.15625 0l0 1.078125q0.84375 -1.25 2.421875 -1.25q0.6875 0 1.265625 0.25q0.578125 0.234375 0.859375 0.640625q0.28125 0.40625 0.40625 0.953125q0.0625 0.359375 0.0625 1.25l0 4.671875l-1.28125 0l0 -4.625q0 -0.78125 -0.15625 -1.171875q-0.15625 -0.390625 -0.546875 -0.625q-0.375 -0.234375 -0.890625 -0.234375q-0.8125 0 -1.421875 0.53125q-0.59375 0.515625 -0.59375 1.96875l0 4.15625l-1.28125 0zm13.104233 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.3073578 3.8125l0 -7.59375l1.15625 0l0 1.0625q0.34375 -0.5625 0.9375 -0.890625q0.609375 -0.34375 1.359375 -0.34375q0.84375 0 1.375 0.34375q0.546875 0.34375 0.765625 0.984375q0.90625 -1.328125 2.359375 -1.328125q1.125 0 1.734375 0.625q0.609375 0.625 0.609375 1.921875l0 5.21875l-1.28125 0l0 -4.78125q0 -0.78125 -0.125 -1.109375q-0.125 -0.34375 -0.453125 -0.546875q-0.328125 -0.21875 -0.78125 -0.21875q-0.796875 0 -1.328125 0.53125q-0.53125 0.53125 -0.53125 1.703125l0 4.421875l-1.28125 0l0 -4.9375q0 -0.859375 -0.3125 -1.28125q-0.3125 -0.4375 -1.03125 -0.4375q-0.546875 0 -1.015625 0.296875q-0.453125 0.28125 -0.671875 0.828125q-0.203125 0.546875 -0.203125 1.59375l0 3.9375l-1.28125 0zm12.208771 -9.015625l0 -1.46875l1.296875 0l0 1.46875l-1.296875 0zm0 9.015625l0 -7.59375l1.296875 0l0 7.59375l-1.296875 0zm8.209274 -2.78125l1.265625 0.15625q-0.203125 1.3125 -1.0625 2.0625q-0.84375 0.734375 -2.09375 0.734375q-1.5625 0 -2.515625 -1.015625q-0.9375 -1.03125 -0.9375 -2.921875q0 -1.234375 0.40625 -2.15625q0.40625 -0.921875 1.234375 -1.375q0.84375 -0.46875 1.8125 -0.46875q1.25 0 2.03125 0.625q0.78125 0.625 1.015625 1.765625l-1.265625 0.203125q-0.171875 -0.765625 -0.625 -1.15625q-0.453125 -0.390625 -1.09375 -0.390625q-0.984375 0 -1.59375 0.703125q-0.609375 0.703125 -0.609375 2.203125q0 1.53125 0.578125 2.234375q0.59375 0.6875 1.546875 0.6875q0.75 0 1.265625 -0.453125q0.515625 -0.46875 0.640625 -1.4375zm2.53125 2.78125l0 -10.484375l3.96875 0q1.046875 0 1.59375 0.09375q0.765625 0.125 1.28125 0.484375q0.53125 0.359375 0.84375 1.015625q0.328125 0.65625 0.328125 1.4375q0 1.328125 -0.859375 2.265625q-0.84375 0.921875 -3.078125 0.921875l-2.6875 0l0 4.265625l-1.390625 0zm1.390625 -5.5l2.71875 0q1.34375 0 1.90625 -0.5q0.5625 -0.5 0.5625 -1.40625q0 -0.671875 -0.328125 -1.140625q-0.328125 -0.46875 -0.875 -0.609375q-0.359375 -0.09375 -1.296875 -0.09375l-2.6875 0l0 3.75zm13.181854 4.5625q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.2917328 3.8125l0 -7.59375l1.15625 0l0 1.140625q0.453125 -0.796875 0.828125 -1.046875q0.375 -0.265625 0.8125 -0.265625q0.65625 0 1.328125 0.40625l-0.4375 1.203125q-0.46875 -0.28125 -0.953125 -0.28125q-0.421875 0 -0.765625 0.25q-0.328125 0.25 -0.46875 0.703125q-0.21875 0.6875 -0.21875 1.5l0 3.984375l-1.28125 0zm9.849396 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.3073578 3.8125l0 -7.59375l1.15625 0l0 1.0625q0.34375 -0.5625 0.9375 -0.890625q0.609375 -0.34375 1.359375 -0.34375q0.84375 0 1.375 0.34375q0.546875 0.34375 0.765625 0.984375q0.90625 -1.328125 2.359375 -1.328125q1.125 0 1.734375 0.625q0.609375 0.625 0.609375 1.921875l0 5.21875l-1.28125 0l0 -4.78125q0 -0.78125 -0.125 -1.109375q-0.125 -0.34375 -0.453125 -0.546875q-0.328125 -0.21875 -0.78125 -0.21875q-0.796875 0 -1.328125 0.53125q-0.53125 0.53125 -0.53125 1.703125l0 4.421875l-1.28125 0l0 -4.9375q0 -0.859375 -0.3125 -1.28125q-0.3125 -0.4375 -1.03125 -0.4375q-0.546875 0 -1.015625 0.296875q-0.453125 0.28125 -0.671875 0.828125q-0.203125 0.546875 -0.203125 1.59375l0 3.9375l-1.28125 0zm11.693146 -2.265625l1.265625 -0.203125q0.109375 0.765625 0.59375 1.171875q0.5 0.40625 1.375 0.40625q0.890625 0 1.3125 -0.359375q0.4375 -0.359375 0.4375 -0.84375q0 -0.4375 -0.375 -0.6875q-0.265625 -0.171875 -1.3125 -0.4375q-1.421875 -0.359375 -1.96875 -0.609375q-0.546875 -0.265625 -0.828125 -0.734375q-0.28125 -0.46875 -0.28125 -1.015625q0 -0.515625 0.21875 -0.9375q0.234375 -0.4375 0.640625 -0.734375q0.296875 -0.21875 0.8125 -0.359375q0.53125 -0.15625 1.125 -0.15625q0.890625 0 1.5625 0.265625q0.671875 0.25 1.0 0.6875q0.328125 0.4375 0.4375 1.171875l-1.25 0.171875q-0.09375 -0.578125 -0.5 -0.90625q-0.40625 -0.34375 -1.15625 -0.34375q-0.890625 0 -1.28125 0.296875q-0.375 0.296875 -0.375 0.6875q0 0.25 0.15625 0.453125q0.15625 0.203125 0.5 0.34375q0.1875 0.078125 1.140625 0.328125q1.359375 0.359375 1.890625 0.59375q0.546875 0.234375 0.859375 0.6875q0.3125 0.4375 0.3125 1.09375q0 0.640625 -0.375 1.21875q-0.375 0.5625 -1.09375 0.875q-0.703125 0.3125 -1.59375 0.3125q-1.484375 0 -2.265625 -0.609375q-0.765625 -0.625 -0.984375 -1.828125zm11.0 2.265625l-4.0625 -10.484375l1.5 0l2.734375 7.609375q0.328125 0.921875 0.54685974 1.71875q0.25 -0.859375 0.5625 -1.71875l2.84375 -7.609375l1.40625 0l-4.109375 10.484375l-1.4218597 0zm11.572464 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.276123 3.8125l0 -10.484375l1.28125 0l0 10.484375l-1.28125 0zm3.287384 -9.015625l0 -1.46875l1.296875 0l0 1.46875l-1.296875 0zm0 9.015625l0 -7.59375l1.296875 0l0 7.59375l-1.296875 0zm8.17804 0l0 -0.953125q-0.71875 1.125 -2.125 1.125q-0.90625 0 -1.671875 -0.5q-0.75 -0.5 -1.171875 -1.390625q-0.421875 -0.90625 -0.421875 -2.078125q0 -1.140625 0.375 -2.0625q0.390625 -0.921875 1.140625 -1.40625q0.765625 -0.5 1.703125 -0.5q0.6875 0 1.21875 0.296875q0.53125 0.28125 0.875 0.734375l0 -3.75l1.28125 0l0 10.484375l-1.203125 0zm-4.0625 -3.796875q0 1.46875 0.609375 2.1875q0.625 0.71875 1.453125 0.71875q0.84375 0 1.4375 -0.6875q0.59375 -0.6875 0.59375 -2.109375q0 -1.5625 -0.609375 -2.28125q-0.59375 -0.734375 -1.484375 -0.734375q-0.84375 0 -1.421875 0.703125q-0.578125 0.703125 -0.578125 2.203125zm12.244843 2.859375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm6.119873 2.65625l0.1875 1.140625q-0.546875 0.109375 -0.984375 0.109375q-0.6875 0 -1.078125 -0.21875q-0.390625 -0.21875 -0.546875 -0.578125q-0.15625 -0.359375 -0.15625 -1.515625l0 -4.375l-0.953125 0l0 -1.0l0.953125 0l0 -1.890625l1.28125 -0.765625l0 2.65625l1.296875 0l0 1.0l-1.296875 0l0 4.4375q0 0.546875 0.0625 0.71875q0.078125 0.15625 0.21875 0.25q0.15625 0.078125 0.453125 0.078125q0.203125 0 0.5625 -0.046875zm0.77508545 -2.640625q0 -2.109375 1.171875 -3.125q0.984375 -0.84375 2.390625 -0.84375q1.578125 0 2.5625 1.03125q1.0 1.015625 1.0 2.828125q0 1.46875 -0.4375 2.3125q-0.4375 0.828125 -1.28125 1.296875q-0.84375 0.46875 -1.84375 0.46875q-1.59375 0 -2.578125 -1.015625q-0.984375 -1.03125 -0.984375 -2.953125zm1.328125 0q0 1.453125 0.625 2.1875q0.640625 0.71875 1.609375 0.71875q0.96875 0 1.59375 -0.71875q0.640625 -0.734375 0.640625 -2.234375q0 -1.40625 -0.640625 -2.125q-0.640625 -0.734375 -1.59375 -0.734375q-0.96875 0 -1.609375 0.71875q-0.625 0.71875 -0.625 2.1875zm7.291748 3.796875l0 -7.59375l1.15625 0l0 1.140625q0.453125 -0.796875 0.828125 -1.046875q0.375 -0.265625 0.8125 -0.265625q0.65625 0 1.328125 0.40625l-0.4375 1.203125q-0.46875 -0.28125 -0.953125 -0.28125q-0.421875 0 -0.765625 0.25q-0.328125 0.25 -0.46875 0.703125q-0.21875 0.6875 -0.21875 1.5l0 3.984375l-1.28125 0z" fill-rule="nonzero"/><path fill="#efefef" d="m249.03937 223.58267l186.80316 0l0 30.141739l-186.80316 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m249.03937 223.58267l186.80316 0l0 30.141739l-186.80316 0z" fill-rule="evenodd"/><path fill="#000000" d="m271.07904 243.73354l0 -10.484375l3.625 0q1.21875 0 1.859375 0.140625q0.90625 0.203125 1.546875 0.75q0.828125 0.703125 1.234375 1.796875q0.40625 1.09375 0.40625 2.5q0 1.1875 -0.28125 2.109375q-0.265625 0.921875 -0.703125 1.53125q-0.4375 0.609375 -0.96875 0.953125q-0.515625 0.34375 -1.25 0.53125q-0.71875 0.171875 -1.671875 0.171875l-3.796875 0zm1.390625 -1.234375l2.25 0q1.03125 0 1.625 -0.1875q0.59375 -0.203125 0.9375 -0.546875q0.5 -0.5 0.765625 -1.328125q0.28125 -0.84375 0.28125 -2.03125q0 -1.640625 -0.546875 -2.515625q-0.53125 -0.890625 -1.3125 -1.1875q-0.546875 -0.21875 -1.796875 -0.21875l-2.203125 0l0 8.015625zm8.974915 4.15625l-0.140625 -1.203125q0.421875 0.109375 0.734375 0.109375q0.4375 0 0.6875 -0.140625q0.265625 -0.140625 0.421875 -0.40625q0.125 -0.1875 0.390625 -0.953125q0.046875 -0.109375 0.125 -0.3125l-2.890625 -7.609375l1.390625 0l1.578125 4.390625q0.3125 0.84375 0.546875 1.765625q0.234375 -0.890625 0.53125 -1.734375l1.625 -4.421875l1.296875 0l-2.890625 7.71875q-0.46875 1.25 -0.734375 1.734375q-0.34375 0.625 -0.78125 0.921875q-0.4375 0.296875 -1.0625 0.296875q-0.375 0 -0.828125 -0.15625zm7.390625 -2.921875l0 -7.59375l1.15625 0l0 1.078125q0.84375 -1.25 2.421875 -1.25q0.6875 0 1.265625 0.25q0.578125 0.234375 0.859375 0.640625q0.28125 0.40625 0.40625 0.953125q0.0625 0.359375 0.0625 1.25l0 4.671875l-1.28125 0l0 -4.625q0 -0.78125 -0.15625 -1.171875q-0.15625 -0.390625 -0.546875 -0.625q-0.375 -0.234375 -0.890625 -0.234375q-0.8125 0 -1.421875 0.53125q-0.59375 0.515625 -0.59375 1.96875l0 4.15625l-1.28125 0zm13.104218 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.307373 3.8125l0 -7.59375l1.15625 0l0 1.0625q0.34375 -0.5625 0.9375 -0.890625q0.609375 -0.34375 1.359375 -0.34375q0.84375 0 1.375 0.34375q0.546875 0.34375 0.765625 0.984375q0.90625 -1.328125 2.359375 -1.328125q1.125 0 1.734375 0.625q0.609375 0.625 0.609375 1.921875l0 5.21875l-1.28125 0l0 -4.78125q0 -0.78125 -0.125 -1.109375q-0.125 -0.34375 -0.453125 -0.546875q-0.328125 -0.21875 -0.78125 -0.21875q-0.796875 0 -1.328125 0.53125q-0.53125 0.53125 -0.53125 1.703125l0 4.421875l-1.28125 0l0 -4.9375q0 -0.859375 -0.3125 -1.28125q-0.3125 -0.4375 -1.03125 -0.4375q-0.546875 0 -1.015625 0.296875q-0.453125 0.28125 -0.671875 0.828125q-0.203125 0.546875 -0.203125 1.59375l0 3.9375l-1.28125 0zm12.208771 -9.015625l0 -1.46875l1.296875 0l0 1.46875l-1.296875 0zm0 9.015625l0 -7.59375l1.296875 0l0 7.59375l-1.296875 0zm8.209259 -2.78125l1.265625 0.15625q-0.203125 1.3125 -1.0625 2.0625q-0.84375 0.734375 -2.09375 0.734375q-1.5625 0 -2.515625 -1.015625q-0.9375 -1.03125 -0.9375 -2.921875q0 -1.234375 0.40625 -2.15625q0.40625 -0.921875 1.234375 -1.375q0.84375 -0.46875 1.8125 -0.46875q1.25 0 2.03125 0.625q0.78125 0.625 1.015625 1.765625l-1.265625 0.203125q-0.171875 -0.765625 -0.625 -1.15625q-0.453125 -0.390625 -1.09375 -0.390625q-0.984375 0 -1.59375 0.703125q-0.609375 0.703125 -0.609375 2.203125q0 1.53125 0.578125 2.234375q0.59375 0.6875 1.546875 0.6875q0.75 0 1.265625 -0.453125q0.515625 -0.46875 0.640625 -1.4375zm2.53125 2.78125l0 -10.484375l3.96875 0q1.046875 0 1.59375 0.09375q0.765625 0.125 1.28125 0.484375q0.53125 0.359375 0.84375 1.015625q0.328125 0.65625 0.328125 1.4375q0 1.328125 -0.859375 2.265625q-0.84375 0.921875 -3.078125 0.921875l-2.6875 0l0 4.265625l-1.390625 0zm1.390625 -5.5l2.71875 0q1.34375 0 1.90625 -0.5q0.5625 -0.5 0.5625 -1.40625q0 -0.671875 -0.328125 -1.140625q-0.328125 -0.46875 -0.875 -0.609375q-0.359375 -0.09375 -1.296875 -0.09375l-2.6875 0l0 3.75zm13.181854 4.5625q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.291748 3.8125l0 -7.59375l1.15625 0l0 1.140625q0.453125 -0.796875 0.828125 -1.046875q0.375 -0.265625 0.8125 -0.265625q0.65625 0 1.328125 0.40625l-0.4375 1.203125q-0.46875 -0.28125 -0.953125 -0.28125q-0.421875 0 -0.765625 0.25q-0.328125 0.25 -0.46875 0.703125q-0.21875 0.6875 -0.21875 1.5l0 3.984375l-1.28125 0zm9.849396 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.3073425 3.8125l0 -7.59375l1.15625 0l0 1.0625q0.34375 -0.5625 0.9375 -0.890625q0.609375 -0.34375 1.359375 -0.34375q0.84375 0 1.375 0.34375q0.546875 0.34375 0.765625 0.984375q0.90625 -1.328125 2.359375 -1.328125q1.125 0 1.734375 0.625q0.609375 0.625 0.609375 1.921875l0 5.21875l-1.28125 0l0 -4.78125q0 -0.78125 -0.125 -1.109375q-0.125 -0.34375 -0.453125 -0.546875q-0.328125 -0.21875 -0.78125 -0.21875q-0.796875 0 -1.328125 0.53125q-0.53125 0.53125 -0.53125 1.703125l0 4.421875l-1.28125 0l0 -4.9375q0 -0.859375 -0.3125 -1.28125q-0.3125 -0.4375 -1.03125 -0.4375q-0.546875 0 -1.015625 0.296875q-0.453125 0.28125 -0.671875 0.828125q-0.203125 0.546875 -0.203125 1.59375l0 3.9375l-1.28125 0zm11.693146 -2.265625l1.265625 -0.203125q0.109375 0.765625 0.59375 1.171875q0.5 0.40625 1.375 0.40625q0.890625 0 1.3125 -0.359375q0.4375 -0.359375 0.4375 -0.84375q0 -0.4375 -0.375 -0.6875q-0.265625 -0.171875 -1.3125 -0.4375q-1.421875 -0.359375 -1.96875 -0.609375q-0.546875 -0.265625 -0.828125 -0.734375q-0.28125 -0.46875 -0.28125 -1.015625q0 -0.515625 0.21875 -0.9375q0.234375 -0.4375 0.640625 -0.734375q0.296875 -0.21875 0.8125 -0.359375q0.53125 -0.15625 1.125 -0.15625q0.890625 0 1.5625 0.265625q0.671875 0.25 1.0 0.6875q0.328125 0.4375 0.4375 1.171875l-1.25 0.171875q-0.09375 -0.578125 -0.5 -0.90625q-0.40625 -0.34375 -1.15625 -0.34375q-0.890625 0 -1.28125 0.296875q-0.375 0.296875 -0.375 0.6875q0 0.25 0.15625 0.453125q0.15625 0.203125 0.5 0.34375q0.1875 0.078125 1.140625 0.328125q1.359375 0.359375 1.890625 0.59375q0.546875 0.234375 0.859375 0.6875q0.3125 0.4375 0.3125 1.09375q0 0.640625 -0.375 1.21875q-0.375 0.5625 -1.09375 0.875q-0.703125 0.3125 -1.59375 0.3125q-1.484375 0 -2.265625 -0.609375q-0.765625 -0.625 -0.984375 -1.828125zm15.484375 -1.40625l1.390625 0.34375q-0.4375 1.703125 -1.578125 2.609375q-1.125 0.890625 -2.765625 0.890625q-1.6875 0 -2.75 -0.6875q-1.0625 -0.6875 -1.625 -2.0q-0.546875 -1.3125 -0.546875 -2.8125q0 -1.640625 0.625 -2.859375q0.625 -1.21875 1.78125 -1.84375q1.15625 -0.640625 2.546875 -0.640625q1.5625 0 2.640625 0.8125q1.078125 0.796875 1.5 2.25l-1.375 0.3125q-0.359375 -1.140625 -1.0625 -1.65625q-0.6875 -0.53125 -1.734375 -0.53125q-1.21875 0 -2.03125 0.578125q-0.8125 0.578125 -1.140625 1.5625q-0.328125 0.96875 -0.328125 2.015625q0 1.328125 0.390625 2.328125q0.390625 1.0 1.21875 1.5q0.828125 0.484375 1.78125 0.484375q1.171875 0 1.96875 -0.671875q0.8125 -0.671875 1.09375 -1.984375zm2.9124146 3.671875l0 -10.484375l1.28125 0l0 10.484375l-1.28125 0zm3.287384 -9.015625l0 -1.46875l1.296875 0l0 1.46875l-1.296875 0zm0 9.015625l0 -7.59375l1.296875 0l0 7.59375l-1.296875 0zm8.45929 -2.453125l1.328125 0.171875q-0.3125 1.171875 -1.171875 1.8125q-0.84375 0.640625 -2.171875 0.640625q-1.671875 0 -2.65625 -1.015625q-0.96875 -1.03125 -0.96875 -2.890625q0 -1.921875 0.984375 -2.96875q1.0 -1.0625 2.578125 -1.0625q1.515625 0 2.484375 1.03125q0.96875 1.03125 0.96875 2.921875q0 0.109375 -0.015625 0.34375l-5.65625 0q0.0625 1.25 0.703125 1.921875q0.640625 0.65625 1.59375 0.65625q0.703125 0 1.203125 -0.359375q0.5 -0.375 0.796875 -1.203125zm-4.234375 -2.078125l4.25 0q-0.09375 -0.953125 -0.484375 -1.4375q-0.625 -0.75 -1.609375 -0.75q-0.875 0 -1.484375 0.59375q-0.609375 0.59375 -0.671875 1.59375zm7.1823425 4.53125l0 -7.59375l1.15625 0l0 1.078125q0.84375 -1.25 2.421875 -1.25q0.6875 0 1.265625 0.25q0.578125 0.234375 0.859375 0.640625q0.28125 0.40625 0.40625 0.953125q0.0625 0.359375 0.0625 1.25l0 4.671875l-1.28125 0l0 -4.625q0 -0.78125 -0.15625 -1.171875q-0.15625 -0.390625 -0.546875 -0.625q-0.375 -0.234375 -0.890625 -0.234375q-0.8125 0 -1.421875 0.53125q-0.59375 0.515625 -0.59375 1.96875l0 4.15625l-1.28125 0zm10.963623 -1.15625l0.1875 1.140625q-0.546875 0.109375 -0.984375 0.109375q-0.6875 0 -1.078125 -0.21875q-0.390625 -0.21875 -0.546875 -0.578125q-0.15625 -0.359375 -0.15625 -1.515625l0 -4.375l-0.953125 0l0 -1.0l0.953125 0l0 -1.890625l1.28125 -0.765625l0 2.65625l1.296875 0l0 1.0l-1.296875 0l0 4.4375q0 0.546875 0.0625 0.71875q0.078125 0.15625 0.21875 0.25q0.15625 0.078125 0.453125 0.078125q0.203125 0 0.5625 -0.046875z" fill-rule="nonzero"/><path fill="#b6d7a8" d="m371.77167 55.937008l186.80316 0l0 30.141735l-186.80316 0z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m371.77167 55.937008l186.80316 0l0 30.141735l-186.80316 0z" fill-rule="evenodd"/><path fill="#000000" d="m383.62424 76.087875l0 -10.484375l3.625 0q1.21875 0 1.859375 0.140625q0.90625 0.203125 1.546875 0.75q0.828125 0.703125 1.234375 1.796875q0.40625 1.09375 0.40625 2.5q0 1.1875 -0.28125 2.109375q-0.265625 0.921875 -0.703125 1.53125q-0.4375 0.609375 -0.96875 0.953125q-0.515625 0.34375 -1.25 0.53125q-0.71875 0.171875 -1.671875 0.171875l-3.796875 0zm1.390625 -1.234375l2.25 0q1.03125 0 1.625 -0.1875q0.59375 -0.203125 0.9375 -0.546875q0.5 -0.5 0.765625 -1.328125q0.28125 -0.84375 0.28125 -2.03125q0 -1.640625 -0.546875 -2.515625q-0.53125 -0.890625 -1.3125 -1.1875q-0.546875 -0.21875 -1.796875 -0.21875l-2.203125 0l0 8.015625zm8.974915 4.15625l-0.140625 -1.203125q0.421875 0.109375 0.734375 0.109375q0.4375 0 0.6875 -0.140625q0.265625 -0.140625 0.421875 -0.40625q0.125 -0.1875 0.390625 -0.953125q0.046875 -0.109375 0.125 -0.3125l-2.890625 -7.609375l1.390625 0l1.578125 4.390625q0.3125 0.84375 0.546875 1.765625q0.234375 -0.890625 0.53125 -1.734375l1.625 -4.421875l1.296875 0l-2.890625 7.71875q-0.46875 1.25 -0.734375 1.734375q-0.34375 0.625 -0.78125 0.921875q-0.4375 0.296875 -1.0625 0.296875q-0.375 0 -0.828125 -0.15625zm7.390625 -2.921875l0 -7.59375l1.15625 0l0 1.078125q0.84375 -1.25 2.421875 -1.25q0.6875 0 1.265625 0.25q0.578125 0.234375 0.859375 0.640625q0.28125 0.40625 0.40625 0.953125q0.0625 0.359375 0.0625 1.25l0 4.671875l-1.28125 0l0 -4.625q0 -0.78125 -0.15625 -1.171875q-0.15625 -0.390625 -0.546875 -0.625q-0.375 -0.234375 -0.890625 -0.234375q-0.8125 0 -1.421875 0.53125q-0.59375 0.515625 -0.59375 1.96875l0 4.15625l-1.28125 0zm13.104218 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.307373 3.8125l0 -7.59375l1.15625 0l0 1.0625q0.34375 -0.5625 0.9375 -0.890625q0.609375 -0.34375 1.359375 -0.34375q0.84375 0 1.375 0.34375q0.546875 0.34375 0.765625 0.984375q0.90625 -1.328125 2.359375 -1.328125q1.125 0 1.734375 0.625q0.609375 0.625 0.609375 1.921875l0 5.21875l-1.28125 0l0 -4.78125q0 -0.78125 -0.125 -1.109375q-0.125 -0.34375 -0.453125 -0.546875q-0.328125 -0.21875 -0.78125 -0.21875q-0.796875 0 -1.328125 0.53125q-0.53125 0.53125 -0.53125 1.703125l0 4.421875l-1.28125 0l0 -4.9375q0 -0.859375 -0.3125 -1.28125q-0.3125 -0.4375 -1.03125 -0.4375q-0.546875 0 -1.015625 0.296875q-0.453125 0.28125 -0.671875 0.828125q-0.203125 0.546875 -0.203125 1.59375l0 3.9375l-1.28125 0zm12.208771 -9.015625l0 -1.46875l1.296875 0l0 1.46875l-1.296875 0zm0 9.015625l0 -7.59375l1.296875 0l0 7.59375l-1.296875 0zm8.209259 -2.78125l1.265625 0.15625q-0.203125 1.3125 -1.0625 2.0625q-0.84375 0.734375 -2.09375 0.734375q-1.5625 0 -2.515625 -1.015625q-0.9375 -1.03125 -0.9375 -2.921875q0 -1.234375 0.40625 -2.15625q0.40625 -0.921875 1.234375 -1.375q0.84375 -0.46875 1.8125 -0.46875q1.25 0 2.03125 0.625q0.78125 0.625 1.015625 1.765625l-1.265625 0.203125q-0.171875 -0.765625 -0.625 -1.15625q-0.453125 -0.390625 -1.09375 -0.390625q-0.984375 0 -1.59375 0.703125q-0.609375 0.703125 -0.609375 2.203125q0 1.53125 0.578125 2.234375q0.59375 0.6875 1.546875 0.6875q0.75 0 1.265625 -0.453125q0.515625 -0.46875 0.640625 -1.4375zm2.53125 2.78125l0 -10.484375l3.96875 0q1.046875 0 1.59375 0.09375q0.765625 0.125 1.28125 0.484375q0.53125 0.359375 0.84375 1.015625q0.328125 0.65625 0.328125 1.4375q0 1.328125 -0.859375 2.265625q-0.84375 0.921875 -3.078125 0.921875l-2.6875 0l0 4.265625l-1.390625 0zm1.390625 -5.5l2.71875 0q1.34375 0 1.90625 -0.5q0.5625 -0.5 0.5625 -1.40625q0 -0.671875 -0.328125 -1.140625q-0.328125 -0.46875 -0.875 -0.609375q-0.359375 -0.09375 -1.296875 -0.09375l-2.6875 0l0 3.75zm13.181854 4.5625q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.291748 3.8125l0 -7.59375l1.15625 0l0 1.140625q0.453125 -0.796875 0.828125 -1.046875q0.375 -0.265625 0.8125 -0.265625q0.65625 0 1.328125 0.40625l-0.4375 1.203125q-0.46875 -0.28125 -0.953125 -0.28125q-0.421875 0 -0.765625 0.25q-0.328125 0.25 -0.46875 0.703125q-0.21875 0.6875 -0.21875 1.5l0 3.984375l-1.28125 0zm9.849396 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.3073425 3.8125l0 -7.59375l1.15625 0l0 1.0625q0.34375 -0.5625 0.9375 -0.890625q0.609375 -0.34375 1.359375 -0.34375q0.84375 0 1.375 0.34375q0.546875 0.34375 0.765625 0.984375q0.90625 -1.328125 2.359375 -1.328125q1.125 0 1.734375 0.625q0.609375 0.625 0.609375 1.921875l0 5.21875l-1.28125 0l0 -4.78125q0 -0.78125 -0.125 -1.109375q-0.125 -0.34375 -0.453125 -0.546875q-0.328125 -0.21875 -0.78125 -0.21875q-0.796875 0 -1.328125 0.53125q-0.53125 0.53125 -0.53125 1.703125l0 4.421875l-1.28125 0l0 -4.9375q0 -0.859375 -0.3125 -1.28125q-0.3125 -0.4375 -1.03125 -0.4375q-0.546875 0 -1.015625 0.296875q-0.453125 0.28125 -0.671875 0.828125q-0.203125 0.546875 -0.203125 1.59375l0 3.9375l-1.28125 0zm11.693146 -2.265625l1.265625 -0.203125q0.109375 0.765625 0.59375 1.171875q0.5 0.40625 1.375 0.40625q0.890625 0 1.3125 -0.359375q0.4375 -0.359375 0.4375 -0.84375q0 -0.4375 -0.375 -0.6875q-0.265625 -0.171875 -1.3125 -0.4375q-1.421875 -0.359375 -1.96875 -0.609375q-0.546875 -0.265625 -0.828125 -0.734375q-0.28125 -0.46875 -0.28125 -1.015625q0 -0.515625 0.21875 -0.9375q0.234375 -0.4375 0.640625 -0.734375q0.296875 -0.21875 0.8125 -0.359375q0.53125 -0.15625 1.125 -0.15625q0.890625 0 1.5625 0.265625q0.671875 0.25 1.0 0.6875q0.328125 0.4375 0.4375 1.171875l-1.25 0.171875q-0.09375 -0.578125 -0.5 -0.90625q-0.40625 -0.34375 -1.15625 -0.34375q-0.890625 0 -1.28125 0.296875q-0.375 0.296875 -0.375 0.6875q0 0.25 0.15625 0.453125q0.15625 0.203125 0.5 0.34375q0.1875 0.078125 1.140625 0.328125q1.359375 0.359375 1.890625 0.59375q0.546875 0.234375 0.859375 0.6875q0.3125 0.4375 0.3125 1.09375q0 0.640625 -0.375 1.21875q-0.375 0.5625 -1.09375 0.875q-0.703125 0.3125 -1.59375 0.3125q-1.484375 0 -2.265625 -0.609375q-0.765625 -0.625 -0.984375 -1.828125zm11.0 2.265625l-4.0625 -10.484375l1.5 0l2.734375 7.609375q0.328125 0.921875 0.546875 1.71875q0.25 -0.859375 0.5625 -1.71875l2.84375 -7.609375l1.40625 0l-4.109375 10.484375l-1.421875 0zm11.572479 -0.9375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm3.276123 3.8125l0 -10.484375l1.28125 0l0 10.484375l-1.28125 0zm3.287384 -9.015625l0 -1.46875l1.296875 0l0 1.46875l-1.296875 0zm0 9.015625l0 -7.59375l1.296875 0l0 7.59375l-1.296875 0zm8.17804 0l0 -0.953125q-0.71875 1.125 -2.125 1.125q-0.90625 0 -1.671875 -0.5q-0.75 -0.5 -1.171875 -1.390625q-0.421875 -0.90625 -0.421875 -2.078125q0 -1.140625 0.375 -2.0625q0.390625 -0.921875 1.140625 -1.40625q0.765625 -0.5 1.703125 -0.5q0.6875 0 1.21875 0.296875q0.53125 0.28125 0.875 0.734375l0 -3.75l1.28125 0l0 10.484375l-1.203125 0zm-4.0625 -3.796875q0 1.46875 0.609375 2.1875q0.625 0.71875 1.453125 0.71875q0.84375 0 1.4375 -0.6875q0.59375 -0.6875 0.59375 -2.109375q0 -1.5625 -0.609375 -2.28125q-0.59375 -0.734375 -1.484375 -0.734375q-0.84375 0 -1.421875 0.703125q-0.578125 0.703125 -0.578125 2.203125zm12.244873 2.859375q-0.71875 0.609375 -1.375 0.859375q-0.65625 0.25 -1.421875 0.25q-1.25 0 -1.921875 -0.609375q-0.671875 -0.609375 -0.671875 -1.5625q0 -0.5625 0.25 -1.015625q0.25 -0.46875 0.65625 -0.75q0.421875 -0.28125 0.9375 -0.421875q0.375 -0.09375 1.140625 -0.1875q1.5625 -0.1875 2.296875 -0.453125q0.015625 -0.265625 0.015625 -0.328125q0 -0.796875 -0.375 -1.109375q-0.484375 -0.4375 -1.453125 -0.4375q-0.921875 0 -1.359375 0.328125q-0.421875 0.3125 -0.625 1.109375l-1.265625 -0.171875q0.171875 -0.796875 0.5625 -1.296875q0.390625 -0.5 1.140625 -0.765625q0.75 -0.265625 1.71875 -0.265625q0.984375 0 1.59375 0.234375q0.609375 0.21875 0.890625 0.5625q0.28125 0.34375 0.40625 0.875q0.0625 0.328125 0.0625 1.1875l0 1.71875q0 1.796875 0.078125 2.28125q0.078125 0.46875 0.328125 0.90625l-1.34375 0q-0.203125 -0.40625 -0.265625 -0.9375zm-0.109375 -2.875q-0.703125 0.28125 -2.09375 0.484375q-0.796875 0.109375 -1.125 0.265625q-0.328125 0.140625 -0.515625 0.421875q-0.171875 0.265625 -0.171875 0.59375q0 0.515625 0.390625 0.859375q0.390625 0.34375 1.140625 0.34375q0.734375 0 1.3125 -0.3125q0.59375 -0.328125 0.859375 -0.890625q0.203125 -0.4375 0.203125 -1.296875l0 -0.46875zm6.119812 2.65625l0.1875 1.140625q-0.546875 0.109375 -0.984375 0.109375q-0.6875 0 -1.078125 -0.21875q-0.390625 -0.21875 -0.546875 -0.578125q-0.15625 -0.359375 -0.15625 -1.515625l0 -4.375l-0.953125 0l0 -1.0l0.953125 0l0 -1.890625l1.28125 -0.765625l0 2.65625l1.296875 0l0 1.0l-1.296875 0l0 4.4375q0 0.546875 0.0625 0.71875q0.078125 0.15625 0.21875 0.25q0.15625 0.078125 0.453125 0.078125q0.203125 0 0.5625 -0.046875zm0.7751465 -2.640625q0 -2.109375 1.171875 -3.125q0.984375 -0.84375 2.390625 -0.84375q1.578125 0 2.5625 1.03125q1.0 1.015625 1.0 2.828125q0 1.46875 -0.4375 2.3125q-0.4375 0.828125 -1.28125 1.296875q-0.84375 0.46875 -1.84375 0.46875q-1.59375 0 -2.578125 -1.015625q-0.984375 -1.03125 -0.984375 -2.953125zm1.328125 0q0 1.453125 0.625 2.1875q0.640625 0.71875 1.609375 0.71875q0.96875 0 1.59375 -0.71875q0.640625 -0.734375 0.640625 -2.234375q0 -1.40625 -0.640625 -2.125q-0.640625 -0.734375 -1.59375 -0.734375q-0.96875 0 -1.609375 0.71875q-0.625 0.71875 -0.625 2.1875zm7.291687 3.796875l0 -7.59375l1.15625 0l0 1.140625q0.453125 -0.796875 0.828125 -1.046875q0.375 -0.265625 0.8125 -0.265625q0.65625 0 1.328125 0.40625l-0.4375 1.203125q-0.46875 -0.28125 -0.953125 -0.28125q-0.421875 0 -0.765625 0.25q-0.328125 0.25 -0.46875 0.703125q-0.21875 0.6875 -0.21875 1.5l0 3.984375l-1.28125 0z" fill-rule="nonzero"/></g></svg> diff --git a/nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_client.hpp b/nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_client.hpp deleted file mode 100644 index 1a07c83c..00000000 --- a/nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_client.hpp +++ /dev/null @@ -1,432 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef NAV2_DYNAMIC_PARAMS__DYNAMIC_PARAMS_CLIENT_HPP_ -#define NAV2_DYNAMIC_PARAMS__DYNAMIC_PARAMS_CLIENT_HPP_ - -#include <cstddef> -#include <map> -#include <memory> -#include <string> -#include <utility> -#include <vector> -#include "rclcpp/rclcpp.hpp" -#include "rclcpp/parameter_events_filter.hpp" - -using namespace std::chrono_literals; // NOLINT - -namespace nav2_dynamic_params -{ - -class DynamicParamsClient -{ -public: - explicit DynamicParamsClient( - rclcpp::Node::SharedPtr node) - : node_(node), - last_event_(std::make_shared<rcl_interfaces::msg::ParameterEvent>()) - {} - - ~DynamicParamsClient() {} - - // Adds a subscription to a namespace parameter events topic - void add_namespace_event_subscriber(const std::string & node_namespace) - { - if (std::find(node_namespaces_.begin(), node_namespaces_.end(), - node_namespace) == node_namespaces_.end()) - { - node_namespaces_.push_back(node_namespace); - auto topic = join_path(node_namespace, "parameter_events"); - RCLCPP_INFO(node_->get_logger(), "Subscribing to topic: %s", topic.c_str()); - - auto event_sub = node_->create_subscription<rcl_interfaces::msg::ParameterEvent>( - topic, std::bind(&DynamicParamsClient::event_callback, this, std::placeholders::_1)); - event_subscriptions_.push_back(event_sub); - } - } - - // Sets user callback as a member variable. - // Default true for init_callback to force user callback upon setting - void set_callback( - std::function<void()> callback, - bool init_callback = true) - { - user_callback_ = callback; - if (init_callback) { - user_callback_(); - } - } - - // Adds and initialize parameters to cached map of dynamic parameters - // If an empty vector is passed, will grab all current parameters on node - void add_parameters(const std::string & path, const std::vector<std::string> & param_names) - { - auto full_path = path; - if (*full_path.begin() != '/') { - full_path = '/' + full_path; - } - - init_as_not_set(full_path, param_names); - auto params = get_params(full_path, param_names); - add_namespace_event_subscriber(split_path(full_path).first); - for (const auto & param : params) { - init_param_in_map(param, full_path); - } - } - - // Variant of add_parameters to add parameters of member node - // As a default (no argument), it will add all parameters on the node - void add_parameters(const std::vector<std::string> & param_names = {}) - { - auto full_path = join_path(node_->get_namespace(), node_->get_name()); - add_parameters(full_path, param_names); - } - - // Variant of add_parameters to pass in namespace and node name - void add_parameters( - const std::string & name_space, - const std::string & node_name, const std::vector<std::string> & param_names) - { - auto full_path = join_path(name_space, node_name); - add_parameters(full_path, param_names); - } - - // Passes empty vector to add_parameters (which will add all parameters on node) - void add_parameters_on_node(const std::string full_path) - { - std::vector<std::string> empty_vector; - add_parameters(full_path, empty_vector); - } - - // Variant of add_parameters_on_node to include node namespace and node name - void add_parameters_on_node(const std::string & ns, const std::string & node) - { - auto full_path = join_path(ns, node); - add_parameters_on_node(full_path); - } - - // Get list of cached dynamic param names - std::vector<std::string> get_param_names() - { - std::vector<std::string> names; - for (const auto & entry : dynamic_param_map_) { - names.push_back(entry.first); - } - return names; - } - - // return full map of dynamic parameters - std::map<std::string, rclcpp::Parameter> get_param_map() - { - return dynamic_param_map_; - } - - // retreive parameter from map given full path to node - template<class T> - bool get_event_param( - const std::string & full_path, const std::string & param_name, T & new_value) - { - auto lookup_name = join_path(full_path, param_name); - if (get_param_from_map<T>(lookup_name, new_value)) { - return true; - } else { - RCLCPP_WARN(node_->get_logger(), - "Parameter '%s' is either unregistered or not set", lookup_name.c_str()); - return false; - } - } - - // Variant of get_event_param for specifying namespace and node name - template<class T> - bool get_event_param( - const std::string & name_space, const std::string & node_name, - const std::string & param_name, T & new_value) - { - return get_event_param<T>(join_path(name_space, node_name), param_name, new_value); - } - - // Variant of get_event_param for member node parameter - template<class T> - bool get_event_param(const std::string & param_name, T & new_value) - { - return get_event_param<T>( - node_->get_namespace(), node_->get_name(), param_name, new_value); - } - - // retrieve parameter or assign default value if not set given full path to node - template<class T> - bool get_event_param_or( - const std::string & full_path, const std::string & param_name, - T & new_value, const T & default_value) - { - if (get_event_param<T>(full_path, param_name, new_value)) { - return true; - } else { - new_value = default_value; - return false; - } - } - - // Variant of get_event_param_or for specifying namespace and node name - template<class T> - bool get_event_param_or( - const std::string & name_space, const std::string & node_name, - const std::string & param_name, T & new_value, const T & default_value) - { - return get_event_param_or<T>( - join_path(name_space, node_name), param_name, new_value, default_value); - } - - // Variant of get_event_param_or for member node parameter - template<class T> - bool get_event_param_or(const std::string & param_name, T & new_value, const T & default_value) - { - return get_event_param_or<T>( - node_->get_namespace(), node_->get_name(), param_name, new_value, default_value); - } - - // A check to filter whether parameter name is part of the lastest event - bool is_in_event(const std::string & path, const std::string & param_name) - { - auto full_path = path; - if (*full_path.begin() != '/') { - full_path = '/' + full_path; - } - - rclcpp::ParameterEventsFilter filter(last_event_, {param_name}, - {rclcpp::ParameterEventsFilter::EventType::NEW, - rclcpp::ParameterEventsFilter::EventType::CHANGED}); - - return full_path == last_event_->node && !filter.get_events().empty(); - } - - // Variant of is_in_event to specify namespace and node name - bool is_in_event( - const std::string & name_space, - const std::string & node_name, const std::string & param_name) - { - auto full_path = join_path(name_space, node_name); - return is_in_event(full_path, param_name); - } - - // Variant of is_in_event to check under member node - bool is_in_event(const std::string & param_name) - { - return is_in_event(node_->get_namespace(), node_->get_name(), param_name); - } - -protected: - void event_callback(const rcl_interfaces::msg::ParameterEvent::SharedPtr event) - { - last_event_ = event; - if (is_event_in_map(event)) { - user_callback_(); - } - } - -private: - // Get current parameters from remote or member node - // For remote nodes, will re-try to grab parameters up to a maximum # of attempts - std::vector<rclcpp::Parameter> get_params( - const std::string & path, - const std::vector<std::string> & param_names, int attempts_max = 5) - { - std::vector<rclcpp::Parameter> params; - bool success = false; - int attempts = 0; - if (path == join_path(node_->get_namespace(), node_->get_name())) { - params_from_this(param_names, params); - } else { - while (!success && attempts < attempts_max) { - success = params_from_remote(path, param_names, params); - attempts++; - } - } - return params; - } - - // Get current parameters from member node - void params_from_this( - const std::vector<std::string> & param_names, - std::vector<rclcpp::Parameter> & params) - { - if (param_names.empty()) { - auto param_list = node_->list_parameters({}, 1); - params = node_->get_parameters(param_list.names); - } else { - params = node_->get_parameters(param_names); - } - } - - // Get current parameters from remote node - bool params_from_remote( - const std::string & path, - const std::vector<std::string> & param_names, std::vector<rclcpp::Parameter> & params) - { - auto client = std::make_shared<rclcpp::AsyncParametersClient>(node_, path); - if (param_names.empty()) { - auto param_list_future = client->list_parameters({}, 1); - if (rclcpp::spin_until_future_complete( - node_, - param_list_future, - std::chrono::duration<int64_t, std::milli>(100)) != - rclcpp::executor::FutureReturnCode::SUCCESS) - { - return false; - } else { - if (!get_params_future(client, param_list_future.get().names, params)) { - return false; - } - } - } else { - if (!get_params_future(client, param_names, params)) { - return false; - } - } - return true; - } - - // Spin parameter future and return success or failure - bool get_params_future( - rclcpp::AsyncParametersClient::SharedPtr client, - const std::vector<std::string> & param_names, std::vector<rclcpp::Parameter> & params) - { - auto params_future = client->get_parameters(param_names); - if (rclcpp::spin_until_future_complete( - node_, - params_future, - std::chrono::duration<int64_t, std::milli>(100)) != - rclcpp::executor::FutureReturnCode::SUCCESS) - { - return false; - } else { - params = params_future.get(); - return true; - } - } - - // Initialize parameters in map as PARAMETER_NOT_SET under full node path - void init_as_not_set(const std::string & full_path, const std::vector<std::string> & param_names) - { - for (const auto & name : param_names) { - auto param = rclcpp::Parameter(name, rclcpp::ParameterValue()); - init_param_in_map(param, full_path); - } - } - - // Initialize parameter value in map under full node path - void init_param_in_map(rclcpp::Parameter param, std::string node_path) - { - auto param_name = join_path(node_path, param.get_name()); - dynamic_param_map_[param_name] = param; - } - - std::pair<std::string, std::string> split_path(const std::string & str) - { - std::size_t found = str.find_last_of("/\\"); - std::string path = str.substr(0, found); - std::string name = str.substr(found + 1); - return {path, name}; - } - - std::string join_path(std::string path, std::string name) - { - std::string joined_path = path; - if (*joined_path.rbegin() != '/' && *name.begin() != '/') { - joined_path = joined_path + "/"; - } - if (*joined_path.begin() != '/') { - joined_path = "/" + joined_path; - } - joined_path = joined_path + name; - return joined_path; - } - - // Grab parameter from internal map and assign to value - template<class T> - bool get_param_from_map(const std::string & name, T & value) - { - if (dynamic_param_map_.count(name) > 0 && - !(dynamic_param_map_[name].get_type() == rclcpp::ParameterType::PARAMETER_NOT_SET)) - { - value = dynamic_param_map_[name].get_value<T>(); - return true; - } else { - return false; - } - } - - // This function checks that event variables exist in the cached dynamic param map - // True if at least one parameter exists in the map - bool is_event_in_map(const rcl_interfaces::msg::ParameterEvent::SharedPtr event) - { - bool result = false; - - for (auto & new_parameter : event->new_parameters) { - auto param_name = join_path(event->node, new_parameter.name); - if (dynamic_param_map_.count(param_name)) { - auto param = rclcpp::Parameter::from_parameter_msg(new_parameter); - dynamic_param_map_[param_name] = param; - result = true; - } - } - - for (auto & changed_parameter : event->changed_parameters) { - auto param_name = join_path(event->node, changed_parameter.name); - if (dynamic_param_map_.count(param_name)) { - auto param = rclcpp::Parameter::from_parameter_msg(changed_parameter); - if (param.get_type() == dynamic_param_map_[param_name].get_type()) { - dynamic_param_map_[param_name] = param; - result = true; - } else { - RCLCPP_WARN(node_->get_logger(), - "Un-matching type for parameter event: %s", param_name.c_str()); - } - } - } - - for (auto & deleted_parameter : event->deleted_parameters) { - if (dynamic_param_map_.count(join_path(event->node, deleted_parameter.name))) { - result = true; - } - } - return result; - } - - // Cached Map of dynamic parameters. Parameter values are initialized - // from remote nodes if the parameter exists - std::map<std::string, rclcpp::Parameter> dynamic_param_map_; - - // Map to store parameter clients to remote nodes - std::map<std::string, rclcpp::SyncParametersClient::SharedPtr> parameters_clients_; - - rclcpp::Node::SharedPtr node_; - - // Vector of unique namespaces added - std::vector<std::string> node_namespaces_; - - // vector of event subscriptions for each namespace - std::vector<rclcpp::Subscription - <rcl_interfaces::msg::ParameterEvent>::SharedPtr> event_subscriptions_; - - // Users of this class will pass in an event callback - std::function<void()> user_callback_; - - // Pointer to latest event message - rcl_interfaces::msg::ParameterEvent::SharedPtr last_event_; -}; - -} // namespace nav2_dynamic_params - -#endif // NAV2_DYNAMIC_PARAMS__DYNAMIC_PARAMS_CLIENT_HPP_ diff --git a/nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_validator.hpp b/nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_validator.hpp deleted file mode 100644 index e4b46cd6..00000000 --- a/nav2_dynamic_params/include/nav2_dynamic_params/dynamic_params_validator.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef NAV2_DYNAMIC_PARAMS__DYNAMIC_PARAMS_VALIDATOR_HPP_ -#define NAV2_DYNAMIC_PARAMS__DYNAMIC_PARAMS_VALIDATOR_HPP_ - -#include <map> -#include <string> -#include <utility> -#include <vector> -#include "rclcpp/rclcpp.hpp" - -namespace nav2_dynamic_params -{ - -class DynamicParamsValidator -{ -public: - explicit DynamicParamsValidator(rclcpp::Node::SharedPtr node, bool reject_new_params = false); - - ~DynamicParamsValidator() {} - - void add_param(const std::string & param_name, const rclcpp::ParameterType & type); - - void add_param( - const std::string & param_name, const rclcpp::ParameterType & type, - std::pair<double, double> bounds); - - void add_param( - const std::string & param_name, const rclcpp::ParameterType & type, - std::pair<double, double> bounds, const int & ignore_bound); - - void add_param(const std::map<std::string, rclcpp::ParameterType> & map); - - // Reject parameter changes to static parameters - void add_static_params(std::vector<std::string> static_param_names); - - void set_validation_callback( - std::function<rcl_interfaces::msg::SetParametersResult( - const std::vector<rclcpp::Parameter> &)> callback); - -private: - rcl_interfaces::msg::SetParametersResult param_validation_callback( - std::vector<rclcpp::Parameter> parameters); - - bool validate_param(const rclcpp::Parameter & param); - - bool validate_param_bounds(const rclcpp::Parameter & param); - - bool check_if_static(const rclcpp::Parameter & param); - - template<rclcpp::ParameterType ParamT> - bool check_bound_of_type(const rclcpp::Parameter & param) - { - auto value = param.get_value<ParamT>(); - auto name = param.get_name(); - if (value >= param_bound_map_[name].first && value <= param_bound_map_[name].second) { - return true; - } else { - RCLCPP_WARN(node_->get_logger(), - "Parameter Change Denied::Outside Bounds: %s", name.c_str()); - return false; - } - } - - rclcpp::Node::SharedPtr node_; - bool reject_new_params_; - std::map<std::string, rclcpp::ParameterType> param_map_; - std::map<std::string, std::pair<double, double>> param_bound_map_; - std::vector<std::string> static_params_; - - std::function<rcl_interfaces::msg::SetParametersResult( - const std::vector<rclcpp::Parameter> &)> validation_callback_; -}; - -} // namespace nav2_dynamic_params - -#endif // NAV2_DYNAMIC_PARAMS__DYNAMIC_PARAMS_VALIDATOR_HPP_ diff --git a/nav2_dynamic_params/package.xml b/nav2_dynamic_params/package.xml deleted file mode 100644 index 19eeba68..00000000 --- a/nav2_dynamic_params/package.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0"?> -<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> -<package format ="3"> - <name>nav2_dynamic_params</name> - <version>0.2.4</version> - <description> - This package provides a validation class for ROS2 parameters with validation based on parameter - type and defined bounds. Support for custom validation callbacks is also provided. Some useful - convenience functions for event callbacks are also provided - </description> - <maintainer email="brian.wilcox@intel.com">Brian Wilcox</maintainer> - <license>Apache-2.0</license> - - <buildtool_depend>ament_cmake</buildtool_depend> - <build_depend>nav2_common</build_depend> - <build_depend>nav2_util</build_depend> - - <depend>rclcpp</depend> - <depend>rclcpp_lifecycle</depend> - - <test_depend>ament_cmake_gtest</test_depend> - <test_depend>ament_cmake_pytest</test_depend> - <test_depend>ament_lint_common</test_depend> - <test_depend>ament_lint_auto</test_depend> - <test_depend>launch</test_depend> - <test_depend>launch_testing</test_depend> - - <export> - <build_type>ament_cmake</build_type> - </export> -</package> diff --git a/nav2_dynamic_params/src/dynamic_params_validator.cpp b/nav2_dynamic_params/src/dynamic_params_validator.cpp deleted file mode 100644 index c5661635..00000000 --- a/nav2_dynamic_params/src/dynamic_params_validator.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <map> -#include <string> -#include <utility> -#include <vector> -#include <limits> -#include "nav2_dynamic_params/dynamic_params_validator.hpp" - -namespace nav2_dynamic_params -{ - -DynamicParamsValidator::DynamicParamsValidator(rclcpp::Node::SharedPtr node, bool reject_new_params) -: node_(node), - reject_new_params_(reject_new_params) -{ - node_->register_param_change_callback( - std::bind(&DynamicParamsValidator::param_validation_callback, this, std::placeholders::_1)); -} - -rcl_interfaces::msg::SetParametersResult DynamicParamsValidator::param_validation_callback( - std::vector<rclcpp::Parameter> parameters) -{ - auto result = rcl_interfaces::msg::SetParametersResult(); - result.successful = true; - - for (auto parameter : parameters) { - RCLCPP_INFO(node_->get_logger(), - "Parameter Change Request: %s", (parameter.get_name()).c_str()); - - // Check if parameter is static - if (check_if_static(parameter)) { - result.successful = false; - return result; - } - - // Validate Parameter Type - if (param_map_.count(parameter.get_name()) > 0) { - if (!validate_param(parameter)) { - result.successful = false; - return result; - } - } else { - // Default to accept new parameters - if (reject_new_params_) { - result.successful = false; - RCLCPP_WARN(node_->get_logger(), - "Parameter Change Denied::Parameter Not Registered: %s", - parameter.get_name().c_str()); - return result; - } - } - - // Validate Parameter Bounds - if (param_bound_map_.count(parameter.get_name()) > 0) { - if (!validate_param_bounds(parameter)) { - result.successful = false; - return result; - } - } - } - - // Check Custom Validation Callback if provided - if (validation_callback_) { - return validation_callback_(parameters); - } - - return result; -} - -void DynamicParamsValidator::add_param( - const std::string & param_name, const rclcpp::ParameterType & type) -{ - param_map_[param_name] = type; -} - -void DynamicParamsValidator::add_param( - const std::string & param_name, const rclcpp::ParameterType & type, - std::pair<double, double> bounds) -{ - param_map_[param_name] = type; - param_bound_map_[param_name] = bounds; -} - -void DynamicParamsValidator::add_param( - const std::string & param_name, const rclcpp::ParameterType & type, - std::pair<double, double> bounds, const int & ignore_bound) -{ - param_map_[param_name] = type; - if (ignore_bound) { - bounds.second = std::numeric_limits<double>::infinity(); - } else { - bounds.first = -std::numeric_limits<double>::infinity(); - } - param_bound_map_[param_name] = bounds; -} - -void DynamicParamsValidator::add_param(const std::map<std::string, rclcpp::ParameterType> & map) -{ - param_map_.insert(map.begin(), map.end()); -} - -void DynamicParamsValidator::add_static_params(std::vector<std::string> param_names) -{ - static_params_.insert(static_params_.end(), param_names.begin(), param_names.end()); -} - -void DynamicParamsValidator::set_validation_callback( - std::function<rcl_interfaces::msg::SetParametersResult( - const std::vector<rclcpp::Parameter> &)> callback) -{ - validation_callback_ = callback; -} - -bool DynamicParamsValidator::validate_param(const rclcpp::Parameter & param) -{ - if (param_map_[param.get_name()] == param.get_type()) { - return true; - } else { - RCLCPP_WARN(node_->get_logger(), - "Parameter Change Denied::Doesn't Match Type: %s", param.get_name().c_str()); - return false; - } -} - -bool DynamicParamsValidator::validate_param_bounds(const rclcpp::Parameter & param) -{ - if (param.get_type() == rclcpp::ParameterType::PARAMETER_DOUBLE) { - return check_bound_of_type<rclcpp::ParameterType::PARAMETER_DOUBLE>(param); - } - - if (param.get_type() == rclcpp::ParameterType::PARAMETER_INTEGER) { - return check_bound_of_type<rclcpp::ParameterType::PARAMETER_INTEGER>(param); - } - RCLCPP_WARN(node_->get_logger(), - "Parameter Change Denied:: Can Only Check Bounds of Type int or double: %s", - param.get_name().c_str()); - return false; -} - -bool DynamicParamsValidator::check_if_static(const rclcpp::Parameter & param) -{ - if (std::find(static_params_.begin(), static_params_.end(), - param.get_name()) != static_params_.end()) - { - RCLCPP_WARN(node_->get_logger(), - "Parameter Change Denied::Parameter is static: %s", param.get_name().c_str()); - return true; - } else { - return false; - } -} - - -} // namespace nav2_dynamic_params diff --git a/nav2_dynamic_params/src/example_dynamic_params_client.cpp b/nav2_dynamic_params/src/example_dynamic_params_client.cpp deleted file mode 100644 index c4cb2303..00000000 --- a/nav2_dynamic_params/src/example_dynamic_params_client.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <memory> -#include <sstream> -#include <string> -#include <vector> -#include "nav2_dynamic_params/dynamic_params_client.hpp" -#include "rclcpp/rclcpp.hpp" - -nav2_dynamic_params::DynamicParamsClient * dynamic_params_client; - -// Define a user event callback -void event_callback() -{ - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "\nEvent Callback!"); - - if (dynamic_params_client->is_in_event("foo")) { - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "'foo' is in this event!"); - } - - if (dynamic_params_client->is_in_event("example_node_B", "bar")) { - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), - "'example_node_B/bar' is in this event!"); - } - - double foo; - dynamic_params_client->get_event_param("example_node_A", "foo", foo); - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "foo: %f", foo); - - int bar_B; - dynamic_params_client->get_event_param_or("example_node_B", "bar", bar_B, 2); - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "bar_B: %d", bar_B); - - int bar_C; - dynamic_params_client->get_event_param_or("some_namespace/example_node_C", "bar", bar_C, 3); - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "bar_C: %d", bar_C); - - std::string baz; - dynamic_params_client->get_event_param_or("some_namespace", "example_node_C", - "baz", baz, std::string("default")); - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "baz: %s", baz.c_str()); - - // Parameter not set on node - double foobar; - dynamic_params_client->get_event_param_or("foobar", foobar, 5.5); - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "foobar: %f", foobar); - - int foobaz; - dynamic_params_client->get_event_param_or("foobaz", foobaz, 25); - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), "foobaz: %d", foobaz); -} - - -int main(int argc, char ** argv) -{ - rclcpp::init(argc, argv); - - auto node = rclcpp::Node::make_shared("example_dynamic_params_client", "some_other_namespace"); - node->set_parameter_if_not_set("foobaz", 50); - - // Add Dynamic Reconfigure Client - dynamic_params_client = new nav2_dynamic_params::DynamicParamsClient(node); - // Add parameters by node. Note that there are different ways to add parameters - // The namespace must be provided, if applicable - dynamic_params_client->add_parameters("example_node_A", {"foo"}); - // If node is not available for service, then none of its parameters will be registered - dynamic_params_client->add_parameters_on_node("example_node_B"); - dynamic_params_client->add_parameters("some_namespace", "example_node_C", {"baz", "bar"}); - // without node path, adding only parameters will grab parameters from member node - dynamic_params_client->add_parameters({"foobar", "foobaz"}); - - dynamic_params_client->set_callback(std::bind(event_callback)); - - // Check list of parameters - auto list = dynamic_params_client->get_param_names(); - std::stringstream ss; - for (auto & param_name : list) { - ss << "\n" << param_name; - } - - RCLCPP_INFO(node->get_logger(), ss.str().c_str()); - - rclcpp::spin(node); - rclcpp::shutdown(); - - delete dynamic_params_client; - return 0; -} diff --git a/nav2_dynamic_params/src/example_dynamic_params_validator.cpp b/nav2_dynamic_params/src/example_dynamic_params_validator.cpp deleted file mode 100644 index 955357e8..00000000 --- a/nav2_dynamic_params/src/example_dynamic_params_validator.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <memory> -#include <sstream> -#include <vector> -#include "nav2_dynamic_params/dynamic_params_validator.hpp" -#include "rclcpp/rclcpp.hpp" - -using rcl_interfaces::msg::SetParametersResult; -using namespace std::chrono_literals; - -// Define a custom validation callback -SetParametersResult custom_validation_callback(const std::vector<rclcpp::Parameter> & parameters) -{ - auto result = SetParametersResult(); - result.successful = true; - - for (const auto & parameter : parameters) { - // Filter for parameter "foo" - if (parameter.get_name() == "foo") { - auto value = parameter.get_value<double>(); - // Reject any set requests between 10 & 20 - if (value > 10.0 && value < 20.0) { - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), - "Parameter Change Denied::Failing Custom Validation: %s", - parameter.get_name().c_str()); - result.successful = false; - return result; - } - } - } - return result; -} - -int main(int argc, char ** argv) -{ - rclcpp::init(argc, argv); - - auto node_A = rclcpp::Node::make_shared("example_node_A"); - auto node_B = rclcpp::Node::make_shared("example_node_B"); - auto node_C = rclcpp::Node::make_shared("example_node_C", "some_namespace"); - - // Create DynamicParamsValidator - auto param_validator_A = new nav2_dynamic_params::DynamicParamsValidator(node_A, true); - param_validator_A->add_param("foo", rclcpp::ParameterType::PARAMETER_DOUBLE); - param_validator_A->set_validation_callback( - std::bind(custom_validation_callback, std::placeholders::_1)); - - auto param_validator_B = new nav2_dynamic_params::DynamicParamsValidator(node_B); - param_validator_B->add_param("bar", rclcpp::ParameterType::PARAMETER_INTEGER, {0, 10}); - - auto param_validator_C = new nav2_dynamic_params::DynamicParamsValidator(node_C, true); - param_validator_C->add_param("bar", rclcpp::ParameterType::PARAMETER_INTEGER, {-25, 25}); - param_validator_C->add_param("baz", rclcpp::ParameterType::PARAMETER_STRING); - - // Set parameters on the node - node_A->set_parameter_if_not_set("foo", 1.0); - node_B->set_parameter_if_not_set("bar", 1); - node_C->set_parameter_if_not_set("baz", "my_string"); - node_C->set_parameter_if_not_set("bar", -1); - rclcpp::sleep_for(100ms); - // Change Parameters - RCLCPP_INFO(node_A->get_logger(), "1st Service Request:"); - node_A->set_parameters({rclcpp::Parameter("foo", 2.0)}); - node_B->set_parameters({rclcpp::Parameter("bar", 3)}); - node_C->set_parameters_atomically({ - rclcpp::Parameter("bar", 5), - rclcpp::Parameter("baz", "my_new_string") - }); - rclcpp::sleep_for(100ms); - // Try to set illegal values - RCLCPP_INFO(node_A->get_logger(), "2nd Service Request:"); - node_A->set_parameters({rclcpp::Parameter("foo", 1)}); - node_A->set_parameters({rclcpp::Parameter("foobar", 28.0)}); - node_B->set_parameters({rclcpp::Parameter("bar", 11)}); - rclcpp::sleep_for(100ms); - // Set new parameter on B - RCLCPP_INFO(node_A->get_logger(), "3rd Service Request:"); - node_B->set_parameters({rclcpp::Parameter("foobar", 28.0)}); - rclcpp::sleep_for(100ms); - // Make "foobar" a static parameter & attempt to set again - param_validator_B->add_static_params({"foobar"}); - RCLCPP_INFO(node_A->get_logger(), "4th Service Request:"); - node_B->set_parameters({rclcpp::Parameter("foobar", 5.0)}); - rclcpp::sleep_for(100ms); - // Try to set "foo" to illegal value from custom validation callback - RCLCPP_INFO(node_A->get_logger(), "5th Service Request:"); - node_A->set_parameters({rclcpp::Parameter("foo", 15.0)}); - rclcpp::sleep_for(100ms); - - rclcpp::executors::MultiThreadedExecutor exec; - exec.add_node(node_A); - exec.add_node(node_B); - exec.add_node(node_C); - exec.spin(); - rclcpp::shutdown(); - - delete param_validator_A; - delete param_validator_B; - delete param_validator_C; - - return 0; -} diff --git a/nav2_dynamic_params/test/CMakeLists.txt b/nav2_dynamic_params/test/CMakeLists.txt deleted file mode 100755 index f61cc791..00000000 --- a/nav2_dynamic_params/test/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -add_executable(test_dynamic_params_helper test_dynamic_params_helper.cpp) - -ament_target_dependencies(test_dynamic_params_helper ${dependencies}) - -target_link_libraries(test_dynamic_params_helper - nav2_dynamic_params -) - -install(TARGETS test_dynamic_params_helper - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION lib/${PROJECT_NAME} -) - -ament_add_gtest(test_dynamic_params_validator test_dynamic_params_validator.cpp) - -ament_target_dependencies(test_dynamic_params_validator ${dependencies}) - -target_link_libraries(test_dynamic_params_validator - nav2_dynamic_params -) - -ament_add_gtest_executable(test_dynamic_params_client_exec test_dynamic_params_client.cpp) - -ament_target_dependencies(test_dynamic_params_client_exec ${dependencies}) - -target_link_libraries(test_dynamic_params_client_exec - nav2_dynamic_params -) - -ament_add_test(test_dynamic_params_client - GENERATE_RESULT_FOR_RETURN_CODE_ZERO - COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/dynamic_params_test.launch.py" - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" - ENV - TEST_EXECUTABLE=$<TARGET_FILE:test_dynamic_params_client_exec> -) \ No newline at end of file diff --git a/nav2_dynamic_params/test/dynamic_params_test.launch.py b/nav2_dynamic_params/test/dynamic_params_test.launch.py deleted file mode 100755 index 469e5409..00000000 --- a/nav2_dynamic_params/test/dynamic_params_test.launch.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import sys - -from launch import LaunchDescription -from launch import LaunchService -from launch.actions import ExecuteProcess -import launch_ros.actions -from launch_testing.legacy import LaunchTestService - - -def generate_launch_description(): - return LaunchDescription([ - launch_ros.actions.Node( - package='nav2_dynamic_params', - node_executable='test_dynamic_params_helper', - output='screen') - ]) - - -def main(argv=sys.argv[1:]): - testExecutable = os.getenv('TEST_EXECUTABLE') - ld = generate_launch_description() - - test1_action = ExecuteProcess( - cmd=[testExecutable], - name='test_dynamic_params_client', - ) - - lts = LaunchTestService() - lts.add_test_action(ld, test1_action) - ls = LaunchService(argv=argv) - ls.include_launch_description(ld) - return lts.run(ls) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/nav2_dynamic_params/test/test_dynamic_params_client.cpp b/nav2_dynamic_params/test/test_dynamic_params_client.cpp deleted file mode 100755 index 2be07b1e..00000000 --- a/nav2_dynamic_params/test/test_dynamic_params_client.cpp +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <memory> -#include <sstream> -#include <string> -#include <vector> -#include <chrono> - -#include "gtest/gtest.h" -#include "nav2_dynamic_params/dynamic_params_client.hpp" -#include "rclcpp/rclcpp.hpp" -#include "nav2_util/lifecycle_utils.hpp" -#include "nav2_util/node_utils.hpp" - -using namespace std::chrono_literals; - -class RclCppFixture -{ -public: - RclCppFixture() - { - rclcpp::init(0, nullptr); - nav2_util::startup_lifecycle_nodes("/test_node:/test_namespace/test_node", 5s); - } - ~RclCppFixture() {rclcpp::shutdown();} -}; - -RclCppFixture g_rclcppfixture; - -class DynamicParamsClientTest : public nav2_dynamic_params::DynamicParamsClient -{ -public: - explicit DynamicParamsClientTest(rclcpp::Node::SharedPtr node) - : DynamicParamsClient(node) - {} - - void call_test_event(std::string path, rclcpp::Parameter param, bool is_new = false) - { - auto event = std::make_shared<rcl_interfaces::msg::ParameterEvent>(); - if (is_new) { - event->new_parameters.push_back(param.to_parameter_msg()); - } else { - event->changed_parameters.push_back(param.to_parameter_msg()); - } - event->node = path; - event_callback(event); - } -}; - -class ClientTest : public ::testing::Test -{ -public: - ClientTest() - { - node_ = rclcpp::Node::make_shared( - "dynamic_param_client_test", nav2_util::get_node_options_default()); - dynamic_params_client_ = std::make_unique<DynamicParamsClientTest>(node_); - } - -protected: - std::unique_ptr<DynamicParamsClientTest> dynamic_params_client_; - rclcpp::Node::SharedPtr node_; - bool callback_result_ = false; -}; - -TEST_F(ClientTest, testAddParamsOtherNodes) -{ - node_->set_parameters({rclcpp::Parameter("baz", 1)}); - - dynamic_params_client_->add_parameters(); - dynamic_params_client_->add_parameters_on_node("test_namespace", "test_node"); - dynamic_params_client_->add_parameters("test_namespace", "test_node", {"foobar"}); - dynamic_params_client_->add_parameters("test_node", {"foo"}); - dynamic_params_client_->add_parameters({"foobar"}); - - auto dynamic_param_map = dynamic_params_client_->get_param_map(); - EXPECT_EQ(1u, dynamic_param_map.count("/dynamic_param_client_test/baz")); - EXPECT_EQ(1u, dynamic_param_map.count("/dynamic_param_client_test/foobar")); - EXPECT_EQ(1u, dynamic_param_map.count("/test_node/foo")); - EXPECT_EQ(1u, dynamic_param_map.count("/test_namespace/test_node/bar")); - EXPECT_EQ(1u, dynamic_param_map.count("/test_namespace/test_node/foobar")); - - // Verify that parameters not added to other namespaces/nodes - EXPECT_EQ(0u, dynamic_param_map.count("/dynamic_param_client_test/bar")); - EXPECT_EQ(0u, dynamic_param_map.count("/test_namespace/dynamic_param_client_test/baz")); - EXPECT_EQ(0u, dynamic_param_map.count("/test_node/bar")); -} - -TEST_F(ClientTest, testGetParams) -{ - node_->set_parameters({rclcpp::Parameter("baz", 5)}); - node_->set_parameters({rclcpp::Parameter("foobaz", 5.0)}); - - dynamic_params_client_->add_parameters_on_node("test_namespace", "test_node"); - dynamic_params_client_->add_parameters("test_namespace", "test_node", {"foobar"}); - dynamic_params_client_->add_parameters("test_node", {"foo"}); - dynamic_params_client_->add_parameters(); - dynamic_params_client_->add_parameters({"foobaz"}); - dynamic_params_client_->add_parameters("some_node", {"barbaz"}); - - double foo, foobaz; - int bar, baz, barbaz; - std::string foobar; - - dynamic_params_client_->get_event_param("baz", baz); - dynamic_params_client_->get_event_param("test_namespace", "test_node", "bar", bar); - dynamic_params_client_->get_event_param("test_node", "foo", foo); - - EXPECT_EQ(5, baz); - EXPECT_EQ(1.0, foo); - EXPECT_EQ(1, bar); - - auto result = dynamic_params_client_->get_event_param_or<std::string>( - "test_namespace/test_node", "foobar", foobar, "test"); - EXPECT_EQ(false, result); - result = dynamic_params_client_->get_event_param_or("foobaz", foobaz, 7.0); - EXPECT_EQ(true, result); - result = dynamic_params_client_->get_event_param("some_node", "barbaz", barbaz); - EXPECT_EQ(false, result); - EXPECT_EQ("test", foobar); - EXPECT_EQ(5.0, foobaz); -} - -TEST_F(ClientTest, testEventCallbacks) -{ - dynamic_params_client_->add_parameters({"baz"}); - dynamic_params_client_->add_parameters("test_node", {"foo"}); - dynamic_params_client_->add_parameters("test_namespace", "test_node", {"bar"}); - - auto param_client_A = std::make_shared<rclcpp::SyncParametersClient>(node_, "/test_node"); - auto param_client_B = std::make_shared<rclcpp::SyncParametersClient>( - node_, "/test_namespace/test_node"); - - std::function<void()> callback = [this]() -> void - { - callback_result_ = true; - }; - - dynamic_params_client_->set_callback(callback, false); - - // Directly call into event callback - /* dynamic_params_client_->call_test_event( - "/dynamic_param_client_test", rclcpp::Parameter("baz", 2), true); */ - node_->set_parameters({rclcpp::Parameter("baz", 2)}); - while (!callback_result_) { - rclcpp::spin_some(node_); - } - - EXPECT_EQ(true, callback_result_); - int baz; - dynamic_params_client_->get_event_param("baz", baz); - EXPECT_EQ(2, baz); - callback_result_ = false; - - // Directly call into event callback - // dynamic_params_client_->call_test_event("/test_node", rclcpp::Parameter("foo", 3.0), false); - param_client_A->set_parameters({rclcpp::Parameter("foo", 3.0)}); - while (!callback_result_) { - rclcpp::spin_some(node_); - } - - EXPECT_EQ(true, callback_result_); - double foo; - dynamic_params_client_->get_event_param("test_node", "foo", foo); - EXPECT_EQ(3.0, foo); - callback_result_ = false; - - // Directly call into event callback - /* dynamic_params_client_->call_test_event( - "/test_namespace/test_node", rclcpp::Parameter("bar", 5), false); */ - param_client_B->set_parameters({rclcpp::Parameter("bar", 5)}); - while (!callback_result_) { - rclcpp::spin_some(node_); - } - - EXPECT_EQ(true, callback_result_); - int bar; - dynamic_params_client_->get_event_param("test_namespace", "test_node", "bar", bar); - EXPECT_EQ(5, bar); - callback_result_ = false; - - // Check that parameter is in the last event - EXPECT_EQ(true, dynamic_params_client_->is_in_event("test_namespace", "test_node", "bar")); - EXPECT_EQ(false, dynamic_params_client_->is_in_event("foo")); - - // If data type unexpectedly changes, callback should be skipped - dynamic_params_client_->call_test_event( - "/dynamic_param_client_test", rclcpp::Parameter("bar", "hello"), false); - EXPECT_EQ(false, callback_result_); - dynamic_params_client_->get_event_param("baz", baz); - EXPECT_EQ(2, baz); -} diff --git a/nav2_dynamic_params/test/test_dynamic_params_helper.cpp b/nav2_dynamic_params/test/test_dynamic_params_helper.cpp deleted file mode 100755 index efb1b4af..00000000 --- a/nav2_dynamic_params/test/test_dynamic_params_helper.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <memory> -#include <sstream> -#include <string> -#include <vector> - -#include "nav2_dynamic_params/dynamic_params_client.hpp" -#include "nav2_util/node_utils.hpp" -#include "rclcpp/rclcpp.hpp" -#include "rclcpp_lifecycle/lifecycle_node.hpp" - -int main(int argc, char ** argv) -{ - rclcpp::init(argc, argv); - - auto node_A = rclcpp_lifecycle::LifecycleNode::make_shared( - "test_node", nav2_util::get_node_options_default()); - auto node_B = rclcpp_lifecycle::LifecycleNode::make_shared( - "test_node", "test_namespace", nav2_util::get_node_options_default()); - - node_A->set_parameters({rclcpp::Parameter("foo", 1.0)}); - node_B->set_parameters({rclcpp::Parameter("bar", 1)}); - - rclcpp::executors::SingleThreadedExecutor exec; - exec.add_node(node_A->get_node_base_interface()); - exec.add_node(node_B->get_node_base_interface()); - exec.spin(); - - rclcpp::shutdown(); - return 0; -} diff --git a/nav2_dynamic_params/test/test_dynamic_params_validator.cpp b/nav2_dynamic_params/test/test_dynamic_params_validator.cpp deleted file mode 100755 index 694a92c8..00000000 --- a/nav2_dynamic_params/test/test_dynamic_params_validator.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) 2018 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <memory> -#include <string> -#include <vector> - -#include "gtest/gtest.h" -#include "nav2_dynamic_params/dynamic_params_validator.hpp" -#include "nav2_util/node_utils.hpp" -#include "rclcpp/rclcpp.hpp" - -using rcl_interfaces::msg::SetParametersResult; - -class RclCppFixture -{ -public: - RclCppFixture() {rclcpp::init(0, nullptr);} - ~RclCppFixture() {rclcpp::shutdown();} -}; - -RclCppFixture g_rclcppfixture; - -// Define a custom validation callback -SetParametersResult custom_validation_callback(const std::vector<rclcpp::Parameter> & parameters) -{ - auto result = SetParametersResult(); - result.successful = true; - - for (const auto & parameter : parameters) { - // Filter for parameter "foo" - if (parameter.get_name() == "custom_param") { - auto value = parameter.get_value<double>(); - // Reject any set requests between 10 & 20 - if (value > 10.0 && value < 20.0) { - RCLCPP_INFO(rclcpp::get_logger("example_dynamic_params"), - "Parameter Change Denied::Failing Custom Validation: %s", - parameter.get_name().c_str()); - result.successful = false; - return result; - } - } - } - return result; -} - -class ValidatorTest : public ::testing::Test -{ -public: - ValidatorTest() - { - node_ = rclcpp::Node::make_shared( - "dynamic_param_validator_test", nav2_util::get_node_options_default()); - param_validator_ = std::make_unique<nav2_dynamic_params::DynamicParamsValidator>(node_); - } - -protected: - std::unique_ptr<nav2_dynamic_params::DynamicParamsValidator> param_validator_; - rclcpp::Node::SharedPtr node_; -}; - - -TEST_F(ValidatorTest, testValidType) -{ - param_validator_->add_param("double", rclcpp::ParameterType::PARAMETER_DOUBLE); - param_validator_->add_param("int", rclcpp::ParameterType::PARAMETER_INTEGER); - param_validator_->add_param("string", rclcpp::ParameterType::PARAMETER_STRING); - param_validator_->add_param("bool", rclcpp::ParameterType::PARAMETER_BOOL); - param_validator_->add_param("double_array", rclcpp::ParameterType::PARAMETER_DOUBLE_ARRAY); - param_validator_->add_param("int_array", rclcpp::ParameterType::PARAMETER_INTEGER_ARRAY); - param_validator_->add_param("string_array", rclcpp::ParameterType::PARAMETER_STRING_ARRAY); - param_validator_->add_param("bool_array", rclcpp::ParameterType::PARAMETER_BOOL_ARRAY); - - // Set valid type values - auto valid_results = node_->set_parameters({ - rclcpp::Parameter("double", 1.0), - rclcpp::Parameter("int", 1), - rclcpp::Parameter("string", "test"), - rclcpp::Parameter("bool", true), - rclcpp::Parameter("double_array", std::vector<double>({1.0, 2.0})), - rclcpp::Parameter("int_array", std::vector<int>({1, 2})), - rclcpp::Parameter("string_array", std::vector<std::string>({"test_1", "test_2"})), - rclcpp::Parameter("bool_array", std::vector<bool>({true, false})) - }); - - // Set invalid type values - auto invalid_results = node_->set_parameters({ - rclcpp::Parameter("double", 1), - rclcpp::Parameter("int", 1.0), - rclcpp::Parameter("string", 1), - rclcpp::Parameter("bool", 1), - rclcpp::Parameter("double_array", 1), - rclcpp::Parameter("int_array", 1), - rclcpp::Parameter("string_array", 1), - rclcpp::Parameter("bool_array", 1), - }); - - for (auto result : valid_results) { - EXPECT_EQ(true, result.successful); - } - for (auto result : invalid_results) { - EXPECT_EQ(false, result.successful); - } -} - -TEST_F(ValidatorTest, testValidRange) -{ - param_validator_->add_param( - "double_bound", rclcpp::ParameterType::PARAMETER_DOUBLE, {0.0, 10.0}); - param_validator_->add_param( - "double_low_bound", rclcpp::ParameterType::PARAMETER_DOUBLE, {0.0, 10.0}, 0); - param_validator_->add_param( - "double_high_bound", rclcpp::ParameterType::PARAMETER_DOUBLE, {0.0, 10.0}, 1); - param_validator_->add_param( - "int_bound", rclcpp::ParameterType::PARAMETER_INTEGER, {0, 10}); - param_validator_->add_param( - "int_low_bound", rclcpp::ParameterType::PARAMETER_INTEGER, {0, 10}, 0); - param_validator_->add_param( - "int_high_bound", rclcpp::ParameterType::PARAMETER_INTEGER, {0, 10}, 1); - param_validator_->add_param( - "string_invalid_bound", rclcpp::ParameterType::PARAMETER_STRING, {0, 10}); - - auto valid_results = node_->set_parameters({ - rclcpp::Parameter("double_bound", 5.0), - rclcpp::Parameter("double_low_bound", -100.0), - rclcpp::Parameter("double_high_bound", 100.0), - rclcpp::Parameter("int_bound", 5), - rclcpp::Parameter("int_low_bound", -100), - rclcpp::Parameter("int_high_bound", 100), - }); - - // Set invalid type values - auto invalid_results = node_->set_parameters({ - rclcpp::Parameter("double_bound", 11.0), - rclcpp::Parameter("double_low_bound", 11.0), - rclcpp::Parameter("double_high_bound", -1.0), - rclcpp::Parameter("int_bound", 11), - rclcpp::Parameter("int_low_bound", 11), - rclcpp::Parameter("int_high_bound", -1), - rclcpp::Parameter("string_invalid_bound", "test"), - }); - - for (auto result : valid_results) { - EXPECT_EQ(true, result.successful); - } - for (auto result : invalid_results) { - EXPECT_EQ(false, result.successful); - } -} - -TEST_F(ValidatorTest, testStaticParams) -{ - param_validator_->add_param( - "static_param", rclcpp::ParameterType::PARAMETER_DOUBLE); - param_validator_->add_param( - "non_static_param", rclcpp::ParameterType::PARAMETER_DOUBLE); - - param_validator_->add_static_params({"static_param"}); - - auto invalid_result = node_->set_parameters_atomically( - {rclcpp::Parameter("static_param", 1.0)}); - auto valid_result = node_->set_parameters_atomically( - {rclcpp::Parameter("non_static_param", 1.0)}); - - EXPECT_EQ(false, invalid_result.successful); - EXPECT_EQ(true, valid_result.successful); -} - -TEST_F(ValidatorTest, testCustomValidation) -{ - param_validator_->add_param("param", rclcpp::ParameterType::PARAMETER_DOUBLE); - param_validator_->add_param("custom_param", rclcpp::ParameterType::PARAMETER_DOUBLE); - - param_validator_->set_validation_callback( - std::bind(custom_validation_callback, std::placeholders::_1)); - - auto valid_result = node_->set_parameters_atomically( - {rclcpp::Parameter("param", 15.0)}); - auto valid_result_custom = node_->set_parameters_atomically( - {rclcpp::Parameter("custom_param", 10.0)}); - auto invalid_result = node_->set_parameters_atomically( - {rclcpp::Parameter("custom_param", 15.0)}); - - EXPECT_EQ(false, invalid_result.successful); - EXPECT_EQ(true, valid_result_custom.successful); - EXPECT_EQ(true, valid_result.successful); -} -- GitLab