From 4160917a421a1e985cb61f7531b26e5ab935181b Mon Sep 17 00:00:00 2001 From: grufoony Date: Mon, 3 Nov 2025 15:51:21 +0100 Subject: [PATCH 1/7] Refactor some benhcs --- CMakeLists.txt | 8 ++ benchmark/Bench_Network.cpp | 78 +++++++++++++++++ benchmark/CMakeLists.txt | 49 +++++++++-- benchmark/Dynamics/BenchDynamics.cpp | 64 -------------- benchmark/Dynamics/CMakeLists.txt | 37 -------- benchmark/Graph/BenchGraph.cpp | 59 ------------- benchmark/Graph/CMakeLists.txt | 23 ----- benchmark/Graph/data/matrix.dat | 121 --------------------------- benchmark/Street/BenchStreet.cpp | 27 ------ benchmark/Street/CMakeLists.txt | 23 ----- 10 files changed, 128 insertions(+), 361 deletions(-) create mode 100644 benchmark/Bench_Network.cpp delete mode 100644 benchmark/Dynamics/BenchDynamics.cpp delete mode 100644 benchmark/Dynamics/CMakeLists.txt delete mode 100644 benchmark/Graph/BenchGraph.cpp delete mode 100644 benchmark/Graph/CMakeLists.txt delete mode 100644 benchmark/Graph/data/matrix.dat delete mode 100644 benchmark/Street/BenchStreet.cpp delete mode 100644 benchmark/Street/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index bd06993ce..27daf81c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ project( option(DSF_TESTS "Build DSF tests" OFF) option(DSF_EXAMPLES "Build DSF examples" OFF) +option(DSF_BENCHMARKS "Build DSF benchmarks" OFF) option(DSF_BUILD_PIC "Build DSF with position-independent code" OFF) option(BUILD_PYTHON_BINDINGS "Build Python bindings" OFF) @@ -238,4 +239,11 @@ message(STATUS "Build DSF examples: ${DSF_EXAMPLES}") if(DSF_EXAMPLES) set(CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH}") add_subdirectory(examples) +endif() + +# Benchmarks +message(STATUS "Build DSF benchmarks: ${DSF_BENCHMARKS}") +if(DSF_BENCHMARKS) + set(CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH}") + add_subdirectory(benchmark) endif() \ No newline at end of file diff --git a/benchmark/Bench_Network.cpp b/benchmark/Bench_Network.cpp new file mode 100644 index 000000000..aeb9447e9 --- /dev/null +++ b/benchmark/Bench_Network.cpp @@ -0,0 +1,78 @@ +#include "dsf/mobility/RoadNetwork.hpp" + +#include + +#include + +static const auto DATA_FOLDER = + std::filesystem::path(__FILE__).parent_path().parent_path() / "test/data"; + +static void BM_RoadNetwork_AddNode(benchmark::State& state) { + dsf::mobility::RoadNetwork network; + dsf::Id nodeId{0}; + for (auto _ : state) { + network.addNode(nodeId++); + } +} +static void BM_RoadNetwork_AddEdge(benchmark::State& state) { + dsf::mobility::RoadNetwork network; + dsf::Id source{0}, target{1}; + for (auto _ : state) { + network.addEdge(source, std::make_pair(source++, target++)); + } +} +static void BM_RoadNetwork_CSVImport(benchmark::State& state) { + for (auto _ : state) { + dsf::mobility::RoadNetwork network; + network.importEdges((DATA_FOLDER / "postua_edges.csv").string()); + network.importNodeProperties((DATA_FOLDER / "postua_nodes.csv").string()); + } +} +static void BM_RoadNetwork_GeoJSONImport(benchmark::State& state) { + for (auto _ : state) { + dsf::mobility::RoadNetwork network; + network.importEdges((DATA_FOLDER / "postua_edges.geojson").string()); + network.importNodeProperties((DATA_FOLDER / "postua_nodes.csv").string()); + } +} +static void BM_RoadNetwork_NodesLooping(benchmark::State& state) { + dsf::mobility::RoadNetwork network; + network.importEdges((DATA_FOLDER / "forlì_edges.csv").string()); + network.importNodeProperties((DATA_FOLDER / "forlì_nodes.csv").string()); + for (auto _ : state) { + for (auto const& [id, node] : network.nodes()) { + benchmark::DoNotOptimize(id); + benchmark::DoNotOptimize(node); + } + } +} +static void BM_RoadNetwork_EdgesLooping(benchmark::State& state) { + dsf::mobility::RoadNetwork network; + network.importEdges((DATA_FOLDER / "forlì_edges.csv").string()); + network.importNodeProperties((DATA_FOLDER / "forlì_nodes.csv").string()); + for (auto _ : state) { + for (auto const& [id, edge] : network.edges()) { + benchmark::DoNotOptimize(id); + benchmark::DoNotOptimize(edge); + } + } +} +static void BM_RoadNetwork_ShortestPath(benchmark::State& state) { + dsf::mobility::RoadNetwork network; + network.importEdges((DATA_FOLDER / "forlì_edges.csv").string()); + network.importNodeProperties((DATA_FOLDER / "forlì_nodes.csv").string()); + auto itNode = network.nodes().cbegin(); + for (auto _ : state) { + auto paths = network.allPathsTo(itNode->first, [](auto const& pEdge) { return pEdge->length(); }); + ++itNode; + } +} +BENCHMARK(BM_RoadNetwork_AddNode); +BENCHMARK(BM_RoadNetwork_AddEdge); +BENCHMARK(BM_RoadNetwork_CSVImport); +BENCHMARK(BM_RoadNetwork_GeoJSONImport); +BENCHMARK(BM_RoadNetwork_NodesLooping); +BENCHMARK(BM_RoadNetwork_EdgesLooping); +BENCHMARK(BM_RoadNetwork_ShortestPath); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 8ed0d3e95..f3b118dda 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,15 +1,50 @@ cmake_minimum_required(VERSION 3.16.0) -project(Benchmark VERSION 1.0.1 LANGUAGES CXX) +project(dsf_benchmarks VERSION 3.0.0 LANGUAGES CXX) -# set the C++ standard +# Set the C++ standard set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -include_directories(../extern/benchmark/) +# Check if being built as part of the main DSF project or standalone +if(NOT TARGET dsf) + # Standalone build - need to find installed DSF + find_package(dsf REQUIRED) + find_package(TBB REQUIRED CONFIG) + find_package(simdjson REQUIRED) +else() + # Building as part of main project - dsf target already exists + # TBB and simdjson should already be found by parent + if(NOT TARGET TBB::tbb) + find_package(TBB REQUIRED CONFIG) + endif() + if(NOT TARGET simdjson::simdjson) + find_package(simdjson REQUIRED) + endif() +endif() -# add subdirectories -# add_subdirectory(Graph) -# add_subdirectory(Street) -add_subdirectory(Dynamics) +# Get Google Benchmark +include(FetchContent) +set(BENCHMARK_ENABLE_TESTING OFF) +FetchContent_Declare( + benchmark + GIT_REPOSITORY https://github.com/google/benchmark + GIT_TAG v1.9.4 +) +FetchContent_MakeAvailable(benchmark) + +# add as executable all cpp files into '.' folder +file(GLOB SOURCES "*.cpp") + +# Set the exe folder to be the one of the CMakeLists.txt +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +# Loop through each source file and create an executable +foreach(SOURCE ${SOURCES}) + get_filename_component(EXE_NAME ${SOURCE} NAME_WE) + add_executable(${EXE_NAME}.out ${SOURCE}) + target_compile_definitions(${EXE_NAME}.out PRIVATE SPDLOG_USE_STD_FORMAT) + target_link_libraries(${EXE_NAME}.out PRIVATE dsf TBB::tbb simdjson::simdjson benchmark::benchmark) + target_include_directories(${EXE_NAME}.out PRIVATE $) +endforeach() diff --git a/benchmark/Dynamics/BenchDynamics.cpp b/benchmark/Dynamics/BenchDynamics.cpp deleted file mode 100644 index bb2ace7db..000000000 --- a/benchmark/Dynamics/BenchDynamics.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include - -#include "mobility/RoadNetwork.hpp" -#include "mobility/Itinerary.hpp" -#include "mobility/FirstOrderDynamics.hpp" -#include "Bench.hpp" - -#include - -using RoadNetwork = dsf::mobility::RoadNetwork; -using Itinerary = dsf::mobility::Itinerary; -using Dynamics = dsf::mobility::FirstOrderDynamics; - -using Bench = sb::Bench; - -int main() { - // Declare generator - std::mt19937_64 generator{std::random_device{}()}; - generator.seed(69); - RoadNetwork graph{}; - graph.importEdges("../test/data/forlì_edges.csv"); - graph.importNodeProperties("../test/data/forlì_nodes.csv"); - - Dynamics dynamics{graph}; - // Take 10 random keys from nodes map - std::vector randomNodeIds; - { - std::vector nodeIds; - nodeIds.reserve(dynamics.graph().nNodes()); - for (const auto& pair : dynamics.graph().nodes()) { - nodeIds.push_back(pair.first); - } - std::sample( - nodeIds.begin(), nodeIds.end(), std::back_inserter(randomNodeIds), 10, generator); - } - dynamics.setDestinationNodes(randomNodeIds); - - const int n_rep{100}; - Bench b1(n_rep); - std::cout << "Benchmarking updatePaths\n"; - b1.benchmark([&dynamics]() -> void { dynamics.updatePaths(); }); - std::cout << "Time elapsed after " << n_rep << " repetitions (us):\n"; - b1.print(); - - for (auto const& [itineraryId, pItinerary] : dynamics.itineraries()) { - auto const& path = pItinerary->path(); - auto const& size = path.size(); - double avgPossibleMoves{0.}; - for (auto const& [nodeId, nextHops] : path) { - avgPossibleMoves += nextHops.size(); - } - double avgDegree{0.}; - for (auto const& nodeId : dynamics.graph().nodes()) { - avgDegree += nodeId.second->outgoingEdges().size(); - } - avgDegree /= dynamics.graph().nNodes(); - avgPossibleMoves /= size; - spdlog::info("Itinerary {}: {} nodes, avg possible moves: {:.2f}, avg degree: {:.2f}", - itineraryId, - size, - avgPossibleMoves, - avgDegree); - } -} diff --git a/benchmark/Dynamics/CMakeLists.txt b/benchmark/Dynamics/CMakeLists.txt deleted file mode 100644 index 5dd8d8698..000000000 --- a/benchmark/Dynamics/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -cmake_minimum_required(VERSION 3.16.0) - -# Set the C++ standard -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -find_package(TBB REQUIRED CONFIG) -find_package(spdlog REQUIRED) -find_package(simdjson REQUIRED) - -# Set the C++ flags -string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -Ofast -march=native -flto=auto") - -# Set the folder for the executable -set(EXECUTABLE_OUTPUT_PATH ../../) - -include(FetchContent) -# Get rapidcsv -FetchContent_Declare(rapidcsv - GIT_REPOSITORY https://github.com/d99kris/rapidcsv - GIT_TAG v8.89 -) -FetchContent_GetProperties(rapidcsv) -if(NOT rapidcsv_POPULATED) - FetchContent_MakeAvailable(rapidcsv) -endif() - -include_directories(../../src/dsf) -include_directories(../../src/dsf/utility/) - -file(GLOB SOURCES "../../src/dsf/base/*.cpp" "../../src/dsf/mobility/*.cpp" "../../src/dsf/utility/*.cpp" "../../src/dsf/geometry/*.cpp") - -# Compile -add_executable(bench_dynamics.out BenchDynamics.cpp ${SOURCES}) -target_include_directories(bench_dynamics.out PRIVATE ${rapidcsv_SOURCE_DIR}/src) -target_link_libraries(bench_dynamics.out PRIVATE TBB::tbb fmt::fmt spdlog::spdlog simdjson::simdjson) diff --git a/benchmark/Graph/BenchGraph.cpp b/benchmark/Graph/BenchGraph.cpp deleted file mode 100644 index d9ec24392..000000000 --- a/benchmark/Graph/BenchGraph.cpp +++ /dev/null @@ -1,59 +0,0 @@ - -#include -#include -#include -#include -#include "Bench.hpp" - -#include "mobility/RoadNetwork.hpp" - -using RoadNetwork = dsf::mobility::RoadNetwork; -using Intersection = dsf::mobility::Intersection; -using Street = dsf::mobility::Street; -using SparseMatrix = dsf::SparseMatrix; - -using Bench = sb::Bench; - -int main() { - RoadNetwork g1; - const int n_rep{1000}; - Bench b1(n_rep); - - std::cout << "Benchmarking addNode\n"; - b1.benchmark([&g1]() -> void { g1.addNode(std::rand()); }); - b1.print(); - std::cout << "Benchmarking addNodes overhead for a single node\n"; - // n1 = Intersection(std::rand()); - // b1.benchmark([&g1](const Intersection& node) -> void { g1.addNodes(node); }, n1); - // b1.print(); - - // std::cout << "Benchmarking addStreet\n"; - // Street s1(std::rand(), std::make_pair(0, 1)); - // b1.benchmark([&g1](const Street& street) -> void { g1.addStreet(street); }, s1); - // b1.print(); - // std::cout << "Benchmarking addStreets overhead for a single street\n"; - // s1 = Street(std::rand(), std::make_pair(0, 1)); - // b1.benchmark([&g1](const Street& street) -> void { g1.addStreets(street); }, s1); - // b1.print(); - - const int n_nodes{10000}; - SparseMatrix sm(n_nodes, n_nodes); - std::mt19937 gen; - std::uniform_real_distribution<> dis(0., 1.); - - for (int i{}; i < n_nodes * n_nodes; ++i) { - if (dis(gen) < (4. / n_nodes)) { - sm.insert(i, true); - } - } - Bench b2; - std::cout << "Benchmarking construction with adjacency matrix\n"; - b2.benchmark([&sm]() -> void { RoadNetwork g(sm); }); - b2.print(); - - // Bench b3(1); - // RoadNetwork g2(sm); - // std::cout << "Benchmarking building the adjacency matrix\n"; - // b3.benchmark([&g2]() -> void { g2.buildAdj(); }); - // b3.print(); -} diff --git a/benchmark/Graph/CMakeLists.txt b/benchmark/Graph/CMakeLists.txt deleted file mode 100644 index b5d8a9826..000000000 --- a/benchmark/Graph/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 3.16.0) - -# Set the C++ standard -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -find_package(TBB REQUIRED CONFIG) - -# Set the C++ flags -string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3") - -# Set the folder for the executable -set(EXECUTABLE_OUTPUT_PATH ../../) - -include_directories(../../src/dsf) -include_directories(../../src/dsf/utility/) - -file(GLOB SOURCES "../../src/dsf/base/*.cpp" "../../src/dsf/mobility/*.cpp" "../../src/dsf/utility/*.cpp" "../../src/dsf/geometry/*.cpp") - -# Compile -add_executable(bench_graph.out BenchGraph.cpp ${SOURCES}) -target_link_libraries(bench_graph.out PRIVATE TBB::tbb) diff --git a/benchmark/Graph/data/matrix.dat b/benchmark/Graph/data/matrix.dat deleted file mode 100644 index 097f54c37..000000000 --- a/benchmark/Graph/data/matrix.dat +++ /dev/null @@ -1,121 +0,0 @@ -120 120 -0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 500.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 500.00 0.00 diff --git a/benchmark/Street/BenchStreet.cpp b/benchmark/Street/BenchStreet.cpp deleted file mode 100644 index dd0ec732e..000000000 --- a/benchmark/Street/BenchStreet.cpp +++ /dev/null @@ -1,27 +0,0 @@ - -#include -#include -#include -#include "Bench.hpp" - -#include "mobility/RoadNetwork.hpp" - -using Agent = dsf::mobility::Agent; -using Street = dsf::mobility::Street; -using SparseMatrix = dsf::SparseMatrix; - -using Bench = sb::Bench; - -int main() { - Street street(0, dsf::geometry::Point(0, 1), 5000.); - Agent agent(0, 0, 0); - Bench b(1000); - - // std::cout << "Benchmarking addAgent\n"; - // b.benchmark([&street](Agent ag) -> void { street.addAgent(ag.id()); }, agent); - // b.print(); - - // std::cout << "Benchmarking dequeue\n"; - // b.benchmark([&street]() -> void { street.dequeue(); }); - // b.print(); -} diff --git a/benchmark/Street/CMakeLists.txt b/benchmark/Street/CMakeLists.txt deleted file mode 100644 index d4e888f50..000000000 --- a/benchmark/Street/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 3.16.0) - -# Set the C++ standard -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -find_package(TBB REQUIRED CONFIG) - -# Set the C++ flags -string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3") - -# Set the folder for the executable -set(EXECUTABLE_OUTPUT_PATH ../../) - -include_directories(../../src/dsf) -include_directories(../../src/dsf/utility/) - -file(GLOB SOURCES "../../src/dsf/base/*.cpp" "../../src/dsf/mobility/*.cpp" "../../src/dsf/utility/*.cpp" "../../src/dsf/geometry/*.cpp") - -# Compile -add_executable(bench_street.out BenchStreet.cpp ${SOURCES}) -target_link_libraries(bench_street.out PRIVATE TBB::tbb) From 48940309e8b636d312d7aea042cb2e5be137b847 Mon Sep 17 00:00:00 2001 From: grufoony Date: Tue, 4 Nov 2025 16:18:29 +0100 Subject: [PATCH 2/7] Also profiling --- CMakeLists.txt | 8 ++++++-- benchmark/Bench_Dynamics.cpp | 22 ++++++++++++++++++++++ examples/CMakeLists.txt | 7 +++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 benchmark/Bench_Dynamics.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ec0329a49..b447bb705 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,11 +25,11 @@ option(BUILD_PYTHON_BINDINGS "Build Python bindings" OFF) # If CMAKE_BUILD_TYPE not set, default to Debug if(NOT CMAKE_BUILD_TYPE) - if(BUILD_PYTHON_BINDINGS) + if(BUILD_PYTHON_BINDINGS OR DSF_BENCHMARKS) set(CMAKE_BUILD_TYPE "Release" CACHE STRING - "Build type (default: Release when building Python bindings)" + "Build type (default: Release when building Python bindings or benchmarks)" FORCE) else() set(CMAKE_BUILD_TYPE @@ -53,6 +53,10 @@ if(CMAKE_BUILD_TYPE MATCHES "Release") elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2") endif() +elseif(CMAKE_BUILD_TYPE MATCHES "Profile") + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Ofast -march=native -flto=auto -pg") + endif() elseif(CMAKE_BUILD_TYPE MATCHES "Coverage") set(DSF_TESTS ON) message(STATUS "Enable code coverage") diff --git a/benchmark/Bench_Dynamics.cpp b/benchmark/Bench_Dynamics.cpp new file mode 100644 index 000000000..d9b9d0291 --- /dev/null +++ b/benchmark/Bench_Dynamics.cpp @@ -0,0 +1,22 @@ +#include "dsf/mobility/FirstOrderDynamics.hpp" + +#include + +#include + +static const auto DATA_FOLDER = + std::filesystem::path(__FILE__).parent_path().parent_path() / "test/data"; + +static void BM_FirstOrderDynamics_Empty_Evolve(benchmark::State& state) { + dsf::mobility::RoadNetwork network; + network.importEdges((DATA_FOLDER / "forlì_edges.csv").string()); + network.importNodeProperties((DATA_FOLDER / "forlì_nodes.csv").string()); + dsf::mobility::FirstOrderDynamics dynamics(network); + for (auto _ : state) { + dynamics.evolve(); + } +} + +BENCHMARK(BM_FirstOrderDynamics_Empty_Evolve); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9017cd171..d079c7e21 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -10,6 +10,13 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +# Add -pg flag to enable profiling if DSF_PROFILE is ON +if(DSF_PROFILE) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + endif() +endif() + # Check if being built as part of the main DSF project or standalone if(NOT TARGET dsf) # Standalone build - need to find installed DSF From c27e30d5cb7fc3acd46aa9558af66643e044d987 Mon Sep 17 00:00:00 2001 From: grufoony Date: Wed, 5 Nov 2025 13:01:01 +0100 Subject: [PATCH 3/7] Add benchmarks --- benchmark/Bench_Agent.cpp | 150 ++++++++++++++ benchmark/Bench_Intersection.cpp | 113 +++++++++++ benchmark/Bench_Roundabout.cpp | 79 ++++++++ benchmark/Bench_Street.cpp | 311 ++++++++++++++++++++++++++++++ benchmark/Bench_TrafficLight.cpp | 97 ++++++++++ src/dsf/mobility/RoadDynamics.hpp | 2 +- 6 files changed, 751 insertions(+), 1 deletion(-) create mode 100644 benchmark/Bench_Agent.cpp create mode 100644 benchmark/Bench_Intersection.cpp create mode 100644 benchmark/Bench_Roundabout.cpp create mode 100644 benchmark/Bench_Street.cpp create mode 100644 benchmark/Bench_TrafficLight.cpp diff --git a/benchmark/Bench_Agent.cpp b/benchmark/Bench_Agent.cpp new file mode 100644 index 000000000..18395dde5 --- /dev/null +++ b/benchmark/Bench_Agent.cpp @@ -0,0 +1,150 @@ +#include "dsf/mobility/Agent.hpp" + +#include +#include + +static void BM_Agent_ConstructionWithItineraryId(benchmark::State& state) { + std::time_t spawnTime = 0; + for (auto _ : state) { + dsf::mobility::Agent agent(spawnTime++, 1, 0); + benchmark::DoNotOptimize(agent); + } +} + +static void BM_Agent_ConstructionWithTrip(benchmark::State& state) { + std::time_t spawnTime = 0; + std::vector trip = {1, 2, 3}; + for (auto _ : state) { + dsf::mobility::Agent agent(spawnTime++, trip, 0); + benchmark::DoNotOptimize(agent); + } +} + +static void BM_Agent_ConstructionRandom(benchmark::State& state) { + std::time_t spawnTime = 0; + for (auto _ : state) { + dsf::mobility::Agent agent(spawnTime++); + benchmark::DoNotOptimize(agent); + } +} + +static void BM_Agent_SetSrcNodeId(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + for (auto _ : state) { + agent.setSrcNodeId(5); + } +} + +static void BM_Agent_SetStreetId(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + for (auto _ : state) { + agent.setStreetId(10); + } +} + +static void BM_Agent_SetNextStreetId(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + for (auto _ : state) { + agent.setNextStreetId(15); + } +} + +static void BM_Agent_SetSpeed(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + for (auto _ : state) { + agent.setSpeed(50.0); + } +} + +static void BM_Agent_SetFreeTime(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + std::time_t freeTime = 100; + for (auto _ : state) { + agent.setFreeTime(freeTime++); + } +} + +static void BM_Agent_IncrementDistance(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + for (auto _ : state) { + agent.incrementDistance(10.0); + } +} + +static void BM_Agent_UpdateItinerary(benchmark::State& state) { + std::vector trip = {1, 2, 3, 4, 5}; + dsf::mobility::Agent agent(0, trip, 0); + for (auto _ : state) { + agent.updateItinerary(); + } +} + +static void BM_Agent_Reset(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + agent.setSpeed(50.0); + agent.setStreetId(10); + std::time_t spawnTime = 1000; + for (auto _ : state) { + agent.reset(spawnTime++); + } +} + +// Getter benchmarks - these are inline so very fast +static void BM_Agent_Getters(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + agent.setSpeed(50.0); + agent.setStreetId(10); + for (auto _ : state) { + auto spawnTime = agent.spawnTime(); + auto freeTime = agent.freeTime(); + auto id = agent.id(); + auto streetId = agent.streetId(); + auto srcNodeId = agent.srcNodeId(); + auto nextStreetId = agent.nextStreetId(); + auto speed = agent.speed(); + auto distance = agent.distance(); + auto isRandom = agent.isRandom(); + benchmark::DoNotOptimize(spawnTime); + benchmark::DoNotOptimize(freeTime); + benchmark::DoNotOptimize(id); + benchmark::DoNotOptimize(streetId); + benchmark::DoNotOptimize(srcNodeId); + benchmark::DoNotOptimize(nextStreetId); + benchmark::DoNotOptimize(speed); + benchmark::DoNotOptimize(distance); + benchmark::DoNotOptimize(isRandom); + } +} + +static void BM_Agent_ItineraryId(benchmark::State& state) { + dsf::mobility::Agent agent(0, 1, 0); + for (auto _ : state) { + auto itineraryId = agent.itineraryId(); + benchmark::DoNotOptimize(itineraryId); + } +} + +static void BM_Agent_Trip(benchmark::State& state) { + dsf::mobility::Agent agent(0, {1, 2, 3}, 0); + for (auto _ : state) { + auto trip = agent.trip(); + benchmark::DoNotOptimize(trip); + } +} + +BENCHMARK(BM_Agent_ConstructionWithItineraryId); +BENCHMARK(BM_Agent_ConstructionWithTrip); +BENCHMARK(BM_Agent_ConstructionRandom); +BENCHMARK(BM_Agent_SetSrcNodeId); +BENCHMARK(BM_Agent_SetStreetId); +BENCHMARK(BM_Agent_SetNextStreetId); +BENCHMARK(BM_Agent_SetSpeed); +BENCHMARK(BM_Agent_SetFreeTime); +BENCHMARK(BM_Agent_IncrementDistance); +BENCHMARK(BM_Agent_UpdateItinerary); +BENCHMARK(BM_Agent_Reset); +BENCHMARK(BM_Agent_Getters); +BENCHMARK(BM_Agent_ItineraryId); +BENCHMARK(BM_Agent_Trip); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/benchmark/Bench_Intersection.cpp b/benchmark/Bench_Intersection.cpp new file mode 100644 index 000000000..09108e1cb --- /dev/null +++ b/benchmark/Bench_Intersection.cpp @@ -0,0 +1,113 @@ +#include "dsf/mobility/Intersection.hpp" +#include "dsf/geometry/Point.hpp" + +#include +#include + +static void BM_Intersection_Construction(benchmark::State& state) { + for (auto _ : state) { + dsf::mobility::Intersection intersection(0); + benchmark::DoNotOptimize(intersection); + } +} + +static void BM_Intersection_ConstructionWithPoint(benchmark::State& state) { + dsf::geometry::Point point{0.0, 0.0}; + for (auto _ : state) { + dsf::mobility::Intersection intersection(0, point); + benchmark::DoNotOptimize(intersection); + } +} + +static void BM_Intersection_AddAgentWithAngle(benchmark::State& state) { + std::time_t spawnTime = 0; + for (auto _ : state) { + dsf::mobility::Intersection intersection(0); + intersection.setCapacity(100); + auto agent = std::make_unique(spawnTime++, 1, 0); + intersection.addAgent(0.0, std::move(agent)); + } +} + +static void BM_Intersection_AddAgentWithoutAngle(benchmark::State& state) { + std::time_t spawnTime = 0; + for (auto _ : state) { + dsf::mobility::Intersection intersection(0); + intersection.setCapacity(100); + auto agent = std::make_unique(spawnTime++, 1, 0); + intersection.addAgent(std::move(agent)); + } +} + +static void BM_Intersection_nAgents(benchmark::State& state) { + dsf::mobility::Intersection intersection(0); + intersection.setCapacity(1000); + std::time_t spawnTime = 0; + for (int i = 0; i < 100; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + intersection.addAgent(std::move(agent)); + } + for (auto _ : state) { + dsf::Size n = intersection.nAgents(); + benchmark::DoNotOptimize(n); + } +} + +static void BM_Intersection_Density(benchmark::State& state) { + dsf::mobility::Intersection intersection(0); + intersection.setCapacity(1000); + std::time_t spawnTime = 0; + for (int i = 0; i < 100; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + intersection.addAgent(std::move(agent)); + } + for (auto _ : state) { + double d = intersection.density(); + benchmark::DoNotOptimize(d); + } +} + +static void BM_Intersection_IsFull(benchmark::State& state) { + dsf::mobility::Intersection intersection(0); + intersection.setCapacity(1000); + std::time_t spawnTime = 0; + for (int i = 0; i < 100; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + intersection.addAgent(std::move(agent)); + } + for (auto _ : state) { + bool full = intersection.isFull(); + benchmark::DoNotOptimize(full); + } +} + +static void BM_Intersection_SetStreetPriorities(benchmark::State& state) { + dsf::mobility::Intersection intersection(0); + std::set priorities = {1, 2, 3}; + for (auto _ : state) { + intersection.setStreetPriorities(priorities); + } +} + +static void BM_Intersection_AddStreetPriority(benchmark::State& state) { + dsf::mobility::Intersection intersection(0); + // Need to add ingoing edges first + intersection.addIngoingEdge(1); + intersection.addIngoingEdge(2); + for (auto _ : state) { + intersection.addStreetPriority(1); + intersection.addStreetPriority(2); + } +} + +BENCHMARK(BM_Intersection_Construction); +BENCHMARK(BM_Intersection_ConstructionWithPoint); +BENCHMARK(BM_Intersection_AddAgentWithAngle); +BENCHMARK(BM_Intersection_AddAgentWithoutAngle); +BENCHMARK(BM_Intersection_nAgents); +BENCHMARK(BM_Intersection_Density); +BENCHMARK(BM_Intersection_IsFull); +BENCHMARK(BM_Intersection_SetStreetPriorities); +BENCHMARK(BM_Intersection_AddStreetPriority); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/benchmark/Bench_Roundabout.cpp b/benchmark/Bench_Roundabout.cpp new file mode 100644 index 000000000..3d88f726a --- /dev/null +++ b/benchmark/Bench_Roundabout.cpp @@ -0,0 +1,79 @@ +#include "dsf/mobility/Roundabout.hpp" +#include "dsf/geometry/Point.hpp" + +#include +#include + +static void BM_Roundabout_Construction(benchmark::State& state) { + for (auto _ : state) { + dsf::mobility::Roundabout roundabout(0); + benchmark::DoNotOptimize(roundabout); + } +} + +static void BM_Roundabout_ConstructionWithPoint(benchmark::State& state) { + dsf::geometry::Point point{0.0, 0.0}; + for (auto _ : state) { + dsf::mobility::Roundabout roundabout(0, point); + benchmark::DoNotOptimize(roundabout); + } +} + +static void BM_Roundabout_Enqueue(benchmark::State& state) { + dsf::mobility::Roundabout roundabout(0); + roundabout.setCapacity(1000); + std::time_t spawnTime = 0; + for (auto _ : state) { + auto agent = std::make_unique(spawnTime++, 1, 0); + roundabout.enqueue(std::move(agent)); + } +} + +static void BM_Roundabout_Dequeue(benchmark::State& state) { + std::time_t spawnTime = 0; + for (auto _ : state) { + dsf::mobility::Roundabout roundabout(0); + roundabout.setCapacity(100); + auto agent = std::make_unique(spawnTime++, 1, 0); + roundabout.enqueue(std::move(agent)); + auto dequeued = roundabout.dequeue(); + benchmark::DoNotOptimize(dequeued); + } +} + +static void BM_Roundabout_Density(benchmark::State& state) { + dsf::mobility::Roundabout roundabout(0); + roundabout.setCapacity(1000); + std::time_t spawnTime = 0; + for (int i = 0; i < 100; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + roundabout.enqueue(std::move(agent)); + } + for (auto _ : state) { + double d = roundabout.density(); + benchmark::DoNotOptimize(d); + } +} + +static void BM_Roundabout_IsFull(benchmark::State& state) { + dsf::mobility::Roundabout roundabout(0); + roundabout.setCapacity(1000); + std::time_t spawnTime = 0; + for (int i = 0; i < 100; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + roundabout.enqueue(std::move(agent)); + } + for (auto _ : state) { + bool full = roundabout.isFull(); + benchmark::DoNotOptimize(full); + } +} + +BENCHMARK(BM_Roundabout_Construction); +BENCHMARK(BM_Roundabout_ConstructionWithPoint); +BENCHMARK(BM_Roundabout_Enqueue); +BENCHMARK(BM_Roundabout_Dequeue); +BENCHMARK(BM_Roundabout_Density); +BENCHMARK(BM_Roundabout_IsFull); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/benchmark/Bench_Street.cpp b/benchmark/Bench_Street.cpp new file mode 100644 index 000000000..a79960339 --- /dev/null +++ b/benchmark/Bench_Street.cpp @@ -0,0 +1,311 @@ +#include "dsf/mobility/Street.hpp" + +#include +#include + +static void BM_Street_Construction(benchmark::State& state) { + for (auto _ : state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + std::nullopt, + 1.0); + benchmark::DoNotOptimize(street); + } +} + +static void BM_Street_AddAgent(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, // capacity + 1.0); + std::time_t spawnTime = 0; + for (auto _ : state) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + } +} + +static void BM_Street_Enqueue(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + } + size_t queueId = 0; + for (auto _ : state) { + if (!street.movingAgents().empty()) { + street.enqueue(queueId); + queueId = (queueId + 1) % 2; + } + } +} + +static void BM_Street_Dequeue(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + street.enqueue(0); + } + size_t index = 0; + for (auto _ : state) { + if (!street.queue(index).empty()) { + auto agent = street.dequeue(index); + benchmark::DoNotOptimize(agent); + } + } +} + +static void BM_Street_nAgents(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + if (i % 2 == 0) street.enqueue(0); + } + for (auto _ : state) { + int n = street.nAgents(); + benchmark::DoNotOptimize(n); + } +} + +static void BM_Street_Density(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + if (i % 2 == 0) street.enqueue(0); + } + for (auto _ : state) { + double d = street.density(false); + benchmark::DoNotOptimize(d); + } +} + +static void BM_Street_nMovingAgents(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + } + for (auto _ : state) { + int n = street.nMovingAgents(); + benchmark::DoNotOptimize(n); + } +} + +static void BM_Street_nExitingAgents(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + street.enqueue(0); + } + for (auto _ : state) { + double n = street.nExitingAgents(dsf::Direction::ANY, false); + benchmark::DoNotOptimize(n); + } +} + +static void BM_Street_SetLaneMapping(benchmark::State& state) { + dsf::mobility::Street street(0, + {0, 1}, + 100.0, + 13.8888888889, + 3, + "test", + {}, + std::nullopt, + 1.0); + std::vector laneMapping = { + dsf::Direction::RIGHTANDSTRAIGHT, + dsf::Direction::STRAIGHT, + dsf::Direction::LEFT}; + for (auto _ : state) { + street.setLaneMapping(laneMapping); + } +} + +static void BM_StochasticStreet_SetFlowRate(benchmark::State& state) { + dsf::mobility::Street baseStreet(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + std::nullopt, + 1.0); + dsf::mobility::StochasticStreet street(std::move(baseStreet), 0.5); + for (auto _ : state) { + street.setFlowRate(0.8); + } +} + +static void BM_StochasticStreet_FlowRate(benchmark::State& state) { + dsf::mobility::Street baseStreet(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + std::nullopt, + 1.0); + dsf::mobility::StochasticStreet street(std::move(baseStreet), 0.5); + for (auto _ : state) { + double fr = street.flowRate(); + benchmark::DoNotOptimize(fr); + } +} + +static void BM_SpireStreet_AddAgent(benchmark::State& state) { + dsf::mobility::Street baseStreet(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + dsf::mobility::SpireStreet street(std::move(baseStreet)); + std::time_t spawnTime = 0; + for (auto _ : state) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + } +} + +static void BM_SpireStreet_MeanFlow(benchmark::State& state) { + dsf::mobility::Street baseStreet(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + dsf::mobility::SpireStreet street(std::move(baseStreet)); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + street.enqueue(0); + if (i % 2 == 0) { + auto dequeued = street.dequeue(0); + } + } + for (auto _ : state) { + int flow = street.meanFlow(); + benchmark::DoNotOptimize(flow); + } +} + +static void BM_SpireStreet_Dequeue(benchmark::State& state) { + dsf::mobility::Street baseStreet(0, + {0, 1}, + 100.0, + 13.8888888889, + 2, + "test", + {}, + 100, + 1.0); + dsf::mobility::SpireStreet street(std::move(baseStreet)); + std::time_t spawnTime = 0; + for (int i = 0; i < 50; ++i) { + auto agent = std::make_unique(spawnTime++, 1, 0); + street.addAgent(std::move(agent)); + street.enqueue(0); + } + size_t index = 0; + for (auto _ : state) { + if (!street.queue(index).empty()) { + auto agent = street.dequeue(index); + benchmark::DoNotOptimize(agent); + } + } +} + +BENCHMARK(BM_Street_Construction); +BENCHMARK(BM_Street_AddAgent); +BENCHMARK(BM_Street_Enqueue); +BENCHMARK(BM_Street_Dequeue); +BENCHMARK(BM_Street_nAgents); +BENCHMARK(BM_Street_Density); +BENCHMARK(BM_Street_nMovingAgents); +BENCHMARK(BM_Street_nExitingAgents); +BENCHMARK(BM_Street_SetLaneMapping); +BENCHMARK(BM_StochasticStreet_SetFlowRate); +BENCHMARK(BM_StochasticStreet_FlowRate); +BENCHMARK(BM_SpireStreet_AddAgent); +BENCHMARK(BM_SpireStreet_MeanFlow); +BENCHMARK(BM_SpireStreet_Dequeue); + +BENCHMARK_MAIN(); diff --git a/benchmark/Bench_TrafficLight.cpp b/benchmark/Bench_TrafficLight.cpp new file mode 100644 index 000000000..9b6371bf4 --- /dev/null +++ b/benchmark/Bench_TrafficLight.cpp @@ -0,0 +1,97 @@ +#include "dsf/mobility/TrafficLight.hpp" +#include "dsf/geometry/Point.hpp" + +#include +#include + +static void BM_TrafficLight_Construction(benchmark::State& state) { + for (auto _ : state) { + dsf::mobility::TrafficLight tl(0, 60); + benchmark::DoNotOptimize(tl); + } +} + +static void BM_TrafficLight_ConstructionWithPoint(benchmark::State& state) { + dsf::geometry::Point point{0.0, 0.0}; + for (auto _ : state) { + dsf::mobility::TrafficLight tl(0, 60, point); + benchmark::DoNotOptimize(tl); + } +} + +static void BM_TrafficLight_OperatorIncrement(benchmark::State& state) { + dsf::mobility::TrafficLight tl(0, 60); + for (auto _ : state) { + ++tl; + benchmark::DoNotOptimize(tl); + } +} + +static void BM_TrafficLight_SetCycle(benchmark::State& state) { + dsf::mobility::TrafficLight tl(0, 60); + dsf::mobility::TrafficLightCycle cycle(30, 0); + for (auto _ : state) { + tl.setCycle(1, dsf::Direction::STRAIGHT, cycle); + } +} + +static void BM_TrafficLight_SetComplementaryCycle(benchmark::State& state) { + for (auto _ : state) { + dsf::mobility::TrafficLight tl(0, 60); + dsf::mobility::TrafficLightCycle cycle(30, 0); + tl.setCycle(1, dsf::Direction::STRAIGHT, cycle); + tl.setComplementaryCycle(2, 1); + } +} + +static void BM_TrafficLight_IsGreen(benchmark::State& state) { + dsf::mobility::TrafficLight tl(0, 60); + dsf::mobility::TrafficLightCycle cycle(30, 0); + tl.setCycle(1, dsf::Direction::STRAIGHT, cycle); + for (auto _ : state) { + bool green = tl.isGreen(1, dsf::Direction::STRAIGHT); + benchmark::DoNotOptimize(green); + } +} + +static void BM_TrafficLight_MeanGreenTime(benchmark::State& state) { + dsf::mobility::TrafficLight tl(0, 60); + dsf::mobility::TrafficLightCycle cycle1(30, 0); + dsf::mobility::TrafficLightCycle cycle2(20, 30); + tl.setCycle(1, dsf::Direction::STRAIGHT, cycle1); + tl.setCycle(2, dsf::Direction::LEFT, cycle2); + for (auto _ : state) { + double mean = tl.meanGreenTime(false); + benchmark::DoNotOptimize(mean); + } +} + +static void BM_TrafficLight_ResetCycles(benchmark::State& state) { + dsf::mobility::TrafficLight tl(0, 60); + dsf::mobility::TrafficLightCycle cycle(30, 0); + tl.setCycle(1, dsf::Direction::STRAIGHT, cycle); + for (auto _ : state) { + tl.resetCycles(); + } +} + +static void BM_TrafficLight_IncreasePhases(benchmark::State& state) { + dsf::mobility::TrafficLight tl(0, 60); + dsf::mobility::TrafficLightCycle cycle(30, 0); + tl.setCycle(1, dsf::Direction::STRAIGHT, cycle); + for (auto _ : state) { + tl.increasePhases(5); + } +} + +BENCHMARK(BM_TrafficLight_Construction); +BENCHMARK(BM_TrafficLight_ConstructionWithPoint); +BENCHMARK(BM_TrafficLight_OperatorIncrement); +BENCHMARK(BM_TrafficLight_SetCycle); +BENCHMARK(BM_TrafficLight_SetComplementaryCycle); +BENCHMARK(BM_TrafficLight_IsGreen); +BENCHMARK(BM_TrafficLight_MeanGreenTime); +BENCHMARK(BM_TrafficLight_ResetCycles); +BENCHMARK(BM_TrafficLight_IncreasePhases); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/src/dsf/mobility/RoadDynamics.hpp b/src/dsf/mobility/RoadDynamics.hpp index 90ac099b0..d84369e18 100644 --- a/src/dsf/mobility/RoadDynamics.hpp +++ b/src/dsf/mobility/RoadDynamics.hpp @@ -576,7 +576,7 @@ namespace dsf::mobility { bool reinsert_agents) { auto const nLanes = pStreet->nLanes(); while (!pStreet->movingAgents().empty()) { - auto const& pAgent{pStreet->movingAgents().top()}; + auto const& pAgent{pStreet->movingAgents().front()}; if (pAgent->freeTime() < this->time_step()) { break; } From 1a4adef7c52a4fecb8f698e78cf0483c624dbc6d Mon Sep 17 00:00:00 2001 From: grufoony Date: Wed, 5 Nov 2025 13:04:29 +0100 Subject: [PATCH 4/7] Add benchmark wf --- .github/workflows/benchmark_release.yml | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/benchmark_release.yml diff --git a/.github/workflows/benchmark_release.yml b/.github/workflows/benchmark_release.yml new file mode 100644 index 000000000..e9e6877a4 --- /dev/null +++ b/.github/workflows/benchmark_release.yml @@ -0,0 +1,36 @@ +name: "Benchmark Release" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + benchmark_release: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y build-essential cmake libtbb-dev libsimdjson-dev libhwloc-dev + + - name: Build in Release mode with benchmarks + working-directory: ${{ github.workspace }} + run: | + mkdir -p build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release -DDSF_BENCHMARKS=ON -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install + cmake --build . -j$(nproc) --config Release + + - name: Run benchmarks + working-directory: ${{ github.workspace }}/benchmark + run: | + for bench in *.out; do + echo "Running $bench" + ./$bench + done \ No newline at end of file From e3c8a23e9cff2b21bd88c7b6ad7d771af4d58ddf Mon Sep 17 00:00:00 2001 From: grufoony Date: Wed, 5 Nov 2025 13:07:37 +0100 Subject: [PATCH 5/7] Ops --- .github/workflows/benchmark_release.yml | 2 +- src/dsf/mobility/RoadDynamics.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark_release.yml b/.github/workflows/benchmark_release.yml index e9e6877a4..84f658b8d 100644 --- a/.github/workflows/benchmark_release.yml +++ b/.github/workflows/benchmark_release.yml @@ -1,4 +1,4 @@ -name: "Benchmark Release" +name: "CI: Benchmark Release" on: push: diff --git a/src/dsf/mobility/RoadDynamics.hpp b/src/dsf/mobility/RoadDynamics.hpp index d84369e18..90ac099b0 100644 --- a/src/dsf/mobility/RoadDynamics.hpp +++ b/src/dsf/mobility/RoadDynamics.hpp @@ -576,7 +576,7 @@ namespace dsf::mobility { bool reinsert_agents) { auto const nLanes = pStreet->nLanes(); while (!pStreet->movingAgents().empty()) { - auto const& pAgent{pStreet->movingAgents().front()}; + auto const& pAgent{pStreet->movingAgents().top()}; if (pAgent->freeTime() < this->time_step()) { break; } From 5256b5105549d5b7e1687304655723cc015efc44 Mon Sep 17 00:00:00 2001 From: grufoony Date: Wed, 5 Nov 2025 13:13:14 +0100 Subject: [PATCH 6/7] Remove sbaldu bench --- .gitmodules | 4 ---- extern/benchmark | 1 - 2 files changed, 5 deletions(-) delete mode 160000 extern/benchmark diff --git a/.gitmodules b/.gitmodules index ca921ca64..994c9ed9c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ -[submodule "extern/benchmark"] - path = extern/benchmark - url = https://github.com/sbaldu/benchmark.git - [submodule "extern/doxygen-awesome"] path = extern/doxygen-awesome url = https://github.com/jothepro/doxygen-awesome-css.git diff --git a/extern/benchmark b/extern/benchmark deleted file mode 160000 index f17dacde9..000000000 --- a/extern/benchmark +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f17dacde945ef2483b50d9089c9aa2ef10fe66df From 5c37c173027674a491a8abf7205a2042bbcab143 Mon Sep 17 00:00:00 2001 From: grufoony Date: Wed, 5 Nov 2025 13:13:24 +0100 Subject: [PATCH 7/7] Refactoring --- .github/workflows/benchmark_release.yml | 2 +- .github/workflows/cmake_tests.yml | 3 +-- benchmark/CMakeLists.txt | 13 +------------ 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/.github/workflows/benchmark_release.yml b/.github/workflows/benchmark_release.yml index 84f658b8d..c3d0737ea 100644 --- a/.github/workflows/benchmark_release.yml +++ b/.github/workflows/benchmark_release.yml @@ -17,7 +17,7 @@ jobs: - name: Install dependencies run: | sudo apt update - sudo apt install -y build-essential cmake libtbb-dev libsimdjson-dev libhwloc-dev + sudo apt install -y build-essential cmake libhwloc-dev - name: Build in Release mode with benchmarks working-directory: ${{ github.workspace }} diff --git a/.github/workflows/cmake_tests.yml b/.github/workflows/cmake_tests.yml index c8ab43249..8f521d026 100644 --- a/.github/workflows/cmake_tests.yml +++ b/.github/workflows/cmake_tests.yml @@ -22,7 +22,7 @@ jobs: if: matrix.os == 'ubuntu-latest' run: | sudo apt update - sudo apt install -y lcov gcovr build-essential cmake libtbb-dev libsimdjson-dev libhwloc-dev + sudo apt install -y lcov gcovr build-essential cmake libhwloc-dev - name: Install dependencies on macOS if: matrix.os == 'macos-latest' @@ -37,7 +37,6 @@ jobs: git clone https://github.com/microsoft/vcpkg.git vcpkg cd vcpkg .\bootstrap-vcpkg.bat - .\vcpkg install tbb:x64-windows simdjson:x64-windows echo "VCPKG_ROOT=$env:GITHUB_WORKSPACE\vcpkg" >> $env:GITHUB_ENV echo "VCPKG_INSTALLED=$env:GITHUB_WORKSPACE\vcpkg\installed\x64-windows" >> $env:GITHUB_ENV diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 734dff6a5..ad666f511 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -14,17 +14,6 @@ set(CMAKE_CXX_EXTENSIONS OFF) if(NOT TARGET dsf) # Standalone build - need to find installed DSF find_package(dsf REQUIRED) - find_package(TBB REQUIRED CONFIG) - find_package(simdjson REQUIRED) -else() - # Building as part of main project - dsf target already exists - # TBB and simdjson should already be found by parent - if(NOT TARGET TBB::tbb) - find_package(TBB REQUIRED CONFIG) - endif() - if(NOT TARGET simdjson::simdjson) - find_package(simdjson REQUIRED) - endif() endif() # Get Google Benchmark @@ -48,6 +37,6 @@ foreach(SOURCE ${SOURCES}) get_filename_component(EXE_NAME ${SOURCE} NAME_WE) add_executable(${EXE_NAME}.out ${SOURCE}) target_compile_definitions(${EXE_NAME}.out PRIVATE SPDLOG_USE_STD_FORMAT) - target_link_libraries(${EXE_NAME}.out PRIVATE dsf TBB::tbb simdjson::simdjson benchmark::benchmark) + target_link_libraries(${EXE_NAME}.out PRIVATE dsf TBB::tbb simdjson::simdjson spdlog::spdlog benchmark::benchmark) target_include_directories(${EXE_NAME}.out PRIVATE $) endforeach()