diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/boost/libs/json/test | |
parent | Initial commit. (diff) | |
download | ceph-upstream/18.2.2.tar.xz ceph-upstream/18.2.2.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/json/test')
408 files changed, 22303 insertions, 0 deletions
diff --git a/src/boost/libs/json/test/CMakeLists.txt b/src/boost/libs/json/test/CMakeLists.txt new file mode 100644 index 000000000..91b96fc03 --- /dev/null +++ b/src/boost/libs/json/test/CMakeLists.txt @@ -0,0 +1,42 @@ +# +# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +# Copyright (c) 2021 DMitry Arkhipov (grisumbras@gmail.com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/json +# + + +if(NOT TARGET tests) + add_custom_target(tests) + set_property(TARGET tests PROPERTY FOLDER _deps) +endif() + + +file(GLOB_RECURSE BOOST_JSON_TESTS_FILES CONFIGURE_DEPENDS Jamfile *.cpp *.hpp) +list(FILTER BOOST_JSON_TESTS_FILES EXCLUDE REGEX cmake_install_test/.*$) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${BOOST_JSON_TESTS_FILES}) +add_executable(boost_json-tests ${BOOST_JSON_TESTS_FILES}) +target_include_directories(boost_json-tests PRIVATE .) +target_link_libraries(boost_json-tests PRIVATE Boost::json) +add_test(NAME boost_json-tests COMMAND boost_json-tests) +add_dependencies(tests boost_json-tests) + + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES limits.cpp main.cpp) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../src PREFIX "" FILES ../src/src.cpp) +add_executable(boost_json-limits limits.cpp main.cpp ../src/src.cpp Jamfile) +boost_json_setup_properties(boost_json-limits) + +target_compile_definitions(boost_json-limits PRIVATE + BOOST_JSON_MAX_STRING_SIZE=1000 + BOOST_JSON_MAX_STRUCTURED_SIZE=20 + BOOST_JSON_STACK_BUFFER_SIZE=256 + BOOST_JSON_NO_LIB=1 +) + +add_test(NAME boost_json-limits COMMAND boost_json-limits) +add_dependencies(tests boost_json-limits) diff --git a/src/boost/libs/json/test/Jamfile b/src/boost/libs/json/test/Jamfile new file mode 100644 index 000000000..ed26d0233 --- /dev/null +++ b/src/boost/libs/json/test/Jamfile @@ -0,0 +1,70 @@ +# +# Copyright (c) 2013-2019 Vinnie Falco (vinnie.falco@gmail.com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/json +# + +import testing ; + +local SOURCES = + array.cpp + basic_parser.cpp + doc_background.cpp + doc_forward_conversion.cpp + doc_parsing.cpp + doc_quick_look.cpp + doc_serializing.cpp + doc_storage_ptr.cpp + doc_uses_allocator.cpp + doc_using_numbers.cpp + double.cpp + error.cpp + fwd.cpp + json.cpp + kind.cpp + memory_resource.cpp + monotonic_resource.cpp + natvis.cpp + null_resource.cpp + object.cpp + parse.cpp + parser.cpp + pilfer.cpp + pointer.cpp + serialize.cpp + serializer.cpp + snippets.cpp + static_resource.cpp + storage_ptr.cpp + stream_parser.cpp + string.cpp + string_view.cpp + system_error.cpp + value.cpp + value_from.cpp + value_stack.cpp + value_to.cpp + value_ref.cpp + visit.cpp + ryu/d2s_intrinsics_test.cpp + ryu/d2s_table_test.cpp + ryu/d2s_test.cpp + ; + +project : requirements <include>. ; + +for local f in $(SOURCES) +{ + run $(f) main.cpp /boost/json//boost_json ; +} + +run limits.cpp main.cpp /boost/json//json_sources + : requirements + <define>BOOST_JSON_SOURCE + <define>BOOST_JSON_MAX_STRING_SIZE=1000 + <define>BOOST_JSON_MAX_STRUCTURED_SIZE=20 + <define>BOOST_JSON_STACK_BUFFER_SIZE=256 + ; diff --git a/src/boost/libs/json/test/README.md b/src/boost/libs/json/test/README.md new file mode 100644 index 000000000..77a970931 --- /dev/null +++ b/src/boost/libs/json/test/README.md @@ -0,0 +1,36 @@ +# JSON Parse Test Vectors + +The files in the direectory parse-vectors come from this project: + +JSON Test Suite + +A comprehensive test suite for RFC 8259 compliant JSON parsers + +https://github.com/nst/JSONTestSuite + +These files are covered by the following copyright and MIT License, +reproduced from the original project: + +--- + +MIT License + +Copyright (c) 2016 Nicolas Seriot + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/boost/libs/json/test/array.cpp b/src/boost/libs/json/test/array.cpp new file mode 100644 index 000000000..1cc87566c --- /dev/null +++ b/src/boost/libs/json/test/array.cpp @@ -0,0 +1,1291 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/array.hpp> + +#include <boost/json/monotonic_resource.hpp> + +#include <forward_list> +#include <list> +#include <iterator> + +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<array>::value ); +BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<array>::value ); + +class array_test +{ +public: + using init_list = + std::initializer_list<value_ref>; + + string_view const str_; + + array_test() + : str_( + "abcdefghijklmnopqrstuvwxyz") + { + // ensure this string does + // not fit in the SBO area. + BOOST_ASSERT(str_.size() > + string().capacity()); + + } + + void + check(array const& a) + { + BOOST_TEST(a.size() == 3); + BOOST_TEST(a[0].is_number()); + BOOST_TEST(a[1].is_bool()); + BOOST_TEST(a[2].is_string()); + } + + void + check( + array const& a, + storage_ptr const& sp) + { + check(a); + check_storage(a, sp); + } + + void + testDestroy() + { + { + monotonic_resource mr; + array a(&mr); + a.reserve(3); + } + { + monotonic_resource mr; + array a(&mr); + a.resize(3); + a.clear(); + } + } + + void + testCtors() + { + // ~array() + { + // implied + } + + // array() + { + array a; + BOOST_TEST(a.empty()); + BOOST_TEST(a.size() == 0); + } + + // array(storage_ptr) + { + array a(storage_ptr{}); + check_storage(a, storage_ptr{}); + } + + // array(size_type, value, storage) + { + // default storage + { + array a(3, true); + BOOST_TEST(a.size() == 3); + for(auto const& v : a) + BOOST_TEST(v.is_bool()); + check_storage(a, storage_ptr{}); + } + + // construct with zero `true` values + { + array(0, true); + } + + // construct with three `true` values + fail_loop([&](storage_ptr const& sp) + { + array a(3, true, sp); + BOOST_TEST(a.size() == 3); + check_storage(a, sp); + }); + } + + // array(size_type, storage) + { + // default storage + { + array a(3); + BOOST_TEST(a.size() == 3); + for(auto const& v : a) + BOOST_TEST(v.is_null()); + check_storage(a, storage_ptr{}); + } + + // zero size + { + array a(0); + BOOST_TEST(a.empty()); + } + + fail_loop([&](storage_ptr const& sp) + { + array a(3, sp); + BOOST_TEST(a.size() == 3); + for(auto const& v : a) + BOOST_TEST(v.is_null()); + check_storage(a, sp); + }); + } + + // array(InputIt, InputIt, storage) + { + // empty range + { + // random-access iterator + std::vector<value> i1; + array a1(i1.begin(), i1.end()); + BOOST_TEST(a1.empty()); + + // bidirectional iterator + std::list<value> i2; + array a2(i2.begin(), i2.end()); + BOOST_TEST(a2.empty()); + + // forward iterator + std::forward_list<value> i3; + array a3(i3.begin(), i3.end()); + BOOST_TEST(a3.empty()); + + // input iterator + auto const it = make_input_iterator(i3.begin()); + array a4(it, it); + BOOST_TEST(a4.empty()); + } + + // default storage + { + init_list init{ 0, 1, str_, 3, 4 }; + array a(init.begin(), init.end()); + check_storage(a, storage_ptr{}); + BOOST_TEST(a[0].as_int64() == 0); + BOOST_TEST(a[1].as_int64() == 1); + BOOST_TEST(a[2].as_string() == str_); + BOOST_TEST(a[3].as_int64() == 3); + BOOST_TEST(a[4].as_int64() == 4); + } + + // random iterator + fail_loop([&](storage_ptr const& sp) + { + init_list init{ 1, true, str_ }; + array a(init.begin(), init.end(), sp); + check(a); + check_storage(a, sp); + }); + + // input iterator + fail_loop([&](storage_ptr const& sp) + { + init_list init{ 1, true, str_ }; + array a( + make_input_iterator(init.begin()), + make_input_iterator(init.end()), sp); + check(a); + check_storage(a, sp); + }); + } + + // array(array const&) + { + { + array a1; + array a2(a1); + } + + { + array a1; + array a2({ 1, true, str_ }); + a2 = a1; + } + + { + init_list init{ 1, true, str_ }; + array a1(init.begin(), init.end()); + array a2(a1); + check(a2); + check_storage(a2, storage_ptr{}); + } + } + + // array(array const&, storage) + fail_loop([&](storage_ptr const& sp) + { + init_list init{ 1, true, str_ }; + array a1(init.begin(), init.end()); + array a2(a1, sp); + check(a2); + check_storage(a2, sp); + }); + + // array(pilfered<array>) + { + { + init_list init{ 1, true, str_ }; + array a1(init.begin(), init.end()); + array a2(pilfer(a1)); + BOOST_TEST(a1.empty()); + check(a2); + check_storage(a2, storage_ptr{}); + } + + // ensure pilfered-from objects + // are trivially destructible + { + array a1(make_shared_resource< + monotonic_resource>()); + array a2(pilfer(a1)); + BOOST_TEST(a1.storage().get() == + storage_ptr().get()); + } + } + + // array(array&&) + { + init_list init{ 1, true, str_ }; + array a1(init.begin(), init.end()); + array a2 = std::move(a1); + BOOST_TEST(a1.empty()); + check(a2); + check_storage(a2, storage_ptr{}); + } + + // array(array&&, storage) + { + { + init_list init{ 1, true, str_ }; + array a1(init.begin(), init.end()); + array a2( + std::move(a1), storage_ptr{}); + BOOST_TEST(a1.empty()); + check(a2); + check_storage(a1, storage_ptr{}); + check_storage(a2, storage_ptr{}); + } + + fail_loop([&](storage_ptr const& sp) + { + init_list init{ 1, true, str_ }; + array a1(init.begin(), init.end()); + array a2(std::move(a1), sp); + BOOST_TEST(! a1.empty()); + check(a2); + check_storage(a1, storage_ptr{}); + check_storage(a2, sp); + }); + } + + // array(init_list, storage) + { + // default storage + { + array a({1, true, str_}); + check(a); + check_storage(a, storage_ptr{}); + } + + fail_loop([&](storage_ptr const& sp) + { + array a({1, true, str_}, sp); + check(a, sp); + check_storage(a, sp); + }); + } + } + + void + testAssign() + { + // operator=(array const&) + { + { + array a1({1, true, str_}); + array a2({nullptr, object{}, 1.f}); + a2 = a1; + check(a1); + check(a2); + check_storage(a1, storage_ptr{}); + check_storage(a2, storage_ptr{}); + } + + fail_loop([&](storage_ptr const& sp) + { + array a1({1, true, str_}); + array a2({nullptr, object{}, 1.f}, sp); + a2 = a1; + check(a1); + check(a2); + check_storage(a1, storage_ptr{}); + check_storage(a2, sp); + }); + + // self-assign + { + array a({1, true, str_}); + auto& a1 = a; + auto& a2 = a; + a1 = a2; + check(a); + } + + // copy from child + { + array a({1, {1,2,3}, 3}); + a = a.at(1).as_array(); + BOOST_TEST( + a == array({1, 2, 3})); + } + } + + // operator=(array&&) + { + { + array a1({1, true, str_}); + array a2({nullptr, object{}, 1.f}); + a2 = std::move(a1); + BOOST_TEST(a1.empty()); + check(a2); + } + + // empty + { + array a1; + array a2; + a2 = std::move(a1); + BOOST_TEST(a1.empty()); + BOOST_TEST(a2.empty()); + } + + fail_loop([&](storage_ptr const& sp) + { + array a1({1, true, str_}); + array a2({nullptr, object{}, 1.f}, sp); + a2 = std::move(a1); + check(a1); + check(a2); + check_storage(a1, storage_ptr{}); + check_storage(a2, sp); + }); + + // self-move + { + array a({1, true, str_}); + auto& a1 = a; + auto& a2 = a; + a1 = std::move(a2); + check(a); + } + + // move from child + { + array a({1, {1,2,3}, 3}); + a = std::move(a.at(1).as_array()); + BOOST_TEST( + a == array({1, 2, 3})); + } + } + + // operator=(init_list) + { + { + array a; + a = {}; + } + + { + array a({ 1, true, str_ }); + a = {}; + } + + { + init_list init{ 1, true, str_ }; + array a({nullptr, object{}, 1.f}); + a = init; + check(a); + check_storage(a, storage_ptr{}); + } + + fail_loop([&](storage_ptr const& sp) + { + init_list init{ 1, true, str_ }; + array a({nullptr, object{}, 1.f}, sp); + a = init; + check(a); + check_storage(a, sp); + }); + } + } + + void + testGetStorage() + { + // storage() + { + // implied + } + } + + void + testAccess() + { + // at(pos) + { + array a({1, true, str_}); + BOOST_TEST(a.at(0).is_number()); + BOOST_TEST(a.at(1).is_bool()); + BOOST_TEST(a.at(2).is_string()); + try + { + a.at(3); + BOOST_TEST_FAIL(); + } + catch(std::out_of_range const&) + { + BOOST_TEST_PASS(); + } + } + + // at(pos) const + { + array const a({1, true, str_}); + BOOST_TEST(a.at(0).is_number()); + BOOST_TEST(a.at(1).is_bool()); + BOOST_TEST(a.at(2).is_string()); + try + { + a.at(3); + BOOST_TEST_FAIL(); + } + catch(std::out_of_range const&) + { + BOOST_TEST_PASS(); + } + } + + // operator[&](size_type) + { + array a({1, true, str_}); + BOOST_TEST(a[0].is_number()); + BOOST_TEST(a[1].is_bool()); + BOOST_TEST(a[2].is_string()); + } + + // operator[&](size_type) const + { + array const a({1, true, str_}); + BOOST_TEST(a[0].is_number()); + BOOST_TEST(a[1].is_bool()); + BOOST_TEST(a[2].is_string()); + } + + // front() + { + array a({1, true, str_}); + BOOST_TEST(a.front().is_number()); + } + + // front() const + { + array const a({1, true, str_}); + BOOST_TEST(a.front().is_number()); + } + + // back() + { + array a({1, true, str_}); + BOOST_TEST(a.back().is_string()); + } + + // back() const + { + array const a({1, true, str_}); + BOOST_TEST(a.back().is_string()); + } + + // if_contains() + // if_contains() const + { + { + array a({1, true, str_}); + BOOST_TEST(a.if_contains(1)->is_bool()); + BOOST_TEST(a.if_contains(3) == nullptr); + } + { + array const a({1, true, str_}); + BOOST_TEST(a.if_contains(1)->is_bool()); + BOOST_TEST(a.if_contains(3) == nullptr); + } + } + + // data() + { + { + array a({1, true, str_}); + BOOST_TEST(a.data() == &a[0]); + } + { + array a; + BOOST_TEST( + a.data() == a.begin()); + } + } + + // data() const + { + { + array const a({1, true, str_}); + BOOST_TEST(a.data() == &a[0]); + } + { + array const a{}; + BOOST_TEST( + a.data() == a.begin()); + } + } + } + + void + testIterators() + { + array a({1, true, str_}); + auto const& ac(a); + + { + auto it = a.begin(); + BOOST_TEST(it->is_number()); ++it; + BOOST_TEST(it->is_bool()); it++; + BOOST_TEST(it->is_string()); ++it; + BOOST_TEST(it == a.end()); + } + { + auto it = a.cbegin(); + BOOST_TEST(it->is_number()); ++it; + BOOST_TEST(it->is_bool()); it++; + BOOST_TEST(it->is_string()); ++it; + BOOST_TEST(it == a.cend()); + } + { + auto it = ac.begin(); + BOOST_TEST(it->is_number()); ++it; + BOOST_TEST(it->is_bool()); it++; + BOOST_TEST(it->is_string()); ++it; + BOOST_TEST(it == ac.end()); + } + { + auto it = a.end(); + --it; BOOST_TEST(it->is_string()); + it--; BOOST_TEST(it->is_bool()); + --it; BOOST_TEST(it->is_number()); + BOOST_TEST(it == a.begin()); + } + { + auto it = a.cend(); + --it; BOOST_TEST(it->is_string()); + it--; BOOST_TEST(it->is_bool()); + --it; BOOST_TEST(it->is_number()); + BOOST_TEST(it == a.cbegin()); + } + { + auto it = ac.end(); + --it; BOOST_TEST(it->is_string()); + it--; BOOST_TEST(it->is_bool()); + --it; BOOST_TEST(it->is_number()); + BOOST_TEST(it == ac.begin()); + } + + { + auto it = a.rbegin(); + BOOST_TEST(it->is_string()); ++it; + BOOST_TEST(it->is_bool()); it++; + BOOST_TEST(it->is_number()); ++it; + BOOST_TEST(it == a.rend()); + } + { + auto it = a.crbegin(); + BOOST_TEST(it->is_string()); ++it; + BOOST_TEST(it->is_bool()); it++; + BOOST_TEST(it->is_number()); ++it; + BOOST_TEST(it == a.crend()); + } + { + auto it = ac.rbegin(); + BOOST_TEST(it->is_string()); ++it; + BOOST_TEST(it->is_bool()); it++; + BOOST_TEST(it->is_number()); ++it; + BOOST_TEST(it == ac.rend()); + } + { + auto it = a.rend(); + --it; BOOST_TEST(it->is_number()); + it--; BOOST_TEST(it->is_bool()); + --it; BOOST_TEST(it->is_string()); + BOOST_TEST(it == a.rbegin()); + } + { + auto it = a.crend(); + --it; BOOST_TEST(it->is_number()); + it--; BOOST_TEST(it->is_bool()); + --it; BOOST_TEST(it->is_string()); + BOOST_TEST(it == a.crbegin()); + } + { + auto it = ac.rend(); + --it; BOOST_TEST(it->is_number()); + it--; BOOST_TEST(it->is_bool()); + --it; BOOST_TEST(it->is_string()); + BOOST_TEST(it == ac.rbegin()); + } + + { + array a2; + array const& ca2(a2); + BOOST_TEST(std::distance( + a2.begin(), a2.end()) == 0); + BOOST_TEST(std::distance( + ca2.begin(), ca2.end()) == 0); + BOOST_TEST(std::distance( + ca2.cbegin(), ca2.cend()) == 0); + BOOST_TEST(std::distance( + a2.rbegin(), a2.rend()) == 0); + BOOST_TEST(std::distance( + ca2.rbegin(), ca2.rend()) == 0); + BOOST_TEST(std::distance( + ca2.crbegin(), ca2.crend()) == 0); + } + } + + void + testCapacity() + { + // empty() + { + { + array a; + BOOST_TEST(a.empty()); + a.emplace_back(1); + BOOST_TEST(! a.empty()); + } + + { + array a({1, 2}); + BOOST_TEST(! a.empty()); + a.clear(); + BOOST_TEST(a.empty()); + BOOST_TEST(a.capacity() > 0); + } + } + + // size() + { + array a; + BOOST_TEST(a.size() == 0); + a.emplace_back(1); + BOOST_TEST(a.size() == 1); + } + + // max_size() + { + array a; + BOOST_TEST(a.max_size() > 0); + } + + // reserve() + { + { + array a; + a.reserve(0); + } + + { + array a(3); + a.reserve(1); + } + + { + array a(3); + a.reserve(0); + } + + { + array a; + a.reserve(50); + BOOST_TEST(a.capacity() >= 50); + } + + fail_loop([&](storage_ptr const& sp) + { + array a(4, 'c', sp); + a.reserve(a.capacity() + 1); + auto const new_cap = a.capacity(); + // 1.5x growth + BOOST_TEST(new_cap == 6); + a.reserve(new_cap + 1); + BOOST_TEST(a.capacity() == 9); + }); + } + + // capacity() + { + array a; + BOOST_TEST(a.capacity() == 0); + } + + // shrink_to_fit() + { + { + array a(1); + a.shrink_to_fit(); + BOOST_TEST(a.size() == 1); + BOOST_TEST(a.capacity() >= 1); + } + + { + array a(2, 'c'); + BOOST_TEST(a.capacity() == 2); + a.erase(a.begin()); + a.shrink_to_fit(); + BOOST_TEST(a.capacity() == 1); + } + + fail_loop([&](storage_ptr const& sp) + { + array a(1, sp); + a.resize(a.capacity()); + a.shrink_to_fit(); + BOOST_TEST(a.size() == a.capacity()); + }); + + fail_loop([&](storage_ptr const& sp) + { + array a(sp); + a.reserve(10); + BOOST_TEST(a.capacity() >= 10); + a.shrink_to_fit(); + BOOST_TEST(a.capacity() == 0); + }); + + fail_loop([&](storage_ptr const& sp) + { + array a(4, sp); + a.reserve(a.capacity() * 2); + BOOST_TEST(a.capacity() >= 4); + a.shrink_to_fit(); + if(a.capacity() != a.size()) + throw test_failure{}; + }); + } + } + + void + testModifiers() + { + // clear + { + { + array a; + BOOST_TEST(a.size() == 0); + BOOST_TEST(a.capacity() == 0); + a.clear(); + BOOST_TEST(a.size() == 0); + BOOST_TEST(a.capacity() == 0); + } + { + array a({1, true, str_}); + a.clear(); + BOOST_TEST(a.size() == 0); + BOOST_TEST(a.capacity() > 0); + } + } + + // insert(const_iterator, value_type const&) + { + // fast path + fail_loop([&](storage_ptr const& sp) + { + array a({1, 2, 3}, sp); + a.pop_back(); + BOOST_TEST( + a.capacity() > a.size()); + a.insert(a.begin(), 1); + BOOST_TEST( + a == array({1, 1, 2})); + }); + + // self-insert + { + array a = {1, 2, 3}; + a.insert(a.begin(), a[1]); + BOOST_TEST( + a == array({2, 1, 2, 3})); + } + + // fail + fail_loop([&](storage_ptr const& sp) + { + array a({1, str_}, sp); + value v(true); + a.insert(a.begin() + 1, v); + check(a); + check_storage(a, sp); + }); + } + + // insert(const_iterator, value_type&&) + fail_loop([&](storage_ptr const& sp) + { + array a({1, str_}, sp); + value v(true); + a.insert( + a.begin() + 1, std::move(v)); + check(a); + check_storage(a, sp); + }); + + // insert(const_iterator, size_type, value_type const&) + { + // fast path + fail_loop([&](storage_ptr const& sp) + { + array a({1, str_}, sp); + a.reserve(3); + BOOST_TEST( + a.capacity() > a.size()); + a.insert(&a[1], 1, true); + check(a); + }); + + // zero + { + array a(3); + a.insert(&a[1], 0, true); + BOOST_TEST(a.size() == 3); + } + + fail_loop([&](storage_ptr const& sp) + { + value v({1,2,3}); + array a({1, str_}, sp); + a.insert(a.begin() + 1, 3, v); + BOOST_TEST(a[0].is_number()); + BOOST_TEST(a[1].as_array().size() == 3); + BOOST_TEST(a[2].as_array().size() == 3); + BOOST_TEST(a[3].as_array().size() == 3); + BOOST_TEST(a[4].is_string()); + }); + } + + // insert(const_iterator, InputIt, InputIt) + { + // random iterator + fail_loop([&](storage_ptr const& sp) + { + std::initializer_list< + value> init = {1, true}; + array a({str_}, sp); + a.insert(a.begin(), + init.begin(), init.end()); + check(a); + }); + + // random iterator (multiple growth) + fail_loop([&](storage_ptr const& sp) + { + std::initializer_list<value_ref> init = { + 1, str_, true, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30 }; + array a(sp); + a.insert(a.begin(), + init.begin(), init.end()); + BOOST_TEST(a.size() == init.size()); + BOOST_TEST(a.capacity() == init.size()); + }); + + // input iterator (empty range) + { + std::initializer_list<value_ref> init; + array a; + a.insert(a.begin(), + make_input_iterator(init.begin()), + make_input_iterator(init.end())); + BOOST_TEST(a.empty()); + } + + // input iterator + fail_loop([&](storage_ptr const& sp) + { + std::initializer_list< + value> init = {1, true}; + array a({str_}, sp); + a.insert(a.begin(), + make_input_iterator(init.begin()), + make_input_iterator(init.end())); + check(a); + }); + + // input iterator (multiple growth) + fail_loop([&](storage_ptr const& sp) + { + std::initializer_list<value_ref> init = + {1, true, 1, 2, 3, 4, 5, 6, 7}; + array a({str_}, sp); + a.insert(a.begin(), + make_input_iterator(init.begin()), + make_input_iterator(init.end())); + BOOST_TEST(a.size() == init.size() + 1); + }); + + // backward relocate + fail_loop([&](storage_ptr const& sp) + { + std::initializer_list<value_ref> init = {1, 2}; + array a({"a", "b", "c", "d", "e"}, sp); + a.insert( + a.begin() + 1, + init.begin(), init.end()); + }); + } + + // insert(const_iterator, init_list) + fail_loop([&](storage_ptr const& sp) + { + array a({0, 3, 4}, sp); + auto it = a.insert( + a.begin() + 1, {1, str_}); + BOOST_TEST(it == a.begin() + 1); + BOOST_TEST(a[0].as_int64() == 0); + BOOST_TEST(a[1].as_int64() == 1); + BOOST_TEST(a[2].as_string() == str_); + BOOST_TEST(a[3].as_int64() == 3); + BOOST_TEST(a[4].as_int64() == 4); + }); + + // emplace(const_iterator, arg) + fail_loop([&](storage_ptr const& sp) + { + array a({0, 2, 3, 4}, sp); + auto it = a.emplace( + a.begin() + 1, str_); + BOOST_TEST(it == a.begin() + 1); + BOOST_TEST(a[0].as_int64() == 0); + BOOST_TEST(a[1].as_string() == str_); + BOOST_TEST(a[2].as_int64() == 2); + BOOST_TEST(a[3].as_int64() == 3); + BOOST_TEST(a[4].as_int64() == 4); + }); + + // erase(pos) + { + array a({1, true, nullptr, str_}); + a.erase(a.begin() + 2); + check(a); + } + + // erase(first, last) + { + array a({1, true, nullptr, 1.f, str_}); + a.erase( + a.begin() + 2, + a.begin() + 4); + check(a); + } + + // push_back(value const&) + { + // fast path + { + array a = {1, 2, 3}; + a.pop_back(); + BOOST_TEST( + a.capacity() > a.size()); + a.push_back(1); + BOOST_TEST(a == + array({1, 2, 1})); + } + + // self push_back + { + array a = {1, 2, 3}; + a.push_back(a[1]); + BOOST_TEST(a == + array({1, 2, 3, 2})); + } + + fail_loop([&](storage_ptr const& sp) + { + array a({1, true}, sp); + value v(str_); + a.push_back(v); + BOOST_TEST( + v.as_string() == str_); + check(a); + check_storage(a, sp); + }); + } + + // push_back(value&&) + { + fail_loop([&](storage_ptr const& sp) + { + array a({1, true}, sp); + value v(str_); + a.push_back(std::move(v)); + check(a); + check_storage(a, sp); + }); + } + + // emplace_back(arg) + fail_loop([&](storage_ptr const& sp) + { + array a({1, true}, sp); + a.emplace_back(str_); + check(a); + check_storage(a, sp); + }); + + // pop_back() + fail_loop([&](storage_ptr const& sp) + { + array a({1, true, str_, nullptr}, sp); + a.pop_back(); + check(a); + check_storage(a, sp); + }); + + // resize(size_type) + { + value v(array{}); + v.as_array().emplace_back(1); + v.as_array().emplace_back(true); + v.as_array().emplace_back(str_); + + fail_loop([&](storage_ptr const& sp) + { + array a(5, sp); + a.resize(3); + BOOST_TEST(a.size() == 3); + check_storage(a, sp); + }); + + fail_loop([&](storage_ptr const& sp) + { + array a(sp); + a.resize(3); + BOOST_TEST(a.size() == 3); + check_storage(a, sp); + }); + } + + // resize(size_type, value_type const&) + { + value v(array{}); + v.as_array().emplace_back(1); + v.as_array().emplace_back(true); + v.as_array().emplace_back(str_); + + fail_loop([&](storage_ptr const& sp) + { + array a(5, v, sp); + a.resize(3, v); + BOOST_TEST(a.size() == 3); + check_storage(a, sp); + }); + + fail_loop([&](storage_ptr const& sp) + { + array a(3, v, sp); + a.resize(5, v); + BOOST_TEST(a.size() == 5); + check_storage(a, sp); + }); + } + + // swap + { + // same storage + { + array a1({1, true, str_}); + array a2 = {1.}; + a1.swap(a2); + check(a2); + BOOST_TEST(a1.size() == 1); + BOOST_TEST(a1.front().is_number()); + BOOST_TEST(a1.front().as_double() == 1.); + } + + // different storage + fail_loop([&](storage_ptr const& sp) + { + array a1({1, true, str_}, sp); + array a2 = {1.}; + a1.swap(a2); + check(a2); + BOOST_TEST(a1.size() == 1); + }); + fail_loop([&](storage_ptr const& sp) + { + array a1 = {1.}; + array a2({1, true, str_}, sp); + a1.swap(a2); + check(a1); + BOOST_TEST(a2.size() == 1); + }); + } + } + + void + testExceptions() + { + // operator=(array const&) + fail_loop([&](storage_ptr const& sp) + { + array a0({1, true, str_}); + array a1; + array a(sp); + a.emplace_back(nullptr); + a = a0; + a1 = a; + check(a1); + }); + + // operator=(init_list) + fail_loop([&](storage_ptr const& sp) + { + init_list init{ 1, true, str_ }; + array a1; + array a(sp); + a.emplace_back(nullptr); + a = init; + a1 = a; + check(a1); + }); + + // insert(const_iterator, count, value_type const&) + fail_loop([&](storage_ptr const& sp) + { + array a1; + array a({1, true}, sp); + a.insert(a.begin() + 1, + 3, nullptr); + a1 = a; + BOOST_TEST(a1.size() == 5); + BOOST_TEST(a1[0].is_number()); + BOOST_TEST(a1[1].is_null()); + BOOST_TEST(a1[2].is_null()); + BOOST_TEST(a1[3].is_null()); + BOOST_TEST(a1[4].is_bool()); + }); + + // insert(const_iterator, InputIt, InputIt) + fail_loop([&](storage_ptr const& sp) + { + init_list init{ 1, true, str_ }; + array a1; + array a(sp); + a.insert(a.end(), + init.begin(), init.end()); + a1 = a; + check(a1); + }); + + // emplace(const_iterator, arg) + fail_loop([&](storage_ptr const& sp) + { + array a1; + array a({1, nullptr}, sp); + a.emplace(a.begin() + 1, true); + a1 = a; + BOOST_TEST(a1.size() == 3); + BOOST_TEST(a1[0].is_number()); + BOOST_TEST(a1[1].is_bool()); + BOOST_TEST(a1[2].is_null()); + }); + + // emplace(const_iterator, arg) + fail_loop([&](storage_ptr const& sp) + { + array a1; + array a({1, str_}, sp); + a.emplace(a.begin() + 1, true); + a1 = a; + check(a1); + BOOST_TEST(a1.size() == 3); + BOOST_TEST(a1[0].is_number()); + BOOST_TEST(a1[1].is_bool()); + BOOST_TEST(a1[2].is_string()); + }); + } + + void + testEquality() + { + BOOST_TEST(array({}) == array({})); + BOOST_TEST(array({}) != array({1,2})); + BOOST_TEST(array({1,2,3}) == array({1,2,3})); + BOOST_TEST(array({1,2,3}) != array({1,2})); + BOOST_TEST(array({1,2,3}) != array({3,2,1})); + } + + void + testHash() + { + BOOST_TEST(check_hash_equal( + array{}, array())); + BOOST_TEST(check_hash_equal( + array{1,1}, array{1,1})); + BOOST_TEST(check_hash_equal( + array{1,1}, array{1,1})); + BOOST_TEST(expect_hash_not_equal( + array{1,1}, array{1,2})); + BOOST_TEST(check_hash_equal( + array{"a", "b", 17}, + array{"a", "b", 17U})); + BOOST_TEST(expect_hash_not_equal( + array{"a", "b", nullptr}, + array{nullptr, "a", "b"})); + } + + void + run() + { + testDestroy(); + testCtors(); + testAssign(); + testGetStorage(); + testAccess(); + testIterators(); + testCapacity(); + testModifiers(); + testExceptions(); + testEquality(); + testHash(); + } +}; + +TEST_SUITE(array_test, "boost.json.array"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/basic_parser.cpp b/src/boost/libs/json/test/basic_parser.cpp new file mode 100644 index 000000000..6f25111d1 --- /dev/null +++ b/src/boost/libs/json/test/basic_parser.cpp @@ -0,0 +1,1651 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/basic_parser_impl.hpp> + +#include <memory> +#include <string> +#include <utility> + +#include "parse-vectors.hpp" +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<basic_parser<int>>::value ); + +namespace base64 { + +std::size_t constexpr +decoded_size(std::size_t n) +{ + return n / 4 * 3; // requires n&3==0, smaller +} + +signed char const* +get_inverse() +{ + static signed char constexpr tab[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95 + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111 + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255 + }; + return &tab[0]; +} + +std::pair<std::size_t, std::size_t> +decode(void* dest, char const* src, std::size_t len) +{ + char* out = static_cast<char*>(dest); + auto in = reinterpret_cast<unsigned char const*>(src); + unsigned char c3[3], c4[4]; + int i = 0; + int j = 0; + + auto const inverse = base64::get_inverse(); + + while(len-- && *in != '=') + { + auto const v = inverse[*in]; + if(v == -1) + break; + ++in; + c4[i] = v; + if(++i == 4) + { + c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4); + c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2); + c3[2] = ((c4[2] & 0x3) << 6) + c4[3]; + + for(i = 0; i < 3; i++) + *out++ = c3[i]; + i = 0; + } + } + + if(i) + { + c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4); + c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2); + c3[2] = ((c4[2] & 0x3) << 6) + c4[3]; + + for(j = 0; j < i - 1; j++) + *out++ = c3[j]; + } + + return {out - static_cast<char*>(dest), + in - reinterpret_cast<unsigned char const*>(src)}; +} + +} // base64 + +namespace { + +bool +validate( string_view s ) +{ + // Parse with the null parser and return false on error + null_parser p; + error_code ec; + p.write( s.data(), s.size(), ec ); + if( ec ) + return false; + + // The string is valid JSON. + return true; +} + +parse_options +make_options( + bool comments, + bool commas, + bool utf8) +{ + parse_options opt; + opt.allow_comments = comments; + opt.allow_trailing_commas = commas; + opt.allow_invalid_utf8 = utf8; + return opt; +} + +} // (anon) + +class basic_parser_test +{ +public: + ::test_suite::log_type log; + + void + grind_one( + string_view s, + bool good, + parse_options po) + { + error_code ec; + fail_parser p(po); + p.write(false, + s.data(), s.size(), ec); + BOOST_TEST((good && !ec) || + (! good && ec)); + } + + void + grind_one( + string_view s, + bool good, + const std::vector<parse_options>& configs) + { + for (const parse_options& po : configs) + grind_one(s, good, po); + } + + void + grind( + string_view s, + bool good, + parse_options po) + { + grind_one(s, good, po); + + // split/errors matrix + if(! s.empty()) + { + for(std::size_t i = 1; + i < s.size(); ++i) + { + for(std::size_t j = 1;;++j) + { + error_code ec; + fail_parser p(j, po); + p.write(true, s.data(), i, ec); + if(ec == error::test_failure) + continue; + if(! ec) + { + p.write(false, s.data() + i, + s.size() - i, ec); + if(ec == error::test_failure) + continue; + } + BOOST_TEST((good && !ec) || ( + ! good && ec)); + break; + } + } + } + + // split/exceptions matrix + if(! s.empty()) + { + for(std::size_t i = 1; + i < s.size(); ++i) + { + for(std::size_t j = 1;;++j) + { + error_code ec; + throw_parser p(j, po); + try + { + p.write( + true, s.data(), i, ec); + if(! ec) + p.write( + false, s.data() + i, + s.size() - i, ec); + BOOST_TEST((good && !ec) || ( + ! good && ec)); + break; + } + catch(test_exception const&) + { + continue; + } + catch(std::exception const& e) + { + BOOST_TEST_FAIL(); + log << " " << + e.what() << std::endl; + } + } + } + } + } + + void + grind( + string_view s, + bool good, + const std::vector<parse_options>& configs) + { + for (const parse_options& po : configs) + grind(s, good, po); + } + + void + bad(string_view s) + { + grind(s, false, parse_options()); + } + + void + good(string_view s) + { + grind(s, true, parse_options()); + } + + void + bad( + string_view s, + const parse_options& po) + { + grind(s, false, po); + } + + void + good( + string_view s, + const parse_options& po) + { + grind(s, true, po); + } + + void + bad_one( + string_view s, + const parse_options& po) + { + grind_one(s, false, po); + } + + void + good_one( + string_view s, + const parse_options& po) + { + grind_one(s, true, po); + } + + void + bad_one(string_view s) + { + grind_one(s, false, parse_options()); + } + + void + good_one(string_view s) + { + grind_one(s, true, parse_options()); + } + + //------------------------------------------------------ + + void + testNull() + { + good("null"); + good(" null"); + good("null "); + good("\tnull"); + good("null\t"); + good("\r\n\t null\r\n\t "); + + bad ("n "); + bad ("nu "); + bad ("nul "); + bad ("n--- "); + bad ("nu-- "); + bad ("nul- "); + + bad ("NULL"); + bad ("Null"); + bad ("nulls"); + } + + void + testBoolean() + { + good("true"); + good(" true"); + good("true "); + good("\ttrue"); + good("true\t"); + good("\r\n\t true\r\n\t "); + + bad ("t "); + bad ("tr "); + bad ("tru "); + bad ("t--- "); + bad ("tr-- "); + bad ("tru- "); + bad ("TRUE"); + bad ("True"); + bad ("truer"); + + good("false"); + good(" false"); + good("false "); + good("\tfalse"); + good("false\t"); + good("\r\n\t false\r\n\t "); + + bad ("f "); + bad ("fa "); + bad ("fal "); + bad ("fals "); + bad ("f---- "); + bad ("fa--- "); + bad ("fal-- "); + bad ("fals- "); + bad ("FALSE"); + bad ("False"); + bad ("falser"); + } + + void + testString() + { + good(R"jv( "x" )jv"); + good(R"jv( "xy" )jv"); + good(R"jv( "x y" )jv"); + + // escapes + good(R"jv(" \" ")jv"); + good(R"jv(" \\ ")jv"); + good(R"jv(" \/ ")jv"); + good(R"jv(" \b ")jv"); + good(R"jv(" \f ")jv"); + good(R"jv(" \n ")jv"); + good(R"jv(" \r ")jv"); + good(R"jv(" \t ")jv"); + + // utf-16 escapes + good(R"jv( " \u0000 " )jv"); + good(R"jv( " \ud7ff " )jv"); + good(R"jv( " \ue000 " )jv"); + good(R"jv( " \uffff " )jv"); + good(R"jv( " \ud800\udc00 " )jv"); + good(R"jv( " \udbff\udfff " )jv"); + good(R"jv( " \n\u0000 " )jv"); + + // escape in key + good(R"jv( {" \n":null} )jv"); + + // incomplete + bad ("\""); + + // illegal control character + bad ({ "\"" "\x00" "\"", 3 }); + bad ("\"" "\x1f" "\""); + bad ("\"" "\\n" "\x1f" "\""); + + // incomplete escape + bad (R"jv( "\" )jv"); + + // invalid escape + bad (R"jv( "\z" )jv"); + + // utf-16 escape, fast path, + // invalid surrogate + bad (R"jv( " \u---- " )jv"); + bad (R"jv( " \ud--- " )jv"); + bad (R"jv( " \ud8-- " )jv"); + bad (R"jv( " \ud80- " )jv"); + // invalid low surrogate + bad (R"jv( " \ud800------ " )jv"); + bad (R"jv( " \ud800\----- " )jv"); + bad (R"jv( " \ud800\u---- " )jv"); + bad (R"jv( " \ud800\ud--- " )jv"); + bad (R"jv( " \ud800\udc-- " )jv"); + bad (R"jv( " \ud800\udc0- " )jv"); + // illegal leading surrogate + bad (R"jv( " \udc00 " )jv"); + bad (R"jv( " \udfff " )jv"); + // illegal trailing surrogate + bad (R"jv( " \ud800\udbff " )jv"); + bad (R"jv( " \ud800\ue000 " )jv"); + } + + void + testNumber() + { + good("0"); + good("0 "); + good("0e0 "); + good("0E0 "); + good("0e00 "); + good("0E01 "); + good("0e+0 "); + good("0e-0 "); + good("0.0 "); + good("0.01 "); + good("0.0e0 "); + good("0.01e+0 "); + good("0.02E-0 "); + good("1 "); + good("12 "); + good("1e0 "); + good("1E0 "); + good("1e00 "); + good("1E01 "); + good("1e+0 "); + good("1e-0 "); + good("1.0 "); + good("1.01 "); + good("1.0e0 "); + good("1.01e+0 "); + good("1.02E-0 "); + good("1.0"); + + good("-0 "); + good("-0e0 "); + good("-0E0 "); + good("-0e00 "); + good("-0E01 "); + good("-0e+0 "); + good("-0e-0 "); + good("-0.0 "); + good("-0.01 "); + good("-0.0e0 "); + good("-0.01e+0 "); + good("-0.02E-0 "); + good("-1 "); + good("-12 "); + good("-1 "); + good("-1e0 "); + good("-1E0 "); + good("-1e00 "); + good("-1E01 "); + good("-1e+0 "); + good("-1e-0 "); + good("-1.0 "); + good("-1.01 "); + good("-1.0e0 "); + good("-1.01e+0 "); + good("-1.02E-0 "); + good("-1.0"); + + good("1.1e309 "); + good("9223372036854775807 "); + good("-9223372036854775807 "); + good("18446744073709551615 "); + good("-18446744073709551615 "); + + good("1234567890123456"); + good("-1234567890123456"); + good("10000000000000000000000000"); + + good("0.900719925474099178 "); + + // non-significant digits + good("1000000000000000000000000 "); + good("1000000000000000000000000e1 "); + good("1000000000000000000000000.0 "); + good("1000000000000000000000000.00 "); + good("1000000000000000000000000.000000000001"); + good("1000000000000000000000000.0e1 "); + good("1000000000000000000000000.0 "); + + good("1000000000.1000000000 "); + + bad(""); + bad("- "); + bad("00 "); + bad("01 "); + bad("00. "); + bad("00.0 "); + bad("-00 "); + bad("-01 "); + bad("-00. "); + bad("-00.0 "); + bad("1a "); + bad("-a "); + bad(". "); + bad("1. "); + bad("1+ "); + bad("0.0+ "); + bad("0.0e+ "); + bad("0.0e- "); + bad("0.0e0- "); + bad("0.0e "); + bad("1eX "); + bad("1000000000000000000000000.e "); + bad("0."); + bad("0.0e+"); + bad("0.0e2147483648"); + } + + void + testArray() + { + good("[]"); + good("[ ]"); + good("[ \t ]"); + good("[ \"\" ]"); + good("[ \" \" ]"); + good("[ \"x\" ]"); + good("[ \"x\", \"y\" ]"); + good("[1,2,3]"); + good(" [1,2,3]"); + good("[1,2,3] "); + good(" [1,2,3] "); + good("[1,2,3]"); + good("[ 1,2,3]"); + good("[1 ,2,3]"); + good("[1, 2,3]"); + good("[1,2 ,3]"); + good("[1,2, 3]"); + good("[1,2,3 ]"); + good(" [ 1 , 2 \t\n , \n3]"); + + bad ("["); + bad (" ["); + bad (" []]"); + bad ("[{]"); + bad (R"jv( [ null ; 1 ] )jv"); + } + + void + testObject() + { + good("{}"); + good("{ }"); + good("{ \t }"); + good("{\"x\":null}"); + good("{ \"x\":null}"); + good("{\"x\" :null}"); + good("{\"x\": null}"); + good("{\"x\":null }"); + good("{ \"x\" : null }"); + good("{ \"x\" : {} }"); + good("{ \"x\" : [] }"); + good("{ \"x\" : { \"y\" : null } }"); + good("{ \"x\" : [{}] }"); + good("{\"x\\ny\\u0022\":null}"); + good("{ \"x\":1, \"y\":null}"); + good("{\"x\":1,\"y\":2,\"z\":3}"); + good(" {\"x\":1,\"y\":2,\"z\":3}"); + good("{\"x\":1,\"y\":2,\"z\":3} "); + good(" {\"x\":1,\"y\":2,\"z\":3} "); + good("{ \"x\":1,\"y\":2,\"z\":3}"); + good("{\"x\" :1,\"y\":2,\"z\":3}"); + good("{\"x\":1 ,\"y\":2,\"z\":3}"); + good("{\"x\":1,\"y\" :2,\"z\":3}"); + good("{\"x\":1,\"y\": 2,\"z\":3}"); + good("{\"x\":1,\"y\":2 ,\"z\":3}"); + good("{\"x\":1,\"y\":2, \"z\":3}"); + good("{\"x\":1,\"y\":2, \"z\" :3}"); + good("{\"x\":1,\"y\":2, \"z\": 3}"); + good("{\"x\":1,\"y\":2, \"z\":3 }"); + good(" \t { \"x\" \n : 1, \"y\" :2, \"z\" : 3} \n"); + + good("[{\"x\":[{\"y\":null}]}]"); + + bad ("{"); + bad (" {"); + bad (" {}}"); + bad ("{{}}"); + bad ("{[]}"); + + bad (R"jv( {"x";null} )jv"); + bad (R"jv( {"x":null . "y":0} )jv"); + } + + void + testParser() + { + auto const check = + [this]( string_view s, + bool done) + { + fail_parser p; + error_code ec; + p.write_some( + true, + s.data(), s.size(), + ec); + if(! BOOST_TEST(! ec)) + { + log << " failed to parse: " << s << '\n'; + return; + } + BOOST_TEST(done == p.done()); + }; + + // done() + + check("{}", true); + check("{} ", true); + check("{}x", true); + check("{} x", true); + + check("[]", true); + check("[] ", true); + check("[]x", true); + check("[] x", true); + + check("\"a\"", true); + check("\"a\" ", true); + check("\"a\"x", true); + check("\"a\" x", true); + + check("0", false); + check("0 ", true); + check("0x", true); + check("0 x", true); + check("0.", false); + check("0.0", false); + check("0.0 ", true); + check("0.0 x", true); + + check("true", true); + check("true ", true); + check("truex", true); + check("true x", true); + + check("false", true); + check("false ", true); + check("falsex", true); + check("false x", true); + + check("null", true); + check("null ", true); + check("nullx", true); + check("null x", true); + + // flush + { + { + for(auto esc : + { "\\\"", "\\\\", "\\/", "\\b", + "\\f", "\\n", "\\r", "\\t", "\\u0000" + }) + { + std::string const big = + "\\\"" + std::string( + BOOST_JSON_STACK_BUFFER_SIZE-4, '*') + esc; + std::string const s = + "{\"" + big + "\":\"" + big + "\"}"; + good_one(s); + } + } + { + std::string big; + big = "\\\"" + + std::string( + BOOST_JSON_STACK_BUFFER_SIZE+ 1, '*'); + std::string s; + s = "{\"" + big + "\":\"" + big + "\"}"; + good_one(s); + } + } + + // no input + { + error_code ec; + fail_parser p; + p.write(false, nullptr, 0, ec); + BOOST_TEST(ec); + } + } + + void + testMembers() + { + fail_parser p; + std::size_t n; + error_code ec; + n = p.write_some(true, "null", 4, ec ); + if(BOOST_TEST(! ec)) + { + BOOST_TEST(n == 4); + BOOST_TEST(p.done()); + n = p.write_some(false, " \t42", 4, ec); + BOOST_TEST(n == 2); + BOOST_TEST(! ec); + } + p.reset(); + n = p.write_some(false, "[1,2,3]", 7, ec); + if(BOOST_TEST(! ec)) + { + BOOST_TEST(n == 7); + BOOST_TEST(p.done()); + } + } + + void + testParseVectors() + { + std::vector<parse_options> all_configs = + { + make_options(false, false, true), + make_options(true, false, true), + make_options(false, true, true), + make_options(true, true, true), + make_options(false, false, false), + make_options(true, false, false), + make_options(false, true, false), + make_options(true, true, false) + }; + parse_vectors pv; + for(auto const& v : pv) + { + // skip these , because basic_parser + // doesn't have a max_depth setting. + if( v.name == "structure_100000_opening_arrays" || + v.name == "structure_open_array_object") + { + continue; + } + for (const parse_options& po : all_configs) + { + if(v.result == 'i') + { + error_code ec; + fail_parser p(po); + p.write( + false, + v.text.data(), + v.text.size(), + ec); + if(! ec) + good_one(v.text, po); + else + bad_one(v.text, po); + } + else if(v.result == 'y') + good_one(v.text, po); + else + bad_one(v.text, po); + } + } + } + + // https://github.com/boostorg/json/issues/13 + void + testIssue13() + { + validate("\"~QQ36644632 {n"); + } + + void + testIssue20() + { + string_view s = + "WyL//34zOVx1ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlM2M4dWRlMTlcdWQ4M2RcdWRlMzlkZWUzOVx1" + "ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlMzlcXHVkY2M4M1x1ZDg5ZFx1ZGUzOVx1ZDgzZFx1ZGUzOWRb" + "IGZhbHNlLDMzMzMzMzMzMzMzMzMzMzMzNDMzMzMzMTY1MzczNzMwLDMzMzMzMzMzMzMzMzMzMzMz" + "MzM3ODAsMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz" + "MzM3ODAsMzMzMzMzMzMzMzMzMzQzMzMzMzE2NTM3MzczMCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgw" + "LDMzMzMzMzM4MzU1MzMwNzQ3NDYwLDMzMTY2NTAwMDAzMzMzMzMwNzQ3MzMzMzMzMzc3OSwzMzMz" + "MzMzMzMzMzMzMzMzNDMzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMz" + "MzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAs" + "MzMzMzMzMzMxNjY1MDAwMDMzMzMzNDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMz" + "MzMzMzM3MzMzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQz" + "MzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzNzgw" + "LDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3" + "NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgw" + "LDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMzMzMwODgzNTUz" + "MzA3NDM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMzMzMDczMzM3" + "NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz" + "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0" + "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4" + "MzU1MzMwNzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzMzMzMz" + "MzMzMzM0MjQ3LDMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMzMzMzMzMzM3MzMzMzQzMzMzMzMzMDc0" + "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz" + "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3" + "NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4" + "MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMzMzMzMzMzLDMzMzMzMzMzMzMzMzMz" + "MzMzMzM3ODAsMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1" + "MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzM3ODAsMzMzMzMzMzgzNTUzMzA3NDc0" + "NjAsMzMxNjY1MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzMz" + "MzA3NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMw" + "NzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzE2NjUwMDAwMzMz" + "MzM0NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3" + "MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAw" + "MzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0NzQ2MCwzMzMz" + "MzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDM3ODAsMzMzMzMz" + "MzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMTY2NTAwMDAzMzMzMzQ3NDYwLDMzMzMz" + "MzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzNzMzMzM0MzMzMzMzMzA3NDc0NjAsMzMzMzMz" + "MzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1MDAwMDMz" + "MzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzNcdWQ4N2RcdWRlZGV1ZGM4" + "ZGUzOVx1ZDg0ZFx1ZGM4M2RcdWQ4OGRcdWRlMzlcdWQ4OWRcdWRlMjM5MzMzZWUzOVxk"; + auto const len = base64::decoded_size(s.size()); + std::unique_ptr<char[]> p(new char[len]); + base64::decode( + p.get(), s.data(), s.size()); + string_view const js(p.get(), len); + BOOST_TEST(! validate(js)); + } + + void + testIssue113() + { + string_view s = + "\"\\r\\n section id='description'>\\r\\nAll mbers form the uncountable set " + "\\u211D. Among its subsets, relatively simple are the convex sets, each expressed " + "as a range between two real numbers <i>a</i> and <i>b</i> where <i>a</i> \\u2264 <i>" + "b</i>. There are actually four cases for the meaning of \\\"between\\\", depending " + "on open or closed boundary:\\r\\n\\r\\n<ul>\\r\\n <li>[<i>a</i>, <i>b</i>]: {<i>" + "x</i> | <i>a</i> \\u2264 <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n <li>" + "(<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> < <i>x</i> and <i>x</i> < <i>b</i> }" + "</li>\\r\\n <li>[<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> \\u2264 <i>x</i> and " + "<i>x</i> < <i>b</i> }</li>\\r\\n <li>(<i>a</i>, <i>b</i>]: {<i>x</i> | <i>a</i> " + "< <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n</ul>\\r\\n\\r\\nNote that " + "if <i>a</i> = <i>b</i>, of the four only [<i>a</i>, <i>a</i>] would be non-empty." + "\\r\\n\\r\\n<strong>Task</strong>\\r\\n\\r\\n<ul>\\r\\n <li>Devise a way to " + "represent any set of real numbers, for the definition of \\\"any\\\" in the " + "implementation notes below.</li>\\r\\n <li>Provide methods for these common " + "set operations (<i>x</i> is a real number; <i>A</i> and <i>B</i> are sets):</li>" + "\\r\\n <ul>\\r\\n <li>\\r\\n <i>x</i> \\u2208 <i>A</i>: determine if <i>" + "x</i> is an element of <i>A</i><br>\\r\\n example: 1 is in [1, 2), while 2, " + "3, ... are not.\\r\\n </li>\\r\\n <li>\\r\\n <i>A</i> \\u222A <i>B</i>: " + "union of <i>A</i> and <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 <i>A</i> or <i>x" + "</i> \\u2208 <i>B</i>}<br>\\r\\n example: [0, 2) \\u222A (1, 3) = [0, 3); " + "[0, 1) \\u222A (2, 3] = well, [0, 1) \\u222A (2, 3]\\r\\n </li>\\r\\n <li>" + "\\r\\n <i>A</i> \\u2229 <i>B</i>: intersection of <i>A</i> and <i>B</i>, i.e. " + "{<i>x</i> | <i>x</i> \\u2208 <i>A</i> and <i>x</i> \\u2208 <i>B</i>}<br>\\r\\n " + "example: [0, 2) \\u2229 (1, 3) = (1, 2); [0, 1) \\u2229 (2, 3] = empty set\\r\\n " + "</li>\\r\\n <li>\\r\\n <i>A</i> - <i>B</i>: difference between <i>A</i> and " + "<i>B</i>, also written as <i>A</i> \\\\ <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 " + "<i>A</i> and <i>x</i> \\u2209 <i>B</i>}<br>\\r\\n example: [0, 2) \\u2212 (1, " + "3) = [0, 1]\\r\\n </li>\\r\\n </ul>\\r\\n</ul>\\r\\n</section>\\r\\n\"\n"; + good_one(s); + } + + class comment_parser + { + struct handler + { + constexpr static std::size_t max_object_size = std::size_t(-1); + constexpr static std::size_t max_array_size = std::size_t(-1); + constexpr static std::size_t max_key_size = std::size_t(-1); + constexpr static std::size_t max_string_size = std::size_t(-1); + + std::string captured = ""; + bool on_document_begin( error_code& ) { return true; } + bool on_document_end( error_code& ) { return true; } + bool on_object_begin( error_code& ) { return true; } + bool on_object_end( std::size_t, error_code& ) { return true; } + bool on_array_begin( error_code& ) { return true; } + bool on_array_end( std::size_t, error_code& ) { return true; } + bool on_key_part( string_view, std::size_t, error_code& ) { return true; } + bool on_key( string_view, std::size_t, error_code& ) { return true; } + bool on_string_part( string_view, std::size_t, error_code& ) { return true; } + bool on_string( string_view, std::size_t, error_code& ) { return true; } + bool on_number_part( string_view, error_code&) { return true; } + bool on_int64( std::int64_t, string_view, error_code& ) { return true; } + bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; } + bool on_double( double, string_view, error_code& ) { return true; } + bool on_bool( bool, error_code& ) { return true; } + bool on_null( error_code& ) { return true; } + bool on_comment_part( string_view s, error_code& ) + { + captured.append(s.data(), s.size()); + return true; + } + bool on_comment( string_view s, error_code& ) + { + captured.append(s.data(), s.size()); + return true; + } + }; + + basic_parser<handler> p_; + + public: + comment_parser() + : p_(make_options(true, false, false)) + { + } + + std::size_t + write( + char const* data, + std::size_t size, + error_code& ec) + { + auto const n = p_.write_some( + false, data, size, ec); + if(! ec && n < size) + ec = error::extra_data; + return n; + } + + string_view + captured() const noexcept + { + return p_.handler().captured; + } + }; + + void + testComments() + { + parse_options disabled; + parse_options enabled; + enabled.allow_comments = true; + + const auto replace_and_test = + [&](string_view s) + { + static std::vector<string_view> comments = + { + "//\n", + "// \n", + "//aaaa\n", + "// aaaa\n", + "// /* \n", + "// /**/ \n", + "/**/", + "/*//*/", + "/*/*/", + "/******/", + "/*** ***/", + "/**aaaa***/", + "/*** aaaa***/" + }; + + std::string formatted = ""; + std::string just_comments = ""; + std::size_t guess = std::count( + s.begin(), s.end(), '@') * 12; + formatted.reserve(guess + s.size()); + just_comments.reserve(guess); + std::size_t n = 0; + for (char c : s) + { + if (c == '@') + { + string_view com = + comments[((formatted.size() + n) % s.size()) % comments.size()]; + formatted.append(com.data(), n = com.size()); + just_comments.append(com.data(), com.size()); + continue; + } + formatted += c; + } + bad(formatted, disabled); + good(formatted, enabled); + + { + // test the handler + comment_parser p; + error_code ec; + p.write( formatted.data(), formatted.size(), ec ); + BOOST_TEST(! ec); + BOOST_TEST(p.captured() == just_comments); + } + }; + + replace_and_test("@1"); + replace_and_test("1@"); + replace_and_test("@1@"); + replace_and_test("[@1]"); + replace_and_test("[1@]"); + replace_and_test("[1,2@]"); + replace_and_test("[1,@2]"); + replace_and_test("[1@,2]"); + replace_and_test("@[@1@,@2@]@"); + replace_and_test("{@\"a\":1}"); + replace_and_test("{\"a\"@:1}"); + replace_and_test("{\"a\":1@}"); + replace_and_test("{\"a\":1@,\"b\":2}"); + replace_and_test("{\"a\":1,@\"b\":2}"); + replace_and_test("@{@\"a\"@:@1@,@\"b\"@:@2@}"); + + // no following token + bad("1/", enabled); + // bad second token + bad("1/x", enabled); + // no comment close + bad("1/*", enabled); + bad("1/**", enabled); + bad("[1 //, 2]", enabled); + + // just comment + bad("//\n", enabled); + bad("//", enabled); + bad("/**/", enabled); + + // no newline at EOF + good("1//", enabled); + } + + void + testAllowTrailing() + { + parse_options disabled; + parse_options enabled; + enabled.allow_trailing_commas = true; + + bad("[1,]", disabled); + good("[1,]", enabled); + + bad("[1,[],]", disabled); + good("[1,[],]", enabled); + + bad("[1,{},]", disabled); + good("[1,{},]", enabled); + + bad("[1,{\"a\":1,},]", disabled); + good("[1,{\"a\":1,},]", enabled); + + bad("{\"a\":1,}", disabled); + good("{\"a\":1,}", enabled); + + bad("{\"a\":[1,],}", disabled); + good("{\"a\":[1,],}", enabled); + + bad("{\"a\":[],}", disabled); + good("{\"a\":[],}", enabled); + + bad("{\"a\":[{}, [1,]],}", disabled); + good("{\"a\":[{}, [1,]],}", enabled); + + bad("[[[[[[[],],],],],],]", disabled); + good("[[[[[[[],],],],],],]", enabled); + + bad("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", disabled); + good("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", enabled); + } + + class utf8_parser + { + struct handler + { + constexpr static std::size_t max_object_size = std::size_t(-1); + constexpr static std::size_t max_array_size = std::size_t(-1); + constexpr static std::size_t max_key_size = std::size_t(-1); + constexpr static std::size_t max_string_size = std::size_t(-1); + + std::string captured = ""; + bool on_document_begin( error_code& ) { return true; } + bool on_document_end( error_code& ) { return true; } + bool on_object_begin( error_code& ) { return true; } + bool on_object_end( std::size_t, error_code& ) { return true; } + bool on_array_begin( error_code& ) { return true; } + bool on_array_end( std::size_t, error_code& ) { return true; } + bool on_key_part( string_view, std::size_t, error_code& ) { return true; } + bool on_key( string_view, std::size_t, error_code& ) { return true; } + bool on_string_part( string_view sv, std::size_t, error_code& ) + { + captured.append(sv.data(), sv.size()); + return true; + } + bool on_string( string_view sv, std::size_t, error_code& ) + { + captured.append(sv.data(), sv.size()); + return true; + } + bool on_number_part( string_view, error_code&) { return true; } + bool on_int64( std::int64_t, string_view, error_code& ) { return true; } + bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; } + bool on_double( double, string_view, error_code& ) { return true; } + bool on_bool( bool, error_code& ) { return true; } + bool on_null( error_code& ) { return true; } + bool on_comment_part( string_view, error_code& ) { return true; } + bool on_comment( string_view, error_code& ) { return true; } + }; + + basic_parser<handler> p_; + + public: + utf8_parser() + : p_(parse_options()) + { + } + + std::size_t + write( + bool more, + char const* data, + std::size_t size, + error_code& ec) + { + auto const n = p_.write_some( + more, data, size, ec); + if(! ec && n < size) + ec = error::extra_data; + return n; + } + + string_view + captured() const noexcept + { + return p_.handler().captured; + } + }; + + void + testUTF8Validation() + { + good("\"\xc2\x80----------\""); + good("\"\xc2\xbf----------\""); + good("\"\xdf\x80----------\""); + good("\"\xdf\xbf----------\""); + + good("\"\xcf\x90----------\""); + + good("\"\xe0\xa0\x80----------\""); + good("\"\xe0\xa0\xbf----------\""); + good("\"\xe0\xbf\x80----------\""); + good("\"\xe0\xbf\xbf----------\""); + + good("\"\xe0\xb0\x90----------\""); + + good("\"\xe1\x80\x80----------\""); + good("\"\xe1\xbf\x80----------\""); + good("\"\xec\x80\x80----------\""); + good("\"\xec\xbf\x80----------\""); + good("\"\xe1\x80\xbf----------\""); + good("\"\xe1\xbf\xbf----------\""); + good("\"\xec\x80\xbf----------\""); + good("\"\xec\xbf\xbf----------\""); + + good("\"\xe6\x90\x90----------\""); + + good("\"\xed\x80\x80----------\""); + good("\"\xed\x80\xbf----------\""); + good("\"\xed\x9f\x80----------\""); + good("\"\xed\x9f\xbf----------\""); + + good("\"\xed\x90\x90----------\""); + + good("\"\xee\x80\x80----------\""); + good("\"\xee\xbf\x80----------\""); + good("\"\xef\x80\x80----------\""); + good("\"\xef\xbf\x80----------\""); + good("\"\xee\x80\xbf----------\""); + good("\"\xee\xbf\xbf----------\""); + good("\"\xef\x80\xbf----------\""); + good("\"\xef\xbf\xbf----------\""); + + good("\"\xee\x90\x90----------\""); + good("\"\xef\x90\x90----------\""); + + good("\"\xf0\x90\x80\x80----------\""); + good("\"\xf0\x90\xbf\x80----------\""); + good("\"\xf0\x90\xbf\xbf----------\""); + good("\"\xf0\x90\x80\xbf----------\""); + good("\"\xf0\xbf\x80\x80----------\""); + good("\"\xf0\xbf\xbf\x80----------\""); + good("\"\xf0\xbf\xbf\xbf----------\""); + good("\"\xf0\xbf\x80\xbf----------\""); + + good("\"\xf0\xA0\x90\x90----------\""); + + good("\"\xf4\x80\x80\x80----------\""); + good("\"\xf4\x80\xbf\x80----------\""); + good("\"\xf4\x80\xbf\xbf----------\""); + good("\"\xf4\x80\x80\xbf----------\""); + good("\"\xf4\x8f\x80\x80----------\""); + good("\"\xf4\x8f\xbf\x80----------\""); + good("\"\xf4\x8f\xbf\xbf----------\""); + good("\"\xf4\x8f\x80\xbf----------\""); + + good("\"\xf4\x88\x90\x90----------\""); + + good("\"\xf1\x80\x80\x80----------\""); + good("\"\xf1\x80\xbf\x80----------\""); + good("\"\xf1\x80\xbf\xbf----------\""); + good("\"\xf1\x80\x80\xbf----------\""); + good("\"\xf1\xbf\x80\x80----------\""); + good("\"\xf1\xbf\xbf\x80----------\""); + good("\"\xf1\xbf\xbf\xbf----------\""); + good("\"\xf1\xbf\x80\xbf----------\""); + good("\"\xf3\x80\x80\x80----------\""); + good("\"\xf3\x80\xbf\x80----------\""); + good("\"\xf3\x80\xbf\xbf----------\""); + good("\"\xf3\x80\x80\xbf----------\""); + good("\"\xf3\xbf\x80\x80----------\""); + good("\"\xf3\xbf\xbf\x80----------\""); + good("\"\xf3\xbf\xbf\xbf----------\""); + good("\"\xf3\xbf\x80\xbf----------\""); + + good("\"\xf2\x90\x90\x90----------\""); + + bad("\"\xc0\x80----------\""); + bad("\"\xc2\xc0----------\""); + bad("\"\xef\x80----------\""); + bad("\"\xdf\x70----------\""); + + bad("\"\xff\x90----------\""); + + bad("\"\xe0\x9f\x80----------\""); + bad("\"\xe0\xa0\xfe----------\""); + bad("\"\xc0\xff\xff----------\""); + bad("\"\xc0\xbf\x76----------\""); + + bad("\"\xe0\xde\x90----------\""); + + bad("\"\xe1\x80\x7f----------\""); + bad("\"\xe1\x7f\x80----------\""); + bad("\"\xec\xff\x80----------\""); + bad("\"\xef\x7f\x80----------\""); + bad("\"\xe1\x80\xff----------\""); + bad("\"\xe1\xbf\x0f----------\""); + bad("\"\xec\x01\xff----------\""); + bad("\"\xec\xff\xff----------\""); + + bad("\"\xe6\x60\x90----------\""); + + bad("\"\xed\x7f\x80----------\""); + bad("\"\xed\xa0\xbf----------\""); + bad("\"\xed\xbf\x80----------\""); + bad("\"\xed\x9f\x7f----------\""); + + bad("\"\xed\xce\xbf----------\""); + + bad("\"\xee\x7f\x80----------\""); + bad("\"\xee\xcc\x80----------\""); + bad("\"\xef\x80\xcc----------\""); + bad("\"\xef\xbf\x0a----------\""); + bad("\"\xee\x50\xbf----------\""); + bad("\"\xee\xef\xbf----------\""); + bad("\"\xef\xf0\xff----------\""); + bad("\"\xef\xaa\xee----------\""); + + bad("\"\xc0\x90\x90----------\""); + bad("\"\xc1\x90\x90----------\""); + + bad("\"\xff\x90\x80\x80----------\""); + bad("\"\xfe\x90\xbf\x80----------\""); + bad("\"\xfd\x90\xbf\xbf----------\""); + bad("\"\xf0\xff\x80\xbf----------\""); + bad("\"\xf0\xfe\x80\x80----------\""); + bad("\"\xf0\xfd\xbf\x80----------\""); + bad("\"\xf0\x90\x80\xff----------\""); + bad("\"\xf0\x90\x5f\x80----------\""); + + bad("\"\xf4\x70\x80\x80----------\""); + bad("\"\xf4\x80\x70\x80----------\""); + bad("\"\xf4\x80\xbf\x70----------\""); + bad("\"\xf4\xce\x80\xbf----------\""); + bad("\"\xf4\x8f\xce\x80----------\""); + bad("\"\xf4\x8f\xbf\xce----------\""); + + bad("\"\xf1\x7f\xbf\xbf----------\""); + bad("\"\xf2\x80\x7f\xbf----------\""); + bad("\"\xf3\x80\xbf\xce----------\""); + + // utf8 after escape + good("\"\\u0000 \xf3\xbf\x80\xbf\xf3\xbf\x80\xbf\""); + good("\"\\ud7ff\xf4\x80\xbf\xbf \""); + good("\"\\ue000 \xef\xbf\x80\""); + good("\"\xef\xbf\x80 \\uffff \xef\xbf\x80\""); + good("\"\xc2\x80\xc2\x80\xc2\x80\xc2\x80\xc2\x80\\ud800\\udc00 \""); + good("\"\\udbff\\udfff \xe1\x80\xbf \\udbff\\udfff \xe1\x80\xbf\""); + good("\"\\u0000\xe1\x80\xbf \""); + bad("\"\\t\\t\xf4\x70\x80\x80----------\""); + bad("\"\\n\xf4\x80\x70\x80----------\""); + bad("\"\\n\xf4\x80\xbf\x70-\\n\xf4\x80\xbf\x70\""); + + const auto check = + [this](string_view expected) + { + good(expected); + for (std::size_t write_size : {2, 4, 8}) + { + utf8_parser p; + for(std::size_t i = 0; i < expected.size(); i += write_size) + { + error_code ec; + write_size = (std::min)(write_size, expected.size() - i); + auto more = (i < expected.size() - write_size); + auto written = p.write(more, + expected.data() + i, write_size, ec); + BOOST_TEST(written == write_size); + BOOST_TEST(! ec); + } + BOOST_TEST(p.captured() == + expected.substr(1, expected.size() - 2)); + } + }; + + check("\"\xd1\x82\""); + check("\"\xd1\x82\xd0\xb5\xd1\x81\xd1\x82\""); + check("\"\xc3\x0b1""and\xc3\xba\""); + } + + void + testMaxDepth() + { + { + string_view s = "[[[[[]]]]]"; + parse_options opt; + opt.max_depth = 4; + null_parser p(opt); + error_code ec; + p.write(s.data(), s.size(), ec); + BOOST_TEST(ec == error::too_deep); + BOOST_TEST(ec.has_location()); + } + { + string_view s = "[[[[]]], [[[[]]]]]"; + parse_options opt; + opt.max_depth = 4; + null_parser p(opt); + error_code ec; + p.write(s.data(), s.size(), ec); + BOOST_TEST(ec == error::too_deep); + BOOST_TEST(ec.has_location()); + } + { + string_view s = + "{\"a\":{\"b\":{\"c\":{}}},\"b\":{\"c\":{\"d\":{\"e\":{}}}}}"; + parse_options opt; + opt.max_depth = 4; + null_parser p(opt); + error_code ec; + p.write(s.data(), s.size(), ec); + BOOST_TEST(ec == error::too_deep); + BOOST_TEST(ec.has_location()); + } + { + string_view s = + "{\"a\":{\"b\":{\"c\":{\"d\":{}}}}}"; + parse_options opt; + opt.max_depth = 4; + null_parser p(opt); + error_code ec; + p.write(s.data(), s.size(), ec); + BOOST_TEST(ec == error::too_deep); + BOOST_TEST(ec.has_location()); + } + } + + class literal_parser + { + struct handler + { + constexpr static std::size_t max_object_size = std::size_t(-1); + constexpr static std::size_t max_array_size = std::size_t(-1); + constexpr static std::size_t max_key_size = std::size_t(-1); + constexpr static std::size_t max_string_size = std::size_t(-1); + + std::string captured = ""; + bool on_document_begin( error_code& ) { return true; } + bool on_document_end( error_code& ) { return true; } + bool on_object_begin( error_code& ) { return true; } + bool on_object_end( std::size_t, error_code& ) { return true; } + bool on_array_begin( error_code& ) { return true; } + bool on_array_end( std::size_t, error_code& ) { return true; } + bool on_key_part( string_view, std::size_t, error_code& ) { return true; } + bool on_key( string_view, std::size_t, error_code& ) { return true; } + bool on_string_part( string_view, std::size_t, error_code& ) { return true; } + bool on_string( string_view, std::size_t, error_code& ) { return true; } + bool on_number_part( string_view sv, error_code&) + { + captured.append(sv.data(), sv.size()); + return true; + } + bool on_int64( std::int64_t, string_view sv, error_code& ) + { + captured.append(sv.data(), sv.size()); + captured += 's'; + return true; + } + bool on_uint64( std::uint64_t, string_view sv, error_code& ) + { + captured.append(sv.data(), sv.size()); + captured += 'u'; + return true; + } + bool on_double( double, string_view sv, error_code& ) + { + captured.append(sv.data(), sv.size()); + captured += 'd'; + return true; + } + bool on_bool( bool, error_code& ) { return true; } + bool on_null( error_code& ) { return true; } + bool on_comment_part( string_view, error_code& ) { return true; } + bool on_comment( string_view, error_code& ) { return true; } + }; + + basic_parser<handler> p_; + + public: + literal_parser() + : p_(make_options(true, false, false)) + { + } + + std::size_t + write( + bool more, + char const* data, + std::size_t size, + error_code& ec) + { + auto const n = p_.write_some( + more, data, size, ec); + if(! ec && n < size) + ec = error::extra_data; + return n; + } + + string_view + captured() + { + return p_.handler().captured; + } + }; + + void + testNumberLiteral() + { + const auto check = + [](string_view expected) + { + string_view sv = expected; + sv.remove_suffix(1); + for(std::size_t i = 0; + i < sv.size(); ++i) + { + literal_parser p; + error_code ec; + if(i != 0) + { + p.write(true, + sv.data(), i, ec); + } + if(BOOST_TEST(! ec)) + { + p.write(false, + sv.data() + i, + sv.size() - i, ec); + } + BOOST_TEST(! ec); + BOOST_TEST(p.captured() == expected); + } + }; + + check("1s"); + check("-1s"); + check("0s"); + check("0s"); + check("123456s"); + check("-123456s"); + check("9223372036854775808u"); + + check("1.0d"); + check("-1.0d"); + check("0.0d"); + check("1.0e3d"); + check("1e1d"); + check("1e+1d"); + check("1e-1d"); + check("-100000000000000000000000d"); + check("100000000000000000000000d"); + check("10000000000.10000000000000d"); + check("-10000000000.10000000000000d"); + check("1000000000000000.0e1000000d"); + } + + void + testStickyErrors() + { + { + null_parser p; + error_code ec; + p.write("*", 1, ec); + BOOST_TEST(ec); + error_code ec2; + p.write("[]", 2, ec2); + BOOST_TEST(ec2 == ec); + p.reset(); + p.write("[]", 2, ec2); + BOOST_TEST(! ec2); + } + + // exceptions do not cause UB + { + throw_parser p(1); + try + { + error_code ec; + p.write(false, "null", 4, ec); + BOOST_TEST_FAIL(); + } + catch(std::exception const&) + { + error_code ec; + p.write(false, "null", 4, ec); + BOOST_TEST(ec == error::exception); + BOOST_TEST(ec.has_location()); + } + } + } + +#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW + using SV = std::string_view; +#else + using SV = string_view; +#endif + // The null parser, but uses std type equivalents + class std_null_parser + { + struct handler + { + constexpr static std::size_t max_object_size = std::size_t(-1); + constexpr static std::size_t max_array_size = std::size_t(-1); + constexpr static std::size_t max_key_size = std::size_t(-1); + constexpr static std::size_t max_string_size = std::size_t(-1); + + bool on_document_begin( std::error_code& ) { return true; } + bool on_document_end( std::error_code& ) { return true; } + bool on_object_begin( std::error_code& ) { return true; } + bool on_object_end( std::size_t, std::error_code& ) { return true; } + bool on_array_begin( std::error_code& ) { return true; } + bool on_array_end( std::size_t, std::error_code& ) { return true; } + bool on_key_part( SV, std::size_t, std::error_code& ) { return true; } + bool on_key( SV, std::size_t, std::error_code& ) { return true; } + bool on_string_part( SV, std::size_t, std::error_code& ) { return true; } + bool on_string( SV, std::size_t, std::error_code& ) { return true; } + bool on_number_part( SV, std::error_code&) { return true; } + bool on_int64( std::int64_t, SV, std::error_code& ) { return true; } + bool on_uint64( std::uint64_t, SV, std::error_code& ) { return true; } + bool on_double( double, SV, std::error_code& ) { return true; } + bool on_bool( bool, std::error_code& ) { return true; } + bool on_null( std::error_code& ) { return true; } + bool on_comment_part( SV, std::error_code& ) { return true; } + bool on_comment( SV, std::error_code& ) { return true; } + }; + + basic_parser<handler> p_; + + public: + std_null_parser() + : p_(parse_options()) + { + } + + explicit + std_null_parser(parse_options po) + : p_(po) + { + } + + void + reset() + { + p_.reset(); + } + + std::size_t + write( + SV s, + std::error_code& ec) + { + auto const n = p_.write_some( + false, s.data(), s.size(), ec); + if(! ec && n < s.size()) + ec = error::extra_data; + return n; + } + }; + + void testStdTypes() + { + std_null_parser p; + std::error_code ec; + std::string const doc = "{}"; + p.write(doc, ec); + if(! BOOST_TEST(! ec)) + { + log << " failed to parse: " << doc << '\n'; + return; + } + } + + void + run() + { + testNull(); + testBoolean(); + testString(); + testNumber(); + testArray(); + testObject(); + testParser(); + testMembers(); + testParseVectors(); + testIssue13(); + testIssue20(); + testIssue113(); + testAllowTrailing(); + testComments(); + testUTF8Validation(); + testMaxDepth(); + testNumberLiteral(); + testStickyErrors(); + testStdTypes(); + } +}; + +TEST_SUITE(basic_parser_test, "boost.json.basic_parser"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/checking_resource.hpp b/src/boost/libs/json/test/checking_resource.hpp new file mode 100644 index 000000000..077f8ba7f --- /dev/null +++ b/src/boost/libs/json/test/checking_resource.hpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2021 Dmitry Arkhipov (grisumbras@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#ifndef BOOST_JSON_CHECKING_RESOURCE_HPP +#define BOOST_JSON_CHECKING_RESOURCE_HPP + +#include <boost/json/storage_ptr.hpp> +#include <map> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class checking_resource + : public memory_resource +{ + storage_ptr upstream_; + std::map<void const*, std::pair<std::size_t, std::size_t>> allocs_; + +public: + explicit checking_resource(storage_ptr upstream = {}) noexcept + : upstream_(std::move(upstream)) + {} + +private: + void* do_allocate(std::size_t size, std::size_t alignment) override + { + void* result = upstream_->allocate(size, alignment); + allocs_.emplace(result, std::make_pair(size, alignment)); + return result; + } + + void do_deallocate(void* ptr, std::size_t size, std::size_t alignment) + override + { + auto const it = allocs_.find(ptr); + if( BOOST_TEST(it != allocs_.end()) ) + { + BOOST_TEST(size == it->second.first); + BOOST_TEST(alignment == it->second.second); + + allocs_.erase(it); + } + + return upstream_->deallocate(ptr, size, alignment); + } + + bool do_is_equal(memory_resource const& other) const noexcept + override + { + return this == &other; + } +}; + +BOOST_JSON_NS_END + +#endif // BOOST_JSON_CHECKING_RESOURCE_HPP diff --git a/src/boost/libs/json/test/cmake_install_test/CMakeLists.txt b/src/boost/libs/json/test/cmake_install_test/CMakeLists.txt new file mode 100644 index 000000000..fb7ef02c6 --- /dev/null +++ b/src/boost/libs/json/test/cmake_install_test/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright 2018 Peter Dimov +# Copyright 2018 Richard Hodges +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5...3.16) + +project(cmake_install_test LANGUAGES CXX) + +find_package(boost_json REQUIRED) + +add_executable(main main.cpp) +target_link_libraries(main Boost::json) + +enable_testing() +add_test(NAME main COMMAND main) + +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
\ No newline at end of file diff --git a/src/boost/libs/json/test/cmake_install_test/main.cpp b/src/boost/libs/json/test/cmake_install_test/main.cpp new file mode 100644 index 000000000..29f40f64c --- /dev/null +++ b/src/boost/libs/json/test/cmake_install_test/main.cpp @@ -0,0 +1,13 @@ +// Copyright 2018 Peter Dimov +// Copyright 2020 Richard Hodges +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt + +#include <boost/json.hpp> +#include <cstdio> + +int main() +{ + const boost::json::value value = boost::json::parse("{ \"test\": true }"); + std::puts(boost::json::to_string(value).c_str()); +} diff --git a/src/boost/libs/json/test/doc_background.cpp b/src/boost/libs/json/test/doc_background.cpp new file mode 100644 index 000000000..45313dbe8 --- /dev/null +++ b/src/boost/libs/json/test/doc_background.cpp @@ -0,0 +1,205 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/static_resource.hpp> +#include <boost/json/value.hpp> +#include <boost/container/pmr/vector.hpp> +#include <vector> + +#include "test_suite.hpp" + +#ifdef assert +#undef assert +#endif +#define assert BOOST_TEST + +BOOST_JSON_NS_BEGIN + +namespace doc_background { + +namespace background { +template<class T> +using vector = boost::container::pmr::vector<T>; +} // background + +//---------------------------------------------------------- + +namespace std { +template<class T> +using allocator = ::std::allocator<T>; +} // std + +//[doc_background_1 +namespace std { + +template< class T, class Allocator = std::allocator< T > > +class vector; + +} // namespace std +//] + +//---------------------------------------------------------- + +//[doc_background_2 +namespace std { + +template< class T, class Allocator > +class vector +{ +public: + explicit vector( Allocator const& alloc ); + + //... +//] +}; + +template<class T, class A> +vector<T,A>::vector(A const&){} +} + +//---------------------------------------------------------- + +//[doc_background_3 +namespace std { +namespace pmr { + +class memory_resource +{ +public: + virtual ~memory_resource(); + + void* allocate ( size_t bytes, size_t alignment ); + void deallocate( void* p, size_t bytes, size_t alignment ); + bool is_equal ( const memory_resource& other ) const; + +protected: + virtual void* do_allocate ( size_t bytes, size_t alignment ) = 0; + virtual void do_deallocate( void* p, size_t bytes, size_t alignment ) = 0; + virtual bool do_is_equal ( memory_resource const& other ) const noexcept = 0; +}; + +} // namespace pmr +} // namespace std +//] + +//---------------------------------------------------------- + +//[doc_background_4 + +namespace std { +namespace pmr { + +template< class T > +using vector = std::vector< T, polymorphic_allocator< T > >; + +} // namespace pmr +} // namespace std + +//] + +//---------------------------------------------------------- + +static void set1() { +using namespace background; + +//---------------------------------------------------------- +{ +struct T {}; +//[doc_background_5 +// A type of memory resource +monotonic_resource mr; + +// Construct a vector using the monotonic buffer resource +vector< T > v1(( polymorphic_allocator< T >(&mr) )); + +// Or this way, since construction from memory_resource* is implicit: +vector< T > v2( &mr ); +//] +} +//---------------------------------------------------------- +{ +//[doc_background_6 +{ + // A type of memory resource which uses a stack buffer + unsigned char temp[4096]; + static_resource mr( temp, sizeof(temp) ); + + // Construct a vector using the static buffer resource + vector< value > v( &mr ); + + // The vector will allocate from `temp` first, and then the heap. +} +//] +} +//---------------------------------------------------------- + +} // set1 + +//---------------------------------------------------------- + +struct my_resource : memory_resource +{ + void* do_allocate ( size_t, size_t ) override { return 0; } + void do_deallocate( void*, size_t, size_t ) override {} + bool do_is_equal ( memory_resource const& ) const noexcept override { return true; } +}; +//[doc_background_7 +namespace my_library { + +std::pmr::vector<char> get_chars1() +{ + // This leaks memory because `v` does not own the memory resource + std::pmr::vector<char> v( new my_resource ); + + return v; +} + +} // my_library +//] + +//---------------------------------------------------------- + +//[doc_background_8 +namespace my_library { + +std::pmr::vector<char> get_chars2() +{ + // Declare a local memory resource + my_resource mr; + + // Construct a vector that uses our resource + std::pmr::vector<char> v( &mr ); + + // Undefined behavior, `mr` goes out of scope! + return v; +} + +} // my_library +//] + +//---------------------------------------------------------- + +} // doc_background + +class doc_background_test +{ +public: + void + run() + { + using namespace doc_background; + (void)&set1; + BOOST_TEST_PASS(); + } +}; + +TEST_SUITE(doc_background_test, "boost.json.doc_background"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/doc_forward_conversion.cpp b/src/boost/libs/json/test/doc_forward_conversion.cpp new file mode 100644 index 000000000..4017d7011 --- /dev/null +++ b/src/boost/libs/json/test/doc_forward_conversion.cpp @@ -0,0 +1,101 @@ +// +// Copyright (c) 2021 Dmitry Arkhipov (grisumbras@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +//[doc_forward_conversion_1 +namespace boost { +namespace json { + +class value; + +struct value_from_tag; + +template< class T > +struct value_to_tag; + +template< class T > +T value_to( const value& v ); + +template<class T> +void value_from( T&& t, value& jv ); + +} +} +//] + +#include <string> + +namespace thirdparty { + +struct customer +{ + std::uint64_t id; + std::string name; + bool late; + + customer() = default; + + customer( std::uint64_t i, const std::string& n, bool l ) + : id( i ), name( n ), late( l ) { } +}; + +} // namespace thirdparty + +//[doc_forward_conversion_2 +namespace thirdparty { + +template< class JsonValue > +customer tag_invoke( const boost::json::value_to_tag<customer>&, const JsonValue& jv ) +{ + std::uint64_t id = boost::json::value_to<std::uint64_t>( jv.at( "id" ) ); + std::string name = boost::json::value_to< std::string >( jv.at( "name" ) ); + bool late = boost::json::value_to<bool>( jv.at( "late" ) ); + return customer(id, std::move(name), late); +} + +template< class JsonValue > +void tag_invoke( const boost::json::value_from_tag&, JsonValue& jv, const customer& c) +{ + auto& obj = jv.emplace_object(); + boost::json::value_from(c.id, obj["id"]); + boost::json::value_from(c.name, obj["name"]); + boost::json::value_from(c.late, obj["late"]); +} + +} +//] + + +#include <boost/json/value_from.hpp> +#include <boost/json/value_to.hpp> + +#include "test_suite.hpp" + + +BOOST_JSON_NS_BEGIN + +class doc_forward_conversion +{ +public: + void + run() + { + value const jv{ { "id", 1 }, { "name", "Carl" }, { "late", true } }; + auto const c = value_to<thirdparty::customer>( jv ); + BOOST_TEST( c.id == 1 ); + BOOST_TEST( c.name == "Carl" ); + BOOST_TEST( c.late ); + + value const jv2 = value_from( c ); + BOOST_TEST( jv == jv2 ); + } +}; + +TEST_SUITE(doc_forward_conversion, "boost.json.doc_forward_conversion"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/doc_parsing.cpp b/src/boost/libs/json/test/doc_parsing.cpp new file mode 100644 index 000000000..de064d3c1 --- /dev/null +++ b/src/boost/libs/json/test/doc_parsing.cpp @@ -0,0 +1,254 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/null_resource.hpp> +#include <boost/json/parse.hpp> +#include <boost/json/parser.hpp> +#include <boost/json/static_resource.hpp> +#include <boost/json/stream_parser.hpp> + +#include <iostream> +#include <string> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +//---------------------------------------------------------- + +static void set1() { + +//---------------------------------------------------------- +{ +//[doc_parsing_1 +value jv = parse( "[1,2,3,4,5]" ); +//] +} +//---------------------------------------------------------- +{ +//[doc_parsing_2 +error_code ec; +value jv = parse( "[1,2,3,4,5]", ec ); +if( ec ) + std::cout << "Parsing failed: " << ec.message() << "\n"; +//] +} +//---------------------------------------------------------- +{ +//[doc_parsing_3 +try +{ + error_code ec; + value jv = parse( "[1,2,3,4,5]", ec ); + if( ec ) + std::cout << "Parsing failed: " << ec.message() << "\n"; +} +catch( std::bad_alloc const& e) +{ + std::cout << "Parsing failed: " << e.what() << "\n"; +} +//] +} +//---------------------------------------------------------- +{ +//[doc_parsing_4 +{ + monotonic_resource mr; + + value const jv = parse( "[1,2,3,4,5]", &mr ); +} +//] +} +//---------------------------------------------------------- +{ +//[doc_parsing_5 +parse_options opt; // all extensions default to off +opt.allow_comments = true; // permit C and C++ style comments to appear in whitespace +opt.allow_trailing_commas = true; // allow an additional trailing comma in object and array element lists +opt.allow_invalid_utf8 = true; // skip utf-8 validation of keys and strings + +value jv = parse( "[1,2,3,] // comment ", storage_ptr(), opt ); +//] +} +//---------------------------------------------------------- +{ +#if __cpp_designated_initializers >= 201707L +//[doc_parsing_6 +value jv = parse( "[1,2,3,] // comment ", storage_ptr(), + { + .allow_comments = true, // permit C and C++ style comments to appear in whitespace + .allow_trailing_commas = true, // allow a trailing comma in object and array lists + .allow_invalid_utf8 = true // skip utf-8 validation of keys and strings + }); +//] +#endif +} +//---------------------------------------------------------- + +} // set1 + +//---------------------------------------------------------- +//[doc_parsing_7 +class connection +{ + parser p_; // persistent data member + +public: + void do_read( string_view s ) // called for each complete message from the network + { + p_.reset(); // start parsing a new JSON using the default resource + p_.write( s ); // parse the buffer, using exceptions to indicate error + do_rpc( p_.release() ); // process the command + } + + void do_rpc( value jv ); +}; +//] + +//---------------------------------------------------------- + +static void set2() { + +//---------------------------------------------------------- +{ +//[doc_parsing_8 +stream_parser p; +error_code ec; +string_view s = "[1,2,3] %HOME%"; +std::size_t n = p.write_some( s, ec ); +assert( ! ec && p.done() && n == 8 ); +s = s.substr( n ); +value jv = p.release(); +assert( s == "%HOME%" ); +//] +} +//---------------------------------------------------------- +{ +//[doc_parsing_9 +parse_options opt; // All extensions default to off +opt.allow_comments = true; // Permit C and C++ style comments to appear in whitespace +opt.allow_trailing_commas = true; // Allow an additional trailing comma in object and array element lists +opt.allow_invalid_utf8 = true; // Skip utf-8 validation of keys and strings +stream_parser p( storage_ptr(), opt ); // The stream_parser will use the options +//] +} +//---------------------------------------------------------- + +} // set2 + +//---------------------------------------------------------- +//[doc_parsing_10 +value read_json( std::istream& is, error_code& ec ) +{ + stream_parser p; + std::string line; + while( std::getline( is, line ) ) + { + p.write( line, ec ); + if( ec ) + return nullptr; + } + p.finish( ec ); + if( ec ) + return nullptr; + return p.release(); +} +//] + +//---------------------------------------------------------- + +static void set3() { + +//---------------------------------------------------------- +{ +//[doc_parsing_11 +{ + monotonic_resource mr; + + stream_parser p; + p.reset( &mr ); // Use mr for the resulting value + p.write( "[1,2,3,4,5]" ); // Parse the input JSON + value const jv = p.release(); // Retrieve the result + assert( *jv.storage() == mr ); // Same memory resource +} +//] +} +//---------------------------------------------------------- +{ +//[doc_parsing_12 +unsigned char temp[ 4096 ]; // Declare our buffer +stream_parser p( + storage_ptr(), // Default memory resource + parse_options{}, // Default parse options (strict parsing) + temp); // Use our buffer for temporary storage +//] +} +//---------------------------------------------------------- + +} // set3 + +//---------------------------------------------------------- + +//[doc_parsing_13 +/* Parse JSON and invoke the handler + + This function parses the JSON specified in `s` + and invokes the handler, whose signature must + be equivalent to: + + void( value const& jv ); + + The operation is guaranteed not to perform any + dynamic memory allocations. However, some + implementation-defined upper limits on the size + of the input JSON and the size of the resulting + value are imposed. + + Upon error, an exception is thrown. +*/ +template< class Handler > +void do_rpc( string_view s, Handler&& handler ) +{ + unsigned char temp[ 4096 ]; // The parser will use this storage for its temporary needs + parser p( // Construct a strict parser using the temp buffer and no dynamic memory + get_null_resource(), // The null resource never dynamically allocates memory + parse_options(), // Default constructed parse options allow only standard JSON + temp ); + + unsigned char buf[ 16384 ]; // Now we need a buffer to hold the actual JSON values + static_resource mr2( buf ); // The static resource is monotonic, using only a caller-provided buffer + p.reset( &mr2 ); // Use the static resource for producing the value + p.write( s ); // Parse the entire string we received from the network client + + // Retrieve the value and invoke the handler with it. + // The value will use `buf` for storage. The handler + // must not take ownership, since monotonic resources + // are inefficient with mutation. + handler( p.release() ); +} +//] + +//---------------------------------------------------------- + +class doc_parsing_test +{ +public: + void + run() + { + (void)&set1; + (void)&set2; + (void)&set3; + } +}; + +TEST_SUITE(doc_parsing_test, "boost.json.doc_parsing"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/doc_quick_look.cpp b/src/boost/libs/json/test/doc_quick_look.cpp new file mode 100644 index 000000000..64318c5e7 --- /dev/null +++ b/src/boost/libs/json/test/doc_quick_look.cpp @@ -0,0 +1,333 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json.hpp> +#include <boost/container/pmr/vector.hpp> +#include <iostream> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +static void set1() { + +//---------------------------------------------------------- +{ +//[doc_quick_look_1 +object obj; // construct an empty object +obj[ "pi" ] = 3.141; // insert a double +obj[ "happy" ] = true; // insert a bool +obj[ "name" ] = "Boost"; // insert a string +obj[ "nothing" ] = nullptr; // insert a null +obj[ "answer" ].emplace_object()["everything"] = 42; // insert an object with 1 element +obj[ "list" ] = { 1, 0, 2 }; // insert an array with 3 elements +obj[ "object" ] = { {"currency", "USD"}, {"value", 42.99} }; // insert an object with 2 elements +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_2 +value jv = { + { "pi", 3.141 }, + { "happy", true }, + { "name", "Boost" }, + { "nothing", nullptr }, + { "answer", { + { "everything", 42 } } }, + {"list", {1, 0, 2}}, + {"object", { + { "currency", "USD" }, + { "value", 42.99 } + } } + }; +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_3 +array arr; // construct an empty array +arr = { 1, 2, 3 }; // replace the contents with 3 elements +value jv1( arr ); // this makes a copy of the array +value jv2( std::move(arr) ); // this performs a move-construction + +assert( arr.empty() ); // moved-from arrays become empty +arr = { nullptr, true, "boost" }; // fill in the array again +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_4 +{ + unsigned char buf[ 4096 ]; // storage for our array + static_resource mr( buf ); // memory resource which uses buf + array arr( &mr ); // construct using the memory resource + arr = { 1, 2, 3 }; // all allocated memory comes from `buf` +} +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_5 +{ + monotonic_resource mr; // memory resource optimized for insertion + array arr( &mr ); // construct using the memory resource + arr.resize( 1 ); // make space for one element + arr[ 0 ] = { 1, 2, 3 }; // assign an array to element 0 + assert( *arr[0].storage() == *arr.storage() ); // same memory resource +} +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_6 +{ + monotonic_resource mr; + boost::container::pmr::vector< value > vv( &mr ); + vv.resize( 3 ); + + // The memory resource of the container is propagated to each element + assert( *vv.get_allocator().resource() == *vv[0].storage() ); + assert( *vv.get_allocator().resource() == *vv[1].storage() ); + assert( *vv.get_allocator().resource() == *vv[2].storage() ); +} +//] +} +//---------------------------------------------------------- + +} // set1() + +//---------------------------------------------------------- + +//[doc_quick_look_7 +value f() +{ + // create a reference-counted memory resource + storage_ptr sp = make_shared_resource< monotonic_resource >(); + + // construct with shared ownership of the resource + value jv( sp ); + + // assign an array with 3 elements, the monotonic resource will be used + jv = { 1, 2, 3 }; + + // The caller receives the value, which still owns the resource + return jv; +} +//] +//---------------------------------------------------------- + +static void set2() { + +//---------------------------------------------------------- +{ +//[doc_quick_look_8 +value jv = parse( "[1, 2, 3]" ); +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_9 +error_code ec; +value jv = parse( R"( "Hello, world!" )", ec ); +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_10 +unsigned char buf[ 4096 ]; +static_resource mr( buf ); +parse_options opt; +opt.allow_comments = true; +opt.allow_trailing_commas = true; +value jv = parse( "[1, 2, 3, ] // array ", &mr, opt ); +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_11 +stream_parser p; +error_code ec; +p.reset(); +p.write( "[1, 2 ", ec ); +if( ! ec ) + p.write( ", 3]", ec ); +if( ! ec ) + p.finish( ec ); +if( ec ) + return; +value jv = p.release(); +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_12 +value jv = { 1, 2, 3 }; +std::string s = serialize( jv ); // produces "[1,2,3]" +//] +} +//---------------------------------------------------------- +{ +value jv; +//[doc_quick_look_13 +serializer sr; +sr.reset( &jv ); // prepare to output `jv` +do +{ + char buf[ 16 ]; + std::cout << sr.read( buf ); +} +while( ! sr.done() ); +//] +} +//---------------------------------------------------------- + +} // set2() + +//---------------------------------------------------------- + +//[doc_quick_look_14 +namespace my_app { + +struct customer +{ + int id; + std::string name; + bool current; +}; + +} // namespace my_app +//] + +//---------------------------------------------------------- + +//[doc_quick_look_15 +namespace my_app { + +void tag_invoke( value_from_tag, value& jv, customer const& c ) +{ + jv = { + { "id" , c.id }, + { "name", c.name }, + { "current", c.current } + }; +} + +} // namespace my_app +//] + +static void set3() { + +//---------------------------------------------------------- +{ +//[doc_quick_look_16 +my_app::customer c{ 1001, "Boost", true }; +std::cout << serialize( value_from( c ) ); +//] +} +//---------------------------------------------------------- +{ +//[doc_quick_look_17 +std::vector< my_app::customer > vc; +//... +value jv = value_from( vc ); +//] +} +//---------------------------------------------------------- + +} // set3() + +//---------------------------------------------------------- + +//[doc_quick_look_18 +namespace my_app { + +// This helper function deduces the type and assigns the value with the matching key +template<class T> +void extract( object const& obj, T& t, string_view key ) +{ + t = value_to<T>( obj.at( key ) ); +} + +customer tag_invoke( value_to_tag< customer >, value const& jv ) +{ + customer c; + object const& obj = jv.as_object(); + extract( obj, c.id, "id" ); + extract( obj, c.name, "name" ); + extract( obj, c.current, "current" ); + return c; +} + +} // namespace my_app +//] + +//---------------------------------------------------------- + +namespace my_app_2 { +namespace my_app { using boost::json::my_app::customer; } +//[doc_quick_look_19 +namespace my_app { + +customer tag_invoke( value_to_tag< customer >, value const& jv ) +{ + object const& obj = jv.as_object(); + return customer { + value_to<int>( obj.at( "id" ) ), + value_to<std::string>( obj.at( "name" ) ), + value_to<bool>( obj.at( "current" ) ) + }; +} + +} // namespace my_app +//] +} // my_app_2 + +//---------------------------------------------------------- + +static void set4() { +using namespace my_app; + +//---------------------------------------------------------- +{ +//[doc_quick_look_20 +json::value jv; +//... +customer c( value_to<customer>(jv) ); +//] +} +//---------------------------------------------------------- +{ +json::value jv; +//[doc_quick_look_21 +std::vector< customer > vc = value_to< std::vector< customer > >( jv ); +//] +} +//---------------------------------------------------------- + +//---------------------------------------------------------- + +} // set4 + +class doc_quick_look_test +{ +public: + void + run() + { + (void)&set1; + (void)&set2; + (void)&set3; + (void)&set4; + BOOST_TEST_PASS(); + } +}; + +TEST_SUITE(doc_quick_look_test, "boost.json.doc_quick_look"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/doc_serializing.cpp b/src/boost/libs/json/test/doc_serializing.cpp new file mode 100644 index 000000000..8d1dc4566 --- /dev/null +++ b/src/boost/libs/json/test/doc_serializing.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/serialize.hpp> +#include <boost/json/serializer.hpp> + +#include <iostream> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +//---------------------------------------------------------- + +static void set1() { + +//---------------------------------------------------------- +{ +//[doc_serializing_1 +value jv = { 1, 2, 3, 4, 5 }; + +std::cout << jv << "\n"; +//] +} +//---------------------------------------------------------- +{ +//[doc_serializing_2 +value jv = { 1, 2, 3, 4, 5 }; + +std::string s = serialize( jv ); +//] +} +//---------------------------------------------------------- +{ +//[doc_serializing_3 +//] +} +//---------------------------------------------------------- +{ +//[doc_serializing_4 +//] +} +//---------------------------------------------------------- +{ +//[doc_serializing_5 +//] +} +//---------------------------------------------------------- +{ +//[doc_serializing_6 +//] +} +//---------------------------------------------------------- + +} // set1 + +class doc_serializing_test +{ +public: + void + run() + { + (void)&set1; + } +}; + +TEST_SUITE(doc_serializing_test, "boost.json.doc_serializing"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/doc_storage_ptr.cpp b/src/boost/libs/json/test/doc_storage_ptr.cpp new file mode 100644 index 000000000..a13c851d1 --- /dev/null +++ b/src/boost/libs/json/test/doc_storage_ptr.cpp @@ -0,0 +1,176 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/parse.hpp> +#include <boost/json/static_resource.hpp> +#include <boost/json/storage_ptr.hpp> +#include <boost/json/value.hpp> + +#include <iostream> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +//---------------------------------------------------------- + +static void set1() { + +//---------------------------------------------------------- +{ +//[doc_storage_ptr_1 +storage_ptr sp1; +storage_ptr sp2; + +assert( sp1.get() != nullptr ); // always points to a valid resource +assert( sp1.get() == sp2.get() ); // both point to the default resource +assert( *sp1.get() == *sp2.get() ); // the default resource compares equal +//] +} +//---------------------------------------------------------- +{ +//[doc_storage_ptr_2 +array arr; // default construction +object obj; +string str; +value jv; + +assert( jv.storage().get() == storage_ptr().get() ); // uses the default memory resource +assert( jv.storage().get() == arr.storage().get() ); // both point to the default resource +assert( *arr.storage() == *obj.storage() ); // containers use equivalent resources +//] +} +//---------------------------------------------------------- +{ +//[doc_storage_ptr_3 +monotonic_resource mr; + +value const jv = parse( "[1,2,3]", &mr ); +//] +} +//---------------------------------------------------------- + +} // set1 + +//---------------------------------------------------------- + +//[doc_storage_ptr_4 +value parse_value( string_view s) +{ + return parse( s, make_shared_resource< monotonic_resource >() ); +} +//] + +//---------------------------------------------------------- + +//[doc_storage_ptr_5 +template< class Handler > +void do_rpc( string_view s, Handler&& h ) +{ + unsigned char buffer[ 8192 ]; // Small stack buffer to avoid most allocations during parse + monotonic_resource mr( buffer ); // This resource will use our local buffer first + value const jv = parse( s, &mr ); // Parse the input string into a value that uses our resource + h( jv ); // Call the handler to perform the RPC command +} +//] + +//---------------------------------------------------------- + +void set2() { + +//---------------------------------------------------------- +{ +//[doc_storage_ptr_6 +unsigned char buffer[ 8192 ]; +static_resource mr( buffer ); // The resource will use our local buffer +//] +} +//---------------------------------------------------------- +{ +//[doc_storage_ptr_7 +monotonic_resource mr; +array arr( &mr ); // construct an array using our resource +arr.emplace_back( "boost" ); // insert a string +assert( *arr[0].as_string().storage() == mr ); // the resource is propagated to the string +//] +} +//---------------------------------------------------------- +{ +//[doc_storage_ptr_8 +{ + monotonic_resource mr; + + array arr( &mr ); // construct an array using our resource + + assert( ! arr.storage().is_shared() ); // no shared ownership +} +//] +} +//---------------------------------------------------------- +{ +//[doc_storage_ptr_9 +storage_ptr sp = make_shared_resource< monotonic_resource >(); + +string str( sp ); + +assert( sp.is_shared() ); // shared ownership +assert( str.storage().is_shared() ); // shared ownership +//] +} +//---------------------------------------------------------- + +} // set2 + +//---------------------------------------------------------- +//[doc_storage_ptr_10 +class logging_resource : public memory_resource +{ +private: + void* do_allocate( std::size_t bytes, std::size_t align ) override + { + std::cout << "Allocating " << bytes << " bytes with alignment " << align << '\n'; + + return ::operator new( bytes ); + } + + void do_deallocate( void* ptr, std::size_t bytes, std::size_t align ) override + { + std::cout << "Deallocating " << bytes << " bytes with alignment " << align << " @ address " << ptr << '\n'; + + return ::operator delete( ptr ); + } + + bool do_is_equal( memory_resource const& other ) const noexcept override + { + // since the global allocation and deallocation functions are used, + // any instance of a logging_resource can deallocate memory allocated + // by another instance of a logging_resource + + return dynamic_cast< logging_resource const* >( &other ) != nullptr; + } +}; +//] + +//---------------------------------------------------------- + +class doc_storage_ptr_test +{ +public: + void + run() + { + (void)&set1; + BOOST_TEST_PASS(); + } +}; + +TEST_SUITE(doc_storage_ptr_test, "boost.json.doc_storage_ptr"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/doc_uses_allocator.cpp b/src/boost/libs/json/test/doc_uses_allocator.cpp new file mode 100644 index 000000000..72aa93ef7 --- /dev/null +++ b/src/boost/libs/json/test/doc_uses_allocator.cpp @@ -0,0 +1,77 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/memory_resource.hpp> +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/value.hpp> +#include <vector> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +//---------------------------------------------------------- + +static void set1() { + +//---------------------------------------------------------- +{ +//[doc_uses_allocator_1 +// We want to use this resource for all the containers +monotonic_resource mr; + +// Declare a vector of JSON values +std::vector< value, polymorphic_allocator< value > > v( &mr ); + +// The polymorphic allocator will use our resource +assert( v.get_allocator().resource() == &mr ); + +// Add a string to the vector +v.emplace_back( "boost" ); + +// The vector propagates the memory resource to the string +assert( v[0].storage().get() == &mr ); +//] +} +//---------------------------------------------------------- +{ +//[doc_uses_allocator_2 +// This vector will use the default memory resource +std::vector< value, polymorphic_allocator < value > > v; + +// This value will same memory resource as the vector +value jv( v.get_allocator() ); + +// However, ownership is not transferred, +assert( ! jv.storage().is_shared() ); + +// and deallocate is never null +assert( ! jv.storage().is_deallocate_trivial() ); +//] +} +//---------------------------------------------------------- + +} // set1 + +//---------------------------------------------------------- + +class doc_uses_allocator_test +{ +public: + void + run() + { + (void)&set1; + BOOST_TEST_PASS(); + } +}; + +TEST_SUITE(doc_uses_allocator_test, "boost.json.doc_uses_allocator"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/doc_using_numbers.cpp b/src/boost/libs/json/test/doc_using_numbers.cpp new file mode 100644 index 000000000..6dfc8e445 --- /dev/null +++ b/src/boost/libs/json/test/doc_using_numbers.cpp @@ -0,0 +1,193 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/parse.hpp> +#include <boost/json/value.hpp> +#include <boost/json/value_to.hpp> + +#include "test_suite.hpp" + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4101) +# pragma warning(disable: 4189) // local variable is initialized but not referenced +#elif defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunused" +# pragma clang diagnostic ignored "-Wunused-variable" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused" +# pragma GCC diagnostic ignored "-Wunused-variable" +#endif + +BOOST_JSON_NS_BEGIN + +//---------------------------------------------------------- + +static void set1() { + +//---------------------------------------------------------- +{ +//[doc_using_numbers_1 +// construction from int +value jv1 = 1; + +assert( jv1.is_int64() ); + +// construction from unsigned int +value jv2 = 2u; + +assert( jv2.is_uint64() ); + +// construction from double +value jv3 = 3.0; + +assert( jv3.is_double() ); +//] +} +//---------------------------------------------------------- +{ +//[doc_using_numbers_2 + +value jv = 1; + +assert( jv.is_int64() ); + +// jv.kind() != kind::uint64; throws +std::uint64_t r1 = jv.as_uint64(); + +// jv.kind() != kind::uint64; the behavior is undefined +std::uint64_t r2 = jv.get_uint64(); + +// if_double will always return nullptr, branch is not taken +if(double* d = jv.if_double()) + assert( false ); + +//] +}; +//---------------------------------------------------------- +{ +//[doc_using_numbers_3 +struct convert_int64 +{ + value jv; + + operator int() const + { + return value_to< int >( this->jv ); + } +}; +//] +} +//---------------------------------------------------------- +try +{ +//[doc_using_numbers_4 + value jv1 = 404; + + assert( jv1.is_int64() ); + + // ok, identity conversion + std::int64_t r1 = value_to< std::int64_t >( jv1 ); + + // loss of data, throws system_error + char r2 = value_to< char >( jv1 ); + + // ok, no loss of data + double r3 = value_to< double >( jv1 ); + + value jv2 = 1.23; + + assert( jv1.is_double() ); + + // ok, same as static_cast<float>( jv2.get_double() ) + float r4 = value_to< float >( jv2 ); + + // not exact, throws system_error + int r5 = value_to< int >( jv2 ); + + value jv3 = {1, 2, 3}; + + assert( ! jv3.is_number() ); + + // not a number, throws system_error + int r6 = value_to< int >( jv3 ); +//] +} +catch(...) +{ +} +//---------------------------------------------------------- +{ +//[doc_using_numbers_5 + +value jv = 10.5; + +error_code ec; + +// ok, conversion is exact +float r1 = jv.to_number< float >( ec ); + +assert( ! ec ); + +// error, conversion is non-exact +int r2 = jv.to_number< int >( ec ); + +assert( ec == error::not_exact ); + +//] +} +//---------------------------------------------------------- +{ +//[doc_using_numbers_6 +value jv = parse("[-42, 100, 10.25, -299999999999999999998, 2e32]"); + +array ja = jv.as_array(); + +// represented by std::int64_t +assert( ja[0].is_int64() ); + +// represented by std::int64_t +assert( ja[1].is_int64() ); + +// contains decimal point, represented as double +assert( ja[2].is_double() ); + +// less than INT64_MIN, represented as double +assert( ja[3].is_double() ); + +// contains exponent, represented as double +assert( ja[4].is_double() ); +//] +} +//---------------------------------------------------------- +{ +//[doc_using_numbers_7 +//] +} +//---------------------------------------------------------- + +} // set1 + +//---------------------------------------------------------- + +class doc_using_numbers_test +{ +public: + void + run() + { + (void)&set1; + } +}; + +TEST_SUITE(doc_using_numbers_test, "boost.json.doc_using_numbers"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/double.cpp b/src/boost/libs/json/test/double.cpp new file mode 100644 index 000000000..4bb77c4bd --- /dev/null +++ b/src/boost/libs/json/test/double.cpp @@ -0,0 +1,434 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/stream_parser.hpp> +#include <boost/json/parse.hpp> +#include <boost/json/serialize.hpp> + +#include <iostream> +#include <random> +#include <cinttypes> + +#include "parse-vectors.hpp" +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +template<std::size_t N, class... Args> +void +sprintf(char (&buf)[N], + char const* format, Args&&... args) +{ +#ifdef _MSC_VER + sprintf_s(buf, format, + std::forward<Args>(args)...); +#else + std::sprintf(buf, format, + std::forward<Args>(args)...); +#endif +} + +class double_test +{ +public: + struct f_boost + { + static + string_view + name() noexcept + { + return "boost"; + } + + double + operator()(string_view s) const + { + BOOST_TEST_CHECKPOINT(); + error_code ec; + stream_parser p; + p.write(s.data(), s.size(), ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + if(! BOOST_TEST(! ec)) + return 0; + auto const jv = p.release(); + double const d = jv.as_double(); + grind_double(s, d); + return d; + } + }; + + bool + within_1ulp(double x, double y) + { + std::uint64_t bx, by; + std::memcpy(&bx, &x, sizeof(x)); + std::memcpy(&by, &y, sizeof(y)); + + auto diff = bx - by; + switch (diff) + { + case 0: + case 1: + case 0xffffffffffffffff: + return true; + default: + break; + } + return false; + } + + static + value + from_string_test( + string_view s, + storage_ptr sp = {}, + const parse_options& po = parse_options()) + { + stream_parser p(storage_ptr(), po); + error_code ec; + p.reset(std::move(sp)); + p.write(s.data(), s.size(), ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + BOOST_TEST(! ec); + return p.release(); + } + + void + static + check_round_trip(value const& jv1, + const parse_options& po = parse_options()) + { + auto const s2 = + //to_string_test(jv1); // use this if serializer is broken + serialize(jv1); + auto jv2 = + from_string_test(s2, {}, po); + BOOST_TEST(equal(jv1, jv2)); + } + + template<class F> + void + static + grind_one( + string_view s, + storage_ptr sp, + F const& f, + const parse_options& po = parse_options()) + { + auto const jv = + from_string_test(s, sp, po); + f(jv, po); + } + + static + void + grind_one(string_view s) + { + auto const jv = + from_string_test(s); + check_round_trip(jv); + } + + template<class F> + static + void + grind(string_view s, F const& f, + const parse_options& po = parse_options()) + { + try + { + grind_one(s, {}, f, po); + + fail_loop([&](storage_ptr const& sp) + { + grind_one(s, sp, f, po); + }); + + if(s.size() > 1) + { + // Destroy the stream_parser at every + // split point to check leaks. + for(std::size_t i = 1; + i < s.size(); ++i) + { + fail_resource mr; + mr.fail_max = 0; + stream_parser p(storage_ptr(), po); + error_code ec; + p.reset(&mr); + p.write(s.data(), i, ec); + if(BOOST_TEST(! ec)) + p.write( + s.data() + i, + s.size() - i, ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + if(BOOST_TEST(! ec)) + f(p.release(), po); + } + } + } + catch(std::exception const&) + { + BOOST_TEST_FAIL(); + } + } + + static + void + grind(string_view s, + const parse_options& po = parse_options()) + { + grind(s, + [](value const& jv, const parse_options& po) + { + check_round_trip(jv, po); + }, po); + } + + static + void + grind_double(string_view s, double v) + { + grind(s, + [v](value const& jv, const parse_options&) + { + if(! BOOST_TEST(jv.is_double())) + return; + BOOST_TEST(jv.get_double() == v); + }); + } + + // Verify that f converts to the + // same double produced by `strtod`. + // Requires `s` is not represented by an integral type. + template<class F> + void + fc(std::string const& s, F const& f) + { + char* str_end; + double const need = + std::strtod(s.c_str(), &str_end); + // BOOST_TEST(str_end == &s.back() + 1); + double const got = f(s); + auto same = got == need; + auto close = same ? + true : within_1ulp(got, need); + + if( !BOOST_TEST(close) ) + { + std::cerr << "Failure on '" << s << "': " << got << " != " << need << "\n"; + } + } + + void + fc(std::string const& s) + { + fc(s, f_boost{}); + fc(s + std::string( 64, ' ' ), f_boost{}); + } + + void + testDouble() + { + grind_double("-1.010", -1.01); + grind_double("-0.010", -0.01); + grind_double("-0.0", -0.0); + grind_double("-0e0", -0.0); + grind_double( "18.4", 18.4); + grind_double("-18.4", -18.4); + grind_double( "18446744073709551616", 1.8446744073709552e+19); + grind_double("-18446744073709551616", -1.8446744073709552e+19); + grind_double( "18446744073709551616.0", 1.8446744073709552e+19); + grind_double( "18446744073709551616.00009", 1.8446744073709552e+19); + grind_double( "1844674407370955161600000", 1.8446744073709552e+24); + grind_double("-1844674407370955161600000", -1.8446744073709552e+24); + grind_double( "1844674407370955161600000.0", 1.8446744073709552e+24); + grind_double( "1844674407370955161600000.00009", 1.8446744073709552e+24); + grind_double( "19700720435664.186294290058937593e13", 1.9700720435664185e+26); + + grind_double( "1.0", 1.0); + grind_double( "1.1", 1.1); + grind_double( "1.11", 1.11); + grind_double( "1.11111", 1.11111); + grind_double( "11.1111", 11.1111); + grind_double( "111.111", 111.111); + + fc("-0.9999999999999999999999"); + fc("-0.9999999999999999"); + fc("-0.9007199254740991"); + fc("-0.999999999999999"); + fc("-0.99999999999999"); + fc("-0.9999999999999"); + fc("-0.999999999999"); + fc("-0.99999999999"); + fc("-0.9999999999"); + fc("-0.999999999"); + fc("-0.99999999"); + fc("-0.9999999"); + fc("-0.999999"); + fc("-0.99999"); + fc("-0.9999"); + fc("-0.8125"); + fc("-0.999"); + fc("-0.99"); + fc("-1.0"); + fc("-0.9"); + fc("-0.0"); + fc("0.0"); + fc("0.9"); + fc("0.99"); + fc("0.999"); + fc("0.8125"); + fc("0.9999"); + fc("0.99999"); + fc("0.999999"); + fc("0.9999999"); + fc("0.99999999"); + fc("0.999999999"); + fc("0.9999999999"); + fc("0.99999999999"); + fc("0.999999999999"); + fc("0.9999999999999"); + fc("0.99999999999999"); + fc("0.999999999999999"); + fc("0.9007199254740991"); + fc("0.9999999999999999"); + fc("0.9999999999999999999999"); + fc("0.999999999999999999999999999"); + + fc("-1e308"); + fc("-1e-308"); + fc("-9999e300"); + fc("-999e100"); + fc("-99e10"); + fc("-9e1"); + fc("9e1"); + fc("99e10"); + fc("999e100"); + fc("9999e300"); + fc("999999999999999999.0"); + fc("999999999999999999999.0"); + fc("999999999999999999999e5"); + fc("999999999999999999999.0e5"); + + fc("0.00000000000000001"); + + fc("-1e-1"); + fc("-1e0"); + fc("-1e1"); + fc("0e0"); + fc("1e0"); + fc("1e10"); + + fc("0." + "00000000000000000000000000000000000000000000000000" // 50 zeroes + "1e50"); + fc("-0." + "00000000000000000000000000000000000000000000000000" // 50 zeroes + "1e50"); + + fc("0." + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" // 500 zeroes + "1e600"); + fc("-0." + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" // 500 zeroes + "1e600"); + + fc("0e" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" // 500 zeroes + ); + } + + void checkAccuracy(const char* nm, int max_ulp) + { + double x = std::strtod( nm, 0 ); + double y = boost::json::parse( nm ).as_double(); + std::uint64_t bx, by; + std::memcpy( &bx, &x, sizeof(x) ); + std::memcpy( &by, &y, sizeof(y) ); + std::int64_t diff = bx - by; + if (!BOOST_TEST(std::abs( diff ) <= max_ulp)) + std::fprintf(stderr, + "%s: difference %" PRId64 " ulp\n" + " strtod: %.13a %.16g\n" + " boost.json: %.13a %.16g\n\n", + nm, diff, x, x, y, y ); + } + + void + testWithinULP() + { + std::mt19937_64 rng; + + checkAccuracy("10199214983525025199.13135016100190689227e-308", 2); + + for( int i = 0; i < 1000000; ++i ) + { + unsigned long long x1 = rng(); + unsigned long long x2 = rng(); + int x3 = std::uniform_int_distribution<>( -308, +308 )( rng ); + + char buffer[ 128 ]; + sprintf( buffer, "%llu.%llue%d", x1, x2, x3 ); + + checkAccuracy( buffer, 2 ); + } + + for( int i = -326; i <= +309; ++i ) + { + char buffer[ 128 ]; + sprintf( buffer, "1e%d", i ); + + checkAccuracy( buffer, 0 ); + } + }; + + void + run() + { + testDouble(); + testWithinULP(); + } +}; + +TEST_SUITE(double_test, "boost.json.double"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/error.cpp b/src/boost/libs/json/test/error.cpp new file mode 100644 index 000000000..dc267159c --- /dev/null +++ b/src/boost/libs/json/test/error.cpp @@ -0,0 +1,88 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/error.hpp> + +#include <memory> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class error_test +{ +public: + void check(error e) + { + auto const ec = make_error_code(e); + BOOST_TEST(ec.category().name() != nullptr); + BOOST_TEST(! ec.message().empty()); + BOOST_TEST(ec.category().default_error_condition( + static_cast<int>(e)).category() == ec.category()); + } + + void check(condition c, error e) + { + { + auto const ec = make_error_code(e); + BOOST_TEST(ec.category().name() != nullptr); + BOOST_TEST(! ec.message().empty()); + BOOST_TEST(ec == c); + } + { + auto ec = make_error_condition(c); + BOOST_TEST(ec.category().name() != nullptr); + BOOST_TEST(! ec.message().empty()); + BOOST_TEST(ec == c); + } + } + + void + run() + { + check(condition::parse_error, error::syntax); + check(condition::parse_error, error::extra_data); + check(condition::parse_error, error::incomplete); + check(condition::parse_error, error::exponent_overflow); + check(condition::parse_error, error::too_deep); + check(condition::parse_error, error::illegal_leading_surrogate); + check(condition::parse_error, error::illegal_trailing_surrogate); + check(condition::parse_error, error::expected_hex_digit); + check(condition::parse_error, error::expected_utf16_escape); + check(condition::parse_error, error::object_too_large); + check(condition::parse_error, error::array_too_large); + check(condition::parse_error, error::key_too_large); + check(condition::parse_error, error::string_too_large); + check(condition::parse_error, error::exception); + + check(condition::assign_error, error::not_number); + check(condition::assign_error, error::not_exact); + + check(condition::pointer_parse_error, error::missing_slash); + check(condition::pointer_parse_error, error::invalid_escape); + + check(condition::pointer_use_error, error::token_not_number); + check(condition::pointer_use_error, error::value_is_scalar); + check(condition::pointer_use_error, error::not_found); + check(condition::pointer_use_error, error::token_overflow); + check(condition::pointer_use_error, error::past_the_end); + + check(error::test_failure); + + // check std interop + std::error_code const ec = error::syntax; + BOOST_TEST(ec == error::syntax); + BOOST_TEST(ec == condition::parse_error); + } +}; + +TEST_SUITE(error_test, "boost.json.error"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/fwd.cpp b/src/boost/libs/json/test/fwd.cpp new file mode 100644 index 000000000..75063e629 --- /dev/null +++ b/src/boost/libs/json/test/fwd.cpp @@ -0,0 +1,14 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/fwd.hpp> + +// make sure declarations are consistent +#include <boost/json.hpp> diff --git a/src/boost/libs/json/test/json.cpp b/src/boost/libs/json/test/json.cpp new file mode 100644 index 000000000..8fd9e9219 --- /dev/null +++ b/src/boost/libs/json/test/json.cpp @@ -0,0 +1,40 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +struct json_test +{ + ::test_suite::log_type log; + + void + run() + { + log << + "sizeof(alignof)\n" + " object == " << sizeof(object) << " (" << alignof(object) << ")\n" + " value_type == " << sizeof(object::value_type) << " (" << alignof(object::value_type) << ")\n" + " array == " << sizeof(array) << " (" << alignof(array) << ")\n" + " string == " << sizeof(string) << " (" << alignof(string) << ")\n" + " value == " << sizeof(value) << " (" << alignof(value) << ")\n" + " serializer == " << sizeof(serializer) << "\n" + " stream_parser == " << sizeof(stream_parser) + ; + BOOST_TEST_PASS(); + } +}; + +TEST_SUITE(json_test, "boost.json.zsizes"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/kind.cpp b/src/boost/libs/json/test/kind.cpp new file mode 100644 index 000000000..c7c644bf4 --- /dev/null +++ b/src/boost/libs/json/test/kind.cpp @@ -0,0 +1,53 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/kind.hpp> + +#include <boost/json/string_view.hpp> + +#include <type_traits> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class kind_test +{ +public: + BOOST_STATIC_ASSERT( + std::is_enum<kind>::value); + + void + check(kind k, string_view s) + { + BOOST_TEST( + to_string(k) == s); + std::stringstream ss; + ss << k; + BOOST_TEST(ss.str() == s); + } + + void + run() + { + check(kind::array, "array"); + check(kind::object, "object"); + check(kind::string, "string"); + check(kind::int64, "int64"); + check(kind::uint64, "uint64"); + check(kind::double_, "double"); + check(kind::bool_, "bool"); + check(kind::null, "null"); + } +}; + +TEST_SUITE(kind_test, "boost.json.kind"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/limits.cpp b/src/boost/libs/json/test/limits.cpp new file mode 100644 index 000000000..40f2cb99a --- /dev/null +++ b/src/boost/libs/json/test/limits.cpp @@ -0,0 +1,400 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/array.hpp> +#include <boost/json/object.hpp> +#include <boost/json/string.hpp> +#include <boost/json/value.hpp> +#include <boost/json/parse.hpp> +#include <boost/json/stream_parser.hpp> + +#include <vector> + +#include "test_suite.hpp" +#include "test.hpp" + +BOOST_JSON_NS_BEGIN + +/* + This translation unit exercises code paths + related to library limits such as max string + length. +*/ + +class limits_test +{ +public: + void + testValue() + { + // object too large + { + std::initializer_list<std::pair< + string_view, value_ref>> init = { + { "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5}, + { "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10}, + {"11",11},{"12",12},{"13",13},{"14",14},{"15",15}, + {"16",16},{"17",17},{"18",18},{"19",19},{"10",10}, + {"21",21},{"22",22},{"23",23},{"24",24},{"25",25}, + {"26",26},{"27",27},{"28",28},{"29",29},{"30",30}, + {"31",31}}; + BOOST_TEST(init.size() > object::max_size()); + BOOST_TEST_THROWS(value{init}, std::length_error); + } + } + + void + testObject() + { + // max_size() + { + BOOST_TEST_THROWS( + object(object::max_size()+1), + std::length_error); + } + + // object(), max size + { + std::initializer_list<std::pair< + string_view, value_ref>> init = { + { "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5}, + { "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10}, + {"11",11},{"12",12},{"13",13},{"14",14},{"15",15}, + {"16",16},{"17",17},{"18",18},{"19",19},{"10",10}, + {"21",21},{"22",22},{"23",23},{"24",24},{"25",25}, + {"26",26},{"27",27},{"28",28},{"29",29},{"30",30}, + {"31",31}}; + BOOST_TEST(init.size() > object::max_size()); + BOOST_TEST_THROWS( + object(init), + std::length_error); + BOOST_TEST_THROWS( + object(init.begin(), init.end()), + std::length_error); + BOOST_TEST_THROWS( + object( + make_input_iterator(init.begin()), + make_input_iterator(init.end())), + std::length_error); + } + + // reserve(), max size + { + object o; + BOOST_TEST_THROWS( + o.reserve(o.max_size() + 1), + std::length_error); + } + + // insert(), max size + { + std::initializer_list<std::pair< + string_view, value_ref>> init = { + { "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5}, + { "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10}, + {"11",11},{"12",12},{"13",13},{"14",14},{"15",15}, + {"16",16},{"17",17},{"18",18},{"19",19},{"10",10}, + {"21",21},{"22",22},{"23",23},{"24",24},{"25",25}, + {"26",26},{"27",27},{"28",28},{"29",29},{"30",30}, + {"31",31}}; + BOOST_TEST(init.size() > object::max_size()); + object o; + BOOST_TEST_THROWS( + o.insert(init), + std::length_error); + BOOST_TEST_THROWS( + o.insert(init.begin(), init.end()), + std::length_error); + BOOST_TEST_THROWS( + o.insert( + make_input_iterator(init.begin()), + make_input_iterator(init.end())), + std::length_error); + } + + // max key size + { + std::string const big( + string::max_size() + 1, '*'); + BOOST_TEST_THROWS( + object({ {big, nullptr} }), + std::length_error); + } + + // reserve + { + object obj; + BOOST_TEST_THROWS( + obj.reserve(object::max_size() + 1), + std::length_error); + } + } + + void + testArray() + { + { + BOOST_TEST_THROWS( + array( + array::max_size()+1, + value(nullptr)), + std::length_error); + } + + { + std::vector<int> v( + array::max_size()+1, 42); + BOOST_TEST_THROWS( + array(v.begin(), v.end()), + std::length_error); + } + + { + std::vector<int> v( + array::max_size()+1, 42); + BOOST_TEST_THROWS(array( + make_input_iterator(v.begin()), + make_input_iterator(v.end())), + std::length_error); + } + + { + array a; + BOOST_TEST_THROWS( + a.insert(a.begin(), + array::max_size() + 1, + nullptr), + std::length_error); + } + } + + void + testString() + { + // strings + { + { + string s; + BOOST_TEST_THROWS( + (s.resize(s.max_size() + 1)), + std::length_error); + } + + { + string s; + s.resize(100); + BOOST_TEST_THROWS( + (s.append(s.max_size() - 1, '*')), + std::length_error); + } + + { + string s; + s.resize(s.max_size() - 5); + BOOST_TEST_THROWS( + (s.replace(0, 1, s.subview(0, 10))), + std::length_error); + } + + { + string s; + s.resize(s.max_size() - 5); + BOOST_TEST_THROWS( + (s.replace(0, 1, 10, 'a')), + std::length_error); + } + + { + string s; + s.resize(s.max_size() - 5); + BOOST_TEST_THROWS( + (s.insert(0, s.subview(0, 10))), + std::length_error); + } + + #if 0 + { + // VFALCO tsan doesn't like this + string s; + try + { + s.resize(s.max_size() - 1); + } + catch(std::exception const&) + { + } + } + #endif + } + + // string in parser + { + stream_parser p; + std::string const big( + string::max_size() + 1, '*'); + auto const js = + "\"" + big + "\":null"; + error_code ec; + auto jv = parse(js, ec); + BOOST_TEST(ec == error::string_too_large); + BOOST_TEST(ec.has_location()); + } + + // key in parser + { + stream_parser p; + std::string const big( + string::max_size() + 1, '*'); + auto const js = + "{\"" + big + "\":null}"; + error_code ec; + auto jv = parse(js, ec); + BOOST_TEST(ec == error::key_too_large); + BOOST_TEST(ec.has_location()); + } + } + + void + testParser() + { + // string buffer flush + { + string_view s = + "\"\\na\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" + "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\""; + error_code ec; + auto jv = parse(s, ec); + BOOST_TEST(! ec); + } + // overflow in on_key_part + { + error_code ec; + std::string big; + big = "\\b"; + big += std::string( + string::max_size()*2, '*'); + auto const js = + "{\"" + big + "\":null}"; + auto jv = parse(js, ec); + BOOST_TEST(ec == error::key_too_large); + BOOST_TEST(ec.has_location()); + } + + // overflow in on_key + { + error_code ec; + std::string big; + big = "\\b"; + big += std::string( + (string::max_size()*3)/2, '*'); + auto const js = + "{\"" + big + "\":null}"; + auto jv = parse(js, ec); + BOOST_TEST(ec == error::key_too_large); + BOOST_TEST(ec.has_location()); + } + + // overflow in on_string_part + { + error_code ec; + std::string big; + big = "\\b"; + big += std::string( + string::max_size()*2, '*'); + auto const js = + "\"" + big + "\""; + auto jv = parse(js, ec); + BOOST_TEST(ec == error::string_too_large); + BOOST_TEST(ec.has_location()); + } + + // overflow in on_string + { + error_code ec; + std::string big; + big = "\\b"; + big += std::string( + (string::max_size()*3)/2, '*'); + auto const js = + "\"" + big + "\""; + auto jv = parse(js, ec); + BOOST_TEST(ec == error::string_too_large); + BOOST_TEST(ec.has_location()); + } + + + // object overflow + { + error_code ec; + string_view s = R"({ + "00":0,"01":0,"02":0,"03":0,"04":0,"05":0,"06":0,"07":0,"08":0,"09":0, + "10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0, + "20":0 + })"; + + auto jv = parse(s, ec); + BOOST_TEST(ec == error::object_too_large); + BOOST_TEST(ec.has_location()); + } + + // array overflow + { + error_code ec; + string_view s = "[" + "0,0,0,0,0,0,0,0,0,0," + "0,0,0,0,0,0,0,0,0,0," + "0" + "]"; + auto jv = parse(s, ec); + BOOST_TEST(ec == error::array_too_large); + BOOST_TEST(ec.has_location()); + } + } + + void + run() + { + #if ! defined(BOOST_JSON_NO_MAX_STRUCTURED_SIZE) && \ + ! defined(BOOST_JSON_NO_MAX_STRING_SIZE) && \ + ! defined(BOOST_JSON_NO_MAX_STACK_SIZE) && \ + ! defined(BOOST_JSON_NO_STACK_BUFFER_SIZE) + + //testValue(); + testObject(); + testArray(); + testString(); + testParser(); + + #else + BOOST_TEST_PASS(); + #endif + } +}; + +TEST_SUITE(limits_test, "boost.json.limits"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/main.cpp b/src/boost/libs/json/test/main.cpp new file mode 100644 index 000000000..6ee59cdf6 --- /dev/null +++ b/src/boost/libs/json/test/main.cpp @@ -0,0 +1,31 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include "test_suite.hpp" + +#include <iostream> +#ifdef _MSC_VER +#include <crtdbg.h> +#endif + +// Simple main used to produce stand +// alone executables that run unit tests. +int main(int argc, char const* const* argv) +{ +#ifdef _MSC_VER + { + int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flags |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flags); + } +#endif + + ::test_suite::debug_stream log(std::cerr); + return ::test_suite::run(log, argc, argv); +} diff --git a/src/boost/libs/json/test/make-pvs.py b/src/boost/libs/json/test/make-pvs.py new file mode 100644 index 000000000..74e6cdb2e --- /dev/null +++ b/src/boost/libs/json/test/make-pvs.py @@ -0,0 +1,117 @@ +# Build test vector variable + +import os + +def chex(c): + d1 = ord(c)/16; + d2 = ord(c)%16; + d = "0123456789ABCDEF"; + s = "\\x" + d[d1:d1+1] + d[d2:d2+1]; + return s; + +def escape(c): + if c == ' ' or c == '\t': + return c; + elif c == '\"': + return "\\\""; + elif c == '\\': + return "\\\\"; + n = ord(c); + if n >= 32 and n <= 127: + return c; + return chex(c) + "\"\""; + +def tocpp(s): + v0 = "" + v = "\""; + for c in s: + v = v + escape(c); + if len(v) > 80: + if len(v0) > 50000: + return v0 + v + "\""; + v0 += v + "\"\n \""; + v = ""; + return v0 + v + "\""; + +def do_files(directory): + for root, directories, files in os.walk(directory): + for filename in files: + filepath = os.path.join(root, filename) + with open(filepath, 'r') as file: + data = file.read(); + print(" { '" + filename[0:1] + "', \"" + filename[2:-5] + "\", lit(" + tocpp(data) + ") },"); + +print(""" +// +// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#ifndef PARSE_VECTORS +#define PARSE_VECTORS + +#include <boost/utility/string_view.hpp> +#include <cstdlib> +#include <type_traits> + +struct parse_vectors +{ + struct item + { + char result; + ::boost::string_view name; + ::boost::string_view text; + }; + + using iterator = item const*; + + iterator begin() const noexcept + { + return first_; + } + + iterator end() const noexcept + { + return last_; + } + + std::size_t + size() const noexcept + { + return last_ - first_; + } + + inline parse_vectors() noexcept; + +private: + template<std::size_t N> + static + ::boost::string_view + lit(char const (&s)[N]) + { + return {s, N - 1}; + } + + iterator first_; + iterator last_; +}; + +parse_vectors:: +parse_vectors() noexcept +{ + static item const list[] = {"""); + +do_files("parse-vectors"); + +print(""" { ' ', "", "" } + }; + first_ = &list[0]; + last_ = &list[std::extent< + decltype(list)>::value - 1]; +} + +#endif"""); diff --git a/src/boost/libs/json/test/make-strings.py b/src/boost/libs/json/test/make-strings.py new file mode 100644 index 000000000..c8c1a9d84 --- /dev/null +++ b/src/boost/libs/json/test/make-strings.py @@ -0,0 +1,17 @@ +# Build array of random strings + +import os +import random +from random import randint + +def randstr(): + letters = "0123456789!@#$%^&*()_-+=[]{}|;:,<.>/?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + return ''.join(random.choice(letters) for i in range(randint(1, 2000))); + +print "["; +for i in range(1000): + print "\"", randstr(), "\","; +print "\"", randstr(), "\""; +print "]"; + + diff --git a/src/boost/libs/json/test/memory_resource.cpp b/src/boost/libs/json/test/memory_resource.cpp new file mode 100644 index 000000000..b68cffaf9 --- /dev/null +++ b/src/boost/libs/json/test/memory_resource.cpp @@ -0,0 +1,109 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/memory_resource.hpp> +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/value.hpp> +#include <boost/container/pmr/vector.hpp> +#include <vector> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class memory_resource_test +{ +public: + void + testBoostPmr() + { + using allocator_type = + polymorphic_allocator<value>; + + // pass polymorphic_allocator + // where storage_ptr is expected + { + monotonic_resource mr; + value jv( allocator_type{&mr} ); + object o( allocator_type{&mr} ); + array a( allocator_type{&mr} ); + string s( allocator_type{&mr} ); + } + { + monotonic_resource mr; + allocator_type a(&mr); + + boost::container::pmr::vector<value> v1(a); + v1.resize(3); + BOOST_TEST(v1[1].storage().get() == &mr); + + std::vector<value, allocator_type> v2(3, {}, a); + BOOST_TEST(v2[1].storage().get() == &mr); + } + } + + // These are here instead of the type-specific + // test TUs, so that we only need to link to + // Boost.Container from one file. + void + testPmr() + { + // array + { + // get_allocator + { + monotonic_resource mr; + array a(&mr); + BOOST_TEST(a.get_allocator().resource() == &mr); + } + } + + // object + { + // get_allocator + { + monotonic_resource mr; + object o(&mr); + BOOST_TEST(o.get_allocator().resource() == &mr); + } + } + + // string + { + // get_allocator + { + monotonic_resource mr; + string s(&mr); + BOOST_TEST(s.get_allocator().resource() == &mr); + } + } + + // value + { + // get_allocator + { + monotonic_resource mr; + value jv(&mr); + BOOST_TEST(jv.get_allocator().resource() == &mr); + } + } + } + + void + run() + { + testBoostPmr(); + testPmr(); + } +}; + +TEST_SUITE(memory_resource_test, "boost.json.memory_resource"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/monotonic_resource.cpp b/src/boost/libs/json/test/monotonic_resource.cpp new file mode 100644 index 000000000..6bf391718 --- /dev/null +++ b/src/boost/libs/json/test/monotonic_resource.cpp @@ -0,0 +1,311 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/monotonic_resource.hpp> + +#include <boost/json/null_resource.hpp> +#include <boost/json/parse.hpp> +#include <boost/json/serialize.hpp> +#include <boost/json/detail/align.hpp> +#include <iostream> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<monotonic_resource>::value ); + +class monotonic_resource_test +{ +private: + bool + in_buffer( + void* ptr, + void* buffer, + std::size_t buffer_size) + { + using ptr_t = const volatile unsigned char*; + return reinterpret_cast<ptr_t>(ptr) >= reinterpret_cast<ptr_t>(buffer) && + reinterpret_cast<ptr_t>(ptr) < reinterpret_cast<ptr_t>(buffer) + buffer_size; + } + + bool + all_alloc_in_same_block( + monotonic_resource& mr, + std::size_t bytes, + std::size_t align) + { + // base of the block + auto first = mr.allocate(align, align); + bool result = true; + for (auto allocs = (bytes - align) / align; allocs; --allocs) + result &= in_buffer(mr.allocate(align, align), first, bytes); + return result; + } + +public: + void + testJavadocs() + { + //-------------------------------------- + + unsigned char buf[4000]; + monotonic_resource mr( buf ); + + // Parse the string, using our memory resource + auto const jv = parse( "[1,2,3]", &mr ); + + // Print the JSON + std::cout << jv; + + //-------------------------------------- + } + + void + testMembers() + { + // ~monotonic_resource + { + // implied + } + + // monotonic_resource(size_t, storage_ptr) + { + { + monotonic_resource mr(1); + } + { + monotonic_resource mr(5000); + } + { + monotonic_resource mr( + 1, get_null_resource()); + } + { + monotonic_resource mr( + 5000, get_null_resource()); + } + } + + // monotonic_resource(unsigned char*, size_t, storage_ptr) + { + { + unsigned char buf[2000]; + monotonic_resource mr( + &buf[0], sizeof(buf)); + } + { + unsigned char buf[2000]; + monotonic_resource mr( + &buf[0], sizeof(buf), + get_null_resource()); + } + } + + // monotonic_resource(unsigned char[N], storage_ptr) + { + { + unsigned char buf[2000]; + monotonic_resource mr(buf); + } + { + unsigned char buf[2000]; + monotonic_resource mr(buf, + get_null_resource()); + } + } + + #ifdef __cpp_lib_byte + // monotonic_resource(std::byte[N], storage_ptr) + { + { + std::byte buf[2000]; + monotonic_resource mr(buf); + } + + { + std::byte buf[2000]; + monotonic_resource mr(buf, + get_null_resource()); + } + } + #endif + + // monotonic_resource(unsigned char[N], std::size_t, storage_ptr) + { + { + unsigned char buf[2000]; + monotonic_resource mr(buf, 1000); + } + { + unsigned char buf[2000]; + monotonic_resource mr(buf, 1000, + get_null_resource()); + } + } + + #ifdef __cpp_lib_byte + // monotonic_resource(unsigned char[N], std::size_t, storage_ptr) + { + { + std::byte buf[2000]; + monotonic_resource mr(buf, 1000); + } + { + std::byte buf[2000]; + monotonic_resource mr(buf, 1000, + get_null_resource()); + } + } + #endif + + // release() + { + unsigned char buf[10]; + monotonic_resource mr( + buf, sizeof(buf)); + (void)mr.allocate(10,1); + mr.release(); + (void)mr.allocate(10,1); + } + + // coverage + { + monotonic_resource mr(std::size_t(-1)-2); + } + } + + void + testGeneral() + { + // test that each block gets filled to capacity + // and if the growth factor is correct + { + monotonic_resource mr; + BOOST_TEST(all_alloc_in_same_block(mr, 1024, 1)); + BOOST_TEST(all_alloc_in_same_block(mr, 2048, 2)); + BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1)); + BOOST_TEST(all_alloc_in_same_block(mr, 8192, 4)); + BOOST_TEST(all_alloc_in_same_block(mr, 16384, 1)); + BOOST_TEST(all_alloc_in_same_block(mr, 32768, 8)); + BOOST_TEST(all_alloc_in_same_block(mr, 65536, 1)); + } + // test if each allocation is aligned correctly + { + monotonic_resource mr; + for (std::size_t i = 0; i < 4096; ++i) + { + const auto size = ((i * 3) % 32) + 1; + std::size_t next = 1; + for (auto mod = i % alignof(detail::max_align_t); + mod; mod >>= 1, next <<= 1); + const auto align = (std::max)(next, + std::size_t(1)); + BOOST_TEST(!(reinterpret_cast<std::uintptr_t>(mr.allocate(size, align)) % align)); + } + } + // test if user provided sizes are correctly rounded + { + { + monotonic_resource mr(10); + BOOST_TEST(all_alloc_in_same_block(mr, 1024, 1)); + } + { + monotonic_resource mr(1025); + BOOST_TEST(all_alloc_in_same_block(mr, 2048, 1)); + } + { + monotonic_resource mr(4000); + BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1)); + } + } + // test if sizes are correctly determined from initial buffers + { + { + unsigned char buf[512]; + monotonic_resource mr(buf, 512); + BOOST_TEST(all_alloc_in_same_block(mr, 512, 1)); + BOOST_TEST(all_alloc_in_same_block(mr, 1024, 1)); + } + { + unsigned char buf[2048]; + monotonic_resource mr(buf, 2048); + BOOST_TEST(all_alloc_in_same_block(mr, 2048, 1)); + BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1)); + } + { + unsigned char buf[4000]; + monotonic_resource mr(buf, 4000); + BOOST_TEST(all_alloc_in_same_block(mr, 4000, 1)); + BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1)); + } + } + // test if allocations that exceed the block size cause rounding to occur + { + { + monotonic_resource mr; + auto p = mr.allocate(2048); + (void)p; + BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1)); + } + { + monotonic_resource mr; + void* p; + p = mr.allocate(2000, 1); + p = mr.allocate(48, 1); + (void)p; + BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1)); + } + } + } + + void + testStorage() + { + auto jv = parse( +R"xx({ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +})xx" + , make_shared_resource<monotonic_resource>()); + BOOST_TEST_PASS(); + } + + void + run() + { + testMembers(); + testStorage(); + testGeneral(); + } +}; + +TEST_SUITE(monotonic_resource_test, "boost.json.monotonic_resource"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/natvis.cpp b/src/boost/libs/json/test/natvis.cpp new file mode 100644 index 000000000..81fc1c9a9 --- /dev/null +++ b/src/boost/libs/json/test/natvis.cpp @@ -0,0 +1,115 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/value.hpp> + +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/static_resource.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class natvis_test +{ +public: + static + value + make_key(string_view s) + { + value jv; + detail::access::construct_value( + &jv, s, storage_ptr()); + return jv; + } + + void + run() + { + // These variables may be inspected in the + // Visual Studio IDE to verify that the .natvis + // file is working correctly + + value jv0 = nullptr; + value jv1 = true; + value jv2 = -1; + value jv3 = 42u; + value jv4 = 3.141; + value jv5 = "string"; + value jv6 = make_key("key"); + value jv7 = "dynamically-allocated-string"; + value jv8 = { 1, 2, 3 }; + value jv9 = { {"a",1}, {"b",2}, {"c",3} }; + + string& x0 = jv5.get_string(); (void)x0; + string& x1 = jv6.get_string(); (void)x1; + string& x2 = jv7.get_string(); (void)x2; + array& x3 = jv8.get_array(); (void)x3; + object& x4 = jv9.get_object(); (void)x4; + + array y0; + y0.emplace_back(jv0); + y0.emplace_back(jv1); + y0.emplace_back(jv2); + y0.emplace_back(jv4); + y0.emplace_back(jv5); + y0.emplace_back(jv6); + y0.emplace_back(jv7); + y0.emplace_back(jv8); + y0.emplace_back(jv9); + + object y1; + y1.emplace("a", jv0); + y1.emplace("b", jv1); + y1.emplace("c", jv2); + y1.emplace("d", jv4); + y1.emplace("f", jv5); + y1.emplace("g", jv6); + y1.emplace("h", jv7); + y1.emplace("i", jv8); + y1.emplace("j", jv9); + + key_value_pair& z0 = y1.begin()[0]; (void)z0; + key_value_pair& z1 = y1.begin()[1]; (void)z1; + key_value_pair& z2 = y1.begin()[2]; (void)z2; + key_value_pair& z3 = y1.begin()[3]; (void)z3; + key_value_pair& z4 = y1.begin()[4]; (void)z4; + key_value_pair& z5 = y1.begin()[5]; (void)z5; + key_value_pair& z6 = y1.begin()[6]; (void)z6; + key_value_pair& z7 = y1.begin()[7]; (void)z7; + key_value_pair& z8 = y1.begin()[8]; (void)z8; + + { + auto sp = y1.storage(); + } + { + unsigned char buf[1024]; + storage_ptr sp; + sp = make_shared_resource< + monotonic_resource>(); + sp = make_shared_resource< + static_resource>(buf); + sp = {}; + } + { + unsigned char buf[1024]; + monotonic_resource mr1; + static_resource mr2(buf); + storage_ptr sp; + + sp = &mr1; + sp = &mr2; + sp = {}; + } + } +}; + +TEST_SUITE(natvis_test, "json.natvis"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/null_resource.cpp b/src/boost/libs/json/test/null_resource.cpp new file mode 100644 index 000000000..8b4056449 --- /dev/null +++ b/src/boost/libs/json/test/null_resource.cpp @@ -0,0 +1,45 @@ +// +// Copyright (c) 2020 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/null_resource.hpp> + +#include <boost/json/storage_ptr.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class null_resource_test +{ +public: + void + test() + { + auto& mr = *get_null_resource(); + BOOST_TEST_THROWS( + mr.allocate(16), + std::bad_alloc); + char buf[128]; + // no-op + mr.deallocate(&buf[0], 128); + BOOST_TEST( + mr == *get_null_resource()); + } + + void + run() + { + test(); + } +}; + +TEST_SUITE(null_resource_test, "boost.json.null_resource"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/object.cpp b/src/boost/libs/json/test/object.cpp new file mode 100644 index 000000000..1186fa6dd --- /dev/null +++ b/src/boost/libs/json/test/object.cpp @@ -0,0 +1,1554 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/object.hpp> + +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/parse.hpp> +#include <boost/json/serialize.hpp> + +#include <cmath> +#include <forward_list> +#include <map> +#include <string> +#include <type_traits> +#include <vector> + +#include "test.hpp" +#include "test_suite.hpp" +#include "checking_resource.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<object>::value ); +BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<object>::value ); + +class object_test +{ +public: + static + constexpr + std::size_t + size0_ = + detail::small_object_size_ - 2; + + static + constexpr + std::size_t + size1_ = size0_ + 4; + + test_suite::log_type log; + string_view const str_; + + using init_list = + std::initializer_list< + std::pair<string_view, value_ref>>; + +#define DECLARE_INIT_LISTS \ + init_list i0_ = { \ + { "0", 0 }, { "1", 1 }, { "2", 2 }, { "3", 3 }, { "4", 4 }, \ + { "5", 5 }, { "6", 6 }, { "7", 7 }, { "8", 8 }, { "9", 9 }, \ + { "10", 10 }, { "11", 11 }, { "12", 12 }, { "13", 13 }, { "14", 14 }, \ + { "15", 15 } }; \ + init_list i1_ = { \ + { "0", 0 }, { "1", 1 }, { "2", 2 }, { "3", 3 }, { "4", 4 }, \ + { "5", 5 }, { "6", 6 }, { "7", 7 }, { "8", 8 }, { "9", 9 }, \ + { "10", 10 }, { "11", 11 }, { "12", 12 }, { "13", 13 }, { "14", 14 }, \ + { "15", 15 }, { "16", 16 }, { "17", 17 }, { "18", 18 }, { "19", 19 } } + + string_view const s0_ = + R"({"0":0,"1":1,"2":2,"3":3,"4":4,)" + R"("5":5,"6":6,"7":7,"8":8,"9":9,)" + R"("10":10,"11":11,"12":12,"13":13,"14":14,)" + R"("15":15})"; + + string_view const s1_ = + R"({"0":0,"1":1,"2":2,"3":3,"4":4,)" + R"("5":5,"6":6,"7":7,"8":8,"9":9,)" + R"("10":10,"11":11,"12":12,"13":13,"14":14,)" + R"("15":15,"16":16,"17":17,"18":18,"19":19})"; + + object_test() + : str_("abcdefghijklmnopqrstuvwxyz") + { + // ensure this string does + // not fit in the SBO area. + BOOST_ASSERT(str_.size() > + string().capacity()); + + DECLARE_INIT_LISTS; + + BOOST_TEST( + i0_.size() == size0_); + BOOST_TEST( + i1_.size() == size1_); + } + + template<class T, class U, class = void> + struct is_equal_comparable : std::false_type {}; + + template<class T, class U> + struct is_equal_comparable<T, U, detail::void_t<decltype( + std::declval<T const&>() == std::declval<U const&>() + )>> : std::true_type {}; + + template<class T, class U, class = void> + struct is_unequal_comparable : std::false_type {}; + + template<class T, class U> + struct is_unequal_comparable<T, U, detail::void_t<decltype( + std::declval<T const&>() != std::declval<U const&>() + )>> : std::true_type {}; + + BOOST_STATIC_ASSERT( std::is_constructible<object::iterator, object::iterator>::value); + BOOST_STATIC_ASSERT(! std::is_constructible<object::iterator, object::const_iterator>::value); + + BOOST_STATIC_ASSERT( std::is_constructible<object::const_iterator, object::iterator>::value); + BOOST_STATIC_ASSERT( std::is_constructible<object::const_iterator, object::const_iterator>::value); + + BOOST_STATIC_ASSERT( std::is_assignable<object::iterator&, object::iterator>::value); + BOOST_STATIC_ASSERT(! std::is_assignable<object::iterator&, object::const_iterator>::value); + + BOOST_STATIC_ASSERT( std::is_assignable<object::const_iterator&, object::iterator>::value); + BOOST_STATIC_ASSERT( std::is_assignable<object::const_iterator&, object::const_iterator>::value); + + BOOST_STATIC_ASSERT(is_equal_comparable<object::iterator, object::iterator>::value); + BOOST_STATIC_ASSERT(is_equal_comparable<object::iterator, object::const_iterator>::value); + + BOOST_STATIC_ASSERT(is_equal_comparable<object::const_iterator, object::iterator>::value); + BOOST_STATIC_ASSERT(is_equal_comparable<object::const_iterator, object::const_iterator>::value); + + BOOST_STATIC_ASSERT(is_unequal_comparable<object::iterator, object::iterator>::value); + BOOST_STATIC_ASSERT(is_unequal_comparable<object::iterator, object::const_iterator>::value); + + BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_iterator, object::iterator>::value); + BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_iterator, object::const_iterator>::value); + + BOOST_STATIC_ASSERT( std::is_constructible<object::reverse_iterator, object::reverse_iterator>::value); + // std::reverse_iterator ctor is not SFINAEd + //BOOST_STATIC_ASSERT(! std::is_constructible<object::reverse_iterator, object::const_reverse_iterator>::value); + + BOOST_STATIC_ASSERT( std::is_constructible<object::const_reverse_iterator, object::reverse_iterator>::value); + BOOST_STATIC_ASSERT( std::is_constructible<object::const_reverse_iterator, object::const_reverse_iterator>::value); + + BOOST_STATIC_ASSERT( std::is_assignable<object::reverse_iterator&, object::reverse_iterator>::value); + // std::reverse_iterator assignment is not SFINAEd + //BOOST_STATIC_ASSERT(! std::is_assignable<object::reverse_iterator&, object::const_reverse_iterator>::value); + + BOOST_STATIC_ASSERT( std::is_assignable<object::const_reverse_iterator&, object::reverse_iterator>::value); + BOOST_STATIC_ASSERT( std::is_assignable<object::const_reverse_iterator&, object::const_reverse_iterator>::value); + + BOOST_STATIC_ASSERT(is_equal_comparable<object::reverse_iterator, object::reverse_iterator>::value); + BOOST_STATIC_ASSERT(is_equal_comparable<object::reverse_iterator, object::const_reverse_iterator>::value); + + BOOST_STATIC_ASSERT(is_equal_comparable<object::const_reverse_iterator, object::reverse_iterator>::value); + BOOST_STATIC_ASSERT(is_equal_comparable<object::const_reverse_iterator, object::const_reverse_iterator>::value); + + BOOST_STATIC_ASSERT(is_unequal_comparable<object::reverse_iterator, object::reverse_iterator>::value); + BOOST_STATIC_ASSERT(is_unequal_comparable<object::reverse_iterator, object::const_reverse_iterator>::value); + + BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_reverse_iterator, object::reverse_iterator>::value); + BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_reverse_iterator, object::const_reverse_iterator>::value); + + static + void + check( + object const& o, + string_view s, + std::size_t capacity = 0) + { + BOOST_TEST( + parse(serialize(o)).as_object() == + parse(s).as_object()); + if(capacity != 0) + BOOST_TEST(o.capacity() == capacity); + } + + static + void + check( + object const& o, + std::size_t capacity) + { + BOOST_TEST(! o.empty()); + BOOST_TEST(o.size() == 3); + BOOST_TEST( + o.capacity() == capacity); + BOOST_TEST(o.at("a").as_int64() == 1); + BOOST_TEST(o.at("b").as_bool()); + BOOST_TEST(o.at("c").as_string() == "hello"); + check_storage(o, o.storage()); + } + + void + testDtor() + { + // ~object() + { + object o; + } + } + + void + testCtors() + { + DECLARE_INIT_LISTS; + + // object(detail::unchecked_object&&) + { + // small + { + value const jv = parse(s0_); + check(jv.as_object(), s0_, i0_.size()); + } + + // small, duplicate + { + value const jv = parse( + R"({"0":0,"1":1,"2":2,"3":3,"4":4,)" + R"("5":5,"6":6,"7":7,"8":8,"9":9,)" + R"("10":10,"11":11,"12":12,"13":13,"14":14,)" + R"("15":15,"10":10})"); + check(jv.as_object(), s0_, i0_.size() + 1); + } + + // large + { + value const jv = parse(s1_); + check(jv.as_object(), s1_, i1_.size()); + } + + // large, duplicate + { + value const jv = parse( + R"({"0":0,"1":1,"2":2,"3":3,"4":4,)" + R"("5":5,"6":6,"7":7,"8":8,"9":9,)" + R"("10":10,"11":11,"12":12,"13":13,"14":14,)" + R"("15":15,"16":16,"17":17,"18":18,"19":19,"10":10})"); + check(jv.as_object(), s1_, i1_.size() + 1); + } + } + + // object() + { + object o; + BOOST_TEST(o.empty()); + BOOST_TEST(o.size() == 0); + BOOST_TEST(o.capacity() == 0); + } + + // object(storage_ptr) + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + check_storage(o, sp); + BOOST_TEST(o.empty()); + BOOST_TEST(o.size() == 0); + BOOST_TEST(o.capacity() == 0); + }); + + // object(std::size_t, storage_ptr) + { + // small + { + object o(size0_); + BOOST_TEST(o.empty()); + BOOST_TEST(o.size() == 0); + BOOST_TEST(o.capacity() == size0_); + } + + // small + fail_loop([&](storage_ptr const& sp) + { + object o(size0_, sp); + check_storage(o, sp); + BOOST_TEST(o.empty()); + BOOST_TEST(o.size() == 0); + BOOST_TEST(o.capacity() == size0_); + }); + + // large + { + object o(size1_); + BOOST_TEST(o.empty()); + BOOST_TEST(o.size() == 0); + BOOST_TEST(o.capacity() == size1_); + } + + // large + fail_loop([&](storage_ptr const& sp) + { + object o(size1_, sp); + check_storage(o, sp); + BOOST_TEST(o.empty()); + BOOST_TEST(o.size() == 0); + BOOST_TEST(o.capacity() == size1_); + }); + } + + // object(InputIt, InputIt, size_type, storage_ptr) + { + // empty range + { + // random-access iterator + std::vector<std::pair<string_view, value>> i1; + object o1(i1.begin(), i1.end()); + BOOST_TEST(o1.empty()); + + // bidirectional iterator + std::map<string_view, value> i2; + object o2(i2.begin(), i2.end()); + BOOST_TEST(o2.empty()); + + // forward iterator + std::forward_list<std::pair<string_view, value>> i3; + object o3(i3.begin(), i3.end()); + BOOST_TEST(o3.empty()); + + // input iterator + auto const it = make_input_iterator(i3.begin()); + object o4(it, it); + BOOST_TEST(o4.empty()); + } + + // small + { + object o(i0_.begin(), i0_.end()); + check(o, s0_, i0_.size()); + } + + // small, ForwardIterator + fail_loop([&](storage_ptr const& sp) + { + object o(i0_.begin(), i0_.end(), size0_ + 1, sp); + BOOST_TEST(! o.empty()); + check(o, s0_, size0_ + 1); + check_storage(o, sp); + }); + + // small, InputIterator + fail_loop([&](storage_ptr const& sp) + { + object o( + make_input_iterator(i0_.begin()), + make_input_iterator(i0_.end()), size0_ + 1, sp); + BOOST_TEST(! o.empty()); + BOOST_TEST(o.capacity() == size0_ + 1); + check(o, s0_, size0_ + 1); + check_storage(o, sp); + }); + + // large + { + object o(i1_.begin(), i1_.end()); + check(o, s1_, i1_.size()); + } + + // large, ForwardIterator + fail_loop([&](storage_ptr const& sp) + { + object o(i1_.begin(), i1_.end(), size1_ + 1, sp); + BOOST_TEST(! o.empty()); + BOOST_TEST(o.capacity() == size1_ + 1); + check(o, s1_, size1_ + 1); + check_storage(o, sp); + }); + + // large, InputIterator + fail_loop([&](storage_ptr const& sp) + { + object o( + make_input_iterator(i1_.begin()), + make_input_iterator(i1_.end()), size1_ + 1, sp); + BOOST_TEST(! o.empty()); + BOOST_TEST(o.capacity() == size1_ + 1); + check(o, s1_, size1_ + 1); + check_storage(o, sp); + }); + } + + // object(object&&) + { + object o1(i0_); + check(o1, s0_); + auto const sp = + storage_ptr{}; + object o2(std::move(o1)); + BOOST_TEST(o1.empty()); + BOOST_TEST(o1.size() == 0); + check(o2, s0_); + check_storage(o1, sp); + check_storage(o2, sp); + } + + // object(object&&, storage_ptr) + { + // small + fail_loop([&](storage_ptr const& sp) + { + object o1(i0_); + object o2(std::move(o1), sp); + BOOST_TEST(! o1.empty()); + check(o2, s0_, i0_.size()); + check_storage(o1, + storage_ptr{}); + check_storage(o2, sp); + }); + + // large + fail_loop([&](storage_ptr const& sp) + { + object o1(i1_); + object o2(std::move(o1), sp); + BOOST_TEST(! o1.empty()); + check(o2, s1_, i1_.size()); + check_storage(o1, + storage_ptr{}); + check_storage(o2, sp); + }); + } + + // object(pilfered<object>) + { + { + auto const sp = + make_shared_resource<unique_resource>(); + object o1(i0_, sp); + object o2(pilfer(o1)); + BOOST_TEST( + o1.storage() == storage_ptr()); + BOOST_TEST( + *o2.storage() == *sp); + BOOST_TEST(o1.empty()); + check(o2, s0_, i0_.size()); + } + + // ensure pilfered-from objects + // are trivially destructible + { + object o1(make_shared_resource< + monotonic_resource>()); + object o2(pilfer(o1)); + BOOST_TEST(o1.storage().get() == + storage_ptr().get()); + } + } + + auto const sp = + make_shared_resource< + unique_resource>(); + auto const sp0 = storage_ptr{}; + + // object(object const&) + { + // small + { + object o1(i0_); + object o2(o1); + BOOST_TEST(! o1.empty()); + check(o2, s0_, i0_.size()); + } + + // large + { + object o1(i1_); + object o2(o1); + BOOST_TEST(! o1.empty()); + check(o2, s1_, i1_.size()); + } + } + + // object(object const&, storage_ptr) + { + // small + fail_loop([&](storage_ptr const& sp) + { + object o1(i0_); + object o2(o1, sp); + BOOST_TEST(! o1.empty()); + check(o2, s0_, i0_.size()); + check_storage(o2, sp); + }); + + // large + fail_loop([&](storage_ptr const& sp) + { + object o1(i1_); + object o2(o1, sp); + BOOST_TEST(! o1.empty()); + check(o2, s1_, i1_.size()); + check_storage(o2, sp); + }); + } + + // object(initializer_list, storage_ptr) + { + // small + { + object o(i0_); + check(o, s0_, i0_.size()); + } + + // small + fail_loop([&](storage_ptr const& sp) + { + object o(i0_, sp); + check(o, s0_, i0_.size()); + check_storage(o, sp); + }); + + // large + { + object o(i1_); + check(o, s1_, i1_.size()); + } + + // large + fail_loop([&](storage_ptr const& sp) + { + object o(i1_, sp); + check(o, s1_, i1_.size()); + check_storage(o, sp); + }); + } + + // object(initializer_list, std::size_t, storage_ptr) + { + // small + { + object o(i0_, size0_ + 1); + check(o, s0_, size0_ + 1); + } + + // small + fail_loop([&](storage_ptr const& sp) + { + object o(i0_, size0_ + 1, sp); + BOOST_TEST( + *o.storage() == *sp); + check(o, s0_, size0_ + 1); + }); + } + + // operator=(object const&) + { + { + object o1(i0_); + object o2; + o2 = o1; + check(o1, s0_, i0_.size()); + check(o2, s0_, i0_.size()); + check_storage(o1, + storage_ptr{}); + check_storage(o2, + storage_ptr{}); + } + + fail_loop([&](storage_ptr const& sp) + { + object o1(i0_); + object o2(sp); + o2 = o1; + check(o1, s0_, i0_.size()); + check(o2, s0_, i0_.size()); + check_storage(o1, + storage_ptr{}); + check_storage(o2, sp); + }); + + // self-assign + { + object o1(i0_); + object const& o2(o1); + o1 = o2; + check(o1, s0_, i0_.size()); + } + + // copy from child + { + object o({ + {"a", 1}, {"b", + { {"a", 1}, {"b", true}, {"c", "hello"} } + }, {"c", "hello"}}); + o = o["b"].as_object(); + check(o, 3); + } + } + + // operator=(object&&) + { + { + object o1({ + {"a", 1}, + {"b", true}, + {"c", "hello"}}); + object o2; + o2 = std::move(o1); + check(o2, 3); + BOOST_TEST(o1.empty()); + check_storage(o1, + storage_ptr{}); + check_storage(o2, + storage_ptr{}); + } + + fail_loop([&](storage_ptr const& sp) + { + object o1({ + {"a", 1}, + {"b", true}, + {"c", "hello"}}); + object o2(sp); + o2 = std::move(o1); + check(o1, 3); + check(o2, 3); + check_storage(o1, + storage_ptr{}); + check_storage(o2, sp); + }); + + // self-move + { + object o1({ + {"a", 1}, + {"b", true}, + {"c", "hello"}}); + object const& o2(o1); + o1 = std::move(o2); + check(o1, 3); + } + + // move from child + { + object o({ + {"a", 1}, {"b", + { {"a", 1}, {"b", true}, {"c", "hello"} } + }, {"c", "hello"}}); + o = std::move(o["b"].as_object()); + check(o, 3); + } + } + + // operator=(initializer_list) + { + { + object o; + o = { + {"a", 1}, + {"b", true}, + {"c", "hello"} }, + check(o, 3); + check_storage(o, + storage_ptr{}); + } + + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o = { + {"a", 1}, + {"b", true}, + {"c", "hello"} }, + BOOST_TEST( + *o.storage() == *sp); + check(o, 3); + check_storage(o, sp); + }); + + // assign from child + { + object o = { + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 } }; + o = { { "k2", o["k2"] } }; + BOOST_TEST( + o == object({ { "k2", 2 } })); + } + } + } + + void + testIterators() + { + object o({ + {"a", 1}, + {"b", true}, + {"c", "hello"}}); + auto const& co = o; + object no; + auto const& cno = no; + + // empty container + { + BOOST_TEST(no.begin() == no.end()); + BOOST_TEST(cno.begin() == cno.end()); + BOOST_TEST(no.cbegin() == no.cend()); + } + + // begin() + { + auto it = o.begin(); + BOOST_TEST(it->key() == "a"); ++it; + BOOST_TEST(it->key() == "b"); it++; + BOOST_TEST(it->key() == "c"); ++it; + BOOST_TEST(it == o.end()); + } + + // begin() const + { + auto it = co.begin(); + BOOST_TEST(it->key() == "a"); ++it; + BOOST_TEST(it->key() == "b"); it++; + BOOST_TEST(it->key() == "c"); ++it; + BOOST_TEST(it == co.end()); + } + + // cbegin() + { + auto it = o.cbegin(); + BOOST_TEST(it->key() == "a"); ++it; + BOOST_TEST(it->key() == "b"); it++; + BOOST_TEST(it->key() == "c"); ++it; + BOOST_TEST(it == o.cend()); + } + + // end() + { + auto it = o.end(); + --it; BOOST_TEST(it->key() == "c"); + it--; BOOST_TEST(it->key() == "b"); + --it; BOOST_TEST(it->key() == "a"); + BOOST_TEST(it == o.begin()); + } + + // end() const + { + auto it = co.end(); + --it; BOOST_TEST(it->key() == "c"); + it--; BOOST_TEST(it->key() == "b"); + --it; BOOST_TEST(it->key() == "a"); + BOOST_TEST(it == co.begin()); + } + + // cend() + { + auto it = o.cend(); + --it; BOOST_TEST(it->key() == "c"); + it--; BOOST_TEST(it->key() == "b"); + --it; BOOST_TEST(it->key() == "a"); + BOOST_TEST(it == o.cbegin()); + } + + // rbegin() + { + auto it = o.rbegin(); + BOOST_TEST(it->key() == "c"); ++it; + BOOST_TEST(it->key() == "b"); it++; + BOOST_TEST(it->key() == "a"); ++it; + BOOST_TEST(it == o.rend()); + } + + // rbegin() const + { + auto it = co.rbegin(); + BOOST_TEST(it->key() == "c"); ++it; + BOOST_TEST(it->key() == "b"); it++; + BOOST_TEST(it->key() == "a"); ++it; + BOOST_TEST(it == co.rend()); + } + + // crbegin() + { + auto it = o.crbegin(); + BOOST_TEST(it->key() == "c"); ++it; + BOOST_TEST(it->key() == "b"); it++; + BOOST_TEST(it->key() == "a"); ++it; + BOOST_TEST(it == o.crend()); + } + + // rend() + { + auto it = o.rend(); + --it; BOOST_TEST(it->key() == "a"); + it--; BOOST_TEST(it->key() == "b"); + --it; BOOST_TEST(it->key() == "c"); + BOOST_TEST(it == o.rbegin()); + } + + // rend() const + { + auto it = co.rend(); + --it; BOOST_TEST(it->key() == "a"); + it--; BOOST_TEST(it->key() == "b"); + --it; BOOST_TEST(it->key() == "c"); + BOOST_TEST(it == co.rbegin()); + } + + // crend() + { + auto it = o.crend(); + --it; BOOST_TEST(it->key() == "a"); + it--; BOOST_TEST(it->key() == "b"); + --it; BOOST_TEST(it->key() == "c"); + BOOST_TEST(it == o.crbegin()); + } + } + + //------------------------------------------------------ + + void + testCapacity() + { + BOOST_TEST( + object{}.size() < object{}.max_size()); + } + + //------------------------------------------------------ + + void + testModifiers() + { + DECLARE_INIT_LISTS; + + // clear + { + // empty + { + object o; + o.clear(); + BOOST_TEST(o.empty()); + } + + // small + { + object o(i0_); + BOOST_TEST(! o.empty()); + o.clear(); + BOOST_TEST(o.empty()); + } + + // large + { + object o(i1_); + BOOST_TEST(! o.empty()); + o.clear(); + BOOST_TEST(o.empty()); + } + } + + // insert(P&&) + { + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + auto result = o.insert( + std::make_pair("x", 1)); + BOOST_TEST(result.second); + BOOST_TEST(result.first->key() == "x"); + BOOST_TEST(result.first->value().as_int64() == 1); + }); + + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + auto const p = std::make_pair("x", 1); + auto result = o.insert(p); + BOOST_TEST(result.second); + BOOST_TEST(result.first->key() == "x"); + BOOST_TEST(result.first->value().as_int64() == 1); + }); + + fail_loop([&](storage_ptr const& sp) + { + object o({ + {"a", 1}, + {"b", 2}, + {"c", 3}}, sp); + auto const result = o.insert( + std::make_pair("b", 4)); + BOOST_TEST( + result.first->value().as_int64() == 2); + BOOST_TEST(! result.second); + }); + + // insert child + { + object o = { + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 } }; + o.insert(std::pair< + string_view, value&>( + "k4", o["k2"])); + BOOST_TEST(o == object({ + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 }, + { "k4", 2 }})); + } + } + + // insert(InputIt, InputIt) + { + // small + { + // ForwardIterator + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.insert(i0_.begin(), i0_.end()); + check(o, s0_); + }); + + // InputIterator + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.insert( + make_input_iterator(i0_.begin()), + make_input_iterator(i0_.end())); + check(o, s0_); + }); + + // existing duplicate key, ForwardIterator + { + object o({{"0",0},{"1",1},{"2",2}}); + init_list i = {{"2",nullptr},{"3",3}}; + o.insert(i.begin(), i.end()); + BOOST_TEST(o.capacity() <= + detail::small_object_size_); + check(o, R"({"0":0,"1":1,"2":2,"3":3})"); + } + + // existing duplicate key, InputIterator + { + object o({{"0",0},{"1",1},{"2",2}}); + init_list i = {{"2",nullptr},{"3",3}}; + o.insert( + make_input_iterator(i.begin()), + make_input_iterator(i.end())); + BOOST_TEST(o.capacity() <= + detail::small_object_size_); + check(o, R"({"0":0,"1":1,"2":2,"3":3})"); + } + + // new duplicate key, ForwardIterator + { + object o({{"0",0},{"1",1},{"2",2}}); + init_list i = {{"3",3},{"4",4},{"3",5}}; + o.insert(i.begin(), i.end()); + BOOST_TEST(o.capacity() <= + detail::small_object_size_); + check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})"); + } + + // new duplicate key, InputIterator + { + object o({{"0",0},{"1",1},{"2",2}}); + init_list i = {{"3",3},{"4",4},{"3",5}}; + o.insert( + make_input_iterator(i.begin()), + make_input_iterator(i.end())); + BOOST_TEST(o.capacity() <= + detail::small_object_size_); + check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})"); + } + } + + // large, ForwardIterator + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.insert(i1_.begin(), i1_.end()); + check(o, s1_); + }); + + // large, InputIterator + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.insert( + make_input_iterator(i1_.begin()), + make_input_iterator(i1_.end())); + check(o, s1_); + }); + } + + // insert(initializer_list) + { + // small + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.insert(i0_); + check(o, s0_); + }); + + // small, existing duplicate + fail_loop([&](storage_ptr const& sp) + { + object o({{"0",0},{"1",1},/*{"2",2},*/{"3",3},{"4",4}}, sp); + BOOST_TEST(o.capacity() <= detail::small_object_size_); + o.insert({{"2",2},{"3",3}}); + BOOST_TEST(o.capacity() <= detail::small_object_size_); + check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})"); + }); + + // small, new duplicate + fail_loop([&](storage_ptr const& sp) + { + object o({{"0",0},{"1",1},/*{"2",2},{"3",3},*/{"4",4}}, sp); + BOOST_TEST(o.capacity() <= detail::small_object_size_); + o.insert({{"2",2},{"3",3},{"2",2}}); + BOOST_TEST(o.capacity() <= detail::small_object_size_); + check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})"); + }); + + // large + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.insert(i1_); + check(o, s1_); + }); + + // large, existing duplicate + fail_loop([&](storage_ptr const& sp) + { + object o({ + {"0",0},{"1",1},{"2",2},{"3",3},{"4",4}, + {"5",5},{"6",6},{"7",7},{"8",8},{"9",9}, + /*{"10",10},*/{"11",11},{"12",12},{"13",13},{"14",14}, + {"15",15},{"16",16},{"17",17},{"18",18},{"19",19}}, sp); + BOOST_TEST(o.capacity() > detail::small_object_size_); + o.insert({{"10",10},{"11",11}}); + BOOST_TEST(o.capacity() > detail::small_object_size_); + check(o, s1_); + }); + + // large, new duplicate + fail_loop([&](storage_ptr const& sp) + { + object o({ + {"0",0},{"1",1},{"2",2},{"3",3},{"4",4}, + {"5",5},{"6",6},{"7",7},{"8",8},{"9",9}, + /*{"10",10},{"11",11},*/{"12",12},{"13",13},{"14",14}, + {"15",15},{"16",16},{"17",17},{"18",18},{"19",19}}, + detail::small_object_size_ + 1, sp); + BOOST_TEST(o.capacity() > detail::small_object_size_); + o.insert({{"10",10},{"11",11},{"10",10}}); + BOOST_TEST(o.capacity() > detail::small_object_size_); + check(o, s1_); + }); + + // do rollback in ~revert_insert + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.insert({ + { "a", { 1, 2, 3, 4 } } }); + }); + + // insert child + { + object o = { + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 } }; + o.insert({ + { "k4", o["k2"] } }); + BOOST_TEST(o == object({ + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 }, + { "k4", 2 }})); + } + } + + // insert_or_assign(key, o); + { + fail_loop([&](storage_ptr const& sp) + { + object o({{"a", 1}}, sp); + o.insert_or_assign("a", str_); + BOOST_TEST(o["a"].is_string()); + }); + + fail_loop([&](storage_ptr const& sp) + { + object o({ + {"a", 1}, + {"b", 2}, + {"c", 3}}, sp); + o.insert_or_assign("d", str_); + BOOST_TEST(o["d"].is_string()); + BOOST_TEST(o.size() == 4); + }); + + fail_loop([&](storage_ptr const& sp) + { + object o({{"a", 1}}, sp); + o.insert_or_assign("b", true); + o.insert_or_assign("c", "hello"); + check(o, 3); + }); + + fail_loop([&](storage_ptr const& sp) + { + object o({{"a", 1}}, sp); + BOOST_TEST( + ! o.insert_or_assign("a", 2).second); + BOOST_TEST(o["a"].as_int64() == 2); + }); + + // insert child + { + object o = { + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 } }; + o.insert_or_assign( + "k4", o["k2"]); + BOOST_TEST(o == object({ + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 }, + { "k4", 2 }})); + } + } + + // emplace(key, arg) + { + fail_loop([&](storage_ptr const& sp) + { + object o(sp); + o.emplace("a", 1); + o.emplace("b", true); + o.emplace("c", "hello"); + check(o, 3); + }); + + // emplace child + { + object o = { + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 } }; + o.emplace( + "k4", o["k2"]); + BOOST_TEST(o == object({ + { "k1", 1 }, + { "k2", 2 }, + { "k3", 3 }, + { "k4", 2 }})); + } + } + + // erase(pos) + { + // small + { + object o(i0_); + auto it = o.erase(o.find("10")); + BOOST_TEST(it->key() == "15"); + BOOST_TEST( + it->value().as_int64() == 15); + BOOST_TEST(serialize(o) == + R"({"0":0,"1":1,"2":2,"3":3,"4":4,)" + R"("5":5,"6":6,"7":7,"8":8,"9":9,)" + R"("15":15,"11":11,"12":12,"13":13,"14":14})"); + } + + // large + { + object o(i1_); + auto it = o.erase(o.find("10")); + BOOST_TEST(it->key() == "19"); + BOOST_TEST( + it->value().as_int64() == 19); + BOOST_TEST(serialize(o) == + R"({"0":0,"1":1,"2":2,"3":3,"4":4,)" + R"("5":5,"6":6,"7":7,"8":8,"9":9,)" + R"("19":19,"11":11,"12":12,"13":13,"14":14,)" + R"("15":15,"16":16,"17":17,"18":18})"); + } + } + + // erase(key) + { + { + object o({ + {"a", 1}, + {"b", true}, + {"c", "hello"}}); + BOOST_TEST(o.erase("b2") == 0); + check(o, 3); + } + + { + object o({ + {"a", 1}, + {"b", true}, + {"b2", 2}, + {"c", "hello"}}); + BOOST_TEST(o.erase("b2") == 1); + check(o, 4); + } + } + + // swap(object&) + { + { + object o1 = {{"a",1}, {"b",true}, {"c", "hello"}}; + object o2 = {{"d",{1,2,3}}}; + swap(o1, o2); + BOOST_TEST(o1.size() == 1); + BOOST_TEST(o2.size() == 3); + BOOST_TEST(o1.count("d") == 1); + } + + fail_loop([&](storage_ptr const& sp) + { + object o1 = {{"a",1}, {"b",true}, {"c", "hello"}}; + object o2({{"d",{1,2,3}}}, sp); + swap(o1, o2); + BOOST_TEST(o1.size() == 1); + BOOST_TEST(o2.size() == 3); + BOOST_TEST(o1.count("d") == 1); + }); + + fail_loop([&](storage_ptr const& sp) + { + object o1({{"d",{1,2,3}}}, sp); + object o2 = {{"a",1}, {"b",true}, {"c", "hello"}}; + swap(o1, o2); + BOOST_TEST(o1.size() == 3); + BOOST_TEST(o2.size() == 1); + BOOST_TEST(o2.count("d") == 1); + }); + } + } + + //------------------------------------------------------ + + void + testLookup() + { + object o0; + object o1({ + {"a", 1}, + {"b", true}, + {"c", "hello"}}); + auto const& co0 = o0; + auto const& co1 = o1; + + // at(key) + { + BOOST_TEST( + o1.at("a").is_number()); + BOOST_TEST_THROWS((o1.at("d")), + std::out_of_range); + } + + // at(key) const + { + BOOST_TEST( + co1.at("a").is_number()); + BOOST_TEST_THROWS((co1.at("d")), + std::out_of_range); + } + + // operator[&](key) + { + object o({ + {"a", 1}, + {"b", true}, + {"c", "hello"}}); + BOOST_TEST(o.count("d") == 0);; + BOOST_TEST(o["a"].is_number()); + BOOST_TEST(o["d"].is_null()); + BOOST_TEST(o.count("d") == 1); + } + + // count(key) + { + BOOST_TEST(o1.count("a") == 1); + BOOST_TEST(o1.count("d") == 0); + BOOST_TEST(o1.count("e") == 0); + } + + // find(key) + // find(key) const + { + BOOST_TEST( + o0.find("") == o0.end()); + BOOST_TEST( + o1.find("a")->key() == "a"); + BOOST_TEST( + o1.find("e") == o1.end()); + + BOOST_TEST( + co0.find("") == co0.end()); + BOOST_TEST( + co1.find("a")->key() == "a"); + BOOST_TEST( + co1.find("e") == o1.end()); + } + + // contains(key) + { + BOOST_TEST(o1.contains("a")); + BOOST_TEST(! o1.contains("e")); + BOOST_TEST(! object().contains("")); + } + + // if_contains(key) + // if_contains(key) const + { + BOOST_TEST(o1.if_contains("a")->is_int64()); + BOOST_TEST(o1.if_contains("e") == nullptr); + BOOST_TEST(co1.if_contains("a")->is_int64()); + BOOST_TEST(co1.if_contains("e") == nullptr); + + *o1.if_contains("a") = 2; + BOOST_TEST(co1.if_contains("a")->as_int64() == 2); + } + } + + void + testHashPolicy() + { + // reserve(size_type) + { + { + object o; + for(std::size_t i = 0; i < 10; ++i) + o.emplace(std::to_string(i), i); + o.reserve(15); + BOOST_TEST(o.capacity() >= 15); + o.reserve(20); + BOOST_TEST(o.capacity() >= 20); + } + + { + object o; + o.reserve(3); + BOOST_TEST(o.capacity() == 3); + o.reserve(7); + BOOST_TEST(o.capacity() == 7); + } + } + } + + //------------------------------------------------------ + + void + testImplementation() + { + // insert duplicate keys + { + object o({ + {"a", 1}, + {"b", true}, + {"b", {1,2,3}}, + {"c", "hello"}}); + BOOST_TEST(o.at("a").as_int64() == 1); + BOOST_TEST(o.at("b").as_bool() == true); + BOOST_TEST(o.at("c").as_string() == "hello"); + } + + // destroy key_value_pair array with need_free=false + { + monotonic_resource mr; + object o({ + {"a", 1}, + {"b", true}, + {"b", {1,2,3}}, + {"c", "hello"}}, &mr); + } + } + + static + string_view + make_key( + std::size_t i, + char* buf) + { + int constexpr base = 62; + char const* const alphabet = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + char* dest = buf; + do + { + *dest++ = alphabet[i%base]; + i /= base; + } + while(i); + return { buf, static_cast< + std::size_t>(dest-buf) }; + } + + void + testCollisions() + { + int constexpr buckets = + detail::small_object_size_ + 1; + int constexpr collisions = 3; + + //DECLARE_INIT_LISTS; + + // find a set of keys that collide + std::vector<std::string> v; + object o; + o.reserve(buckets); + { + BOOST_TEST( + o.capacity() == buckets); + char buf[26]; + auto const match = + o.t_->digest("0") % buckets; + v.push_back("0"); + std::size_t i = 1; + for(;;) + { + auto s = make_key(i, buf); + if((o.t_->digest(s) % + buckets) == match) + { + v.push_back(std::string( + s.data(), s.size())); + if(v.size() >= collisions) + break; + } + ++i; + } + } + + // ensure collisions are distinguishable + { + o.clear(); + BOOST_TEST( + (o.t_->digest(v[0]) % buckets) == + (o.t_->digest(v[1]) % buckets)); + BOOST_TEST( + (o.t_->digest(v[1]) % buckets) == + (o.t_->digest(v[2]) % buckets)); + o.emplace(v[0], 1); + o.emplace(v[1], 2); + o.emplace(v[2], 3); + BOOST_TEST(o.at(v[0]).to_number<int>() == 1); + BOOST_TEST(o.at(v[1]).to_number<int>() == 2); + BOOST_TEST(o.at(v[2]).to_number<int>() == 3); + } + + // erase k1 + { + o.clear(); + o.emplace(v[0], 1); + o.emplace(v[1], 2); + o.emplace(v[2], 3); + o.erase(v[0]); + BOOST_TEST(o.at(v[1]).to_number<int>() == 2); + BOOST_TEST(o.at(v[2]).to_number<int>() == 3); + } + + // erase k2 + { + o.clear(); + o.emplace(v[0], 1); + o.emplace(v[1], 2); + o.emplace(v[2], 3); + o.erase(v[1]); + BOOST_TEST(o.at(v[0]).to_number<int>() == 1); + BOOST_TEST(o.at(v[2]).to_number<int>() == 3); + } + + // erase k3 + { + o.clear(); + o.emplace(v[0], 1); + o.emplace(v[1], 2); + o.emplace(v[2], 3); + o.erase(v[2]); + BOOST_TEST(o.at(v[0]).to_number<int>() == 1); + BOOST_TEST(o.at(v[1]).to_number<int>() == 2); + } + } + + void + testEquality() + { + BOOST_TEST(object({}) == object({})); + BOOST_TEST(object({}) != object({{"1",1},{"2",2}})); + BOOST_TEST(object({{"1",1},{"2",2},{"3",3}}) == object({{"1",1},{"2",2},{"3",3}})); + BOOST_TEST(object({{"1",1},{"2",2},{"3",3}}) != object({{"1",1},{"2",2}})); + BOOST_TEST(object({{"1",1},{"2",2},{"3",3}}) == object({{"3",3},{"2",2},{"1",1}})); + } + + void + testAllocation() + { + { + checking_resource res; + object o(&res); + o.reserve(1); + } + + { + checking_resource res; + object o(&res); + o.reserve(1000); + } + + { + checking_resource res; + object o({std::make_pair("one", 1)}, &res); + } + } + + void + testHash() + { + BOOST_TEST(check_hash_equal( + object(), object({}))); + BOOST_TEST(expect_hash_not_equal( + object(), object({{"1",1},{"2",2}}))); + BOOST_TEST(check_hash_equal( + object({{"a",1}, {"b",2}, {"c",3}}), + object({{"b",2}, {"c",3}, {"a",1}}))); + BOOST_TEST(expect_hash_not_equal( + object({{"a",1}, {"b",2}, {"c",3}}), + object({{"b",2}, {"c",3}}))); + } + + void + run() + { + testDtor(); + testCtors(); + testIterators(); + testCapacity(); + testModifiers(); + testLookup(); + testHashPolicy(); + testImplementation(); + testCollisions(); + testEquality(); + testAllocation(); + testHash(); + } +}; + +TEST_SUITE(object_test, "boost.json.object"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/parse-vectors.hpp b/src/boost/libs/json/test/parse-vectors.hpp new file mode 100644 index 000000000..dc120d966 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors.hpp @@ -0,0 +1,1470 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#ifndef PARSE_VECTORS +#define PARSE_VECTORS + +#include <boost/json/detail/config.hpp> +#include <cstdlib> +#include <type_traits> + +BOOST_JSON_NS_BEGIN + +struct parse_vectors +{ + struct item + { + char result; + string_view name; + string_view text; + }; + + using iterator = item const*; + + iterator begin() const noexcept + { + return first_; + } + + iterator end() const noexcept + { + return last_; + } + + std::size_t + size() const noexcept + { + return last_ - first_; + } + + inline parse_vectors() noexcept; + +private: + template<std::size_t N> + static + string_view + lit(char const (&s)[N]) + { + return {s, N - 1}; + } + + iterator first_; + iterator last_; +}; + +parse_vectors:: +parse_vectors() noexcept +{ + static item const list[] = { + { 'i', "number_double_huge_neg_exp", lit("[123.456e-789]") }, + { 'i', "number_huge_exp", lit("[0.4e006699999999999999999999999999999999999999999999999999999999999999999999999" + "99999999999999999999999999999999999999999999969999999006]") }, + { 'i', "number_neg_int_huge_exp", lit("[-1e+9999]") }, + { 'i', "number_pos_double_huge_exp", lit("[1.5e+9999]") }, + { 'i', "number_real_neg_overflow", lit("[-123123e100000]") }, + { 'i', "number_real_pos_overflow", lit("[123123e100000]") }, + { 'i', "number_real_underflow", lit("[123e-10000000]") }, + { 'i', "number_too_big_neg_int", lit("[-123123123123123123123123123123]") }, + { 'i', "number_too_big_pos_int", lit("[100000000000000000000]") }, + { 'i', "number_very_big_negative_int", lit("[-237462374673276894279832749832423479823246327846]") }, + { 'i', "object_key_lone_2nd_surrogate", lit("{\"\\uDFAA\":0}") }, + { 'i', "string_1st_surrogate_but_2nd_missing", lit("[\"\\uDADA\"]") }, + { 'i', "string_1st_valid_surrogate_2nd_invalid", lit("[\"\\uD888\\u1234\"]") }, + { 'i', "string_incomplete_surrogates_escape_valid", lit("[\"\\uD800\\uD800\\n\"]") }, + { 'i', "string_incomplete_surrogate_and_escape_valid", lit("[\"\\uD800\\n\"]") }, + { 'i', "string_incomplete_surrogate_pair", lit("[\"\\uDd1ea\"]") }, + { 'i', "string_invalid_lonely_surrogate", lit("[\"\\ud800\"]") }, + { 'i', "string_invalid_surrogate", lit("[\"\\ud800abc\"]") }, + { 'i', "string_invalid_utf-8", lit("[\"\xFF""\"]") }, + { 'i', "string_inverted_surrogates_U+1D11E", lit("[\"\\uDd1e\\uD834\"]") }, + { 'i', "string_iso_latin_1", lit("[\"\xE9""\"]") }, + { 'i', "string_lone_second_surrogate", lit("[\"\\uDFAA\"]") }, + { 'i', "string_lone_utf8_continuation_byte", lit("[\"\x81""\"]") }, + { 'i', "string_not_in_unicode_range", lit("[\"\xF4""\xBF""\xBF""\xBF""\"]") }, + { 'i', "string_overlong_sequence_2_bytes", lit("[\"\xC0""\xAF""\"]") }, + { 'i', "string_overlong_sequence_6_bytes", lit("[\"\xFC""\x83""\xBF""\xBF""\xBF""\xBF""\"]") }, + { 'i', "string_overlong_sequence_6_bytes_null", lit("[\"\xFC""\x80""\x80""\x80""\x80""\x80""\"]") }, + { 'i', "string_truncated-utf-8", lit("[\"\xE0""\xFF""\"]") }, + { 'i', "string_UTF-16LE_with_BOM", lit("\xFF""\xFE""[\x00""\"\x00""\xE9""\x00""\"\x00""]\x00""") }, + { 'i', "string_UTF-8_invalid_sequence", lit("[\"\xE6""\x97""\xA5""\xD1""\x88""\xFA""\"]") }, + { 'i', "string_utf16BE_no_BOM", lit("\x00""[\x00""\"\x00""\xE9""\x00""\"\x00""]") }, + { 'i', "string_utf16LE_no_BOM", lit("[\x00""\"\x00""\xE9""\x00""\"\x00""]\x00""") }, + { 'i', "string_UTF8_surrogate_U+D800", lit("[\"\xED""\xA0""\x80""\"]") }, + { 'i', "structure_500_nested_arrays", lit("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]") }, + { 'i', "structure_UTF-8_BOM_empty_object", lit("\xEF""\xBB""\xBF""{}") }, + { 'n', "array_1_true_without_comma", lit("[1 true]") }, + { 'n', "array_a_invalid_utf8", lit("[a\xE5""]") }, + { 'n', "array_colon_instead_of_comma", lit("[\"\": 1]") }, + { 'n', "array_comma_after_close", lit("[\"\"],") }, + { 'n', "array_comma_and_number", lit("[,1]") }, + { 'n', "array_double_comma", lit("[1,,2]") }, + { 'n', "array_double_extra_comma", lit("[\"x\",,]") }, + { 'n', "array_extra_close", lit("[\"x\"]]") }, + { 'n', "array_incomplete", lit("[\"x\"") }, + { 'n', "array_incomplete_invalid_value", lit("[x") }, + { 'n', "array_inner_array_no_comma", lit("[3[4]]") }, + { 'n', "array_invalid_utf8", lit("[\xFF""]") }, + { 'n', "array_items_separated_by_semicolon", lit("[1:2]") }, + { 'n', "array_just_comma", lit("[,]") }, + { 'n', "array_just_minus", lit("[-]") }, + { 'n', "array_misclosed", lit("[}") }, + { 'n', "array_missing_value", lit("[ , \"\"]") }, + { 'n', "array_newlines_unclosed", lit("[\"a\",\x0A""4\x0A"",1,") }, + { 'n', "array_number_and_several_commas", lit("[1,,]") }, + { 'n', "array_spaces_vertical_tab_formfeed", lit("[\"\x0B""a\"\\f]") }, + { 'n', "array_star_inside", lit("[*]") }, + { 'n', "array_unclosed", lit("[\"\"") }, + { 'n', "array_unclosed_trailing_comma", lit("[1,") }, + { 'n', "array_unclosed_with_new_lines", lit("[1,\x0A""1\x0A"",1") }, + { 'n', "array_unclosed_with_object_inside", lit("[{}") }, + { 'n', "fail01", lit("[\"mismatch\"}") }, + { 'n', "fail02", lit("[\"Unclosed array\"") }, + { 'n', "fail03", lit("{unquoted_key: \"keys must be quoted\"}") }, + { 'n', "fail05", lit("[\"double extra comma\",,]") }, + { 'n', "fail06", lit("[ , \"<-- missing value\"]") }, + { 'n', "fail07", lit("[\"Comma after the close\"],") }, + { 'n', "fail08", lit("[\"Extra close\"]]") }, + { 'n', "fail10", lit("{\"Extra value after close\": true} \"misplaced quoted value\"") }, + { 'n', "fail11", lit("{\"Illegal expression\": 1 + 2}") }, + { 'n', "fail12", lit("{\"Illegal invocation\": alert()}") }, + { 'n', "fail13", lit("{\"Numbers cannot have leading zeroes\": 013}") }, + { 'n', "fail14", lit("{\"Numbers cannot be hex\": 0x14}") }, + { 'n', "fail15", lit("[\"Illegal backslash escape: \\x15\"]") }, + { 'n', "fail16", lit("[\\naked]") }, + { 'n', "fail17", lit("[\"Illegal backslash escape: \\017\"]") }, + { 'n', "fail19", lit("{\"Missing colon\" null}") }, + { 'n', "fail20", lit("{\"Double colon\":: null}") }, + { 'n', "fail21", lit("{\"Comma instead of colon\", null}") }, + { 'n', "fail22", lit("[\"Colon instead of comma\": false]") }, + { 'n', "fail23", lit("[\"Bad value\", truth]") }, + { 'n', "fail24", lit("['single quote']") }, + { 'n', "fail25", lit("[\" tab character in string \"]") }, + { 'n', "fail26", lit("[\"tab\\ character\\ in\\ string\\ \"]") }, + { 'n', "fail27", lit("[\"line\x0A""break\"]") }, + { 'n', "fail28", lit("[\"line\\\x0A""break\"]") }, + { 'n', "fail29", lit("[0e]") }, + { 'n', "fail30", lit("[0e+]") }, + { 'n', "fail31", lit("[0e+-1]") }, + { 'n', "fail32", lit("{\"Comma instead if closing brace\": true,") }, + { 'n', "incomplete_false", lit("[fals]") }, + { 'n', "incomplete_null", lit("[nul]") }, + { 'n', "incomplete_true", lit("[tru]") }, + { 'n', "multidigit_number_then_00", lit("123\x00""") }, + { 'n', "number_++", lit("[++1234]") }, + { 'n', "number_+1", lit("[+1]") }, + { 'n', "number_+Inf", lit("[+Inf]") }, + { 'n', "number_-01", lit("[-01]") }, + { 'n', "number_-1.0.", lit("[-1.0.]") }, + { 'n', "number_-2.", lit("[-2.]") }, + { 'n', "number_-NaN", lit("[-NaN]") }, + { 'n', "number_.-1", lit("[.-1]") }, + { 'n', "number_.2e-3", lit("[.2e-3]") }, + { 'n', "number_0.1.2", lit("[0.1.2]") }, + { 'n', "number_0.3e+", lit("[0.3e+]") }, + { 'n', "number_0.3e", lit("[0.3e]") }, + { 'n', "number_0.e1", lit("[0.e1]") }, + { 'n', "number_0e+", lit("[0e+]") }, + { 'n', "number_0e", lit("[0e]") }, + { 'n', "number_0_capital_E+", lit("[0E+]") }, + { 'n', "number_0_capital_E", lit("[0E]") }, + { 'n', "number_1.0e+", lit("[1.0e+]") }, + { 'n', "number_1.0e-", lit("[1.0e-]") }, + { 'n', "number_1.0e", lit("[1.0e]") }, + { 'n', "number_1eE2", lit("[1eE2]") }, + { 'n', "number_1_000", lit("[1 000.0]") }, + { 'n', "number_2.e+3", lit("[2.e+3]") }, + { 'n', "number_2.e-3", lit("[2.e-3]") }, + { 'n', "number_2.e3", lit("[2.e3]") }, + { 'n', "number_9.e+", lit("[9.e+]") }, + { 'n', "number_expression", lit("[1+2]") }, + { 'n', "number_hex_1_digit", lit("[0x1]") }, + { 'n', "number_hex_2_digits", lit("[0x42]") }, + { 'n', "number_Inf", lit("[Inf]") }, + { 'n', "number_infinity", lit("[Infinity]") }, + { 'n', "number_invalid+-", lit("[0e+-1]") }, + { 'n', "number_invalid-negative-real", lit("[-123.123foo]") }, + { 'n', "number_invalid-utf-8-in-bigger-int", lit("[123\xE5""]") }, + { 'n', "number_invalid-utf-8-in-exponent", lit("[1e1\xE5""]") }, + { 'n', "number_invalid-utf-8-in-int", lit("[0\xE5""]\x0A""") }, + { 'n', "number_minus_infinity", lit("[-Infinity]") }, + { 'n', "number_minus_sign_with_trailing_garbage", lit("[-foo]") }, + { 'n', "number_minus_space_1", lit("[- 1]") }, + { 'n', "number_NaN", lit("[NaN]") }, + { 'n', "number_neg_int_starting_with_zero", lit("[-012]") }, + { 'n', "number_neg_real_without_int_part", lit("[-.123]") }, + { 'n', "number_neg_with_garbage_at_end", lit("[-1x]") }, + { 'n', "number_real_garbage_after_e", lit("[1ea]") }, + { 'n', "number_real_without_fractional_part", lit("[1.]") }, + { 'n', "number_real_with_invalid_utf8_after_e", lit("[1e\xE5""]") }, + { 'n', "number_starting_with_dot", lit("[.123]") }, + { 'n', "number_U+FF11_fullwidth_digit_one", lit("[\xEF""\xBC""\x91""]") }, + { 'n', "number_with_alpha", lit("[1.2a-3]") }, + { 'n', "number_with_alpha_char", lit("[1.8011670033376514H-308]") }, + { 'n', "number_with_leading_zero", lit("[012]") }, + { 'n', "object_bad_value", lit("[\"x\", truth]") }, + { 'n', "object_bracket_key", lit("{[: \"x\"}\x0A""") }, + { 'n', "object_comma_instead_of_colon", lit("{\"x\", null}") }, + { 'n', "object_comma_after_colon", lit("{\"x\":, \"y\":1}") }, + { 'n', "object_double_colon", lit("{\"x\"::\"b\"}") }, + { 'n', "object_emoji", lit("{\xF0""\x9F""\x87""\xA8""\xF0""\x9F""\x87""\xAD""}") }, + { 'n', "object_garbage_at_end", lit("{\"a\":\"a\" 123}") }, + { 'n', "object_just_comma", lit("{,}") }, + { 'n', "object_key_with_single_quotes", lit("{key: 'value'}") }, + { 'n', "object_missing_colon", lit("{\"a\" b}") }, + { 'n', "object_missing_key", lit("{:\"b\"}") }, + { 'n', "object_missing_semicolon", lit("{\"a\" \"b\"}") }, + { 'n', "object_missing_value", lit("{\"a\":") }, + { 'n', "object_no-colon", lit("{\"a\"") }, + { 'n', "object_non_string_key", lit("{1:1}") }, + { 'n', "object_non_string_key_but_huge_number_instead", lit("{9999E9999:1}") }, + { 'n', "object_repeated_null_null", lit("{null:null,null:null}") }, + { 'n', "object_several_trailing_commas", lit("{\"id\":0,,,,,}") }, + { 'n', "object_single_quote", lit("{'a':0}") }, + { 'n', "object_trailing_comment_open", lit("{\"a\":\"b\"}/**//") }, + { 'n', "object_trailing_comment_slash_open_incomplete", lit("{\"a\":\"b\"}/") }, + { 'n', "object_two_commas_in_a_row", lit("{\"a\":\"b\",,\"c\":\"d\"}") }, + { 'n', "object_unquoted_key", lit("{a: \"b\"}") }, + { 'n', "object_unterminated-value", lit("{\"a\":\"a") }, + { 'n', "object_with_single_string", lit("{ \"foo\" : \"bar\", \"a\" }") }, + { 'n', "object_with_trailing_garbage", lit("{\"a\":\"b\"}#") }, + { 'n', "single_space", lit(" ") }, + { 'n', "string_1_surrogate_then_escape", lit("[\"\\uD800\\\"]") }, + { 'n', "string_1_surrogate_then_escape_u", lit("[\"\\uD800\\u\"]") }, + { 'n', "string_1_surrogate_then_escape_u1", lit("[\"\\uD800\\u1\"]") }, + { 'n', "string_1_surrogate_then_escape_u1x", lit("[\"\\uD800\\u1x\"]") }, + { 'n', "string_accentuated_char_no_quotes", lit("[\xC3""\xA9""]") }, + { 'n', "string_backslash_00", lit("[\"\\\x00""\"]") }, + { 'n', "string_escaped_backslash_bad", lit("[\"\\\\\\\"]") }, + { 'n', "string_escaped_ctrl_char_tab", lit("[\"\\ \"]") }, + { 'n', "string_escaped_emoji", lit("[\"\\\xF0""\x9F""\x8C""\x80""\"]") }, + { 'n', "string_escape_x", lit("[\"\\x00\"]") }, + { 'n', "string_incomplete_escape", lit("[\"\\\"]") }, + { 'n', "string_incomplete_escaped_character", lit("[\"\\u00A\"]") }, + { 'n', "string_incomplete_surrogate", lit("[\"\\uD834\\uDd\"]") }, + { 'n', "string_incomplete_surrogate_escape_invalid", lit("[\"\\uD800\\uD800\\x\"]") }, + { 'n', "string_invalid-utf-8-in-escape", lit("[\"\\u\xE5""\"]") }, + { 'n', "string_invalid_backslash_esc", lit("[\"\\a\"]") }, + { 'n', "string_invalid_unicode_escape", lit("[\"\\uqqqq\"]") }, + { 'n', "string_invalid_utf8_after_escape", lit("[\"\\\xE5""\"]") }, + { 'n', "string_leading_uescaped_thinspace", lit("[\\u0020\"asd\"]") }, + { 'n', "string_no_quotes_with_bad_escape", lit("[\\n]") }, + { 'n', "string_single_doublequote", lit("\"") }, + { 'n', "string_single_quote", lit("['single quote']") }, + { 'n', "string_single_string_no_double_quotes", lit("abc") }, + { 'n', "string_start_escape_unclosed", lit("[\"\\") }, + { 'n', "string_unescaped_crtl_char", lit("[\"a\x00""a\"]") }, + { 'n', "string_unescaped_newline", lit("[\"new\x0A""line\"]") }, + { 'n', "string_unescaped_tab", lit("[\" \"]") }, + { 'n', "string_unicode_CapitalU", lit("\"\\UA66D\"") }, + { 'n', "string_with_trailing_garbage", lit("\"\"x") }, + { 'n', "structure_100000_opening_arrays", lit("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[") }, + { 'n', "structure_angle_bracket_.", lit("<.>") }, + { 'n', "structure_angle_bracket_null", lit("[<null>]") }, + { 'n', "structure_array_trailing_garbage", lit("[1]x") }, + { 'n', "structure_array_with_extra_array_close", lit("[1]]") }, + { 'n', "structure_array_with_unclosed_string", lit("[\"asd]") }, + { 'n', "structure_ascii-unicode-identifier", lit("a\xC3""\xA5""") }, + { 'n', "structure_capitalized_True", lit("[True]") }, + { 'n', "structure_close_unopened_array", lit("1]") }, + { 'n', "structure_comma_instead_of_closing_brace", lit("{\"x\": true,") }, + { 'n', "structure_double_array", lit("[][]") }, + { 'n', "structure_end_array", lit("]") }, + { 'n', "structure_incomplete_UTF8_BOM", lit("\xEF""\xBB""{}") }, + { 'n', "structure_lone-invalid-utf-8", lit("\xE5""") }, + { 'n', "structure_lone-open-bracket", lit("[") }, + { 'n', "structure_no_data", lit("") }, + { 'n', "structure_null-byte-outside-string", lit("[\x00""]") }, + { 'n', "structure_number_with_trailing_garbage", lit("2@") }, + { 'n', "structure_object_followed_by_closing_object", lit("{}}") }, + { 'n', "structure_object_unclosed_no_value", lit("{\"\":") }, + { 'n', "structure_object_with_trailing_garbage", lit("{\"a\": true} \"x\"") }, + { 'n', "structure_open_array_apostrophe", lit("['") }, + { 'n', "structure_open_array_comma", lit("[,") }, + { 'n', "structure_open_array_object", lit("[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[" + "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\"" + ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"" + "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[") }, + { 'n', "structure_open_array_open_object", lit("[{") }, + { 'n', "structure_open_array_open_string", lit("[\"a") }, + { 'n', "structure_open_array_string", lit("[\"a\"") }, + { 'n', "structure_open_object", lit("{") }, + { 'n', "structure_open_object_close_array", lit("{]") }, + { 'n', "structure_open_object_comma", lit("{,") }, + { 'n', "structure_open_object_open_array", lit("{[") }, + { 'n', "structure_open_object_open_string", lit("{\"a") }, + { 'n', "structure_open_object_string_with_apostrophes", lit("{'a'") }, + { 'n', "structure_open_open", lit("[\"\\{[\"\\{[\"\\{[\"\\{") }, + { 'n', "structure_single_eacute", lit("\xE9""") }, + { 'n', "structure_single_star", lit("*") }, + { 'n', "structure_trailing_#", lit("{\"a\":\"b\"}#{}") }, + { 'n', "structure_U+2060_word_joined", lit("[\xE2""\x81""\xA0""]") }, + { 'n', "structure_uescaped_LF_before_string", lit("[\\u000A\"\"]") }, + { 'n', "structure_unclosed_array", lit("[1") }, + { 'n', "structure_unclosed_array_partial_null", lit("[ false, nul") }, + { 'n', "structure_unclosed_array_unfinished_false", lit("[ true, fals") }, + { 'n', "structure_unclosed_array_unfinished_true", lit("[ false, tru") }, + { 'n', "structure_unclosed_object", lit("{\"asd\":\"asd\"") }, + { 'n', "structure_unicode-identifier", lit("\xC3""\xA5""") }, + { 'n', "structure_UTF8_BOM_no_data", lit("\xEF""\xBB""\xBF""") }, + { 'n', "structure_whitespace_formfeed", lit("[\x0C""]") }, + { 'n', "structure_whitespace_U+2060_word_joiner", lit("[\xE2""\x81""\xA0""]") }, + { 'y', "array_arraysWithSpaces", lit("[[] ]") }, + { 'y', "array_empty-string", lit("[\"\"]") }, + { 'y', "array_empty", lit("[]") }, + { 'y', "array_ending_with_newline", lit("[\"a\"]") }, + { 'y', "array_false", lit("[false]") }, + { 'y', "array_heterogeneous", lit("[null, 1, \"1\", {}]") }, + { 'y', "array_null", lit("[null]") }, + { 'y', "array_with_1_and_newline", lit("[1\x0A""]") }, + { 'y', "array_with_leading_space", lit(" [1]") }, + { 'y', "array_with_several_null", lit("[1,null,null,null,2]") }, + { 'y', "array_with_trailing_space", lit("[2] ") }, + { 'y', "number", lit("[123e65]") }, + { 'y', "number_0e+1", lit("[0e+1]") }, + { 'y', "number_0e1", lit("[0e1]") }, + { 'y', "number_after_space", lit("[ 4]") }, + { 'y', "number_double_close_to_zero", lit("[-0.0000000000000000000000000000000000000000000000000000000000000000000000000000" + "01]\x0A""") }, + { 'y', "number_int_with_exp", lit("[20e1]") }, + { 'y', "number_minus_zero", lit("[-0]") }, + { 'y', "number_negative_int", lit("[-123]") }, + { 'y', "number_negative_one", lit("[-1]") }, + { 'y', "number_negative_zero", lit("[-0]") }, + { 'y', "number_real_capital_e", lit("[1E22]") }, + { 'y', "number_real_capital_e_neg_exp", lit("[1E-2]") }, + { 'y', "number_real_capital_e_pos_exp", lit("[1E+2]") }, + { 'y', "number_real_exponent", lit("[123e45]") }, + { 'y', "number_real_fraction_exponent", lit("[123.456e78]") }, + { 'y', "number_real_neg_exp", lit("[1e-2]") }, + { 'y', "number_real_pos_exponent", lit("[1e+2]") }, + { 'y', "number_simple_int", lit("[123]") }, + { 'y', "number_simple_real", lit("[123.456789]") }, + { 'y', "object", lit("{\"asd\":\"sdf\", \"dfg\":\"fgh\"}") }, + { 'y', "object_basic", lit("{\"asd\":\"sdf\"}") }, + { 'y', "object_duplicated_key", lit("{\"a\":\"b\",\"a\":\"c\"}") }, + { 'y', "object_duplicated_key_and_value", lit("{\"a\":\"b\",\"a\":\"b\"}") }, + { 'y', "object_empty", lit("{}") }, + { 'y', "object_empty_key", lit("{\"\":0}") }, + { 'y', "object_escaped_null_in_key", lit("{\"foo\\u0000bar\": 42}") }, + { 'y', "object_extreme_numbers", lit("{ \"min\": -1.0e+28, \"max\": 1.0e+28 }") }, + { 'y', "object_long_strings", lit("{\"x\":[{\"id\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}], \"id\": \"xxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}") }, + { 'y', "object_simple", lit("{\"a\":[]}") }, + { 'y', "object_string_unicode", lit("{\"title\":\"\\u041f\\u043e\\u043b\\u0442\\u043e\\u0440\\u0430 \\u0417\\u0435\\u" + "043c\\u043b\\u0435\\u043a\\u043e\\u043f\\u0430\" }") }, + { 'y', "object_with_newlines", lit("{\x0A""\"a\": \"b\"\x0A""}") }, + { 'y', "pass01", lit("[\x0A"" \"JSON Test Pattern pass1\",\x0A"" {\"object with 1 member\":[\"ar" + "ray with 1 element\"]},\x0A"" {},\x0A"" [],\x0A"" -42,\x0A"" true,\x0A""" + " false,\x0A"" null,\x0A"" {\x0A"" \"integer\": 1234567890,\x0A"" " + " \"real\": -9876.543210,\x0A"" \"e\": 0.123456789e-12,\x0A"" " + "\"E\": 1.234567890E+34,\x0A"" \"\": 23456789012E66,\x0A"" \"zero\"" + ": 0,\x0A"" \"one\": 1,\x0A"" \"space\": \" \",\x0A"" \"quote" + "\": \"\\\"\",\x0A"" \"backslash\": \"\\\\\",\x0A"" \"controls\": \"" + "\\b\\f\\n\\r\\t\",\x0A"" \"slash\": \"/ & \\/\",\x0A"" \"alpha\": \"" + "abcdefghijklmnopqrstuvwyz\",\x0A"" \"ALPHA\": \"ABCDEFGHIJKLMNOPQRSTUVWYZ\"" + ",\x0A"" \"digit\": \"0123456789\",\x0A"" \"0123456789\": \"digit\"," + "\x0A"" \"special\": \"`1~!@#$%^&*()_+-={':[,]}|;.</>?\",\x0A"" \"he" + "x\": \"\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A\",\x0A"" \"true\": true," + "\x0A"" \"false\": false,\x0A"" \"null\": null,\x0A"" \"array" + "\":[ ],\x0A"" \"object\":{ },\x0A"" \"address\": \"50 St. James S" + "treet\",\x0A"" \"url\": \"http://www.JSON.org/\",\x0A"" \"comment\"" + ": \"// /* <!-- --\",\x0A"" \"# -- --> */\": \" \",\x0A"" \" s p a c" + " e d \" :[1,2 , 3\x0A""\x0A"",\x0A""\x0A""4 , 5 , 6 ,7 " + " ],\"compact\":[1,2,3,4,5,6,7],\x0A"" \"jsontext\": \"{\\\"object wi" + "th 1 member\\\":[\\\"array with 1 element\\\"]}\",\x0A"" \"quotes\": \"" + "4; \\u0022 %22 0x22 034 "\",\x0A"" \"\\/\\\\\\\"\\uCAFE\\uBABE\\uAB98" + "\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?\"\x0A"": \"A " + "key can be any string\"\x0A"" },\x0A"" 0.5 ,98.6\x0A"",\x0A""99.44\x0A"",\x0A""" + "\x0A""1066,\x0A""1e1,\x0A""0.1e1,\x0A""1e-1,\x0A""1e00,2e+00,2e-00\x0A"",\"rosebu" + "d\"]") }, + { 'y', "pass02", lit("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]") }, + { 'y', "pass03", lit("{\x0A"" \"JSON Test Pattern pass3\": {\x0A"" \"The outermost value\": " + "\"must be an object or array.\",\x0A"" \"In this test\": \"It is an object" + ".\"\x0A"" }\x0A""}\x0A""") }, + { 'y', "string_1_2_3_bytes_UTF-8_sequences", lit("[\"\\u0060\\u012a\\u12AB\"]") }, + { 'y', "string_accepted_surrogate_pair", lit("[\"\\uD801\\udc37\"]") }, + { 'y', "string_accepted_surrogate_pairs", lit("[\"\\ud83d\\ude39\\ud83d\\udc8d\"]") }, + { 'y', "string_allowed_escapes", lit("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]") }, + { 'y', "string_backslash_and_u_escaped_zero", lit("[\"\\\\u0000\"]") }, + { 'y', "string_backslash_doublequotes", lit("[\"\\\"\"]") }, + { 'y', "string_comments", lit("[\"a/*b*/c/*d//e\"]") }, + { 'y', "string_double_escape_a", lit("[\"\\\\a\"]") }, + { 'y', "string_double_escape_n", lit("[\"\\\\n\"]") }, + { 'y', "string_escaped_control_character", lit("[\"\\u0012\"]") }, + { 'y', "string_escaped_noncharacter", lit("[\"\\uFFFF\"]") }, + { 'y', "string_in_array", lit("[\"asd\"]") }, + { 'y', "string_in_array_with_leading_space", lit("[ \"asd\"]") }, + { 'y', "string_last_surrogates_1_and_2", lit("[\"\\uDBFF\\uDFFF\"]") }, + { 'y', "string_nbsp_uescaped", lit("[\"new\\u00A0line\"]") }, + { 'y', "string_nonCharacterInUTF-8_U+10FFFF", lit("[\"\xF4""\x8F""\xBF""\xBF""\"]") }, + { 'y', "string_nonCharacterInUTF-8_U+FFFF", lit("[\"\xEF""\xBF""\xBF""\"]") }, + { 'y', "string_null_escape", lit("[\"\\u0000\"]") }, + { 'y', "string_one-byte-utf-8", lit("[\"\\u002c\"]") }, + { 'y', "string_pi", lit("[\"\xCF""\x80""\"]") }, + { 'y', "string_reservedCharacterInUTF-8_U+1BFFF", lit("[\"\xF0""\x9B""\xBF""\xBF""\"]") }, + { 'y', "string_simple_ascii", lit("[\"asd \"]") }, + { 'y', "string_space", lit("\" \"") }, + { 'y', "string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF", lit("[\"\\uD834\\uDd1e\"]") }, + { 'y', "string_three-byte-utf-8", lit("[\"\\u0821\"]") }, + { 'y', "string_two-byte-utf-8", lit("[\"\\u0123\"]") }, + { 'y', "string_u+2028_line_sep", lit("[\"\xE2""\x80""\xA8""\"]") }, + { 'y', "string_u+2029_par_sep", lit("[\"\xE2""\x80""\xA9""\"]") }, + { 'y', "string_uEscape", lit("[\"\\u0061\\u30af\\u30EA\\u30b9\"]") }, + { 'y', "string_uescaped_newline", lit("[\"new\\u000Aline\"]") }, + { 'y', "string_unescaped_char_delete", lit("[\"\"]") }, + { 'y', "string_unicode", lit("[\"\\uA66D\"]") }, + { 'y', "string_unicodeEscapedBackslash", lit("[\"\\u005C\"]") }, + { 'y', "string_unicode_2", lit("[\"\xE2""\x8D""\x82""\xE3""\x88""\xB4""\xE2""\x8D""\x82""\"]") }, + { 'y', "string_unicode_escaped_double_quote", lit("[\"\\u0022\"]") }, + { 'y', "string_unicode_U+10FFFE_nonchar", lit("[\"\\uDBFF\\uDFFE\"]") }, + { 'y', "string_unicode_U+1FFFE_nonchar", lit("[\"\\uD83F\\uDFFE\"]") }, + { 'y', "string_unicode_U+200B_ZERO_WIDTH_SPACE", lit("[\"\\u200B\"]") }, + { 'y', "string_unicode_U+2064_invisible_plus", lit("[\"\\u2064\"]") }, + { 'y', "string_unicode_U+FDD0_nonchar", lit("[\"\\uFDD0\"]") }, + { 'y', "string_unicode_U+FFFE_nonchar", lit("[\"\\uFFFE\"]") }, + { 'y', "string_utf8", lit("[\"\xE2""\x82""\xAC""\xF0""\x9D""\x84""\x9E""\"]") }, + { 'y', "string_with_del_character", lit("[\"aa\"]") }, + { 'y', "structure_lonely_false", lit("false") }, + { 'y', "structure_lonely_int", lit("42") }, + { 'y', "structure_lonely_negative_real", lit("-0.1") }, + { 'y', "structure_lonely_null", lit("null") }, + { 'y', "structure_lonely_string", lit("\"asd\"") }, + { 'y', "structure_lonely_true", lit("true") }, + { 'y', "structure_string_empty", lit("\"\"") }, + { 'y', "structure_trailing_newline", lit("[\"a\"]\x0A""") }, + { 'y', "structure_true_in_array", lit("[true]") }, + { 'y', "structure_whitespace_array", lit(" [] ") }, + { ' ', "", "" } + }; + first_ = &list[0]; + last_ = &list[std::extent< + decltype(list)>::value - 1]; +} + +BOOST_JSON_NS_END + +#endif diff --git a/src/boost/libs/json/test/parse-vectors/i_number_double_huge_neg_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_double_huge_neg_exp.json new file mode 100644 index 000000000..ae4c7b71f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_double_huge_neg_exp.json @@ -0,0 +1 @@ +[123.456e-789]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_huge_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_huge_exp.json new file mode 100644 index 000000000..9b5efa236 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_huge_exp.json @@ -0,0 +1 @@ +[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_neg_int_huge_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_neg_int_huge_exp.json new file mode 100644 index 000000000..3abd58a5c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_neg_int_huge_exp.json @@ -0,0 +1 @@ +[-1e+9999]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_pos_double_huge_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_pos_double_huge_exp.json new file mode 100644 index 000000000..e10a7eb62 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_pos_double_huge_exp.json @@ -0,0 +1 @@ +[1.5e+9999]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_real_neg_overflow.json b/src/boost/libs/json/test/parse-vectors/i_number_real_neg_overflow.json new file mode 100644 index 000000000..3d628a994 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_real_neg_overflow.json @@ -0,0 +1 @@ +[-123123e100000]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_real_pos_overflow.json b/src/boost/libs/json/test/parse-vectors/i_number_real_pos_overflow.json new file mode 100644 index 000000000..54d7d3dcd --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_real_pos_overflow.json @@ -0,0 +1 @@ +[123123e100000]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_real_underflow.json b/src/boost/libs/json/test/parse-vectors/i_number_real_underflow.json new file mode 100644 index 000000000..c5236eb26 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_real_underflow.json @@ -0,0 +1 @@ +[123e-10000000]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_too_big_neg_int.json b/src/boost/libs/json/test/parse-vectors/i_number_too_big_neg_int.json new file mode 100644 index 000000000..dfa384619 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_too_big_neg_int.json @@ -0,0 +1 @@ +[-123123123123123123123123123123]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_too_big_pos_int.json b/src/boost/libs/json/test/parse-vectors/i_number_too_big_pos_int.json new file mode 100644 index 000000000..338a8c3c0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_too_big_pos_int.json @@ -0,0 +1 @@ +[100000000000000000000]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_number_very_big_negative_int.json b/src/boost/libs/json/test/parse-vectors/i_number_very_big_negative_int.json new file mode 100644 index 000000000..e2d9738c2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_number_very_big_negative_int.json @@ -0,0 +1 @@ +[-237462374673276894279832749832423479823246327846]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_object_key_lone_2nd_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_object_key_lone_2nd_surrogate.json new file mode 100644 index 000000000..5be7ebaf9 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_object_key_lone_2nd_surrogate.json @@ -0,0 +1 @@ +{"\uDFAA":0}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_1st_surrogate_but_2nd_missing.json b/src/boost/libs/json/test/parse-vectors/i_string_1st_surrogate_but_2nd_missing.json new file mode 100644 index 000000000..3b9e37c67 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_1st_surrogate_but_2nd_missing.json @@ -0,0 +1 @@ +["\uDADA"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_1st_valid_surrogate_2nd_invalid.json b/src/boost/libs/json/test/parse-vectors/i_string_1st_valid_surrogate_2nd_invalid.json new file mode 100644 index 000000000..487592832 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_1st_valid_surrogate_2nd_invalid.json @@ -0,0 +1 @@ +["\uD888\u1234"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_UTF-16LE_with_BOM.json b/src/boost/libs/json/test/parse-vectors/i_string_UTF-16LE_with_BOM.json Binary files differnew file mode 100644 index 000000000..2a79c0629 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_UTF-16LE_with_BOM.json diff --git a/src/boost/libs/json/test/parse-vectors/i_string_UTF-8_invalid_sequence.json b/src/boost/libs/json/test/parse-vectors/i_string_UTF-8_invalid_sequence.json new file mode 100644 index 000000000..e2a968a15 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_UTF-8_invalid_sequence.json @@ -0,0 +1 @@ +["日шú"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_UTF8_surrogate_U+D800.json b/src/boost/libs/json/test/parse-vectors/i_string_UTF8_surrogate_U+D800.json new file mode 100644 index 000000000..916bff920 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_UTF8_surrogate_U+D800.json @@ -0,0 +1 @@ +["í €"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_and_escape_valid.json b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_and_escape_valid.json new file mode 100644 index 000000000..3cb11d229 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_and_escape_valid.json @@ -0,0 +1 @@ +["\uD800\n"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_pair.json b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_pair.json new file mode 100644 index 000000000..38ec23bb0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_pair.json @@ -0,0 +1 @@ +["\uDd1ea"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogates_escape_valid.json b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogates_escape_valid.json new file mode 100644 index 000000000..c9cd6f6c3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogates_escape_valid.json @@ -0,0 +1 @@ +["\uD800\uD800\n"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_invalid_lonely_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_string_invalid_lonely_surrogate.json new file mode 100644 index 000000000..3abbd8d8d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_invalid_lonely_surrogate.json @@ -0,0 +1 @@ +["\ud800"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_invalid_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_string_invalid_surrogate.json new file mode 100644 index 000000000..ffddc04f5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_invalid_surrogate.json @@ -0,0 +1 @@ +["\ud800abc"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_invalid_utf-8.json b/src/boost/libs/json/test/parse-vectors/i_string_invalid_utf-8.json new file mode 100644 index 000000000..8e45a7eca --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_invalid_utf-8.json @@ -0,0 +1 @@ +["ÿ"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_inverted_surrogates_U+1D11E.json b/src/boost/libs/json/test/parse-vectors/i_string_inverted_surrogates_U+1D11E.json new file mode 100644 index 000000000..0d5456cc3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_inverted_surrogates_U+1D11E.json @@ -0,0 +1 @@ +["\uDd1e\uD834"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_iso_latin_1.json b/src/boost/libs/json/test/parse-vectors/i_string_iso_latin_1.json new file mode 100644 index 000000000..9389c9823 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_iso_latin_1.json @@ -0,0 +1 @@ +["é"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_lone_second_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_string_lone_second_surrogate.json new file mode 100644 index 000000000..1dbd397f3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_lone_second_surrogate.json @@ -0,0 +1 @@ +["\uDFAA"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_lone_utf8_continuation_byte.json b/src/boost/libs/json/test/parse-vectors/i_string_lone_utf8_continuation_byte.json new file mode 100644 index 000000000..729337c0a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_lone_utf8_continuation_byte.json @@ -0,0 +1 @@ +[""]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_not_in_unicode_range.json b/src/boost/libs/json/test/parse-vectors/i_string_not_in_unicode_range.json new file mode 100644 index 000000000..df90a2916 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_not_in_unicode_range.json @@ -0,0 +1 @@ +["ô¿¿¿"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_2_bytes.json b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_2_bytes.json new file mode 100644 index 000000000..c8cee5e0a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_2_bytes.json @@ -0,0 +1 @@ +["À¯"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes.json b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes.json new file mode 100644 index 000000000..9a91da791 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes.json @@ -0,0 +1 @@ +["üƒ¿¿¿¿"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes_null.json b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes_null.json new file mode 100644 index 000000000..d24fffdd9 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes_null.json @@ -0,0 +1 @@ +["ü€€€€€"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_truncated-utf-8.json b/src/boost/libs/json/test/parse-vectors/i_string_truncated-utf-8.json new file mode 100644 index 000000000..63c7777fb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_truncated-utf-8.json @@ -0,0 +1 @@ +["àÿ"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_string_utf16BE_no_BOM.json b/src/boost/libs/json/test/parse-vectors/i_string_utf16BE_no_BOM.json Binary files differnew file mode 100644 index 000000000..57e5392ff --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_utf16BE_no_BOM.json diff --git a/src/boost/libs/json/test/parse-vectors/i_string_utf16LE_no_BOM.json b/src/boost/libs/json/test/parse-vectors/i_string_utf16LE_no_BOM.json Binary files differnew file mode 100644 index 000000000..c49c1b25d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_string_utf16LE_no_BOM.json diff --git a/src/boost/libs/json/test/parse-vectors/i_structure_500_nested_arrays.json b/src/boost/libs/json/test/parse-vectors/i_structure_500_nested_arrays.json new file mode 100644 index 000000000..711840589 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_structure_500_nested_arrays.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/i_structure_UTF-8_BOM_empty_object.json b/src/boost/libs/json/test/parse-vectors/i_structure_UTF-8_BOM_empty_object.json new file mode 100644 index 000000000..22fdca1b2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/i_structure_UTF-8_BOM_empty_object.json @@ -0,0 +1 @@ +{}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_1_true_without_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_1_true_without_comma.json new file mode 100644 index 000000000..c14e3f6b1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_1_true_without_comma.json @@ -0,0 +1 @@ +[1 true]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_a_invalid_utf8.json b/src/boost/libs/json/test/parse-vectors/n_array_a_invalid_utf8.json new file mode 100644 index 000000000..38a86e2e6 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_a_invalid_utf8.json @@ -0,0 +1 @@ +[aå]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_colon_instead_of_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_colon_instead_of_comma.json new file mode 100644 index 000000000..0d02ad448 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_colon_instead_of_comma.json @@ -0,0 +1 @@ +["": 1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_comma_after_close.json b/src/boost/libs/json/test/parse-vectors/n_array_comma_after_close.json new file mode 100644 index 000000000..2ccba8d95 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_comma_after_close.json @@ -0,0 +1 @@ +[""],
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_comma_and_number.json b/src/boost/libs/json/test/parse-vectors/n_array_comma_and_number.json new file mode 100644 index 000000000..d2c84e374 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_comma_and_number.json @@ -0,0 +1 @@ +[,1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_double_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_double_comma.json new file mode 100644 index 000000000..0431712bc --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_double_comma.json @@ -0,0 +1 @@ +[1,,2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_double_extra_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_double_extra_comma.json new file mode 100644 index 000000000..3f01d3129 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_double_extra_comma.json @@ -0,0 +1 @@ +["x",,]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_extra_close.json b/src/boost/libs/json/test/parse-vectors/n_array_extra_close.json new file mode 100644 index 000000000..c12f9fae1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_extra_close.json @@ -0,0 +1 @@ +["x"]]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_extra_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_extra_comma.json new file mode 100644 index 000000000..5f8ce18e4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_extra_comma.json @@ -0,0 +1 @@ +["",]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_incomplete.json b/src/boost/libs/json/test/parse-vectors/n_array_incomplete.json new file mode 100644 index 000000000..cc65b0b51 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_incomplete.json @@ -0,0 +1 @@ +["x"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_incomplete_invalid_value.json b/src/boost/libs/json/test/parse-vectors/n_array_incomplete_invalid_value.json new file mode 100644 index 000000000..c21a8f6cf --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_incomplete_invalid_value.json @@ -0,0 +1 @@ +[x
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_inner_array_no_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_inner_array_no_comma.json new file mode 100644 index 000000000..c70b71647 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_inner_array_no_comma.json @@ -0,0 +1 @@ +[3[4]]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_invalid_utf8.json b/src/boost/libs/json/test/parse-vectors/n_array_invalid_utf8.json new file mode 100644 index 000000000..6099d3441 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_invalid_utf8.json @@ -0,0 +1 @@ +[ÿ]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_items_separated_by_semicolon.json b/src/boost/libs/json/test/parse-vectors/n_array_items_separated_by_semicolon.json new file mode 100644 index 000000000..d4bd7314c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_items_separated_by_semicolon.json @@ -0,0 +1 @@ +[1:2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_just_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_just_comma.json new file mode 100644 index 000000000..9d7077c68 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_just_comma.json @@ -0,0 +1 @@ +[,]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_just_minus.json b/src/boost/libs/json/test/parse-vectors/n_array_just_minus.json new file mode 100644 index 000000000..29501c6ca --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_just_minus.json @@ -0,0 +1 @@ +[-]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_missing_value.json b/src/boost/libs/json/test/parse-vectors/n_array_missing_value.json new file mode 100644 index 000000000..3a6ba86f3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_missing_value.json @@ -0,0 +1 @@ +[ , ""]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_newlines_unclosed.json b/src/boost/libs/json/test/parse-vectors/n_array_newlines_unclosed.json new file mode 100644 index 000000000..646680065 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_newlines_unclosed.json @@ -0,0 +1,3 @@ +["a", +4 +,1,
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_number_and_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_number_and_comma.json new file mode 100644 index 000000000..13f6f1d18 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_number_and_comma.json @@ -0,0 +1 @@ +[1,]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_number_and_several_commas.json b/src/boost/libs/json/test/parse-vectors/n_array_number_and_several_commas.json new file mode 100644 index 000000000..0ac408cb8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_number_and_several_commas.json @@ -0,0 +1 @@ +[1,,]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_spaces_vertical_tab_formfeed.json b/src/boost/libs/json/test/parse-vectors/n_array_spaces_vertical_tab_formfeed.json new file mode 100644 index 000000000..6cd7cf585 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_spaces_vertical_tab_formfeed.json @@ -0,0 +1 @@ +["a"\f]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_star_inside.json b/src/boost/libs/json/test/parse-vectors/n_array_star_inside.json new file mode 100644 index 000000000..5a5194647 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_star_inside.json @@ -0,0 +1 @@ +[*]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed.json new file mode 100644 index 000000000..060733059 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed.json @@ -0,0 +1 @@ +[""
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed_trailing_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_trailing_comma.json new file mode 100644 index 000000000..6604698ff --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_trailing_comma.json @@ -0,0 +1 @@ +[1,
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_new_lines.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_new_lines.json new file mode 100644 index 000000000..4f61de3fb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_new_lines.json @@ -0,0 +1,3 @@ +[1, +1 +,1
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_object_inside.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_object_inside.json new file mode 100644 index 000000000..043a87e2d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_object_inside.json @@ -0,0 +1 @@ +[{}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail01.json b/src/boost/libs/json/test/parse-vectors/n_fail01.json new file mode 100644 index 000000000..ca5eb19dc --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail01.json @@ -0,0 +1 @@ +["mismatch"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail02.json b/src/boost/libs/json/test/parse-vectors/n_fail02.json new file mode 100644 index 000000000..6b7c11e5a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail02.json @@ -0,0 +1 @@ +["Unclosed array"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail03.json b/src/boost/libs/json/test/parse-vectors/n_fail03.json new file mode 100644 index 000000000..168c81eb7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail03.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail04.json b/src/boost/libs/json/test/parse-vectors/n_fail04.json new file mode 100644 index 000000000..9de168bf3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail04.json @@ -0,0 +1 @@ +["extra comma",]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail05.json b/src/boost/libs/json/test/parse-vectors/n_fail05.json new file mode 100644 index 000000000..ddf3ce3d2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail05.json @@ -0,0 +1 @@ +["double extra comma",,]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail06.json b/src/boost/libs/json/test/parse-vectors/n_fail06.json new file mode 100644 index 000000000..ed91580e1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail06.json @@ -0,0 +1 @@ +[ , "<-- missing value"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail07.json b/src/boost/libs/json/test/parse-vectors/n_fail07.json new file mode 100644 index 000000000..8a96af3e4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail07.json @@ -0,0 +1 @@ +["Comma after the close"],
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail08.json b/src/boost/libs/json/test/parse-vectors/n_fail08.json new file mode 100644 index 000000000..b28479c6e --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail08.json @@ -0,0 +1 @@ +["Extra close"]]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail09.json b/src/boost/libs/json/test/parse-vectors/n_fail09.json new file mode 100644 index 000000000..5815574f3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail09.json @@ -0,0 +1 @@ +{"Extra comma": true,}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail10.json b/src/boost/libs/json/test/parse-vectors/n_fail10.json new file mode 100644 index 000000000..5d8c0047b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail11.json b/src/boost/libs/json/test/parse-vectors/n_fail11.json new file mode 100644 index 000000000..76eb95b45 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail12.json b/src/boost/libs/json/test/parse-vectors/n_fail12.json new file mode 100644 index 000000000..77580a452 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail13.json b/src/boost/libs/json/test/parse-vectors/n_fail13.json new file mode 100644 index 000000000..379406b59 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail14.json b/src/boost/libs/json/test/parse-vectors/n_fail14.json new file mode 100644 index 000000000..0ed366b38 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail15.json b/src/boost/libs/json/test/parse-vectors/n_fail15.json new file mode 100644 index 000000000..fc8376b60 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail16.json b/src/boost/libs/json/test/parse-vectors/n_fail16.json new file mode 100644 index 000000000..3fe21d4b5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail16.json @@ -0,0 +1 @@ +[\naked]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail17.json b/src/boost/libs/json/test/parse-vectors/n_fail17.json new file mode 100644 index 000000000..62b9214ae --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail19.json b/src/boost/libs/json/test/parse-vectors/n_fail19.json new file mode 100644 index 000000000..3b9c46fa9 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail19.json @@ -0,0 +1 @@ +{"Missing colon" null}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail20.json b/src/boost/libs/json/test/parse-vectors/n_fail20.json new file mode 100644 index 000000000..27c1af3e7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail20.json @@ -0,0 +1 @@ +{"Double colon":: null}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail21.json b/src/boost/libs/json/test/parse-vectors/n_fail21.json new file mode 100644 index 000000000..62474573b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail22.json b/src/boost/libs/json/test/parse-vectors/n_fail22.json new file mode 100644 index 000000000..a7752581b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail23.json b/src/boost/libs/json/test/parse-vectors/n_fail23.json new file mode 100644 index 000000000..494add1ca --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail23.json @@ -0,0 +1 @@ +["Bad value", truth]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail24.json b/src/boost/libs/json/test/parse-vectors/n_fail24.json new file mode 100644 index 000000000..caff239bf --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail24.json @@ -0,0 +1 @@ +['single quote']
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail25.json b/src/boost/libs/json/test/parse-vectors/n_fail25.json new file mode 100644 index 000000000..8b7ad23e0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail25.json @@ -0,0 +1 @@ +[" tab character in string "]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail26.json b/src/boost/libs/json/test/parse-vectors/n_fail26.json new file mode 100644 index 000000000..845d26a6a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail27.json b/src/boost/libs/json/test/parse-vectors/n_fail27.json new file mode 100644 index 000000000..6b01a2ca4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail27.json @@ -0,0 +1,2 @@ +["line +break"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail28.json b/src/boost/libs/json/test/parse-vectors/n_fail28.json new file mode 100644 index 000000000..621a0101c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail28.json @@ -0,0 +1,2 @@ +["line\ +break"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail29.json b/src/boost/libs/json/test/parse-vectors/n_fail29.json new file mode 100644 index 000000000..47ec421bb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail29.json @@ -0,0 +1 @@ +[0e]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail30.json b/src/boost/libs/json/test/parse-vectors/n_fail30.json new file mode 100644 index 000000000..8ab0bc4b8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail30.json @@ -0,0 +1 @@ +[0e+]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail31.json b/src/boost/libs/json/test/parse-vectors/n_fail31.json new file mode 100644 index 000000000..1cce602b5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail31.json @@ -0,0 +1 @@ +[0e+-1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_fail32.json b/src/boost/libs/json/test/parse-vectors/n_fail32.json new file mode 100644 index 000000000..45cba7396 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true,
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_incomplete_false.json b/src/boost/libs/json/test/parse-vectors/n_incomplete_false.json new file mode 100644 index 000000000..eb18c6a14 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_incomplete_false.json @@ -0,0 +1 @@ +[fals]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_incomplete_null.json b/src/boost/libs/json/test/parse-vectors/n_incomplete_null.json new file mode 100644 index 000000000..c18ef5385 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_incomplete_null.json @@ -0,0 +1 @@ +[nul]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_incomplete_true.json b/src/boost/libs/json/test/parse-vectors/n_incomplete_true.json new file mode 100644 index 000000000..f451ac6d2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_incomplete_true.json @@ -0,0 +1 @@ +[tru]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_multidigit_number_then_00.json b/src/boost/libs/json/test/parse-vectors/n_multidigit_number_then_00.json Binary files differnew file mode 100644 index 000000000..c22507b86 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_multidigit_number_then_00.json diff --git a/src/boost/libs/json/test/parse-vectors/n_number_++.json b/src/boost/libs/json/test/parse-vectors/n_number_++.json new file mode 100644 index 000000000..bdb62aaf4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_++.json @@ -0,0 +1 @@ +[++1234]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_+1.json b/src/boost/libs/json/test/parse-vectors/n_number_+1.json new file mode 100644 index 000000000..3cbe58c92 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_+1.json @@ -0,0 +1 @@ +[+1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_+Inf.json b/src/boost/libs/json/test/parse-vectors/n_number_+Inf.json new file mode 100644 index 000000000..871ae14d5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_+Inf.json @@ -0,0 +1 @@ +[+Inf]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-01.json b/src/boost/libs/json/test/parse-vectors/n_number_-01.json new file mode 100644 index 000000000..0df32bac8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_-01.json @@ -0,0 +1 @@ +[-01]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-1.0..json b/src/boost/libs/json/test/parse-vectors/n_number_-1.0..json new file mode 100644 index 000000000..7cf55a85a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_-1.0..json @@ -0,0 +1 @@ +[-1.0.]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-2..json b/src/boost/libs/json/test/parse-vectors/n_number_-2..json new file mode 100644 index 000000000..9be84365d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_-2..json @@ -0,0 +1 @@ +[-2.]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-NaN.json b/src/boost/libs/json/test/parse-vectors/n_number_-NaN.json new file mode 100644 index 000000000..f61615d40 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_-NaN.json @@ -0,0 +1 @@ +[-NaN]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_.-1.json b/src/boost/libs/json/test/parse-vectors/n_number_.-1.json new file mode 100644 index 000000000..1c9f2dd1b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_.-1.json @@ -0,0 +1 @@ +[.-1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_.2e-3.json b/src/boost/libs/json/test/parse-vectors/n_number_.2e-3.json new file mode 100644 index 000000000..c6c976f25 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_.2e-3.json @@ -0,0 +1 @@ +[.2e-3]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.1.2.json b/src/boost/libs/json/test/parse-vectors/n_number_0.1.2.json new file mode 100644 index 000000000..c83a25621 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0.1.2.json @@ -0,0 +1 @@ +[0.1.2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.3e+.json b/src/boost/libs/json/test/parse-vectors/n_number_0.3e+.json new file mode 100644 index 000000000..a55a1bfef --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0.3e+.json @@ -0,0 +1 @@ +[0.3e+]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.3e.json b/src/boost/libs/json/test/parse-vectors/n_number_0.3e.json new file mode 100644 index 000000000..3dd5df4b3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0.3e.json @@ -0,0 +1 @@ +[0.3e]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.e1.json b/src/boost/libs/json/test/parse-vectors/n_number_0.e1.json new file mode 100644 index 000000000..c92c71ccb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0.e1.json @@ -0,0 +1 @@ +[0.e1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E+.json b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E+.json new file mode 100644 index 000000000..3ba2c7d6d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E+.json @@ -0,0 +1 @@ +[0E+]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E.json b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E.json new file mode 100644 index 000000000..5301840d1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E.json @@ -0,0 +1 @@ +[0E]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0e+.json b/src/boost/libs/json/test/parse-vectors/n_number_0e+.json new file mode 100644 index 000000000..8ab0bc4b8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0e+.json @@ -0,0 +1 @@ +[0e+]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0e.json b/src/boost/libs/json/test/parse-vectors/n_number_0e.json new file mode 100644 index 000000000..47ec421bb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_0e.json @@ -0,0 +1 @@ +[0e]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1.0e+.json b/src/boost/libs/json/test/parse-vectors/n_number_1.0e+.json new file mode 100644 index 000000000..cd84b9f69 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_1.0e+.json @@ -0,0 +1 @@ +[1.0e+]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1.0e-.json b/src/boost/libs/json/test/parse-vectors/n_number_1.0e-.json new file mode 100644 index 000000000..4eb7afa0f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_1.0e-.json @@ -0,0 +1 @@ +[1.0e-]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1.0e.json b/src/boost/libs/json/test/parse-vectors/n_number_1.0e.json new file mode 100644 index 000000000..21753f4c7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_1.0e.json @@ -0,0 +1 @@ +[1.0e]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1_000.json b/src/boost/libs/json/test/parse-vectors/n_number_1_000.json new file mode 100644 index 000000000..7b18b66b3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_1_000.json @@ -0,0 +1 @@ +[1 000.0]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1eE2.json b/src/boost/libs/json/test/parse-vectors/n_number_1eE2.json new file mode 100644 index 000000000..4318a341d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_1eE2.json @@ -0,0 +1 @@ +[1eE2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_2.e+3.json b/src/boost/libs/json/test/parse-vectors/n_number_2.e+3.json new file mode 100644 index 000000000..4442f394d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_2.e+3.json @@ -0,0 +1 @@ +[2.e+3]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_2.e-3.json b/src/boost/libs/json/test/parse-vectors/n_number_2.e-3.json new file mode 100644 index 000000000..a65060edf --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_2.e-3.json @@ -0,0 +1 @@ +[2.e-3]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_2.e3.json b/src/boost/libs/json/test/parse-vectors/n_number_2.e3.json new file mode 100644 index 000000000..66f7cf701 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_2.e3.json @@ -0,0 +1 @@ +[2.e3]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_9.e+.json b/src/boost/libs/json/test/parse-vectors/n_number_9.e+.json new file mode 100644 index 000000000..732a7b11c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_9.e+.json @@ -0,0 +1 @@ +[9.e+]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_Inf.json b/src/boost/libs/json/test/parse-vectors/n_number_Inf.json new file mode 100644 index 000000000..c40c734c3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_Inf.json @@ -0,0 +1 @@ +[Inf]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_NaN.json b/src/boost/libs/json/test/parse-vectors/n_number_NaN.json new file mode 100644 index 000000000..499231790 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_NaN.json @@ -0,0 +1 @@ +[NaN]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_U+FF11_fullwidth_digit_one.json b/src/boost/libs/json/test/parse-vectors/n_number_U+FF11_fullwidth_digit_one.json new file mode 100644 index 000000000..b14587e5e --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_U+FF11_fullwidth_digit_one.json @@ -0,0 +1 @@ +[1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_expression.json b/src/boost/libs/json/test/parse-vectors/n_number_expression.json new file mode 100644 index 000000000..76fdbc8a4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_expression.json @@ -0,0 +1 @@ +[1+2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_hex_1_digit.json b/src/boost/libs/json/test/parse-vectors/n_number_hex_1_digit.json new file mode 100644 index 000000000..3b214880c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_hex_1_digit.json @@ -0,0 +1 @@ +[0x1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_hex_2_digits.json b/src/boost/libs/json/test/parse-vectors/n_number_hex_2_digits.json new file mode 100644 index 000000000..83e516ab0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_hex_2_digits.json @@ -0,0 +1 @@ +[0x42]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_infinity.json b/src/boost/libs/json/test/parse-vectors/n_number_infinity.json new file mode 100644 index 000000000..8c2baf783 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_infinity.json @@ -0,0 +1 @@ +[Infinity]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid+-.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid+-.json new file mode 100644 index 000000000..1cce602b5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid+-.json @@ -0,0 +1 @@ +[0e+-1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-negative-real.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-negative-real.json new file mode 100644 index 000000000..5fc3c1efb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-negative-real.json @@ -0,0 +1 @@ +[-123.123foo]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-bigger-int.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-bigger-int.json new file mode 100644 index 000000000..3b97e580e --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-bigger-int.json @@ -0,0 +1 @@ +[123å]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-exponent.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-exponent.json new file mode 100644 index 000000000..ea35d723c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-exponent.json @@ -0,0 +1 @@ +[1e1å]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-int.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-int.json new file mode 100644 index 000000000..371226e4c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-int.json @@ -0,0 +1 @@ +[0å] diff --git a/src/boost/libs/json/test/parse-vectors/n_number_minus_infinity.json b/src/boost/libs/json/test/parse-vectors/n_number_minus_infinity.json new file mode 100644 index 000000000..cf4133d22 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_minus_infinity.json @@ -0,0 +1 @@ +[-Infinity]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_minus_sign_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_number_minus_sign_with_trailing_garbage.json new file mode 100644 index 000000000..a6d8e78e7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_minus_sign_with_trailing_garbage.json @@ -0,0 +1 @@ +[-foo]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_minus_space_1.json b/src/boost/libs/json/test/parse-vectors/n_number_minus_space_1.json new file mode 100644 index 000000000..9a5ebedf6 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_minus_space_1.json @@ -0,0 +1 @@ +[- 1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_neg_int_starting_with_zero.json b/src/boost/libs/json/test/parse-vectors/n_number_neg_int_starting_with_zero.json new file mode 100644 index 000000000..67af0960a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_neg_int_starting_with_zero.json @@ -0,0 +1 @@ +[-012]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_neg_real_without_int_part.json b/src/boost/libs/json/test/parse-vectors/n_number_neg_real_without_int_part.json new file mode 100644 index 000000000..1f2a43496 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_neg_real_without_int_part.json @@ -0,0 +1 @@ +[-.123]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_neg_with_garbage_at_end.json b/src/boost/libs/json/test/parse-vectors/n_number_neg_with_garbage_at_end.json new file mode 100644 index 000000000..2aa73119f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_neg_with_garbage_at_end.json @@ -0,0 +1 @@ +[-1x]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_real_garbage_after_e.json b/src/boost/libs/json/test/parse-vectors/n_number_real_garbage_after_e.json new file mode 100644 index 000000000..9213dfca8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_real_garbage_after_e.json @@ -0,0 +1 @@ +[1ea]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_real_with_invalid_utf8_after_e.json b/src/boost/libs/json/test/parse-vectors/n_number_real_with_invalid_utf8_after_e.json new file mode 100644 index 000000000..1e52ef964 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_real_with_invalid_utf8_after_e.json @@ -0,0 +1 @@ +[1eå]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_real_without_fractional_part.json b/src/boost/libs/json/test/parse-vectors/n_number_real_without_fractional_part.json new file mode 100644 index 000000000..1de287cf8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_real_without_fractional_part.json @@ -0,0 +1 @@ +[1.]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_starting_with_dot.json b/src/boost/libs/json/test/parse-vectors/n_number_starting_with_dot.json new file mode 100644 index 000000000..f682dbdce --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_starting_with_dot.json @@ -0,0 +1 @@ +[.123]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_with_alpha.json b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha.json new file mode 100644 index 000000000..1e42d8182 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha.json @@ -0,0 +1 @@ +[1.2a-3]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_with_alpha_char.json b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha_char.json new file mode 100644 index 000000000..b79daccb8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha_char.json @@ -0,0 +1 @@ +[1.8011670033376514H-308]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_number_with_leading_zero.json b/src/boost/libs/json/test/parse-vectors/n_number_with_leading_zero.json new file mode 100644 index 000000000..7106da1f3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_number_with_leading_zero.json @@ -0,0 +1 @@ +[012]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_bad_value.json b/src/boost/libs/json/test/parse-vectors/n_object_bad_value.json new file mode 100644 index 000000000..a03a8c03b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_bad_value.json @@ -0,0 +1 @@ +["x", truth]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_bracket_key.json b/src/boost/libs/json/test/parse-vectors/n_object_bracket_key.json new file mode 100644 index 000000000..cc443b483 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_bracket_key.json @@ -0,0 +1 @@ +{[: "x"} diff --git a/src/boost/libs/json/test/parse-vectors/n_object_comma_instead_of_colon.json b/src/boost/libs/json/test/parse-vectors/n_object_comma_instead_of_colon.json new file mode 100644 index 000000000..8d5637708 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_comma_instead_of_colon.json @@ -0,0 +1 @@ +{"x", null}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_double_colon.json b/src/boost/libs/json/test/parse-vectors/n_object_double_colon.json new file mode 100644 index 000000000..80e8c7b89 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_double_colon.json @@ -0,0 +1 @@ +{"x"::"b"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_emoji.json b/src/boost/libs/json/test/parse-vectors/n_object_emoji.json new file mode 100644 index 000000000..cb4078eaa --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_emoji.json @@ -0,0 +1 @@ +{🇨ðŸ‡}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_garbage_at_end.json b/src/boost/libs/json/test/parse-vectors/n_object_garbage_at_end.json new file mode 100644 index 000000000..80c42cbad --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_garbage_at_end.json @@ -0,0 +1 @@ +{"a":"a" 123}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_key_with_single_quotes.json b/src/boost/libs/json/test/parse-vectors/n_object_key_with_single_quotes.json new file mode 100644 index 000000000..77c327599 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_key_with_single_quotes.json @@ -0,0 +1 @@ +{key: 'value'}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_lone_continuation_byte_in_key_and_trailing_comma.json b/src/boost/libs/json/test/parse-vectors/n_object_lone_continuation_byte_in_key_and_trailing_comma.json new file mode 100644 index 000000000..aa2cb637c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_lone_continuation_byte_in_key_and_trailing_comma.json @@ -0,0 +1 @@ +{"¹":"0",}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_colon.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_colon.json new file mode 100644 index 000000000..b98eff62d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_colon.json @@ -0,0 +1 @@ +{"a" b}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_key.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_key.json new file mode 100644 index 000000000..b4fb0f528 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_key.json @@ -0,0 +1 @@ +{:"b"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_semicolon.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_semicolon.json new file mode 100644 index 000000000..e3451384f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_semicolon.json @@ -0,0 +1 @@ +{"a" "b"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_value.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_value.json new file mode 100644 index 000000000..3ef538a60 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_value.json @@ -0,0 +1 @@ +{"a":
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_no-colon.json b/src/boost/libs/json/test/parse-vectors/n_object_no-colon.json new file mode 100644 index 000000000..f3797b357 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_no-colon.json @@ -0,0 +1 @@ +{"a"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_non_string_key.json b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key.json new file mode 100644 index 000000000..b9945b34b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key.json @@ -0,0 +1 @@ +{1:1}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_non_string_key_but_huge_number_instead.json b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key_but_huge_number_instead.json new file mode 100644 index 000000000..b37fa86c0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key_but_huge_number_instead.json @@ -0,0 +1 @@ +{9999E9999:1}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_repeated_null_null.json b/src/boost/libs/json/test/parse-vectors/n_object_repeated_null_null.json new file mode 100644 index 000000000..f7d2959d0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_repeated_null_null.json @@ -0,0 +1 @@ +{null:null,null:null}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_several_trailing_commas.json b/src/boost/libs/json/test/parse-vectors/n_object_several_trailing_commas.json new file mode 100644 index 000000000..3c9afe8dc --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_several_trailing_commas.json @@ -0,0 +1 @@ +{"id":0,,,,,}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_single_quote.json b/src/boost/libs/json/test/parse-vectors/n_object_single_quote.json new file mode 100644 index 000000000..e5cdf976a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_single_quote.json @@ -0,0 +1 @@ +{'a':0}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comma.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comma.json new file mode 100644 index 000000000..a4b025094 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comma.json @@ -0,0 +1 @@ +{"id":0,}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment.json new file mode 100644 index 000000000..a372c6553 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment.json @@ -0,0 +1 @@ +{"a":"b"}/**/
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_open.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_open.json new file mode 100644 index 000000000..d557f41ca --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_open.json @@ -0,0 +1 @@ +{"a":"b"}/**//
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open.json new file mode 100644 index 000000000..e335136c0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open.json @@ -0,0 +1 @@ +{"a":"b"}//
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open_incomplete.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open_incomplete.json new file mode 100644 index 000000000..d892e49f1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open_incomplete.json @@ -0,0 +1 @@ +{"a":"b"}/
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_two_commas_in_a_row.json b/src/boost/libs/json/test/parse-vectors/n_object_two_commas_in_a_row.json new file mode 100644 index 000000000..7c639ae64 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_two_commas_in_a_row.json @@ -0,0 +1 @@ +{"a":"b",,"c":"d"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_unquoted_key.json b/src/boost/libs/json/test/parse-vectors/n_object_unquoted_key.json new file mode 100644 index 000000000..8ba137293 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_unquoted_key.json @@ -0,0 +1 @@ +{a: "b"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_unterminated-value.json b/src/boost/libs/json/test/parse-vectors/n_object_unterminated-value.json new file mode 100644 index 000000000..7fe699a6a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_unterminated-value.json @@ -0,0 +1 @@ +{"a":"a
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_with_single_string.json b/src/boost/libs/json/test/parse-vectors/n_object_with_single_string.json new file mode 100644 index 000000000..d63f7fbb7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_with_single_string.json @@ -0,0 +1 @@ +{ "foo" : "bar", "a" }
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_object_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_object_with_trailing_garbage.json new file mode 100644 index 000000000..787c8f0a8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_object_with_trailing_garbage.json @@ -0,0 +1 @@ +{"a":"b"}#
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_single_space.json b/src/boost/libs/json/test/parse-vectors/n_single_space.json new file mode 100644 index 000000000..0519ecba6 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_single_space.json @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape.json new file mode 100644 index 000000000..acec66d8f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape.json @@ -0,0 +1 @@ +["\uD800\"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u.json new file mode 100644 index 000000000..e834b05e9 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u.json @@ -0,0 +1 @@ +["\uD800\u"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1.json new file mode 100644 index 000000000..a04cd3489 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1.json @@ -0,0 +1 @@ +["\uD800\u1"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1x.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1x.json new file mode 100644 index 000000000..bfbd23409 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1x.json @@ -0,0 +1 @@ +["\uD800\u1x"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_accentuated_char_no_quotes.json b/src/boost/libs/json/test/parse-vectors/n_string_accentuated_char_no_quotes.json new file mode 100644 index 000000000..fd6895693 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_accentuated_char_no_quotes.json @@ -0,0 +1 @@ +[é]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_backslash_00.json b/src/boost/libs/json/test/parse-vectors/n_string_backslash_00.json Binary files differnew file mode 100644 index 000000000..b5bf267b5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_backslash_00.json diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escape_x.json b/src/boost/libs/json/test/parse-vectors/n_string_escape_x.json new file mode 100644 index 000000000..fae291938 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_escape_x.json @@ -0,0 +1 @@ +["\x00"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escaped_backslash_bad.json b/src/boost/libs/json/test/parse-vectors/n_string_escaped_backslash_bad.json new file mode 100644 index 000000000..016fcb47e --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_escaped_backslash_bad.json @@ -0,0 +1 @@ +["\\\"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escaped_ctrl_char_tab.json b/src/boost/libs/json/test/parse-vectors/n_string_escaped_ctrl_char_tab.json new file mode 100644 index 000000000..f35ea382b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_escaped_ctrl_char_tab.json @@ -0,0 +1 @@ +["\ "]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escaped_emoji.json b/src/boost/libs/json/test/parse-vectors/n_string_escaped_emoji.json new file mode 100644 index 000000000..a27775421 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_escaped_emoji.json @@ -0,0 +1 @@ +["\🌀"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escape.json new file mode 100644 index 000000000..3415c33ca --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escape.json @@ -0,0 +1 @@ +["\"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escaped_character.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escaped_character.json new file mode 100644 index 000000000..0f2197ea2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escaped_character.json @@ -0,0 +1 @@ +["\u00A"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate.json new file mode 100644 index 000000000..75504a656 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate.json @@ -0,0 +1 @@ +["\uD834\uDd"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate_escape_invalid.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate_escape_invalid.json new file mode 100644 index 000000000..bd9656060 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate_escape_invalid.json @@ -0,0 +1 @@ +["\uD800\uD800\x"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid-utf-8-in-escape.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid-utf-8-in-escape.json new file mode 100644 index 000000000..0c4300643 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid-utf-8-in-escape.json @@ -0,0 +1 @@ +["\uå"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid_backslash_esc.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid_backslash_esc.json new file mode 100644 index 000000000..d1eb60921 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid_backslash_esc.json @@ -0,0 +1 @@ +["\a"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid_unicode_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid_unicode_escape.json new file mode 100644 index 000000000..7608cb6ba --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid_unicode_escape.json @@ -0,0 +1 @@ +["\uqqqq"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid_utf8_after_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid_utf8_after_escape.json new file mode 100644 index 000000000..2f757a25b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid_utf8_after_escape.json @@ -0,0 +1 @@ +["\å"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_leading_uescaped_thinspace.json b/src/boost/libs/json/test/parse-vectors/n_string_leading_uescaped_thinspace.json new file mode 100644 index 000000000..7b297c636 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_leading_uescaped_thinspace.json @@ -0,0 +1 @@ +[\u0020"asd"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_no_quotes_with_bad_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_no_quotes_with_bad_escape.json new file mode 100644 index 000000000..01bc70aba --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_no_quotes_with_bad_escape.json @@ -0,0 +1 @@ +[\n]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_single_doublequote.json b/src/boost/libs/json/test/parse-vectors/n_string_single_doublequote.json new file mode 100644 index 000000000..9d68933c4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_single_doublequote.json @@ -0,0 +1 @@ +"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_single_quote.json b/src/boost/libs/json/test/parse-vectors/n_string_single_quote.json new file mode 100644 index 000000000..caff239bf --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_single_quote.json @@ -0,0 +1 @@ +['single quote']
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_single_string_no_double_quotes.json b/src/boost/libs/json/test/parse-vectors/n_string_single_string_no_double_quotes.json new file mode 100644 index 000000000..f2ba8f84a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_single_string_no_double_quotes.json @@ -0,0 +1 @@ +abc
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_start_escape_unclosed.json b/src/boost/libs/json/test/parse-vectors/n_string_start_escape_unclosed.json new file mode 100644 index 000000000..db62a46fc --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_start_escape_unclosed.json @@ -0,0 +1 @@ +["\
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unescaped_crtl_char.json b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_crtl_char.json Binary files differnew file mode 100644 index 000000000..9f2134807 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_crtl_char.json diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unescaped_newline.json b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_newline.json new file mode 100644 index 000000000..700d36086 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_newline.json @@ -0,0 +1,2 @@ +["new +line"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unescaped_tab.json b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_tab.json new file mode 100644 index 000000000..160264a2d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_tab.json @@ -0,0 +1 @@ +[" "]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unicode_CapitalU.json b/src/boost/libs/json/test/parse-vectors/n_string_unicode_CapitalU.json new file mode 100644 index 000000000..17332bb17 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_unicode_CapitalU.json @@ -0,0 +1 @@ +"\UA66D"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_string_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_string_with_trailing_garbage.json new file mode 100644 index 000000000..efe3bd272 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_string_with_trailing_garbage.json @@ -0,0 +1 @@ +""x
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_100000_opening_arrays.json b/src/boost/libs/json/test/parse-vectors/n_structure_100000_opening_arrays.json new file mode 100644 index 000000000..a4823eecc --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_100000_opening_arrays.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_U+2060_word_joined.json b/src/boost/libs/json/test/parse-vectors/n_structure_U+2060_word_joined.json new file mode 100644 index 000000000..81156a699 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_U+2060_word_joined.json @@ -0,0 +1 @@ +[â ]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_UTF8_BOM_no_data.json b/src/boost/libs/json/test/parse-vectors/n_structure_UTF8_BOM_no_data.json new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_UTF8_BOM_no_data.json @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_..json b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_..json new file mode 100644 index 000000000..a56fef0b0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_..json @@ -0,0 +1 @@ +<.>
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_null.json b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_null.json new file mode 100644 index 000000000..617f26254 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_null.json @@ -0,0 +1 @@ +[<null>]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_array_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_structure_array_trailing_garbage.json new file mode 100644 index 000000000..5a745e6f3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_array_trailing_garbage.json @@ -0,0 +1 @@ +[1]x
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_array_with_extra_array_close.json b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_extra_array_close.json new file mode 100644 index 000000000..6cfb1398d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_extra_array_close.json @@ -0,0 +1 @@ +[1]]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_array_with_unclosed_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_unclosed_string.json new file mode 100644 index 000000000..ba6b1788b --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_unclosed_string.json @@ -0,0 +1 @@ +["asd]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_ascii-unicode-identifier.json b/src/boost/libs/json/test/parse-vectors/n_structure_ascii-unicode-identifier.json new file mode 100644 index 000000000..ef2ab62fe --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_ascii-unicode-identifier.json @@ -0,0 +1 @@ +aå
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_capitalized_True.json b/src/boost/libs/json/test/parse-vectors/n_structure_capitalized_True.json new file mode 100644 index 000000000..7cd88469a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_capitalized_True.json @@ -0,0 +1 @@ +[True]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_close_unopened_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_close_unopened_array.json new file mode 100644 index 000000000..d2af0c646 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_close_unopened_array.json @@ -0,0 +1 @@ +1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_comma_instead_of_closing_brace.json b/src/boost/libs/json/test/parse-vectors/n_structure_comma_instead_of_closing_brace.json new file mode 100644 index 000000000..ac61b8200 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_comma_instead_of_closing_brace.json @@ -0,0 +1 @@ +{"x": true,
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_double_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_double_array.json new file mode 100644 index 000000000..058d1626e --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_double_array.json @@ -0,0 +1 @@ +[][]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_end_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_end_array.json new file mode 100644 index 000000000..54caf60b1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_end_array.json @@ -0,0 +1 @@ +]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_incomplete_UTF8_BOM.json b/src/boost/libs/json/test/parse-vectors/n_structure_incomplete_UTF8_BOM.json new file mode 100644 index 000000000..bfcdd514f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_incomplete_UTF8_BOM.json @@ -0,0 +1 @@ +ï»{}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_lone-invalid-utf-8.json b/src/boost/libs/json/test/parse-vectors/n_structure_lone-invalid-utf-8.json new file mode 100644 index 000000000..8b1296cad --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_lone-invalid-utf-8.json @@ -0,0 +1 @@ +å
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_lone-open-bracket.json b/src/boost/libs/json/test/parse-vectors/n_structure_lone-open-bracket.json new file mode 100644 index 000000000..8e2f0bef1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_lone-open-bracket.json @@ -0,0 +1 @@ +[
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_no_data.json b/src/boost/libs/json/test/parse-vectors/n_structure_no_data.json new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_no_data.json diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_null-byte-outside-string.json b/src/boost/libs/json/test/parse-vectors/n_structure_null-byte-outside-string.json Binary files differnew file mode 100644 index 000000000..326db1442 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_null-byte-outside-string.json diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_number_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_structure_number_with_trailing_garbage.json new file mode 100644 index 000000000..0746539d2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_number_with_trailing_garbage.json @@ -0,0 +1 @@ +2@
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_followed_by_closing_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_followed_by_closing_object.json new file mode 100644 index 000000000..aa9ebaec5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_followed_by_closing_object.json @@ -0,0 +1 @@ +{}}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_unclosed_no_value.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_unclosed_no_value.json new file mode 100644 index 000000000..17d045147 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_unclosed_no_value.json @@ -0,0 +1 @@ +{"":
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_with_comment.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_comment.json new file mode 100644 index 000000000..ed1b569b7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_comment.json @@ -0,0 +1 @@ +{"a":/*comment*/"b"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_trailing_garbage.json new file mode 100644 index 000000000..9ca2336d7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_trailing_garbage.json @@ -0,0 +1 @@ +{"a": true} "x"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_apostrophe.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_apostrophe.json new file mode 100644 index 000000000..8bebe3af0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_apostrophe.json @@ -0,0 +1 @@ +['
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_comma.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_comma.json new file mode 100644 index 000000000..6295fdc36 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_comma.json @@ -0,0 +1 @@ +[,
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_object.json new file mode 100644 index 000000000..e870445b2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_object.json @@ -0,0 +1 @@ +[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"": diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_object.json new file mode 100644 index 000000000..7a63c8c57 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_object.json @@ -0,0 +1 @@ +[{
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_string.json new file mode 100644 index 000000000..9822a6baf --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_string.json @@ -0,0 +1 @@ +["a
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_string.json new file mode 100644 index 000000000..42a619362 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_string.json @@ -0,0 +1 @@ +["a"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object.json new file mode 100644 index 000000000..81750b96f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object.json @@ -0,0 +1 @@ +{
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_close_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_close_array.json new file mode 100644 index 000000000..eebc700a1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_close_array.json @@ -0,0 +1 @@ +{]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_comma.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_comma.json new file mode 100644 index 000000000..47bc9106f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_comma.json @@ -0,0 +1 @@ +{,
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_array.json new file mode 100644 index 000000000..381ede5de --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_array.json @@ -0,0 +1 @@ +{[
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_string.json new file mode 100644 index 000000000..328c30cd7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_string.json @@ -0,0 +1 @@ +{"a
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_string_with_apostrophes.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_string_with_apostrophes.json new file mode 100644 index 000000000..9dba17090 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_string_with_apostrophes.json @@ -0,0 +1 @@ +{'a'
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_open.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_open.json new file mode 100644 index 000000000..841fd5f86 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_open.json @@ -0,0 +1 @@ +["\{["\{["\{["\{
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_single_eacute.json b/src/boost/libs/json/test/parse-vectors/n_structure_single_eacute.json new file mode 100644 index 000000000..92a39f398 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_single_eacute.json @@ -0,0 +1 @@ +é
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_single_star.json b/src/boost/libs/json/test/parse-vectors/n_structure_single_star.json new file mode 100644 index 000000000..f59ec20aa --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_single_star.json @@ -0,0 +1 @@ +*
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_trailing_#.json b/src/boost/libs/json/test/parse-vectors/n_structure_trailing_#.json new file mode 100644 index 000000000..898611087 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_trailing_#.json @@ -0,0 +1 @@ +{"a":"b"}#{}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_uescaped_LF_before_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_uescaped_LF_before_string.json new file mode 100644 index 000000000..df2f0f242 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_uescaped_LF_before_string.json @@ -0,0 +1 @@ +[\u000A""]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array.json new file mode 100644 index 000000000..11209515c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array.json @@ -0,0 +1 @@ +[1
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_partial_null.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_partial_null.json new file mode 100644 index 000000000..0d591762c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_partial_null.json @@ -0,0 +1 @@ +[ false, nul
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_false.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_false.json new file mode 100644 index 000000000..a2ff8504a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_false.json @@ -0,0 +1 @@ +[ true, fals
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_true.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_true.json new file mode 100644 index 000000000..3149e8f5a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_true.json @@ -0,0 +1 @@ +[ false, tru
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_object.json new file mode 100644 index 000000000..694d69dbd --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_object.json @@ -0,0 +1 @@ +{"asd":"asd"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unicode-identifier.json b/src/boost/libs/json/test/parse-vectors/n_structure_unicode-identifier.json new file mode 100644 index 000000000..7284aea33 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_unicode-identifier.json @@ -0,0 +1 @@ +Ã¥
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_U+2060_word_joiner.json b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_U+2060_word_joiner.json new file mode 100644 index 000000000..81156a699 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_U+2060_word_joiner.json @@ -0,0 +1 @@ +[â ]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_formfeed.json b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_formfeed.json new file mode 100644 index 000000000..a9ea535d1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_formfeed.json @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_arraysWithSpaces.json b/src/boost/libs/json/test/parse-vectors/y_array_arraysWithSpaces.json new file mode 100644 index 000000000..582290798 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_arraysWithSpaces.json @@ -0,0 +1 @@ +[[] ]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_empty-string.json b/src/boost/libs/json/test/parse-vectors/y_array_empty-string.json new file mode 100644 index 000000000..93b6be2bc --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_empty-string.json @@ -0,0 +1 @@ +[""]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_empty.json b/src/boost/libs/json/test/parse-vectors/y_array_empty.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_empty.json @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_ending_with_newline.json b/src/boost/libs/json/test/parse-vectors/y_array_ending_with_newline.json new file mode 100644 index 000000000..eac5f7b46 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_ending_with_newline.json @@ -0,0 +1 @@ +["a"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_false.json b/src/boost/libs/json/test/parse-vectors/y_array_false.json new file mode 100644 index 000000000..67b2f0760 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_false.json @@ -0,0 +1 @@ +[false]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_heterogeneous.json b/src/boost/libs/json/test/parse-vectors/y_array_heterogeneous.json new file mode 100644 index 000000000..d3c1e2648 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_heterogeneous.json @@ -0,0 +1 @@ +[null, 1, "1", {}]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_null.json b/src/boost/libs/json/test/parse-vectors/y_array_null.json new file mode 100644 index 000000000..500db4a86 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_null.json @@ -0,0 +1 @@ +[null]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_1_and_newline.json b/src/boost/libs/json/test/parse-vectors/y_array_with_1_and_newline.json new file mode 100644 index 000000000..994825500 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_with_1_and_newline.json @@ -0,0 +1,2 @@ +[1 +]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_leading_space.json b/src/boost/libs/json/test/parse-vectors/y_array_with_leading_space.json new file mode 100644 index 000000000..18bfe6422 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_with_leading_space.json @@ -0,0 +1 @@ + [1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_several_null.json b/src/boost/libs/json/test/parse-vectors/y_array_with_several_null.json new file mode 100644 index 000000000..99f6c5d1d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_with_several_null.json @@ -0,0 +1 @@ +[1,null,null,null,2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_trailing_space.json b/src/boost/libs/json/test/parse-vectors/y_array_with_trailing_space.json new file mode 100644 index 000000000..de9e7a944 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_array_with_trailing_space.json @@ -0,0 +1 @@ +[2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number.json b/src/boost/libs/json/test/parse-vectors/y_number.json new file mode 100644 index 000000000..e5f5cc334 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number.json @@ -0,0 +1 @@ +[123e65]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_0e+1.json b/src/boost/libs/json/test/parse-vectors/y_number_0e+1.json new file mode 100644 index 000000000..d1d396706 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_0e+1.json @@ -0,0 +1 @@ +[0e+1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_0e1.json b/src/boost/libs/json/test/parse-vectors/y_number_0e1.json new file mode 100644 index 000000000..3283a7936 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_0e1.json @@ -0,0 +1 @@ +[0e1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_after_space.json b/src/boost/libs/json/test/parse-vectors/y_number_after_space.json new file mode 100644 index 000000000..623570d96 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_after_space.json @@ -0,0 +1 @@ +[ 4]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_double_close_to_zero.json b/src/boost/libs/json/test/parse-vectors/y_number_double_close_to_zero.json new file mode 100644 index 000000000..96555ff78 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_double_close_to_zero.json @@ -0,0 +1 @@ +[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001] diff --git a/src/boost/libs/json/test/parse-vectors/y_number_int_with_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_int_with_exp.json new file mode 100644 index 000000000..a4ca9e754 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_int_with_exp.json @@ -0,0 +1 @@ +[20e1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_minus_zero.json b/src/boost/libs/json/test/parse-vectors/y_number_minus_zero.json new file mode 100644 index 000000000..37af1312a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_minus_zero.json @@ -0,0 +1 @@ +[-0]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_negative_int.json b/src/boost/libs/json/test/parse-vectors/y_number_negative_int.json new file mode 100644 index 000000000..8e30f8bd9 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_negative_int.json @@ -0,0 +1 @@ +[-123]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_negative_one.json b/src/boost/libs/json/test/parse-vectors/y_number_negative_one.json new file mode 100644 index 000000000..99d21a2a0 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_negative_one.json @@ -0,0 +1 @@ +[-1]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_negative_zero.json b/src/boost/libs/json/test/parse-vectors/y_number_negative_zero.json new file mode 100644 index 000000000..37af1312a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_negative_zero.json @@ -0,0 +1 @@ +[-0]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e.json b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e.json new file mode 100644 index 000000000..6edbdfcb1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e.json @@ -0,0 +1 @@ +[1E22]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_neg_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_neg_exp.json new file mode 100644 index 000000000..0a01bd3ef --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_neg_exp.json @@ -0,0 +1 @@ +[1E-2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_pos_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_pos_exp.json new file mode 100644 index 000000000..5a8fc0972 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_pos_exp.json @@ -0,0 +1 @@ +[1E+2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_exponent.json b/src/boost/libs/json/test/parse-vectors/y_number_real_exponent.json new file mode 100644 index 000000000..da2522d61 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_real_exponent.json @@ -0,0 +1 @@ +[123e45]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_fraction_exponent.json b/src/boost/libs/json/test/parse-vectors/y_number_real_fraction_exponent.json new file mode 100644 index 000000000..3944a7a45 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_real_fraction_exponent.json @@ -0,0 +1 @@ +[123.456e78]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_neg_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_real_neg_exp.json new file mode 100644 index 000000000..ca40d3c25 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_real_neg_exp.json @@ -0,0 +1 @@ +[1e-2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_pos_exponent.json b/src/boost/libs/json/test/parse-vectors/y_number_real_pos_exponent.json new file mode 100644 index 000000000..343601d51 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_real_pos_exponent.json @@ -0,0 +1 @@ +[1e+2]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_simple_int.json b/src/boost/libs/json/test/parse-vectors/y_number_simple_int.json new file mode 100644 index 000000000..e47f69afc --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_simple_int.json @@ -0,0 +1 @@ +[123]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_number_simple_real.json b/src/boost/libs/json/test/parse-vectors/y_number_simple_real.json new file mode 100644 index 000000000..b02878e5f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_number_simple_real.json @@ -0,0 +1 @@ +[123.456789]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object.json b/src/boost/libs/json/test/parse-vectors/y_object.json new file mode 100644 index 000000000..78262eda3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object.json @@ -0,0 +1 @@ +{"asd":"sdf", "dfg":"fgh"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_basic.json b/src/boost/libs/json/test/parse-vectors/y_object_basic.json new file mode 100644 index 000000000..646bbe7bb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_basic.json @@ -0,0 +1 @@ +{"asd":"sdf"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key.json b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key.json new file mode 100644 index 000000000..bbc2e1ce4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key.json @@ -0,0 +1 @@ +{"a":"b","a":"c"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key_and_value.json b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key_and_value.json new file mode 100644 index 000000000..211581c20 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key_and_value.json @@ -0,0 +1 @@ +{"a":"b","a":"b"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_empty.json b/src/boost/libs/json/test/parse-vectors/y_object_empty.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_empty.json @@ -0,0 +1 @@ +{}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_empty_key.json b/src/boost/libs/json/test/parse-vectors/y_object_empty_key.json new file mode 100644 index 000000000..c0013d3b8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_empty_key.json @@ -0,0 +1 @@ +{"":0}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_escaped_null_in_key.json b/src/boost/libs/json/test/parse-vectors/y_object_escaped_null_in_key.json new file mode 100644 index 000000000..593f0f67f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_escaped_null_in_key.json @@ -0,0 +1 @@ +{"foo\u0000bar": 42}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_extreme_numbers.json b/src/boost/libs/json/test/parse-vectors/y_object_extreme_numbers.json new file mode 100644 index 000000000..a0d3531c3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_extreme_numbers.json @@ -0,0 +1 @@ +{ "min": -1.0e+28, "max": 1.0e+28 }
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_long_strings.json b/src/boost/libs/json/test/parse-vectors/y_object_long_strings.json new file mode 100644 index 000000000..bdc4a0871 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_long_strings.json @@ -0,0 +1 @@ +{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_simple.json b/src/boost/libs/json/test/parse-vectors/y_object_simple.json new file mode 100644 index 000000000..dacac917f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_simple.json @@ -0,0 +1 @@ +{"a":[]}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_string_unicode.json b/src/boost/libs/json/test/parse-vectors/y_object_string_unicode.json new file mode 100644 index 000000000..8effdb297 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_string_unicode.json @@ -0,0 +1 @@ +{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_object_with_newlines.json b/src/boost/libs/json/test/parse-vectors/y_object_with_newlines.json new file mode 100644 index 000000000..246ec6b34 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_object_with_newlines.json @@ -0,0 +1,3 @@ +{ +"a": "b" +}
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_pass01.json b/src/boost/libs/json/test/parse-vectors/y_pass01.json new file mode 100644 index 000000000..70e268543 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_pass01.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* <!-- --", + "# -- --> */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_pass02.json b/src/boost/libs/json/test/parse-vectors/y_pass02.json new file mode 100644 index 000000000..d3c63c7ad --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_pass02.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_pass03.json b/src/boost/libs/json/test/parse-vectors/y_pass03.json new file mode 100644 index 000000000..4528d51f1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_pass03.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/src/boost/libs/json/test/parse-vectors/y_string_1_2_3_bytes_UTF-8_sequences.json b/src/boost/libs/json/test/parse-vectors/y_string_1_2_3_bytes_UTF-8_sequences.json new file mode 100644 index 000000000..9967ddeb8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_1_2_3_bytes_UTF-8_sequences.json @@ -0,0 +1 @@ +["\u0060\u012a\u12AB"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pair.json b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pair.json new file mode 100644 index 000000000..996875cc8 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pair.json @@ -0,0 +1 @@ +["\uD801\udc37"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pairs.json b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pairs.json new file mode 100644 index 000000000..3401021ec --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pairs.json @@ -0,0 +1 @@ +["\ud83d\ude39\ud83d\udc8d"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_allowed_escapes.json b/src/boost/libs/json/test/parse-vectors/y_string_allowed_escapes.json new file mode 100644 index 000000000..7f495532f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_allowed_escapes.json @@ -0,0 +1 @@ +["\"\\\/\b\f\n\r\t"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_backslash_and_u_escaped_zero.json b/src/boost/libs/json/test/parse-vectors/y_string_backslash_and_u_escaped_zero.json new file mode 100644 index 000000000..d4439eda7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_backslash_and_u_escaped_zero.json @@ -0,0 +1 @@ +["\\u0000"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_backslash_doublequotes.json b/src/boost/libs/json/test/parse-vectors/y_string_backslash_doublequotes.json new file mode 100644 index 000000000..ae03243b6 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_backslash_doublequotes.json @@ -0,0 +1 @@ +["\""]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_comments.json b/src/boost/libs/json/test/parse-vectors/y_string_comments.json new file mode 100644 index 000000000..2260c20c2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_comments.json @@ -0,0 +1 @@ +["a/*b*/c/*d//e"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_double_escape_a.json b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_a.json new file mode 100644 index 000000000..6715d6f40 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_a.json @@ -0,0 +1 @@ +["\\a"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_double_escape_n.json b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_n.json new file mode 100644 index 000000000..44ca56c4d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_n.json @@ -0,0 +1 @@ +["\\n"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_escaped_control_character.json b/src/boost/libs/json/test/parse-vectors/y_string_escaped_control_character.json new file mode 100644 index 000000000..5b014a9c2 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_escaped_control_character.json @@ -0,0 +1 @@ +["\u0012"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_escaped_noncharacter.json b/src/boost/libs/json/test/parse-vectors/y_string_escaped_noncharacter.json new file mode 100644 index 000000000..2ff52e2c5 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_escaped_noncharacter.json @@ -0,0 +1 @@ +["\uFFFF"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_in_array.json b/src/boost/libs/json/test/parse-vectors/y_string_in_array.json new file mode 100644 index 000000000..21d7ae4cd --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_in_array.json @@ -0,0 +1 @@ +["asd"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_in_array_with_leading_space.json b/src/boost/libs/json/test/parse-vectors/y_string_in_array_with_leading_space.json new file mode 100644 index 000000000..9e1887c1e --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_in_array_with_leading_space.json @@ -0,0 +1 @@ +[ "asd"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_last_surrogates_1_and_2.json b/src/boost/libs/json/test/parse-vectors/y_string_last_surrogates_1_and_2.json new file mode 100644 index 000000000..3919cef76 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_last_surrogates_1_and_2.json @@ -0,0 +1 @@ +["\uDBFF\uDFFF"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_nbsp_uescaped.json b/src/boost/libs/json/test/parse-vectors/y_string_nbsp_uescaped.json new file mode 100644 index 000000000..2085ab1a1 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_nbsp_uescaped.json @@ -0,0 +1 @@ +["new\u00A0line"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+10FFFF.json b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+10FFFF.json new file mode 100644 index 000000000..059e4d9dd --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+10FFFF.json @@ -0,0 +1 @@ +["ô¿¿"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+FFFF.json b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+FFFF.json new file mode 100644 index 000000000..4c913bd41 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+FFFF.json @@ -0,0 +1 @@ +["ï¿¿"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_null_escape.json b/src/boost/libs/json/test/parse-vectors/y_string_null_escape.json new file mode 100644 index 000000000..c1ad84404 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_null_escape.json @@ -0,0 +1 @@ +["\u0000"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_one-byte-utf-8.json b/src/boost/libs/json/test/parse-vectors/y_string_one-byte-utf-8.json new file mode 100644 index 000000000..157185923 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_one-byte-utf-8.json @@ -0,0 +1 @@ +["\u002c"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_pi.json b/src/boost/libs/json/test/parse-vectors/y_string_pi.json new file mode 100644 index 000000000..9df11ae88 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_pi.json @@ -0,0 +1 @@ +["Ï€"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_reservedCharacterInUTF-8_U+1BFFF.json b/src/boost/libs/json/test/parse-vectors/y_string_reservedCharacterInUTF-8_U+1BFFF.json new file mode 100644 index 000000000..10a33a171 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_reservedCharacterInUTF-8_U+1BFFF.json @@ -0,0 +1 @@ +["𛿿"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_simple_ascii.json b/src/boost/libs/json/test/parse-vectors/y_string_simple_ascii.json new file mode 100644 index 000000000..8cadf7d05 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_simple_ascii.json @@ -0,0 +1 @@ +["asd "]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_space.json b/src/boost/libs/json/test/parse-vectors/y_string_space.json new file mode 100644 index 000000000..efd782cc3 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_space.json @@ -0,0 +1 @@ +" "
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json b/src/boost/libs/json/test/parse-vectors/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json new file mode 100644 index 000000000..7620b6655 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json @@ -0,0 +1 @@ +["\uD834\uDd1e"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_three-byte-utf-8.json b/src/boost/libs/json/test/parse-vectors/y_string_three-byte-utf-8.json new file mode 100644 index 000000000..108f1d67d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_three-byte-utf-8.json @@ -0,0 +1 @@ +["\u0821"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_two-byte-utf-8.json b/src/boost/libs/json/test/parse-vectors/y_string_two-byte-utf-8.json new file mode 100644 index 000000000..461503c31 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_two-byte-utf-8.json @@ -0,0 +1 @@ +["\u0123"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_u+2028_line_sep.json b/src/boost/libs/json/test/parse-vectors/y_string_u+2028_line_sep.json new file mode 100644 index 000000000..897b6021a --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_u+2028_line_sep.json @@ -0,0 +1 @@ +["
"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_u+2029_par_sep.json b/src/boost/libs/json/test/parse-vectors/y_string_u+2029_par_sep.json new file mode 100644 index 000000000..8cd998c89 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_u+2029_par_sep.json @@ -0,0 +1 @@ +["
"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_uEscape.json b/src/boost/libs/json/test/parse-vectors/y_string_uEscape.json new file mode 100644 index 000000000..f7b41a02f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_uEscape.json @@ -0,0 +1 @@ +["\u0061\u30af\u30EA\u30b9"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_uescaped_newline.json b/src/boost/libs/json/test/parse-vectors/y_string_uescaped_newline.json new file mode 100644 index 000000000..3a5a220b6 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_uescaped_newline.json @@ -0,0 +1 @@ +["new\u000Aline"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unescaped_char_delete.json b/src/boost/libs/json/test/parse-vectors/y_string_unescaped_char_delete.json new file mode 100644 index 000000000..7d064f498 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unescaped_char_delete.json @@ -0,0 +1 @@ +[""]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode.json new file mode 100644 index 000000000..3598095b7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode.json @@ -0,0 +1 @@ +["\uA66D"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicodeEscapedBackslash.json b/src/boost/libs/json/test/parse-vectors/y_string_unicodeEscapedBackslash.json new file mode 100644 index 000000000..0bb3b51e7 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicodeEscapedBackslash.json @@ -0,0 +1 @@ +["\u005C"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_2.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_2.json new file mode 100644 index 000000000..a7dcb9768 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_2.json @@ -0,0 +1 @@ +["â‚㈴â‚"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+10FFFE_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+10FFFE_nonchar.json new file mode 100644 index 000000000..9a8370b96 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+10FFFE_nonchar.json @@ -0,0 +1 @@ +["\uDBFF\uDFFE"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+1FFFE_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+1FFFE_nonchar.json new file mode 100644 index 000000000..c51f8ae45 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+1FFFE_nonchar.json @@ -0,0 +1 @@ +["\uD83F\uDFFE"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json new file mode 100644 index 000000000..626d5f815 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json @@ -0,0 +1 @@ +["\u200B"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+2064_invisible_plus.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+2064_invisible_plus.json new file mode 100644 index 000000000..1e23972c6 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+2064_invisible_plus.json @@ -0,0 +1 @@ +["\u2064"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FDD0_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FDD0_nonchar.json new file mode 100644 index 000000000..18ef151b4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FDD0_nonchar.json @@ -0,0 +1 @@ +["\uFDD0"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FFFE_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FFFE_nonchar.json new file mode 100644 index 000000000..13d261fda --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FFFE_nonchar.json @@ -0,0 +1 @@ +["\uFFFE"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_escaped_double_quote.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_escaped_double_quote.json new file mode 100644 index 000000000..4e6257856 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_escaped_double_quote.json @@ -0,0 +1 @@ +["\u0022"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_utf8.json b/src/boost/libs/json/test/parse-vectors/y_string_utf8.json new file mode 100644 index 000000000..40878435f --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_utf8.json @@ -0,0 +1 @@ +["€ð„ž"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_string_with_del_character.json b/src/boost/libs/json/test/parse-vectors/y_string_with_del_character.json new file mode 100644 index 000000000..8bd24907d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_string_with_del_character.json @@ -0,0 +1 @@ +["aa"]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_false.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_false.json new file mode 100644 index 000000000..02e4a84d6 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_false.json @@ -0,0 +1 @@ +false
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_int.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_int.json new file mode 100644 index 000000000..f70d7bba4 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_int.json @@ -0,0 +1 @@ +42
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_negative_real.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_negative_real.json new file mode 100644 index 000000000..b5135a207 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_negative_real.json @@ -0,0 +1 @@ +-0.1
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_null.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_null.json new file mode 100644 index 000000000..ec747fa47 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_null.json @@ -0,0 +1 @@ +null
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_string.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_string.json new file mode 100644 index 000000000..b6e982ca9 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_string.json @@ -0,0 +1 @@ +"asd"
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_true.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_true.json new file mode 100644 index 000000000..f32a5804e --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_true.json @@ -0,0 +1 @@ +true
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_string_empty.json b/src/boost/libs/json/test/parse-vectors/y_structure_string_empty.json new file mode 100644 index 000000000..3cc762b55 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_string_empty.json @@ -0,0 +1 @@ +""
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_trailing_newline.json b/src/boost/libs/json/test/parse-vectors/y_structure_trailing_newline.json new file mode 100644 index 000000000..0c3426d4c --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_trailing_newline.json @@ -0,0 +1 @@ +["a"] diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_true_in_array.json b/src/boost/libs/json/test/parse-vectors/y_structure_true_in_array.json new file mode 100644 index 000000000..de601e305 --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_true_in_array.json @@ -0,0 +1 @@ +[true]
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_whitespace_array.json b/src/boost/libs/json/test/parse-vectors/y_structure_whitespace_array.json new file mode 100644 index 000000000..2bedf7f2d --- /dev/null +++ b/src/boost/libs/json/test/parse-vectors/y_structure_whitespace_array.json @@ -0,0 +1 @@ + []
\ No newline at end of file diff --git a/src/boost/libs/json/test/parse.cpp b/src/boost/libs/json/test/parse.cpp new file mode 100644 index 000000000..d07e0ed6a --- /dev/null +++ b/src/boost/libs/json/test/parse.cpp @@ -0,0 +1,180 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/parse.hpp> + +#include <boost/json/serialize.hpp> + +#include <string> + +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class parse_test +{ +public: + bool hasLocation(std::error_code const&) + { + return true; + } + + bool hasLocation(error_code const& ec) + { + return ec.has_location(); + } + + template <class ErrorCode> + void + good_impl(string_view s) + { + ErrorCode ec; + auto jv = parse(s, ec); + if(! BOOST_TEST(! ec)) + return; + BOOST_TEST( + serialize(jv) == s); + } + + template <class ErrorCode> + void + bad_impl(string_view s) + { + ErrorCode ec; + auto jv = parse(s, ec); + BOOST_TEST(ec); + BOOST_TEST(hasLocation(ec)); + } + + void + good(string_view s) + { + good_impl<error_code>(s); + good_impl<std::error_code>(s); + } + + void + bad(string_view s) + { + bad_impl<error_code>(s); + bad_impl<std::error_code>(s); + } + + void + testParse() + { + good("null"); + good("[1,2,3]"); + bad ("[1,2,3] #"); + bad ("555415214748364655415E2147483646"); + bad ("9.88874836020e-2147483640"); + } + + void + testMemoryUsage() + { + // string + { + std::string s(10000, '*'); + s.insert(s.begin(), '\"'); + s.append(1, '\"'); + + fail_resource mr1; + value jv1 = parse(s, &mr1); + + fail_resource mr2; + value jv2(jv1, &mr2); + BOOST_TEST(mr1.bytes == mr2.bytes); + + fail_resource mr3; + value jv3(&mr3); + jv3 = jv1; + BOOST_TEST(mr1.bytes == mr3.bytes); + } + + // array + { + { + fail_resource mr1; + value jv1 = parse("[1]", &mr1); + + fail_resource mr2; + value jv2(jv1, &mr2); + BOOST_TEST(mr1.bytes == mr2.bytes); + + fail_resource mr3; + value jv3(&mr3); + jv3 = jv1; + BOOST_TEST(mr1.bytes == mr3.bytes); + } + { + std::string s; + s = "1,2,3,4"; + s = s + "," + s; + s = s + "," + s; + s = s + "," + s; + s = s + "," + s; + s = s + "," + s; + s = s + "," + s; + s = s + "," + s; + s = s + "," + s; + s = "[[" + s + "]]"; + + fail_resource mr1; + value jv1 = parse(s, &mr1); + + fail_resource mr2; + value jv2(jv1, &mr2); + BOOST_TEST(mr1.bytes == mr2.bytes); + + fail_resource mr3; + value jv3(&mr3); + jv3 = jv1; + BOOST_TEST(mr1.bytes == mr3.bytes); + } + } + + // object + { + std::string s; + s = "{\"0\":null"; + for(int i = 1; i < 1000; ++i) + s += + ",\"" + + std::to_string(i) + + "\":null"; + s.append("}"); + + fail_resource mr1; + value jv1 = parse(s, &mr1); + + fail_resource mr2; + value jv2(jv1, &mr2); + BOOST_TEST(mr1.bytes == mr2.bytes); + + fail_resource mr3; + value jv3(&mr3); + jv3 = jv1; + BOOST_TEST(mr1.bytes == mr3.bytes); + } + } + + void + run() + { + testParse(); + testMemoryUsage(); + } +}; + +TEST_SUITE(parse_test, "boost.json.parse"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/parser.cpp b/src/boost/libs/json/test/parser.cpp new file mode 100644 index 000000000..9282a4c0d --- /dev/null +++ b/src/boost/libs/json/test/parser.cpp @@ -0,0 +1,395 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/parser.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class parser_test +{ +public: + bool + hasLocation(std::error_code const&) + { + return true; + } + + bool + hasLocation(error_code const& ec) + { + return ec.has_location(); + } + + void + testCtors() + { + // parser(parser const&) + BOOST_STATIC_ASSERT( + ! std::is_copy_constructible<parser>::value); + + // operator=(parser const&) + BOOST_STATIC_ASSERT( + ! std::is_copy_assignable<parser>::value); + + // ~parser() + { + // implied + } + + // parser(storage_ptr, parse_options, unsigned char*, size_t) + { + unsigned char buf[256]; + parser p( + storage_ptr(), + parse_options(), + &buf[0], + sizeof(buf)); + } + + // parser() + { + parser p; + } + + // parser(storage_ptr, parse_options) + { + parser p(storage_ptr{}, parse_options()); + } + + // parser(storage_ptr) + { + parser p(storage_ptr{}); + } + + // parser(storage_ptr, parse_options, unsigned char[]) + { + unsigned char buf[256]; + parser p( + storage_ptr(), + parse_options(), + buf); + } + + #if defined(__cpp_lib_byte) + // parser(storage_ptr, parse_options, std::byte*, size_t) + { + std::byte buf[256]; + parser p( + storage_ptr(), + parse_options(), + &buf[0], + sizeof(buf)); + } + + // parser(storage_ptr, parse_options, std::byte[]) + { + std::byte buf[256]; + parser p( + storage_ptr(), + parse_options(), + buf); + } + #endif + + // parser(storage_ptr, parse_options, unsigned char[], size_t) + { + unsigned char buf[256]; + parser p( + storage_ptr(), + parse_options(), + buf, + sizeof(buf)); + } + + #if defined(__cpp_lib_byte) + // parser(storage_ptr, parse_options, std::byte[], size_t) + { + std::byte buf[256]; + parser p( + storage_ptr(), + parse_options(), + buf, + sizeof(buf)); + } + #endif + } + + template <class ErrorCode> + void + testMembers() + { + // reset + { + parser p; + p.reset(); + } + + // write_some(char const*, size_t, ErrorCode&) + { + // valid json + { + parser p; + ErrorCode ec; + auto const n = + p.write_some("null", 4, ec); + BOOST_TEST(! ec); + BOOST_TEST(n == 4); + } + + // valid json with trailing space + { + parser p; + ErrorCode ec; + auto const n = + p.write_some("null ", 5, ec); + BOOST_TEST(! ec); + BOOST_TEST(n == 5); + } + + // valid json with invalid trailing char + { + parser p; + ErrorCode ec; + auto const n = + p.write_some("null*", 5, ec); + BOOST_TEST(! ec); + BOOST_TEST(n == 4); + } + + // partial json + { + parser p; + ErrorCode ec; + p.write_some("nul", 3, ec); + BOOST_TEST(ec); + } + } + + // write_some(string_view, ErrorCode&) + { + // valid json + { + parser p; + ErrorCode ec; + auto const n = + p.write_some("null", ec); + BOOST_TEST(! ec); + BOOST_TEST(n == 4); + } + + // partial json + { + parser p; + ErrorCode ec; + p.write_some("nul", ec); + BOOST_TEST(ec); + } + } + + // write_some(char const*, size_t) + { + // valid json with trailing space + { + parser p; + auto const n = + p.write_some("null ", 5); + BOOST_TEST(n == 5); + } + + // partial json + { + parser p; + BOOST_TEST_THROWS( + p.write_some("nul", 3), + system_error); + } + } + + // write_some(string_view) + { + // valid json with trailing space + { + parser p; + auto const n = + p.write_some("null "); + BOOST_TEST(n == 5); + } + + // partial json + { + parser p; + BOOST_TEST_THROWS( + p.write_some("nul"), + system_error); + } + } + + //-------------------------------------------------- + + // write(char const*, size_t, ErrorCode&) + { + // valid json + { + parser p; + ErrorCode ec; + auto const n = + p.write("null", 4, ec); + BOOST_TEST(! ec); + BOOST_TEST(n == 4); + } + + // valid json with trailing space + { + parser p; + ErrorCode ec; + auto const n = + p.write("null ", 5, ec); + BOOST_TEST(! ec); + BOOST_TEST(n == 5); + } + + // valid json with invalid trailing char + { + parser p; + ErrorCode ec; + p.write("null*", 5, ec); + BOOST_TEST(ec); + } + + // partial json + { + parser p; + ErrorCode ec; + p.write("nul", 3, ec); + BOOST_TEST(ec); + } + } + + // write(string_view, ErrorCode&) + { + // valid json + { + parser p; + ErrorCode ec; + auto const n = + p.write("null", ec); + BOOST_TEST(! ec); + BOOST_TEST(n == 4); + } + + // partial json + { + parser p; + ErrorCode ec; + p.write("nul", ec); + BOOST_TEST(ec); + } + } + + // write(char const*, size_t) + { + // valid json with trailing space + { + parser p; + auto const n = + p.write("null ", 5); + BOOST_TEST(n == 5); + } + + // valid json with invalid trailing char + { + parser p; + BOOST_TEST_THROWS( + p.write("null*", 5), + system_error); + } + + // partial json + { + parser p; + BOOST_TEST_THROWS( + p.write("nul", 3), + system_error); + } + } + + // write(string_view) + { + // valid json with trailing space + { + parser p; + auto const n = + p.write("null "); + BOOST_TEST(n == 5); + } + + // valid json with invalid trailing char + { + parser p; + BOOST_TEST_THROWS( + p.write("null*"), + system_error); + } + + // partial json + { + parser p; + BOOST_TEST_THROWS( + p.write("nul"), + system_error); + } + } + + // release + { + // valid json + { + parser p; + p.write("[1,2,3]"); + BOOST_TEST(p.release() == + value({1,2,3})); + } + + // release with no write + { + parser p; + BOOST_TEST_THROWS( + p.release(), + system_error); + } + + // release after error + { + parser p; + ErrorCode ec; + p.write("nul", ec); + BOOST_TEST(ec); + BOOST_TEST(hasLocation(ec)); + BOOST_TEST_THROWS( + p.release(), + system_error); + } + } + } + + void + run() + { + testCtors(); + testMembers<error_code>(); + testMembers<std::error_code>(); + } +}; + +TEST_SUITE(parser_test, "boost.json.parser"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/pilfer.cpp b/src/boost/libs/json/test/pilfer.cpp new file mode 100644 index 000000000..01c321955 --- /dev/null +++ b/src/boost/libs/json/test/pilfer.cpp @@ -0,0 +1,30 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/pilfer.hpp> + +// VFALCO This fails to compile in msvc: +// https://godbolt.org/z/8q6K8e +#if 0 +namespace boost { +namespace json { + +namespace detail { +struct V{}; +} // detail + +namespace detail { +struct T{}; +} // detail +struct U : detail::T{}; + +} // json +} // boost +#endif diff --git a/src/boost/libs/json/test/pointer.cpp b/src/boost/libs/json/test/pointer.cpp new file mode 100644 index 000000000..889e5dd6d --- /dev/null +++ b/src/boost/libs/json/test/pointer.cpp @@ -0,0 +1,248 @@ +// +// Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/value.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + + +class pointer_test +{ + bool + hasLocation(error_code const& ec) + { + return ec.has_location(); + } + + bool + hasLocation(std::error_code const&) + { + return true; + } + + value + testValue() const + { + return value{ + {"foo", {"bar", "baz", "baf"}}, + {"", 0}, + {"a/b", 1}, + {"c%d", 2}, + {"e^f", 3}, + {"g|h", 4}, + {"i\\j", 5}, + {"k\"l", 6}, + {" ", 7}, + {"m~n", 8}, + {"x", object{{"y", "z"}}}, + }; + } + + value + bigObject() const + { + object result; + for (int i = 0; i < 50; ++i) + { + result.emplace(std::to_string(i), i); + } + return result; + } + +public: + void + testRootPointer() + { + value const jv = testValue(); + BOOST_TEST(&jv.at_pointer("") == &jv); + } + + void + testChildPointer() + { + value const jv = testValue(); + BOOST_TEST(&jv.at_pointer("/foo")== &jv.at("foo")); + BOOST_TEST(&jv.at_pointer("/c%d")== &jv.at("c%d")); + BOOST_TEST(&jv.at_pointer("/e^f")== &jv.at("e^f")); + BOOST_TEST(&jv.at_pointer("/g|h")== &jv.at("g|h")); + BOOST_TEST(&jv.at_pointer("/")== &jv.at("")); + BOOST_TEST(&jv.at_pointer("/i\\j")== &jv.at("i\\j")); + BOOST_TEST(&jv.at_pointer("/k\"l")== &jv.at("k\"l")); + BOOST_TEST(&jv.at_pointer("/ ")== &jv.at(" ")); + } + + void + testEscaped() + { + value const jv = testValue(); + BOOST_TEST(&jv.at_pointer("/a~1b")== &jv.at("a/b")); + BOOST_TEST(&jv.at_pointer("/m~0n")== &jv.at("m~n")); + } + + void + testNested() + { + value const jv = testValue(); + BOOST_TEST(&jv.at_pointer("/foo/0") == &jv.at("foo").at(0)); + BOOST_TEST(&jv.at_pointer("/foo/1") == &jv.at("foo").at(1)); + BOOST_TEST(&jv.at_pointer("/x/y") == &jv.at("x").at("y")); + + { + value v1; + object& o1 = v1.emplace_object(); + object& o2 = (o1["very"] = value()).emplace_object(); + object& o3 = (o2["deep"] = value()).emplace_object(); + + array& a1 = (o3["path"] = value()).emplace_array(); + a1.emplace_back(value()); + + array& a2 = a1.emplace_back(value()).emplace_array(); + a2.emplace_back(value()); + a2.emplace_back(value()); + + array& a3 = a2.emplace_back(value()).emplace_array(); + object& o4 = a3.emplace_back(value()).emplace_object(); + object& o5 = (o4["0"] = value()).emplace_object(); + value& v2 = o5["fin"] = value(); + + BOOST_TEST(&v1.at_pointer("/very/deep/path/1/2/0/0/fin") == &v2); + } + } + + void + testErrors() + { + value const jv = testValue(); + BOOST_TEST_THROWS(jv.at_pointer("foo"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/fo"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/m~"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/m~n"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/foo/bar"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/foo/"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/foo/01"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/foo/2b"), system_error); + BOOST_TEST_THROWS(jv.at_pointer("/x/y/z"), system_error); + } + + template<class ErrorCode> + void + testNonThrowing() + { + value jv = testValue(); + ErrorCode ec = error::syntax; + BOOST_TEST(jv.find_pointer("/foo/0", ec) == &jv.at("foo").at(0)); + BOOST_TEST(!ec); + + auto const& cjv = jv; + ec = error::syntax; + BOOST_TEST(cjv.find_pointer("/foo/1", ec) == &jv.at("foo").at(1)); + BOOST_TEST(!ec); + + jv.find_pointer("foo", ec); + BOOST_TEST(ec == error::missing_slash); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/fo", ec); + BOOST_TEST(ec == error::not_found); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/25", ec); + BOOST_TEST(ec == error::not_found); + BOOST_TEST(hasLocation(ec)); + + value(object()).find_pointer("/foo", ec); + BOOST_TEST(ec == error::not_found); + BOOST_TEST(hasLocation(ec)); + + bigObject().find_pointer("/foo", ec); + BOOST_TEST(ec == error::not_found); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/m~", ec); + BOOST_TEST(ec == error::invalid_escape); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/m~n", ec); + BOOST_TEST(ec == error::invalid_escape); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/bar", ec); + BOOST_TEST(ec == error::token_not_number); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/", ec); + BOOST_TEST(ec == error::token_not_number); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/01", ec); + BOOST_TEST(ec == error::token_not_number); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/2b", ec); + BOOST_TEST(ec == error::token_not_number); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/2.", ec); + BOOST_TEST(ec == error::token_not_number); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/-", ec); + BOOST_TEST(ec == error::past_the_end); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/-/x", ec); + BOOST_TEST(ec == error::past_the_end); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/foo/-1", ec); + BOOST_TEST(ec == error::token_not_number); + BOOST_TEST(hasLocation(ec)); + + jv.find_pointer("/x/y/z", ec); + BOOST_TEST(ec == error::value_is_scalar); + BOOST_TEST(hasLocation(ec)); + + string s = "/foo/"; + s += std::to_string((std::numeric_limits<std::size_t>::max)()); + if ( '9' == s[s.size() - 1] ) + { + for (std::size_t i = 6; i < s.size(); ++i) + { + s[i] = '0'; + } + s[5] = '1'; + s += "0"; + } + else + { + ++s[s.size() - 1]; + } + jv.find_pointer(s, ec); + BOOST_TEST(ec == error::token_overflow); + BOOST_TEST(hasLocation(ec)); + } + + void + run() + { + testRootPointer(); + testChildPointer(); + testEscaped(); + testNested(); + testErrors(); + testNonThrowing<error_code>(); + testNonThrowing<std::error_code>(); + } +}; + +TEST_SUITE(pointer_test, "boost.json.pointer"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/ryu/d2s_intrinsics_test.cpp b/src/boost/libs/json/test/ryu/d2s_intrinsics_test.cpp new file mode 100644 index 000000000..bb492cc71 --- /dev/null +++ b/src/boost/libs/json/test/ryu/d2s_intrinsics_test.cpp @@ -0,0 +1,56 @@ +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +/* + This is a derivative work +*/ + +#include <boost/json/detail/ryu/detail/d2s_intrinsics.hpp> +#include "gtest.hpp" +#include <math.h> + +BOOST_JSON_NS_BEGIN +namespace detail { + +namespace ryu { +namespace detail { + +TEST(D2sIntrinsicsTest, mod1e9) { + ASSERT_EQ(0, mod1e9(0)); + ASSERT_EQ(1, mod1e9(1)); + ASSERT_EQ(2, mod1e9(2)); + ASSERT_EQ(10, mod1e9(10)); + ASSERT_EQ(100, mod1e9(100)); + ASSERT_EQ(1000, mod1e9(1000)); + ASSERT_EQ(10000, mod1e9(10000)); + ASSERT_EQ(100000, mod1e9(100000)); + ASSERT_EQ(1000000, mod1e9(1000000)); + ASSERT_EQ(10000000, mod1e9(10000000)); + ASSERT_EQ(100000000, mod1e9(100000000)); + ASSERT_EQ(0, mod1e9(1000000000)); + ASSERT_EQ(0, mod1e9(2000000000)); + ASSERT_EQ(1, mod1e9(1000000001)); + ASSERT_EQ(1234, mod1e9(1000001234)); + ASSERT_EQ(123456789, mod1e9(12345123456789ull)); + ASSERT_EQ(123456789, mod1e9(123456789123456789ull)); +} + +} // detail +} // ryu + +} // detail +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/ryu/d2s_table_test.cpp b/src/boost/libs/json/test/ryu/d2s_table_test.cpp new file mode 100644 index 000000000..226a2fc64 --- /dev/null +++ b/src/boost/libs/json/test/ryu/d2s_table_test.cpp @@ -0,0 +1,106 @@ +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +/* + This is a derivative work +*/ + +#if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) +#define BOOST_JSON_RYU_HAS_UINT128 +#elif defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64) \ + && !defined(__clang__) // https://bugs.llvm.org/show_bug.cgi?id=37755 +#define BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS +#endif + +// We want to test the size-optimized case here. +#if !defined(BOOST_JSON_RYU_OPTIMIZE_SIZE) +#define BOOST_JSON_RYU_OPTIMIZE_SIZE +#endif +#include <boost/json/detail/ryu/detail/d2s.hpp> +#include <boost/json/detail/ryu/detail/d2s_full_table.hpp> +#include <array> +#include <cstdint> +#include <cmath> +#include "gtest.hpp" + +BOOST_JSON_NS_BEGIN +namespace detail { + +namespace ryu { +namespace detail { + +TEST(D2sTableTest, double_computePow5) { + for (int i = 0; i < 326; i++) { + uint64_t m[2]; + double_computePow5(i, m); + ASSERT_EQ(m[0], DOUBLE_POW5_SPLIT()[i][0]); + ASSERT_EQ(m[1], DOUBLE_POW5_SPLIT()[i][1]); + } +} + +TEST(D2sTableTest, compute_offsets_for_double_computePow5) { + uint32_t totalErrors = 0; + uint32_t offsets[13] = {0}; + for (int i = 0; i < 326; i++) { + uint64_t m[2]; + double_computePow5(i, m); + if (m[0] != DOUBLE_POW5_SPLIT()[i][0]) { + offsets[i / POW5_TABLE_SIZE] |= 1 << (i % POW5_TABLE_SIZE); + totalErrors++; + } + } + if (totalErrors != 0) { + for (int i = 0; i < 13; i++) { + printf("0x%08x,\n", offsets[i]); + } + } + ASSERT_EQ(totalErrors, 0); +} + +TEST(D2sTableTest, double_computeInvPow5) { + for (int i = 0; i < 292; i++) { + uint64_t m[2]; + double_computeInvPow5(i, m); + ASSERT_EQ(m[0], DOUBLE_POW5_INV_SPLIT()[i][0]); + ASSERT_EQ(m[1], DOUBLE_POW5_INV_SPLIT()[i][1]); + } +} + +TEST(D2sTableTest, compute_offsets_for_double_computeInvPow5) { + uint32_t totalErrors = 0; + uint32_t offsets[20] = {0}; + for (int i = 0; i < 292; i++) { + uint64_t m[2]; + double_computeInvPow5(i, m); + if (m[0] != DOUBLE_POW5_INV_SPLIT()[i][0]) { + offsets[i / 16] |= ((DOUBLE_POW5_INV_SPLIT()[i][0] - m[0]) & 3) << ((i % 16) << 1); + totalErrors++; + } + } + if (totalErrors != 0) { + for (int i = 0; i < 20; i++) { + printf("0x%08x,\n", offsets[i]); + } + } + ASSERT_EQ(totalErrors, 0); +} + +} // detail +} // ryu + +} // detail +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/ryu/d2s_test.cpp b/src/boost/libs/json/test/ryu/d2s_test.cpp new file mode 100644 index 000000000..e5d969d07 --- /dev/null +++ b/src/boost/libs/json/test/ryu/d2s_test.cpp @@ -0,0 +1,277 @@ +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +/* + This is a derivative work +*/ + +#include <boost/json/detail/ryu/ryu.hpp> +#include <array> +#include <cmath> +#include "gtest.hpp" + +BOOST_JSON_NS_BEGIN +namespace detail { + +namespace ryu { + +static double int64Bits2Double(uint64_t bits) { + double f; + memcpy(&f, &bits, sizeof(double)); + return f; +} + +static double ieeeParts2Double(const bool sign, const uint32_t ieeeExponent, const uint64_t ieeeMantissa) { + BOOST_ASSERT(ieeeExponent <= 2047); + BOOST_ASSERT(ieeeMantissa <= ((std::uint64_t)1 << 53) - 1); + return int64Bits2Double(((std::uint64_t)sign << 63) | ((std::uint64_t)ieeeExponent << 52) | ieeeMantissa); +} + +char const* d2s_test_helper(char* result, double f) { + int index = d2s_buffered_n(f, result); + result[index] = '\0'; + return result; +} + +TEST(D2sTest, Basic) { + std::array<char, 25> buffer; + ASSERT_STREQ("0E0", d2s_test_helper(buffer.data(), 0.0)); + ASSERT_STREQ("-0E0", d2s_test_helper(buffer.data(), -0.0)); + ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1.0)); + ASSERT_STREQ("-1E0", d2s_test_helper(buffer.data(), -1.0)); + ASSERT_STREQ("NaN", d2s_test_helper(buffer.data(), NAN)); + ASSERT_STREQ("Infinity", d2s_test_helper(buffer.data(), INFINITY)); + ASSERT_STREQ("-Infinity", d2s_test_helper(buffer.data(), -INFINITY)); +} + +TEST(D2sTest, SwitchToSubnormal) { + std::array<char, 25> buffer; + ASSERT_STREQ("2.2250738585072014E-308", d2s_test_helper(buffer.data(), 2.2250738585072014E-308)); +} + +TEST(D2sTest, MinAndMax) { + std::array<char, 25> buffer; + ASSERT_STREQ("1.7976931348623157E308", d2s_test_helper(buffer.data(), int64Bits2Double(0x7fefffffffffffff))); + ASSERT_STREQ("5E-324", d2s_test_helper(buffer.data(), int64Bits2Double(1))); +} + +TEST(D2sTest, LotsOfTrailingZeros) { + std::array<char, 25> buffer; + ASSERT_STREQ("2.9802322387695312E-8", d2s_test_helper(buffer.data(), 2.98023223876953125E-8)); +} + +TEST(D2sTest, Regression) { + std::array<char, 25> buffer; + ASSERT_STREQ("-2.109808898695963E16", d2s_test_helper(buffer.data(), -2.109808898695963E16)); + ASSERT_STREQ("4.940656E-318", d2s_test_helper(buffer.data(), 4.940656E-318)); + ASSERT_STREQ("1.18575755E-316", d2s_test_helper(buffer.data(), 1.18575755E-316)); + ASSERT_STREQ("2.989102097996E-312", d2s_test_helper(buffer.data(), 2.989102097996E-312)); + ASSERT_STREQ("9.0608011534336E15", d2s_test_helper(buffer.data(), 9.0608011534336E15)); + ASSERT_STREQ("4.708356024711512E18", d2s_test_helper(buffer.data(), 4.708356024711512E18)); + ASSERT_STREQ("9.409340012568248E18", d2s_test_helper(buffer.data(), 9.409340012568248E18)); + ASSERT_STREQ("1.2345678E0", d2s_test_helper(buffer.data(), 1.2345678)); +} + +TEST(D2sTest, LooksLikePow5) { + std::array<char, 25> buffer; + // These numbers have a mantissa that is a multiple of the largest power of 5 that fits, + // and an exponent that causes the computation for q to result in 22, which is a corner + // case for Ryu. + ASSERT_STREQ("5.764607523034235E39", d2s_test_helper(buffer.data(), int64Bits2Double(0x4830F0CF064DD592))); + ASSERT_STREQ("1.152921504606847E40", d2s_test_helper(buffer.data(), int64Bits2Double(0x4840F0CF064DD592))); + ASSERT_STREQ("2.305843009213694E40", d2s_test_helper(buffer.data(), int64Bits2Double(0x4850F0CF064DD592))); +} + +TEST(D2sTest, OutputLength) { + std::array<char, 25> buffer; + ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1)); // already tested in Basic + ASSERT_STREQ("1.2E0", d2s_test_helper(buffer.data(), 1.2)); + ASSERT_STREQ("1.23E0", d2s_test_helper(buffer.data(), 1.23)); + ASSERT_STREQ("1.234E0", d2s_test_helper(buffer.data(), 1.234)); + ASSERT_STREQ("1.2345E0", d2s_test_helper(buffer.data(), 1.2345)); + ASSERT_STREQ("1.23456E0", d2s_test_helper(buffer.data(), 1.23456)); + ASSERT_STREQ("1.234567E0", d2s_test_helper(buffer.data(), 1.234567)); + ASSERT_STREQ("1.2345678E0", d2s_test_helper(buffer.data(), 1.2345678)); // already tested in Regression + ASSERT_STREQ("1.23456789E0", d2s_test_helper(buffer.data(), 1.23456789)); + ASSERT_STREQ("1.234567895E0", d2s_test_helper(buffer.data(), 1.234567895)); // 1.234567890 would be trimmed + ASSERT_STREQ("1.2345678901E0", d2s_test_helper(buffer.data(), 1.2345678901)); + ASSERT_STREQ("1.23456789012E0", d2s_test_helper(buffer.data(), 1.23456789012)); + ASSERT_STREQ("1.234567890123E0", d2s_test_helper(buffer.data(), 1.234567890123)); + ASSERT_STREQ("1.2345678901234E0", d2s_test_helper(buffer.data(), 1.2345678901234)); + ASSERT_STREQ("1.23456789012345E0", d2s_test_helper(buffer.data(), 1.23456789012345)); + ASSERT_STREQ("1.234567890123456E0", d2s_test_helper(buffer.data(), 1.234567890123456)); + ASSERT_STREQ("1.2345678901234567E0", d2s_test_helper(buffer.data(), 1.2345678901234567)); + + // Test 32-bit chunking + ASSERT_STREQ("4.294967294E0", d2s_test_helper(buffer.data(), 4.294967294)); // 2^32 - 2 + ASSERT_STREQ("4.294967295E0", d2s_test_helper(buffer.data(), 4.294967295)); // 2^32 - 1 + ASSERT_STREQ("4.294967296E0", d2s_test_helper(buffer.data(), 4.294967296)); // 2^32 + ASSERT_STREQ("4.294967297E0", d2s_test_helper(buffer.data(), 4.294967297)); // 2^32 + 1 + ASSERT_STREQ("4.294967298E0", d2s_test_helper(buffer.data(), 4.294967298)); // 2^32 + 2 +} + +// Test min, max shift values in shiftright128 +TEST(D2sTest, MinMaxShift) { + std::array<char, 25> buffer; + const uint64_t maxMantissa = ((std::uint64_t)1 << 53) - 1; + + // 32-bit opt-size=0: 49 <= dist <= 50 + // 32-bit opt-size=1: 30 <= dist <= 50 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 30 <= dist <= 50 + ASSERT_STREQ("1.7800590868057611E-307", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 4, 0))); + // 32-bit opt-size=0: 49 <= dist <= 49 + // 32-bit opt-size=1: 28 <= dist <= 49 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 28 <= dist <= 50 + ASSERT_STREQ("2.8480945388892175E-306", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 6, maxMantissa))); + // 32-bit opt-size=0: 52 <= dist <= 53 + // 32-bit opt-size=1: 2 <= dist <= 53 + // 64-bit opt-size=0: 53 <= dist <= 53 + // 64-bit opt-size=1: 2 <= dist <= 53 + ASSERT_STREQ("2.446494580089078E-296", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 41, 0))); + // 32-bit opt-size=0: 52 <= dist <= 52 + // 32-bit opt-size=1: 2 <= dist <= 52 + // 64-bit opt-size=0: 53 <= dist <= 53 + // 64-bit opt-size=1: 2 <= dist <= 53 + ASSERT_STREQ("4.8929891601781557E-296", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 40, maxMantissa))); + + // 32-bit opt-size=0: 57 <= dist <= 58 + // 32-bit opt-size=1: 57 <= dist <= 58 + // 64-bit opt-size=0: 58 <= dist <= 58 + // 64-bit opt-size=1: 58 <= dist <= 58 + ASSERT_STREQ("1.8014398509481984E16", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 1077, 0))); + // 32-bit opt-size=0: 57 <= dist <= 57 + // 32-bit opt-size=1: 57 <= dist <= 57 + // 64-bit opt-size=0: 58 <= dist <= 58 + // 64-bit opt-size=1: 58 <= dist <= 58 + ASSERT_STREQ("3.6028797018963964E16", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 1076, maxMantissa))); + // 32-bit opt-size=0: 51 <= dist <= 52 + // 32-bit opt-size=1: 51 <= dist <= 59 + // 64-bit opt-size=0: 52 <= dist <= 52 + // 64-bit opt-size=1: 52 <= dist <= 59 + ASSERT_STREQ("2.900835519859558E-216", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 307, 0))); + // 32-bit opt-size=0: 51 <= dist <= 51 + // 32-bit opt-size=1: 51 <= dist <= 59 + // 64-bit opt-size=0: 52 <= dist <= 52 + // 64-bit opt-size=1: 52 <= dist <= 59 + ASSERT_STREQ("5.801671039719115E-216", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 306, maxMantissa))); + + // https://github.com/ulfjack/ryu/commit/19e44d16d80236f5de25800f56d82606d1be00b9#commitcomment-30146483 + // 32-bit opt-size=0: 49 <= dist <= 49 + // 32-bit opt-size=1: 44 <= dist <= 49 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 44 <= dist <= 50 + ASSERT_STREQ("3.196104012172126E-27", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 934, 0x000FA7161A4D6E0Cu))); +} + +TEST(D2sTest, SmallIntegers) { + std::array<char, 25> buffer; + ASSERT_STREQ("9.007199254740991E15", d2s_test_helper(buffer.data(), 9007199254740991.0)); // 2^53-1 + ASSERT_STREQ("9.007199254740992E15", d2s_test_helper(buffer.data(), 9007199254740992.0)); // 2^53 + + ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1.0e+0)); + ASSERT_STREQ("1.2E1", d2s_test_helper(buffer.data(), 1.2e+1)); + ASSERT_STREQ("1.23E2", d2s_test_helper(buffer.data(), 1.23e+2)); + ASSERT_STREQ("1.234E3", d2s_test_helper(buffer.data(), 1.234e+3)); + ASSERT_STREQ("1.2345E4", d2s_test_helper(buffer.data(), 1.2345e+4)); + ASSERT_STREQ("1.23456E5", d2s_test_helper(buffer.data(), 1.23456e+5)); + ASSERT_STREQ("1.234567E6", d2s_test_helper(buffer.data(), 1.234567e+6)); + ASSERT_STREQ("1.2345678E7", d2s_test_helper(buffer.data(), 1.2345678e+7)); + ASSERT_STREQ("1.23456789E8", d2s_test_helper(buffer.data(), 1.23456789e+8)); + ASSERT_STREQ("1.23456789E9", d2s_test_helper(buffer.data(), 1.23456789e+9)); + ASSERT_STREQ("1.234567895E9", d2s_test_helper(buffer.data(), 1.234567895e+9)); + ASSERT_STREQ("1.2345678901E10", d2s_test_helper(buffer.data(), 1.2345678901e+10)); + ASSERT_STREQ("1.23456789012E11", d2s_test_helper(buffer.data(), 1.23456789012e+11)); + ASSERT_STREQ("1.234567890123E12", d2s_test_helper(buffer.data(), 1.234567890123e+12)); + ASSERT_STREQ("1.2345678901234E13", d2s_test_helper(buffer.data(), 1.2345678901234e+13)); + ASSERT_STREQ("1.23456789012345E14", d2s_test_helper(buffer.data(), 1.23456789012345e+14)); + ASSERT_STREQ("1.234567890123456E15", d2s_test_helper(buffer.data(), 1.234567890123456e+15)); + + // 10^i + ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1.0e+0)); + ASSERT_STREQ("1E1", d2s_test_helper(buffer.data(), 1.0e+1)); + ASSERT_STREQ("1E2", d2s_test_helper(buffer.data(), 1.0e+2)); + ASSERT_STREQ("1E3", d2s_test_helper(buffer.data(), 1.0e+3)); + ASSERT_STREQ("1E4", d2s_test_helper(buffer.data(), 1.0e+4)); + ASSERT_STREQ("1E5", d2s_test_helper(buffer.data(), 1.0e+5)); + ASSERT_STREQ("1E6", d2s_test_helper(buffer.data(), 1.0e+6)); + ASSERT_STREQ("1E7", d2s_test_helper(buffer.data(), 1.0e+7)); + ASSERT_STREQ("1E8", d2s_test_helper(buffer.data(), 1.0e+8)); + ASSERT_STREQ("1E9", d2s_test_helper(buffer.data(), 1.0e+9)); + ASSERT_STREQ("1E10", d2s_test_helper(buffer.data(), 1.0e+10)); + ASSERT_STREQ("1E11", d2s_test_helper(buffer.data(), 1.0e+11)); + ASSERT_STREQ("1E12", d2s_test_helper(buffer.data(), 1.0e+12)); + ASSERT_STREQ("1E13", d2s_test_helper(buffer.data(), 1.0e+13)); + ASSERT_STREQ("1E14", d2s_test_helper(buffer.data(), 1.0e+14)); + ASSERT_STREQ("1E15", d2s_test_helper(buffer.data(), 1.0e+15)); + + // 10^15 + 10^i + ASSERT_STREQ("1.000000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+0)); + ASSERT_STREQ("1.00000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+1)); + ASSERT_STREQ("1.0000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+2)); + ASSERT_STREQ("1.000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+3)); + ASSERT_STREQ("1.00000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+4)); + ASSERT_STREQ("1.0000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+5)); + ASSERT_STREQ("1.000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+6)); + ASSERT_STREQ("1.00000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+7)); + ASSERT_STREQ("1.0000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+8)); + ASSERT_STREQ("1.000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+9)); + ASSERT_STREQ("1.00001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+10)); + ASSERT_STREQ("1.0001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+11)); + ASSERT_STREQ("1.001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+12)); + ASSERT_STREQ("1.01E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+13)); + ASSERT_STREQ("1.1E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+14)); + + // Largest power of 2 <= 10^(i+1) + ASSERT_STREQ("8E0", d2s_test_helper(buffer.data(), 8.0)); + ASSERT_STREQ("6.4E1", d2s_test_helper(buffer.data(), 64.0)); + ASSERT_STREQ("5.12E2", d2s_test_helper(buffer.data(), 512.0)); + ASSERT_STREQ("8.192E3", d2s_test_helper(buffer.data(), 8192.0)); + ASSERT_STREQ("6.5536E4", d2s_test_helper(buffer.data(), 65536.0)); + ASSERT_STREQ("5.24288E5", d2s_test_helper(buffer.data(), 524288.0)); + ASSERT_STREQ("8.388608E6", d2s_test_helper(buffer.data(), 8388608.0)); + ASSERT_STREQ("6.7108864E7", d2s_test_helper(buffer.data(), 67108864.0)); + ASSERT_STREQ("5.36870912E8", d2s_test_helper(buffer.data(), 536870912.0)); + ASSERT_STREQ("8.589934592E9", d2s_test_helper(buffer.data(), 8589934592.0)); + ASSERT_STREQ("6.8719476736E10", d2s_test_helper(buffer.data(), 68719476736.0)); + ASSERT_STREQ("5.49755813888E11", d2s_test_helper(buffer.data(), 549755813888.0)); + ASSERT_STREQ("8.796093022208E12", d2s_test_helper(buffer.data(), 8796093022208.0)); + ASSERT_STREQ("7.0368744177664E13", d2s_test_helper(buffer.data(), 70368744177664.0)); + ASSERT_STREQ("5.62949953421312E14", d2s_test_helper(buffer.data(), 562949953421312.0)); + ASSERT_STREQ("9.007199254740992E15", d2s_test_helper(buffer.data(), 9007199254740992.0)); + + // 1000 * (Largest power of 2 <= 10^(i+1)) + ASSERT_STREQ("8E3", d2s_test_helper(buffer.data(), 8.0e+3)); + ASSERT_STREQ("6.4E4", d2s_test_helper(buffer.data(), 64.0e+3)); + ASSERT_STREQ("5.12E5", d2s_test_helper(buffer.data(), 512.0e+3)); + ASSERT_STREQ("8.192E6", d2s_test_helper(buffer.data(), 8192.0e+3)); + ASSERT_STREQ("6.5536E7", d2s_test_helper(buffer.data(), 65536.0e+3)); + ASSERT_STREQ("5.24288E8", d2s_test_helper(buffer.data(), 524288.0e+3)); + ASSERT_STREQ("8.388608E9", d2s_test_helper(buffer.data(), 8388608.0e+3)); + ASSERT_STREQ("6.7108864E10", d2s_test_helper(buffer.data(), 67108864.0e+3)); + ASSERT_STREQ("5.36870912E11", d2s_test_helper(buffer.data(), 536870912.0e+3)); + ASSERT_STREQ("8.589934592E12", d2s_test_helper(buffer.data(), 8589934592.0e+3)); + ASSERT_STREQ("6.8719476736E13", d2s_test_helper(buffer.data(), 68719476736.0e+3)); + ASSERT_STREQ("5.49755813888E14", d2s_test_helper(buffer.data(), 549755813888.0e+3)); + ASSERT_STREQ("8.796093022208E15", d2s_test_helper(buffer.data(), 8796093022208.0e+3)); +} + +} // ryu + +} // detail +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/ryu/gtest.hpp b/src/boost/libs/json/test/ryu/gtest.hpp new file mode 100644 index 000000000..582cebe21 --- /dev/null +++ b/src/boost/libs/json/test/ryu/gtest.hpp @@ -0,0 +1,34 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#ifndef GTEST_HPP +#define GTEST_HPP + +#include <boost/json/detail/config.hpp> +#include <boost/json/string_view.hpp> + +#include "test_suite.hpp" + +#define TEST(s1,s2) \ +struct s1 ## _ ## s2 ## _test; \ +TEST_SUITE(s1 ## _ ## s2 ## _test, "boost.Ryu." #s1 "." #s2); \ +struct s1 ## _ ## s2 ## _test { \ + void run(); }; void s1 ## _ ## s2 ## _test::run() + +#define EXPECT_STREQ(s1, s2) \ + BOOST_TEST(::boost::json::string_view(s1) == \ + ::boost::json::string_view(s2)) + +#define ASSERT_STREQ(s1, s2) \ + { auto const s1_ = (s1); auto const s2_ = (s2); \ + EXPECT_STREQ(s1_, s2_); } + +#define ASSERT_EQ(e1, e2) BOOST_TEST((e1)==(e2)) + +#endif diff --git a/src/boost/libs/json/test/serialize.cpp b/src/boost/libs/json/test/serialize.cpp new file mode 100644 index 000000000..0bbde7032 --- /dev/null +++ b/src/boost/libs/json/test/serialize.cpp @@ -0,0 +1,68 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/serialize.hpp> + +#include <boost/json/parse.hpp> +#include <boost/json/static_resource.hpp> +#include <sstream> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class serialize_test +{ +public: + template<class T> + static + std::string + print(T const& t) + { + std::stringstream ss; + ss << t; + return ss.str(); + } + + void + testSerialize() + { + { + value const jv = { 1, 2, 3 }; + BOOST_TEST(serialize(jv) == "[1,2,3]"); + BOOST_TEST(print(jv) == "[1,2,3]"); + } + { + array const arr = { 1, 2 ,3 }; + BOOST_TEST(serialize(arr) == "[1,2,3]"); + BOOST_TEST(print(arr) == "[1,2,3]"); + } + { + object const obj = { {"k1",1}, {"k2",2} }; + BOOST_TEST(serialize(obj) == "{\"k1\":1,\"k2\":2}"); + BOOST_TEST(print(obj) == "{\"k1\":1,\"k2\":2}"); + } + { + string const str = "123"; + BOOST_TEST(serialize(str) == "\"123\""); + BOOST_TEST(print(str) == "\"123\""); + } + } + + void + run() + { + testSerialize(); + } +}; + +TEST_SUITE(serialize_test, "boost.json.serialize"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/serializer.cpp b/src/boost/libs/json/test/serializer.cpp new file mode 100644 index 000000000..7a78f0f2f --- /dev/null +++ b/src/boost/libs/json/test/serializer.cpp @@ -0,0 +1,565 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/serializer.hpp> + +#include <boost/json/parse.hpp> +#include <boost/json/serialize.hpp> +#include <iostream> + +#include "parse-vectors.hpp" +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<serializer>::value ); + +class serializer_test +{ +public: + //------------------------------------------------------ + + // From the javadoc + + void print( std::ostream& os, value const& jv) + { + serializer sr; + sr.reset( &jv ); + while( ! sr.done() ) + { + char buf[ 4000 ]; + os << sr.read( buf ); + } + } + + //------------------------------------------------------ + + ::test_suite::log_type log; + + void + grind_one( + string_view s, + value const& jv, + string_view name = {}) + { + { + error_code ec; + auto const s1 = serialize(jv); + auto const jv2 = parse(s1, ec); + if(! BOOST_TEST(equal(jv, jv2))) + { + if(name.empty()) + log << + " " << s << "\n" + " " << s1 << + std::endl; + else + log << name << ":\n" + " " << s << "\n" + " " << s1 << + std::endl; + } + } + + // large buffer + { + error_code ec; + serializer sr; + sr.reset(&jv); + string js; + js.reserve(4096); + js.grow(sr.read( + js.data(), js.capacity()).size()); + + auto const s1 = serialize(jv); + auto const jv2 = parse(s1, ec); + BOOST_TEST(equal(jv, jv2)); + } + } + + void + grind( + string_view s0, + value const& jv, + string_view name = {}) + { + grind_one(s0, jv, name); + + auto const s1 = serialize(jv); + for(std::size_t i = 1; + i < s1.size(); ++i) + { + serializer sr; + sr.reset(&jv); + string s2; + s2.reserve(s1.size()); + s2.grow(sr.read( + s2.data(), i).size()); + auto const dump = + [&] + { + if(name.empty()) + log << + " " << s0 << "\n" + " " << s1 << "\n" + " " << s2 << std::endl; + else + log << name << ":\n" + " " << s0 << "\n" + " " << s1 << "\n" + " " << s2 << std::endl; + }; + if(! BOOST_TEST( + s2.size() == i)) + { + dump(); + break; + } + s2.grow(sr.read( + s2.data() + i, + s1.size() - i).size()); + if(! BOOST_TEST( + s2.size() == s1.size())) + { + dump(); + break; + } + if(! BOOST_TEST(s2 == s1)) + { + dump(); + break; + } + } + } + + //------------------------------------------------------ + + void + testNull() + { + check("null"); + } + + void + testBoolean() + { + check("true"); + check("false"); + } + + void + testString() + { + check("\"\""); + check("\"x\""); + check("\"xyz\""); + check("\"x z\""); + + // escapes + check("\"\\\"\""); // double quote + check("\"\\\\\""); // backslash + check("\"\\b\""); // backspace + check("\"\\f\""); // formfeed + check("\"\\n\""); // newline + check("\"\\r\""); // carriage return + check("\"\\t\""); // horizontal tab + + // control characters + check("\"\\u0000\""); + check("\"\\u0001\""); + check("\"\\u0002\""); + check("\"\\u0003\""); + check("\"\\u0004\""); + check("\"\\u0005\""); + check("\"\\u0006\""); + check("\"\\u0007\""); + check("\"\\u0008\""); + check("\"\\u0009\""); + check("\"\\u000a\""); + check("\"\\u000b\""); + check("\"\\u000c\""); + check("\"\\u000d\""); + check("\"\\u000e\""); + check("\"\\u000f\""); + check("\"\\u0010\""); + check("\"\\u0011\""); + check("\"\\u0012\""); + check("\"\\u0013\""); + check("\"\\u0014\""); + check("\"\\u0015\""); + check("\"\\u0016\""); + check("\"\\u0017\""); + check("\"\\u0018\""); + check("\"\\u0019\""); + check("\"\\u0020\""); + check("\"\\u0021\""); + } + + void + testNumber() + { + // VFALCO These don't perfectly round-trip, + // because the representations are not exact. + // The test needs to do a better job of comparison. + + check("-999999999999999999999"); + check("-100000000000000000009"); + check("-10000000000000000000"); + //check("-9223372036854775809"); + check("-9223372036854775808"); + check("-9223372036854775807"); + check("-999999999999999999"); + check("-99999999999999999"); + check("-9999999999999999"); + check("-999999999999999"); + check("-99999999999999"); + check("-9999999999999"); + check("-999999999999"); + check("-99999999999"); + check("-9999999999"); + check("-999999999"); + check("-99999999"); + check("-9999999"); + check("-999999"); + check("-99999"); + check("-9999"); + check("-999"); + check("-99"); + check("-9"); + check("-0"); + check("-0.0"); + check( "0"); + check( "9"); + check( "99"); + check( "999"); + check( "9999"); + check( "99999"); + check( "999999"); + check( "9999999"); + check( "99999999"); + check( "999999999"); + check( "9999999999"); + check( "99999999999"); + check( "999999999999"); + check( "9999999999999"); + check( "99999999999999"); + check( "999999999999999"); + check( "9999999999999999"); + check( "99999999999999999"); + check( "999999999999999999"); + check( "9223372036854775807"); + check( "9223372036854775808"); + check( "9999999999999999999"); + check( "18446744073709551615"); + //check( "18446744073709551616"); + check( "99999999999999999999"); + check( "999999999999999999999"); + check( "1000000000000000000000"); + check( "9999999999999999999999"); + check( "99999999999999999999999"); + + //check("-0.9999999999999999999999"); + check("-0.9999999999999999"); + //check("-0.9007199254740991"); + //check("-0.999999999999999"); + //check("-0.99999999999999"); + //check("-0.9999999999999"); + //check("-0.999999999999"); + //check("-0.99999999999"); + //check("-0.9999999999"); + //check("-0.999999999"); + //check("-0.99999999"); + //check("-0.9999999"); + //check("-0.999999"); + //check("-0.99999"); + //check("-0.9999"); + //check("-0.8125"); + //check("-0.999"); + //check("-0.99"); + check("-1.0"); + check("-0.9"); + check("-0.0"); + check( "0.0"); + check( "0.9"); + //check( "0.99"); + //check( "0.999"); + //check( "0.8125"); + //check( "0.9999"); + //check( "0.99999"); + //check( "0.999999"); + //check( "0.9999999"); + //check( "0.99999999"); + //check( "0.999999999"); + //check( "0.9999999999"); + //check( "0.99999999999"); + //check( "0.999999999999"); + //check( "0.9999999999999"); + //check( "0.99999999999999"); + //check( "0.999999999999999"); + //check( "0.9007199254740991"); + check( "0.9999999999999999"); + //check( "0.9999999999999999999999"); + //check( "0.999999999999999999999999999"); + + check("-1e308"); + check("-1e-308"); + //check("-9999e300"); + //check("-999e100"); + //check("-99e10"); + check("-9e1"); + check( "9e1"); + //check( "99e10"); + //check( "999e100"); + //check( "9999e300"); + check( "999999999999999999.0"); + check( "999999999999999999999.0"); + check( "999999999999999999999e5"); + check( "999999999999999999999.0e5"); + + check("-1e-1"); + check("-1e0"); + check("-1e1"); + check( "0e0"); + check( "1e0"); + check( "1e10"); + } + + void + testArray() + { + check("[]"); + check("[[]]"); + check("[[],[],[]]"); + check("[[[[[[[[[[]]]]]]]]]]"); + check("[{}]"); + check("[{},{}]"); + check("[1,2,3,4,5]"); + check("[true,false,null]"); + } + + void + testObject() + { + check("{}"); + check("{\"x\":1}"); + check("{\"x\":[]}"); + check("{\"x\":1,\"y\":null}"); + } + + //------------------------------------------------------ + + void + testMembers() + { + // serializer() + { + serializer sr; + + char buf[32]; + BOOST_TEST(sr.read(buf) == "null"); + } + + // done() + { + value jv = 1; + serializer sr; + sr.reset(&jv); + BOOST_TEST(! sr.done()); + char buf[32]; + BOOST_TEST(sr.read(buf) == "1"); + BOOST_TEST(sr.done()); + } + + // read() + { + value jv = 1; + serializer sr; + sr.reset(&jv); + char buf[1024]; + auto const s = sr.read(buf); + BOOST_TEST(sr.done()); + BOOST_TEST(s == "1"); + } + + // checked read() + { + serializer sr; + char buf[100]; + BOOST_TEST(sr.read(buf, 50) == "null"); + } + + // reset(value) + { + char buf[100]; + serializer sr; + value jv = { 1, 2, 3 }; + sr.reset(&jv); + BOOST_TEST(sr.read(buf) == "[1,2,3]"); + } + + // reset(array) + { + char buf[100]; + serializer sr; + array arr = { 1, 2, 3 }; + sr.reset(&arr); + BOOST_TEST(sr.read(buf) == "[1,2,3]"); + } + + // reset(object) + { + char buf[100]; + serializer sr; + object obj = { {"k1",1}, {"k2",2} }; + sr.reset(&obj); + BOOST_TEST(sr.read(buf) == "{\"k1\":1,\"k2\":2}"); + } + + // reset(string) + { + char buf[100]; + serializer sr; + string str = "123"; + sr.reset(&str); + BOOST_TEST(sr.read(buf) == "\"123\""); + } + } + + void + check( + string_view s, + string_view name = {}) + { + try + { + auto const jv = parse(s); + grind(s, jv, name); + } + catch(std::exception const&) + { + BOOST_TEST_FAIL(); + } + } + + void + testVectors() + { +#if 0 + check( + R"xx({ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } + })xx"); +#endif + + parse_vectors const pv; + for(auto const e : pv) + { + if(e.result != 'y') + continue; + // skip these failures for now + if( + e.name == "number" || + e.name == "number_real_exponent" || + e.name == "number_real_fraction_exponent" || + e.name == "number_simple_real" || + e.name == "object_extreme_numbers" || + e.name == "pass01" + ) + continue; + check(e.text, e.name); + } + } + + std::string + to_ostream(value const& jv) + { + std::stringstream ss; + ss << jv; + return ss.str(); + } + + void + testOstream() + { + for(string_view js : { + "{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1," + "\"5\":-1,\"6\":144.0,\"7\":false,\"8\":null}", + "[1,2,3,4,5]" + }) + { + error_code ec; + auto const jv1 = parse(js, ec); + if(! BOOST_TEST(! ec)) + return; + auto const jv2 = + parse(to_ostream(jv1), ec); + if(! BOOST_TEST(! ec)) + return; + if(! BOOST_TEST(equal(jv1, jv2))) + log << + " " << js << "\n" + " " << jv1 << "\n" + " " << jv2 << + std::endl; + } + } + + void + testNumberRoundTrips() + { + // no decimal or exponent parsed as integer + BOOST_TEST(parse("-0").as_int64() == 0); + BOOST_TEST(serialize(parse("-0")) == "0"); + BOOST_TEST(parse("-0.0").as_double() == -0); + BOOST_TEST(serialize(parse("0.0")) == "0E0"); + BOOST_TEST(parse("0.0").as_double() == 0); + BOOST_TEST(serialize(parse("-0.0")) == "-0E0"); + } + + void + run() + { + testNull(); + testBoolean(); + testString(); + testNumber(); + testArray(); + testObject(); + + testMembers(); + testVectors(); + testOstream(); + testNumberRoundTrips(); + } +}; + +TEST_SUITE(serializer_test, "boost.json.serializer"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/snippets.cpp b/src/boost/libs/json/test/snippets.cpp new file mode 100644 index 000000000..5d7893f3a --- /dev/null +++ b/src/boost/libs/json/test/snippets.cpp @@ -0,0 +1,903 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json.hpp> + +#include <algorithm> +#include <cmath> +#include <complex> +#include <iostream> +#include <map> +#include <numeric> +#include <string> +#include <unordered_map> +#include <vector> + +#include "test_suite.hpp" + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4101) +#elif defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunused" +# pragma clang diagnostic ignored "-Wmismatched-tags" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused" +#endif + +//[snippet_conv_3 + +template< std::size_t N > +struct static_string { }; + +namespace std +{ + +template< std::size_t N > +class hash< static_string< N > > +{ +public: + std::size_t + operator()(const static_string< N >& str ) const noexcept + { + return std::hash< std::string >()( str ); + } +}; + +} // std + +//] + +BOOST_JSON_NS_BEGIN + +//[snippet_conv_4 + +template< class T > +void +tag_invoke( const value_from_tag&, value& jv, std::complex< T > const& t) +{ + // Store a complex number as a 2-element array + // with the real part followed by the imaginary part + jv = { t.real(), t.imag() }; +} + +template< class T > +std::complex< T > +tag_invoke( const value_to_tag< std::complex< T > >&, value const& jv ) +{ + return std::complex< T >( + jv.as_array().at(0).to_number< T >(), + jv.as_array().at(1).to_number< T >()); +} + +//] + +namespace { + +void +usingStrings() +{ + { + //[snippet_strings_1 + + string str1; // empty string, uses the default memory resource + + string str2( make_shared_resource<monotonic_resource>() ); // empty string, uses a counted monotonic resource + + //] + } + { + //[snippet_strings_2 + + std::string sstr1 = "helloworld"; + std::string sstr2 = "world"; + + json::string jstr1 = "helloworld"; + json::string jstr2 = "world"; + + assert( jstr2.insert(0, jstr1.subview(0, 5)) == "helloworld" ); + + // this is equivalent to + assert( sstr2.insert(0, sstr1, 0, 5) == "helloworld" ); + + //] + } + { + //[snippet_strings_3 + + std::string sstr = "hello"; + + json::string jstr = "hello"; + + assert(sstr.append({'w', 'o', 'r', 'l', 'd'}) == "helloworld"); + + // such syntax is inefficient, and the same can + // be achieved with a character array. + + assert(jstr.append("world") == "helloworld"); + + //] + } + + { + //[snippet_strings_4 + + json::string str = "Boost.JSON"; + json::string_view sv = str; + + // all of these call compare(string_view) + str.compare(sv); + + str.compare(sv.substr(0, 5)); + + str.compare(str); + + str.compare("Boost"); + + //] + } +} + +//---------------------------------------------------------- + +void +usingValues() +{ + { + //[snippet_value_1 + + value jv1; + value jv2( nullptr ); + + assert( jv1.is_null() ); + assert( jv2.is_null() ); + + //] + } + { + //[snippet_value_2 + + value jv( object_kind ); + + assert( jv.kind() == kind::object ); + assert( jv.is_object() ); + assert( ! jv.is_number() ); + + //] + } + { + auto f = []{ + //[snippet_value_3 + + value jv( object_kind ); + + if( auto p = jv.if_object() ) + return p->size(); + + //] + return std::size_t(0); + }; + (void)f; + } + { + //[snippet_value_4 + + value jv; + jv = value( array_kind ); + + assert( jv.is_array() ); + + jv.emplace_string(); + + assert( jv.is_string() ); + + //] + } + { + //[snippet_value_5 + + value jv; + jv.emplace_string() = "Hello, world!"; + + int64_t& num = jv.emplace_int64(); + num = 1; + + assert( jv.is_int64() ); + + //] + } + { + try + { + //[snippet_value_6 + + value jv( true ); + jv.as_bool() = true; + + jv.as_string() = "Hello, world!"; // throws an exception + + //] + } + catch(...) + { + } + } + { + //[snippet_value_7 + + value jv( string_kind ); + if( string* str = jv.if_string() ) + *str = "Hello, world!"; + + //] + } + { + //[snippet_value_8 + + value jv( string_kind ); + + // The compiler's static analysis can see that + // a null pointer is never dereferenced. + *jv.if_string() = "Hello, world!"; + + //] + } +} + +//---------------------------------------------------------- + +void +usingInitLists() +{ + { + //[snippet_init_list_1 + + value jv = { + { "name", "John Doe" }, + { "active", true }, + { "associated-accounts", nullptr }, + { "total-balance", 330.00 }, + { "account-balances", { 84, 120, 126 } } }; + + //] + } + + { + //[snippet_init_list_2 + + value jv = { true, 2, "hello", nullptr }; + + assert( jv.is_array() ); + + assert( jv.as_array().size() == 4 ); + + assert( serialize(jv) == "[true,2,\"hello\",null]" ); + + //] + } + + { + //[snippet_init_list_3 + + value jv = { true, 2, "hello", { "bye", nullptr, false } }; + + assert( jv.is_array() ); + + assert( jv.as_array().back().is_array() ); + + assert( serialize(jv) == "[true,2,\"hello\",[\"bye\",null,false]]" ); + + //] + } + + { + //[snippet_init_list_4 + + // Should this be an array or an object? + value jv = { { "hello", 42 }, { "world", 43 } }; + + //] + } + + { + //[snippet_init_list_5 + + value jv1 = { { "hello", 42 }, { "world", 43 } }; + + assert( jv1.is_object() ); + + assert( jv1.as_object().size() == 2 ); + + assert( serialize(jv1) == R"({"hello":42,"world":43})" ); + + // All of the following are arrays + + value jv2 = { { "make", "Tesla" }, { "model", 3 }, "black" }; + + value jv3 = { { "library", "JSON" }, { "Boost", "C++", "Fast", "JSON" } }; + + value jv4 = { { "color", "blue" }, { 1, "red" } }; + + assert( jv2.is_array() && jv3.is_array() && jv4.is_array() ); + + //] + } + + { + //[snippet_init_list_6 + + value jv = { { "hello", 42 }, array{ "world", 43 } }; + + assert( jv.is_array() ); + + array& ja = jv.as_array(); + + assert( ja[0].is_array() && ja[1].is_array()); + + assert ( serialize(jv) == R"([["hello",42],["world",43]])" ); + + //] + + (void)ja; + } + + { + //[snippet_init_list_7 + + value jv = { { "mercury", 36 }, { "venus", 67 }, { "earth", 93 } }; + + assert( jv.is_object() ); + + assert( serialize(jv) == "{\"mercury\":36,\"venus\":67,\"earth\":93}" ); + + array ja = { { "mercury", 36 }, { "venus", 67 }, { "earth", 93 } }; + + assert( serialize(ja) == "[[\"mercury\",36],[\"venus\",67],[\"earth\",93]]" ); + + //] + + (void)ja; + } + + { + //[snippet_init_list_8 + + object jo = { { "mercury", { { "distance", 36 } } }, { "venus", { 67, "million miles" } }, { "earth", 93 } }; + + assert( jo["mercury"].is_object() ); + + assert( jo["venus"].is_array() ); + + //] + } + + { + //[snippet_init_list_9 + + object jo1 = { { "john", 100 }, { "dave", 500 }, { "joe", 300 } }; + + value jv = { { "clients", std::move(jo1) } }; + + object& jo2 = jv.as_object()["clients"].as_object(); + + assert( ! jo2.empty() && jo1.empty() ); + + assert( serialize(jv) == R"({"clients":{"john":100,"dave":500,"joe":300}})" ); + + //] + + (void)jo2; + } +} + +//---------------------------------------------------------- + +void +usingArrays() +{ + { + //[snippet_arrays_1 + + array arr1; // empty array, uses the default memory resource + + array arr2( make_shared_resource<monotonic_resource>() ); // empty array, uses a counted monotonic resource + + //] + } + { + //[snippet_arrays_2 + + array arr( { "Hello", 42, true } ); + + //] + } + try + { + //[snippet_arrays_3 + + array arr; + + arr.emplace_back( "Hello" ); + arr.emplace_back( 42 ); + arr.emplace_back( true ); + + //] + + //[snippet_arrays_4 + + assert( arr[0].as_string() == "Hello" ); + + // The following line throws std::out_of_range, since the index is out of range + arr.at( 3 ) = nullptr; + + //] + } + catch (...) + { + } +} + +//---------------------------------------------------------- + +void +usingObjects() +{ + { + //[snippet_objects_1 + + object obj1; // empty object, uses the default memory resource + + object obj2( make_shared_resource<monotonic_resource>() ); // empty object, uses a counted monotonic resource + + //] + } + { + //[snippet_objects_2 + + object obj( {{"key1", "value1" }, { "key2", 42 }, { "key3", false }} ); + + //] + } + { + //[snippet_objects_3 + + object obj; + + obj.emplace( "key1", "value1" ); + obj.emplace( "key2", 42 ); + obj.emplace( "key3", false ); + + //] + } + try + { + //[snippet_objects_4 + + object obj; + + obj["key1"] = "value1"; + obj["key2"] = 42; + obj["key3"] = false; + + // The following line throws std::out_of_range, since the key does not exist + obj.at( "key4" ); + + //] + } + catch (...) + { + } +} + +//---------------------------------------------------------- + +//[snippet_conv_2 + +template< class T > +void identity_swap( T& a, T& b ) +{ + // introduces the declaration of + // std::swap into this scope + using std::swap; + if( &a == &b ) + return; + // the overload set will contain std::swap, + // any declarations of swap within the enclosing + // namespace, and any declarations of swap within + // the namespaces associated with T + swap( a, b ); +} + +//] + +//[snippet_conv_5 + +template< class T > +struct vec3 +{ + T x, y, z; +}; + +template< class T > +void tag_invoke( const value_from_tag&, value& jv, const vec3<T>& vec ) +{ + jv = { + { "x", vec.x }, + { "y", vec.y }, + { "z", vec.z } + }; +} + +//] + +#ifdef BOOST_JSON_DOCS +//[snippet_conv_7 + +template< class T, typename std::enable_if< + std::is_floating_point< T >::value>::type* = nullptr > +void tag_invoke( const value_from_tag&, value& jv, T t ) +{ + jv = std::llround( t ); +} + +//] +#endif + +//[snippet_conv_10 + +struct customer +{ + std::uint64_t id; + std::string name; + bool late; + + customer() = default; + + customer( std::uint64_t i, const std::string& n, bool l ) + : id( i ), name( n ), late( l ) { } + + explicit customer( value const& ); +}; + +void tag_invoke( const value_from_tag&, value& jv, customer const& c ) +{ + // Assign a JSON value + jv = { + { "id", c.id }, + { "name", c.name }, + { "late", c.late } + }; +} + +//] + +//[snippet_conv_14 + +customer tag_invoke( const value_to_tag<customer>&, const value& jv ) +{ + // at() throws if `jv` is not an object, or if the key is not found. + // as_uint64() will throw if the value is not an unsigned 64-bit integer. + std::uint64_t id = jv.at( "id" ).as_uint64(); + + // We already know that jv is an object from + // the previous call to jv.as_object() succeeding, + // now we use jv.get_object() which skips the + // check. value_to will throw if jv.kind() != kind::string + std::string name = value_to< std::string >( jv.get_object().at( "name" ) ); + + // id and name are constructed from JSON in the member + // initializer list above, but we can also use regular + // assignments in the body of the function as shown below. + // as_bool() will throw if kv.kind() != kind::bool + bool late = jv.get_object().at( "late" ).as_bool(); + + return customer(id, name, late); +} + +//] + +void +usingExchange() +{ + { + //[snippet_conv_1 + + std::vector< int > v1{ 1, 2, 3, 4 }; + + // Convert the vector to a JSON array + value jv = value_from( v1 ); + + assert( jv.is_array() ); + + array& ja = jv.as_array(); + + assert( ja.size() == 4 ); + + for ( std::size_t i = 0; i < v1.size(); ++i ) + assert( v1[i] == ja[i].as_int64() ); + + // Convert back to vector< int > + std::vector< int > v2 = value_to< std::vector< int > >( jv ); + + assert( v1 == v2 ); + + //] + + (void)ja; + } + { + //[snippet_conv_6 + + vec3< int > pos = { 4, 1, 4 }; + + value jv = value_from( pos ); + + assert( serialize( jv ) == "{\"x\":4,\"y\":1,\"z\":4}" ); + + //] + } + { + //[snippet_conv_8 + + value jv = value_from( 1.5 ); // error + + //] + } + { + //[snippet_conv_9 + + std::map< std::string, vec3< int > > positions = { + { "Alex", { 42, -60, 18 } }, + { "Blake", { 300, -60, -240} }, + { "Carol", { -60, 30, 30 } } + }; + + // conversions are applied recursively; + // the key type and value type will be converted + // using value_from as well + value jv = value_from( positions ); + + assert( jv.is_object() ); + + object& jo = jv.as_object(); + + assert( jo.size() == 3 ); + + // The sum of the coordinates is 0 + assert( std::accumulate( jo.begin(), jo.end(), std::int64_t(0), + []( std::int64_t total, const key_value_pair& jp ) + { + assert ( jp.value().is_object() ); + + const object& pos = jp.value().as_object(); + + return total + pos.at( "x" ).as_int64() + + pos.at( "y" ).as_int64() + + pos.at( "z" ).as_int64(); + + } ) == 0 ); + + //] + + (void)jo; + } + { + //[snippet_conv_11 + + std::vector< customer > customers = { + customer( 0, "Alison", false ), + customer( 1, "Bill", false ), + customer( 3, "Catherine", true ), + customer( 4, "Doug", false ) + }; + + storage_ptr sp = make_shared_resource< monotonic_resource >(); + + value jv = value_from( customers, sp ); + + assert( jv.storage() == sp ); + + assert( jv.is_array() ); + + //] + } + + { + //[snippet_conv_12 + + // Satisfies both FromMapLike and FromContainerLike + std::unordered_map< std::string, bool > available_tools = { + { "Crowbar", true }, + { "Hammer", true }, + { "Drill", true }, + { "Saw", false }, + }; + + value jv = value_from( available_tools ); + + assert( jv.is_object() ); + + //] + } + { + //[snippet_conv_13 + + std::complex< double > c1 = { 3.14159, 2.71828 }; + + // Convert a complex number to JSON + value jv = value_from( c1 ); + + assert ( jv.is_array() ); + + // Convert back to a complex number + + std::complex< double > c2 = value_to< std::complex< double > >( jv ); + + //] + + (void)c2; + } + { + //[snippet_conv_15 + + customer c1( 5, "Ed", false ); + + // Convert customer to value + value jv = value_from( c1 ); + + // Convert the result back to customer + customer c2 = value_to< customer >( jv ); + + // The resulting customer is unchanged + assert( c1.name == c2.name ); + + //] + } + { + //[snippet_conv_16 + + value available_tools = { + { "Crowbar", true }, + { "Hammer", true }, + { "Drill", true }, + { "Saw", false } + }; + + assert( available_tools.is_object() ); + + auto as_map = value_to< std::map< std::string, bool > >( available_tools ); + + assert( available_tools.as_object().size() == as_map.size() ); + + //] + } +} + +void +usingPointer() +{ + //[snippet_pointer_1 + value jv = { {"one", 1}, {"two", 2} }; + assert( jv.at("one") == jv.at_pointer("/one") ); + + jv.at_pointer("/one") = {{"foo", "bar"}}; + assert( jv.at("one").at("foo") == jv.at_pointer("/one/foo") ); + + jv.at_pointer("/one/foo") = {true, 4, "qwerty"}; + assert( jv.at("one").at("foo").at(1) == jv.at_pointer("/one/foo/1") ); + //] + + value* elem1 = [&]() -> value* + { + //[snippet_pointer_2 + object* obj = jv.if_object(); + if( !obj ) + return nullptr; + + value* val = obj->if_contains("one"); + if( !val ) + return nullptr; + + obj = val->if_object(); + if( !obj ) + return nullptr; + + val = obj->if_contains("foo"); + if( !val ) + return nullptr; + + array* arr = val->if_array(); + if( !arr ) + return nullptr; + + return arr->if_contains(1); + //] + }(); + + value* elem2 = [&]() -> value* + { + //[snippet_pointer_3 + error_code ec; + return jv.find_pointer("/one/foo/1", ec); + //] + }(); + + (void)elem1; + (void)elem2; + assert( elem1 == elem2 ); +} + +BOOST_STATIC_ASSERT( + has_value_from<customer>::value); + +BOOST_STATIC_ASSERT( + has_value_from<std::complex<float>>::value); +BOOST_STATIC_ASSERT( + has_value_from<std::complex<double>>::value); + +BOOST_STATIC_ASSERT( + has_value_to<std::complex<float>>::value); +BOOST_STATIC_ASSERT( + has_value_to<std::complex<double>>::value); + +} // (anon) + +} // json +} // boost + +//---------------------------------------------------------- + + +namespace { + +class my_non_deallocating_resource { }; + +} // (anon) + +//[snippet_allocators_14 +namespace boost { +namespace json { + +template<> +struct is_deallocate_trivial< my_non_deallocating_resource > +{ + static constexpr bool value = true; +}; + +} // json +} // boost + +//] + +namespace boost { +namespace json { + +class snippets_test +{ +public: + void + run() + { + usingValues(); + usingInitLists(); + usingExchange(); + usingArrays(); + usingObjects(); + usingStrings(); + usingPointer(); + + BOOST_TEST_PASS(); + } +}; + +TEST_SUITE(snippets_test, "boost.json.snippets"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/static_resource.cpp b/src/boost/libs/json/test/static_resource.cpp new file mode 100644 index 000000000..c21fb0b65 --- /dev/null +++ b/src/boost/libs/json/test/static_resource.cpp @@ -0,0 +1,129 @@ +// +// Copyright (c) 2020 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/static_resource.hpp> + +#include <boost/json/parse.hpp> +#include <boost/json/serialize.hpp> +#include <iostream> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<static_resource>::value ); + +class static_resource_test +{ +public: + void + testJavadocs() + { + //-------------------------------------- + + unsigned char buf[ 4000 ]; + static_resource mr( buf ); + + // Parse the string, using our memory resource + value jv = parse( "[1,2,3]", &mr ); + + // Print the JSON + std::cout << jv; + + //-------------------------------------- + } + + void + test() + { + // static_resource(unsigned char*, size_t) + { + unsigned char buf[1000]; + static_resource mr( + &buf[0], sizeof(buf)); + BOOST_TEST(serialize(parse( + "[1,2,3]", &mr)) == "[1,2,3]"); + } + + #if defined(__cpp_lib_byte) + // static_resource(std::byte*, size_t) + { + std::byte buf[1000]; + static_resource mr( + &buf[0], sizeof(buf)); + BOOST_TEST(serialize(parse( + "[1,2,3]", &mr)) == "[1,2,3]"); + } + #endif + + // static_resource(unsigned char[N]) + { + unsigned char buf[10]; + static_resource mr(buf); + BOOST_TEST_THROWS( + serialize(parse("[1,2,3]", &mr)), + std::bad_alloc); + } + + #if defined(__cpp_lib_byte) + // static_resource(std::byte[N]) + { + std::byte buf[10]; + static_resource mr(buf); + BOOST_TEST_THROWS( + serialize(parse("[1,2,3]", &mr)), + std::bad_alloc); + } + #endif + + // static_resource(unsigned char[N], size_t) + { + unsigned char buf[1000]; + static_resource mr( + buf, 500); + BOOST_TEST(serialize(parse( + "[1,2,3]", &mr)) == "[1,2,3]"); + } + + #if defined(__cpp_lib_byte) + // static_resource(std::byte[N]) + { + std::byte buf[1000]; + static_resource mr( + buf, 500); + BOOST_TEST(serialize(parse( + "[1,2,3]", &mr)) == "[1,2,3]"); + } + #endif + + // release() + { + unsigned char buf[10]; + static_resource mr( + buf, sizeof(buf)); + (void)mr.allocate(10,1); + BOOST_TEST_THROWS( + mr.allocate(10,1), + std::bad_alloc); + mr.release(); + (void)mr.allocate(10,1); + } + } + + void + run() + { + test(); + } +}; + +TEST_SUITE(static_resource_test, "boost.json.static_resource"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/storage_ptr.cpp b/src/boost/libs/json/test/storage_ptr.cpp new file mode 100644 index 000000000..3669c4096 --- /dev/null +++ b/src/boost/libs/json/test/storage_ptr.cpp @@ -0,0 +1,214 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/storage_ptr.hpp> + +#include <type_traits> + +#include "test.hpp" +#include "test_suite.hpp" + +//---------------------------------------------------------- + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4702) // unreachable code +#endif + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( + std::is_nothrow_move_constructible<storage_ptr>::value); + +class storage_ptr_test +{ +public: + static value jv1; + static value jv2; + + struct throwing + : memory_resource + { + throwing() + { + throw std::exception{}; + } + + void* + do_allocate( + std::size_t, + std::size_t) override + { + return nullptr; + } + + void + do_deallocate( + void*, + std::size_t, + std::size_t) noexcept override + { + } + + bool + do_is_equal( + memory_resource const& mr) const noexcept override + { + return this == &mr; + } + }; + + void + testMembers() + { + auto const dsp = storage_ptr{}; + auto const usp = + make_shared_resource<unique_resource>(); + + // ~storage_ptr() + { + // implied + } + + // storage_ptr() + { + storage_ptr sp; + BOOST_TEST(sp.get()); + } + + // storage_ptr(storage_ptr&&) + { + storage_ptr sp1 = dsp; + storage_ptr sp2(std::move(sp1)); + BOOST_TEST(sp1.get()); + BOOST_TEST(*sp2 == *dsp); + } + + // storage_ptr(storage_ptr const&) + { + storage_ptr sp1 = dsp; + storage_ptr sp2(sp1); + BOOST_TEST(sp1 == sp2); + } + + // operator=(storage_ptr&&) + { + storage_ptr sp1(dsp); + storage_ptr sp2(usp); + sp2 = std::move(sp1); + BOOST_TEST(*sp2 == *dsp); + } + + // operator=(storage_ptr const&) + { + storage_ptr sp1(dsp); + storage_ptr sp2(usp); + sp2 = sp1; + BOOST_TEST(*sp1 == *sp2); + } + + // get() + { + { + storage_ptr sp(dsp); + BOOST_TEST(sp.get() == dsp.get()); + } + } + + // operator->() + { + storage_ptr sp(dsp); + BOOST_TEST(sp.operator->() == dsp.get()); + } + + // operator*() + { + storage_ptr sp(dsp); + BOOST_TEST(&sp.operator*() == dsp.get()); + } + + // exception in make_storage + { + BOOST_TEST_THROWS( + make_shared_resource<throwing>(), + std::exception); + } + } + + // https://github.com/boostorg/json/pull/182 + void + testPull182() + { + struct other + { + virtual void f() {} + }; + + struct my_resource + : other + , memory_resource + { + void* + do_allocate( + std::size_t, + std::size_t) override + { + return nullptr; + } + + void + do_deallocate( + void*, + std::size_t, + std::size_t) noexcept override + { + } + + bool + do_is_equal( + memory_resource const&) const noexcept override + { + return true; + } + }; + + my_resource mr; + BOOST_TEST(storage_ptr(&mr).get() == &mr); + } + + void + testInitOrder() + { + BOOST_ASSERT(jv1.storage() == jv2.storage()); + BOOST_TEST(! jv1.storage().is_deallocate_trivial()); + BOOST_TEST(! jv1.storage().is_shared()); + } + + void + run() + { + storage_ptr sp; + + testMembers(); + testPull182(); + testInitOrder(); + } +}; + +value storage_ptr_test::jv1 = {1, 2, 3}; +value storage_ptr_test::jv2 = {1, 2, 3}; + +TEST_SUITE(storage_ptr_test, "boost.json.storage_ptr"); + +BOOST_JSON_NS_END + +#ifdef _MSC_VER +#pragma warning(pop) +#endif diff --git a/src/boost/libs/json/test/stream_parser.cpp b/src/boost/libs/json/test/stream_parser.cpp new file mode 100644 index 000000000..7c92960d9 --- /dev/null +++ b/src/boost/libs/json/test/stream_parser.cpp @@ -0,0 +1,1284 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/stream_parser.hpp> + +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/parse.hpp> +#include <boost/json/serialize.hpp> + +#include <sstream> +#include <iostream> + +#include "parse-vectors.hpp" +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<stream_parser>::value ); + +class stream_parser_test +{ +public: + ::test_suite::log_type log; + + //------------------------------------------------------ + + void + testCtors() + { + // stream_parser(stream_parser const&) + BOOST_STATIC_ASSERT( + ! std::is_copy_constructible<stream_parser>::value); + + // operator=(stream_parser const&) + BOOST_STATIC_ASSERT( + ! std::is_copy_assignable<stream_parser>::value); + + // ~stream_parser() + { + { + stream_parser p; + } + + { + stream_parser p; + p.reset(make_shared_resource< + monotonic_resource>()); + } + } + + // stream_parser(storage_ptr, parse_options, unsigned char*, size_t) + { + unsigned char buf[256]; + stream_parser p( + storage_ptr(), + parse_options(), + &buf[0], + sizeof(buf)); + } + + // stream_parser() + { + stream_parser p; + } + + // stream_parser(storage_ptr, parse_options) + { + stream_parser p(storage_ptr{}, parse_options()); + } + + // stream_parser(storage_ptr) + { + stream_parser p(storage_ptr{}); + } + + // stream_parser(storage_ptr, parse_options, unsigned char[]) + { + unsigned char buf[256]; + stream_parser p( + storage_ptr(), + parse_options(), + buf); + } + + #if defined(__cpp_lib_byte) + // stream_parser(storage_ptr, parse_options, std::byte*, size_t) + { + std::byte buf[256]; + stream_parser p( + storage_ptr(), + parse_options(), + &buf[0], + sizeof(buf)); + } + + // stream_parser(storage_ptr, parse_options, std::byte[]) + { + std::byte buf[256]; + stream_parser p( + storage_ptr(), + parse_options(), + buf); + } + #endif + + // stream_parser(storage_ptr, parse_options, unsigned char[], size_t) + { + unsigned char buf[256]; + stream_parser p( + storage_ptr(), + parse_options(), + buf, + sizeof(buf)); + } + + #if defined(__cpp_lib_byte) + // stream_parser(storage_ptr, parse_options, std::byte[], size_t) + { + std::byte buf[256]; + stream_parser p( + storage_ptr(), + parse_options(), + buf, + sizeof(buf)); + } + #endif + } + + void + testMembers() + { + // write_some(char const*, size_t, error_code&) + // write_some(char const*, size_t, std::error_code&) + // write_some(string_view, error_code&) + // write_some(string_view, std::error_code&) + { + { + stream_parser p; + error_code ec; + BOOST_TEST(p.write_some( + "[]*", ec) == 2); + BOOST_TEST(! ec); + } + { + stream_parser p; + std::error_code ec; + BOOST_TEST(p.write_some( + "[]*", ec) == 2); + BOOST_TEST(! ec); + } + { + stream_parser p; + error_code ec; + BOOST_TEST(p.write_some( + "[*", ec) == 1); + BOOST_TEST(ec); + } + { + stream_parser p; + std::error_code ec; + BOOST_TEST(p.write_some( + "[*", ec) == 1); + BOOST_TEST(ec); + } + } + + // write_some(char const*, size_t) + // write_some(string_view) + { + { + stream_parser p; + BOOST_TEST( + p.write_some("[]*") == 2); + } + { + stream_parser p; + BOOST_TEST_THROWS( + p.write_some("[*"), + system_error); + } + } + + // write(char const*, size_t, error_code&) + // write(char const*, size_t, std::error_code&) + // write(string_view, error_code&) + // write(string_view, std::error_code&) + { + { + stream_parser p; + error_code ec; + BOOST_TEST(p.write( + "null", ec) == 4); + BOOST_TEST(! ec); + } + { + stream_parser p; + std::error_code ec; + BOOST_TEST(p.write( + "null", ec) == 4); + BOOST_TEST(! ec); + } + { + stream_parser p; + error_code ec; + p.write("[]*", ec), + BOOST_TEST( + ec == error::extra_data); + BOOST_TEST(ec.has_location()); + } + { + stream_parser p; + std::error_code ec; + p.write("[]*", ec), + BOOST_TEST(ec == error::extra_data); + } + } + + // write(char const*, size_t) + // write(string_view) + { + { + stream_parser p; + BOOST_TEST(p.write( + "null") == 4); + } + { + stream_parser p; + BOOST_TEST_THROWS( + p.write("[]*"), + system_error); + } + } + + // finish() + // finish(error_code&) + // finish(std::error_code&) + { + { + stream_parser p; + p.write("1"); + BOOST_TEST(! p.done()); + p.finish(); + BOOST_TEST(p.done()); + } + { + stream_parser p; + BOOST_TEST(! p.done()); + p.write("1."); + BOOST_TEST_THROWS( + p.finish(), + system_error); + } + { + stream_parser p; + p.write("[1,2"); + error_code ec; + p.finish(ec); + BOOST_TEST( + ec == error::incomplete); + BOOST_TEST(ec.has_location()); + } + { + stream_parser p; + p.write("[1,2"); + error_code ec; + p.finish(ec); + BOOST_TEST_THROWS( + p.finish(), + system_error); + } + { + stream_parser p; + p.write("[1,2"); + std::error_code ec; + p.finish(ec); + BOOST_TEST(ec == error::incomplete); + } + { + stream_parser p; + p.write("[1,2"); + std::error_code ec; + p.finish(ec); + BOOST_TEST_THROWS( + p.finish(), + system_error); + } + } + + // release() + { + { + stream_parser p; + BOOST_TEST( + p.write_some("[") == 1); + BOOST_TEST(! p.done()); + BOOST_TEST_THROWS( + p.release(), + system_error); + } + { + stream_parser p; + BOOST_TEST( + p.write_some("[]*") == 2); + BOOST_TEST(p.done()); + p.release(); + } + { + stream_parser p; + p.write("["); + BOOST_TEST(! p.done()); + BOOST_TEST_THROWS( + p.release(), + system_error); + } + { + stream_parser p; + error_code ec; + p.write("[]*", ec); + BOOST_TEST( + ec == error::extra_data); + BOOST_TEST(ec.has_location()); + BOOST_TEST(! p.done()); + BOOST_TEST_THROWS( + p.release(), + system_error); + } + } + } + + //------------------------------------------------------ + + static + value + from_string_test( + string_view s, + storage_ptr sp = {}, + const parse_options& po = parse_options()) + { + stream_parser p(storage_ptr(), po); + error_code ec; + p.reset(std::move(sp)); + p.write(s.data(), s.size(), ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + BOOST_TEST(! ec); + return p.release(); + } + + void + static + check_round_trip(value const& jv1, + const parse_options& po = parse_options()) + { + auto const s2 = + //to_string_test(jv1); // use this if serializer is broken + serialize(jv1); + auto jv2 = + from_string_test(s2, {}, po); + BOOST_TEST(equal(jv1, jv2)); + } + + template<class F> + void + static + grind_one( + string_view s, + storage_ptr sp, + F const& f, + const parse_options& po = parse_options()) + { + auto const jv = + from_string_test(s, sp, po); + f(jv, po); + } + + static + void + grind_one(string_view s) + { + auto const jv = + from_string_test(s); + check_round_trip(jv); + } + + template<class F> + static + void + grind(string_view s, F const& f, + const parse_options& po = parse_options()) + { + try + { + grind_one(s, {}, f, po); + + fail_loop([&](storage_ptr const& sp) + { + grind_one(s, sp, f, po); + }); + + if(s.size() > 1) + { + // Destroy the stream_parser at every + // split point to check leaks. + for(std::size_t i = 1; + i < s.size(); ++i) + { + fail_resource mr; + mr.fail_max = 0; + stream_parser p(storage_ptr(), po); + error_code ec; + p.reset(&mr); + p.write(s.data(), i, ec); + if(BOOST_TEST(! ec)) + p.write( + s.data() + i, + s.size() - i, ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + if(BOOST_TEST(! ec)) + f(p.release(), po); + } + } + } + catch(std::exception const&) + { + BOOST_TEST_FAIL(); + } + } + + static + void + grind(string_view s, + const parse_options& po = parse_options()) + { + grind(s, + [](value const& jv, const parse_options& po) + { + check_round_trip(jv, po); + }, po); + } + + static + void + grind_int64(string_view s, int64_t v) + { + grind(s, + [v](value const& jv, const parse_options&) + { + if(! BOOST_TEST(jv.is_int64())) + return; + BOOST_TEST(jv.get_int64() == v); + }); + } + + static + void + grind_uint64(string_view s, uint64_t v) + { + grind(s, + [v](value const& jv, const parse_options&) + { + if(! BOOST_TEST(jv.is_uint64())) + return; + BOOST_TEST(jv.get_uint64() == v); + }); + } + + static + void + grind_double(string_view s, double v) + { + grind(s, + [v](value const& jv, const parse_options&) + { + if(! BOOST_TEST(jv.is_double())) + return; + BOOST_TEST(jv.get_double() == v); + }); + } + + //------------------------------------------------------ + + void + testNull() + { + grind("null"); + grind(" null"); + grind(" null"); + grind("null\n"); + grind("null\n\n"); + grind("\r null\t "); + } + + void + testBool() + { + grind("true"); + grind(" true"); + grind(" true"); + grind("true\n"); + grind("true\n\n"); + grind("\r true\t "); + + grind("false"); + grind(" false"); + grind(" false"); + grind("false\n"); + grind("false\n\n"); + grind("\r false\t "); + } + + //------------------------------------------------------ + + void + testString() + { + grind("\"\""); + grind("\"x\""); + grind(" \"x\""); + grind(" \"x\""); + grind("\"x\"\n"); + grind("\"x\"\n\n"); + grind("\r \"x\"\t "); + + grind("\"abcdefghij\""); + grind("\"" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "\""); + grind("\"" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "\""); + + // escapes + grind("\"\\\"\""); + grind("\"\\\\\""); + grind("\"\\/\""); + grind("\"\\b\""); + grind("\"\\f\""); + grind("\"\\n\""); + grind("\"\\r\""); + grind("\"\\t\""); + + // unicode + grind("\"\\u0000\""); + grind("\"\\ud7fF\""); + grind("\"\\ue000\""); + grind("\"\\ufFfF\""); + grind("\"\\ud800\\udc00\""); + grind("\"\\udbff\\udffF\""); + + // big string + { + std::string const big(4000, '*'); + { + std::string js; + js = "\"" + big + "\""; + auto const N = js.size() / 2; + error_code ec; + stream_parser p; + p.write(js.data(), N, ec); + if(BOOST_TEST(! ec)) + { + p.write(js.data() + N, + js.size() - N, ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + if(BOOST_TEST(! ec)) + check_round_trip( + p.release()); + } + } + } + } + + //------------------------------------------------------ + + struct f_boost + { + static + string_view + name() noexcept + { + return "boost"; + } + + double + operator()(string_view s) const + { + BOOST_TEST_CHECKPOINT(); + error_code ec; + stream_parser p; + p.write(s.data(), s.size(), ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + if(! BOOST_TEST(! ec)) + return 0; + auto const jv = p.release(); + double const d = jv.as_double(); + grind_double(s, d); + return d; + } + }; + + bool + within_1ulp(double x, double y) + { + std::uint64_t bx, by; + std::memcpy(&bx, &x, sizeof(x)); + std::memcpy(&by, &y, sizeof(y)); + + auto diff = bx - by; + switch (diff) + { + case 0: + case 1: + case 0xffffffffffffffff: + return true; + default: + break; + } + return false; + } + + // Verify that f converts to the + // same double produced by `strtod`. + // Requires `s` is not represented by an integral type. + template<class F> + void + fc(std::string const& s, F const& f) + { + char* str_end; + double const need = + std::strtod(s.c_str(), &str_end); + // BOOST_TEST(str_end == &s.back() + 1); + double const got = f(s); + auto same = got == need; + auto close = same ? + true : within_1ulp(got, need); + + if( !BOOST_TEST(close) ) + { + std::cerr << "Failure on '" << s << "': " << got << " != " << need << "\n"; + } + } + + void + fc(std::string const& s) + { + fc(s, f_boost{}); + fc(s + std::string( 64, ' ' ), f_boost{}); + } + + void + testNumber() + { + grind("0"); + grind(" 0"); + grind(" 0"); + grind("0\n"); + grind("0\n\n"); + grind("\r 0\t "); + + grind_int64( "-9223372036854775808", INT64_MIN); + grind_int64( "-9223372036854775807", -9223372036854775807); + grind_int64( "-999999999999999999", -999999999999999999); + grind_int64( "-99999999999999999", -99999999999999999); + grind_int64( "-9999999999999999", -9999999999999999); + grind_int64( "-999999999999999", -999999999999999); + grind_int64( "-99999999999999", -99999999999999); + grind_int64( "-9999999999999", -9999999999999); + grind_int64( "-999999999999", -999999999999); + grind_int64( "-99999999999", -99999999999); + grind_int64( "-9999999999", -9999999999); + grind_int64( "-999999999", -999999999); + grind_int64( "-99999999", -99999999); + grind_int64( "-9999999", -9999999); + grind_int64( "-999999", -999999); + grind_int64( "-99999", -99999); + grind_int64( "-9999", -9999); + grind_int64( "-999", -999); + grind_int64( "-99", -99); + grind_int64( "-9", -9); + grind_int64( "-0", 0); + grind_int64( "0", 0); + grind_int64( "1", 1); + grind_int64( "9", 9); + grind_int64( "99", 99); + grind_int64( "999", 999); + grind_int64( "9999", 9999); + grind_int64( "99999", 99999); + grind_int64( "999999", 999999); + grind_int64( "9999999", 9999999); + grind_int64( "99999999", 99999999); + grind_int64( "999999999", 999999999); + grind_int64( "9999999999", 9999999999); + grind_int64( "99999999999", 99999999999); + grind_int64( "999999999999", 999999999999); + grind_int64( "9999999999999", 9999999999999); + grind_int64( "99999999999999", 99999999999999); + grind_int64( "999999999999999", 999999999999999); + grind_int64( "9999999999999999", 9999999999999999); + grind_int64( "99999999999999999", 99999999999999999); + grind_int64( "999999999999999999", 999999999999999999); + grind_int64( "9223372036854775807", INT64_MAX); + + grind_uint64( "9223372036854775808", 9223372036854775808ULL); + grind_uint64( "9999999999999999999", 9999999999999999999ULL); + grind_uint64( "18446744073709551615", UINT64_MAX); + + grind_double("-1.010", -1.01); + grind_double("-0.010", -0.01); + grind_double("-0.0", -0.0); + grind_double("-0e0", -0.0); + grind_double( "18446744073709551616", 1.8446744073709552e+19); + grind_double("-18446744073709551616", -1.8446744073709552e+19); + grind_double( "18446744073709551616.0", 1.8446744073709552e+19); + grind_double( "18446744073709551616.00009", 1.8446744073709552e+19); + grind_double( "1844674407370955161600000", 1.8446744073709552e+24); + grind_double("-1844674407370955161600000", -1.8446744073709552e+24); + grind_double( "1844674407370955161600000.0", 1.8446744073709552e+24); + grind_double( "1844674407370955161600000.00009", 1.8446744073709552e+24); + + grind_double( "1.0", 1.0); + grind_double( "1.1", 1.1); + grind_double( "1.11", 1.11); + grind_double( "1.11111", 1.11111); + grind_double( "11.1111", 11.1111); + grind_double( "111.111", 111.111); + + fc("-999999999999999999999"); + fc("-100000000000000000009"); + fc("-10000000000000000000"); + fc("-9223372036854775809"); + + fc("18446744073709551616"); + fc("99999999999999999999"); + fc("999999999999999999999"); + fc("1000000000000000000000"); + fc("9999999999999999999999"); + fc("99999999999999999999999"); + + fc("-0.9999999999999999999999"); + fc("-0.9999999999999999"); + fc("-0.9007199254740991"); + fc("-0.999999999999999"); + fc("-0.99999999999999"); + fc("-0.9999999999999"); + fc("-0.999999999999"); + fc("-0.99999999999"); + fc("-0.9999999999"); + fc("-0.999999999"); + fc("-0.99999999"); + fc("-0.9999999"); + fc("-0.999999"); + fc("-0.99999"); + fc("-0.9999"); + fc("-0.8125"); + fc("-0.999"); + fc("-0.99"); + fc("-1.0"); + fc("-0.9"); + fc("-0.0"); + fc("0.0"); + fc("0.9"); + fc("0.99"); + fc("0.999"); + fc("0.8125"); + fc("0.9999"); + fc("0.99999"); + fc("0.999999"); + fc("0.9999999"); + fc("0.99999999"); + fc("0.999999999"); + fc("0.9999999999"); + fc("0.99999999999"); + fc("0.999999999999"); + fc("0.9999999999999"); + fc("0.99999999999999"); + fc("0.999999999999999"); + fc("0.9007199254740991"); + fc("0.9999999999999999"); + fc("0.9999999999999999999999"); + fc("0.999999999999999999999999999"); + + fc("-1e308"); + fc("-1e-308"); + fc("-9999e300"); + fc("-999e100"); + fc("-99e10"); + fc("-9e1"); + fc("9e1"); + fc("99e10"); + fc("999e100"); + fc("9999e300"); + fc("999999999999999999.0"); + fc("999999999999999999999.0"); + fc("999999999999999999999e5"); + fc("999999999999999999999.0e5"); + + fc("0.00000000000000001"); + + fc("-1e-1"); + fc("-1e0"); + fc("-1e1"); + fc("0e0"); + fc("1e0"); + fc("1e10"); + + fc("0." + "00000000000000000000000000000000000000000000000000" // 50 zeroes + "1e50"); + fc("-0." + "00000000000000000000000000000000000000000000000000" // 50 zeroes + "1e50"); + + fc("0." + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" // 500 zeroes + "1e600"); + fc("-0." + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" // 500 zeroes + "1e600"); + + fc("0e" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" // 500 zeroes + ); + } + + //------------------------------------------------------ + + void + testArray() + { + grind("[]"); + grind(" []"); + grind("[] "); + grind(" [] "); + grind(" [ ] "); + grind("[1]"); + grind("[ 1]"); + grind("[1 ]"); + grind("[ 1 ]"); + grind("[1,2]"); + grind("[ 1,2]"); + grind("[1 ,2]"); + grind("[1, 2]"); + grind("[1,2 ]"); + grind("[ 1 ,2]"); + grind("[1 , 2]"); + grind("[1, 2 ]"); + + grind("[[]]"); + grind("[[],[]]"); + grind("[[],[],[]]"); + grind("[[[]],[[],[]],[[],[],[]]]"); + grind("[{},[],\"x\",1,-1,1.0,true,null]"); + + // depth + { + error_code ec; + parse_options opt; + opt.max_depth = 0; + stream_parser p(storage_ptr(), opt); + p.write("[]", 2, ec); + BOOST_TEST( + ec == error::too_deep); + BOOST_TEST(ec.has_location()); + } + } + + //------------------------------------------------------ + + void + testObject() + { + grind("{}"); + grind(" {}"); + grind("{} "); + grind(" {} "); + grind(" { } "); + grind("{\"1\":1}"); + grind("{ \"1\":1}"); + grind("{\"1\" :1}"); + grind("{\"1\": 1}"); + grind("{\"1\":1 }"); + grind("{ \"1\" :1 }"); + grind("{\"1\" : 1 }"); + grind("{\"1\":1,\"2\":2}"); + grind("{\"1\":1, \"2\":2}"); + grind("{\"1\":1, \"2\" : 2 }"); + + grind("{\"\":[]}"); + grind("{\"1\":[],\"2\":[]}"); + + grind( + "{\"1\":{\"2\":{}},\"3\":{\"4\":{},\"5\":{}}," + "\"6\":{\"7\":{},\"8\":{},\"9\":{}}}"); + + grind( + "{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1," + "\"5\":-1,\"6\":1.0,\"7\":false,\"8\":null}"); + + // big keys + { + std::string const big(4000, '*'); + { + std::string js; + js = "{\"" + big + "\":null}"; + grind(js); + } + + { + std::string js; + js = "{\"x\":\"" + big + "\"}"; + grind(js); + } + + { + std::string js; + js = "{\"" + big + "\":\"" + big + "\"}"; + grind(js); + } + } + + // depth + { + error_code ec; + parse_options opt; + opt.max_depth = 0; + stream_parser p(storage_ptr(), opt); + p.write("{}", 2, ec); + BOOST_TEST( + ec == error::too_deep); + BOOST_TEST(ec.has_location()); + } + } + + //------------------------------------------------------ + + void + testFreeFunctions() + { + string_view const js = + "{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1," + "\"5\":-1,\"6\":1.0,\"7\":false,\"8\":null}"; + + // parse(string_view, error_code) + { + { + error_code ec; + auto jv = parse(js, ec); + BOOST_TEST(! ec); + check_round_trip(jv); + } + { + error_code ec; + auto jv = parse("xxx", ec); + BOOST_TEST(ec); + BOOST_TEST(ec.has_location()); + BOOST_TEST(jv.is_null()); + } + } + + // parse(string_view, storage_ptr, error_code) + { + { + error_code ec; + monotonic_resource mr; + auto jv = parse(js, ec, &mr); + BOOST_TEST(! ec); + //check_round_trip(jv); + } + + { + error_code ec; + monotonic_resource mr; + auto jv = parse("xxx", ec, &mr); + BOOST_TEST(ec); + BOOST_TEST(ec.has_location()); + BOOST_TEST(jv.is_null()); + } + } + + // parse(string_view) + { + { + check_round_trip( + parse(js)); + } + + { + value jv; + BOOST_TEST_THROWS( + jv = parse("{,"), + system_error); + } + } + + // parse(string_view, storage_ptr) + { + { + monotonic_resource mr; + check_round_trip(parse(js, &mr)); + } + + { + monotonic_resource mr; + value jv; + BOOST_TEST_THROWS( + jv = parse("xxx", &mr), + system_error); + } + } + } + + void + testSampleJson() + { + string_view in = +R"xx({ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +})xx"; + string_view out = + "{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":" + "{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\"," + "\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup " + "Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\"," + "\"GlossDef\":{\"para\":\"A meta-markup language, used to create " + "markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]}," + "\"GlossSee\":\"markup\"}}}}}"; + storage_ptr sp = + make_shared_resource<monotonic_resource>(); + stream_parser p(sp); + error_code ec; + p.write(in.data(), in.size(), ec); + if(BOOST_TEST(! ec)) + p.finish(ec); + if(BOOST_TEST(! ec)) + BOOST_TEST(serialize(p.release()) == out); + } + + void + testTrailingCommas() + { + parse_options enabled; + enabled.allow_trailing_commas = true; + + grind("[1,]", enabled); + grind("[1, 2,]", enabled); + grind("{\"a\": 1,}", enabled); + grind("{\"a\": 1, \"b\": 2,}", enabled); + } + + void + testComments() + { + parse_options enabled; + enabled.allow_comments = true; + + grind("[/* c */1]", enabled); + grind("[1/* c */]", enabled); + grind("[1] /* c */", enabled); + grind("/* c */ [1]", enabled); + grind("[1/* c */, 2]", enabled); + grind("[1, /* c */ 2]", enabled); + + grind("// c++ \n[1]", enabled); + grind("[1] // c++ \n", enabled); + grind("[1] // c++", enabled); + grind("[// c++ \n1]", enabled); + grind("[1// c++ \n]", enabled); + grind("[1// c++ \n, 2]", enabled); + grind("[1, // c++ \n 2]", enabled); + + grind("{/* c */\"a\":1}", enabled); + grind("{\"a\":1/* c */}", enabled); + grind("{\"a\":1} /* c */", enabled); + grind("/* c */ {\"a\":1}", enabled); + grind("{\"a\":1/* c */, \"b\":1}", enabled); + grind("{\"a\":1, /* c */ \"b\":1}", enabled); + grind("{\"a\"/* c */:1}", enabled); + grind("{\"a\":/* c */1}", enabled); + + grind("// c++ \n{\"a\":1}", enabled); + grind("{\"a\":1} // c++ \n", enabled); + grind("{\"a\":1} // c++", enabled); + grind("{// c++ \n\"a\":1}", enabled); + grind("{\"a\":1// c++ \n}", enabled); + grind("{\"a\":1// c++ \n, \"b\":2}", enabled); + grind("{\"a\":1, // c++ \n \"b\":2}", enabled); + grind("{\"a\"// c++ \n:1}", enabled); + grind("{\"a\":// c++ \n1}", enabled); + } + + void + testUnicodeStrings() + { + // Embedded NULL correctly converted + { + auto expected = string_view("Hello\x00World", 11); + { + auto s = string_view(R"json("Hello\u0000World")json"); + grind(s); + BOOST_TEST(json::parse(s).as_string() == expected); + } + { + auto s = string_view(R"json(["Hello\u0000World"])json"); + grind(s); + BOOST_TEST(json::parse(s).as_array().at(0).as_string() == expected); + } + } + + // surrogate pairs correctly converted to UTF-8 + { + auto expected = string_view("\xF0\x9D\x84\x9E", 4); + { + auto s = string_view(R"json("\uD834\uDD1E")json"); + grind(s); + BOOST_TEST(json::parse(s).as_string() == expected); + } + { + auto s = string_view(R"json(["\uD834\uDD1E"])json"); + grind(s); + BOOST_TEST(json::parse(s).as_array().at(0).as_string() == expected); + } + } + } + + void + testDupeKeys() + { + { + value jv = parse(R"({"a":1,"b":2,"a":3})"); + object& jo = jv.as_object(); + BOOST_TEST(jo.size() == 2); + BOOST_TEST(jo.at("a").as_int64() == 3); + BOOST_TEST(jo.at("b").as_int64() == 2); + } + { + value jv = parse(R"({"a":1,"a":3,"b":2})"); + object& jo = jv.as_object(); + BOOST_TEST(jo.size() == 2); + BOOST_TEST(jo.at("a").as_int64() == 3); + BOOST_TEST(jo.at("b").as_int64() == 2); + } + { + value jv = parse(R"({"a":1,"a":3,"b":2,"a":4})"); + object& jo = jv.as_object(); + BOOST_TEST(jo.size() == 2); + BOOST_TEST(jo.at("a").as_int64() == 4); + BOOST_TEST(jo.at("b").as_int64() == 2); + } + { + value jv = parse(R"({"a":1,"a":3,"b":2,"a":4,"b":5})"); + object& jo = jv.as_object(); + BOOST_TEST(jo.size() == 2); + BOOST_TEST(jo.at("a").as_int64() == 4); + BOOST_TEST(jo.at("b").as_int64() == 5); + } + } + + //------------------------------------------------------ + + // https://github.com/boostorg/json/issues/15 + void + testIssue15() + { + BOOST_TEST( + json::parse("{\"port\": 12345}") + .as_object() + .at("port") + .as_int64() == 12345); + } + + // https://github.com/boostorg/json/issues/45 + void + testIssue45() + { + struct T + { + value jv; + + T(value jv_) + : jv(jv_) + { + } + }; + + auto const jv = parse("[]"); + auto const t = T{jv}; + BOOST_TEST(serialize(t.jv) == "[]"); + } + + //------------------------------------------------------ + + void + run() + { + testCtors(); + testMembers(); + + testNull(); + testBool(); + testString(); + testNumber(); + testArray(); + testObject(); + + testFreeFunctions(); + testSampleJson(); + testUnicodeStrings(); + testTrailingCommas(); + testComments(); + testDupeKeys(); + testIssue15(); + testIssue45(); + } +}; + +TEST_SUITE(stream_parser_test, "boost.json.stream_parser"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/string.cpp b/src/boost/libs/json/test/string.cpp new file mode 100644 index 000000000..390d67038 --- /dev/null +++ b/src/boost/libs/json/test/string.cpp @@ -0,0 +1,2814 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/string.hpp> + +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/parse.hpp> + +#include <numeric> +#include <sstream> +#include <string> +#include <stdint.h> +#include <unordered_set> + +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<string>::value ); +BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<string>::value ); + +class string_test +{ +public: + +#if BOOST_JSON_ARCH == 64 +# define INIT1 { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n' } +# define INIT2 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' } +#elif BOOST_JSON_ARCH == 32 +# define INIT1 { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } +# define INIT2 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' } +#else +# error Unknown architecture +#endif + + struct test_vectors + { + // fit in sbo + string_view v1; // "abc... + + // dynamic alloc + string_view v2; // "ABC... + + std::string const s1; + std::string const s2; + + test_vectors() + : s1([&] + { + std::string s; + s.resize(string{}.capacity()); + std::iota(s.begin(), s.end(), 'a'); + return s; + }()) + , s2([&] + { + std::string s; + s.resize(string{}.capacity() + 1); + std::iota(s.begin(), s.end(), 'A'); + return s; + }()) + { + v1 = s1; + v2 = s2; + + BOOST_TEST(std::string(INIT1) == s1); + BOOST_TEST(std::string(INIT2) == s2); + } + }; + + static + string_view + last_of( + string_view s, + std::size_t n) + { + return s.substr(s.size() - n); + } + + void + testConstruction() + { + test_vectors const t; + + // string() + { + string s; + } + + // string(storage_ptr) + { + auto const sp = + make_shared_resource<unique_resource>(); + string s(sp); + BOOST_TEST(s.empty()); + BOOST_TEST(*s.storage() == *sp.get()); + } + + // string(size_type, char, storage_ptr) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + BOOST_TEST(s == std::string(t.v1.size(), '*')); + }); + + { + string s(t.v2.size(), '*'); + BOOST_TEST(s == std::string(t.v2.size(), '*')); + } + } + + // string(char const*, storage_ptr) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.s1.c_str(), sp); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.s2.c_str(), sp); + BOOST_TEST(s == t.v2); + }); + + { + string s(t.s1.c_str()); + BOOST_TEST(s == t.v1); + } + + { + string s(t.s2.c_str()); + BOOST_TEST(s == t.v2); + } + } + + // string(char const*, size_type, storage_ptr) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.s1.c_str(), 3, sp); + BOOST_TEST(s == "abc"); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.s2.c_str(), 3, sp); + BOOST_TEST(s == "ABC"); + }); + + { + string s(t.s1.c_str(), 3); + BOOST_TEST(s == "abc"); + } + + { + string s(t.s2.c_str(), 3); + BOOST_TEST(s == "ABC"); + } + } + + // string(InputIt, InputIt, storage_ptr) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.begin(), t.v1.end(), sp); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.begin(), t.v2.end(), sp); + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s( + make_input_iterator(t.v1.begin()), + make_input_iterator(t.v1.end()), sp); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s( + make_input_iterator(t.v2.begin()), + make_input_iterator(t.v2.end()), sp); + BOOST_TEST(s == t.v2); + }); + + { + string s(t.v1.begin(), t.v1.end()); + BOOST_TEST(s == t.v1); + } + + { + string s(t.v2.begin(), t.v2.end()); + BOOST_TEST(s == t.v2); + } + + { + string s( + make_input_iterator(t.v1.begin()), + make_input_iterator(t.v1.end())); + BOOST_TEST(s == t.v1); + } + + { + string s( + make_input_iterator(t.v2.begin()), + make_input_iterator(t.v2.end())); + BOOST_TEST(s == t.v2); + } + } + + // string(string) + { + { + string const s0(t.v1); + string s(s0); + BOOST_TEST(s == t.v1); + } + + { + string const s0(t.v2); + string s(s0); + BOOST_TEST(s == t.v2); + } + } + + // string(string, storage_ptr) + { + fail_loop([&](storage_ptr const& sp) + { + string const s0(t.v1); + string s(s0, sp); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string const s0(t.v2); + string s(s0, sp); + BOOST_TEST(s == t.v2); + }); + } + + // string(pilfered<string>) + { + { + string s1(t.v1); + string s2(pilfer(s1)); + BOOST_TEST(s2 == t.v1); + BOOST_TEST(s1.empty()); + BOOST_TEST( + s1.storage() == storage_ptr()); + } + + { + string s1(t.v2); + string s2(pilfer(s1)); + BOOST_TEST(s2 == t.v2); + BOOST_TEST(s1.empty()); + BOOST_TEST( + s1.storage() == storage_ptr()); + } + + // ensure pilfered-from objects + // are trivially destructible + { + string s1(make_shared_resource< + monotonic_resource>()); + string s2(pilfer(s1)); + BOOST_TEST(s1.storage().get() == + storage_ptr().get()); + } + } + + // string(string&&) + { + { + string s1(t.v1); + string s2(std::move(s1)); + BOOST_TEST(s2 == t.v1); + BOOST_TEST(s1.empty()); + BOOST_TEST( + *s1.storage() == + *s2.storage()); + } + + { + string s1(t.v2); + string s2(std::move(s1)); + BOOST_TEST(s2 == t.v2); + BOOST_TEST(s1.empty()); + BOOST_TEST( + *s1.storage() == + *s2.storage()); + } + } + + // string(string&&, storage_ptr) + { + // same storage + + fail_loop([&](storage_ptr const& sp) + { + string s1(t.v1, sp); + string s2(std::move(s1), sp); + BOOST_TEST(s2 == t.v1); + BOOST_TEST(s1.empty()); + BOOST_TEST( + *s1.storage() == + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s1(t.v2, sp); + string s2(std::move(s1)); + BOOST_TEST(s2 == t.v2); + BOOST_TEST(s1.empty()); + BOOST_TEST( + *s1.storage() == + *s2.storage()); + }); + + // different storage + + fail_loop([&](storage_ptr const& sp) + { + string s1(t.v1); + string s2(std::move(s1), sp); + BOOST_TEST(s2 == t.v1); + BOOST_TEST(s1 == t.v1); + BOOST_TEST( + *s1.storage() != + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s1(t.v2); + string s2(std::move(s1), sp); + BOOST_TEST(s2 == t.v2); + BOOST_TEST(s1 == t.v2); + BOOST_TEST( + *s1.storage() != + *s2.storage()); + }); + } + + // string(string_view, storage_ptr) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + BOOST_TEST(s == t.v2); + }); + + { + string s(t.v1); + BOOST_TEST(s == t.v1); + } + + { + string s(t.v2); + BOOST_TEST(s == t.v2); + } + } + } + + void + testAssignment() + { + test_vectors const t; + + // operator=(string) + { + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string const s2(t.v1); + s = s2; + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string const s2(t.v1); + s = s2; + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string const s2(t.v2); + s = s2; + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string const s2(t.v2); + s = s2; + BOOST_TEST(s == t.v2); + }); + } + + // operator=(string&&) + { + // same storage + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v1, sp); + s = std::move(s2); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v1, sp); + s = std::move(s2); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v2, sp); + s = std::move(s2); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v2, sp); + s = std::move(s2); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + // different storage + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v1); + s = std::move(s2); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2 == t.v1); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v1); + s = std::move(s2); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2 == t.v1); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v2); + s = std::move(s2); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2 == t.v2); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v2); + s = std::move(s2); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2 == t.v2); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + } + + // operator=(char const*) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s = t.s1.c_str(); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s = t.s1.c_str(); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s = t.s2.c_str(); + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s = t.s2.c_str(); + BOOST_TEST(s == t.v2); + }); + } + + // operator=(string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s = t.v1; + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s = t.v1; + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s = t.v2; + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s = t.v2; + BOOST_TEST(s == t.v2); + }); + } + } + + void + testAssign() + { + test_vectors const t; + + // assign(size_type, char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), 'x', sp); + s.assign(t.v1.size(), '*'); + BOOST_TEST( + s == std::string(t.v1.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), 'x', sp); + s.assign(t.v1.size(), '*'); + BOOST_TEST( + s == std::string(t.v1.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), 'x', sp); + s.assign(t.v2.size(), '*'); + BOOST_TEST( + s == std::string(t.v2.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), 'x', sp); + s.assign(t.v2.size(), '*'); + BOOST_TEST( + s == std::string(t.v2.size(), '*')); + }); + } + + // assign(string) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), 'x', sp); + s.assign(string(t.v1.size(), '*')); + BOOST_TEST( + s == std::string(t.v1.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), 'x', sp); + s.assign(string(t.v1.size(), '*')); + BOOST_TEST( + s == std::string(t.v1.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), 'x', sp); + s.assign(string(t.v2.size(), '*')); + BOOST_TEST( + s == std::string(t.v2.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), 'x', sp); + s.assign(string(t.v2.size(), '*')); + BOOST_TEST( + s == std::string(t.v2.size(), '*')); + }); + + // self-assign + { + string s(t.v1); + s = static_cast<string const&>(s); + BOOST_TEST(s == t.v1); + } + } + + // assign(string&&) + { + // same storage + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v1, sp); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v1, sp); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v2, sp); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v2, sp); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2.empty()); + BOOST_TEST( + *s.storage() == + *s2.storage()); + }); + + // different storage + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v1); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2 == t.v1); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v1); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v1); + BOOST_TEST(s2 == t.v1); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v1.size(), '*'); + string s(c, sp); + string s2(t.v2); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2 == t.v2); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + + fail_loop([&](storage_ptr const& sp) + { + std::string c(t.v2.size(), '*'); + string s(c, sp); + string s2(t.v2); + s.assign(std::move(s2)); + BOOST_TEST(s == t.v2); + BOOST_TEST(s2 == t.v2); + BOOST_TEST( + *s.storage() != + *s2.storage()); + }); + } + + // assign(char const*, size_type) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.s1.c_str(), 3); + BOOST_TEST(s == "abc"); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.s1.c_str(), 3); + BOOST_TEST(s == "abc"); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.s2.c_str(), 3); + BOOST_TEST(s == "ABC"); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.s2.c_str(), 3); + BOOST_TEST(s == "ABC"); + }); + }; + + // assign(char const* s) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.s1.c_str()); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.s1.c_str()); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.s2.c_str()); + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.s2.c_str()); + BOOST_TEST(s == t.v2); + }); + } + + // assign(InputIt, InputIt) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.s1.begin(), t.s1.end()); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.s1.begin(), t.s1.end()); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign( + make_input_iterator(t.s1.begin()), + make_input_iterator(t.s1.end())); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign( + make_input_iterator(t.s1.begin()), + make_input_iterator(t.s1.end())); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.s2.begin(), t.s2.end()); + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.s2.begin(), t.s2.end()); + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign( + make_input_iterator(t.s2.begin()), + make_input_iterator(t.s2.end())); + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign( + make_input_iterator(t.s2.begin()), + make_input_iterator(t.s2.end())); + BOOST_TEST(s == t.v2); + }); + + // empty range + { + string s(t.v1); + s.assign(t.s1.begin(), t.s1.begin()); + BOOST_TEST(s.empty()); + } + + // empty range + { + string s(t.v1); + s.assign( + make_input_iterator(t.s1.begin()), + make_input_iterator(t.s1.begin())); + BOOST_TEST(s.empty()); + } + } + + // assign(string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.v1); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.v1); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1.size(), '*', sp); + s.assign(t.v2); + BOOST_TEST(s == t.v2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2.size(), '*', sp); + s.assign(t.v2); + BOOST_TEST(s == t.v2); + }); + } + } + + void + testConversion() + { + test_vectors const t; + + string s(t.s1); + auto const& cs(s); + + char const* chars = cs.c_str(); + BOOST_TEST(chars == t.s1); + json::string_view sv = cs; + BOOST_TEST(sv == t.s1); +#if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + std::string_view std_sv = cs; + BOOST_TEST(std_sv == t.s1); +#endif + + s = t.s2; + + chars = cs.c_str(); + BOOST_TEST(chars == t.s2); + sv = cs; + BOOST_TEST(sv == t.s2); +#if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + std_sv = cs; + BOOST_TEST(std_sv == t.s2); +#endif + } + + void + testElementAccess() + { + test_vectors const t; + + string s1(t.v1); + string s2(t.v2); + auto const& cs1(s1); + auto const& cs2(s2); + + // at(size_type) + { + BOOST_TEST(s1.at(1) == 'b'); + s1.at(1) = '*'; + BOOST_TEST(s1.at(1) == '*'); + s1.at(1) = 'b'; + BOOST_TEST(s1.at(1) == 'b'); + + BOOST_TEST(s2.at(1) == 'B'); + s2.at(1) = '*'; + BOOST_TEST(s2.at(1) == '*'); + s2.at(1) = 'B'; + BOOST_TEST(s2.at(1) == 'B'); + + BOOST_TEST_THROWS(s1.at(s2.size()), + std::out_of_range); + } + + // at(size_type) const + { + BOOST_TEST(cs1.at(1) == 'b'); + BOOST_TEST(cs2.at(1) == 'B'); + + BOOST_TEST_THROWS(cs1.at(cs2.size()), + std::out_of_range); + } + + // operator[&](size_type) + { + BOOST_TEST(s1[1] == 'b'); + s1[1] = '*'; + BOOST_TEST(s1[1] == '*'); + s1[1] = 'b'; + BOOST_TEST(s1[1] == 'b'); + + BOOST_TEST(s2[1] == 'B'); + s2[1] = '*'; + BOOST_TEST(s2[1] == '*'); + s2[1] = 'B'; + BOOST_TEST(s2[1] == 'B'); + } + + // operator[&](size_type) const + { + BOOST_TEST(cs1[1] == 'b'); + BOOST_TEST(cs2[1] == 'B'); + } + + // front() + { + BOOST_TEST(s1.front() == 'a'); + s1.front() = '*'; + BOOST_TEST(s1.front() == '*'); + s1.front() = 'a'; + BOOST_TEST(s1.front() == 'a'); + + BOOST_TEST(s2.front() == 'A'); + s2.front() = '*'; + BOOST_TEST(s2.front() == '*'); + s2.front() = 'A'; + BOOST_TEST(s2.front() == 'A'); + } + + // front() const + { + BOOST_TEST(cs1.front() == 'a'); + BOOST_TEST(cs2.front() == 'A'); + } + + // back() + { + auto const ch1 = s1.at(s1.size()-1); + auto const ch2 = s2.at(s2.size()-1); + + BOOST_TEST(s1.back() == ch1); + s1.back() = '*'; + BOOST_TEST(s1.back() == '*'); + s1.back() = ch1; + BOOST_TEST(s1.back() == ch1); + + BOOST_TEST(s2.back() == ch2); + s2.back() = '*'; + BOOST_TEST(s2.back() == '*'); + s2.back() = ch2; + BOOST_TEST(s2.back() == ch2); + } + + // back() const + { + auto const ch1 = s1.at(s1.size()-1); + auto const ch2 = s2.at(s2.size()-1); + + BOOST_TEST(cs1.back() == ch1); + BOOST_TEST(cs2.back() == ch2); + } + + // data() + { + BOOST_TEST( + string_view(s1.data()) == t.v1); + BOOST_TEST( + string_view(s2.data()) == t.v2); + } + // data() const + { + BOOST_TEST( + string_view(cs1.data()) == t.v1); + BOOST_TEST( + string_view(cs2.data()) == t.v2); + } + + // c_str() + { + BOOST_TEST( + string_view(cs1.c_str()) == t.v1); + BOOST_TEST( + string_view(cs2.c_str()) == t.v2); + } + + // operator string_view() + { + BOOST_TEST( + string_view(cs1) == t.v1); + BOOST_TEST( + string_view(cs2) == t.v2); + } + } + + void + testIterators() + { + string s = "abc"; + auto const& ac(s); + + { + auto it = s.begin(); + BOOST_TEST(*it == 'a'); ++it; + BOOST_TEST(*it == 'b'); it++; + BOOST_TEST(*it == 'c'); ++it; + BOOST_TEST(it == s.end()); + } + { + auto it = s.cbegin(); + BOOST_TEST(*it == 'a'); ++it; + BOOST_TEST(*it == 'b'); it++; + BOOST_TEST(*it == 'c'); ++it; + BOOST_TEST(it == s.cend()); + } + { + auto it = ac.begin(); + BOOST_TEST(*it == 'a'); ++it; + BOOST_TEST(*it == 'b'); it++; + BOOST_TEST(*it == 'c'); ++it; + BOOST_TEST(it == ac.end()); + } + { + auto it = s.end(); + --it; BOOST_TEST(*it == 'c'); + it--; BOOST_TEST(*it == 'b'); + --it; BOOST_TEST(*it == 'a'); + BOOST_TEST(it == s.begin()); + } + { + auto it = s.cend(); + --it; BOOST_TEST(*it == 'c'); + it--; BOOST_TEST(*it == 'b'); + --it; BOOST_TEST(*it == 'a'); + BOOST_TEST(it == s.cbegin()); + } + { + auto it = ac.end(); + --it; BOOST_TEST(*it == 'c'); + it--; BOOST_TEST(*it == 'b'); + --it; BOOST_TEST(*it == 'a'); + BOOST_TEST(it == ac.begin()); + } + + { + auto it = s.rbegin(); + BOOST_TEST(*it == 'c'); ++it; + BOOST_TEST(*it == 'b'); it++; + BOOST_TEST(*it == 'a'); ++it; + BOOST_TEST(it == s.rend()); + } + { + auto it = s.crbegin(); + BOOST_TEST(*it == 'c'); ++it; + BOOST_TEST(*it == 'b'); it++; + BOOST_TEST(*it == 'a'); ++it; + BOOST_TEST(it == s.crend()); + } + { + auto it = ac.rbegin(); + BOOST_TEST(*it == 'c'); ++it; + BOOST_TEST(*it == 'b'); it++; + BOOST_TEST(*it == 'a'); ++it; + BOOST_TEST(it == ac.rend()); + } + { + auto it = s.rend(); + --it; BOOST_TEST(*it == 'a'); + it--; BOOST_TEST(*it == 'b'); + --it; BOOST_TEST(*it == 'c'); + BOOST_TEST(it == s.rbegin()); + } + { + auto it = s.crend(); + --it; BOOST_TEST(*it == 'a'); + it--; BOOST_TEST(*it == 'b'); + --it; BOOST_TEST(*it == 'c'); + BOOST_TEST(it == s.crbegin()); + } + { + auto it = ac.rend(); + --it; BOOST_TEST(*it == 'a'); + it--; BOOST_TEST(*it == 'b'); + --it; BOOST_TEST(*it == 'c'); + BOOST_TEST(it == ac.rbegin()); + } + + { + string s2; + string const& cs2(s2); + BOOST_TEST(std::distance( + s2.begin(), s2.end()) == 0); + BOOST_TEST(std::distance( + cs2.begin(), cs2.end()) == 0); + BOOST_TEST(std::distance( + s2.rbegin(), s2.rend()) == 0); + BOOST_TEST(std::distance( + cs2.rbegin(), cs2.rend()) == 0); + } + } + + void + testCapacity() + { + test_vectors const t; + + // empty() + { + { + string s; + BOOST_TEST(s.empty()); + } + { + string s = "abc"; + BOOST_TEST(! s.empty()); + } + } + + // size() + // max_size() + { + string s = "abc"; + BOOST_TEST(s.size() == 3); + BOOST_TEST(s.max_size() < string::npos); + } + + // reserve(size_type) + { + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + s.append(t.v1); + s.append(t.v2); + + s.reserve(0); + BOOST_TEST(s.size() == + t.v1.size() + t.v2.size()); + + s.reserve(t.v1.size() + t.v2.size()); + BOOST_TEST(s.size() == + t.v1.size() + t.v2.size()); + + s.reserve(s.size() * 2); + BOOST_TEST(s.capacity() > + t.v1.size() + t.v2.size()); + + s.resize(t.v1.size()); + s.reserve(t.v1.size()); + BOOST_TEST(s == t.v1); + }); + } + + // capacity() + { + // implied + } + + // shrink_to_fit() + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + string::size_type cap; + + cap = s.capacity(); + s.shrink_to_fit(); + BOOST_TEST(s.capacity() == cap); + + s.reserve(s.capacity() + 1); + s.shrink_to_fit(); + BOOST_TEST(s.capacity() == cap); + + s.resize(cap * 3, '*'); + cap = s.capacity(); + s.resize(cap - 1); + s.shrink_to_fit(); + BOOST_TEST(s.capacity() == cap); + + s.resize(cap / 2); + BOOST_TEST(s.capacity() == cap); + + s.shrink_to_fit(); + BOOST_TEST(s.capacity() < cap); + }); + } + + void + testClear() + { + test_vectors const t; + + // clear() + { + { + string s(t.v1); + s.clear(); + BOOST_TEST(s.empty()); + BOOST_TEST(s.size() == 0); + BOOST_TEST(s.capacity() > 0); + } + + { + string s(t.v2); + s.clear(); + BOOST_TEST(s.empty()); + BOOST_TEST(s.size() == 0); + BOOST_TEST(s.capacity() > 0); + } + } + } + + void + testInsert() + { + test_vectors const t; + + // insert(size_type, size_type, char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(1, 3, '*'); + BOOST_TEST(s == std::string( + t.v1).insert(1, 3, '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(1, 3, '*'); + BOOST_TEST(s == std::string( + t.v2).insert(1, 3, '*')); + }); + + // pos out of range + { + string s(t.v1); + BOOST_TEST_THROWS( + (s.insert(s.size() + 2, 1, '*')), + std::out_of_range); + } + + // size > max_size + { + string s(t.v1); + BOOST_TEST_THROWS( + (s.insert(1, s.max_size(), 'a')), + std::length_error); + } + } + + // insert(size_type, char const*) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(1, "***"); + BOOST_TEST(s == std::string( + t.v1).insert(1, "***")); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(1, "***"); + BOOST_TEST(s == std::string( + t.v2).insert(1, "***")); + }); + + // pos out of range + { + string s(t.v1); + BOOST_TEST_THROWS( + (s.insert(s.size() + 2, "*")), + std::out_of_range); + } + } + + // insert(size_type, char const*, size_type) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(1, "*****"); + BOOST_TEST(s == std::string( + t.v1).insert(1, "*****")); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(1, "*****"); + BOOST_TEST(s == std::string( + t.v2).insert(1, "*****")); + }); + } + + // insert(size_type, string const&) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(1, string(t.v2)); + BOOST_TEST(s == std::string( + t.v1).insert(1, t.s2)); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(1, string(t.v1)); + BOOST_TEST(s == std::string( + t.v2).insert(1, t.s1)); + }); + } + + //// KRYSTIAN These tests are superseded by the new string_view overloads + //// insert(size_type, string const&, size_type, size_type) + //{ + // fail_loop([&](storage_ptr const& sp) + // { + // string s(t.v1, sp); + // s.insert(1, string(t.v2), 1, 3); + // BOOST_TEST(s == std::string( + // t.v1).insert(1, t.s2, 1, 3)); + // }); + + // fail_loop([&](storage_ptr const& sp) + // { + // string s(t.v2, sp); + // s.insert(1, string(t.v1), 1, 3); + // BOOST_TEST(s == std::string( + // t.v2).insert(1, t.s1, 1, 3)); + // }); + + // fail_loop([&](storage_ptr const& sp) + // { + // string s(t.v1, sp); + // s.insert(1, string(t.v2), 1); + // BOOST_TEST(s == std::string( + // t.v1).insert(1, t.s2, 1, std::string::npos)); + // }); + + // fail_loop([&](storage_ptr const& sp) + // { + // string s(t.v2, sp); + // s.insert(1, string(t.v1), 1); + // BOOST_TEST(s == std::string( + // t.v2).insert(1, t.s1, 1, std::string::npos)); + // }); + //} + + // insert(size_type, char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + BOOST_TEST( + s.insert(2, '*')[2] == '*'); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + BOOST_TEST( + s.insert(2, '*')[2] == '*'); + }); + } + + // insert(const_iterator, size_type, char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + BOOST_TEST(string_view( + &(s.insert(2, 3, '*')[2]), 5) == + "***cd"); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + BOOST_TEST(string_view( + &(s.insert(2, 3, '*')[2]), 5) == + "***CD"); + }); + } + + // insert(const_iterator, InputIt, InputIt) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(2, t.s2.begin(), t.s2.end()); + std::string cs(t.s1); + cs.insert(2, &t.s2[0], t.s2.size()); + BOOST_TEST(s == cs); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(2, t.s1.begin(), t.s1.end()); + std::string cs(t.s2); + cs.insert(2, &t.s1[0], t.s1.size()); + BOOST_TEST(s == cs); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(2, + make_input_iterator(t.s2.begin()), + make_input_iterator(t.s2.end())); + std::string cs(t.s1); + cs.insert(2, &t.s2[0], t.s2.size()); + BOOST_TEST(s == cs); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(2, + make_input_iterator(t.s1.begin()), + make_input_iterator(t.s1.end())); + std::string cs(t.s2); + cs.insert(2, &t.s1[0], t.s1.size()); + BOOST_TEST(s == cs); + }); + } + + // insert(const_iterator, string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(2, string_view(t.v2)); + std::string cs(t.v1); + cs.insert(2, t.s2); + BOOST_TEST(s == cs); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(2, string_view(t.v1)); + std::string cs(t.v2); + cs.insert(2, t.s1); + BOOST_TEST(s == cs); + }); + } + + // insert(const_iterator, string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(2, string_view(t.v2).substr(2, 3)); + std::string cs(t.v1); + cs.insert(2, t.s2, 2, 3); + BOOST_TEST(s == cs); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(2, string_view(t.v1).substr(2, 3)); + std::string cs(t.v2); + cs.insert(2, t.s1, 2, 3); + BOOST_TEST(s == cs); + }); + } + + // insert(size_type, char const*) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.insert(1, "***"); + BOOST_TEST(s == std::string( + t.v1).insert(1, "***")); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.insert(1, "***"); + BOOST_TEST(s == std::string( + t.v2).insert(1, "***")); + }); + + // pos out of range + { + string s(t.v1); + BOOST_TEST_THROWS( + (s.insert(s.size() + 2, "*")), + std::out_of_range); + } + } + + // insert tests for when source is within destination + { + // start before splice point + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.reserve(s.size() + 10); + s.insert(4, s.subview(0, 3)); + std::string cs(t.v1); + cs.insert(4, cs.substr(0, 3)); + BOOST_TEST(s == cs); + }); + + // start after splice point + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.reserve(s.size() + 10); + s.insert(0, s.subview(3, 3)); + std::string cs(t.v1); + cs.insert(0, cs.substr(3, 3)); + BOOST_TEST(s == cs); + }); + + // insert pos bisects the inserted string + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.reserve(s.size() + 10); + s.insert(2, s.subview(0, 5)); + std::string cs(t.v1); + cs.insert(2, cs.substr(0, 5)); + BOOST_TEST(s == cs); + }); + } + + // insert reallocation test + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + std::string cs(t.v2); + const auto view = t.v2.substr(0, 4); + s.append(s); + cs.append(cs); + s.insert(2, view); + cs.insert(2, view.data(), view.size()); + BOOST_TEST(s == cs); + }); + } + } + + void + testErase() + { + test_vectors const t; + + // erase(size_type, size_type) + { + { + string s(t.v1); + s.erase(1, 3); + BOOST_TEST(s == + std::string(t.v1).erase(1, 3)); + } + + { + string s(t.v2); + s.erase(1, 3); + BOOST_TEST(s == + std::string(t.v2).erase(1, 3)); + } + + { + string s(t.v1); + s.erase(3); + BOOST_TEST(s == + std::string(t.v1).erase(3)); + } + + { + string s(t.v2); + s.erase(3); + BOOST_TEST(s == + std::string(t.v2).erase(3)); + } + + { + string s(t.v1); + s.erase(); + BOOST_TEST(s == + std::string(t.v1).erase()); + } + + { + string s(t.v2); + s.erase(); + BOOST_TEST(s == + std::string(t.v2).erase()); + } + + { + string s(t.v1); + BOOST_TEST_THROWS( + (s.erase(t.v1.size() + 1, 1)), + std::out_of_range); + } + } + + // iterator erase(const_iterator) + { + { + string s(t.v1); + std::string s2(t.v1); + s.erase(s.begin() + 3); + s2.erase(s2.begin() + 3); + BOOST_TEST(s == s2); + } + + { + string s(t.v2); + std::string s2(t.v2); + s.erase(s.begin() + 3); + s2.erase(s2.begin() + 3); + BOOST_TEST(s == s2); + } + } + + // iterator erase(const_iterator, const_iterator) + { + string s(t.v1); + std::string s2(t.v1); + s.erase(s.begin() + 1, s.begin() + 3); + s2.erase(s2.begin() + 1, s2.begin() + 3); + BOOST_TEST(s == s2); + } + } + + void + testPushPop() + { + test_vectors const t; + + // push_back(char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + for(auto ch : t.v1) + s.push_back(ch); + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + for(auto ch : t.v2) + s.push_back(ch); + BOOST_TEST(s == t.v2); + }); + } + + // pop_back(char) + { + { + string s(t.v1); + while(! s.empty()) + s.pop_back(); + BOOST_TEST(s.empty()); + BOOST_TEST(s.capacity() > 0); + } + + { + string s(t.v2); + while(! s.empty()) + s.pop_back(); + BOOST_TEST(s.empty()); + BOOST_TEST(s.capacity() > 0); + } + } + } + + void + testAppend() + { + test_vectors const t; + + // append(size_type, char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(t.v2.size(), '*'); + BOOST_TEST(s == t.s1 + + std::string(t.v2.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(t.v1.size(), '*'); + BOOST_TEST(s == t.s2 + + std::string(t.v1.size(), '*')); + }); + } + + // append(string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(string(t.v2)); + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(string(t.v1)); + BOOST_TEST(s == t.s2 + t.s1); + }); + } + + // append(string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(string(t.v2).subview(3)); + BOOST_TEST(s == t.s1 + t.s2.substr(3)); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(string(t.v1).subview(3)); + BOOST_TEST(s == t.s2 + t.s1.substr(3)); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(string(t.v2).subview(2, 3)); + BOOST_TEST(s == t.s1 + t.s2.substr(2, 3)); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(string(t.v1).subview(2, 3)); + BOOST_TEST(s == t.s2 + t.s1.substr(2, 3)); + }); + } + + // append(char const*) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(t.s2.c_str()); + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(t.s1.c_str()); + BOOST_TEST(s == t.s2 + t.s1); + }); + } + + // append(InputIt, InputIt) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(t.s2.begin(), t.s2.end()); + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(t.s1.begin(), t.s1.end()); + BOOST_TEST(s == t.s2 + t.s1); + }); + + // Fails on Visual Studio 2017 C++2a Strict + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append( + make_input_iterator(t.s2.begin()), + make_input_iterator(t.s2.end())); + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append( + make_input_iterator(t.s1.begin()), + make_input_iterator(t.s1.end())); + BOOST_TEST(s == t.s2 + t.s1); + }); + } + + // append(string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(t.v2); + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(t.v1); + BOOST_TEST(s == t.s2 + t.s1); + }); + } + + // append(string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(t.v2.substr(2)); + BOOST_TEST(s == t.s1 + t.s2.substr(2)); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(t.v1.substr(2)); + BOOST_TEST(s == t.s2 + t.s1.substr(2)); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s.append(t.v2.substr(2, 3)); + BOOST_TEST(s == t.s1 + t.s2.substr(2, 3)); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s.append(t.v1.substr(2, 3)); + BOOST_TEST(s == t.s2 + t.s1.substr(2, 3)); + }); + } + } + + void + testPlusEquals() + { + test_vectors const t; + + // operator+=(string) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s += string(t.v2); + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s += string(t.v1); + BOOST_TEST(s == t.s2 + t.s1); + }); + } + + // operator+=(char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + for(auto ch : t.v1) + s += ch; + BOOST_TEST(s == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + for(auto ch : t.v2) + s += ch; + BOOST_TEST(s == t.v2); + }); + } + + // operator+=(char const*) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s += t.s2.c_str(); + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s += t.s1.c_str(); + BOOST_TEST(s == t.s2 + t.s1); + }); + } + + // operator+=(string_view) + { + fail_loop([&](storage_ptr const& sp) + { + string s(t.v1, sp); + s += t.v2; + BOOST_TEST(s == t.s1 + t.s2); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + s += t.v1; + BOOST_TEST(s == t.s2 + t.s1); + }); + } + } + + void + testCompare() + { + test_vectors const t; + string const v1 = t.v1; + + // compare(string) + BOOST_TEST(v1.compare(string("aaaaaaa")) > 0); + BOOST_TEST(v1.compare(string(t.v1)) == 0); + BOOST_TEST(v1.compare(string("bbbbbbb")) < 0); + + // compare(char const*) + BOOST_TEST(v1.compare("aaaaaaa") > 0); + BOOST_TEST(v1.compare(t.s1.c_str()) == 0); + BOOST_TEST(v1.compare("bbbbbbb") < 0); + + // compare(string_view s) + BOOST_TEST(v1.compare(string_view("aaaaaaa")) > 0); + BOOST_TEST(v1.compare(t.v1) == 0); + BOOST_TEST(v1.compare(string_view("bbbbbbb")) < 0); + } + + void + testStartEndsWith() + { + test_vectors const t; + string const v1 = t.v1; + string const v2 = t.v2; + + // starts_with(string_view) + { + BOOST_TEST(v1.starts_with(string_view("abc"))); + BOOST_TEST(v2.starts_with(string_view("ABC"))); + BOOST_TEST(! v1.starts_with(string_view("xyz"))); + BOOST_TEST(! v2.starts_with(string_view("XYZ"))); + } + + // starts_with(char) + { + BOOST_TEST(v1.starts_with('a')); + BOOST_TEST(v2.starts_with('A')); + BOOST_TEST(! v1.starts_with('x')); + BOOST_TEST(! v2.starts_with('X')); + } + + // starts_with(char const*) + { + BOOST_TEST(v1.starts_with("abc")); + BOOST_TEST(v2.starts_with("ABC")); + BOOST_TEST(! v1.starts_with("xyz")); + BOOST_TEST(! v2.starts_with("XYZ")); + } + + // ends_with(string_view) + { + BOOST_TEST(v1.ends_with(last_of(t.s1,3))); + BOOST_TEST(v2.ends_with(last_of(t.s2,3))); + BOOST_TEST(! v1.ends_with(string_view("abc"))); + BOOST_TEST(! v2.ends_with(string_view("ABC"))); + } + + // ends_with(char) + { + BOOST_TEST(v1.ends_with(last_of(t.s1, 1)[0])); + BOOST_TEST(v2.ends_with(last_of(t.s2, 1)[0])); + BOOST_TEST(! v1.ends_with('a')); + BOOST_TEST(! v2.ends_with('A')); + } + + // ends_with(char const*) + { + BOOST_TEST(v1.ends_with(last_of(t.s1, 3).data())); + BOOST_TEST(v2.ends_with(last_of(t.s2, 3).data())); + BOOST_TEST(! v1.ends_with("abc")); + BOOST_TEST(! v2.ends_with("ABC")); + } + } + + void + testReplace() + { + test_vectors const t; + + // replace(std::size_t, std::size_t, string_view) + { + // pos out of range + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, t.v2), + std::out_of_range); + }); + + // outside, shrink + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(0, 4, t.v2.substr(4, 2)) == + s1.replace(0, 4, t.v2.data() + 4, 2)); + }); + + // outside, grow + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) == + s1.replace(0, 1, t.v2.data(), t.v2.size())); + }); + + // outside, grow, reallocate + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + s1.append(s1); + s2.append(s2); + BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) == + s1.replace(0, 1, t.v2.data(), t.v2.size())); + }); + + // outside, same + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(0, 2, t.v2.substr(0, 2)) == + s1.replace(0, 2, t.v2.data(), 2)); + }); + + // replace tests for full coverage + + // inside, no effect + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(0, 4, s2.subview(0, 4)) == + s1.replace(0, 4, s1.data() + 0, 4)); + }); + + // inside, shrink, split + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(1, 4, s2.subview(4, 2)) == + s1.replace(1, 4, s1.data() + 4, 2)); + }); + + // inside, grow no reallocate, split + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(1, 1, s2.subview(0)) == + s1.replace(1, 1, s1.data(), s1.size())); + }); + + // inside, reallocate, split + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + s1.append(s1); + s2.append(s2); + BOOST_TEST(s2.replace(1, 1, s2.subview(0)) == + s1.replace(1, 1, s1.data(), s1.size())); + }); + + // inside, same, split + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(1, 2, s2.subview(0, 2)) == + s1.replace(1, 2, s1.data(), 2)); + }); + } + + // replace(const_iterator, const_iterator, string_view) + { + // outside, shrink + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST( + s2.replace( + s2.begin(), + s2.begin() + 4, + t.v2.substr(4, 2)) == + s1.replace(0, + 4, t.v2.data() + 4, + 2)); + }); + + // outside, grow + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST( + s2.replace( + s2.begin(), + s2.begin() + 1, + t.v2.substr(0)) == + s1.replace(0, + 1, t.v2.data(), + t.v2.size())); + }); + + // outside, same + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST( + s2.replace( + s2.begin(), + s2.begin() + 2, + t.v2.substr(0, 2)) == + s1.replace( + 0, 2, + t.v2.data(), + 2)); + }); + + // inside, shrink + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST( + s2.replace( + s2.begin() + 1, + s2.begin() + 5, + s2.subview(4, 2)) == + s1.replace( + 1, 4, + s1.data() + 4, + 2)); + }); + + // inside, grow + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST( + s2.replace( + s2.begin() + 1, + s2.begin() + 2, + s2.subview(0)) == + s1.replace( + 1, 1, + s1.data(), + s1.size())); + }); + + // inside, same + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST( + s2.replace( + s2.begin() + 1, + s2.begin() + 3, + s2.subview(0, 2)) == + s1.replace( + 1, 2, + s1.data(), + 2)); + }); + } + + // replace(std::size_t, std::size_t, std::size_t, char) + { + // grow, no realloc + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(0, 4, 10, 'a') == + s1.replace(0, 4, 10, 'a')); + }); + + // grow, realloc + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + const auto grow = (std::max)(s1.capacity(), s2.capacity()); + BOOST_TEST(s2.replace(0, 4, grow, 'a') == + s1.replace(0, 4, grow, 'a')); + }); + + // no change in size + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST(s2.replace(0, 1, 1, 'a') == + s1.replace(0, 1, 1, 'a')); + }); + + // pos out of range + fail_loop([&](storage_ptr const& sp) + { + string s(t.v2, sp); + BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, 1, 'a'), + std::out_of_range); + }); + } + + // replace(const_iterator, const_iterator, std::size_t, char) + { + fail_loop([&](storage_ptr const& sp) + { + std::string s1(t.v2.data(), t.v2.size()); + string s2(t.v2, sp); + BOOST_TEST( + s2.replace(s2.begin(), s2.begin() + 4, 10, 'a') == + s1.replace(0, 4, 10, 'a')); + }); + } + } + + void + testSubStr() + { + test_vectors const t; + string const s1 = t.v1; + string const s2 = t.v2; + + // subview(size_type, size_type) + BOOST_TEST(s1.subview() == t.v1); + BOOST_TEST(s1.subview(1) == t.v1.substr(1)); + BOOST_TEST(s1.subview(1, 3) == t.v1.substr(1, 3)); + BOOST_TEST(s2.subview() == t.v2); + BOOST_TEST(s2.subview(1) == t.v2.substr(1)); + BOOST_TEST(s2.subview(1, 3) == t.v2.substr(1, 3)); + } + + void + testCopy() + { + test_vectors const t; + + // copy(char*, count, pos) + { + { + string s(t.v1); + std::string d; + d.resize(s.size()); + s.copy(&d[0], d.size(), 0); + BOOST_TEST(d == t.v1); + } + + { + string s(t.v1); + std::string d; + d.resize(s.size()); + s.copy(&d[0], d.size()); + BOOST_TEST(d == t.v1); + } + } + } + + void + testResize() + { + test_vectors const t; + + // resize(size_type) + { + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + s.resize(t.v1.size()); + BOOST_TEST(s.size() == t.v1.size()); + BOOST_TEST(s == string(t.v1.size(), '\0')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + s.resize(t.v2.size()); + BOOST_TEST(s.size() == t.v2.size()); + BOOST_TEST(s == string(t.v2.size(), '\0')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + s.resize(t.v1.size()); + s.resize(t.v2.size()); + BOOST_TEST(s == string(t.v2.size(), '\0')); + s.resize(t.v1.size()); + BOOST_TEST(s == string(t.v1.size(), '\0')); + }); + } + + // resize(size_type, char) + { + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + s.resize(t.v1.size(), '*'); + BOOST_TEST(s.size() == t.v1.size()); + BOOST_TEST(s == string(t.v1.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + s.resize(t.v2.size(), '*'); + BOOST_TEST(s.size() == t.v2.size()); + BOOST_TEST(s == string(t.v2.size(), '*')); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s(sp); + s.resize(t.v1.size(), '*'); + s.resize(t.v2.size(), '*'); + BOOST_TEST(s == string(t.v2.size(), '*')); + s.resize(t.v1.size()); + BOOST_TEST(s == string(t.v1.size(), '*')); + }); + } + } + + void + testSwap() + { + test_vectors const t; + + // swap + { + fail_loop([&](storage_ptr const& sp) + { + string s1(t.v1, sp); + string s2(t.v2, sp); + s1.swap(s2); + BOOST_TEST(s1 == t.v2); + BOOST_TEST(s2 == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s1(t.v1, sp); + string s2(t.v2, sp); + swap(s1, s2); + BOOST_TEST(s1 == t.v2); + BOOST_TEST(s2 == t.v1); + }); + + fail_loop([&](storage_ptr const& sp) + { + string s1(t.v1); + string s2(t.v2, sp); + s1.swap(s2); + BOOST_TEST(s1 == t.v2); + BOOST_TEST(s2 == t.v1); + }); + } + } + + void + testFind() + { + test_vectors const t; + string const s1 = t.v1; + + // find(string_view, size_type) + BOOST_TEST(s1.find("bcd") == 1); + BOOST_TEST(s1.find("cde") == 2); + + BOOST_TEST(s1.find("bcd", 0) == 1); + BOOST_TEST(s1.find("cde", 1) == 2); + BOOST_TEST(s1.find("efg", 5) == string::npos); + + // find(char, size_type) + BOOST_TEST(s1.find('b') == 1); + BOOST_TEST(s1.find('c', 1) == 2); + BOOST_TEST(s1.find('e', 5) == string::npos); + } + + void + testRfind() + { + test_vectors const t; + string const s1 = t.v1; + + // rfind(string_view, size_type) + BOOST_TEST(s1.rfind("bcd") == 1); + BOOST_TEST(s1.rfind("cde") == 2); + + BOOST_TEST(s1.rfind("bcd", 1) == 1); + BOOST_TEST(s1.rfind("cde", 2) == 2); + BOOST_TEST(s1.rfind("efg", 3) == string::npos); + + // rfind(char, size_type) + BOOST_TEST(s1.rfind('b') == 1); + BOOST_TEST(s1.rfind('c', 2) == 2); + BOOST_TEST(s1.rfind('e', 3) == string::npos); + } + + void + testFindFirstOf() + { + test_vectors const t; + string const s1 = t.v1; + + // find_first_of(string_view, size_type) + BOOST_TEST(s1.find_first_of("bcd") == 1); + BOOST_TEST(s1.find_first_of("cde") == 2); + + BOOST_TEST(s1.find_first_of("bcd", 0) == 1); + BOOST_TEST(s1.find_first_of("cde", 1) == 2); + BOOST_TEST(s1.find_first_of("efg", 7) == string::npos); + } + + void + testFindFirstNotOf() + { + test_vectors const t; + string const s1 = t.v1; + + // find_first_not_of(string_view, size_type) + BOOST_TEST(s1.find_first_not_of("abc") == 3); + BOOST_TEST(s1.find_first_not_of("cde") == 0); + + BOOST_TEST(s1.find_first_not_of("bcd", 0) == 0); + BOOST_TEST(s1.find_first_not_of("cde", 2) == 5); + + // find_first_not_of(char, size_type) + BOOST_TEST(s1.find_first_not_of('b') == 0); + BOOST_TEST(s1.find_first_not_of('a', 0) == 1); + BOOST_TEST(s1.find_first_not_of('e', 4) == 5); + } + + void + testFindLastOf() + { + test_vectors const t; + string const s1 = t.v1; + + // find_last_of(string_view, size_type) + BOOST_TEST(s1.find_last_of("bcd") == 3); + BOOST_TEST(s1.find_last_of("cde") == 4); + + BOOST_TEST(s1.find_last_of("bcd", 3) == 3); + BOOST_TEST(s1.find_last_of("cde", 5) == 4); + BOOST_TEST(s1.find_last_of("efg", 3) == string::npos); + } + + void + testFindLastNotOf() + { + test_vectors const t; + string const s1 = t.v1; + + // find_last_not_of(string_view, size_type) + BOOST_TEST(s1.find_last_not_of("abc", 3) == 3); + BOOST_TEST(s1.find_last_not_of("bcd", 3) == 0); + + BOOST_TEST(s1.find_last_not_of("efg", 4) == 3); + BOOST_TEST(s1.find_last_not_of("abc", 2) == string::npos); + + // find_first_not_of(char, size_type) + BOOST_TEST(s1.find_last_not_of('a', 3) == 3); + BOOST_TEST(s1.find_last_not_of('e', 4) == 3); + BOOST_TEST(s1.find_last_not_of('a', 0) == string::npos); + } + + void + testNonMembers() + { + test_vectors const t; + string const s1(t.v1); + string const s2(t.v2); + auto const v1(t.v1); + auto const v2(t.v2); + auto const c1 = t.s1.c_str(); + auto const c2 = t.s2.c_str(); + + BOOST_TEST(! operator< (s1, s2)); + BOOST_TEST(! operator< (s1, v2)); + BOOST_TEST(! operator< (s1, c2)); + BOOST_TEST(! operator<=(s1, s2)); + BOOST_TEST(! operator<=(s1, v2)); + BOOST_TEST(! operator<=(s1, c2)); + BOOST_TEST(! operator==(s1, s2)); + BOOST_TEST(! operator==(s1, v2)); + BOOST_TEST(! operator==(s1, c2)); + BOOST_TEST( operator!=(s1, s2)); + BOOST_TEST( operator!=(s1, v2)); + BOOST_TEST( operator!=(s1, c2)); + BOOST_TEST( operator>=(s1, s2)); + BOOST_TEST( operator>=(s1, v2)); + BOOST_TEST( operator>=(s1, c2)); + BOOST_TEST( operator> (s1, s2)); + BOOST_TEST( operator> (s1, v2)); + BOOST_TEST( operator> (s1, c2)); + + BOOST_TEST( operator< (s2, s1)); + BOOST_TEST( operator< (s2, v1)); + BOOST_TEST( operator< (s2, c1)); + BOOST_TEST( operator<=(s2, s1)); + BOOST_TEST( operator<=(s2, v1)); + BOOST_TEST( operator<=(s2, c1)); + BOOST_TEST( operator!=(s2, s1)); + BOOST_TEST( operator!=(s2, v1)); + BOOST_TEST( operator!=(s2, c1)); + BOOST_TEST(! operator==(s2, s1)); + BOOST_TEST(! operator==(s2, v1)); + BOOST_TEST(! operator==(s2, c1)); + BOOST_TEST(! operator>=(s2, s1)); + BOOST_TEST(! operator>=(s2, v1)); + BOOST_TEST(! operator>=(s2, c1)); + BOOST_TEST(! operator> (s2, s1)); + BOOST_TEST(! operator> (s2, v1)); + BOOST_TEST(! operator> (s2, c1)); + + BOOST_TEST( operator< (s2, s1)); + BOOST_TEST( operator< (v2, s1)); + BOOST_TEST( operator< (c2, s1)); + BOOST_TEST( operator<=(s2, s1)); + BOOST_TEST( operator<=(v2, s1)); + BOOST_TEST( operator<=(c2, s1)); + BOOST_TEST( operator!=(s2, s1)); + BOOST_TEST( operator!=(v2, s1)); + BOOST_TEST( operator!=(c2, s1)); + BOOST_TEST(! operator==(s2, s1)); + BOOST_TEST(! operator==(v2, s1)); + BOOST_TEST(! operator==(c2, s1)); + BOOST_TEST(! operator>=(s2, s1)); + BOOST_TEST(! operator>=(v2, s1)); + BOOST_TEST(! operator>=(c2, s1)); + BOOST_TEST(! operator> (s2, s1)); + BOOST_TEST(! operator> (v2, s1)); + BOOST_TEST(! operator> (c2, s1)); + + BOOST_TEST(! operator< (s1, s2)); + BOOST_TEST(! operator< (v1, s2)); + BOOST_TEST(! operator< (c1, s2)); + BOOST_TEST(! operator<=(s1, s2)); + BOOST_TEST(! operator<=(v1, s2)); + BOOST_TEST(! operator<=(c1, s2)); + BOOST_TEST(! operator==(s1, s2)); + BOOST_TEST(! operator==(v1, s2)); + BOOST_TEST(! operator==(c1, s2)); + BOOST_TEST( operator!=(s1, s2)); + BOOST_TEST( operator!=(v1, s2)); + BOOST_TEST( operator!=(c1, s2)); + BOOST_TEST( operator>=(s1, s2)); + BOOST_TEST( operator>=(v1, s2)); + BOOST_TEST( operator>=(c1, s2)); + BOOST_TEST( operator> (s1, s2)); + BOOST_TEST( operator> (v1, s2)); + BOOST_TEST( operator> (c1, s2)); + } + + void + testHash() + { + // libstdc++ 4.8 bug +#if !defined(__GNUC__) || (__GNUC__ > 4 || \ + (__GNUC__ == 4 && __GNUC_MINOR__ > 8)) + { + std::unordered_set<string> us; + us.emplace("first"); + us.emplace("second"); + } + { + std::unordered_set<string>( + 0, + std::hash<string>(32)); + } +#endif + { + std::hash<string> h1(32); + std::hash<string> h2(h1); + std::hash<string> h3(59); + h1 = h3; + h2 = h3; + (void)h2; + } + } + + void + run() + { + testConstruction(); + testAssignment(); + testAssign(); + testConversion(); + testElementAccess(); + testIterators(); + testCapacity(); + + testClear(); + testInsert(); + testErase(); + testPushPop(); + testAppend(); + testPlusEquals(); + testCompare(); + testStartEndsWith(); + testReplace(); + testSubStr(); + testCopy(); + testResize(); + testSwap(); + + testFind(); + testRfind(); + testFindFirstOf(); + testFindFirstNotOf(); + testFindLastOf(); + testFindLastNotOf(); + + testNonMembers(); + + testHash(); + } +}; + +TEST_SUITE(string_test, "boost.json.string"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/string_view.cpp b/src/boost/libs/json/test/string_view.cpp new file mode 100644 index 000000000..671132c3f --- /dev/null +++ b/src/boost/libs/json/test/string_view.cpp @@ -0,0 +1,11 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/string_view.hpp> diff --git a/src/boost/libs/json/test/system_error.cpp b/src/boost/libs/json/test/system_error.cpp new file mode 100644 index 000000000..4b34ec799 --- /dev/null +++ b/src/boost/libs/json/test/system_error.cpp @@ -0,0 +1,11 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/system_error.hpp> diff --git a/src/boost/libs/json/test/test.hpp b/src/boost/libs/json/test/test.hpp new file mode 100644 index 000000000..fe6dd540c --- /dev/null +++ b/src/boost/libs/json/test/test.hpp @@ -0,0 +1,1163 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#ifndef BOOST_JSON_TEST_HPP +#define BOOST_JSON_TEST_HPP + +#include <boost/json/basic_parser.hpp> +#include <boost/json/value.hpp> +#include <boost/json/serializer.hpp> +#include <boost/json/storage_ptr.hpp> +#include <boost/json/detail/format.hpp> + +#include <cstddef> +#include <iterator> +#include <memory> +#include <type_traits> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +//---------------------------------------------------------- + +struct test_failure : std::exception +{ + virtual + char const* + what() const noexcept override + { + return "test failure"; + } +}; + +struct fail_resource + : memory_resource +{ + std::size_t fail_max = 0; + std::size_t fail = 0; + std::size_t nalloc = 0; + std::size_t bytes = 0; + + ~fail_resource() + { + BOOST_TEST(nalloc == 0); + } + + void* + do_allocate( + std::size_t n, + std::size_t) override + { + if(++fail == fail_max) + { + ++fail_max; + fail = 0; + throw test_failure{}; + } + auto p = ::operator new(n); + ++nalloc; + bytes += n; + return p; + } + + void + do_deallocate( + void* p, + std::size_t n, + std::size_t) noexcept override + { + if(BOOST_TEST(nalloc > 0)) + --nalloc; + bytes -= n; + ::operator delete(p); + } + + bool + do_is_equal( + memory_resource const& mr) const noexcept override + { + return this == &mr; + } +}; + +template<class F> +void +fail_loop(F&& f) +{ + fail_resource ss; + ss.fail_max = 1; + while(ss.fail < 200) + { + try + { + f(&ss); + } + catch(test_failure const&) + { + continue; + } + break; + } + BOOST_TEST(ss.fail < 200); +} + +//---------------------------------------------------------- + +struct unique_resource + : memory_resource +{ + unique_resource() = default; + + void* + do_allocate( + std::size_t n, + std::size_t) override + { + return ::operator new(n); + } + + void + do_deallocate( + void* p, + std::size_t, + std::size_t) noexcept override + { + return ::operator delete(p); + } + + bool + do_is_equal( + memory_resource const& mr) const noexcept override + { + return this == &mr; + } +}; + +//---------------------------------------------------------- + +// The null parser discards all the data + +class null_parser +{ + struct handler + { + constexpr static std::size_t max_object_size = std::size_t(-1); + constexpr static std::size_t max_array_size = std::size_t(-1); + constexpr static std::size_t max_key_size = std::size_t(-1); + constexpr static std::size_t max_string_size = std::size_t(-1); + + bool on_document_begin( error_code& ) { return true; } + bool on_document_end( error_code& ) { return true; } + bool on_object_begin( error_code& ) { return true; } + bool on_object_end( std::size_t, error_code& ) { return true; } + bool on_array_begin( error_code& ) { return true; } + bool on_array_end( std::size_t, error_code& ) { return true; } + bool on_key_part( string_view, std::size_t, error_code& ) { return true; } + bool on_key( string_view, std::size_t, error_code& ) { return true; } + bool on_string_part( string_view, std::size_t, error_code& ) { return true; } + bool on_string( string_view, std::size_t, error_code& ) { return true; } + bool on_number_part( string_view, error_code&) { return true; } + bool on_int64( std::int64_t, string_view, error_code& ) { return true; } + bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; } + bool on_double( double, string_view, error_code& ) { return true; } + bool on_bool( bool, error_code& ) { return true; } + bool on_null( error_code& ) { return true; } + bool on_comment_part( string_view, error_code& ) { return true; } + bool on_comment( string_view, error_code& ) { return true; } + }; + + basic_parser<handler> p_; + +public: + null_parser() + : p_(parse_options()) + { + } + + explicit + null_parser(parse_options po) + : p_(po) + { + } + + void + reset() + { + p_.reset(); + } + + std::size_t + write( + char const* data, + std::size_t size, + error_code& ec) + { + auto const n = p_.write_some( + false, data, size, ec); + if(! ec && n < size) + ec = error::extra_data; + return n; + } +}; + +//---------------------------------------------------------- + +class fail_parser +{ + struct handler + { + constexpr static std::size_t max_object_size = std::size_t(-1); + constexpr static std::size_t max_array_size = std::size_t(-1); + constexpr static std::size_t max_key_size = std::size_t(-1); + constexpr static std::size_t max_string_size = std::size_t(-1); + + std::size_t n; + + handler() + : n(std::size_t(-1)) + { + } + + bool + maybe_fail(error_code& ec) + { + if(n && --n > 0) + return true; + ec = error::test_failure; + return false; + } + + bool + on_document_begin( + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_document_end( + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_object_begin( + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_object_end( + std::size_t, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_array_begin( + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_array_end( + std::size_t, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_key_part( + string_view, + std::size_t, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_key( + string_view, + std::size_t, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_string_part( + string_view, + std::size_t, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_string( + string_view, + std::size_t, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_number_part( + string_view, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_int64( + int64_t, + string_view, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_uint64( + uint64_t, + string_view, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_double( + double, + string_view, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_bool( + bool, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_null(error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_comment_part( + string_view, + error_code& ec) + { + return maybe_fail(ec); + } + + bool + on_comment( + string_view, + error_code& ec) + { + return maybe_fail(ec); + } + }; + + basic_parser<handler> p_; + +public: + fail_parser() + : p_(parse_options()) + { + } + + explicit + fail_parser( + std::size_t n, + parse_options po = parse_options()) + : p_(po) + { + p_.handler().n = n; + } + + explicit + fail_parser(parse_options po) + : p_(po) + { + } + + void + reset() + { + p_.reset(); + } + + bool + done() const noexcept + { + return p_.done(); + } + + std::size_t + write_some( + bool more, + char const* data, + std::size_t size, + error_code& ec) + { + return p_.write_some( + more, data, size, ec); + } + + std::size_t + write( + bool more, + char const* data, + std::size_t size, + error_code& ec) + { + auto const n = p_.write_some( + more, data, size, ec); + if(! ec && n < size) + ec = error::extra_data; + return n; + } +}; + +//---------------------------------------------------------- + +struct test_exception + : std::exception +{ + char const* + what() const noexcept + { + return "test exception"; + } +}; + +// Exercises every exception path +class throw_parser +{ + struct handler + { + constexpr static std::size_t max_object_size = std::size_t(-1); + constexpr static std::size_t max_array_size = std::size_t(-1); + constexpr static std::size_t max_key_size = std::size_t(-1); + constexpr static std::size_t max_string_size = std::size_t(-1); + + std::size_t n; + + handler() + : n(std::size_t(-1)) + { + } + + bool + maybe_throw() + { + if(n && --n > 0) + return true; + throw test_exception{}; + } + + bool + on_document_begin( + error_code&) + { + return maybe_throw(); + } + + bool + on_document_end( + error_code&) + { + return maybe_throw(); + } + + bool + on_object_begin( + error_code&) + { + return maybe_throw(); + } + + bool + on_object_end( + std::size_t, + error_code&) + { + return maybe_throw(); + } + + bool + on_array_begin( + error_code&) + { + return maybe_throw(); + } + + bool + on_array_end( + std::size_t, + error_code&) + { + return maybe_throw(); + } + + bool + on_key_part( + string_view, + std::size_t, + error_code&) + { + return maybe_throw(); + } + + bool + on_key( + string_view, + std::size_t, + error_code&) + { + return maybe_throw(); + } + + bool + on_string_part( + string_view, + std::size_t, + error_code&) + { + return maybe_throw(); + } + + bool + on_string( + string_view, + std::size_t, + error_code&) + { + return maybe_throw(); + } + + bool + on_number_part( + string_view, + error_code&) + { + return maybe_throw(); + } + + bool + on_int64( + int64_t, + string_view, + error_code&) + { + return maybe_throw(); + } + + bool + on_uint64( + uint64_t, + string_view, + error_code&) + { + return maybe_throw(); + } + + bool + on_double( + double, + string_view, + error_code&) + { + return maybe_throw(); + } + + bool + on_bool( + bool, + error_code&) + { + return maybe_throw(); + } + + bool + on_null(error_code&) + { + return maybe_throw(); + } + + bool + on_comment_part( + string_view, + error_code&) + { + return maybe_throw(); + } + + bool + on_comment( + string_view, + error_code&) + { + return maybe_throw(); + } + }; + + basic_parser<handler> p_; + +public: + throw_parser() + : p_(parse_options()) + { + } + + explicit + throw_parser( + std::size_t n, + parse_options po = parse_options()) + : p_(po) + { + p_.handler().n = n; + } + + explicit + throw_parser(parse_options po) + : p_(po) + { + } + + void + reset() noexcept + { + p_.reset(); + } + + std::size_t + write( + bool more, + char const* data, + std::size_t size, + error_code& ec) + { + auto const n = p_.write_some( + more, data, size, ec); + if(! ec && n < size) + ec = error::extra_data; + return n; + } +}; + +//---------------------------------------------------------- + +// wrap an iterator to make an input iterator +template<class FwdIt> +class input_iterator +{ + FwdIt it_; + +public: + using value_type = typename std::iterator_traits<FwdIt>::value_type; + using pointer = typename std::iterator_traits<FwdIt>::pointer; + using reference = typename std::iterator_traits<FwdIt>::reference; + using difference_type = typename std::iterator_traits<FwdIt>::difference_type; + using iterator_category = std::input_iterator_tag; + + input_iterator() = default; + input_iterator(input_iterator const&) = default; + input_iterator& operator=( + input_iterator const&) = default; + + input_iterator(FwdIt it) + : it_(it) + { + } + + input_iterator& + operator++() noexcept + { + ++it_; + return *this; + } + + input_iterator + operator++(int) noexcept + { + auto tmp = *this; + ++*this; + return tmp; + } + + pointer + operator->() const noexcept + { + return it_.operator->(); + } + + reference + operator*() const noexcept + { + return *it_; + } + + bool + operator==(input_iterator other) const noexcept + { + return it_ == other.it_; + } + + bool + operator!=(input_iterator other) const noexcept + { + return it_ != other.it_; + } +}; + +template<class FwdIt> +input_iterator<FwdIt> +make_input_iterator(FwdIt it) +{ + return input_iterator<FwdIt>(it); +} + +//---------------------------------------------------------- + +inline +bool +equal_storage( + value const& v, + storage_ptr const& sp); + +inline +bool +equal_storage( + object const& o, + storage_ptr const& sp) +{ + if(*o.storage() != *sp) + return false; + for(auto const& e : o) + if(! equal_storage(e.value(), sp)) + return false; + return true; +} + +inline +bool +equal_storage( + array const& a, + storage_ptr const& sp) +{ + if(*a.storage() != *sp) + return false; + for(auto const& v : a) + if(! equal_storage(v, sp)) + return false; + return true; +} + +bool +equal_storage( + value const& v, + storage_ptr const& sp) +{ + switch(v.kind()) + { + case json::kind::object: + if(*v.as_object().storage() != *sp) + return false; + return equal_storage(v.as_object(), sp); + + case json::kind::array: + if(*v.as_array().storage() != *sp) + return false; + return equal_storage(v.as_array(), sp); + + case json::kind::string: + return *v.as_string().storage() == *sp; + + case json::kind::int64: + case json::kind::uint64: + case json::kind::double_: + case json::kind::bool_: + case json::kind::null: + break; + } + + return *v.storage() == *sp; +} + +inline +void +check_storage( + object const& o, + storage_ptr const& sp) +{ + BOOST_TEST(equal_storage(o, sp)); +} + +inline +void +check_storage( + array const& a, + storage_ptr const& sp) +{ + BOOST_TEST(equal_storage(a, sp)); +} + +inline +void +check_storage( + value const& v, + storage_ptr const& sp) +{ + BOOST_TEST(equal_storage(v, sp)); +} + +//---------------------------------------------------------- + +namespace detail { + +inline +void +to_string_test( + string& dest, + json::value const& jv) +{ + switch(jv.kind()) + { + case kind::object: + { + dest.push_back('{'); + auto const& obj( + jv.get_object()); + auto it = obj.begin(); + if(it != obj.end()) + { + goto obj_first; + while(it != obj.end()) + { + dest.push_back(','); + obj_first: + dest.push_back('\"'); + dest.append(it->key()); + dest.push_back('\"'); + dest.push_back(':'); + to_string_test( + dest, it->value()); + ++it; + } + } + dest.push_back('}'); + break; + } + + case kind::array: + { + dest.push_back('['); + auto const& arr( + jv.get_array()); + auto it = arr.begin(); + if(it != arr.end()) + { + goto arr_first; + while(it != arr.end()) + { + dest.push_back(','); + arr_first: + to_string_test( + dest, *it); + ++it; + } + } + dest.push_back(']'); + break; + } + + case kind::string: + #if 1 + // safe, but doesn't handle escsapes + dest.push_back('\"'); + dest.append(jv.get_string()); + dest.push_back('\"'); + #else + dest.append(serialize(jv)); + #endif + break; + + case kind::int64: + { + char buf[detail::max_number_chars]; + auto const n = + detail::format_int64( + buf, jv.as_int64()); + dest.append(string_view(buf).substr(0, n)); + break; + } + + case kind::uint64: + { + char buf[detail::max_number_chars]; + auto const n = + detail::format_uint64( + buf, jv.as_uint64()); + dest.append(string_view(buf).substr(0, n)); + break; + } + + case kind::double_: + { + char buf[detail::max_number_chars]; + auto const n = + detail::format_double( + buf, jv.as_double()); + dest.append(string_view(buf).substr(0, n)); + break; + } + + case kind::bool_: + if(jv.as_bool()) + dest.append("true"); + else + dest.append("false"); + break; + + case kind::null: + dest.append("null"); + break; + + default: + // should never get here + dest.append("?"); + break; + } +} + +} // detail + +inline +string +to_string_test( + json::value const& jv) +{ + string s; + s.reserve(1024); + detail::to_string_test(s, jv); + return s; +} + +//---------------------------------------------------------- + +inline +bool +equal( + value const& lhs, + value const& rhs) +{ + if(lhs.kind() != rhs.kind()) + return false; + switch(lhs.kind()) + { + case kind::object: + { + auto const& obj1 = + lhs.get_object(); + auto const& obj2 = + rhs.get_object(); + auto n = obj1.size(); + if(obj2.size() != n) + return false; + auto it1 = obj1.begin(); + auto it2 = obj2.begin(); + while(n--) + { + if( it1->key() != + it2->key()) + return false; + if(! equal( + it1->value(), + it2->value())) + return false; + ++it1; + ++it2; + } + return true; + } + + case kind::array: + { + auto const& arr1 = + lhs.get_array(); + auto const& arr2 = + rhs.get_array(); + auto n = arr1.size(); + if(arr2.size() != n) + return false; + auto it1 = arr1.begin(); + auto it2 = arr2.begin(); + while(n--) + if(! equal(*it1++, *it2++)) + return false; + return true; + } + + case kind::string: + return + lhs.get_string() == + rhs.get_string(); + + case kind::double_: + return + lhs.get_double() == + rhs.get_double(); + + case kind::int64: + return + lhs.get_int64() == + rhs.get_int64(); + + case kind::uint64: + return + lhs.get_uint64() == + rhs.get_uint64(); + + case kind::bool_: + return + lhs.get_bool() == + rhs.get_bool(); + + case kind::null: + return true; + } + + return false; +} + +template<typename T> +inline +bool +check_hash_equal( + T const& lhs, + T const& rhs) +{ + if(lhs == rhs){ + return (std::hash<T>{}(lhs) == std::hash<T>{}(rhs)); + } + return false; // ensure lhs == rhs intention +} + +template<typename T, typename U> +inline +bool +check_hash_equal( + T const& lhs, + U const& rhs) +{ + if(lhs == rhs){ + return (std::hash<value>{}(lhs) == std::hash<value>{}(rhs)); + } + return false; // ensure lhs == rhs intention +} + +template<typename T> +inline +bool +expect_hash_not_equal( + T const& lhs, + T const& rhs) +{ + if(std::hash<T>{}(lhs) != std::hash<T>{}(rhs)){ + return lhs != rhs; + } + return true; // pass if hash values collide +} + +template<typename T, typename U> +inline +bool +expect_hash_not_equal( + T const& lhs, + U const& rhs) +{ + if(std::hash<value>{}(lhs) != std::hash<value>{}(rhs)){ + return lhs != rhs; + } + return true; // pass if hash values collide +} +//---------------------------------------------------------- + +namespace detail { + +inline +void +check_array_impl(int, value const&) +{ +} + +template<class Arg> +void +check_array_impl( + int i, value const& jv, + Arg const& arg) +{ + BOOST_TEST(equal(jv.at(i), arg)); +} + +template< + class Arg0, + class Arg1, + class... Argn> +void +check_array_impl( + int i, value const& jv, + Arg0 const& arg0, + Arg1 const& arg1, + Argn const&... argn) +{ + BOOST_TEST(equal(jv.at(i), arg0)); + BOOST_TEST(equal(jv.at(i + 1), arg1)); + check_array_impl(i + 2, jv, argn...); +} + +} // detail + +template<class... Argn> +static +void +check_array( + value const& jv, + Argn const&... argn) +{ + if(! BOOST_TEST(jv.is_array())) + return; + if(! BOOST_TEST(sizeof...(argn) == + jv.get_array().size())) + return; + detail::check_array_impl(0, jv, argn...); +} + +//---------------------------------------------------------- + +BOOST_JSON_NS_END + +#endif diff --git a/src/boost/libs/json/test/test_suite.hpp b/src/boost/libs/json/test/test_suite.hpp new file mode 100644 index 000000000..990737430 --- /dev/null +++ b/src/boost/libs/json/test/test_suite.hpp @@ -0,0 +1,758 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#ifndef TEST_SUITE_HPP +#define TEST_SUITE_HPP + +#include <algorithm> +#include <atomic> +#include <chrono> +#include <cstdlib> +#include <cstring> +#include <iomanip> +#include <ios> +#include <memory> +#include <ostream> +#include <sstream> +#include <streambuf> +#include <stdexcept> +#include <string> +#include <type_traits> +#include <vector> + +#ifdef _MSC_VER +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <debugapi.h> +#endif + +// This is a derivative work +// Copyright 2002-2018 Peter Dimov +// Copyright (c) 2002, 2009, 2014 Peter Dimov +// Copyright (2) Beman Dawes 2010, 2011 +// Copyright (3) Ion Gaztanaga 2013 +// +// Copyright 2018 Glen Joseph Fernandes +// (glenjofe@gmail.com) + +namespace test_suite { + +//---------------------------------------------------------- + +#ifdef _MSC_VER + +namespace detail { + +template< + class CharT, class Traits, class Allocator> +class debug_streambuf + : public std::basic_stringbuf< + CharT, Traits, Allocator> +{ + using ostream = + std::basic_ostream<CharT, Traits>; + + ostream& os_; + bool dbg_; + + template<class T> + void write(T const*) = delete; + + void write(char const* s) + { + if(dbg_) + ::OutputDebugStringA(s); + os_ << s; + } + + void write(wchar_t const* s) + { + if(dbg_) + ::OutputDebugStringW(s); + os_ << s; + } + +public: + explicit + debug_streambuf(ostream& os) + : os_(os) + , dbg_(::IsDebuggerPresent() != 0) + { + } + + ~debug_streambuf() + { + sync(); + } + + int + sync() override + { + write(this->str().c_str()); + this->str(""); + return 0; + } +}; + +/** std::ostream with Visual Studio IDE redirection. + + Instances of this stream wrap a specified `std::ostream` + (such as `std::cout` or `std::cerr`). If the IDE debugger + is attached when the stream is created, output will be + additionally copied to the Visual Studio Output window. +*/ +template< + class CharT, + class Traits = std::char_traits<CharT>, + class Allocator = std::allocator<CharT> +> +class basic_debug_stream + : public std::basic_ostream<CharT, Traits> +{ + detail::debug_streambuf< + CharT, Traits, Allocator> buf_; + +public: + /** Construct a stream. + + @param os The output stream to wrap. + */ + explicit + basic_debug_stream(std::ostream& os) + : std::basic_ostream<CharT, Traits>(&buf_) + , buf_(os) + { + if(os.flags() & std::ios::unitbuf) + std::unitbuf(*this); + } +}; + +} // detail + +using debug_stream = detail::basic_debug_stream<char>; +using debug_wstream = detail::basic_debug_stream<wchar_t>; + +#else + +using debug_stream = std::ostream&; +using debug_wstream = std::wostream&; + +#endif + +//---------------------------------------------------------- + +namespace detail { + +struct suite_info +{ + char const* name; + void (*run)(); +}; + +class runner; + +inline +runner*& +current() noexcept; + +inline +void +debug_break() +{ +#ifdef _MSC_VER + ::DebugBreak(); +#else + //?? profit? +#endif +} + +//---------------------------------------------------------- + +struct checkpoint +{ + char const* const file; + int const line; + std::size_t const id; + + static + checkpoint*& + current() noexcept + { + static checkpoint* p = nullptr; + return p; + } + + checkpoint( + char const* file_, + int line_, + std::size_t id_ = 0) + : file(file_) + , line(line_) + , id([] + { + static std::size_t n = 0; + return ++n; + }()) + , prev_(current()) + { + current() = this; + if(id_ == id) + debug_break(); + } + + ~checkpoint() + { + current() = prev_; + } + +private: + checkpoint* prev_; +}; + +//---------------------------------------------------------- + +class runner +{ + runner* saved_; + +public: + runner() noexcept + : saved_(current()) + { + current() = this; + } + + virtual + ~runner() + { + current() = saved_; + } + + virtual void on_begin(char const* name) = 0; + virtual void on_end() = 0; + + virtual void note(char const* msg) = 0; + virtual void pass(char const* expr, char const* file, int line, char const* func) = 0; + virtual void fail(char const* expr, char const* file, int line, char const* func) = 0; + + template<class Bool +#if 0 + ,class = typename std::enable_if< + std::is_convertible<bool, Bool>::Value>::type +#endif + > + bool + maybe_fail( + Bool cond, + char const* expr, + char const* file, + int line, + char const* func) + { + if(!!cond) + { + pass(expr, file, line, func); + return true; + } + fail(expr, file, line, func); + return false; + } + + void + run(suite_info const& si) + { + on_begin(si.name); + si.run(); + on_end(); + } +}; + +runner*& +current() noexcept +{ + static runner* p = nullptr; + return p; +} + +//---------------------------------------------------------- + +using clock_type = + std::chrono::steady_clock; + +struct elapsed +{ + clock_type::duration d; +}; + +inline +std::ostream& +operator<<( + std::ostream& os, + elapsed const& e) +{ + using namespace std::chrono; + auto const ms = duration_cast< + milliseconds>(e.d); + if(ms < seconds{1}) + { + os << ms.count() << "ms"; + } + else + { + std::streamsize width{ + os.width()}; + std::streamsize precision{ + os.precision()}; + os << std::fixed << + std::setprecision(1) << + (ms.count() / 1000.0) << "s"; + os.precision(precision); + os.width(width); + } + return os; +} + +class simple_runner : public runner +{ + struct summary + { + char const* name; + clock_type::time_point start; + clock_type::duration elapsed; + std::atomic<std::size_t> failed; + std::atomic<std::size_t> total; + + summary(summary const& other) noexcept + : name(other.name) + , start(other.start) + , elapsed(other.elapsed) + , failed(other.failed.load()) + , total(other.total.load()) + { + } + + explicit + summary(char const* name_) noexcept + : name(name_) + , start(clock_type::now()) + , failed(0) + , total(0) + { + } + }; + + summary all_; + std::ostream& log_; + std::vector<summary> v_; + +public: + explicit + simple_runner( + std::ostream& log) + : all_("(all)") + , log_(log) + { + std::unitbuf(log_); + v_.reserve(256); + } + + ~simple_runner() + { + log_ << + elapsed{clock_type::now() - + all_.start } << ", " << + v_.size() << " suites, " << + all_.failed.load() << " failures, " << + all_.total.load() << " total." << + std::endl; + } + + // true if no failures + bool + success() const noexcept + { + return all_.failed.load() == 0; + } + + void + on_begin(char const* name) override + { + v_.emplace_back(name); + log_ << name << "\n"; + } + + void + on_end() override + { + v_.back().elapsed = + clock_type::now() - + v_.back().start; + } + + void + note(char const* msg) override + { + log_ << msg << "\n"; + } + + char const* + filename( + char const* file) + { + auto const p0 = file; + auto p = p0 + std::strlen(file); + while(p-- != p0) + { + #ifdef _MSC_VER + if(*p == '\\') + #else + if(*p == '/') + #endif + break; + } + return p + 1; + } + + void + pass( + char const*, + char const*, + int, + char const*) override + { + ++all_.total; + ++v_.back().total; + } + + void + fail( + char const* expr, + char const* file, + int line, + char const*) override + { + ++all_.failed; + ++v_.back().total; + ++v_.back().failed; + auto const id = ++all_.total; + auto const cp = + checkpoint::current(); + if(cp) + log_ << + "case " << cp->id << + "(#" << id << ") " << + filename(cp->file) << + "(" << cp->line << ") " + "failed: " << expr << "\n"; + else + log_ << + "#" << id << + " " << filename(file) << + "(" << line << ") " + "failed: " << expr << "\n"; + } +}; + +//---------------------------------------------------------- + +template< + class CharT, + class Traits = std::char_traits<CharT>, + class Allocator = std::allocator<CharT> +> +class log_ostream + : public std::basic_ostream<CharT, Traits> +{ + struct buffer_type : + std::basic_stringbuf< + CharT, Traits, Allocator> + { + ~buffer_type() + { + sync(); + } + + int + sync() override + { + auto const& s = this->str(); + if(s.size() > 0) + current()->note(s.c_str()); + this->str(""); + return 0; + } + }; + + buffer_type buf_; + +public: + log_ostream() + : std::basic_ostream< + CharT, Traits>(&buf_) + { + } +}; + +//---------------------------------------------------------- + +class suite_list +{ + static std::size_t const max_size_ = 256; + std::size_t count_ = 0; + suite_info data_[max_size_]; + +public: + void + insert(suite_info inf) + { + #ifndef BOOST_NO_EXCEPTIONS + if(count_ == max_size_) + throw std::length_error( + "too many test suites"); + #endif + data_[count_++] = inf; + } + + suite_info const* + begin() const noexcept + { + return data_; + } + + suite_info const* + end() const noexcept + { + return begin() + count_; + } + + void + sort() + { + std::sort( + data_, + data_ + count_, + []( detail::suite_info const& lhs, + detail::suite_info const& rhs) + { + return std::lexicographical_compare( + lhs.name, lhs.name + std::strlen(lhs.name), + rhs.name, rhs.name + std::strlen(rhs.name)); + }); + } +}; + +inline +suite_list& +suites() +{ + static suite_list list; + return list; +} + +//---------------------------------------------------------- + +template<class T> +struct instance +{ + explicit + instance( + char const* name) noexcept + { + suites().insert(suite_info{ + name, &instance::run }); + } + + static + void + run() + { + auto const saved = + current(); + //current()->os_ + T().run(); + current() = saved; + } +}; + +//---------------------------------------------------------- + +inline +void +current_function_helper() +{ +#if defined(__GNUC__) || \ + (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || \ + (defined(__ICC) && (__ICC >= 600)) || \ + defined(__ghs__) || \ + defined(__clang__) +# define TEST_SUITE_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__DMC__) && (__DMC__ >= 0x810) +# define TEST_SUITE_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__FUNCSIG__) +# define TEST_SUITE_FUNCTION __FUNCSIG__ + +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || \ + (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) +# define TEST_SUITE_FUNCTION __FUNCTION__ + +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) +# define TEST_SUITE_FUNCTION __FUNC__ + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define TEST_SUITE_FUNCTION __func__ + +#elif defined(__cplusplus) && (__cplusplus >= 201103) +# define TEST_SUITE_FUNCTION __func__ + +#else +# define TEST_SUITE_FUNCTION "(unknown)" + +#endif +} + +} // detail + +//---------------------------------------------------------- + +/** The type of log for output to the currently running suite. +*/ +using log_type = detail::log_ostream<char>; + +#define BOOST_TEST_CHECKPOINT(...) \ + ::test_suite::detail::checkpoint \ + _BOOST_TEST_CHECKPOINT ## __LINE__ ( \ + __FILE__, __LINE__, __VA_ARGS__ + 0) + +#define BOOST_TEST(expr) \ + ::test_suite::detail::current()->maybe_fail( \ + (expr), #expr, __FILE__, __LINE__, TEST_SUITE_FUNCTION) + +#define BOOST_ERROR(msg) \ + ::test_suite::detail::current()->fail( \ + msg, __FILE__, __LINE__, TEST_SUITE_FUNCTION) + +#define BOOST_TEST_PASS() \ + ::test_suite::detail::current()->pass( \ + "", __FILE__, __LINE__, TEST_SUITE_FUNCTION) + +#define BOOST_TEST_FAIL() \ + ::test_suite::detail::current()->fail( \ + "", __FILE__, __LINE__, TEST_SUITE_FUNCTION) + +#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr)) + +#ifndef BOOST_NO_EXCEPTIONS +# define BOOST_TEST_THROWS( expr, except ) \ + try { \ + (void)(expr); \ + ::test_suite::detail::current()->fail ( \ + #except, __FILE__, __LINE__, \ + TEST_SUITE_FUNCTION); \ + } \ + catch(except const&) { \ + ::test_suite::detail::current()->pass( \ + #except, __FILE__, __LINE__, \ + TEST_SUITE_FUNCTION); \ + } \ + catch(...) { \ + ::test_suite::detail::current()->fail( \ + #except, __FILE__, __LINE__, \ + TEST_SUITE_FUNCTION); \ + } + +# define BOOST_TEST_THROWS_WITH_LOCATION( expr ) \ + try \ + { \ + expr; \ + ::test_suite::detail::current()->fail( \ + "system_error", __FILE__, __LINE__, \ + TEST_SUITE_FUNCTION); \ + } \ + catch (::boost::json::system_error const& exc) \ + { \ + ::test_suite::detail::current()->maybe_fail( \ + exc.code().has_location(), "has_location()", __FILE__, __LINE__, \ + TEST_SUITE_FUNCTION); \ + } \ + catch(...) { \ + ::test_suite::detail::current()->fail( \ + "system_error", __FILE__, __LINE__, \ + TEST_SUITE_FUNCTION); \ + } + +#else + #define BOOST_TEST_THROWS( expr, except ) + #define BOOST_TEST_THROWS_WITH_LOCATION(expr) +#endif + +#define TEST_SUITE(type, name) \ + static ::test_suite::detail::instance<type> type##_(name) + +inline +int +run(std::ostream& log, + int argc, char const* const* argv) +{ + if(argc == 2) + { + std::string arg(argv[1]); + if(arg == "-h" || arg == "--help") + { + log << + "Usage:\n" + " " << argv[0] << ": { <suite-name>... }" << + std::endl; + return EXIT_SUCCESS; + } + } + + using namespace ::test_suite; + + detail::simple_runner runner(log); + detail::suites().sort(); + if(argc == 1) + { + for(auto const& e : detail::suites()) + runner.run(e); + } + else + { + std::vector<std::string> args; + args.reserve(argc - 1); + for(int i = 0; i < argc - 1; ++i) + args.push_back(argv[i + 1]); + for(auto const& e : detail::suites()) + { + std::string s(e.name); + if(std::find_if( + args.begin(), args.end(), + [&](std::string const& arg) + { + if(arg.size() > s.size()) + return false; + return s.compare( + s.size() - arg.size(), + arg.size(), + arg.data(), + arg.size()) == 0; + }) != args.end()) + { + runner.run(e); + } + } + } + return runner.success() ? + EXIT_SUCCESS : EXIT_FAILURE; +} + +} // test_suite + +#endif diff --git a/src/boost/libs/json/test/value.cpp b/src/boost/libs/json/test/value.cpp new file mode 100644 index 000000000..52684fe25 --- /dev/null +++ b/src/boost/libs/json/test/value.cpp @@ -0,0 +1,2186 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/value.hpp> + +#include <boost/json/monotonic_resource.hpp> + +#include <memory> +#include <string> +#include <vector> + +#include "test.hpp" +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<value>::value ); +BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<value>::value ); + +namespace { + +template<class T> +static +T max_of() +{ + return (std::numeric_limits<T>::max)(); +} + +template<class T> +static +T min_of() +{ + return (std::numeric_limits<T>::min)(); +} + +} // (anon) + +class value_test +{ +public: + //BOOST_STATIC_ASSERT(has_value_from<short>::value); + + string_view const str_; + + value_test() + : str_( + "abcdefghijklmnopqrstuvwxyz") + { + // ensure this string does + // not fit in the SBO area. + BOOST_ASSERT(str_.size() > + string().capacity()); + } + + //------------------------------------------------------ + + void + testSpecial() + { + auto dsp = storage_ptr{}; + auto sp = make_shared_resource<unique_resource>(); + + // ~value() + { + value(object{}); + value(array{}); + value(string{}); + value(std::int64_t(0)); + value(std::uint64_t(0)); + value(double(0)); + value(true); + value(nullptr); + } + + // value() + { + value jv; + BOOST_TEST(*jv.storage() == *dsp); + } + + // value(storage_ptr) + { + value jv(sp); + BOOST_TEST(*jv.storage() == *sp); + } + + // value(pilfered<value>) + { + { + value jv1(object{}); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_object()); + } + { + value jv1(array{}); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_array()); + } + { + value jv1(string{}); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_string()); + } + { + value jv1(std::int64_t{}); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_int64()); + } + { + value jv1(std::uint64_t{}); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_uint64()); + } + { + value jv1(double{}); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_double()); + } + { + value jv1(true); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_bool()); + } + { + value jv1(nullptr); + value jv2(pilfer(jv1)); + BOOST_TEST(jv2.is_null()); + } + + // ensure pilfered-from objects + // are trivially destructible + { + value v1(make_shared_resource< + monotonic_resource>()); + value v2(pilfer(v1)); + BOOST_TEST(v1.storage().get() == + storage_ptr().get()); + } + } + + // value(value const&) + { + { + value jv1(object{}); + value jv2(jv1); + BOOST_TEST(jv2.is_object()); + } + { + value jv1(array{}); + value jv2(jv1); + BOOST_TEST(jv2.is_array()); + } + { + value jv1(string{}); + value jv2(jv1); + BOOST_TEST(jv2.is_string()); + } + { + value jv1(std::int64_t{}); + value jv2(jv1); + BOOST_TEST(jv2.is_int64()); + } + { + value jv1(std::uint64_t{}); + value jv2(jv1); + BOOST_TEST(jv2.is_uint64()); + } + { + value jv1(double{}); + value jv2(jv1); + BOOST_TEST(jv2.is_double()); + } + { + value jv1(true); + value jv2(jv1); + BOOST_TEST(jv2.is_bool()); + } + { + value jv1(nullptr); + value jv2(jv1); + BOOST_TEST(jv2.is_null()); + } + } + + // value(value const&, storage_ptr) + { + { + value jv1(object{}); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_object()); + BOOST_TEST(*jv2.storage() == *sp); + } + { + value jv1(array{}); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_array()); + BOOST_TEST(*jv2.storage() == *sp); + } + { + value jv1(string{}); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_string()); + BOOST_TEST(*jv2.storage() == *sp); + } + { + value jv1(std::int64_t{}); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_int64()); + BOOST_TEST(*jv2.storage() == *sp); + } + { + value jv1(std::uint64_t{}); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_uint64()); + BOOST_TEST(*jv2.storage() == *sp); + } + { + value jv1(double{}); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_double()); + BOOST_TEST(*jv2.storage() == *sp); + } + { + value jv1(true); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_bool()); + BOOST_TEST(*jv2.storage() == *sp); + } + { + value jv1(nullptr); + value jv2(jv1, sp); + BOOST_TEST(jv2.is_null()); + BOOST_TEST(*jv2.storage() == *sp); + } + } + + // value(value&&) + { + { + value jv1(object{}); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_object()); + } + { + value jv1(array{}); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_array()); + } + { + value jv1(string{}); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_string()); + } + { + value jv1(std::int64_t{}); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_int64()); + } + { + value jv1(std::uint64_t{}); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_uint64()); + } + { + value jv1(double{}); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_double()); + } + { + value jv1(true); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_bool()); + } + { + value jv1(nullptr); + value jv2(std::move(jv1)); + BOOST_TEST(jv2.is_null()); + } + } + + // value(value&&, storage_ptr) + { + { + value jv1(object{}); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_object()); + } + { + value jv1(array{}); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_array()); + } + { + value jv1(string{}); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_string()); + } + { + value jv1(std::int64_t{}); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_int64()); + } + { + value jv1(std::uint64_t{}); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_uint64()); + } + { + value jv1(double{}); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_double()); + } + { + value jv1(true); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_bool()); + } + { + value jv1(nullptr); + value jv2(std::move(jv1), sp); + BOOST_TEST(jv2.is_null()); + } + } + } + + void + testConversion() + { + auto dsp = storage_ptr{}; + auto sp = make_shared_resource<unique_resource>(); + + // value(object) + // value(object, storage_ptr) + // value(object_kind, storage_ptr) + { + { + auto jv = value(object()); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(object(sp)); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *sp); + } + { + auto jv = value(object(), sp); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *sp); + } + { + auto jv = value(object_kind); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(object_kind, sp); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *sp); + } + { + // verify moved from + object obj{{"a", 1}, {"b", 2}}; + BOOST_TEST(obj.capacity() > 0); + value jv(std::move(obj), {}); + BOOST_TEST(obj.capacity() == 0); + } + } + + // value(array) + // value(array, storage_ptr) + // value(object_kind, storage_ptr) + { + { + auto jv = value(array()); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(array(sp)); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *sp); + } + { + auto jv = value(array(), sp); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *sp); + } + { + auto jv = value(array_kind); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(array_kind, sp); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // value(string) + // value(string, storage_ptr) + { + { + auto jv = value(string()); + BOOST_TEST(jv.is_string()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(string(sp)); + BOOST_TEST(jv.is_string()); + BOOST_TEST(*jv.storage() == *sp); + } + { + auto jv = value(string(), sp); + BOOST_TEST(jv.is_string()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // value(int64) + // value(int64, storage_ptr) + { + { + auto jv = value(std::int64_t{-65536}); + BOOST_TEST(jv.is_int64()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(std::int64_t{-65536}, sp); + BOOST_TEST(jv.is_int64()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // value(uint64) + // value(uint64, storage_ptr) + { + { + auto jv = value(std::uint64_t{65536}); + BOOST_TEST(jv.is_uint64()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(std::uint64_t{65536}, sp); + BOOST_TEST(jv.is_uint64()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // value(double) + // value(double, storage_ptr) + { + { + auto jv = value(double{3.141}); + BOOST_TEST(jv.is_double()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(double{3.141}, sp); + BOOST_TEST(jv.is_double()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // value(bool) + // value(bool, storage_ptr) + { + { + auto jv = value(true); + BOOST_TEST(jv.is_bool()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(true, sp); + BOOST_TEST(jv.is_bool()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // value(nullptr_t) + // value(nullptr_t, storage_ptr) + { + { + auto jv = value(nullptr); + BOOST_TEST(jv.is_null()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + auto jv = value(nullptr, sp); + BOOST_TEST(jv.is_null()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // value(initializer_list) + // value(initializer_list, storage_ptr) + { + { + value jv({1, 2, 3}); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + value jv({1, 2, 3}, sp); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *sp); + } + { + value jv({{"a",1},{"b",2},{"c",3}}); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + value jv({{"a",1},{"b",2},{"c",3}}, sp); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *sp); + } + } + } + + void + testAssignment() + { + auto dsp = storage_ptr{}; + auto sp = make_shared_resource<unique_resource>(); + + // operator=(value const&) + { + { + value jv1(object{}); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_object()); + } + { + value jv1(array{}); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_array()); + } + { + value jv1(string{}); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_string()); + } + { + value jv1(std::int64_t{}); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_int64()); + } + { + value jv1(std::uint64_t{}); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_uint64()); + } + { + value jv1(double{}); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_double()); + } + { + value jv1(true); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_bool()); + } + { + value jv1(nullptr); + value jv2; + jv2 = jv1; + BOOST_TEST(jv2.is_null()); + } + + fail_loop([&](storage_ptr const sp) + { + value jv1({1, 2, 3, 4, 5}); + value jv2(sp); + jv2 = jv1; + BOOST_TEST(jv2.as_array().size() == 5); + }); + + fail_loop([&](storage_ptr const sp) + { + value jv1({ + {"a",1},{"b",2},{"c",3}}); + value jv2(sp); + jv2 = jv1; + BOOST_TEST(jv2.as_object().size() == 3); + }); + + fail_loop([&](storage_ptr const sp) + { + value jv1(str_); + value jv2(sp); + jv2 = jv1; + BOOST_TEST(jv2.as_string() == str_); + }); + + // self-assign + { + value jv = { 1, 2, 3 }; + jv = static_cast<value const&>(jv); + BOOST_TEST(jv == value({1, 2, 3})); + } + + // copy from child + { + value jv = { 1, 2, 3 }; + jv = jv.at(1); + BOOST_TEST( + *jv.if_int64() == 2); + } + } + + // operator=(value&&) + { + { + value jv; + jv = value(object{}); + BOOST_TEST(jv.is_object()); + } + { + value jv; + jv = value(array{}); + BOOST_TEST(jv.is_array()); + } + { + value jv; + jv = value(string{}); + BOOST_TEST(jv.is_string()); + } + { + value jv; + jv = value(std::int64_t{}); + BOOST_TEST(jv.is_int64()); + } + { + value jv; + jv = value(std::uint64_t{}); + BOOST_TEST(jv.is_uint64()); + } + { + value jv; + jv = value(double{}); + BOOST_TEST(jv.is_double()); + } + { + value jv; + jv = value(true); + BOOST_TEST(jv.is_bool()); + } + { + value jv; + jv = value(nullptr); + BOOST_TEST(jv.is_null()); + } + + fail_loop([&](storage_ptr const sp) + { + value jv(sp); + jv = value({ + { {"a",1}, {"b",2u} }, + { 1, 2 }, + "hello", + 1, + 2u, + 3., + true, + nullptr + }); + BOOST_TEST(jv.as_array().size() == 8); + }); + + fail_loop([&](storage_ptr const sp) + { + value jv(sp); + jv = value({ + { "aa", { {"a",1}, {"b",2u} } }, + { "bb", { 1, 2 } }, + { "cc", "hello" }, + { "dd", 1 }, + { "ee", 2u }, + { "ff", 3. }, + { "gg", true }, + { "hh", nullptr }, + }); + BOOST_TEST(jv.as_object().size() == 8); + }); + + fail_loop([&](storage_ptr const sp) + { + value jv(sp); + jv = value(str_); + BOOST_TEST(jv.as_string() == str_); + }); + + // self-move + { + value jv = { 1, 2, 3 }; + value* p = &jv; + jv = std::move(*p); + BOOST_TEST(jv == value({1, 2, 3})); + } + + // move from child + { + value jv = { 1, 2, 3 }; + jv = std::move(jv.at(1)); + BOOST_TEST( + *jv.if_int64() == 2); + } + } + + // operator=(initializer_list) + { + value jv; + jv = {1, 2, 3}; + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *dsp); + BOOST_TEST(jv.at(0).as_int64() == 1); + BOOST_TEST(jv.at(1).as_int64() == 2); + BOOST_TEST(jv.at(2).as_int64() == 3); + } + + // operator=(nullptr_t) + { + { + value jv = 1; + BOOST_TEST(! jv.is_null()); + jv = nullptr; + BOOST_TEST(jv.is_null()); + } + { + value jv = "string"; + BOOST_TEST(! jv.is_null()); + jv = nullptr; + BOOST_TEST(jv.is_null()); + } + } + + // operator=(bool) + { + { + value jv = 1; + BOOST_TEST(! jv.is_bool()); + jv = true; + BOOST_TEST(jv.is_bool()); + } + { + value jv = "string"; + BOOST_TEST(! jv.is_bool()); + jv = true; + BOOST_TEST(jv.is_bool()); + } + } + + // operator=(int64) + { + { + value jv = false; + BOOST_TEST(! jv.is_int64()); + jv = std::int64_t{-65536}; + BOOST_TEST(jv.is_int64()); + } + { + value jv = "string"; + BOOST_TEST(! jv.is_int64()); + jv = std::int64_t{-65536}; + BOOST_TEST(jv.is_int64()); + } + } + + // operator=(uint64) + { + { + value jv = false; + BOOST_TEST(! jv.is_uint64()); + jv = std::uint64_t{65536}; + BOOST_TEST(jv.is_uint64()); + } + { + value jv = "string"; + BOOST_TEST(! jv.is_uint64()); + jv = std::uint64_t{65536}; + BOOST_TEST(jv.is_uint64()); + } + } + + // operator=(double) + { + { + value jv = false; + BOOST_TEST(! jv.is_double()); + jv = double{3.141}; + BOOST_TEST(jv.is_double()); + } + { + value jv = "string"; + BOOST_TEST(! jv.is_double()); + jv = double{3.141}; + BOOST_TEST(jv.is_double()); + } + } + + // operator=(string) + { + { + value jv; + jv = string(); + BOOST_TEST(jv.is_string()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + value jv(sp); + jv = string(); + BOOST_TEST(jv.is_string()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // operator=(array) + { + { + value jv; + jv = array(); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *dsp); + } + { + value jv(sp); + jv = array(); + BOOST_TEST(jv.is_array()); + BOOST_TEST(*jv.storage() == *sp); + } + } + + // operator=(object) + { + { + value jv; + jv = object(); + BOOST_TEST(*jv.storage() == *dsp); + BOOST_TEST(jv.is_object()); + } + { + value jv(sp); + jv = object(); + BOOST_TEST(jv.is_object()); + BOOST_TEST(*jv.storage() == *sp); + } + } + } + + void + testModifiers() + { + // emplace + { + BOOST_TEST(value().emplace_object().empty()); + BOOST_TEST(value().emplace_array().empty()); + BOOST_TEST(value().emplace_string().empty()); + BOOST_TEST(value().emplace_int64() == 0); + BOOST_TEST(value().emplace_uint64() == 0); + BOOST_TEST(value().emplace_double() == 0); + BOOST_TEST(value().emplace_bool() = true); + { + value jv(object_kind); + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + { + value jv(array_kind); + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + { + value jv(string_kind); + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + { + value jv(-1); + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + { + value jv(1U); + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + { + value jv(1.0); + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + { + value jv(false); + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + { + value jv; + jv.emplace_null(); + BOOST_TEST(jv.is_null()); + } + } + + // swap + { + { + // self-swap + value jv; + swap(jv, jv); + } + { + value jv1(1); + value jv2("abc"); + BOOST_TEST( + *jv1.storage() == *jv2.storage()); + swap(jv1, jv2); + BOOST_TEST(jv1.as_string() == "abc"); + BOOST_TEST(jv2.as_int64() == 1); + } + + // different storage + fail_loop([&](storage_ptr const& sp) + { + value jv1(1); + value jv2("abc", sp); + BOOST_TEST( + *jv1.storage() != *jv2.storage()); + swap(jv1, jv2); + BOOST_TEST(jv1.as_string() == "abc"); + BOOST_TEST(jv2.as_int64() == 1); + }); + } + } + + template<typename T> + using tt = T; + + void + testExchange() + { + // string{} + { + BOOST_TEST(value("abc").is_string()); + BOOST_TEST(value(std::string()).is_string()); + BOOST_TEST(value(string_view()).is_string()); + + { value jv; BOOST_TEST((jv = "abc").is_string()); } + { value jv; BOOST_TEST((jv = std::string()).is_string()); } + { value jv; BOOST_TEST((jv = string_view()).is_string()); } + } + + // numbers + { + BOOST_TEST(value(tt<signed char>{}).is_int64()); + BOOST_TEST(value(tt<short>{}).is_int64()); + BOOST_TEST(value(tt<int>{}).is_int64()); + BOOST_TEST(value(tt<long>{}).is_int64()); + BOOST_TEST(value(tt<long long>{}).is_int64()); + BOOST_TEST(value(tt<unsigned char>{}).is_uint64()); + BOOST_TEST(value(tt<unsigned short>{}).is_uint64()); + BOOST_TEST(value(tt<unsigned int>{}).is_uint64()); + BOOST_TEST(value(tt<unsigned long>{}).is_uint64()); + BOOST_TEST(value(tt<unsigned long long>{}).is_uint64()); + BOOST_TEST(value(tt<float>{}).is_double()); + BOOST_TEST(value(tt<double>{}).is_double()); + + { value jv; BOOST_TEST((jv = tt<signed char>{}).is_int64()); } + { value jv; BOOST_TEST((jv = tt<short>{}).is_int64()); } + { value jv; BOOST_TEST((jv = tt<int>{}).is_int64()); } + { value jv; BOOST_TEST((jv = tt<long>{}).is_int64()); } + { value jv; BOOST_TEST((jv = tt<long long>{}).is_int64()); } + { value jv; BOOST_TEST((jv = tt<unsigned char>{}).is_uint64()); } + { value jv; BOOST_TEST((jv = tt<unsigned short>{}).is_uint64()); } + { value jv; BOOST_TEST((jv = tt<unsigned int>{}).is_uint64()); } + { value jv; BOOST_TEST((jv = tt<unsigned long>{}).is_uint64()); } + { value jv; BOOST_TEST((jv = tt<unsigned long long>{}).is_uint64()); } + { value jv; BOOST_TEST((jv = tt<float>{}).is_double()); } + { value jv; BOOST_TEST((jv = tt<double>{}).is_double()); } + } + + // bool + { + BOOST_TEST(value(true).is_bool()); + BOOST_TEST(value(false).is_bool()); + + { value jv; BOOST_TEST((jv = true).is_bool()); } + { value jv; BOOST_TEST((jv = false).is_bool()); } + } + + // nullptr + { + BOOST_TEST(value(nullptr).is_null()); + + { value jv("x"); BOOST_TEST((jv = nullptr).is_null()); } + } + + // VFALCO TODO store() + } + + void + testObservers() + { + value const obj(object{}); + value const arr(array{}); + value const str(string{}); + value const i64(std::int64_t{}); + value const u64(std::uint64_t{}); + value const dub(double{}); + value const boo(true); + value const nul(nullptr); + + // kind() + { + BOOST_TEST(obj.kind() == kind::object); + BOOST_TEST(arr.kind() == kind::array); + BOOST_TEST(str.kind() == kind::string); + BOOST_TEST(i64.kind() == kind::int64); + BOOST_TEST(u64.kind() == kind::uint64); + BOOST_TEST(dub.kind() == kind::double_); + BOOST_TEST(boo.kind() == kind::bool_); + BOOST_TEST(nul.kind() == kind::null); + } + + // is_object() + { + BOOST_TEST( obj.is_object()); + BOOST_TEST(! arr.is_object()); + BOOST_TEST(! str.is_object()); + BOOST_TEST(! i64.is_object()); + BOOST_TEST(! u64.is_object()); + BOOST_TEST(! dub.is_object()); + BOOST_TEST(! boo.is_object()); + BOOST_TEST(! nul.is_object()); + } + + // is_array() + { + BOOST_TEST(! obj.is_array()); + BOOST_TEST( arr.is_array()); + BOOST_TEST(! str.is_array()); + BOOST_TEST(! i64.is_array()); + BOOST_TEST(! u64.is_array()); + BOOST_TEST(! dub.is_array()); + BOOST_TEST(! boo.is_array()); + BOOST_TEST(! nul.is_array()); + } + + // is_string() + { + BOOST_TEST(! obj.is_string()); + BOOST_TEST(! arr.is_string()); + BOOST_TEST( str.is_string()); + BOOST_TEST(! i64.is_string()); + BOOST_TEST(! u64.is_string()); + BOOST_TEST(! dub.is_string()); + BOOST_TEST(! boo.is_string()); + BOOST_TEST(! nul.is_string()); + } + + // is_int64() + { + BOOST_TEST(! obj.is_int64()); + BOOST_TEST(! arr.is_int64()); + BOOST_TEST(! str.is_int64()); + BOOST_TEST( i64.is_int64()); + BOOST_TEST(! u64.is_int64()); + BOOST_TEST(! dub.is_int64()); + BOOST_TEST(! boo.is_int64()); + BOOST_TEST(! nul.is_int64()); + } + + // is_uint64() + { + BOOST_TEST(! obj.is_uint64()); + BOOST_TEST(! arr.is_uint64()); + BOOST_TEST(! str.is_uint64()); + BOOST_TEST(! i64.is_uint64()); + BOOST_TEST( u64.is_uint64()); + BOOST_TEST(! dub.is_uint64()); + BOOST_TEST(! boo.is_uint64()); + BOOST_TEST(! nul.is_uint64()); + } + + // is_double() + { + BOOST_TEST(! obj.is_double()); + BOOST_TEST(! arr.is_double()); + BOOST_TEST(! str.is_double()); + BOOST_TEST(! i64.is_double()); + BOOST_TEST(! u64.is_double()); + BOOST_TEST( dub.is_double()); + BOOST_TEST(! boo.is_double()); + BOOST_TEST(! nul.is_double()); + } + + // is_bool() + { + BOOST_TEST(! obj.is_bool()); + BOOST_TEST(! arr.is_bool()); + BOOST_TEST(! str.is_bool()); + BOOST_TEST(! i64.is_bool()); + BOOST_TEST(! u64.is_bool()); + BOOST_TEST(! dub.is_bool()); + BOOST_TEST( boo.is_bool()); + BOOST_TEST(! nul.is_bool()); + } + + // is_null() + { + BOOST_TEST(! obj.is_null()); + BOOST_TEST(! arr.is_null()); + BOOST_TEST(! str.is_null()); + BOOST_TEST(! i64.is_null()); + BOOST_TEST(! u64.is_null()); + BOOST_TEST(! dub.is_null()); + BOOST_TEST(! boo.is_null()); + BOOST_TEST( nul.is_null()); + } + + // is_number() + { + BOOST_TEST(! obj.is_number()); + BOOST_TEST(! arr.is_number()); + BOOST_TEST(! str.is_number()); + BOOST_TEST( i64.is_number()); + BOOST_TEST( u64.is_number()); + BOOST_TEST( dub.is_number()); + BOOST_TEST(! boo.is_number()); + BOOST_TEST(! nul.is_number()); + } + + // is_primitive() + { + BOOST_TEST(! obj.is_primitive()); + BOOST_TEST(! arr.is_primitive()); + BOOST_TEST( str.is_primitive()); + BOOST_TEST( i64.is_primitive()); + BOOST_TEST( u64.is_primitive()); + BOOST_TEST( dub.is_primitive()); + BOOST_TEST( boo.is_primitive()); + BOOST_TEST( nul.is_primitive()); + } + + // is_structured() + { + BOOST_TEST( obj.is_structured()); + BOOST_TEST( arr.is_structured()); + BOOST_TEST(! str.is_structured()); + BOOST_TEST(! i64.is_structured()); + BOOST_TEST(! u64.is_structured()); + BOOST_TEST(! dub.is_structured()); + BOOST_TEST(! boo.is_structured()); + BOOST_TEST(! nul.is_structured()); + } + } + + //------------------------------------------------------ + // + // Accessors + // + //------------------------------------------------------ + + void + testGetStorage() + { + auto const sp = + make_shared_resource<unique_resource>(); + + value obj(object{}, sp); + value arr(array{}, sp); + value str(string{}, sp); + value i64(std::int64_t{}, sp); + value u64(std::uint64_t{}, sp); + value dub(double{}, sp); + value boo(true, sp); + value nul(nullptr, sp); + + // storage() + { + BOOST_TEST(*obj.storage() == *sp); + BOOST_TEST(*arr.storage() == *sp); + BOOST_TEST(*str.storage() == *sp); + BOOST_TEST(*i64.storage() == *sp); + BOOST_TEST(*u64.storage() == *sp); + BOOST_TEST(*dub.storage() == *sp); + BOOST_TEST(*boo.storage() == *sp); + BOOST_TEST(*nul.storage() == *sp); + } + } + + void + testIf() + { + value obj(object{}); + value arr(array{}); + value str(string{}); + value i64(std::int64_t{}); + value u64(std::uint64_t{}); + value dub(double{}); + value boo(true); + value nul(nullptr); + + auto const& cobj(obj); + auto const& carr(arr); + auto const& cstr(str); + auto const& ci64(i64); + auto const& cu64(u64); + auto const& cdub(dub); + auto const& cboo(boo); + auto const& cnul(nul); + + // if_object() + { + BOOST_TEST(obj.if_object() != nullptr); + BOOST_TEST(arr.if_object() == nullptr); + BOOST_TEST(str.if_object() == nullptr); + BOOST_TEST(i64.if_object() == nullptr); + BOOST_TEST(u64.if_object() == nullptr); + BOOST_TEST(dub.if_object() == nullptr); + BOOST_TEST(boo.if_object() == nullptr); + BOOST_TEST(nul.if_object() == nullptr); + } + + // if_object() const + { + BOOST_TEST(cobj.if_object() != nullptr); + BOOST_TEST(carr.if_object() == nullptr); + BOOST_TEST(cstr.if_object() == nullptr); + BOOST_TEST(ci64.if_object() == nullptr); + BOOST_TEST(cu64.if_object() == nullptr); + BOOST_TEST(cdub.if_object() == nullptr); + BOOST_TEST(cboo.if_object() == nullptr); + BOOST_TEST(cnul.if_object() == nullptr); + } + + // if_array() + { + BOOST_TEST(obj.if_array() == nullptr); + BOOST_TEST(arr.if_array() != nullptr); + BOOST_TEST(str.if_array() == nullptr); + BOOST_TEST(i64.if_array() == nullptr); + BOOST_TEST(u64.if_array() == nullptr); + BOOST_TEST(dub.if_array() == nullptr); + BOOST_TEST(boo.if_array() == nullptr); + BOOST_TEST(nul.if_array() == nullptr); + } + + // if_array() const + { + BOOST_TEST(cobj.if_array() == nullptr); + BOOST_TEST(carr.if_array() != nullptr); + BOOST_TEST(cstr.if_array() == nullptr); + BOOST_TEST(ci64.if_array() == nullptr); + BOOST_TEST(cu64.if_array() == nullptr); + BOOST_TEST(cdub.if_array() == nullptr); + BOOST_TEST(cboo.if_array() == nullptr); + BOOST_TEST(cnul.if_array() == nullptr); + } + + // if_string() + { + BOOST_TEST(obj.if_string() == nullptr); + BOOST_TEST(arr.if_string() == nullptr); + BOOST_TEST(str.if_string() != nullptr); + BOOST_TEST(i64.if_string() == nullptr); + BOOST_TEST(u64.if_string() == nullptr); + BOOST_TEST(dub.if_string() == nullptr); + BOOST_TEST(boo.if_string() == nullptr); + BOOST_TEST(nul.if_string() == nullptr); + } + + // if_string() const + { + BOOST_TEST(cobj.if_string() == nullptr); + BOOST_TEST(carr.if_string() == nullptr); + BOOST_TEST(cstr.if_string() != nullptr); + BOOST_TEST(ci64.if_string() == nullptr); + BOOST_TEST(cu64.if_string() == nullptr); + BOOST_TEST(cdub.if_string() == nullptr); + BOOST_TEST(cboo.if_string() == nullptr); + BOOST_TEST(cnul.if_string() == nullptr); + } + + // if_int64() + { + BOOST_TEST(obj.if_int64() == nullptr); + BOOST_TEST(arr.if_int64() == nullptr); + BOOST_TEST(str.if_int64() == nullptr); + BOOST_TEST(i64.if_int64() != nullptr); + BOOST_TEST(u64.if_int64() == nullptr); + BOOST_TEST(dub.if_int64() == nullptr); + BOOST_TEST(boo.if_int64() == nullptr); + BOOST_TEST(nul.if_int64() == nullptr); + } + + // if_int64() const + { + BOOST_TEST(cobj.if_int64() == nullptr); + BOOST_TEST(carr.if_int64() == nullptr); + BOOST_TEST(cstr.if_int64() == nullptr); + BOOST_TEST(ci64.if_int64() != nullptr); + BOOST_TEST(cu64.if_int64() == nullptr); + BOOST_TEST(cdub.if_int64() == nullptr); + BOOST_TEST(cboo.if_int64() == nullptr); + BOOST_TEST(cnul.if_int64() == nullptr); + } + + // if_uint64() + { + BOOST_TEST(obj.if_uint64() == nullptr); + BOOST_TEST(arr.if_uint64() == nullptr); + BOOST_TEST(str.if_uint64() == nullptr); + BOOST_TEST(i64.if_uint64() == nullptr); + BOOST_TEST(u64.if_uint64() != nullptr); + BOOST_TEST(dub.if_uint64() == nullptr); + BOOST_TEST(boo.if_uint64() == nullptr); + BOOST_TEST(nul.if_uint64() == nullptr); + } + + // if_uint64() const + { + BOOST_TEST(cobj.if_uint64() == nullptr); + BOOST_TEST(carr.if_uint64() == nullptr); + BOOST_TEST(cstr.if_uint64() == nullptr); + BOOST_TEST(ci64.if_uint64() == nullptr); + BOOST_TEST(cu64.if_uint64() != nullptr); + BOOST_TEST(cdub.if_uint64() == nullptr); + BOOST_TEST(cboo.if_uint64() == nullptr); + BOOST_TEST(cnul.if_uint64() == nullptr); + } + + // if_double() + { + BOOST_TEST(obj.if_double() == nullptr); + BOOST_TEST(arr.if_double() == nullptr); + BOOST_TEST(str.if_double() == nullptr); + BOOST_TEST(i64.if_double() == nullptr); + BOOST_TEST(u64.if_double() == nullptr); + BOOST_TEST(dub.if_double() != nullptr); + BOOST_TEST(boo.if_double() == nullptr); + BOOST_TEST(nul.if_double() == nullptr); + } + + // if_double() const + { + BOOST_TEST(cobj.if_double() == nullptr); + BOOST_TEST(carr.if_double() == nullptr); + BOOST_TEST(cstr.if_double() == nullptr); + BOOST_TEST(ci64.if_double() == nullptr); + BOOST_TEST(cu64.if_double() == nullptr); + BOOST_TEST(cdub.if_double() != nullptr); + BOOST_TEST(cboo.if_double() == nullptr); + BOOST_TEST(cnul.if_double() == nullptr); + } + + // if_bool() + { + BOOST_TEST(obj.if_bool() == nullptr); + BOOST_TEST(arr.if_bool() == nullptr); + BOOST_TEST(str.if_bool() == nullptr); + BOOST_TEST(i64.if_bool() == nullptr); + BOOST_TEST(u64.if_bool() == nullptr); + BOOST_TEST(dub.if_bool() == nullptr); + BOOST_TEST(boo.if_bool() != nullptr); + BOOST_TEST(nul.if_bool() == nullptr); + } + + // if_bool() const + { + BOOST_TEST(cobj.if_bool() == nullptr); + BOOST_TEST(carr.if_bool() == nullptr); + BOOST_TEST(cstr.if_bool() == nullptr); + BOOST_TEST(ci64.if_bool() == nullptr); + BOOST_TEST(cu64.if_bool() == nullptr); + BOOST_TEST(cdub.if_bool() == nullptr); + BOOST_TEST(cboo.if_bool() != nullptr); + BOOST_TEST(cnul.if_bool() == nullptr); + } + } + + void + testToNumber() + { +#define EQAL(T) BOOST_TEST(jv.to_number<T>() == V) +#define EQUS(T) BOOST_TEST((V >= 0) && jv.to_number<T>() == static_cast<std::uint64_t>(V)) +#define EQUF(T) BOOST_TEST(static_cast<float>(V) == static_cast<float>(jv.to_number<T>())) +#define THRO(T) BOOST_TEST_THROWS_WITH_LOCATION(jv.to_number<T>()); + + BOOST_TEST_THROWS_WITH_LOCATION(value(nullptr).to_number<int>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(false).to_number<int>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(string_kind).to_number<int>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(array_kind).to_number<int>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(object_kind).to_number<int>()); + + BOOST_TEST_THROWS_WITH_LOCATION(value(nullptr).to_number<unsigned>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(false).to_number<unsigned>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(string_kind).to_number<unsigned>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(array_kind).to_number<unsigned>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(object_kind).to_number<unsigned>()); + + BOOST_TEST_THROWS_WITH_LOCATION(value(nullptr).to_number<double>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(false).to_number<double>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(string_kind).to_number<double>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(array_kind).to_number<double>()); + BOOST_TEST_THROWS_WITH_LOCATION(value(object_kind).to_number<double>()); + + { + unsigned char V = 0; + value const jv(V); + EQAL(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + EQAL(std::uint8_t); + EQAL(std::uint16_t); + EQAL(std::uint32_t); + EQAL(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = max_of<std::int8_t>(); + value const jv(V); + EQAL(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + EQAL(std::uint8_t); + EQAL(std::uint16_t); + EQUS(std::uint32_t); + EQUS(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = max_of<std::int16_t>(); + value const jv(V); + THRO(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + EQAL(std::uint16_t); + EQUS(std::uint32_t); + EQUS(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = max_of<std::int32_t>(); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + EQUS(std::uint32_t); + EQUS(std::uint64_t); + EQUF(float); + EQAL(double); + } + { + auto V = max_of<std::int64_t>(); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + THRO(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + EQUS(std::uint64_t); + EQUF(float); + EQUF(double); + } + //--- + { + auto V = max_of<std::uint8_t>(); + value const jv(V); + THRO(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + EQAL(std::uint8_t); + EQAL(std::uint16_t); + EQAL(std::uint32_t); + EQAL(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = max_of<std::uint16_t>(); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + EQAL(std::uint16_t); + EQAL(std::uint32_t); + EQAL(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = max_of<std::uint32_t>(); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + THRO(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + EQAL(std::uint32_t); + EQAL(std::uint64_t); + EQUF(float); + EQAL(double); + } + { + auto V = max_of<std::uint64_t>(); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + THRO(std::int32_t); + THRO(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + EQAL(std::uint64_t); + EQUF(float); + EQUF(double); + } + //--- + { + auto V = min_of<std::int8_t>(); + value const jv(V); + EQAL(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + THRO(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = min_of<std::int16_t>(); + value const jv(V); + THRO(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + THRO(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = min_of<std::int32_t>(); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + THRO(std::uint64_t); + EQUF(float); + EQAL(double); + } + { + auto V = min_of<std::int64_t>(); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + THRO(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + THRO(std::uint64_t); + EQUF(float); + EQUF(double); + } + //--- + { + auto V = double(1.5); + value const jv(V); + THRO(std::int8_t); + THRO(std::int16_t); + THRO(std::int32_t); + THRO(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + THRO(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = double(2.0); + value const jv(V); + EQAL(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + EQAL(std::uint8_t); + EQAL(std::uint16_t); + EQAL(std::uint32_t); + EQAL(std::uint64_t); + EQAL(float); + EQAL(double); + } + { + auto V = double(-4.0); + value const jv(V); + EQAL(std::int8_t); + EQAL(std::int16_t); + EQAL(std::int32_t); + EQAL(std::int64_t); + THRO(std::uint8_t); + THRO(std::uint16_t); + THRO(std::uint32_t); + THRO(std::uint64_t); + EQAL(float); + EQAL(double); + } + + { + error_code ec; + value(nullptr).to_number<double>(ec); + BOOST_TEST(ec == error::not_number); + BOOST_TEST(ec.has_location()); + } + + { + std::error_code ec; + value(nullptr).to_number<double>(ec); + BOOST_TEST(error::not_number == ec); + } + } + + void + testAs() + { + value obj(object{}); + value arr(array{}); + value str(string{}); + value i64(std::int64_t{}); + value u64(std::uint64_t{}); + value dub(double{}); + value boo(true); + value nul(nullptr); + + auto const& cobj(obj); + auto const& carr(arr); + auto const& cstr(str); + auto const& ci64(i64); + auto const& cu64(u64); + auto const& cdub(dub); + auto const& cboo(boo); + auto const& cnul(nul); + + // as_object() + { + object& x = obj.as_object(); + BOOST_TEST_THROWS(arr.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(str.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(i64.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(u64.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(dub.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(boo.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(nul.as_object(), std::invalid_argument); + (void)x; + } + + // as_object() const + { + object const& x = cobj.as_object(); + BOOST_TEST_THROWS(carr.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(cstr.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(ci64.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(cu64.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(cdub.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(cboo.as_object(), std::invalid_argument); + BOOST_TEST_THROWS(cnul.as_object(), std::invalid_argument); + (void)x; + } + + // as_array() + { + BOOST_TEST_THROWS(obj.as_array(), std::invalid_argument); + array& x = arr.as_array(); + BOOST_TEST_THROWS(str.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(i64.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(u64.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(dub.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(boo.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(nul.as_array(), std::invalid_argument); + (void)x; + } + + // as_array() const + { + BOOST_TEST_THROWS(cobj.as_array(), std::invalid_argument); + array const& x = carr.as_array(); + BOOST_TEST_THROWS(cstr.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(ci64.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(cu64.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(cdub.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(cboo.as_array(), std::invalid_argument); + BOOST_TEST_THROWS(cnul.as_array(), std::invalid_argument); + (void)x; + } + + // as_string() + { + BOOST_TEST_THROWS(obj.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(arr.as_string(), std::invalid_argument); + string& x = str.as_string(); + BOOST_TEST_THROWS(i64.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(u64.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(dub.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(boo.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(nul.as_string(), std::invalid_argument); + (void)x; + } + + // as_string() const + { + BOOST_TEST_THROWS(cobj.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(carr.as_string(), std::invalid_argument); + string const& x = cstr.as_string(); + BOOST_TEST_THROWS(ci64.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(cu64.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(cdub.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(cboo.as_string(), std::invalid_argument); + BOOST_TEST_THROWS(cnul.as_string(), std::invalid_argument); + (void)x; + } + + // as_int64() + { + BOOST_TEST_THROWS(obj.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(arr.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(str.as_int64(), std::invalid_argument); + std::int64_t& x = i64.as_int64(); + BOOST_TEST_THROWS(u64.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(dub.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(boo.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(nul.as_int64(), std::invalid_argument); + (void)x; + } + + // as_int64() const + { + BOOST_TEST_THROWS(cobj.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(carr.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(cstr.as_int64(), std::invalid_argument); + std::int64_t const& x = ci64.as_int64(); + BOOST_TEST_THROWS(cu64.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(cdub.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(cboo.as_int64(), std::invalid_argument); + BOOST_TEST_THROWS(cnul.as_int64(), std::invalid_argument); + (void)x; + } + + // as_uint64() + { + BOOST_TEST_THROWS(obj.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(arr.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(str.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(i64.as_uint64(), std::invalid_argument); + std::uint64_t& x = u64.as_uint64(); + BOOST_TEST_THROWS(dub.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(boo.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(nul.as_uint64(), std::invalid_argument); + (void)x; + } + + // as_uint64() const + { + BOOST_TEST_THROWS(cobj.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(carr.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(cstr.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(ci64.as_uint64(), std::invalid_argument); + std::uint64_t const& x = cu64.as_uint64(); + BOOST_TEST_THROWS(cdub.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(cboo.as_uint64(), std::invalid_argument); + BOOST_TEST_THROWS(cnul.as_uint64(), std::invalid_argument); + (void)x; + } + + // as_double() + { + BOOST_TEST_THROWS(obj.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(arr.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(str.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(i64.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(u64.as_double(), std::invalid_argument); + double& x = dub.as_double(); + BOOST_TEST_THROWS(boo.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(nul.as_double(), std::invalid_argument); + (void)x; + } + + // as_double() const + { + BOOST_TEST_THROWS(cobj.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(carr.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(cstr.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(ci64.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(cu64.as_double(), std::invalid_argument); + double const& x = cdub.as_double(); + BOOST_TEST_THROWS(cboo.as_double(), std::invalid_argument); + BOOST_TEST_THROWS(cnul.as_double(), std::invalid_argument); + (void)x; + } + + // as_bool() + { + BOOST_TEST_THROWS(obj.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(arr.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(str.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(i64.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(u64.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(dub.as_bool(), std::invalid_argument); + bool& x = boo.as_bool(); + BOOST_TEST_THROWS(nul.as_bool(), std::invalid_argument); + (void)x; + } + + // as_bool() const + { + BOOST_TEST_THROWS(cobj.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(carr.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(cstr.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(ci64.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(cu64.as_bool(), std::invalid_argument); + BOOST_TEST_THROWS(cdub.as_bool(), std::invalid_argument); + bool const&x = cboo.as_bool(); + BOOST_TEST_THROWS(cnul.as_bool(), std::invalid_argument); + (void)x; + } + } + + void + testGet() + { + value obj(object{}); + value arr(array{}); + value str(string{}); + value i64(std::int64_t{}); + value u64(std::uint64_t{}); + value dub(double{}); + value boo(true); + + auto const& cobj(obj); + auto const& carr(arr); + auto const& cstr(str); + auto const& ci64(i64); + auto const& cu64(u64); + auto const& cdub(dub); + auto const& cboo(boo); + + // get_object() + // get_array() + // get_string() + // get_int64() + // get_uint64() + // get_double() + // get_bool() + { + object& xobj = obj.get_object(); + array& xarr = arr.get_array(); + string& xstr = str.get_string(); + std::int64_t& xi64 = i64.get_int64(); + std::uint64_t& xu64 = u64.get_uint64(); + double& xdub = dub.get_double(); + bool& xboo = boo.get_bool(); + + (void)(xobj); + (void)(xarr); + (void)(xstr); + (void)(xi64); + (void)(xu64); + (void)(xdub); + (void)(xboo); + } + + // get_object() const + // get_array() const + // get_string() const + // get_int64() const + // get_uint64() const + // get_double() const + // get_bool() const + { + object const& xobj = cobj.get_object(); + array const& xarr = carr.get_array(); + string const& xstr = cstr.get_string(); + std::int64_t + const& xi64 = ci64.get_int64(); + std::uint64_t + const& xu64 = cu64.get_uint64(); + double const& xdub = cdub.get_double(); + bool const& xboo = cboo.get_bool(); + + (void)(xobj); + (void)(xarr); + (void)(xstr); + (void)(xi64); + (void)(xu64); + (void)(xdub); + (void)(xboo); + } + } + + void + testAt() + { + // object + BOOST_TEST(value( + {{"k1", "value"}, {"k2", nullptr}} + ).at("k1").as_string() == "value"); + BOOST_TEST_THROWS(value( + {{"k1", "value"}, {"k2", nullptr}} + ).at("null"), + std::out_of_range); + + // array + BOOST_TEST( + value({true,2,"3"}).at(1).as_int64() == 2); + + BOOST_TEST_THROWS( value({false,2,false}).at(4), std::out_of_range ); + BOOST_TEST_THROWS( value({false,2,"3"}).at(4), std::out_of_range ); + BOOST_TEST_THROWS( value({false,false}).at(4), std::out_of_range ); + BOOST_TEST_THROWS( value({false,2}).at(4), std::out_of_range ); + BOOST_TEST_THROWS( value({false,2,"3",nullptr}).at(4), std::out_of_range ); + BOOST_TEST_THROWS( value({2,false,"3"}).at(4), std::out_of_range ); + BOOST_TEST_THROWS( value({true,2,"3"}).at(4), std::out_of_range ); + } + + //------------------------------------------------------ + + void + testKeyValuePair() + { + using kvp = key_value_pair; + + kvp v1("key", "value"); + kvp v2(v1); + BOOST_TEST(v2.key() == "key"); + BOOST_TEST( + v2.value().get_string() == "value"); + kvp v3(std::move(v2)); + BOOST_TEST(v3.key() == "key"); + BOOST_TEST( + v3.value().get_string() == "value"); + BOOST_TEST(std::memcmp( + v3.key_c_str(), "key\0", 4) == 0); + + BOOST_STATIC_ASSERT(std::tuple_size<key_value_pair>::value == 2); + BOOST_TEST(get<0>(v3) == "key"); + BOOST_TEST( + get<1>(v3).get_string() == "value"); + + BOOST_STATIC_ASSERT(std::is_same< + decltype(get<1>(std::declval<kvp>())), json::value&&>::value); + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) + auto const [kc, vc] = v1; + static_assert(std::is_same<decltype(kc), string_view const>::value); + static_assert(std::is_same<decltype(vc), value const&>::value); + BOOST_TEST(kc == "key"); + BOOST_TEST(&vc != &v1.value()); + + auto& [kr, vr] = v1; + static_assert(std::is_same<decltype(kr), string_view const>::value); + static_assert(std::is_same<decltype(vr), value&>::value); + BOOST_TEST(kr == "key"); + BOOST_TEST(&vr == &v1.value()); + + auto const& [kcr, vcr] = v1; + static_assert(std::is_same<decltype(kcr), string_view const>::value); + static_assert(std::is_same<decltype(vcr), value const&>::value); + BOOST_TEST(kcr == "key"); + BOOST_TEST(&vcr == &v1.value()); + + const kvp v4("const key", "const value"); + auto& [ckr, cvr] = v4; + static_assert(std::is_same<decltype(ckr), string_view const>::value); + static_assert(std::is_same<decltype(cvr), value const&>::value); + BOOST_TEST(ckr == "const key"); + BOOST_TEST(&cvr == &v4.value()); +#endif + } + + //------------------------------------------------------ + + void + testStdConstruction() + { + { + value jv(std::string("test")); + } + } + + void + testInitList() + { + check_array(value{0,0,0}, 0, 0, 0); + check_array(value{false,false,false}, false, false, false); + check_array(value{false,2,false}, false, 2, false); + check_array(value{false,2,"3"}, false, 2, "3"); + check_array(value{false,false}, false, false); + check_array(value{false,2}, false, 2); + check_array(value{false,2,"3",nullptr}, false, 2, "3", nullptr); + check_array(value{2,false,"3"}, 2, false, "3"); + check_array(value{true,2,"3"}, true, 2, "3"); + } + + //------------------------------------------------------ + + void + testEquality() + { + BOOST_TEST(value(nullptr) == value(nullptr)); + BOOST_TEST(value(nullptr) != value(true)); + + BOOST_TEST(value(false) == value(false)); + BOOST_TEST(value(true) != value(false)); + BOOST_TEST(value(true) != value(nullptr)); + + BOOST_TEST(value( 1) == value( 1)); + BOOST_TEST(value( 1) != value( 2)); + BOOST_TEST(value(-1) == value(-1)); + BOOST_TEST(value(-1) != value(-2)); + BOOST_TEST(value(-1) != value( 2)); + BOOST_TEST(value( 1) == value( 1UL)); + BOOST_TEST(value( 1) != value( 2UL)); + BOOST_TEST(value(-1) != value( 1UL)); + BOOST_TEST(value(-1) != value(nullptr)); + + BOOST_TEST(value(1UL) == value( 1UL)); + BOOST_TEST(value(1UL) != value( 2UL)); + BOOST_TEST(value(1UL) == value( 1)); + BOOST_TEST(value(1UL) != value(-1)); + BOOST_TEST(value(1UL) != value(nullptr)); + + BOOST_TEST(value(1.5) == value(1.5)); + BOOST_TEST(value(1.5) != value(2.5)); + BOOST_TEST(value(1.5) != value(false)); + BOOST_TEST(value(2.0) != value(2)); + + BOOST_TEST(value("abc") == value("abc")); + BOOST_TEST(value("abc") != value("xyz")); + BOOST_TEST(value("abc") != value("x")); + BOOST_TEST(value("abc") != value(nullptr)); + + BOOST_TEST(value({1,2,3}) == value({1,2,3})); + BOOST_TEST(value({1,2,3}) != value({2,3,1})); + BOOST_TEST(value({1,2,3}) != value({2,3,4})); + BOOST_TEST(value({1,2,3}) != value(nullptr)); + BOOST_TEST(value({ + {"a",1}, {"b",2}, {"c",3} }) == value({ + {"a",1}, {"b",2}, {"c",3} })); + BOOST_TEST(value({ + {"a",1}, {"b",2}, {"c",3} }) == value({ + {"c",3}, {"a",1}, {"b",2} })); + BOOST_TEST(value({ + {"a",1}, {"b",2}, {"c",3} }) != value({ + {"b",1}, {"c",2}, {"d",3} })); + BOOST_TEST(value({ + {"a",1}, {"b",2}, {"c",3} }) != value({ + {"a",2}, {"b",3}, {"c",4} })); + BOOST_TEST(value({ + {"a",1}, {"b",2}, {"c",3} }) != value(nullptr)); + } + + void + testHash() + { + BOOST_TEST(check_hash_equal(value(nullptr), value(nullptr))); + BOOST_TEST(check_hash_equal(value(nullptr), value())); + BOOST_TEST(check_hash_equal(value(nullptr), value{})); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value({}))); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value({object()}))); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value(true))); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value(false))); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value(0))); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value(0UL))); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value(0.0))); + BOOST_TEST(expect_hash_not_equal(value(nullptr), value(""))); + + BOOST_TEST(check_hash_equal(value(true), value(true))); + BOOST_TEST(check_hash_equal(value(false), value(false))); + BOOST_TEST(expect_hash_not_equal(value(false), value(true))); + BOOST_TEST(expect_hash_not_equal(value(false), value(0))); + BOOST_TEST(expect_hash_not_equal(value(false), value(0UL))); + BOOST_TEST(expect_hash_not_equal(value(false), value(0.0))); + BOOST_TEST(expect_hash_not_equal(value(true), value(1))); + BOOST_TEST(expect_hash_not_equal(value(true), value(1UL))); + BOOST_TEST(expect_hash_not_equal(value(true), value(1.0))); + + BOOST_TEST(check_hash_equal(value(2021), value(2021UL))); + BOOST_TEST(expect_hash_not_equal(value(2021U), value(-2021))); + BOOST_TEST(expect_hash_not_equal(value(2021UL), value(2021.0))); + + BOOST_TEST(expect_hash_not_equal(value({}), value({object()}))); + BOOST_TEST(expect_hash_not_equal(value({}), value(""))); + BOOST_TEST(expect_hash_not_equal(value({object()}), value(""))); + + BOOST_TEST(check_hash_equal( + value({{"a",1}, {"b",2}, {"c",3}}), + value({{"b",2}, {"c",3}, {"a",1}}))); + BOOST_TEST(expect_hash_not_equal( + value({{"a",1}, {"b",2}, {"c",3}}), + object({{"b",2}, {"c",3}, {"a",1}}))); + BOOST_TEST(expect_hash_not_equal( + value({{"a",1}, {"b",2}, {"c",3}}), + value({{"b",2}, {"c",3}}))); + BOOST_TEST(check_hash_equal( + value({"a", "b", 17}), + value({"a", "b", 17U}))); + BOOST_TEST(expect_hash_not_equal( + value({"a", "b", 17}), + array({"a", "b", 17}))); + BOOST_TEST(expect_hash_not_equal( + value({"a", "b", 17}), + value({17, "a", "b"}))); + BOOST_TEST(expect_hash_not_equal( + value({"a", "b"}), + value({{"a", "b"}}))); + } + + //------------------------------------------------------ + + void + run() + { + testSpecial(); + testConversion(); + testAssignment(); + testModifiers(); + testExchange(); + testObservers(); + testGetStorage(); + testIf(); + testToNumber(); + testAs(); + testGet(); + testAt(); + testKeyValuePair(); + testStdConstruction(); + testInitList(); + testEquality(); + testHash(); + } +}; + +TEST_SUITE(value_test, "boost.json.value"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/value_from.cpp b/src/boost/libs/json/test/value_from.cpp new file mode 100644 index 000000000..b4b45ac0a --- /dev/null +++ b/src/boost/libs/json/test/value_from.cpp @@ -0,0 +1,308 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/value_from.hpp> + +#include <boost/json/value.hpp> // prevent intellisense bugs +#include <boost/json/serialize.hpp> + +#include "test_suite.hpp" + +#include <array> +#include <string> +#include <vector> +#include <tuple> +#include <map> +#include <unordered_map> + +//---------------------------------------------------------- + +namespace value_from_test_ns { + +//---------------------------------------------------------- + +struct T1 +{ + int i = 42; +}; + +void +tag_invoke( + ::boost::json::value_from_tag, + ::boost::json::value& jv, + T1 const& t) +{ + jv = t.i; +} + +//---------------------------------------------------------- + +// member function +// uses generic algorithms +struct T2 +{ + std::vector<int> v; + std::string s; + + T2() + : v({1,2,3, 4}) + , s("test") + { + } +}; + +void +tag_invoke( + ::boost::json::value_from_tag, + ::boost::json::value& jv, + T2 const& t) +{ + jv = { t.v, t.s }; +} + +struct T3 +{ +}; + +BOOST_STATIC_ASSERT(! ::boost::json::has_value_from<T3>::value); + +struct T4 +{ + operator ::boost::json::value() + { + return nullptr; + } +}; + +BOOST_STATIC_ASSERT(! ::boost::json::has_value_from<T4>::value); + +//---------------------------------------------------------- + +struct T5 : std::vector<int> +{ + using std::vector<int>::vector; +}; + +void +tag_invoke( + ::boost::json::value_from_tag, + ::boost::json::value& jv, + T5 const&) +{ + jv = "T5"; +} + + +//---------------------------------------------------------- + +} // value_from_test_ns + +template<class T> +static +void +check( + ::boost::json::string_view s, + T const& t) +{ + { + auto const jv = value_from(t, + ::boost::json::storage_ptr{}); + auto const js = + ::boost::json::serialize(jv); + BOOST_TEST(js == s); + } + { + auto const jv = + ::boost::json::value_from(t); + auto const js = + ::boost::json::serialize(jv); + BOOST_TEST(js == s); + } +} + +BOOST_JSON_NS_BEGIN + +namespace { + +template<class T> +static +void +testValueCtor(T const& t) +{ + BOOST_TEST( serialize(value_from(t)) == serialize(value(t)) ); +} + +template<class T> +static +void +testValueCtor() +{ + testValueCtor(T{}); +} + +} // namespace + +// integral +BOOST_STATIC_ASSERT(has_value_from<int>::value); +BOOST_STATIC_ASSERT(has_value_from<int&>::value); +BOOST_STATIC_ASSERT(has_value_from<int&&>::value); +// array +BOOST_STATIC_ASSERT(has_value_from<int[4]>::value); +BOOST_STATIC_ASSERT(has_value_from<int(&)[4]>::value); +BOOST_STATIC_ASSERT(has_value_from<int(&&)[4]>::value); +// forward range +BOOST_STATIC_ASSERT(has_value_from<std::vector<int>>::value); +BOOST_STATIC_ASSERT(has_value_from<std::vector<int>&>::value); +BOOST_STATIC_ASSERT(has_value_from<std::vector<int>&&>::value); +// tuple-like +BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>>::value); +BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>&>::value); +BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>&&>::value); +BOOST_STATIC_ASSERT(has_value_from<key_value_pair>::value); +BOOST_STATIC_ASSERT(has_value_from<key_value_pair&>::value); +BOOST_STATIC_ASSERT(has_value_from<key_value_pair&&>::value); + +// object-like +BOOST_STATIC_ASSERT(has_value_from<std::map<string_view, int>>::value); + +class value_from_test +{ +public: + static + void + testValueCtors() + { + // value_from supports every value constructor + + testValueCtor<value>(); + + char const* s = "5"; + testValueCtor(s); + } + + static + void + testGeneral() + { + { + int a[4] = {1, 2, 3, 4}; + value b{1, 2, 3, 4}; + value c = value_from(a); + BOOST_TEST(c.is_array()); + BOOST_TEST(serialize(c) == serialize(b)); + } + { + std::tuple<int, string, int, bool> a{1, "2", 42, true}; + value b{1, "2", 42, true}; + value c = value_from(a); + BOOST_TEST(c.is_array()); + BOOST_TEST(serialize(c) == serialize(b)); + } + { + std::array<int, 1000> a; + a.fill(0); + + value b; + array& b_arr = b.emplace_array(); + b_arr.insert(b_arr.end(), a.begin(), a.end()); + + BOOST_TEST(value_from(a) == b); + } + { + std::pair<int, string> a{1, string("2")}; + value b{1, "2"}; + value c = value_from(a); + BOOST_TEST(c.is_array()); + BOOST_TEST(serialize(c) == serialize(b)); + } + { + // ensures that this isn't parsed as a key value pair + std::pair<string_view, int> a{"2", 1}; + value b{"2", 1}; + value c = value_from(a); + BOOST_TEST(c.is_array()); + BOOST_TEST(serialize(c) == serialize(b)); + } + { + key_value_pair a{"2", 1}; + value b{"2", 1}; + value c = value_from(a); + BOOST_TEST(c.is_array()); + BOOST_TEST(serialize(c) == serialize(b)); + } + } + + static + void + testAssociative() + { + { + std::map<string_view, int> a = + {{"a", 1}, {"b", 2}, {"c", 3}}; + value b = {{"a", 1}, {"b", 2}, {"c", 3}}; + value c = value_from(a); + BOOST_TEST(c.is_object()); + BOOST_TEST(a.size() == c.as_object().size()); + BOOST_TEST(b.as_object().size() == c.as_object().size()); + } + { + std::unordered_map<std::string, int> a = + {{"a", 1}, {"b", 2}, {"c", 3}}; + value b = {{"a", 1}, {"b", 2}, {"c", 3}}; + value c = value_from(a); + BOOST_TEST(c.is_object()); + BOOST_TEST(a.size() == c.as_object().size()); + BOOST_TEST(b.as_object().size() == c.as_object().size()); + } + { + std::map<int, int> a = + {{1, 1}, {2, 2}, {3, 3}}; + value b = {{1, 1}, {2, 2}, {3, 3}}; + value c = value_from(a); + BOOST_TEST(!c.is_object()); + BOOST_TEST(a.size() == c.as_array().size()); + BOOST_TEST(b.as_array().size() == c.as_array().size()); + } + { + std::unordered_map<int, int> a = + {{1, 1}, {2, 2}, {3, 3}}; + value b = {{1, 1}, {2, 2}, {3, 3}}; + value c = value_from(a); + BOOST_TEST(!c.is_object()); + BOOST_TEST(a.size() == c.as_array().size()); + BOOST_TEST(b.as_array().size() == c.as_array().size()); + } + } + + static + void + testPreferUserCustomizations() + { + value_from_test_ns::T5 t5; + BOOST_TEST((::boost::json::value_from(t5) == "T5")); + } + + void + run() + { + check("42", ::value_from_test_ns::T1{}); + check("[[1,2,3,4],\"test\"]", ::value_from_test_ns::T2{}); + + testValueCtors(); + testGeneral(); + testAssociative(); + testPreferUserCustomizations(); + } +}; + +TEST_SUITE(value_from_test, "boost.json.value_from"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/value_ref.cpp b/src/boost/libs/json/test/value_ref.cpp new file mode 100644 index 000000000..86e3a4fce --- /dev/null +++ b/src/boost/libs/json/test/value_ref.cpp @@ -0,0 +1,404 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/value_ref.hpp> + +#include <boost/json/value.hpp> +#include <boost/json/serialize.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +//---------------------------------------------------------- + +// From the javadoc + + class my_type + { + json::value jv_; + + public: + my_type( std::initializer_list< json::value_ref > init ) + : jv_(init) + { + } + }; + +//---------------------------------------------------------- + +class value_ref_test +{ +public: + using init_list = + std::initializer_list<value_ref>; + + void + testCtors() + { + // scalars + (void)value_ref((signed char)1); + (void)value_ref((short)1); + (void)value_ref((int)1); + (void)value_ref((long)1); + (void)value_ref((long long)1); + (void)value_ref((unsigned char)1); + (void)value_ref((unsigned short)1); + (void)value_ref((unsigned int)1); + (void)value_ref((unsigned long)1); + (void)value_ref((unsigned long long)1); + (void)value_ref((float)1.); + (void)value_ref((double)1.); + (void)value_ref(true); + (void)value_ref(nullptr); + + // string_view, char const* + (void)(value_ref)string_view("test"); + (void)(value_ref)("test"); + + // init-list + value_ref({1,2,3,4,5}); + + // value + (value_ref)value(); + { + value jv; + (value_ref)jv; + } + { + value const jv; + (value_ref)jv; + } + + // object + (value_ref)object(); + { + object o; + (value_ref)o; + } + { + object const o{}; + (value_ref)o; + } + + // array + (value_ref)object(); + { + array a; + (value_ref)a; + } + { + array const a{}; + (value_ref)a; + } + + // string + (value_ref)string(); + { + string s; + (value_ref)s; + } + { + string const s{}; + (value_ref)s; + } + + // construct from a const rvalue + { + const value val; + (void)value_ref(std::move(val)); + } + } + + void + testInitList() + { + // string_view, char const* + (void)init_list{string_view("test")}; + (void)init_list{"test"}; + + // scalars + (void)init_list{(short)1}; + (void)init_list{(int)1}; + (void)init_list{(long)1}; + (void)init_list{(long long)1}; + (void)init_list{(unsigned short)1}; + (void)init_list{(unsigned int)1}; + (void)init_list{(unsigned long)1}; + (void)init_list{(unsigned long long)1}; + (void)init_list{(float)1.}; + (void)init_list{(double)1.}; + (void)init_list{true}; + (void)init_list{nullptr}; + + // bool + { + bool b = true; + auto const cb = b; + BOOST_TEST(value_ref::make_value(init_list{b}, {}).at(0).is_bool()); + BOOST_TEST(value_ref::make_value(init_list{cb}, {}).at(0).is_bool()); + } + + // value + (void)init_list{value()}; + { + value jv; + (void)init_list{jv}; + } + { + value const jv{}; + (void)init_list{jv}; + } + + // object + (void)init_list{object()}; + { + object o; + (void)init_list{o}; + } + { + object const o{}; + (void)init_list{o}; + } + + // array + (void)init_list{object()}; + { + array a; + (void)init_list{a}; + } + { + array const a{}; + (void)init_list{a}; + } + + // string + (void)init_list{string()}; + { + string s; + (void)init_list{s}; + } + { + string const s{}; + (void)init_list{s}; + } + + // init_list + (void)init_list{{1,2,3,4,5}}; + (void)init_list{{{1,2},{3,4,5}}}; + (void)init_list{{1,2,{3,{4,5}}}}; + + { + init_list init = + { { "key", true } }; + (void)init; + } + } + + void + make_value( + init_list init, + string_view s) + { + auto const jv = + value_ref(init).make_value({}); + auto const js = serialize(jv); + BOOST_TEST(js == s); + } + + void + testMakeValue() + { + // scalars + make_value({(short)-1}, "[-1]"); + make_value({(int)-2}, "[-2]"); + make_value({(long)-3}, "[-3]"); + make_value({(long long)-4}, "[-4]"); + make_value({(unsigned short)1}, "[1]"); + make_value({(unsigned int)2}, "[2]"); + make_value({(unsigned long)3}, "[3]"); + make_value({(unsigned long long)4}, "[4]"); + //make_value({(float)1.}, "[1]"); + //make_value({(double)1.}, "[1]"); + make_value({true}, "[true]"); + make_value({nullptr}, "[null]"); + + // string_view + make_value({string_view("5")}, "[\"5\"]"); + make_value({"6"}, "[\"6\"]"); + + // value + { + make_value({value(1)}, "[1]"); + value const v(1); + make_value({v}, "[1]"); + make_value({value(2)}, "[2]"); + } + + // object + { + make_value({object({{"k1",1},{"k2",2}})}, "[{\"k1\":1,\"k2\":2}]"); + object const obj({{"k1",1},{"k2",2}}); + make_value({obj}, "[{\"k1\":1,\"k2\":2}]"); + } + + // array + { + make_value({array({1,2,3})}, "[[1,2,3]]"); + array const arr({1,2,3}); + make_value({arr}, "[[1,2,3]]"); + } + + // string + { + make_value({string("test")}, "[\"test\"]"); + string const str("test"); + make_value({str}, "[\"test\"]"); + } + + // init list with size != 2 + { + make_value({{1,2,3}}, "[[1,2,3]]"); + } + + // `string` as key + { + make_value({ + {string("k1"), 1}, + {string("k2"), 2}}, + "{\"k1\":1,\"k2\":2}"); + } + + // object/array conversion + + make_value( + {1,2,{3,{4,5}}}, + "[1,2,[3,[4,5]]]" ); + + make_value( + {{"k1",1}}, + "{\"k1\":1}"); + + make_value( + {{"k1",1}, {"k2",2}}, + "{\"k1\":1,\"k2\":2}"); + + make_value( + {{"k1",1}, {"k2",{{"k3",3}, {"k4",4}}}}, + "{\"k1\":1,\"k2\":{\"k3\":3,\"k4\":4}}"); + + make_value({value(1)}, "[1]"); + make_value({array({1,2,3,4})}, "[[1,2,3,4]]"); + } + + using kv_init_list = + std::initializer_list< + std::pair<string_view, value_ref>>; + + void + make_object( + kv_init_list init, + string_view s) + { + auto const jv = value(object(init)); + auto const js = serialize(jv); + BOOST_TEST(js == s); + } + + void + testObjects() + { + make_object({ + {"k1",1} + }, "{\"k1\":1}"); + make_object({ + {"k1",1}, {"k2",2} + }, "{\"k1\":1,\"k2\":2}"); + make_object({ + {"k1", {1,2}}, {"k2", {1,2,3}} + }, "{\"k1\":[1,2],\"k2\":[1,2,3]}"); + make_object({ + {"k1", {{"k2",2}, {"k3",3}}} + }, "{\"k1\":{\"k2\":2,\"k3\":3}}"); + } + + void + testMoveFrom() + { + { + string a = "abcdefghijklmnopqrstuvwxyz"; + BOOST_TEST(!a.empty()); + array b{std::move(a), string()}; + BOOST_TEST(a.empty()); + } + { + string a = "abcdefghijklmnopqrstuvwxyz"; + BOOST_TEST(!a.empty()); + array b{a, string()}; + BOOST_TEST(!a.empty()); + } + { + string const a = "abcdefghijklmnopqrstuvwxyz"; + BOOST_TEST(!a.empty()); + array b{a, string()}; + BOOST_TEST(!a.empty()); + } + { + array a{value()}; + BOOST_TEST(a.begin() != a.end()); + array b{std::move(a), array()}; + BOOST_TEST(a.begin() == a.end()); + } + { + array a{value()}; + BOOST_TEST(a.begin() != a.end()); + array b{a, array()}; + BOOST_TEST(a.begin() != a.end()); + } + { + const array a{value()}; + BOOST_TEST(a.begin() != a.end()); + array b{a, array()}; + BOOST_TEST(a.begin() != a.end()); + } + { + object a{{"a", 1}, {"b", 2}}; + BOOST_TEST(a.capacity() > 0); + array b{std::move(a), object()}; + BOOST_TEST(a.capacity() == 0); + } + { + object a{{"a", 1}, {"b", 2}}; + BOOST_TEST(a.capacity() > 0); + array b{a, object()}; + BOOST_TEST(a.capacity() > 0); + } + { + const object a{{"a", 1}, {"b", 2}}; + BOOST_TEST(a.capacity() > 0); + array b{a, object()}; + BOOST_TEST(a.capacity() > 0); + } + } + + void + run() + { + testCtors(); + testInitList(); + testMakeValue(); + testObjects(); + testMoveFrom(); + } +}; + +TEST_SUITE(value_ref_test, "boost.json.value_ref"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/value_stack.cpp b/src/boost/libs/json/test/value_stack.cpp new file mode 100644 index 000000000..56169d389 --- /dev/null +++ b/src/boost/libs/json/test/value_stack.cpp @@ -0,0 +1,127 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/value_stack.hpp> + +#include <boost/json/serialize.hpp> +#include <boost/json/static_resource.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +BOOST_STATIC_ASSERT( std::is_nothrow_destructible<value_stack>::value ); + +class value_stack_test +{ +public: + // This is from the javadoc + void + testValueStack() + { + + //---------------------------------- + // value_stack + { + // This example builds a json::value without any dynamic memory allocations: + + // Construct the value stack using a local buffer + unsigned char temp[4096]; + value_stack st( storage_ptr(), temp, sizeof(temp) ); + + // Create a static resource with a local initial buffer + unsigned char buf[4096]; + static_resource mr( buf, sizeof(buf) ); + + // All values on the stack will use `mr` + st.reset(&mr); + + // Push the key/value pair "a":1. + st.push_key("a"); + st.push_int64(1); + + // Push "b":null + st.push_key("b"); + st.push_null(); + + // Push "c":"hello" + st.push_key("c"); + st.push_string("hello"); + + // Pop the three key/value pairs and push an object with those three values. + st.push_object(3); + + // Pop the object from the stack and take ownership. + value jv = st.release(); + + assert( serialize(jv) == "{\"a\":1,\"b\":null,\"c\":\"hello\"}" ); + + // At this point we could re-use the stack by calling reset + } + + //---------------------------------- + // value_stack::push_array + { + value_stack st; + + // reset must be called first or else the behavior is undefined + st.reset(); + + // Place three values on the stack + st.push_int64( 1 ); + st.push_int64( 2 ); + st.push_int64( 3 ); + + // Remove the 3 values, and push an array with those 3 elements on the stack + st.push_array( 3 ); + + // Pop the object from the stack and take ownership. + value jv = st.release(); + + assert( serialize(jv) == "[1,2,3]" ); + + // At this point, reset must be called again to use the stack + } + + //---------------------------------- + // value_stack::push_object + { + value_stack st; + + // reset must be called first or else the behavior is undefined + st.reset(); + + // Place a key/value pair onto the stack + st.push_key( "x" ); + st.push_bool( true ); + + // Replace the key/value pair with an object containing a single element + st.push_object( 1 ); + + // Pop the object from the stack and take ownership. + value jv = st.release(); + + assert( serialize(jv) == "{\"x\":true}" ); + + // At this point, reset must be called again to use the stack + } + + } + + void + run() + { + testValueStack(); + } +}; + +TEST_SUITE(value_stack_test, "boost.json.value_stack"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/value_to.cpp b/src/boost/libs/json/test/value_to.cpp new file mode 100644 index 000000000..f4d05fb97 --- /dev/null +++ b/src/boost/libs/json/test/value_to.cpp @@ -0,0 +1,128 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/value_to.hpp> + +#include "test_suite.hpp" + +#include <array> +#include <map> +#include <unordered_map> +#include <vector> + +BOOST_JSON_NS_BEGIN + + +template <class T, class = void> +struct can_apply_value_to + : std::false_type +{ +}; + +template <class T> +struct can_apply_value_to<T, detail::void_t<decltype( + value_to<int>(std::declval<T>())) +>> + : std::true_type +{ +}; + +BOOST_STATIC_ASSERT(!can_apply_value_to<int>::value); + + +class value_to_test +{ +public: + + template<class T> + void + check(T t) + { + BOOST_TEST(value_to<T>(value_from(t)) == t); + } + + void + testNumberCast() + { + check((short)-1); + check((int)-2); + check((long)-3); + check((long long)-4); + check((unsigned short)1); + check((unsigned int)2); + check((unsigned long)3); + check((unsigned long long)4); + check((float)1.5); + check((double)2.5); + check(true); + } + + void + testJsonTypes() + { + value_to<object>(value(object_kind)); + value_to<array>(value(array_kind)); + value_to<string>(value(string_kind)); + } + + void + testGenerics() + { + check(std::string("test")); + check(std::map<std::string, int> + { + {"a", 1}, {"b", 2}, {"c", 3} + }); + check(std::unordered_map<std::string, int> + { + { "a", 1 }, {"b", 2}, {"c", 3} + }); + check(std::vector<int>{1, 2, 3, 4}); + check(std::make_pair(std::string("test"), 5)); + check(std::make_tuple(std::string("outer"), + std::make_pair(std::string("test"), 5))); + check(std::map<int, int> + { + {2, 4}, {3, 9}, {5, 25} + }); + + { + std::array<int, 1000> arr; + arr.fill(0); + check(arr); + } + + BOOST_TEST_THROWS( + (value_to<std::tuple<int, int>>(value{1, 2, 3})), + std::invalid_argument); + BOOST_TEST_THROWS( + (value_to<std::tuple<int, int, int, int>>(value{1, 2, 3})), + std::invalid_argument); + + BOOST_TEST_THROWS( + (value_to<std::array<int, 4>>(value{1, 2, 3})), + std::invalid_argument); + BOOST_TEST_THROWS( + (value_to<std::array<int, 4>>(value{1, 2, 3, 4, 5})), + std::invalid_argument); + } + + void + run() + { + testNumberCast(); + testJsonTypes(); + testGenerics(); + } +}; + +TEST_SUITE(value_to_test, "boost.json.value_to"); + +BOOST_JSON_NS_END diff --git a/src/boost/libs/json/test/visit.cpp b/src/boost/libs/json/test/visit.cpp new file mode 100644 index 000000000..3d589031a --- /dev/null +++ b/src/boost/libs/json/test/visit.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +// Test that header file is self-contained. +#include <boost/json/visit.hpp> + +#include "test_suite.hpp" + +BOOST_JSON_NS_BEGIN + +class visit_test +{ +public: + template<class T> + void + check_const(kind k, T t) + { + struct f + { + kind k; + bool operator()(std::nullptr_t) { return k == kind::null; } + bool operator()(bool) { return k == kind::bool_; } + bool operator()(std::int64_t) { return k == kind::int64; } + bool operator()(std::uint64_t) { return k == kind::uint64; } + bool operator()(double) { return k == kind::double_; } + bool operator()(string const&) { return k == kind::string; } + bool operator()(array const&) { return k == kind::array; } + bool operator()(object const&) { return k == kind::object; } + bool operator()(...) { return false; } + }; + value const v(t); + BOOST_TEST(visit(f{k}, v)); + } + + template<class T> + void + check_mutable(kind k, T t) + { + struct f + { + kind k; + bool operator()(std::nullptr_t) { return k == kind::null; } + bool operator()(bool&) { return k == kind::bool_; } + bool operator()(std::int64_t&) { return k == kind::int64; } + bool operator()(std::uint64_t&) { return k == kind::uint64; } + bool operator()(double&) { return k == kind::double_; } + bool operator()(string&) { return k == kind::string; } + bool operator()(array&) { return k == kind::array; } + bool operator()(object&) { return k == kind::object; } + bool operator()(...) { return false; } + }; + value v(t); + BOOST_TEST(visit(f{k}, v)); + } + + void + testVisit() + { + check_const(kind::null, nullptr); + check_const(kind::bool_, true); + check_const(kind::int64, -1); + check_const(kind::uint64, 1U); + check_const(kind::double_, 3.14); + check_const(kind::string, string_kind); + check_const(kind::array, array_kind); + check_const(kind::object, object_kind); + + check_mutable(kind::null, nullptr); + check_mutable(kind::bool_, true); + check_mutable(kind::int64, -1); + check_mutable(kind::uint64, 1U); + check_mutable(kind::double_, 3.14); + check_mutable(kind::string, string_kind); + check_mutable(kind::array, array_kind); + check_mutable(kind::object, object_kind); + } + + void run() + { + testVisit(); + } +}; + +TEST_SUITE(visit_test, "boost.json.visit"); + +BOOST_JSON_NS_END |