From 54754c4ffbb51d27bb05c7b28d4d32ef9bdfb55d Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Thu, 5 Aug 2010 21:05:08 -0700 Subject: [PATCH 01/17] tests and such --- src/jsx.erl | 52 ++++++++++++++++++++++++++++++++++++++++++++- src/jsx_encoder.erl | 28 +++++++++++++++++++++--- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/jsx.erl b/src/jsx.erl index b87d44a..475fdd7 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -31,9 +31,19 @@ -export([is_json/1, is_json/2]). -export([format/1, format/2]). +%% if testing is enabled, export load_tests/1 so all modules may use it +-ifdef(test). +-export([load_tests/1]). +-endif. + %% types for function specifications -include("./include/jsx_types.hrl"). +-ifdef(test). +-include_lib("eunit/include/eunit.hrl"). +-endif. + + %% opts record -record(opts, { comments = false, @@ -206,4 +216,44 @@ detect_encoding(Bin, Opts) -> fun(end_stream) -> {error, badjson} ; (Stream) -> detect_encoding(<>, Opts) end - }. \ No newline at end of file + }. + + +%% eunit tests +-ifdef(test). + +load_tests(Path) -> + %% search the specified directory for any files with the .test ending + TestSpecs = filelib:wildcard("*.test", Path), + Tests = load_tests(TestSpecs, Path, []). + +load_tests([], _Dir, Acc) -> + lists:reverse(Acc); +load_tests([Test|Rest], Dir, Acc) -> + %% should alert about badly formed tests eventually, but for now just skip over them + case file:consult(Dir ++ "/" ++ Test) of + {ok, TestSpec} -> + try + load_tests(Rest, Dir, [parse_test(TestSpec, [])] ++ Acc) + catch _:_ -> + load_tests(Rest, Dir, Acc) + end + ; {error, _Reason} -> + load_tests(Rest, Dir, Acc) + end. + + +%% if the json, erlang or jsx values are lists, assume they're a path to a file that should +%% be read with file:read_file/1 +parse_test([{Key, Path}|Rest], Test) when is_list(Path) -> + case lists:member(Key, [json, erlang, jsx]) of + true -> + case file:read_file(Path) of + {ok, Bin} -> parse_test(Rest, [{Key, Bin}] ++ Test) + ; {error, Reason} -> {error, Reason} + end + ; false -> + parse_test(Rest, [{Key, Path}] ++ Test) + end. + +-endif. \ No newline at end of file diff --git a/src/jsx_encoder.erl b/src/jsx_encoder.erl index f690409..65a6fac 100644 --- a/src/jsx_encoder.erl +++ b/src/jsx_encoder.erl @@ -29,6 +29,11 @@ -include("./include/jsx_types.hrl"). +-ifdef(test). +-include_lib("eunit/include/eunit.hrl"). +-endif. + + -spec term_to_json(JSON::json(), Opts::encoder_opts()) -> binary(). @@ -114,7 +119,7 @@ float_to_decimal(Num) when is_float(Num) -> {F, E} = extract(<>), {R, S, MP, MM} = initial_vals(F, E), K = ceiling(math:log10(abs(Num)) - 1.0e-10), - Round = F band 1 =:= 1, + Round = F band 1 =:= 0, {Dpoint, Digits} = scale(R, S, MP, MM, K, Round), if Num >= 0 -> format(Dpoint, Digits) ; Num < 0 -> "-" ++ format(Dpoint, Digits) @@ -172,7 +177,7 @@ generate(RT, S, MP, MM, Round) -> TC1 = case Round of true -> (R =< MM); false -> (R < MM) end, TC2 = case Round of true -> (R + MP >= S); false -> (R + MP > S) end, case TC1 of - false -> case TC2 of + false -> case TC2 of false -> [D | generate(R * 10, S, MP * 10, MM * 10, Round)] ; true -> [D + 1] end @@ -268,5 +273,22 @@ to_hex(10) -> $a; to_hex(X) -> X + $0. +%% eunit tests +-ifdef(test). - \ No newline at end of file +jsx_escape_test_() -> + [ + {"json string escaping", ?_assert(json_escape(<<"\"\\\b\f\n\r\t">>) =:= <<"\\\"\\\\\\b\\f\\n\\r\\t">>)}, + {"json string hex escape", ?_assert(json_escape(<<1, 2, 3, 11, 26, 30, 31>>) =:= <<"\\u0001\\u0002\\u0003\\u000b\\u001a\\u001e\\u001f">>)} + ]. + +jsx_nice_decimal_test_() -> + [ + {"0.0 to decimal", ?_assert(list_to_float(float_to_decimal(0.0)) =:= 0.0)}, + {"1.0 to decimal", ?_assert(list_to_float(float_to_decimal(1.0)) =:= 1.0)}, + {"-1.0 to decimal", ?_assert(list_to_float(float_to_decimal(-1.0)) =:= -1.0)}, + {"really long float to decimal", ?_assert(list_to_float(float_to_decimal(3.1234567890987654321)) =:= 3.1234567890987654321)}, + {"1.0e23", ?_assert(float_to_decimal(1.0e23) =:= "1.0e23")} + ]. + +-endif. \ No newline at end of file From c6d9035e50cc7dbb9d3d8a95a967ff603808b41a Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Fri, 6 Aug 2010 06:18:09 -0700 Subject: [PATCH 02/17] rebar.config added to allow use of 'rebar eunit' --- rebar.config | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 rebar.config diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..cc78b03 --- /dev/null +++ b/rebar.config @@ -0,0 +1,3 @@ +%% edit `path` to change target directory for tests +{eunit_compile_opts, [{d, test}, {d, path, "./test/cases/"}]}. +{eunit_opts, [verbose]}. \ No newline at end of file From 57c85a41850f2d5e60a090a7415699cbc48f1ed4 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Fri, 6 Aug 2010 06:19:22 -0700 Subject: [PATCH 03/17] fixed compiler warning for unused variable in jsx:load_tests(Path) --- src/jsx.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jsx.erl b/src/jsx.erl index 475fdd7..f5615f3 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -225,7 +225,7 @@ detect_encoding(Bin, Opts) -> load_tests(Path) -> %% search the specified directory for any files with the .test ending TestSpecs = filelib:wildcard("*.test", Path), - Tests = load_tests(TestSpecs, Path, []). + load_tests(TestSpecs, Path, []). load_tests([], _Dir, Acc) -> lists:reverse(Acc); From ca1d605e95a0207e0b80c4634a3135f06db41622 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Fri, 6 Aug 2010 17:55:19 -0700 Subject: [PATCH 04/17] intermediate commit on way to eunit --- src/jsx.erl | 4 ++-- src/jsx_encoder.erl | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/jsx.erl b/src/jsx.erl index f5615f3..a08f696 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -243,10 +243,10 @@ load_tests([Test|Rest], Dir, Acc) -> end. -%% if the json, erlang or jsx values are lists, assume they're a path to a file that should +%% if the json, eep0018 or jsx values are lists, assume they're a path to a file that should %% be read with file:read_file/1 parse_test([{Key, Path}|Rest], Test) when is_list(Path) -> - case lists:member(Key, [json, erlang, jsx]) of + case lists:member(Key, [json, eep0018, jsx]) of true -> case file:read_file(Path) of {ok, Bin} -> parse_test(Rest, [{Key, Bin}] ++ Test) diff --git a/src/jsx_encoder.erl b/src/jsx_encoder.erl index 65a6fac..66df93e 100644 --- a/src/jsx_encoder.erl +++ b/src/jsx_encoder.erl @@ -65,6 +65,7 @@ term_to_events(Term) -> proplist_to_events([{Key, Term}|Rest], Acc) -> Event = term_to_event(Term), EncodedKey = key_to_event(Key), + io:format("~p~n~p~n~n", [EncodedKey, Acc]), case key_repeats(EncodedKey, Acc) of false -> proplist_to_events(Rest, Event ++ EncodedKey ++ Acc) ; true -> erlang:error(badarg) @@ -101,9 +102,10 @@ key_to_event(Key) when is_binary(Key) -> [{key, json_escape(Key)}]. -key_repeats([Key], [Key|_]) -> true; +key_repeats([{key, Key}], [{key, Key}|_Rest]) -> true; +key_repeats(Key, [{Key, _Value}|_Rest]) -> true; key_repeats(Key, [_|Rest]) -> key_repeats(Key, Rest); -key_repeats(_, []) -> false. +key_repeats(_Key, []) -> false. %% conversion of floats to 'nice' decimal output. erlang's float implementation is almost From eaa4ab4018a1c77e9842e27cba7557626f9cece7 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Fri, 6 Aug 2010 18:18:46 -0700 Subject: [PATCH 05/17] some minor changes to eep0018 --- src/jsx_eep0018.erl | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/jsx_eep0018.erl b/src/jsx_eep0018.erl index 7ca86f2..6a2e027 100644 --- a/src/jsx_eep0018.erl +++ b/src/jsx_eep0018.erl @@ -28,6 +28,10 @@ -include("./include/jsx_types.hrl"). +-ifdef(test). +-include_lib("eunit/include/eunit.hrl"). +-endif. + -spec json_to_term(JSON::binary(), Opts::decoder_opts()) -> json(). @@ -40,6 +44,11 @@ json_to_term(JSON, Opts) -> end. +%% the jsx formatter (pretty printer) can do most of the heavy lifting in converting erlang +%% terms to json strings, but it expects a jsx event iterator. luckily, the mapping from +%% erlang terms to jsx events is straightforward and the iterator can be faked with an +%% anonymous function + -spec term_to_json(JSON::json(), Opts::encoder_opts()) -> binary(). term_to_json(List, Opts) -> @@ -52,7 +61,7 @@ term_to_json(List, Opts) -> jsx:format(event_generator(lists:reverse(term_to_events(List))), [{output_encoding, Encoding}] ++ Opts). event_generator([]) -> - fun() -> {event, end_json, fun() -> {incomplete, fun(end_stream) -> ok end} end} end; + fun() -> {event, end_json, fun() -> {incomplete, fun(end_stream) -> event_generator([]) end} end} end; event_generator([Next|Rest]) -> fun() -> {event, Next, event_generator(Rest)} end. @@ -379,3 +388,24 @@ key_repeats([{key, Key}], [{key, Key}|_Rest]) -> true; key_repeats(Key, [{Key, _Value}|_Rest]) -> true; key_repeats(Key, [_|Rest]) -> key_repeats(Key, Rest); key_repeats(_Key, []) -> false. + + +%% eunit tests +-ifdef(test). + +jsx_escape_test_() -> + [ + {"json string escaping", ?_assert(json_escape(<<"\"\\\b\f\n\r\t">>) =:= <<"\\\"\\\\\\b\\f\\n\\r\\t">>)}, + {"json string hex escape", ?_assert(json_escape(<<1, 2, 3, 11, 26, 30, 31>>) =:= <<"\\u0001\\u0002\\u0003\\u000b\\u001a\\u001e\\u001f">>)} + ]. + +jsx_nice_decimal_test_() -> + [ + {"0.0 to decimal", ?_assert(list_to_float(float_to_decimal(0.0)) =:= 0.0)}, + {"1.0 to decimal", ?_assert(list_to_float(float_to_decimal(1.0)) =:= 1.0)}, + {"-1.0 to decimal", ?_assert(list_to_float(float_to_decimal(-1.0)) =:= -1.0)}, + {"really long float to decimal", ?_assert(list_to_float(float_to_decimal(3.1234567890987654321)) =:= 3.1234567890987654321)}, + {"1.0e23", ?_assert(float_to_decimal(1.0e23) =:= "1.0e23")} + ]. + +-endif. \ No newline at end of file From 55e7f701c78605b4b2d631457fa6f762c3d03e0b Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 7 Aug 2010 18:08:31 -0700 Subject: [PATCH 06/17] updated rebar config to suppress most eunit output --- rebar.config | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rebar.config b/rebar.config index cc78b03..acda5f1 100644 --- a/rebar.config +++ b/rebar.config @@ -1,3 +1,5 @@ -%% edit `path` to change target directory for tests +%% edit `path` value to change target directory for tests {eunit_compile_opts, [{d, test}, {d, path, "./test/cases/"}]}. -{eunit_opts, [verbose]}. \ No newline at end of file + +%% uncomment to get verbose output from test suite +%% {eunit_opts, [verbose]}. From 16cb0ad95e91fe29c417894b010fb23503b18498 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 7 Aug 2010 18:08:52 -0700 Subject: [PATCH 07/17] eunit tests for eep0018 module --- src/jsx_eep0018.erl | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/jsx_eep0018.erl b/src/jsx_eep0018.erl index 6a2e027..69c00e3 100644 --- a/src/jsx_eep0018.erl +++ b/src/jsx_eep0018.erl @@ -178,7 +178,6 @@ term_to_events(Term) -> proplist_to_events([{Key, Term}|Rest], Acc) -> Event = term_to_event(Term), EncodedKey = key_to_event(Key), - io:format("~p~n~p~n~n", [EncodedKey, Acc]), case key_repeats(EncodedKey, Acc) of false -> proplist_to_events(Rest, Event ++ EncodedKey ++ Acc) ; true -> erlang:error(badarg) @@ -309,6 +308,8 @@ pow(B, E, Acc) when E band 1 == 1 -> pow(B * B, E bsr 1, B * Acc); pow(B, E, Acc) -> pow(B * B, E bsr 1, Acc). +format(0, Digits) -> + format(Digits, ignore, ".0"); format(Dpoint, Digits) when Dpoint =< length(Digits), Dpoint > 0 -> format(Digits, Dpoint, []); format(Dpoint, Digits) when Dpoint > 0 -> @@ -401,11 +402,30 @@ jsx_escape_test_() -> jsx_nice_decimal_test_() -> [ - {"0.0 to decimal", ?_assert(list_to_float(float_to_decimal(0.0)) =:= 0.0)}, - {"1.0 to decimal", ?_assert(list_to_float(float_to_decimal(1.0)) =:= 1.0)}, - {"-1.0 to decimal", ?_assert(list_to_float(float_to_decimal(-1.0)) =:= -1.0)}, - {"really long float to decimal", ?_assert(list_to_float(float_to_decimal(3.1234567890987654321)) =:= 3.1234567890987654321)}, - {"1.0e23", ?_assert(float_to_decimal(1.0e23) =:= "1.0e23")} + {"0.0", ?_assert(float_to_decimal(0.0) =:= "0.0")}, + {"1.0", ?_assert(float_to_decimal(1.0) =:= "1.0")}, + {"-1.0", ?_assert(float_to_decimal(-1.0) =:= "-1.0")}, + {"3.1234567890987654321", ?_assert(float_to_decimal(3.1234567890987654321) =:= "3.1234567890987655")}, + {"1.0e23", ?_assert(float_to_decimal(1.0e23) =:= "1.0e23")}, + {"0.3", ?_assert(float_to_decimal(3.0/10.0) =:= "0.3")}, + {"0.0001", ?_assert(float_to_decimal(0.0001) =:= "1.0e-4")}, + {"0.00000001", ?_assert(float_to_decimal(0.00000001) =:= "1.0e-8")}, + {"1.0e-323", ?_assert(float_to_decimal(1.0e-323) =:= "1.0e-323")}, + {"1.0e308", ?_assert(float_to_decimal(1.0e308) =:= "1.0e308")}, + {"min normalized float", ?_assert(float_to_decimal(math:pow(2, -1022)) =:= "2.2250738585072014e-308")}, + {"max normalized float", ?_assert(float_to_decimal((2 - math:pow(2, -52)) * math:pow(2, 1023)) =:= "1.7976931348623157e308")}, + {"min denormalized float", ?_assert(float_to_decimal(math:pow(2, -1074)) =:= "5.0e-324")}, + {"max denormalized float", ?_assert(float_to_decimal((1 - math:pow(2, -52)) * math:pow(2, -1022)) =:= "2.225073858507201e-308")} + ]. + +jsx_key_repeats_test_() -> + [ + {"encoded key repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"key">>}, {key, <<"trailing key">>}]) =:= true)}, + {"encoded key no repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"trailing key">>}]) =:= false)}, + {"decoded key (atom) repeat", ?_assert(key_repeats(key, [{notkey, true}, {key, true}, {trailing_key, true}]) =:= true)}, + {"decoded key (binary) repeat", ?_assert(key_repeats(<<"key">>, [{<<"notkey">>, true}, {<<"key">>, true}, {<<"trailing key">>, true}]) =:= true)}, + {"decoded key (atom) no repeat", ?_assert(key_repeats(key, [{notkey, true}, {definitely_not_key, true}, {trailing_key, true}]) =:= false)}, + {"decoded key (binary) no repeat", ?_assert(key_repeats(<<"key">>, [{<<"notkey">>, true}, {<<"definitely not key">>, true}, {<<"trailing key">>, true}]) =:= false)} ]. -endif. \ No newline at end of file From 5da5b6d782e129f8ed3101fa10970bfde9dc7997 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 7 Aug 2010 18:09:07 -0700 Subject: [PATCH 08/17] eunit tests for verify module --- src/jsx_verify.erl | 50 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/jsx_verify.erl b/src/jsx_verify.erl index 70e4921..e3247b5 100644 --- a/src/jsx_verify.erl +++ b/src/jsx_verify.erl @@ -28,13 +28,18 @@ -include("./include/jsx_types.hrl"). +-ifdef(test). +-include_lib("eunit/include/eunit.hrl"). +-endif. + -spec is_json(JSON::binary(), Opts::verify_opts()) -> true | false. is_json(JSON, Opts) -> Encoding = proplists:get_value(encoding, Opts, utf8), - P = jsx:parser([{encoding, Encoding}]), + Comments = proplists:get_value(comments, Opts, false), + P = jsx:parser([{encoding, Encoding}, {comments, Comments}]), case proplists:get_value(strict, Opts, true) of true -> collect_strict(P(JSON), Opts) ; false -> collect(P(JSON), Opts) @@ -63,8 +68,51 @@ collect({event, {key, Key}, Next}, Keys) -> collect({event, _, Next}, Keys) -> collect(Next(), Keys); + +%% needed to parse numbers that don't have trailing whitespace in less strict mode +collect({incomplete, More}, Keys) -> + collect(More(end_stream), Keys); + collect(_, _) -> false. + + + +%% eunit tests +-ifdef(test). + +true_test_() -> + [ + {"empty object", ?_assert(is_json(<<"{}">>, []) =:= true)}, + {"empty array", ?_assert(is_json(<<"[]">>, []) =:= true)}, + {"whitespace", ?_assert(is_json(<<" \n \t \r [true] \t \n\r ">>, []) =:= true)}, + {"nested terms", ?_assert(is_json(<<"[ { \"key\": [ {}, {}, {} ], \"more key\": [{}] }, {}, [[[]]] ]">>, []) =:= true)}, + {"numbers", ?_assert(is_json(<<"[ -1.0, -1, -0, 0, 1e-1, 1, 1.0, 1e1 ]">>, []) =:= true)}, + {"strings", ?_assert(is_json(<<"[ \"a\", \"string\", \"in\", \"multiple\", \"acts\" ]">>, []) =:= true)}, + {"literals", ?_assert(is_json(<<"[ true, false, null ]">>, []) =:= true)} + ]. + +false_test_() -> + [ + {"naked true", ?_assert(is_json(<<"true">>, []) =:= false)}, + {"naked number", ?_assert(is_json(<<"1">>, []) =:= false)}, + {"naked string", ?_assert(is_json(<<"\"i am not json\"">>, []) =:= false)}, + {"unbalanced list", ?_assert(is_json(<<"[[[]]">>, []) =:= false)}, + {"trailing comma", ?_assert(is_json(<<"[ true, false, null, ]">>, []) =:= false)}, + {"unquoted key", ?_assert(is_json(<<"{ key: false }">>, []) =:= false)}, + {"comments", ?_assert(is_json(<<"[ /* a comment */ ]">>, []) =:= false)} + ]. + +less_strict_test_() -> + [ + {"naked true", ?_assert(is_json(<<"true">>, [{strict, false}]) =:= true)}, + {"naked number", ?_assert(is_json(<<"1">>, [{strict, false}]) =:= true)}, + {"naked string", ?_assert(is_json(<<"\"i am not json\"">>, [{strict, false}]) =:= true)}, + {"comments", ?_assert(is_json(<<"[ /* a comment */ ]">>, [{comments, true}]) =:= true)} + ]. + + +-endif. From bff9a38d39378f48aa12f41e73fb34541c013337 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 7 Aug 2010 23:01:04 -0700 Subject: [PATCH 09/17] refactoring of eep0018 --- src/jsx_eep0018.erl | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/jsx_eep0018.erl b/src/jsx_eep0018.erl index 69c00e3..4c4a711 100644 --- a/src/jsx_eep0018.erl +++ b/src/jsx_eep0018.erl @@ -54,19 +54,22 @@ json_to_term(JSON, Opts) -> term_to_json(List, Opts) -> case proplists:get_value(strict, Opts, true) of true when is_list(List) -> continue - ; false -> continue ; true -> erlang:error(badarg) + ; false -> continue end, Encoding = proplists:get_value(encoding, Opts, utf8), jsx:format(event_generator(lists:reverse(term_to_events(List))), [{output_encoding, Encoding}] ++ Opts). + +%% fake the jsx api with a closure to be passed to the pretty printer + event_generator([]) -> fun() -> {event, end_json, fun() -> {incomplete, fun(end_stream) -> event_generator([]) end} end} end; event_generator([Next|Rest]) -> fun() -> {event, Next, event_generator(Rest)} end. -%% internal for json_to_term +%% parse opts for the decoder opts_to_jsx_opts(Opts) -> opts_to_jsx_opts(Opts, []). @@ -86,14 +89,19 @@ opts_to_jsx_opts([_|Rest], Acc) -> opts_to_jsx_opts(Rest, Acc); opts_to_jsx_opts([], Acc) -> Acc. - - + + +%% ensure the first jsx event we get is start_object or start_array when running +%% in strict mode + collect_strict({event, Start, Next}, Acc, Opts) when Start =:= start_object; Start =:= start_array -> collect(Next(), [[]|Acc], Opts); collect_strict(_, _, _) -> erlang:error(badarg). +%% collect decoder events and convert to eep0018 format + collect({event, Start, Next}, Acc, Opts) when Start =:= start_object; Start =:= start_array -> collect(Next(), [[]|Acc], Opts); @@ -136,6 +144,8 @@ collect({event, Event, Next}, [Key, Current|Rest], Opts) -> %% any other event is an error collect(_, _, _) -> erlang:error(badarg). + +%% helper functions for converting jsx events to eep0018 formats event({string, String}, _Opts) -> unicode:characters_to_binary(String); @@ -163,7 +173,7 @@ event({literal, Literal}, _Opts) -> Literal. -%% internal for term_to_json +%% convert eep0018 representation to jsx events. note special casing for the empty object term_to_events([{}]) -> [end_object, start_object]; From 1617c878f54b4f025222741f55f0d743d02a3553 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 10 Aug 2010 11:04:14 -0700 Subject: [PATCH 10/17] abandoning branch for now, work is in intermediate state --- ebin/jsx.app | 3 +- priv/backends.escript | 2 +- priv/jsx_decoder_template.erl | 1 + rebar.config | 5 +- src/jsx.erl | 90 +- src/jsx_eep0018.erl | 6 +- src/jsx_test.erl | 140 ++ src/jsx_utf16.erl | 6 +- src/jsx_utf16le.erl | 6 +- src/jsx_utf32.erl | 6 +- src/jsx_utf32le.erl | 6 +- src/jsx_utf8.erl | 6 +- test/cases/absurdly_deep_array.test | 1551 ++++++++++++++++++++- test/cases/array.test | 30 +- test/cases/comments.test | 17 +- test/cases/deep_array.test | 4 +- test/cases/empty_array.test | 4 +- test/cases/empty_array_with_comment.test | 7 +- test/cases/empty_object.test | 4 +- test/cases/empty_object_with_comment.test | 7 +- test/cases/encoded_surrogates.test | 7 +- test/cases/exp.test | 18 +- test/cases/fraction.test | 23 +- test/cases/integer.json | 2 +- test/cases/integer.test | 16 +- test/cases/multibyte_utf.test | 4 +- test/cases/naked_false.test | 4 +- test/cases/naked_null.test | 4 +- test/cases/naked_number_a.test | 4 +- test/cases/naked_number_b.test | 4 +- test/cases/naked_number_c.test | 4 +- test/cases/naked_number_d.test | 4 +- test/cases/naked_number_e.test | 4 +- test/cases/naked_number_f.test | 4 +- test/cases/naked_number_g.test | 4 +- test/cases/naked_string.test | 4 +- test/cases/naked_true.test | 4 +- test/cases/negative_zero.test | 15 +- test/cases/numbers.test | 24 +- test/cases/object.test | 23 +- test/cases/string.test | 6 +- test/cases/string_escapes.test | 15 +- test/cases/unicode_to_codepoint.test | 10 +- test/cases/unicode_unconverted.test | 10 +- test/cases/whitespace.test | 4 +- test/cases/zero.test | 15 +- 46 files changed, 2040 insertions(+), 97 deletions(-) create mode 100644 src/jsx_test.erl diff --git a/ebin/jsx.app b/ebin/jsx.app index 9dfe537..587d475 100644 --- a/ebin/jsx.app +++ b/ebin/jsx.app @@ -11,7 +11,8 @@ jsx_utf32le, jsx_eep0018, jsx_format, - jsx_verify + jsx_verify, + jsx_test ]}, {registered, []}, {applications, [ diff --git a/priv/backends.escript b/priv/backends.escript index cb813bf..cdbcaed 100755 --- a/priv/backends.escript +++ b/priv/backends.escript @@ -38,7 +38,7 @@ to_abf(Backend) -> end, Name = to_modname(Backend), {ok, _, ABF} = compile:file( - "priv/jsx_decoder.erl", + "priv/jsx_decoder_template.erl", [binary, 'P', {outdir, Out}, {d, list_to_atom(Backend)}, {d, name, Name}] ), {Name, ABF}. diff --git a/priv/jsx_decoder_template.erl b/priv/jsx_decoder_template.erl index 84398a3..839f00d 100644 --- a/priv/jsx_decoder_template.erl +++ b/priv/jsx_decoder_template.erl @@ -35,6 +35,7 @@ -include("./include/jsx_types.hrl"). + -spec parse(JSON::json(), Opts::jsx_opts()) -> jsx_parser_result(). parse(JSON, Opts) -> diff --git a/rebar.config b/rebar.config index acda5f1..fd69bc7 100644 --- a/rebar.config +++ b/rebar.config @@ -1,5 +1,4 @@ -%% edit `path` value to change target directory for tests -{eunit_compile_opts, [{d, test}, {d, path, "./test/cases/"}]}. +{eunit_compile_opts, [{d, test}]}. %% uncomment to get verbose output from test suite -%% {eunit_opts, [verbose]}. +{eunit_opts, [verbose]}. diff --git a/src/jsx.erl b/src/jsx.erl index 1ceae9a..b414d59 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -31,10 +31,6 @@ -export([is_json/1, is_json/2]). -export([format/1, format/2]). -%% if testing is enabled, export load_tests/1 so all modules may use it --ifdef(test). --export([load_tests/1]). --endif. %% types for function specifications -include("./include/jsx_types.hrl"). @@ -218,15 +214,22 @@ detect_encoding(Bin, Opts) -> end }. - %% eunit tests -ifdef(test). +jsx_decoder_test_() -> + lists:map(fun(Encoding) -> + decoder_tests(load_tests("./test/cases"), Encoding, []) + end, + [utf8, utf16, {utf16, little}, utf32, {utf32, little}] + ). + + load_tests(Path) -> %% search the specified directory for any files with the .test ending TestSpecs = filelib:wildcard("*.test", Path), load_tests(TestSpecs, Path, []). - + load_tests([], _Dir, Acc) -> lists:reverse(Acc); load_tests([Test|Rest], Dir, Acc) -> @@ -234,26 +237,69 @@ load_tests([Test|Rest], Dir, Acc) -> case file:consult(Dir ++ "/" ++ Test) of {ok, TestSpec} -> try - load_tests(Rest, Dir, [parse_test(TestSpec, [])] ++ Acc) + ParsedTest = parse_tests(TestSpec, Dir), + load_tests(Rest, Dir, [ParsedTest] ++ Acc) catch _:_ -> load_tests(Rest, Dir, Acc) end ; {error, _Reason} -> load_tests(Rest, Dir, Acc) end. - - -%% if the json, eep0018 or jsx values are lists, assume they're a path to a file that should -%% be read with file:read_file/1 -parse_test([{Key, Path}|Rest], Test) when is_list(Path) -> - case lists:member(Key, [json, eep0018, jsx]) of - true -> - case file:read_file(Path) of - {ok, Bin} -> parse_test(Rest, [{Key, Bin}] ++ Test) - ; {error, Reason} -> {error, Reason} - end - ; false -> - parse_test(Rest, [{Key, Path}] ++ Test) - end. + + +parse_tests(TestSpec, Dir) -> + parse_tests(TestSpec, Dir, []). --endif. +parse_tests([{json, Path}|Rest], Dir, Acc) when is_list(Path) -> + case file:read_file(Dir ++ "/" ++ Path) of + {ok, Bin} -> parse_tests(Rest, Dir, [{json, Bin}] ++ Acc) + ; _ -> erlang:error(badarg) + end; +parse_tests([KV|Rest], Dir, Acc) -> + parse_tests(Rest, Dir, [KV] ++ Acc); +parse_tests([], _Dir, Acc) -> + Acc. + + +decoder_tests([Test|Rest], Encoding, Acc) -> + Name = lists:flatten(proplists:get_value(name, Test) ++ "::" ++ io_lib:format("~p", [Encoding])), + JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), + JSX = proplists:get_value(jsx, Test), + Flags = proplists:get_value(jsx_flags, Test, []), + decoder_tests(Rest, + Encoding, + [{"incremental " ++ Name, ?_assert(incremental_decode(JSON, Flags) =:= JSX)}] + ++ [{Name, ?_assert(decode(JSON, Flags) =:= JSX)}] + ++ Acc + ); +decoder_tests([], _Encoding, Acc) -> + io:format("~p~n", [Acc]), + Acc. + + +decode(JSON, Flags) -> + P = jsx:parser(Flags), + decode_loop(P(JSON), []). + +decode_loop({event, end_json, _Next}, Acc) -> + lists:reverse([end_json] ++ Acc); +decode_loop({incomplete, More}, Acc) -> + decode_loop(More(end_stream), Acc); +decode_loop({event, E, Next}, Acc) -> + decode_loop(Next(), [E] ++ Acc). + + +incremental_decode(<>, Flags) -> + P = jsx:parser(Flags), + incremental_decode_loop(P(C), Rest, []). + +incremental_decode_loop({incomplete, Next}, <<>>, Acc) -> + incremental_decode_loop(Next(end_stream), <<>>, Acc); +incremental_decode_loop({incomplete, Next}, <>, Acc) -> + incremental_decode_loop(Next(C), Rest, Acc); +incremental_decode_loop({event, end_json, _Next}, _Rest, Acc) -> + lists:reverse([end_json] ++ Acc); +incremental_decode_loop({event, Event, Next}, Rest, Acc) -> + incremental_decode_loop(Next(), Rest, [Event] ++ Acc). + +-endif. \ No newline at end of file diff --git a/src/jsx_eep0018.erl b/src/jsx_eep0018.erl index 4c4a711..bd2d604 100644 --- a/src/jsx_eep0018.erl +++ b/src/jsx_eep0018.erl @@ -404,13 +404,13 @@ key_repeats(_Key, []) -> false. %% eunit tests -ifdef(test). -jsx_escape_test_() -> +escape_test_() -> [ {"json string escaping", ?_assert(json_escape(<<"\"\\\b\f\n\r\t">>) =:= <<"\\\"\\\\\\b\\f\\n\\r\\t">>)}, {"json string hex escape", ?_assert(json_escape(<<1, 2, 3, 11, 26, 30, 31>>) =:= <<"\\u0001\\u0002\\u0003\\u000b\\u001a\\u001e\\u001f">>)} ]. -jsx_nice_decimal_test_() -> +nice_decimal_test_() -> [ {"0.0", ?_assert(float_to_decimal(0.0) =:= "0.0")}, {"1.0", ?_assert(float_to_decimal(1.0) =:= "1.0")}, @@ -428,7 +428,7 @@ jsx_nice_decimal_test_() -> {"max denormalized float", ?_assert(float_to_decimal((1 - math:pow(2, -52)) * math:pow(2, -1022)) =:= "2.225073858507201e-308")} ]. -jsx_key_repeats_test_() -> +key_repeats_test_() -> [ {"encoded key repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"key">>}, {key, <<"trailing key">>}]) =:= true)}, {"encoded key no repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"trailing key">>}]) =:= false)}, diff --git a/src/jsx_test.erl b/src/jsx_test.erl new file mode 100644 index 0000000..3cdbe41 --- /dev/null +++ b/src/jsx_test.erl @@ -0,0 +1,140 @@ +%% The MIT License + +%% Copyright (c) 2010 Alisdair Sullivan + +%% 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. + + +-module(jsx_test). +-author("alisdairsullivan@yahoo.ca"). + +-export([test/0]). + +-ifdef(test). +-include_lib("eunit/include/eunit.hrl"). +-endif. + + +%% if not compiled with test support + +-ifndef(test). + +test() -> erlang:error(notest). + +-else. + + + +jsx_decoder_test_() -> + jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}]). + +jsx_decoder_gen([Test|Rest], []) -> + jsx_decoder_gen(Rest, [utf8, utf16, {utf16, little}, utf32, {utf32, little}]); +jsx_decoder_gen([], _) -> + []; +jsx_decoder_gen([Test|Rest] = Tests, [Encoding|Encodings]) -> + Name = lists:flatten(proplists:get_value(name, Test) ++ " :: " ++ io_lib:format("~p", [Encoding])), + JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), + JSX = proplists:get_value(jsx, Test), + Flags = proplists:get_value(jsx_flags, Test, []), + {generator, + fun() -> + [{Name, ?_assert(decode(JSON, Flags) =:= JSX)} | jsx_decoder_gen(Tests, Encodings)] + end + }. + + +load_tests(Path) -> + %% search the specified directory for any files with the .test ending + TestSpecs = filelib:wildcard("*.test", Path), + load_tests(TestSpecs, Path, []). + +load_tests([], _Dir, Acc) -> + lists:reverse(Acc); +load_tests([Test|Rest], Dir, Acc) -> + %% should alert about badly formed tests eventually, but for now just skip over them + case file:consult(Dir ++ "/" ++ Test) of + {ok, TestSpec} -> + try + ParsedTest = parse_tests(TestSpec, Dir), + load_tests(Rest, Dir, [ParsedTest] ++ Acc) + catch _:_ -> + load_tests(Rest, Dir, Acc) + end + ; {error, _Reason} -> + load_tests(Rest, Dir, Acc) + end. + + +parse_tests(TestSpec, Dir) -> + parse_tests(TestSpec, Dir, []). + +parse_tests([{json, Path}|Rest], Dir, Acc) when is_list(Path) -> + case file:read_file(Dir ++ "/" ++ Path) of + {ok, Bin} -> parse_tests(Rest, Dir, [{json, Bin}] ++ Acc) + ; _ -> erlang:error(badarg) + end; +parse_tests([KV|Rest], Dir, Acc) -> + parse_tests(Rest, Dir, [KV] ++ Acc); +parse_tests([], _Dir, Acc) -> + Acc. + + +decoder_tests([Test|Rest], Encoding, Acc) -> + Name = lists:flatten(proplists:get_value(name, Test) ++ "::" ++ io_lib:format("~p", [Encoding])), + JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), + JSX = proplists:get_value(jsx, Test), + Flags = proplists:get_value(jsx_flags, Test, []), + decoder_tests(Rest, + Encoding, + [{"incremental " ++ Name, ?_assert(incremental_decode(JSON, Flags) =:= JSX)}] + ++ [{Name, ?_assert(decode(JSON, Flags) =:= JSX)}] + ++ Acc + ); +decoder_tests([], _Encoding, Acc) -> + io:format("~p~n", [Acc]), + Acc. + + +decode(JSON, Flags) -> + P = jsx:parser(Flags), + decode_loop(P(JSON), []). + +decode_loop({event, end_json, _Next}, Acc) -> + lists:reverse([end_json] ++ Acc); +decode_loop({incomplete, More}, Acc) -> + decode_loop(More(end_stream), Acc); +decode_loop({event, E, Next}, Acc) -> + decode_loop(Next(), [E] ++ Acc). + + +incremental_decode(<>, Flags) -> + P = jsx:parser(Flags), + incremental_decode_loop(P(C), Rest, []). + +incremental_decode_loop({incomplete, Next}, <<>>, Acc) -> + incremental_decode_loop(Next(end_stream), <<>>, Acc); +incremental_decode_loop({incomplete, Next}, <>, Acc) -> + incremental_decode_loop(Next(C), Rest, Acc); +incremental_decode_loop({event, end_json, _Next}, _Rest, Acc) -> + lists:reverse([end_json] ++ Acc); +incremental_decode_loop({event, Event, Next}, Rest, Acc) -> + incremental_decode_loop(Next(), Rest, [Event] ++ Acc). + +-endif. \ No newline at end of file diff --git a/src/jsx_utf16.erl b/src/jsx_utf16.erl index 8eca30e..e79697d 100644 --- a/src/jsx_utf16.erl +++ b/src/jsx_utf16.erl @@ -1,4 +1,4 @@ --file("priv/jsx_decoder.erl", 1). +-file("priv/jsx_decoder_template.erl", 1). -module(jsx_utf16). @@ -8,7 +8,7 @@ -file("./include/jsx_decoder.hrl", 1). --file("priv/jsx_decoder.erl", 38). +-file("priv/jsx_decoder_template.erl", 35). -file("./include/jsx_types.hrl", 1). @@ -111,7 +111,7 @@ | indent | {output_encoding, supported_utf()}. --file("priv/jsx_decoder.erl", 39). +-file("priv/jsx_decoder_template.erl", 36). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). diff --git a/src/jsx_utf16le.erl b/src/jsx_utf16le.erl index 94c9b5b..938fe8a 100644 --- a/src/jsx_utf16le.erl +++ b/src/jsx_utf16le.erl @@ -1,4 +1,4 @@ --file("priv/jsx_decoder.erl", 1). +-file("priv/jsx_decoder_template.erl", 1). -module(jsx_utf16le). @@ -8,7 +8,7 @@ -file("./include/jsx_decoder.hrl", 1). --file("priv/jsx_decoder.erl", 38). +-file("priv/jsx_decoder_template.erl", 35). -file("./include/jsx_types.hrl", 1). @@ -111,7 +111,7 @@ | indent | {output_encoding, supported_utf()}. --file("priv/jsx_decoder.erl", 39). +-file("priv/jsx_decoder_template.erl", 36). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). diff --git a/src/jsx_utf32.erl b/src/jsx_utf32.erl index 03f49ed..8cd573f 100644 --- a/src/jsx_utf32.erl +++ b/src/jsx_utf32.erl @@ -1,4 +1,4 @@ --file("priv/jsx_decoder.erl", 1). +-file("priv/jsx_decoder_template.erl", 1). -module(jsx_utf32). @@ -8,7 +8,7 @@ -file("./include/jsx_decoder.hrl", 1). --file("priv/jsx_decoder.erl", 38). +-file("priv/jsx_decoder_template.erl", 35). -file("./include/jsx_types.hrl", 1). @@ -111,7 +111,7 @@ | indent | {output_encoding, supported_utf()}. --file("priv/jsx_decoder.erl", 39). +-file("priv/jsx_decoder_template.erl", 36). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). diff --git a/src/jsx_utf32le.erl b/src/jsx_utf32le.erl index ed8ac4f..07db008 100644 --- a/src/jsx_utf32le.erl +++ b/src/jsx_utf32le.erl @@ -1,4 +1,4 @@ --file("priv/jsx_decoder.erl", 1). +-file("priv/jsx_decoder_template.erl", 1). -module(jsx_utf32le). @@ -8,7 +8,7 @@ -file("./include/jsx_decoder.hrl", 1). --file("priv/jsx_decoder.erl", 38). +-file("priv/jsx_decoder_template.erl", 35). -file("./include/jsx_types.hrl", 1). @@ -111,7 +111,7 @@ | indent | {output_encoding, supported_utf()}. --file("priv/jsx_decoder.erl", 39). +-file("priv/jsx_decoder_template.erl", 36). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). diff --git a/src/jsx_utf8.erl b/src/jsx_utf8.erl index 6bf2ef3..9b6bf58 100644 --- a/src/jsx_utf8.erl +++ b/src/jsx_utf8.erl @@ -1,4 +1,4 @@ --file("priv/jsx_decoder.erl", 1). +-file("priv/jsx_decoder_template.erl", 1). -module(jsx_utf8). @@ -8,7 +8,7 @@ -file("./include/jsx_decoder.hrl", 1). --file("priv/jsx_decoder.erl", 38). +-file("priv/jsx_decoder_template.erl", 35). -file("./include/jsx_types.hrl", 1). @@ -111,7 +111,7 @@ | indent | {output_encoding, supported_utf()}. --file("priv/jsx_decoder.erl", 39). +-file("priv/jsx_decoder_template.erl", 36). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). diff --git a/test/cases/absurdly_deep_array.test b/test/cases/absurdly_deep_array.test index cbc66ce..8d51dcb 100644 --- a/test/cases/absurdly_deep_array.test +++ b/test/cases/absurdly_deep_array.test @@ -1 +1,1550 @@ -[start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_json]. \ No newline at end of file +{name, "absurdly_deep_array"}. +{jsx, [start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,start_array,start_array,start_array,start_array, + start_array,start_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_array,end_array,end_array, + end_array,end_array,end_array,end_array,end_json]}. +{json, "absurdly_deep_array.json"}. diff --git a/test/cases/array.test b/test/cases/array.test index b39b901..8b86574 100644 --- a/test/cases/array.test +++ b/test/cases/array.test @@ -1 +1,29 @@ -[start_array, {string, "foo"}, {string, "bar"}, {string, "baz"}, start_array, {literal, true}, end_array, start_array, {literal, false}, end_array, start_array, {literal, null}, end_array, {literal, true}, {literal, false}, {literal, null}, {float, "0.7"}, start_object, {key, "key"}, {string, "value"}, end_object, start_array, start_object, end_object, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, end_array, {string, "\n\r\\"}, start_array, {integer, "-1"}, end_array, end_array, end_json]. \ No newline at end of file +{name, "array"}. +{jsx, [start_array, + {string,"foo"}, + {string,"bar"}, + {string,"baz"}, + start_array, + {literal,true}, + end_array,start_array, + {literal,false}, + end_array,start_array, + {literal,null}, + end_array, + {literal,true}, + {literal,false}, + {literal,null}, + {float,"0.7"}, + start_object, + {key,"key"}, + {string,"value"}, + end_object,start_array,start_object,end_object, + {literal,null}, + {literal,null}, + {literal,null}, + start_array,end_array,end_array, + {string,"\n\r\\"}, + start_array, + {integer,"-1"}, + end_array,end_array,end_json]}. +{json, "array.json"}. diff --git a/test/cases/comments.test b/test/cases/comments.test index 4bcfaba..c684eaf 100644 --- a/test/cases/comments.test +++ b/test/cases/comments.test @@ -1,3 +1,14 @@ -[start_array, {string, "a string"}, {integer, "1"}, start_object, {key, "key"}, start_array, end_array, {key, "another key"}, {integer, "0"}, end_object, {literal, true}, end_array, end_json]. - -[{comments, true}]. \ No newline at end of file +{name, "comments"}. +{jsx, [start_array, + {string,"a string"}, + {integer,"1"}, + start_object, + {key,"key"}, + start_array,end_array, + {key,"another key"}, + {integer,"0"}, + end_object, + {literal,true}, + end_array,end_json]}. +{json, "comments.json"}. +{jsx_flags, [{comments,true}]}. diff --git a/test/cases/deep_array.test b/test/cases/deep_array.test index b7d2133..1933fac 100644 --- a/test/cases/deep_array.test +++ b/test/cases/deep_array.test @@ -1 +1,3 @@ -[start_array, start_array, start_array, end_array, end_array, end_array, end_json]. \ No newline at end of file +{name, "deep_array"}. +{jsx, [start_array,start_array,start_array,end_array,end_array,end_array,end_json]}. +{json, "deep_array.json"}. diff --git a/test/cases/empty_array.test b/test/cases/empty_array.test index 784f288..e538683 100644 --- a/test/cases/empty_array.test +++ b/test/cases/empty_array.test @@ -1 +1,3 @@ -[start_array, end_array, end_json]. \ No newline at end of file +{name, "empty_array"}. +{jsx, [start_array,end_array,end_json]}. +{json, "empty_array.json"}. diff --git a/test/cases/empty_array_with_comment.test b/test/cases/empty_array_with_comment.test index 7b9a2f7..086831b 100644 --- a/test/cases/empty_array_with_comment.test +++ b/test/cases/empty_array_with_comment.test @@ -1,3 +1,4 @@ -[start_array, end_array, end_json]. - -[{comments, true}]. \ No newline at end of file +{name, "empty_array_with_comment"}. +{jsx, [start_array,end_array,end_json]}. +{json, "empty_array_with_comment.json"}. +{jsx_flags, [{comments,true}]}. diff --git a/test/cases/empty_object.test b/test/cases/empty_object.test index d9fd5e6..0c985ab 100644 --- a/test/cases/empty_object.test +++ b/test/cases/empty_object.test @@ -1 +1,3 @@ -[start_object, end_object, end_json]. \ No newline at end of file +{name, "empty_object"}. +{jsx, [start_object,end_object,end_json]}. +{json, "empty_object.json"}. diff --git a/test/cases/empty_object_with_comment.test b/test/cases/empty_object_with_comment.test index 3780f2f..09e47d9 100644 --- a/test/cases/empty_object_with_comment.test +++ b/test/cases/empty_object_with_comment.test @@ -1,3 +1,4 @@ -[start_object, end_object, end_json]. - -[{comments, true}]. \ No newline at end of file +{name, "empty_object_with_comment"}. +{jsx, [start_object,end_object,end_json]}. +{json, "empty_object_with_comment.json"}. +{jsx_flags, [{comments,true}]}. diff --git a/test/cases/encoded_surrogates.test b/test/cases/encoded_surrogates.test index a8202ce..0e938ed 100644 --- a/test/cases/encoded_surrogates.test +++ b/test/cases/encoded_surrogates.test @@ -1,3 +1,4 @@ -[start_array, {string, [66560]}, end_array, end_json]. - -[{escaped_unicode, codepoint}]. \ No newline at end of file +{name, "encoded_surrogates"}. +{jsx, [start_array,{string,[66560]},end_array,end_json]}. +{json, "encoded_surrogates.json"}. +{jsx_flags, [{escaped_unicode,codepoint}]}. diff --git a/test/cases/exp.test b/test/cases/exp.test index bed91a3..a79a0e8 100644 --- a/test/cases/exp.test +++ b/test/cases/exp.test @@ -1,3 +1,15 @@ -[start_array, start_array, {float, "2.0e7"}, end_array, {float, "2.0e7"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, {float, "4.2e70"}, end_array, end_json]. - -[{comments, true}]. \ No newline at end of file +{name, "exp"}. +{jsx, [start_array,start_array, + {float,"2.0e7"}, + end_array, + {float,"2.0e7"}, + start_object, + {key,"key"}, + {float,"2.0e7"}, + {key,"another key"}, + {float,"2.0e7"}, + end_object, + {float,"4.2e70"}, + end_array,end_json]}. +{json, "exp.json"}. +{jsx_flags, [{comments,true}]}. diff --git a/test/cases/fraction.test b/test/cases/fraction.test index fbbaa0f..6f3aa73 100644 --- a/test/cases/fraction.test +++ b/test/cases/fraction.test @@ -1,3 +1,20 @@ -[start_array, start_array, {float, "2.0"}, end_array, {float, "2.0"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, start_object, {key, "key"}, {float, "2.0"}, {key, "another key"}, {float, "2.0"}, end_object, {float, "4.2"}, end_array, end_json]. - -[{comments, true}]. \ No newline at end of file +{name, "fraction"}. +{jsx, [start_array,start_array, + {float,"2.0"}, + end_array, + {float,"2.0"}, + start_object, + {key,"key"}, + {float,"2.0e7"}, + {key,"another key"}, + {float,"2.0e7"}, + end_object,start_object, + {key,"key"}, + {float,"2.0"}, + {key,"another key"}, + {float,"2.0"}, + end_object, + {float,"4.2"}, + end_array,end_json]}. +{json, "fraction.json"}. +{jsx_flags, [{comments,true}]}. diff --git a/test/cases/integer.json b/test/cases/integer.json index 6474285..616cb6b 100644 --- a/test/cases/integer.json +++ b/test/cases/integer.json @@ -1 +1 @@ -[[20], 20, {"key":20, "another key":20}, 42 ] \ No newline at end of file +[[20], 20, {"key":20, "another key":20}, 42/*a comment*/ ] \ No newline at end of file diff --git a/test/cases/integer.test b/test/cases/integer.test index bd3f7b7..b5dbc27 100644 --- a/test/cases/integer.test +++ b/test/cases/integer.test @@ -1 +1,15 @@ -[start_array, start_array, {integer, "20"}, end_array, {integer, "20"}, start_object, {key, "key"}, {integer, "20"}, {key, "another key"}, {integer, "20"}, end_object, {integer, "42"}, end_array, end_json]. \ No newline at end of file +{name, "integer"}. +{jsx, [start_array,start_array, + {integer,"20"}, + end_array, + {integer,"20"}, + start_object, + {key,"key"}, + {integer,"20"}, + {key,"another key"}, + {integer,"20"}, + end_object, + {integer,"42"}, + end_array,end_json]}. +{json, "integer.json"}. +{jsx_flags, [{comments,true}]}. diff --git a/test/cases/multibyte_utf.test b/test/cases/multibyte_utf.test index b1b9570..6a9217e 100644 --- a/test/cases/multibyte_utf.test +++ b/test/cases/multibyte_utf.test @@ -1 +1,3 @@ -[start_array,{string,[32, 119070, 32]},end_array,end_json]. \ No newline at end of file +{name, "multibyte_utf"}. +{jsx, [start_array,{string,[32,119070,32]},end_array,end_json]}. +{json, "multibyte_utf.json"}. diff --git a/test/cases/naked_false.test b/test/cases/naked_false.test index 4ec7cdd..5db57a1 100644 --- a/test/cases/naked_false.test +++ b/test/cases/naked_false.test @@ -1 +1,3 @@ -[{literal, false}, end_json]. \ No newline at end of file +{name, "naked_false"}. +{jsx, [{literal,false},end_json]}. +{json, "naked_false.json"}. diff --git a/test/cases/naked_null.test b/test/cases/naked_null.test index 0615c59..7386eaf 100644 --- a/test/cases/naked_null.test +++ b/test/cases/naked_null.test @@ -1 +1,3 @@ -[{literal, null}, end_json]. \ No newline at end of file +{name, "naked_null"}. +{jsx, [{literal,null},end_json]}. +{json, "naked_null.json"}. diff --git a/test/cases/naked_number_a.test b/test/cases/naked_number_a.test index 0a3bef1..74baa86 100644 --- a/test/cases/naked_number_a.test +++ b/test/cases/naked_number_a.test @@ -1 +1,3 @@ -[{integer, "42"}, end_json]. \ No newline at end of file +{name, "naked_number_a"}. +{jsx, [{integer,"42"},end_json]}. +{json, "naked_number_a.json"}. diff --git a/test/cases/naked_number_b.test b/test/cases/naked_number_b.test index b63cbac..586dca2 100644 --- a/test/cases/naked_number_b.test +++ b/test/cases/naked_number_b.test @@ -1 +1,3 @@ -[{integer, "-42"}, end_json]. \ No newline at end of file +{name, "naked_number_b"}. +{jsx, [{integer,"-42"},end_json]}. +{json, "naked_number_b.json"}. diff --git a/test/cases/naked_number_c.test b/test/cases/naked_number_c.test index 8b2a4d6..4fddb7f 100644 --- a/test/cases/naked_number_c.test +++ b/test/cases/naked_number_c.test @@ -1 +1,3 @@ -[{float, "-0.7"}, end_json]. \ No newline at end of file +{name, "naked_number_c"}. +{jsx, [{float,"-0.7"},end_json]}. +{json, "naked_number_c.json"}. diff --git a/test/cases/naked_number_d.test b/test/cases/naked_number_d.test index 780ed9b..27923d6 100644 --- a/test/cases/naked_number_d.test +++ b/test/cases/naked_number_d.test @@ -1 +1,3 @@ -[{float, "0.7"}, end_json]. \ No newline at end of file +{name, "naked_number_d"}. +{jsx, [{float,"0.7"},end_json]}. +{json, "naked_number_d.json"}. diff --git a/test/cases/naked_number_e.test b/test/cases/naked_number_e.test index b67cf55..70d591c 100644 --- a/test/cases/naked_number_e.test +++ b/test/cases/naked_number_e.test @@ -1 +1,3 @@ -[{integer, "0"}, end_json]. \ No newline at end of file +{name, "naked_number_e"}. +{jsx, [{integer,"0"},end_json]}. +{json, "naked_number_e.json"}. diff --git a/test/cases/naked_number_f.test b/test/cases/naked_number_f.test index 72f1272..e8a585d 100644 --- a/test/cases/naked_number_f.test +++ b/test/cases/naked_number_f.test @@ -1 +1,3 @@ -[{float, "1.0e100"}, end_json]. \ No newline at end of file +{name, "naked_number_f"}. +{jsx, [{float,"1.0e100"},end_json]}. +{json, "naked_number_f.json"}. diff --git a/test/cases/naked_number_g.test b/test/cases/naked_number_g.test index 89c3124..e795558 100644 --- a/test/cases/naked_number_g.test +++ b/test/cases/naked_number_g.test @@ -1 +1,3 @@ -[{integer, "7"}, end_json]. \ No newline at end of file +{name, "naked_number_g"}. +{jsx, [{integer,"7"},end_json]}. +{json, "naked_number_g.json"}. diff --git a/test/cases/naked_string.test b/test/cases/naked_string.test index 831ad7f..3ce5c36 100644 --- a/test/cases/naked_string.test +++ b/test/cases/naked_string.test @@ -1 +1,3 @@ -[{string, "this is a naked string"}, end_json]. \ No newline at end of file +{name, "naked_string"}. +{jsx, [{string,"this is a naked string"},end_json]}. +{json, "naked_string.json"}. diff --git a/test/cases/naked_true.test b/test/cases/naked_true.test index 3055bd6..924a200 100644 --- a/test/cases/naked_true.test +++ b/test/cases/naked_true.test @@ -1 +1,3 @@ -[{literal, true}, end_json]. \ No newline at end of file +{name, "naked_true"}. +{jsx, [{literal,true},end_json]}. +{json, "naked_true.json"}. diff --git a/test/cases/negative_zero.test b/test/cases/negative_zero.test index 3c7b3ba..db4ca8d 100644 --- a/test/cases/negative_zero.test +++ b/test/cases/negative_zero.test @@ -1 +1,14 @@ -[start_array, start_array, {integer, "-0"}, end_array, {integer, "-0"}, start_object, {key, "key"}, {integer, "-0"}, {key, "another key"}, {integer, "-0"}, end_object, {integer, "-0"}, end_array, end_json]. \ No newline at end of file +{name, "negative_zero"}. +{jsx, [start_array,start_array, + {integer,"-0"}, + end_array, + {integer,"-0"}, + start_object, + {key,"key"}, + {integer,"-0"}, + {key,"another key"}, + {integer,"-0"}, + end_object, + {integer,"-0"}, + end_array,end_json]}. +{json, "negative_zero.json"}. diff --git a/test/cases/numbers.test b/test/cases/numbers.test index ebdc0e4..6ac82bc 100644 --- a/test/cases/numbers.test +++ b/test/cases/numbers.test @@ -1 +1,23 @@ -[ start_array, {integer, "1"}, {integer, "2"}, {integer, "3"}, {integer, "4"}, {integer, "5"}, {integer, "6"}, {integer, "7"}, {integer, "8"}, {integer, "9"}, {integer, "42"}, {integer, "127"}, {integer, "99999999999999999999999999999"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.325e478534"}, {integer, "-1"}, {float, "-1.0e-1"}, {float, "3.7e-57834235"}, end_array, end_json]. \ No newline at end of file +{name, "numbers"}. +{jsx, [start_array, + {integer,"1"}, + {integer,"2"}, + {integer,"3"}, + {integer,"4"}, + {integer,"5"}, + {integer,"6"}, + {integer,"7"}, + {integer,"8"}, + {integer,"9"}, + {integer,"42"}, + {integer,"127"}, + {integer,"99999999999999999999999999999"}, + {float,"1.0e1"}, + {float,"1.0e1"}, + {float,"1.0e1"}, + {float,"1.325e478534"}, + {integer,"-1"}, + {float,"-1.0e-1"}, + {float,"3.7e-57834235"}, + end_array,end_json]}. +{json, "numbers.json"}. diff --git a/test/cases/object.test b/test/cases/object.test index ec87660..b9b50d4 100644 --- a/test/cases/object.test +++ b/test/cases/object.test @@ -1 +1,22 @@ -[start_object, {key, "foo"}, {string, "bar"}, {key, "baz"}, {literal, true}, {key, "false"}, {literal, null}, {key, "object"}, start_object, {key, "key"}, {string, "value"}, end_object, {key, "list"}, start_array, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, {string, "\n\r\\"}, end_array, end_object, end_json]. \ No newline at end of file +{name, "object"}. +{jsx, [start_object, + {key,"foo"}, + {string,"bar"}, + {key,"baz"}, + {literal,true}, + {key,"false"}, + {literal,null}, + {key,"object"}, + start_object, + {key,"key"}, + {string,"value"}, + end_object, + {key,"list"}, + start_array, + {literal,null}, + {literal,null}, + {literal,null}, + start_array,end_array, + {string,"\n\r\\"}, + end_array,end_object,end_json]}. +{json, "object.json"}. diff --git a/test/cases/string.test b/test/cases/string.test index 2cc5071..8df9aa5 100644 --- a/test/cases/string.test +++ b/test/cases/string.test @@ -1 +1,5 @@ -[start_array, {string, "this is a random string with \n embedded escapes in it"}, end_array, end_json]. \ No newline at end of file +{name, "string"}. +{jsx, [start_array, + {string,"this is a random string with \n embedded escapes in it"}, + end_array,end_json]}. +{json, "string.json"}. diff --git a/test/cases/string_escapes.test b/test/cases/string_escapes.test index 704af35..e33a903 100644 --- a/test/cases/string_escapes.test +++ b/test/cases/string_escapes.test @@ -1,3 +1,12 @@ -[start_array, {string, "\""}, {string, "\\"}, {string, "/"}, {string, "\b"}, {string, "\f"}, {string, "\n"}, {string, "\r"}, {string, "\t"}, end_array, end_json]. - - +{name, "string_escapes"}. +{jsx, [start_array, + {string,"\""}, + {string,"\\"}, + {string,"/"}, + {string,"\b"}, + {string,"\f"}, + {string,"\n"}, + {string,"\r"}, + {string,"\t"}, + end_array,end_json]}. +{json, "string_escapes.json"}. diff --git a/test/cases/unicode_to_codepoint.test b/test/cases/unicode_to_codepoint.test index 69581ec..649ecd5 100644 --- a/test/cases/unicode_to_codepoint.test +++ b/test/cases/unicode_to_codepoint.test @@ -1,3 +1,7 @@ -[start_array, {string, "arabic letter alef: "}, {string, [16#0627]}, end_array, end_json]. - -[{escaped_unicode, codepoint}]. \ No newline at end of file +{name, "unicode_to_codepoint"}. +{jsx, [start_array, + {string,"arabic letter alef: "}, + {string,[1575]}, + end_array,end_json]}. +{json, "unicode_to_codepoint.json"}. +{jsx_flags, [{escaped_unicode,codepoint}]}. diff --git a/test/cases/unicode_unconverted.test b/test/cases/unicode_unconverted.test index aa53cbf..9713a0f 100644 --- a/test/cases/unicode_unconverted.test +++ b/test/cases/unicode_unconverted.test @@ -1,3 +1,7 @@ -[start_array, {string, "arabic letter alef: "}, {string, "\\u0627"}, end_array, end_json]. - -[{escaped_unicode, ascii}]. \ No newline at end of file +{name, "unicode_unconverted"}. +{jsx, [start_array, + {string,"arabic letter alef: "}, + {string,"\\u0627"}, + end_array,end_json]}. +{json, "unicode_unconverted.json"}. +{jsx_flags, [{escaped_unicode,ascii}]}. diff --git a/test/cases/whitespace.test b/test/cases/whitespace.test index df1daa6..2f65d73 100644 --- a/test/cases/whitespace.test +++ b/test/cases/whitespace.test @@ -1 +1,3 @@ -[start_array, {float, "0.3"}, end_array, end_json]. +{name, "whitespace"}. +{jsx, [start_array,{float,"0.3"},end_array,end_json]}. +{json, "whitespace.json"}. diff --git a/test/cases/zero.test b/test/cases/zero.test index 3ff89d2..85e626a 100644 --- a/test/cases/zero.test +++ b/test/cases/zero.test @@ -1 +1,14 @@ -[start_array, start_array, {integer, "0"}, end_array, {integer, "0"}, start_object, {key, "key"}, {integer, "0"}, {key, "another key"}, {integer, "0"}, end_object, {integer, "0"}, end_array, end_json]. \ No newline at end of file +{name, "zero"}. +{jsx, [start_array,start_array, + {integer,"0"}, + end_array, + {integer,"0"}, + start_object, + {key,"key"}, + {integer,"0"}, + {key,"another key"}, + {integer,"0"}, + end_object, + {integer,"0"}, + end_array,end_json]}. +{json, "zero.json"}. From 55540969a63fd53b875a60efc01f28a423245056 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 10 Aug 2010 11:52:18 -0700 Subject: [PATCH 11/17] small modification to jsx_test --- src/jsx_test.erl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/jsx_test.erl b/src/jsx_test.erl index 3cdbe41..31e445b 100644 --- a/src/jsx_test.erl +++ b/src/jsx_test.erl @@ -24,7 +24,9 @@ -module(jsx_test). -author("alisdairsullivan@yahoo.ca"). +-ifndef(test). -export([test/0]). +-endif. -ifdef(test). -include_lib("eunit/include/eunit.hrl"). @@ -39,16 +41,17 @@ test() -> erlang:error(notest). -else. - +fake_test_() -> + [ {"fake test", ?_assert(true)} ]. jsx_decoder_test_() -> jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}]). -jsx_decoder_gen([Test|Rest], []) -> +jsx_decoder_gen([_Test|Rest], []) -> jsx_decoder_gen(Rest, [utf8, utf16, {utf16, little}, utf32, {utf32, little}]); jsx_decoder_gen([], _) -> []; -jsx_decoder_gen([Test|Rest] = Tests, [Encoding|Encodings]) -> +jsx_decoder_gen([Test|_] = Tests, [Encoding|Encodings]) -> Name = lists:flatten(proplists:get_value(name, Test) ++ " :: " ++ io_lib:format("~p", [Encoding])), JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), JSX = proplists:get_value(jsx, Test), From d73ce1eae8008cb05cf69bd49117b3d9984a6389 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 10 Aug 2010 12:31:05 -0700 Subject: [PATCH 12/17] removed superfluous tests --- src/jsx.erl | 97 ++--------------------------------------------------- 1 file changed, 2 insertions(+), 95 deletions(-) diff --git a/src/jsx.erl b/src/jsx.erl index b414d59..34f110e 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -35,10 +35,6 @@ %% types for function specifications -include("./include/jsx_types.hrl"). --ifdef(test). --include_lib("eunit/include/eunit.hrl"). --endif. - %% opts record -record(opts, { @@ -49,6 +45,7 @@ }). + -spec parser() -> jsx_parser(). -spec parser(Opts::jsx_opts()) -> jsx_parser(). @@ -212,94 +209,4 @@ detect_encoding(Bin, Opts) -> fun(end_stream) -> {error, badjson} ; (Stream) -> detect_encoding(<>, Opts) end - }. - -%% eunit tests --ifdef(test). - -jsx_decoder_test_() -> - lists:map(fun(Encoding) -> - decoder_tests(load_tests("./test/cases"), Encoding, []) - end, - [utf8, utf16, {utf16, little}, utf32, {utf32, little}] - ). - - -load_tests(Path) -> - %% search the specified directory for any files with the .test ending - TestSpecs = filelib:wildcard("*.test", Path), - load_tests(TestSpecs, Path, []). - -load_tests([], _Dir, Acc) -> - lists:reverse(Acc); -load_tests([Test|Rest], Dir, Acc) -> - %% should alert about badly formed tests eventually, but for now just skip over them - case file:consult(Dir ++ "/" ++ Test) of - {ok, TestSpec} -> - try - ParsedTest = parse_tests(TestSpec, Dir), - load_tests(Rest, Dir, [ParsedTest] ++ Acc) - catch _:_ -> - load_tests(Rest, Dir, Acc) - end - ; {error, _Reason} -> - load_tests(Rest, Dir, Acc) - end. - - -parse_tests(TestSpec, Dir) -> - parse_tests(TestSpec, Dir, []). - -parse_tests([{json, Path}|Rest], Dir, Acc) when is_list(Path) -> - case file:read_file(Dir ++ "/" ++ Path) of - {ok, Bin} -> parse_tests(Rest, Dir, [{json, Bin}] ++ Acc) - ; _ -> erlang:error(badarg) - end; -parse_tests([KV|Rest], Dir, Acc) -> - parse_tests(Rest, Dir, [KV] ++ Acc); -parse_tests([], _Dir, Acc) -> - Acc. - - -decoder_tests([Test|Rest], Encoding, Acc) -> - Name = lists:flatten(proplists:get_value(name, Test) ++ "::" ++ io_lib:format("~p", [Encoding])), - JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), - JSX = proplists:get_value(jsx, Test), - Flags = proplists:get_value(jsx_flags, Test, []), - decoder_tests(Rest, - Encoding, - [{"incremental " ++ Name, ?_assert(incremental_decode(JSON, Flags) =:= JSX)}] - ++ [{Name, ?_assert(decode(JSON, Flags) =:= JSX)}] - ++ Acc - ); -decoder_tests([], _Encoding, Acc) -> - io:format("~p~n", [Acc]), - Acc. - - -decode(JSON, Flags) -> - P = jsx:parser(Flags), - decode_loop(P(JSON), []). - -decode_loop({event, end_json, _Next}, Acc) -> - lists:reverse([end_json] ++ Acc); -decode_loop({incomplete, More}, Acc) -> - decode_loop(More(end_stream), Acc); -decode_loop({event, E, Next}, Acc) -> - decode_loop(Next(), [E] ++ Acc). - - -incremental_decode(<>, Flags) -> - P = jsx:parser(Flags), - incremental_decode_loop(P(C), Rest, []). - -incremental_decode_loop({incomplete, Next}, <<>>, Acc) -> - incremental_decode_loop(Next(end_stream), <<>>, Acc); -incremental_decode_loop({incomplete, Next}, <>, Acc) -> - incremental_decode_loop(Next(C), Rest, Acc); -incremental_decode_loop({event, end_json, _Next}, _Rest, Acc) -> - lists:reverse([end_json] ++ Acc); -incremental_decode_loop({event, Event, Next}, Rest, Acc) -> - incremental_decode_loop(Next(), Rest, [Event] ++ Acc). - --endif. \ No newline at end of file + }. \ No newline at end of file From 36c322c4a63eb5993b9e962c86edc6be25a22a87 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 10 Aug 2010 13:07:16 -0700 Subject: [PATCH 13/17] added format tests --- src/jsx_format.erl | 53 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/src/jsx_format.erl b/src/jsx_format.erl index 7dac05a..a43d650 100644 --- a/src/jsx_format.erl +++ b/src/jsx_format.erl @@ -26,14 +26,19 @@ -export([format/2]). + -include("./include/jsx_types.hrl"). +-ifdef(test). +-include_lib("eunit/include/eunit.hrl"). +-endif. + -record(opts, { space = 0, indent = 0, - output_encoding = iolist, + output_encoding = utf8, strict = true }). @@ -85,11 +90,21 @@ extract_parser_opts(Opts) -> format_something({event, start_object, Next}, Opts, Level) -> - {Continue, Object} = format_object(Next(), [], Opts, Level + 1), - {Continue, [?start_object, Object, ?end_object]}; + case Next() of + {event, end_object, Continue} -> + {Continue, [?start_object, ?end_object]} + ; Event -> + {Continue, Object} = format_object(Event, [], Opts, Level + 1), + {Continue, [?start_object, Object, indent(Opts, Level), ?end_object]} + end; format_something({event, start_array, Next}, Opts, Level) -> - {Continue, Array} = format_array(Next(), [], Opts, Level + 1), - {Continue, [?start_array, Array, ?end_array]}; + case Next() of + {event, end_array, Continue} -> + {Continue, [?start_array, ?end_array]} + ; Event -> + {Continue, Object} = format_array(Event, [], Opts, Level + 1), + {Continue, [?start_array, Object, indent(Opts, Level), ?end_array]} + end; format_something({event, {Type, Value}, Next}, _Opts, _Level) -> {Next, [encode(Type, Value)]}. @@ -103,7 +118,7 @@ format_object({event, {key, Key}, Next}, Acc, Opts, Level) -> {NextNext, [Acc, indent(Opts, Level), encode(string, Key), ?colon, space(Opts), Value]} ; Else -> format_object(Else, - [Acc, indent(Opts, Level), encode(string, Key), ?colon, space(Opts), Value, ?comma], + [Acc, indent(Opts, Level), encode(string, Key), ?colon, space(Opts), Value, ?comma, space(Opts)], Opts, Level ) @@ -117,7 +132,7 @@ format_array(Event, Acc, Opts, Level) -> {event, end_array, NextNext} -> {NextNext, [Acc, indent(Opts, Level), Value]} ; Else -> - format_array(Else, [Acc, indent(Opts, Level), Value, ?comma], Opts, Level) + format_array(Else, [Acc, indent(Opts, Level), Value, ?comma, space(Opts)], Opts, Level) end. @@ -157,4 +172,26 @@ space(Opts) -> case Opts#opts.space of 0 -> [] ; X when X > 0 -> [ ?space || _ <- lists:seq(1, X) ] - end. \ No newline at end of file + end. + + +%% eunit tests + +-ifdef(test). + +minify_test_() -> + [ + {"minify object", ?_assert(format(<<" { \"key\" :\n\t \"value\"\r\r\r\n } ">>, []) =:= <<"{\"key\":\"value\"}">>)}, + {"minify array", ?_assert(format(<<" [\n\ttrue,\n\tfalse,\n\tnull\n] ">>, []) =:= <<"[true,false,null]">>)} + ]. + +opts_test_() -> + [ + {"unspecified indent/space", ?_assert(format(<<" [\n\ttrue,\n\tfalse,\n\tnull\n] ">>, [space, indent]) =:= <<"[\n true, \n false, \n null\n]">>)}, + {"specific indent/space", ?_assert(format(<<"\n{\n\"key\" : [],\n\"another key\" : true\n}\n">>, [{space, 2}, {indent, 4}]) =:= <<"{\n \"key\": [], \n \"another key\": true\n}">>)}, + {"nested structures", ?_assert(format(<<"[{\"key\":\"value\", \"another key\": \"another value\"}, [[true, false, null]]]">>, [{space, 2}, {indent, 2}]) =:= <<"[\n {\n \"key\": \"value\", \n \"another key\": \"another value\"\n }, \n [\n [\n true, \n false, \n null\n ]\n ]\n]">>)}, + {"just spaces", ?_assert(format(<<"[1,2,3]">>, [{space, 2}]) =:= <<"[1, 2, 3]">>)}, + {"just indent", ?_assert(format(<<"[1.0, 2.0, 3.0]">>, [{indent, 2}]) =:= <<"[\n 1.0,\n 2.0,\n 3.0\n]">>)} + ]. + +-endif. \ No newline at end of file From 4c3b5559d4f47b1e5e045d527ce26a79f0277164 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 10 Aug 2010 13:09:09 -0700 Subject: [PATCH 14/17] housekeeping, fixed makefile --- makefile | 5 +- test/jsx_test.escript | 166 ------------------------------------------ 2 files changed, 1 insertion(+), 170 deletions(-) delete mode 100755 test/jsx_test.escript diff --git a/makefile b/makefile index f4ec36d..10cb8ee 100644 --- a/makefile +++ b/makefile @@ -5,10 +5,7 @@ expand: ./priv/backends.escript create test: compile - ./test/jsx_test.escript test/cases - -prove: compile - prove ./test/jsx_test.escript + ./rebar eunit clean: ./rebar clean diff --git a/test/jsx_test.escript b/test/jsx_test.escript deleted file mode 100755 index a2cc9c7..0000000 --- a/test/jsx_test.escript +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env escript - -%% The MIT License - -%% Copyright (c) 2010 Alisdair Sullivan - -%% 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. - --module(jsx_test). - --export([main/1]). - --define(to_json(X, Y, N), - etap:is(jsx:term_to_json(X), Y, N) -). - --define(to_erep(X, Y, N), - etap:is(jsx:json_to_term(X), Y, N) -). - -main([]) -> - test("./test/cases"); - -main([Path]) -> - test(Path). - - -test(Dir) -> - code:add_path("ebin"), - - ValidJSONTests = load_tests(Dir), - - etap:plan((length(ValidJSONTests) * 10) + 13), - run_jsx_tests(ValidJSONTests), - - etap:is(multi_decode(multi_json_body(), []), multi_test_result(), "multi terms"), - - ?to_erep(<<"{}">>, [{}], "empty object to erep"), - ?to_json([{}], <<"{}">>, "empty object to json"), - ?to_erep(<<"[]">>, [], "empty array to erep"), - ?to_json([], <<"[]">>, "empty array to json"), - ?to_erep(<<"{ \"key\": \"value\", \"another key\": [] }">>, [{<<"key">>, <<"value">>}, {<<"another key">>, []}], "object to erep"), - ?to_json([{<<"key">>, <<"value">>}, {<<"another key">>, []}], <<"{\"key\":\"value\",\"another key\":[]}">>, "object to json"), - ?to_erep(<<"[true, 1, -0.5e7, \"hello world\"]">>, [true, 1, -0.5e7, <<"hello world">>], "array to erep"), - ?to_json([true, 1, -0.5e7, <<"hello world">>], <<"[true,1,-5000000.0,\"hello world\"]">>, "array to json"), - ?to_erep(<<"[[[]]]">>, [[[]]], "deep array to erep"), - ?to_json([[[]]], <<"[[[]]]">>, "deep array to json"), - ?to_erep(<<"{\"a\":{\"a\":{\"a\":{}}}}">>, [{<<"a">>, [{<<"a">>, [{<<"a">>, [{}]}]}]}], "deep object to erep"), - ?to_json([{<<"a">>, [{<<"a">>, [{<<"a">>, [{}]}]}]}], <<"{\"a\":{\"a\":{\"a\":{}}}}">>, "deep object to json"), - - - etap:end_tests(). - - -load_tests(Dir) -> - TestSpecs = filelib:wildcard("*.test", Dir), - load_tests(TestSpecs, Dir, []). - -load_tests([], _Dir, Acc) -> - lists:reverse(Acc); -load_tests([Test|Rest], Dir, Acc) -> - try - TestName = filename:basename(Test, ".test"), - {ok, JSON} = file:read_file(Dir ++ "/" ++ TestName ++ ".json"), - case file:consult(Dir ++ "/" ++ Test) of - {ok, [Events]} -> - load_tests(Rest, Dir, [{TestName, JSON, Events, []}] ++ Acc) - ; {ok, [Events, Flags]} -> - load_tests(Rest, Dir, [{TestName, JSON, Events, Flags}] ++ Acc) - end - catch _:_ -> load_tests(Rest, Dir, Acc) end. - -run_jsx_tests([]) -> - ok; -run_jsx_tests([{TestName, JSON, Events, Flags}|Rest]) -> - etap:is(decode(JSON, Flags), Events, TestName ++ ": utf8"), - etap:is(incremental_decode(JSON, Flags), Events, TestName ++ ": incremental utf8"), - etap:is(decode(to_utf16(JSON), Flags), Events, TestName ++ ": utf16"), - etap:is(incremental_decode(to_utf16(JSON), Flags), Events, TestName ++ ": incremental utf16"), - etap:is(decode(to_utf16le(JSON), Flags), Events, TestName ++ ": utf16le"), - etap:is(incremental_decode(to_utf16le(JSON), Flags), Events, TestName ++ ": incremental utf16le"), - etap:is(decode(to_utf32(JSON), Flags), Events, TestName ++ ": utf32"), - etap:is(incremental_decode(to_utf32(JSON), Flags), Events, TestName ++ ": incremental utf32"), - etap:is(decode(to_utf32le(JSON), Flags), Events, TestName ++ ": utf32le"), - etap:is(incremental_decode(to_utf32le(JSON), Flags), Events, TestName ++ ": incremental utf32le"), - run_jsx_tests(Rest). - - -decode(JSON, Flags) -> - P = jsx:parser(Flags), - decode_loop(P(JSON), []). - -decode_loop({event, end_json, _Next}, Acc) -> - lists:reverse([end_json] ++ Acc); -decode_loop({incomplete, More}, Acc) -> - decode_loop(More(end_stream), Acc); -decode_loop({event, E, Next}, Acc) -> - decode_loop(Next(), [E] ++ Acc). - - -incremental_decode(<>, Flags) -> - P = jsx:parser(Flags), - incremental_decode_loop(P(C), Rest, []). - -incremental_decode_loop({incomplete, Next}, <<>>, Acc) -> - incremental_decode_loop(Next(end_stream), <<>>, Acc); -incremental_decode_loop({incomplete, Next}, <>, Acc) -> - incremental_decode_loop(Next(C), Rest, Acc); -incremental_decode_loop({event, end_json, _Next}, _Rest, Acc) -> - lists:reverse([end_json] ++ Acc); -incremental_decode_loop({event, Event, Next}, Rest, Acc) -> - incremental_decode_loop(Next(), Rest, [Event] ++ Acc). - - -multi_decode(JSON, Flags) -> - P = jsx:parser(Flags ++ [{multi_term, true}]), - multi_decode_loop(P(JSON), [[]]). - -multi_decode_loop({incomplete, _Next}, [[]|Acc]) -> - lists:reverse(Acc); -multi_decode_loop({event, end_json, Next}, [S|Acc]) -> - multi_decode_loop(Next(), [[]|[lists:reverse(S)] ++ Acc]); -multi_decode_loop({event, E, Next}, [S|Acc]) -> - multi_decode_loop(Next(), [[E] ++ S] ++ Acc). - - -to_utf16(Bin) -> unicode:characters_to_binary(Bin, utf8, utf16). -to_utf16le(Bin) -> unicode:characters_to_binary(Bin, utf8, {utf16,little}). -to_utf32(Bin) -> unicode:characters_to_binary(Bin, utf8, utf32). -to_utf32le(Bin) -> unicode:characters_to_binary(Bin, utf8, {utf32,little}). - - -multi_json_body() -> - <<"0 1 -1 1e1 0.7 0.7e-1 true false null {} [] [1, 2, 3] \"hope this works\"">>. - -multi_test_result() -> - [ [{integer, "0"}], - [{integer, "1"}], - [{integer, "-1"}], - [{float, "1.0e1"}], - [{float, "0.7"}], - [{float, "0.7e-1"}], - [{literal, true}], - [{literal, false}], - [{literal, null}], - [start_object, end_object], - [start_array, end_array], - [start_array, {integer, "1"}, {integer, "2"}, {integer, "3"}, end_array], - [{string, "hope this works"}] - ]. \ No newline at end of file From 80d42c4e49ff1b2fa3b686921f5293550d0dcab7 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 10 Aug 2010 17:51:04 -0700 Subject: [PATCH 15/17] removed fake test and redundant functions --- src/jsx_test.erl | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/jsx_test.erl b/src/jsx_test.erl index 31e445b..dd507db 100644 --- a/src/jsx_test.erl +++ b/src/jsx_test.erl @@ -41,9 +41,6 @@ test() -> erlang:error(notest). -else. -fake_test_() -> - [ {"fake test", ?_assert(true)} ]. - jsx_decoder_test_() -> jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}]). @@ -99,22 +96,6 @@ parse_tests([], _Dir, Acc) -> Acc. -decoder_tests([Test|Rest], Encoding, Acc) -> - Name = lists:flatten(proplists:get_value(name, Test) ++ "::" ++ io_lib:format("~p", [Encoding])), - JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), - JSX = proplists:get_value(jsx, Test), - Flags = proplists:get_value(jsx_flags, Test, []), - decoder_tests(Rest, - Encoding, - [{"incremental " ++ Name, ?_assert(incremental_decode(JSON, Flags) =:= JSX)}] - ++ [{Name, ?_assert(decode(JSON, Flags) =:= JSX)}] - ++ Acc - ); -decoder_tests([], _Encoding, Acc) -> - io:format("~p~n", [Acc]), - Acc. - - decode(JSON, Flags) -> P = jsx:parser(Flags), decode_loop(P(JSON), []). From 843b3cdf24f71be37b0e844739cf5ec742674ae9 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 10 Aug 2010 21:56:29 -0700 Subject: [PATCH 16/17] more tests plus associated bug fixes, some tests still broken (in the sense they are not being run, not that they fail) --- src/jsx_eep0018.erl | 86 ++++++++++++++++++++++++++++++++++----------- src/jsx_format.erl | 2 ++ src/jsx_test.erl | 56 +++++++++++++++++++++++++---- 3 files changed, 117 insertions(+), 27 deletions(-) diff --git a/src/jsx_eep0018.erl b/src/jsx_eep0018.erl index bd2d604..cd9c280 100644 --- a/src/jsx_eep0018.erl +++ b/src/jsx_eep0018.erl @@ -127,7 +127,7 @@ collect({event, end_json, _Next}, [[Acc]], _Opts) -> %% the head of the accumulator and deal with it when we receive it's paired value collect({event, {key, _} = PreKey, Next}, [Current|_] = Acc, Opts) -> Key = event(PreKey, Opts), - case key_repeats(Key, Current) of + case decode_key_repeats(Key, Current) of true -> erlang:error(badarg) ; false -> collect(Next(), [Key] ++ Acc, Opts) end; @@ -141,6 +141,14 @@ collect({event, Event, Next}, [Current|Rest], Opts) when is_list(Current) -> collect({event, Event, Next}, [Key, Current|Rest], Opts) -> collect(Next(), [[{Key, event(Event, Opts)}] ++ Current] ++ Rest, Opts); +%% if our first returned event is {incomplete, ...} try to force end and return the +%% Event if one is returned +collect({incomplete, More}, [[]], Opts) -> + case More(end_stream) of + {event, Event, _Next} -> event(Event, Opts) + ; _ -> erlang:error(badarg) + end; + %% any other event is an error collect(_, _, _) -> erlang:error(badarg). @@ -172,6 +180,12 @@ event({float, Float}, _Opts) -> event({literal, Literal}, _Opts) -> Literal. + +decode_key_repeats(Key, [{Key, _Value}|_Rest]) -> true; +decode_key_repeats(Key, [_|Rest]) -> decode_key_repeats(Key, Rest); +decode_key_repeats(_Key, []) -> false. + + %% convert eep0018 representation to jsx events. note special casing for the empty object @@ -188,7 +202,7 @@ term_to_events(Term) -> proplist_to_events([{Key, Term}|Rest], Acc) -> Event = term_to_event(Term), EncodedKey = key_to_event(Key), - case key_repeats(EncodedKey, Acc) of + case encode_key_repeats(EncodedKey, Acc) of false -> proplist_to_events(Rest, Event ++ EncodedKey ++ Acc) ; true -> erlang:error(badarg) end; @@ -223,6 +237,16 @@ key_to_event(Key) when is_atom(Key) -> key_to_event(Key) when is_binary(Key) -> [{key, json_escape(Key)}]. + +encode_key_repeats([Key], SoFar) -> encode_key_repeats(Key, SoFar, 0). + +encode_key_repeats(Key, [Key|_], 0) -> true; +encode_key_repeats(Key, [end_object|Rest], Level) -> encode_key_repeats(Key, Rest, Level + 1); +encode_key_repeats(Key, [start_object|_], 0) -> false; +encode_key_repeats(Key, [start_object|Rest], Level) -> encode_key_repeats(Key, Rest, Level - 1); +encode_key_repeats(Key, [_|Rest], Level) -> encode_key_repeats(Key, Rest, Level); +encode_key_repeats(_, [], 0) -> false. + %% conversion of floats to 'nice' decimal output. erlang's float implementation is almost %% but not quite ieee 754. it converts negative zero to plain zero silently, and throws @@ -393,17 +417,49 @@ to_hex(10) -> $a; to_hex(X) -> X + $0. -%% common functions - -key_repeats([{key, Key}], [{key, Key}|_Rest]) -> true; -key_repeats(Key, [{Key, _Value}|_Rest]) -> true; -key_repeats(Key, [_|Rest]) -> key_repeats(Key, Rest); -key_repeats(_Key, []) -> false. - - %% eunit tests -ifdef(test). +decode_test_() -> + [ + {"empty object", ?_assert(json_to_term(<<"{}">>, []) =:= [{}])}, + {"empty array", ?_assert(json_to_term(<<"[]">>, []) =:= [])}, + {"simple object", ?_assert(json_to_term(<<"{\"a\": true, \"b\": true, \"c\": true}">>, [{label, atom}]) =:= [{a, true}, {b, true}, {c, true}])}, + {"simple array", ?_assert(json_to_term(<<"[true,true,true]">>, []) =:= [true, true, true])}, + {"nested structures", ?_assert(json_to_term(<<"{\"list\":[{\"list\":[{}, {}],\"object\":{}}, []],\"object\":{}}">>, [{label, atom}]) =:= [{list, [[{list, [[{}], [{}]]}, {object, [{}]}],[]]}, {object, [{}]}])}, + {"numbers", ?_assert(json_to_term(<<"[-10000000000.0, -1, 0.0, 0, 1, 10000000000, 1000000000.0]">>, []) =:= [-10000000000.0, -1, 0.0, 0, 1, 10000000000, 1000000000.0])}, + {"numbers (all floats)", ?_assert(json_to_term(<<"[-10000000000.0, -1, 0.0, 0, 1, 10000000000, 1000000000.0]">>, [{float, true}]) =:= [-10000000000.0, -1.0, 0.0, 0.0, 1.0, 10000000000.0, 1000000000.0])}, + {"strings", ?_assert(json_to_term(<<"[\"a string\"]">>, []) =:= [<<"a string">>])}, + {"literals", ?_assert(json_to_term(<<"[true,false,null]">>, []) =:= [true,false,null])}, + {"naked true", ?_assert(json_to_term(<<"true">>, [{strict, false}]) =:= true)}, + {"naked short number", ?_assert(json_to_term(<<"1">>, [{strict, false}]) =:= 1)}, + {"float", ?_assert(json_to_term(<<"1.0">>, [{strict, false}]) =:= 1.0)}, + {"naked string", ?_assert(json_to_term(<<"\"hello world\"">>, [{strict, false}]) =:= <<"hello world">>)}, + {"comments", ?_assert(json_to_term(<<"[ /* a comment in an empty array */ ]">>, [{comments, true}]) =:= [])} + ]. + +encode_test_() -> + [ + {"empty object", ?_assert(term_to_json([{}], []) =:= <<"{}">>)}, + {"empty array", ?_assert(term_to_json([], []) =:= <<"[]">>)}, + {"simple object", ?_assert(term_to_json([{a, true}, {b, true}, {c, true}], []) =:= <<"{\"a\":true,\"b\":true,\"c\":true}">>)}, + {"simple array", ?_assert(term_to_json([true, true, true], []) =:= <<"[true,true,true]">>)}, + {"nested structures", ?_assert(term_to_json([{list, [[{list, [[{}], [{}]]}, {object, [{}]}],[]]}, {object, [{}]}], []) =:= <<"{\"list\":[{\"list\":[{},{}],\"object\":{}},[]],\"object\":{}}">>)}, + {"numbers", ?_assert(term_to_json([-10000000000.0, -1, 0.0, 0, 1, 10000000000, 1000000000.0], []) =:= <<"[-1.0e10,-1,0.0,0,1,10000000000,1.0e9]">>)}, + {"strings", ?_assert(term_to_json([<<"a string">>], []) =:= <<"[\"a string\"]">>)}, + {"literals", ?_assert(term_to_json([true,false,null], []) =:= <<"[true,false,null]">>)}, + {"naked true", ?_assert(term_to_json(true, [{strict, false}]) =:= <<"true">>)}, + {"naked number", ?_assert(term_to_json(1, [{strict, false}]) =:= <<"1">>)}, + {"float", ?_assert(term_to_json(1.0, [{strict, false}]) =:= <<"1.0">>)}, + {"naked string", ?_assert(term_to_json(<<"hello world">>, [{strict, false}]) =:= <<"\"hello world\"">>)} + ]. + +repeated_keys_test_() -> + [ + {"encode", ?_assertError(badarg, term_to_json([{k, true}, {k, false}], []))}, + {"decode", ?_assertError(badarg, json_to_term(<<"{\"k\": true, \"k\": false}">>, []))} + ]. + escape_test_() -> [ {"json string escaping", ?_assert(json_escape(<<"\"\\\b\f\n\r\t">>) =:= <<"\\\"\\\\\\b\\f\\n\\r\\t">>)}, @@ -427,15 +483,5 @@ nice_decimal_test_() -> {"min denormalized float", ?_assert(float_to_decimal(math:pow(2, -1074)) =:= "5.0e-324")}, {"max denormalized float", ?_assert(float_to_decimal((1 - math:pow(2, -52)) * math:pow(2, -1022)) =:= "2.225073858507201e-308")} ]. - -key_repeats_test_() -> - [ - {"encoded key repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"key">>}, {key, <<"trailing key">>}]) =:= true)}, - {"encoded key no repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"trailing key">>}]) =:= false)}, - {"decoded key (atom) repeat", ?_assert(key_repeats(key, [{notkey, true}, {key, true}, {trailing_key, true}]) =:= true)}, - {"decoded key (binary) repeat", ?_assert(key_repeats(<<"key">>, [{<<"notkey">>, true}, {<<"key">>, true}, {<<"trailing key">>, true}]) =:= true)}, - {"decoded key (atom) no repeat", ?_assert(key_repeats(key, [{notkey, true}, {definitely_not_key, true}, {trailing_key, true}]) =:= false)}, - {"decoded key (binary) no repeat", ?_assert(key_repeats(<<"key">>, [{<<"notkey">>, true}, {<<"definitely not key">>, true}, {<<"trailing key">>, true}]) =:= false)} - ]. -endif. \ No newline at end of file diff --git a/src/jsx_format.erl b/src/jsx_format.erl index a43d650..bb2ccef 100644 --- a/src/jsx_format.erl +++ b/src/jsx_format.erl @@ -81,6 +81,8 @@ parse_opts([space|Rest], Opts) -> parse_opts(Rest, Opts#opts{space = 1}); parse_opts([{output_encoding, Val}|Rest], Opts) -> parse_opts(Rest, Opts#opts{output_encoding = Val}); +parse_opts([_|Rest], Opts) -> + parse_opts(Rest, Opts); parse_opts([], Opts) -> Opts. diff --git a/src/jsx_test.erl b/src/jsx_test.erl index dd507db..7386c57 100644 --- a/src/jsx_test.erl +++ b/src/jsx_test.erl @@ -42,20 +42,24 @@ test() -> erlang:error(notest). -else. jsx_decoder_test_() -> - jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}]). + jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}], fun decode/2). -jsx_decoder_gen([_Test|Rest], []) -> - jsx_decoder_gen(Rest, [utf8, utf16, {utf16, little}, utf32, {utf32, little}]); -jsx_decoder_gen([], _) -> +jsx_incremental_test_() -> + jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}], fun incremental_decode/2). + + +jsx_decoder_gen([_Test|Rest], [], F) -> + jsx_decoder_gen(Rest, [utf8, utf16, {utf16, little}, utf32, {utf32, little}], F); +jsx_decoder_gen([], _, _) -> []; -jsx_decoder_gen([Test|_] = Tests, [Encoding|Encodings]) -> +jsx_decoder_gen([Test|_] = Tests, [Encoding|Encodings], F) -> Name = lists:flatten(proplists:get_value(name, Test) ++ " :: " ++ io_lib:format("~p", [Encoding])), JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), JSX = proplists:get_value(jsx, Test), Flags = proplists:get_value(jsx_flags, Test, []), {generator, fun() -> - [{Name, ?_assert(decode(JSON, Flags) =:= JSX)} | jsx_decoder_gen(Tests, Encodings)] + [{Name, ?_assert(F(JSON, Flags) =:= JSX)} | jsx_decoder_gen(Tests, Encodings, F)] end }. @@ -120,5 +124,43 @@ incremental_decode_loop({event, end_json, _Next}, _Rest, Acc) -> lists:reverse([end_json] ++ Acc); incremental_decode_loop({event, Event, Next}, Rest, Acc) -> incremental_decode_loop(Next(), Rest, [Event] ++ Acc). - + + +multi_decode_test_() -> + [ + {"multiple values in a single stream", ?_assert(multi_decode(multi_json_body(), []) =:= multi_test_result())} + ]. + + +multi_decode(JSON, Flags) -> + P = jsx:parser(Flags ++ [{multi_term, true}]), + multi_decode_loop(P(JSON), [[]]). + +multi_decode_loop({incomplete, _Next}, [[]|Acc]) -> + lists:reverse(Acc); +multi_decode_loop({event, end_json, Next}, [S|Acc]) -> + multi_decode_loop(Next(), [[]|[lists:reverse(S)] ++ Acc]); +multi_decode_loop({event, E, Next}, [S|Acc]) -> + multi_decode_loop(Next(), [[E] ++ S] ++ Acc). + + +multi_json_body() -> + <<"0 1 -1 1e1 0.7 0.7e-1 true false null {} [] [1, 2, 3] \"hope this works\"">>. + +multi_test_result() -> + [ [{integer, "0"}], + [{integer, "1"}], + [{integer, "-1"}], + [{float, "1.0e1"}], + [{float, "0.7"}], + [{float, "0.7e-1"}], + [{literal, true}], + [{literal, false}], + [{literal, null}], + [start_object, end_object], + [start_array, end_array], + [start_array, {integer, "1"}, {integer, "2"}, {integer, "3"}, end_array], + [{string, "hope this works"}] + ]. + -endif. \ No newline at end of file From 55f1f183669f82fbd09e6d2ffa7cec4a73b941df Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Wed, 11 Aug 2010 19:27:33 -0700 Subject: [PATCH 17/17] tests working, finally --- rebar.config | 4 +++- src/jsx_test.erl | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/rebar.config b/rebar.config index fd69bc7..0aac6f7 100644 --- a/rebar.config +++ b/rebar.config @@ -1,4 +1,6 @@ -{eunit_compile_opts, [{d, test}]}. +%% edit eunit_test_path if you want to run your own tests, use "../" not "./" as +%% rebar changes to working dir to .eunit when running tests +{eunit_compile_opts, [{d, test}, {d, eunit_test_path, "../test/cases"}]}. %% uncomment to get verbose output from test suite {eunit_opts, [verbose]}. diff --git a/src/jsx_test.erl b/src/jsx_test.erl index 7386c57..74d41d1 100644 --- a/src/jsx_test.erl +++ b/src/jsx_test.erl @@ -42,24 +42,28 @@ test() -> erlang:error(notest). -else. jsx_decoder_test_() -> - jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}], fun decode/2). + jsx_decoder_gen(load_tests(?eunit_test_path)). -jsx_incremental_test_() -> - jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}], fun incremental_decode/2). - -jsx_decoder_gen([_Test|Rest], [], F) -> - jsx_decoder_gen(Rest, [utf8, utf16, {utf16, little}, utf32, {utf32, little}], F); -jsx_decoder_gen([], _, _) -> - []; -jsx_decoder_gen([Test|_] = Tests, [Encoding|Encodings], F) -> +jsx_decoder_gen([]) -> []; +jsx_decoder_gen(Tests) -> jsx_decoder_gen(Tests, [utf8, utf16, {utf16, little}, utf32, {utf32, little}]). + +jsx_decoder_gen([_Test|Rest], []) -> + jsx_decoder_gen(Rest); +jsx_decoder_gen([Test|_] = Tests, [Encoding|Encodings]) -> Name = lists:flatten(proplists:get_value(name, Test) ++ " :: " ++ io_lib:format("~p", [Encoding])), JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding), JSX = proplists:get_value(jsx, Test), Flags = proplists:get_value(jsx_flags, Test, []), {generator, fun() -> - [{Name, ?_assert(F(JSON, Flags) =:= JSX)} | jsx_decoder_gen(Tests, Encodings, F)] + [{Name, ?_assert(decode(JSON, Flags) =:= JSX)} + | {generator, + fun() -> [{Name ++ " incremental", ?_assert(incremental_decode(JSON, Flags) =:= JSX)} + | jsx_decoder_gen(Tests, Encodings)] + end + } + ] end }.